From b9cd1668f0475d733f2cc50457b0eb9fa1f12727 Mon Sep 17 00:00:00 2001 From: Antony Peacock Date: Wed, 26 Jun 2024 14:13:56 +0100 Subject: [PATCH] Add concept for standard container requirements (#314) * Add concept for standard container requirements * Archtypes for container and allocator aware types, with tests. * std::vector sepcialisation of get_allocator is not noexcept * Support sequence containers * Remove duplication * Include ranges * Correct namespace * Update archtype for from_range * Range methods fix * Patch up the sequence concept as best we can * Contiguous concept with tests * Concept for reversible container requirements and partial concepts for associativ and unordered * Complete associative concept * Try compound requirement for visual studio * Complete unorder container concepts * Check for all basic string instantiations --- .../core/src/morpheus/core/CMakeLists.txt | 3 +- .../morpheus/core/containers/CMakeLists.txt | 1 + .../core/containers/concepts/CMakeLists.txt | 12 ++ .../containers/concepts/allocator_aware.hpp | 29 +++ .../core/containers/concepts/associative.hpp | 66 +++++++ .../core/containers/concepts/container.hpp | 34 ++++ .../core/containers/concepts/contiguous.hpp | 21 +++ .../containers/concepts/detail/CMakeLists.txt | 4 + .../concepts/detail/return_types.hpp | 33 ++++ .../core/containers/concepts/reversible.hpp | 28 +++ .../core/containers/concepts/sequence.hpp | 67 +++++++ .../core/containers/concepts/unordered.hpp | 85 +++++++++ .../morpheus/core/functional/CMakeLists.txt | 2 + .../core/functional/concepts/CMakeLists.txt | 5 + .../core/functional/concepts/function.hpp | 19 ++ .../core/functional/concepts/hash.hpp | 21 +++ .../core/memory/concepts/allocator.hpp | 22 ++- .../core/memory/concepts/nullable_pointer.hpp | 7 +- .../src/morpheus/core/meta/CMakeLists.txt | 1 + .../core/src/morpheus/core/meta/is_array.hpp | 15 ++ .../core/testing/morpheus/CMakeLists.txt | 1 + .../morpheus/containers/CMakeLists.txt | 1 + .../containers/concepts/CMakeLists.txt | 1 + .../concepts/archtypes/CMakeLists.txt | 9 + .../concepts/archtypes/allocator_aware.hpp | 32 ++++ .../concepts/archtypes/associative.hpp | 148 +++++++++++++++ .../concepts/archtypes/container.hpp | 48 +++++ .../concepts/archtypes/reversible.hpp | 29 +++ .../concepts/archtypes/sequence.hpp | 55 ++++++ .../concepts/archtypes/unordered.hpp | 171 ++++++++++++++++++ libraries/core/tests/CMakeLists.txt | 1 + .../core/tests/containers/CMakeLists.txt | 1 + .../tests/containers/concepts/CMakeLists.txt | 10 + .../concepts/allocator_aware.tests.cpp | 38 ++++ .../containers/concepts/associative.tests.cpp | 45 +++++ .../containers/concepts/container.tests.cpp | 44 +++++ .../containers/concepts/contiguous.tests.cpp | 51 ++++++ .../containers/concepts/reversible.tests.cpp | 43 +++++ .../containers/concepts/sequence.tests.cpp | 42 +++++ .../containers/concepts/unordered.tests.cpp | 45 +++++ libraries/core/tests/meta/CMakeLists.txt | 1 + libraries/core/tests/meta/is_array.tests.cpp | 39 ++++ 42 files changed, 1318 insertions(+), 12 deletions(-) create mode 100644 libraries/core/src/morpheus/core/containers/CMakeLists.txt create mode 100644 libraries/core/src/morpheus/core/containers/concepts/CMakeLists.txt create mode 100644 libraries/core/src/morpheus/core/containers/concepts/allocator_aware.hpp create mode 100644 libraries/core/src/morpheus/core/containers/concepts/associative.hpp create mode 100644 libraries/core/src/morpheus/core/containers/concepts/container.hpp create mode 100644 libraries/core/src/morpheus/core/containers/concepts/contiguous.hpp create mode 100644 libraries/core/src/morpheus/core/containers/concepts/detail/CMakeLists.txt create mode 100644 libraries/core/src/morpheus/core/containers/concepts/detail/return_types.hpp create mode 100644 libraries/core/src/morpheus/core/containers/concepts/reversible.hpp create mode 100644 libraries/core/src/morpheus/core/containers/concepts/sequence.hpp create mode 100644 libraries/core/src/morpheus/core/containers/concepts/unordered.hpp create mode 100644 libraries/core/src/morpheus/core/functional/concepts/CMakeLists.txt create mode 100644 libraries/core/src/morpheus/core/functional/concepts/function.hpp create mode 100644 libraries/core/src/morpheus/core/functional/concepts/hash.hpp create mode 100644 libraries/core/src/morpheus/core/meta/is_array.hpp create mode 100644 libraries/core/testing/morpheus/containers/CMakeLists.txt create mode 100644 libraries/core/testing/morpheus/containers/concepts/CMakeLists.txt create mode 100644 libraries/core/testing/morpheus/containers/concepts/archtypes/CMakeLists.txt create mode 100644 libraries/core/testing/morpheus/containers/concepts/archtypes/allocator_aware.hpp create mode 100644 libraries/core/testing/morpheus/containers/concepts/archtypes/associative.hpp create mode 100644 libraries/core/testing/morpheus/containers/concepts/archtypes/container.hpp create mode 100644 libraries/core/testing/morpheus/containers/concepts/archtypes/reversible.hpp create mode 100644 libraries/core/testing/morpheus/containers/concepts/archtypes/sequence.hpp create mode 100644 libraries/core/testing/morpheus/containers/concepts/archtypes/unordered.hpp create mode 100644 libraries/core/tests/containers/CMakeLists.txt create mode 100644 libraries/core/tests/containers/concepts/CMakeLists.txt create mode 100644 libraries/core/tests/containers/concepts/allocator_aware.tests.cpp create mode 100644 libraries/core/tests/containers/concepts/associative.tests.cpp create mode 100644 libraries/core/tests/containers/concepts/container.tests.cpp create mode 100644 libraries/core/tests/containers/concepts/contiguous.tests.cpp create mode 100644 libraries/core/tests/containers/concepts/reversible.tests.cpp create mode 100644 libraries/core/tests/containers/concepts/sequence.tests.cpp create mode 100644 libraries/core/tests/containers/concepts/unordered.tests.cpp create mode 100644 libraries/core/tests/meta/is_array.tests.cpp diff --git a/libraries/core/src/morpheus/core/CMakeLists.txt b/libraries/core/src/morpheus/core/CMakeLists.txt index 5ad041c1..b231c883 100644 --- a/libraries/core/src/morpheus/core/CMakeLists.txt +++ b/libraries/core/src/morpheus/core/CMakeLists.txt @@ -10,8 +10,9 @@ target_sources(MorpheusCore ) add_subdirectory(base) -add_subdirectory(conformance) add_subdirectory(concurrency) +add_subdirectory(conformance) +add_subdirectory(containers) add_subdirectory(functional) add_subdirectory(memory) add_subdirectory(meta) diff --git a/libraries/core/src/morpheus/core/containers/CMakeLists.txt b/libraries/core/src/morpheus/core/containers/CMakeLists.txt new file mode 100644 index 00000000..e632a43f --- /dev/null +++ b/libraries/core/src/morpheus/core/containers/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(concepts) \ No newline at end of file diff --git a/libraries/core/src/morpheus/core/containers/concepts/CMakeLists.txt b/libraries/core/src/morpheus/core/containers/concepts/CMakeLists.txt new file mode 100644 index 00000000..06e8a108 --- /dev/null +++ b/libraries/core/src/morpheus/core/containers/concepts/CMakeLists.txt @@ -0,0 +1,12 @@ +add_subdirectory(detail) + +target_sources(MorpheusCore + PUBLIC + allocator_aware.hpp + associative.hpp + container.hpp + contiguous.hpp + reversible.hpp + sequence.hpp + unordered.hpp +) diff --git a/libraries/core/src/morpheus/core/containers/concepts/allocator_aware.hpp b/libraries/core/src/morpheus/core/containers/concepts/allocator_aware.hpp new file mode 100644 index 00000000..6b1c6adc --- /dev/null +++ b/libraries/core/src/morpheus/core/containers/concepts/allocator_aware.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "morpheus/core/containers/concepts/container.hpp" + +#include +#include + +namespace morpheus::containers::concepts +{ + +/// \concept AllocatorAware +/// Concept capturing the requirements for an allocator aware container as outline in the standard at +/// [container.alloc.reqmts], details at +/// AllocatorAwareContainer. +template +concept AllocatorAware = Container && requires(X x, X&& rx, typename X::allocator_type a){ + requires std::same_as; + requires std::default_initializable; + { X(a) }; + { X(std::as_const(x), a) }; + { X(std::move(rx)) }; + { X(std::move(rx), a) }; + { std::as_const(x).get_allocator() } -> std::same_as; + { x = x } -> std::same_as; + { x = rx } -> std::same_as; + { x.swap(x) } -> std::same_as; +}; + +} // namespace morpheus::containers::concepts diff --git a/libraries/core/src/morpheus/core/containers/concepts/associative.hpp b/libraries/core/src/morpheus/core/containers/concepts/associative.hpp new file mode 100644 index 00000000..58df3dbb --- /dev/null +++ b/libraries/core/src/morpheus/core/containers/concepts/associative.hpp @@ -0,0 +1,66 @@ +#pragma once + +#include "morpheus/core/containers/concepts/detail/return_types.hpp" +#include "morpheus/core/containers/concepts/allocator_aware.hpp" + +#include +#include + +namespace morpheus::containers::concepts +{ + +/// \concept Associative +/// Concept capturing the requirements for an associative container as outline in the standard at +/// [associative.reqmts], details at +/// AssociativeContainer. +template +concept Associative = AllocatorAware && requires(T t, typename T::value_type v, typename T::key_type k, typename T::size_type s, typename T::iterator i, + typename T::const_iterator ci, typename T::key_compare c, typename T::node_type n, + std::initializer_list il) +{ + requires (std::default_initializable) and (std::copy_constructible); + { T(c) }; + { T(i, i, c) }; + { T(i, i) }; +#if (__cpp_lib_containers_ranges >= 202202L) + { T(std::from_range, ranges::subrange{}, c) }; + { T(std::from_range, ranges::subrange{}) }; +#endif // (__cpp_lib_containers_ranges >= 202202L) + { T(il, c) }; + { T(il) }; + { t = il }; + { std::as_const(t).key_comp() } -> std::same_as; + { std::as_const(t).value_comp() } -> std::same_as; + { t.emplace() } -> detail::InsertReturnType; + { t.emplace_hint(i) } -> std::same_as; + { t.insert(v) } -> detail::InsertReturnType; + { t.insert(ci, v) } -> std::same_as; + { t.insert(i, i) } -> std::same_as; +#if (__cpp_lib_containers_ranges >= 202202L) + { t.insert_range(ranges::subrange{}) } -> std::same_as; +#endif // (__cpp_lib_containers_ranges >= 202202L) + { t.insert(il) } -> std::same_as; + { t.insert(std::move(n)) } -> detail::InsertNodeHandleReturnType; + { t.insert(ci, std::move(n)) } -> std::same_as; + { t.extract(k) } -> std::same_as; + { t.extract(ci) } -> std::same_as; + { t.merge(t) } -> std::same_as; + { t.erase(i) } -> std::same_as; + { t.erase(ci) } -> std::same_as; + { t.erase(i, i) } -> std::same_as; + { t.erase(ci, ci) } -> std::same_as; + { t.erase(k) } -> std::same_as; + { t.clear() } -> std::same_as; + { t.find(k) } -> std::same_as; + { std::as_const(t).find(k) } -> std::same_as; + { std::as_const(t).count(k) } -> std::same_as; + { std::as_const(t).contains(k) } -> std::same_as; + { t.lower_bound(k) } -> detail::BoundReturnType; + { std::as_const(t).lower_bound(k) } -> detail::BoundConstReturnType; + { t.equal_range(k) } -> detail::BoundReturnType; + { std::as_const(t).equal_range(k) } -> detail::BoundConstReturnType; + { t.upper_bound(k) } -> detail::BoundReturnType; + { std::as_const(t).upper_bound(k) } -> detail::BoundConstReturnType; +}; + +} // namespace morpheus::containers::concepts diff --git a/libraries/core/src/morpheus/core/containers/concepts/container.hpp b/libraries/core/src/morpheus/core/containers/concepts/container.hpp new file mode 100644 index 00000000..f8b1c062 --- /dev/null +++ b/libraries/core/src/morpheus/core/containers/concepts/container.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include + +namespace morpheus::containers::concepts +{ + +/// \concept Container +/// Concept capturing the requirements for a container as outline in the standard at +/// [container.requirements], details at +/// Container. +template +concept Container = requires(C c) { + typename C::value_type; + typename C::reference; + typename C::const_reference; + requires std::forward_iterator; + requires std::forward_iterator; + requires std::signed_integral; + requires std::unsigned_integral; + requires std::convertible_to; + requires std::regular; + { begin(c) } -> std::same_as; + { end(c) } -> std::same_as; + { cbegin(std::as_const(c)) } -> std::same_as; + { cend(std::as_const(c)) } -> std::same_as; + requires (not std::bidirectional_iterator) or requires {{ size(c) } -> std::same_as; }; + { c.max_size() } -> std::same_as; + { empty(c) } -> std::same_as; +}; + +} // namespace morpheus::containers::concepts \ No newline at end of file diff --git a/libraries/core/src/morpheus/core/containers/concepts/contiguous.hpp b/libraries/core/src/morpheus/core/containers/concepts/contiguous.hpp new file mode 100644 index 00000000..8689d46c --- /dev/null +++ b/libraries/core/src/morpheus/core/containers/concepts/contiguous.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "morpheus/core/containers/concepts/sequence.hpp" + +#include +#include + +namespace morpheus::containers::concepts +{ + +/// \concept Contiguous +/// Concept capturing the requirements for a contiguous container, a named requirement outlined in the standard at +/// [container.requirements.general], details at +/// ContiguousContainer. +template +concept Contiguous = StrictSequence && requires(T t){ + requires std::contiguous_iterator; + requires std::contiguous_iterator; +}; + +} // namespace morpheus::containers::concepts diff --git a/libraries/core/src/morpheus/core/containers/concepts/detail/CMakeLists.txt b/libraries/core/src/morpheus/core/containers/concepts/detail/CMakeLists.txt new file mode 100644 index 00000000..0a2cb302 --- /dev/null +++ b/libraries/core/src/morpheus/core/containers/concepts/detail/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(MorpheusCore + PUBLIC + return_types.hpp +) diff --git a/libraries/core/src/morpheus/core/containers/concepts/detail/return_types.hpp b/libraries/core/src/morpheus/core/containers/concepts/detail/return_types.hpp new file mode 100644 index 00000000..e522553d --- /dev/null +++ b/libraries/core/src/morpheus/core/containers/concepts/detail/return_types.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +namespace morpheus::containers::concepts::detail +{ + +template +concept InsertReturnType = requires +{ + requires std::same_as or std::same_as>; +}; + +template +concept InsertNodeHandleReturnType = requires +{ + requires requires { std::same_as; } or requires { std::same_as; }; +}; + +template +concept BoundReturnType = requires +{ + requires std::same_as or std::same_as>; +}; + +template +concept BoundConstReturnType = requires +{ + requires std::same_as or std::same_as>; +}; + +} // namespace morpheus::containers::concepts \ No newline at end of file diff --git a/libraries/core/src/morpheus/core/containers/concepts/reversible.hpp b/libraries/core/src/morpheus/core/containers/concepts/reversible.hpp new file mode 100644 index 00000000..9759644d --- /dev/null +++ b/libraries/core/src/morpheus/core/containers/concepts/reversible.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "morpheus/core/containers/concepts/container.hpp" + +#include +#include +#include + +namespace morpheus::containers::concepts +{ + +/// \concept Reversible +/// Concept capturing the requirements for a reversible container, a named requirement outlined in the standard at +/// [container.rev.reqmts], details at +/// ReversibleContainer. +template +concept Reversible = Container && requires(T t){ + typename T::reverse_iterator; + typename T::const_reverse_iterator; + requires std::same_as>; + requires std::same_as>; + { rbegin(t) } -> std::same_as; + { rend(t) } -> std::same_as; + { crbegin(std::as_const(t)) } -> std::same_as; + { crend(std::as_const(t)) } -> std::same_as; +}; + +} // namespace morpheus::containers::concepts diff --git a/libraries/core/src/morpheus/core/containers/concepts/sequence.hpp b/libraries/core/src/morpheus/core/containers/concepts/sequence.hpp new file mode 100644 index 00000000..329cf5ae --- /dev/null +++ b/libraries/core/src/morpheus/core/containers/concepts/sequence.hpp @@ -0,0 +1,67 @@ +#pragma once + +#include "morpheus/core/containers/concepts/container.hpp" +#include "morpheus/core/conformance/ranges.hpp" +#include "morpheus/core/meta/is_array.hpp" +#include "morpheus/core/meta/is_string.hpp" + +#include +#include +#include +#include +#include + +namespace morpheus::containers::concepts +{ + +/// \concept Sequence +/// Concept capturing the requirements for a sequence container as outline in the standard at +/// [sequence.requirements], details at +/// SequenceContainer. +template +concept Sequence = Container && requires(T t, typename T::value_type v, typename T::size_type s, typename T::iterator i, std::initializer_list il){ + { T(s, v) }; + { T(i, i) }; +#if (__cpp_lib_containers_ranges >= 202202L) + { T(std::from_range, ranges::subrange{}) }; +#endif // (__cpp_lib_containers_ranges >= 202202L) + { T(il) }; + { t = il }; + { t.insert(i, v) } -> std::same_as; + { t.insert(i, std::move(v)) } -> std::same_as; + { t.insert(i, s, v) } -> std::same_as; + { t.insert(i, i, i) } -> std::same_as; +#if (__cpp_lib_containers_ranges >= 202202L) + { t.insert_range(i, ranges::subrange{}) } -> std::same_as; +#endif // (__cpp_lib_containers_ranges >= 202202L) + { t.insert(i, il) } -> std::same_as; + { t.erase(i) } -> std::same_as; + { t.erase(i, i) } -> std::same_as; + { t.clear() } -> std::same_as; + { t.assign(i, i) } -> std::same_as; +#if (__cpp_lib_containers_ranges >= 202202L) + { t.assign_range(ranges::subrange{}) } -> std::same_as; +#endif // (__cpp_lib_containers_ranges >= 202202L) + { t.assign(il) } -> std::same_as; + { t.assign(s, v) } -> std::same_as; +}; + +/// \concept StrictSequence +/// Concept strictly capturing the requirements for a sequence container as outline in the standard at +/// [sequence.requirements], details at +/// SequenceContainer. +/// The requirements [sequence.requirements] don't +/// actually match numerous types listed as sequence containers. This includes: +/// - std::string +/// - std::forward_list +/// - std::array +/// Hoever they are listed as as Sequence types while having interfaces that differ from the Sequence +/// container requirements so this extension concept exactly mirrors that requirement. +template +concept StrictSequence = meta::is_array_v || + meta::is_string_v || + std::same_as> || + Sequence; + + +} // namespace morpheus::containers::concepts diff --git a/libraries/core/src/morpheus/core/containers/concepts/unordered.hpp b/libraries/core/src/morpheus/core/containers/concepts/unordered.hpp new file mode 100644 index 00000000..10e790f8 --- /dev/null +++ b/libraries/core/src/morpheus/core/containers/concepts/unordered.hpp @@ -0,0 +1,85 @@ +#pragma once + +#include "morpheus/core/containers/concepts/detail/return_types.hpp" +#include "morpheus/core/containers/concepts/allocator_aware.hpp" +#include "morpheus/core/functional/concepts/hash.hpp" + +#include +#include + +namespace morpheus::containers::concepts +{ + +/// \concept Unordered +/// Concept capturing the requirements for an unordered associative container as outline in the standard at +/// [unord.req], details at +/// UnorderedAssociativeContainerr. +template +concept Unordered = AllocatorAware && requires(T t, typename T::value_type v, typename T::key_type k, typename T::size_type s, typename T::iterator i, + typename T::const_iterator ci, typename T::hasher h, typename T::key_equal e, typename T::local_iterator l, + typename T::node_type n, std::initializer_list il) +{ + requires functional::concepts::Hash; + requires (std::default_initializable) && (std::copy_constructible); + { T(s, h, e) }; + { T(s, h) }; + { T(s) }; + { T(i, i, s, h, e) }; + { T(i, i, s, h) }; + { T(i, i, s) }; + { T(i, i) }; +#if (__cpp_lib_containers_ranges >= 202202L) + { T(std::from_range, ranges::subrange{}, s, h, e) }; + { T(std::from_range, ranges::subrange{}, s, h) }; + { T(std::from_range, ranges::subrange{}, s) }; + { T(std::from_range, ranges::subrange{}) }; +#endif // (__cpp_lib_containers_ranges >= 202202L) + { T(il, s, h, e) }; + { T(il, s, h) }; + { T(il, s) }; + { T(il) }; + { t = il }; + { std::as_const(t).hash_function() } -> std::same_as; + { std::as_const(t).key_eq() } -> std::same_as; + { t.emplace() } -> detail::InsertReturnType; + { t.emplace_hint(i) } -> std::same_as; + { t.insert(v) } -> detail::InsertReturnType; + { t.insert(ci, v) } -> std::same_as; + { t.insert(i, i) } -> std::same_as; +#if (__cpp_lib_containers_ranges >= 202202L) + { t.insert_range(ranges::subrange{}) } -> std::same_as; +#endif // (__cpp_lib_containers_ranges >= 202202L) + { t.insert(il) } -> std::same_as; + { t.insert(std::move(n)) } -> detail::InsertNodeHandleReturnType; + { t.insert(ci, std::move(n)) } -> std::same_as; + { t.extract(k) } -> std::same_as; + { t.extract(ci) } -> std::same_as; + { t.merge(t) } -> std::same_as; + { t.erase(i) } -> std::same_as; + { t.erase(ci) } -> std::same_as; + { t.erase(i, i) } -> std::same_as; + { t.erase(ci, ci) } -> std::same_as; + { t.erase(k) } -> std::same_as; + { t.clear() } -> std::same_as; + { t.find(k) } -> std::same_as; + { std::as_const(t).find(k) } -> std::same_as; + { std::as_const(t).count(k) } -> std::same_as; + { std::as_const(t).contains(k) } -> std::same_as; + { t.equal_range(k) } -> detail::BoundReturnType; + { std::as_const(t).equal_range(k) } -> detail::BoundConstReturnType; + { std::as_const(t).bucket_count() } -> std::same_as; + { std::as_const(t).max_bucket_count() } -> std::same_as; + { std::as_const(t).bucket(s) } -> std::same_as; + { std::as_const(t).bucket_size(s) } -> std::same_as; + { t.begin(s) } -> std::same_as; + { std::as_const(t).begin(s) } -> std::same_as; + { t.end(s) } -> std::same_as; + { std::as_const(t).end(s) } -> std::same_as; + { std::as_const(t).load_factor() } -> std::same_as; + { std::as_const(t).max_load_factor() } -> std::same_as; + { t.max_load_factor(float{}) } -> std::same_as; + { t.rehash(s) } -> std::same_as; + { t.reserve(s) } -> std::same_as; +}; + +} // namespace morpheus::containers::concepts diff --git a/libraries/core/src/morpheus/core/functional/CMakeLists.txt b/libraries/core/src/morpheus/core/functional/CMakeLists.txt index 60a3a78e..e97113ec 100644 --- a/libraries/core/src/morpheus/core/functional/CMakeLists.txt +++ b/libraries/core/src/morpheus/core/functional/CMakeLists.txt @@ -1,3 +1,5 @@ +add_subdirectory(concepts) + target_sources(MorpheusCore PUBLIC function_ref.hpp diff --git a/libraries/core/src/morpheus/core/functional/concepts/CMakeLists.txt b/libraries/core/src/morpheus/core/functional/concepts/CMakeLists.txt new file mode 100644 index 00000000..b80bb2ab --- /dev/null +++ b/libraries/core/src/morpheus/core/functional/concepts/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(MorpheusCore + PUBLIC + function.hpp + hash.hpp +) diff --git a/libraries/core/src/morpheus/core/functional/concepts/function.hpp b/libraries/core/src/morpheus/core/functional/concepts/function.hpp new file mode 100644 index 00000000..3acd29f3 --- /dev/null +++ b/libraries/core/src/morpheus/core/functional/concepts/function.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +namespace morpheus::functional::concepts +{ + +/// \concept Function +/// Concept capturing the requirements for a function object, a named requirement outlined in the standard at +/// [func.require], details at +/// FunctionObject. +template +concept Function = requires(T t){ + requires std::is_object_v; + requires std::invocable; +}; + +} // namespace morpheus::functional::concepts diff --git a/libraries/core/src/morpheus/core/functional/concepts/hash.hpp b/libraries/core/src/morpheus/core/functional/concepts/hash.hpp new file mode 100644 index 00000000..ac43f2e4 --- /dev/null +++ b/libraries/core/src/morpheus/core/functional/concepts/hash.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "morpheus/core/functional/concepts/function.hpp" + +#include + +namespace morpheus::functional::concepts +{ + +/// \concept Hash +/// Concept capturing the requirements for a hash, a named requirement outlined in the standard at +/// [hash.requirements], details at +/// Hash. +template +concept Hash = requires(T t){ + requires std::copy_constructible; + requires std::destructible; + requires Function; +}; + +} // namespace morpheus::functional::concepts diff --git a/libraries/core/src/morpheus/core/memory/concepts/allocator.hpp b/libraries/core/src/morpheus/core/memory/concepts/allocator.hpp index 67e22548..a744bb17 100644 --- a/libraries/core/src/morpheus/core/memory/concepts/allocator.hpp +++ b/libraries/core/src/morpheus/core/memory/concepts/allocator.hpp @@ -16,22 +16,30 @@ namespace morpheus::memory::concepts /// \concept Allocator /// Concept capturing the requirements for an allocator as outline in the standard at /// [allocator.requirements]. - +/// \par +/// Allocators provide a number of services: +/// - Perform allocation, construction, destruction and deallocation. +/// - Seperate allocation from construction, +/// - Seperate deallocation from destruction. +/// - Encapsulate information about the allocation strategy. +/// - Encapsulate information about the addressing model. +/// - Hide memory management and addressing model details from users. +/// - Support the reuse of an allocation strategy across allocation users. /// \note /// https://rawgit.com/google/cxx-std-draft/allocator-paper/allocator_user_guide.html#reqs template