Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions cpp/Platform.Interfaces.Tests/Platform.Interfaces.Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,57 @@
#include <gtest/gtest.h>

namespace Platform::Interfaces::Tests {
namespace {
struct ReadonlyListModel {
int items[1]{};

const int* begin() const { return items; }
const int* end() const { return items + 1; }
const int& operator[](std::size_t index) const { return items[index]; }
std::size_t size() const { return static_cast<std::size_t>(end() - begin()); }
bool empty() const { return begin() == end(); }
};

struct ReadonlySetModel {
int items[1]{};

const int* begin() const { return items; }
const int* end() const { return items + 1; }
const int* find(int item) const { return items[0] == item ? begin() : end(); }
bool contains(int item) const { return find(item) != end(); }
std::size_t size() const { return static_cast<std::size_t>(end() - begin()); }
bool empty() const { return begin() == end(); }
};

struct ReadonlyDictionaryModel {
std::tuple<int, int> items[1]{};

const std::tuple<int, int>* begin() const { return items; }
const std::tuple<int, int>* end() const { return items + 1; }
const std::tuple<int, int>* find(int key) const { return std::get<0>(items[0]) == key ? begin() : end(); }
bool contains(int key) const { return find(key) != end(); }
std::size_t size() const { return static_cast<std::size_t>(end() - begin()); }
bool empty() const { return begin() == end(); }
};
} // namespace

static_assert(CReadonlyList<const ReadonlyListModel>);
static_assert(CReadonlyList<const ReadonlyListModel, int>);
static_assert(!CList<const ReadonlyListModel>);
static_assert(std::same_as<typename ReadonlyList<const ReadonlyListModel>::Item, int>);

static_assert(CReadonlySet<const ReadonlySetModel>);
static_assert(CReadonlySet<const ReadonlySetModel, int>);
static_assert(!CSet<const ReadonlySetModel>);
static_assert(std::same_as<typename ReadonlySet<const ReadonlySetModel>::Item, int>);

static_assert(CReadonlyDictionary<const ReadonlyDictionaryModel>);
static_assert(CReadonlyDictionary<const ReadonlyDictionaryModel, int>);
static_assert(CReadonlyDictionary<const ReadonlyDictionaryModel, int, int>);
static_assert(!CDictionary<const ReadonlyDictionaryModel>);
static_assert(std::same_as<std::remove_reference_t<typename ReadonlyDictionary<const ReadonlyDictionaryModel>::Key>, int>);
static_assert(std::same_as<std::remove_reference_t<typename ReadonlyDictionary<const ReadonlyDictionaryModel>::Value>, int>);

TEST(CompileTests, Counter) {
struct EmptyCounter1 : ICounter<int> {
int Count() { return {}; }
Expand Down
56 changes: 54 additions & 2 deletions cpp/Platform.Interfaces/CDictionary.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,67 @@ namespace Platform::Interfaces {

return false;
}

template <typename TRawSelf, typename... TArgs>
consteval bool CReadonlyDictionaryHelpFunction() {
using Self = TRawSelf;

using GenericKey = std::remove_reference_t<decltype(std::get<0>(std::declval<typename Enumerable<Self>::Item>()))>;

if constexpr (sizeof...(TArgs) == 0) {
return requires(const Self& self, GenericKey generic_key) {
{ self.find(generic_key) } -> std::forward_iterator;
{ self.contains(generic_key) } -> std::same_as<bool>;
{ self.empty() } -> std::same_as<bool>;
{ self.size() } -> std::integral;

requires std::ranges::forward_range<const Self>;
};
}
if constexpr (sizeof...(TArgs) == 1) {
return requires(const Self& self, std::tuple<TArgs...> args,
decltype(std::get<0>(args)) key) {
{ self.find(key) } -> std::forward_iterator;
{ self.contains(key) } -> std::same_as<bool>;
{ self.empty() } -> std::same_as<bool>;
{ self.size() } -> std::integral;

requires std::ranges::forward_range<const Self>;
};
}
if constexpr (sizeof...(TArgs) == 2) {
return requires(const Self& self, std::tuple<TArgs...> args,
decltype(std::get<0>(args)) key) {
{ self.find(key) } -> std::forward_iterator;
{ self.contains(key) } -> std::same_as<bool>;
{ self.empty() } -> std::same_as<bool>;
{ self.size() } -> std::integral;

requires std::ranges::forward_range<const Self>;
};
}

return false;
}
} // namespace Internal

template <typename TSelf, typename... TArgs>
concept CDictionary = CEnumerable<TSelf> && Internal::CDictionaryHelpFunction<TSelf, TArgs...>();

template <typename TSelf, typename... TArgs>
concept CReadonlyDictionary = CEnumerable<TSelf> && Internal::CReadonlyDictionaryHelpFunction<TSelf, TArgs...>();

template <CDictionary TSelf>
struct Dictionary : Enumerable<TSelf> {
using base = Enumerable<TSelf>;
using Key = decltype(std::get<0>(std::declval<base::Item>()));
using Value = decltype(std::get<1>(std::declval<base::Item>()));
using Key = decltype(std::get<0>(std::declval<typename base::Item>()));
using Value = decltype(std::get<1>(std::declval<typename base::Item>()));
};

template <CReadonlyDictionary TSelf>
struct ReadonlyDictionary : Enumerable<TSelf> {
using base = Enumerable<TSelf>;
using Key = decltype(std::get<0>(std::declval<typename base::Item>()));
using Value = decltype(std::get<1>(std::declval<typename base::Item>()));
};
} // namespace Platform::Interfaces
36 changes: 36 additions & 0 deletions cpp/Platform.Interfaces/CList.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,47 @@ namespace Platform::Interfaces {

return false;
}

template <typename TRawSelf, typename... TItems>
consteval bool CReadonlyListHelpFunction() {
using Self = TRawSelf;

if constexpr (sizeof...(TItems) == 1) {
using RequiredItem = std::remove_reference_t<decltype(std::get<0>(std::declval<std::tuple<TItems...>>()))>;

return requires(const Self& self, std::size_t index) {
{ self.size() } -> std::integral;
{ self.empty() } -> std::same_as<bool>;
{ self[index] } -> std::convertible_to<RequiredItem>;

requires std::ranges::forward_range<const Self>;
};
}
if constexpr (sizeof...(TItems) == 0) {
using GenericItem = typename Enumerable<const Self>::Item;

return requires(const Self& self, std::size_t index) {
{ self.size() } -> std::integral;
{ self.empty() } -> std::same_as<bool>;
{ self[index] } -> std::convertible_to<GenericItem>;

requires std::ranges::forward_range<const Self>;
};
}

return false;
}
} // namespace Internal

template <typename TSelf, typename... TItems>
concept CList = CArray<TSelf> && Internal::CListHelpFunction<TSelf, TItems...>();

template <typename TSelf, typename... TItems>
concept CReadonlyList = CArray<TSelf> && Internal::CReadonlyListHelpFunction<TSelf, TItems...>();

template <CList TSelf>
struct List : Enumerable<TSelf> {};

template <CReadonlyList TSelf>
struct ReadonlyList : Enumerable<TSelf> {};
} // namespace Platform::Interfaces
34 changes: 34 additions & 0 deletions cpp/Platform.Interfaces/CSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,45 @@ namespace Platform::Interfaces {
return false;
}

template <typename TRawSelf, typename... TItems>
consteval bool CReadonlySetHelpFunction() {
using Self = TRawSelf;

if constexpr (sizeof...(TItems) == 1) {
return requires(const Self& self, std::tuple<TItems...> items, decltype(std::get<0>(items)) item) {
{ self.find(item) } -> std::same_as<std::ranges::iterator_t<const Self>>;
{ self.contains(item) } -> std::same_as<bool>;
{ self.empty() } -> std::same_as<bool>;
{ self.size() } -> std::integral;

requires std::ranges::forward_range<const Self>;
};
}
if constexpr (sizeof...(TItems) == 0) {
return requires(const Self& self, typename Enumerable<const Self>::Item generic_item) {
{ self.find(generic_item) } -> std::same_as<std::ranges::iterator_t<const Self>>;
{ self.contains(generic_item) } -> std::same_as<bool>;
{ self.empty() } -> std::same_as<bool>;
{ self.size() } -> std::integral;

requires std::ranges::forward_range<const Self>;
};
}

return false;
}

} // namespace Internal

template <typename TSelf, typename... TItems>
concept CSet = CEnumerable<TSelf> && Internal::CSetHelpFunction<TSelf, TItems...>();

template <typename TSelf, typename... TItems>
concept CReadonlySet = CEnumerable<TSelf> && Internal::CReadonlySetHelpFunction<TSelf, TItems...>();

template <CSet TSelf>
struct Set : Enumerable<TSelf> {};

template <CReadonlySet TSelf>
struct ReadonlySet : Enumerable<TSelf> {};
} // namespace Platform::Interfaces
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<summary>LinksPlatform's Platform.Interfaces is a Template Library what contains common concepts templates.</summary>
<description>LinksPlatform's Platform.Interfaces is a Template Library what contains set of C++ concepts templates. Use Platform.Interfaces.h file to include the library.</description>
<releaseNotes>Test release for automatic deploy system.</releaseNotes>
<version>0.3.42</version>
<version>0.3.43</version>
<authors>konard, uselessgoddess, Mitron57</authors>
<owners>konard, uselessgoddess, Mitron57</owners>
<copyright>konard, uselessgoddess, Mitron57</copyright>
Expand Down
Loading