From c946f3edb7724b29c513e0cf50029f0ffea9f583 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Tue, 24 Jan 2017 14:32:17 -0800 Subject: [PATCH] rework a bunch of the *tructible concepts, Movable requires object types --- include/stl2/detail/concepts/core.hpp | 2 +- .../detail/concepts/object/assignable.hpp | 11 +- .../stl2/detail/concepts/object/movable.hpp | 5 +- .../concepts/object/move_constructible.hpp | 123 ++++-------------- include/stl2/detail/ebo_box.hpp | 3 +- .../stl2/detail/iterator/basic_iterator.hpp | 1 + include/stl2/detail/semiregular_box.hpp | 3 +- include/stl2/detail/temporary_vector.hpp | 4 +- include/stl2/optional.hpp | 4 +- test/concepts/object.cpp | 71 +++------- test/optional.cpp | 6 +- 11 files changed, 67 insertions(+), 166 deletions(-) diff --git a/include/stl2/detail/concepts/core.hpp b/include/stl2/detail/concepts/core.hpp index bc0485c29..afc227cd7 100644 --- a/include/stl2/detail/concepts/core.hpp +++ b/include/stl2/detail/concepts/core.hpp @@ -27,7 +27,7 @@ STL2_OPEN_NAMESPACE { concept bool _Is = _Valid && T::value; template class T, class...V> - concept bool _IsNot = !_Is; + concept bool _IsNot = _Valid && !T::value; // U is a cv/ref-qualified specialization of class template T. template class T> diff --git a/include/stl2/detail/concepts/object/assignable.hpp b/include/stl2/detail/concepts/object/assignable.hpp index 2ed829b5c..254a223b9 100644 --- a/include/stl2/detail/concepts/object/assignable.hpp +++ b/include/stl2/detail/concepts/object/assignable.hpp @@ -22,18 +22,21 @@ STL2_OPEN_NAMESPACE { /////////////////////////////////////////////////////////////////////////// // Assignable [concepts.lib.corelang.assignable] // + // Not to spec + // See https://github.com/ericniebler/stl2/issues/229 template constexpr bool __assignable = false; template requires - requires(T&& t, U&& u) { - STL2_EXACT_TYPE_CONSTRAINT((T&&)t = (U&&)u, T&); + requires(T& t, U&& u) { + STL2_EXACT_TYPE_CONSTRAINT(t = (U&&)u, T&); } - constexpr bool __assignable = true; + constexpr bool __assignable = true; template concept bool Assignable() { - return CommonReference() && + return Same&>() && + CommonReference() && __assignable; } diff --git a/include/stl2/detail/concepts/object/movable.hpp b/include/stl2/detail/concepts/object/movable.hpp index 469ed59bc..695c9a890 100644 --- a/include/stl2/detail/concepts/object/movable.hpp +++ b/include/stl2/detail/concepts/object/movable.hpp @@ -22,9 +22,12 @@ STL2_OPEN_NAMESPACE { /////////////////////////////////////////////////////////////////////////// // Movable [concepts.lib.object.movable] // + // Not to spec + // https://github.com/ericniebler/stl2/issues/310 template concept bool Movable() { - return MoveConstructible() && + return _Is && + MoveConstructible() && Assignable() && Swappable(); } diff --git a/include/stl2/detail/concepts/object/move_constructible.hpp b/include/stl2/detail/concepts/object/move_constructible.hpp index c13a393a5..68b859dc1 100644 --- a/include/stl2/detail/concepts/object/move_constructible.hpp +++ b/include/stl2/detail/concepts/object/move_constructible.hpp @@ -24,6 +24,10 @@ STL2_OPEN_NAMESPACE { // template constexpr bool __addressable = false; + template + constexpr bool __addressable = true; + template + constexpr bool __addressable = true; template requires requires(T& t, const T& ct) { STL2_EXACT_TYPE_CONSTRAINT(&t, T*); @@ -35,7 +39,7 @@ STL2_OPEN_NAMESPACE { namespace ext { template concept bool Addressable() { - return __addressable; + return _Is && __addressable; } } @@ -46,122 +50,43 @@ STL2_OPEN_NAMESPACE { constexpr bool Addressable = true; } - namespace detail { - template - constexpr bool is_complete_object = false; - - template <_Is T> - requires - sizeof(T) > 0 - constexpr bool is_complete_object = true; - - template - constexpr bool MustBeComplete() { - static_assert(is_complete_object, "Concept check for incomplete type T."); - return true; - } - } - /////////////////////////////////////////////////////////////////////////// // Destructible [concepts.lib.object.destructible] - // Not to spec: is_object and accepting the parameters by reference are - // necessary to prevent hard errors in the requires clause - // with odd types. - // - template - constexpr bool __destructible = false; - template - requires _Is && - _IsNot && - detail::MustBeComplete() && - requires(T& t, T* const p) { - { t.~T() } noexcept; - delete p; - delete[] p; - } - constexpr bool __destructible = true; + // Not to spec + // https://github.com/ericniebler/stl2/issues/301 + namespace models { + template + constexpr bool Destructible = is_nothrow_destructible::value && __addressable; + } template concept bool Destructible() { - return ext::Addressable() && __destructible; - } - - namespace models { - template - constexpr bool Destructible = false; - __stl2::Destructible{T} - constexpr bool Destructible = true; + return models::Destructible; } /////////////////////////////////////////////////////////////////////////// // Constructible [concepts.lib.object.constructible] - // Extension: ConstructibleObject and BindableReference are user-visible. - // - namespace ext { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Waddress" - template - constexpr bool __constructible_object = false; - template - requires requires(Args&&...args) { - T{ (Args&&)args... }; - new T{ (Args&&)args... }; - } - constexpr bool __constructible_object = true; - - template - concept bool ConstructibleObject = - Destructible() && __constructible_object; -#pragma GCC diagnostic pop - - // 20150718: Not to spec: spec is broken. - // FIXME: Correct wording. - template - concept bool BindableReference = - _Is && - // requires(Args&&...args) { T{ (Args&&)args... }; }; - // requires(Args&&...args) { T( (Args&&)args... ); }; - _Is; + // Not to spec + // See https://github.com/ericniebler/stl2/issues/301 + template + concept bool Constructible() { + return Destructible() && _Is; } namespace models { - template - constexpr bool ConstructibleObject = false; - __stl2::ext::ConstructibleObject{T, ...Args} - constexpr bool ConstructibleObject = true; - - template - constexpr bool BindableReference = false; - __stl2::ext::BindableReference{T, ...Args} - constexpr bool BindableReference = true; - - template - constexpr bool Constructible = - ConstructibleObject || - BindableReference; - } - - template - concept bool Constructible() { - return models::Constructible; + template + constexpr bool Constructible = false; + __stl2::Constructible{T, ...Args} + constexpr bool Constructible = true; } /////////////////////////////////////////////////////////////////////////// // DefaultConstructible [concepts.lib.object.defaultconstructible] - // Note: Due to implementation variance around DR1518, may not correctly - // enforce the requirement that the default constructor be non-explicit. - // - template - constexpr bool __default_constructible = false; - template - requires requires(const std::size_t n) { - new T[n]{}; // not required to be equality preserving - } - constexpr bool __default_constructible = true; - + // Not to spec + // https://github.com/ericniebler/stl2/issues/301 template concept bool DefaultConstructible() { - return Constructible() && __default_constructible; + return Constructible(); } namespace models { diff --git a/include/stl2/detail/ebo_box.hpp b/include/stl2/detail/ebo_box.hpp index 3750ad779..44b8e100c 100644 --- a/include/stl2/detail/ebo_box.hpp +++ b/include/stl2/detail/ebo_box.hpp @@ -24,6 +24,7 @@ STL2_OPEN_NAMESPACE { is_class::value && !is_final::value; template + requires _Is class ebo_box { public: ebo_box() requires DefaultConstructible() = default; @@ -54,7 +55,7 @@ STL2_OPEN_NAMESPACE { }; template - requires __non_final_class + requires _Is && __non_final_class class ebo_box : private T { public: using T::T; diff --git a/include/stl2/detail/iterator/basic_iterator.hpp b/include/stl2/detail/iterator/basic_iterator.hpp index a84d0ce98..c86a1640e 100644 --- a/include/stl2/detail/iterator/basic_iterator.hpp +++ b/include/stl2/detail/iterator/basic_iterator.hpp @@ -31,6 +31,7 @@ STL2_OPEN_NAMESPACE { template + requires _Is class basic_mixin : protected detail::ebo_box> { using box_t = detail::ebo_box>; public: diff --git a/include/stl2/detail/semiregular_box.hpp b/include/stl2/detail/semiregular_box.hpp index 3631961cc..8244e6fa2 100644 --- a/include/stl2/detail/semiregular_box.hpp +++ b/include/stl2/detail/semiregular_box.hpp @@ -20,7 +20,8 @@ STL2_OPEN_NAMESPACE { namespace detail { - Destructible{T} + template + requires _Is class semiregular_box { public: semiregular_box() = default; diff --git a/include/stl2/detail/temporary_vector.hpp b/include/stl2/detail/temporary_vector.hpp index af25bc558..95c23d5f4 100644 --- a/include/stl2/detail/temporary_vector.hpp +++ b/include/stl2/detail/temporary_vector.hpp @@ -90,6 +90,7 @@ STL2_OPEN_NAMESPACE { }; template + requires _Is class temporary_vector { T* begin_ = nullptr; T* end_ = nullptr; @@ -159,7 +160,8 @@ STL2_OPEN_NAMESPACE { { emplace_back(__stl2::move(t)); } }; - Destructible{T} + template + requires _Is temporary_vector make_temporary_vector(temporary_buffer& buf) { return {buf}; } diff --git a/include/stl2/optional.hpp b/include/stl2/optional.hpp index 9fddebf42..289664632 100644 --- a/include/stl2/optional.hpp +++ b/include/stl2/optional.hpp @@ -46,7 +46,7 @@ STL2_OPEN_NAMESPACE { }; template - requires models::Destructible + requires models::Destructible && _Is class optional; namespace __optional { @@ -233,7 +233,7 @@ STL2_OPEN_NAMESPACE { } template - requires models::Destructible + requires models::Destructible && _Is class optional : public meta::_t> , detail::smf_control::copy> diff --git a/test/concepts/object.cpp b/test/concepts/object.cpp index a49346e58..fe70a8de1 100644 --- a/test/concepts/object.cpp +++ b/test/concepts/object.cpp @@ -16,14 +16,6 @@ namespace models { template constexpr bool Destructible = ranges::Destructible(); -template -constexpr bool ConstructibleObject = - ranges::concepts::models(); - -template -constexpr bool BindableReference = - ranges::concepts::models(); - template constexpr bool Constructible = ranges::Constructible(); @@ -82,6 +74,10 @@ struct indestructible { ~indestructible() = delete; }; +struct throwing_destructor { + ~throwing_destructor() noexcept(false); +}; + struct explicit_default { explicit explicit_default() {} }; @@ -133,17 +129,19 @@ struct XXX CONCEPT_ASSERT(models::Destructible); CONCEPT_ASSERT(models::Destructible); CONCEPT_ASSERT(!models::Destructible); -CONCEPT_ASSERT(!models::Destructible); +CONCEPT_ASSERT(models::Destructible); CONCEPT_ASSERT(!models::Destructible); CONCEPT_ASSERT(models::Destructible); -CONCEPT_ASSERT(!models::Destructible); +CONCEPT_ASSERT(models::Destructible); CONCEPT_ASSERT(!models::Destructible); -CONCEPT_ASSERT(!models::Destructible); +CONCEPT_ASSERT(models::Destructible); CONCEPT_ASSERT(models::Destructible); -CONCEPT_ASSERT(!models::Destructible); +CONCEPT_ASSERT(!models::Addressable); +CONCEPT_ASSERT(models::Destructible); CONCEPT_ASSERT(models::Destructible); CONCEPT_ASSERT(models::Destructible); CONCEPT_ASSERT(!models::Destructible); +CONCEPT_ASSERT(!models::Destructible); #if 0 // ill-formed (hard error) @@ -162,17 +160,11 @@ CONCEPT_ASSERT(!models::Constructible); CONCEPT_ASSERT(!models::Constructible); CONCEPT_ASSERT(!models::Constructible); CONCEPT_ASSERT(!models::Constructible); -CONCEPT_ASSERT(!models::Constructible); +CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(!models::Constructible); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(!models::Constructible); -CONCEPT_ASSERT(models::ConstructibleObject); -CONCEPT_ASSERT(models::ConstructibleObject); -CONCEPT_ASSERT(models::ConstructibleObject); -CONCEPT_ASSERT(models::ConstructibleObject); -CONCEPT_ASSERT(models::ConstructibleObject); -CONCEPT_ASSERT(models::ConstructibleObject); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::Constructible); @@ -180,12 +172,6 @@ CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::Constructible); -CONCEPT_ASSERT(models::ConstructibleObject); -CONCEPT_ASSERT(models::ConstructibleObject); -CONCEPT_ASSERT(models::ConstructibleObject); -CONCEPT_ASSERT(models::ConstructibleObject); -CONCEPT_ASSERT(models::ConstructibleObject); -CONCEPT_ASSERT(models::ConstructibleObject); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::Constructible); @@ -193,12 +179,6 @@ CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::Constructible); -CONCEPT_ASSERT(!models::BindableReference); -CONCEPT_ASSERT(models::BindableReference); -CONCEPT_ASSERT(!models::BindableReference); -CONCEPT_ASSERT(!models::BindableReference); -CONCEPT_ASSERT(!models::BindableReference); -CONCEPT_ASSERT(!models::BindableReference); CONCEPT_ASSERT(!models::Constructible); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(!models::Constructible); @@ -206,12 +186,6 @@ CONCEPT_ASSERT(!models::Constructible); CONCEPT_ASSERT(!models::Constructible); CONCEPT_ASSERT(!models::Constructible); -CONCEPT_ASSERT(models::BindableReference); -CONCEPT_ASSERT(models::BindableReference); -CONCEPT_ASSERT(models::BindableReference); -CONCEPT_ASSERT(models::BindableReference); -CONCEPT_ASSERT(models::BindableReference); -CONCEPT_ASSERT(models::BindableReference); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::Constructible); @@ -219,12 +193,6 @@ CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::Constructible); -CONCEPT_ASSERT(models::BindableReference); -CONCEPT_ASSERT(!models::BindableReference); -CONCEPT_ASSERT(models::BindableReference); -CONCEPT_ASSERT(!models::BindableReference); -CONCEPT_ASSERT(!models::BindableReference); -CONCEPT_ASSERT(!models::BindableReference); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(!models::Constructible); CONCEPT_ASSERT(models::Constructible); @@ -232,12 +200,6 @@ CONCEPT_ASSERT(!models::Constructible); CONCEPT_ASSERT(!models::Constructible); CONCEPT_ASSERT(!models::Constructible); -CONCEPT_ASSERT(models::BindableReference); -CONCEPT_ASSERT(!models::BindableReference); -CONCEPT_ASSERT(models::BindableReference); -CONCEPT_ASSERT(models::BindableReference); -CONCEPT_ASSERT(!models::BindableReference); -CONCEPT_ASSERT(models::BindableReference); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(!models::Constructible); CONCEPT_ASSERT(models::Constructible); @@ -256,7 +218,7 @@ CONCEPT_ASSERT(!models::DefaultConstructible); CONCEPT_ASSERT(models::DefaultConstructible); CONCEPT_ASSERT(!models::DefaultConstructible); CONCEPT_ASSERT(!models::DefaultConstructible); -CONCEPT_ASSERT(!models::DefaultConstructible); +CONCEPT_ASSERT(models::DefaultConstructible); CONCEPT_ASSERT(!models::DefaultConstructible); // It's hard to catch explicit default constructors, see @@ -275,7 +237,6 @@ CONCEPT_ASSERT(models::MoveConstructible); CONCEPT_ASSERT(models::MoveConstructible); CONCEPT_ASSERT(models::MoveConstructible); -CONCEPT_ASSERT(models::ConstructibleObject); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::MoveConstructible); CONCEPT_ASSERT(models::MoveConstructible); @@ -354,12 +315,16 @@ CONCEPT_ASSERT(!models::Regular); CONCEPT_ASSERT(!models::Regular); CONCEPT_ASSERT(!models::Regular); -CONCEPT_ASSERT(models::ConstructibleObject>); CONCEPT_ASSERT(models::Constructible>); CONCEPT_ASSERT(models::DefaultConstructible>); -CONCEPT_ASSERT(models::ConstructibleObject); CONCEPT_ASSERT(models::Constructible); CONCEPT_ASSERT(models::DefaultConstructible); +// https://github.com/ericniebler/stl2/issues/301 +CONCEPT_ASSERT(!models::Constructible); + +// https://github.com/ericniebler/stl2/issues/310 +CONCEPT_ASSERT(!models::Movable); + int main() {} diff --git a/test/optional.cpp b/test/optional.cpp index 147518360..fb81fa8f0 100644 --- a/test/optional.cpp +++ b/test/optional.cpp @@ -226,11 +226,11 @@ int main() { static_assert(models::Constructible); static_assert(models::ConvertibleTo); - static_assert(!models::ConvertibleTo); - static_assert(!models::Constructible); + static_assert(models::ConvertibleTo); + static_assert(models::Constructible); static_assert(models::ConvertibleTo); - static_assert(!models::Constructible); // narrowing + static_assert(models::Constructible); static_assert(!models::Swappable); }