Skip to content

Commit

Permalink
Implement extension 'structible object concepts
Browse files Browse the repository at this point in the history
  • Loading branch information
CaseyCarter committed Jul 2, 2017
1 parent ae6fc47 commit 6625e7d
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 35 deletions.
18 changes: 18 additions & 0 deletions include/stl2/detail/concepts/object.hpp
Expand Up @@ -54,6 +54,24 @@ STL2_OPEN_NAMESPACE {


namespace ext {
///////////////////////////////////////////////////////////////////////////
// 'structible object concepts
//
template <class T>
concept bool DestructibleObject = Object<T> && Destructible<T>;

template <class T, class... Args>
concept bool ConstructibleObject = Object<T> && Constructible<T, Args...>;

template <class T>
concept bool DefaultConstructibleObject = Object<T> && DefaultConstructible<T>;

template <class T>
concept bool MoveConstructibleObject = Object<T> && MoveConstructible<T>;

template <class T>
concept bool CopyConstructibleObject = Object<T> && CopyConstructible<T>;

///////////////////////////////////////////////////////////////////////////
// TriviallyFoo concepts
//
Expand Down
4 changes: 2 additions & 2 deletions include/stl2/detail/concepts/object/movable.hpp
Expand Up @@ -26,7 +26,7 @@ STL2_OPEN_NAMESPACE {
// https://github.com/ericniebler/stl2/issues/310
template <class T>
concept bool Movable =
_Is<T, is_object> &&
ext::Object<T> &&
MoveConstructible<T> &&
Assignable<T&, T&&> &&
Swappable<T>;
Expand All @@ -36,7 +36,7 @@ STL2_OPEN_NAMESPACE {
constexpr bool Movable = false;
__stl2::Movable{T}
constexpr bool Movable<T> = true;
}
} // namespace models
} STL2_CLOSE_NAMESPACE

#endif
17 changes: 16 additions & 1 deletion include/stl2/detail/concepts/object/move_constructible.hpp
Expand Up @@ -19,6 +19,21 @@
#include <stl2/detail/concepts/core.hpp>

STL2_OPEN_NAMESPACE {
///////////////////////////////////////////////////////////////////////////
// Object [Extension]
//
namespace ext {
template <class T>
concept bool Object = _Is<T, std::is_object>;
} // namespace ext

namespace models {
template <class>
constexpr bool Object = false;
__stl2::ext::Object{T}
constexpr bool Object<T> = true;
} // namespace models

///////////////////////////////////////////////////////////////////////////
// Addressable [Extension]
//
Expand All @@ -34,7 +49,7 @@ STL2_OPEN_NAMESPACE {
namespace ext {
template <class T>
concept bool Addressable =
_Is<T, is_object> && __addressable<T>;
Object<T> && __addressable<T>;
}

namespace models {
Expand Down
8 changes: 3 additions & 5 deletions include/stl2/detail/ebo_box.hpp
Expand Up @@ -19,8 +19,7 @@

STL2_OPEN_NAMESPACE {
namespace detail {
template <Destructible T, class Tag = void>
requires std::is_object<T>::value
template <ext::DestructibleObject T, class Tag = void>
struct ebo_box {
ebo_box() = default;
constexpr ebo_box(const T& t)
Expand Down Expand Up @@ -58,9 +57,8 @@ STL2_OPEN_NAMESPACE {
T item_;
};

template <Destructible T, class Tag>
requires std::is_object<T>::value &&
std::is_empty<T>::value && !std::is_final<T>::value
template <ext::DestructibleObject T, class Tag>
requires std::is_empty<T>::value && !std::is_final<T>::value
struct ebo_box<T, Tag> : private T {
ebo_box() = default;
constexpr ebo_box(const T& t)
Expand Down
5 changes: 3 additions & 2 deletions include/stl2/detail/functional/invoke.hpp
Expand Up @@ -15,6 +15,7 @@
#include <stl2/detail/fwd.hpp>
#include <stl2/detail/meta.hpp>
#include <stl2/detail/concepts/core.hpp>
#include <stl2/detail/concepts/object.hpp>

STL2_OPEN_NAMESPACE {
///////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -61,10 +62,10 @@ STL2_OPEN_NAMESPACE {
(coerce<T>(std::forward<T1>(t1)).*f)(std::forward<Args>(args)...)
)

template <_Is<is_object> D, class T, class T1>
template <ext::Object D, class T, class T1>
constexpr decltype(auto) impl(D (T::*f), T1&& t1) = delete;

template <_Is<is_object> D, class T, class T1>
template <ext::Object D, class T, class T1>
requires
requires(D (T::*f), T1&& t1) {
coerce<T>(std::forward<T1>(t1)).*f;
Expand Down
17 changes: 13 additions & 4 deletions include/stl2/detail/iterator/concepts.hpp
Expand Up @@ -124,9 +124,10 @@ STL2_OPEN_NAMESPACE {
template <class>
struct value_type {};

template <class T>
struct value_type<T*> :
meta::lazy::if_<is_object<T>, remove_cv_t<T>> {};
template <ext::Object T>
struct value_type<T*> {
using type = std::remove_cv_t<T>;
};

template <_Is<is_array> T>
struct value_type<T> : value_type<decay_t<T>> {};
Expand All @@ -135,13 +136,21 @@ STL2_OPEN_NAMESPACE {
struct value_type<I const> : value_type<decay_t<I>> {};

template <detail::MemberValueType T>
struct value_type<T> {};

template <detail::MemberValueType T>
requires ext::Object<typename T::value_type>
struct value_type<T> {
using type = typename T::value_type;
};

template <detail::MemberElementType T>
struct value_type<T> {};

template <detail::MemberElementType T>
requires ext::Object<std::remove_cv_t<typename T::element_type>>
struct value_type<T> {
using type = typename T::element_type;
using type = std::remove_cv_t<typename T::element_type>;
};

///////////////////////////////////////////////////////////////////////////
Expand Down
7 changes: 4 additions & 3 deletions include/stl2/detail/iterator/increment.hpp
Expand Up @@ -38,9 +38,10 @@ STL2_OPEN_NAMESPACE {

template <class> struct difference_type {};

template <class T>
struct difference_type<T*>
: meta::lazy::if_<std::is_object<T>, std::ptrdiff_t> {};
template <ext::Object T>
struct difference_type<T*> {
using type = std::ptrdiff_t;
};

template <class T>
struct difference_type<const T>
Expand Down
3 changes: 1 addition & 2 deletions include/stl2/detail/semiregular_box.hpp
Expand Up @@ -20,8 +20,7 @@

STL2_OPEN_NAMESPACE {
namespace detail {
template <Destructible T>
requires _Is<T, is_object>
template <ext::DestructibleObject T>
class semiregular_box {
public:
semiregular_box() = default;
Expand Down
15 changes: 7 additions & 8 deletions include/stl2/detail/temporary_vector.hpp
Expand Up @@ -89,8 +89,7 @@ STL2_OPEN_NAMESPACE {
}
};

template <Destructible T>
requires _Is<T, is_object>
template <ext::DestructibleObject T>
class temporary_vector {
T* begin_ = nullptr;
T* end_ = nullptr;
Expand All @@ -108,9 +107,10 @@ STL2_OPEN_NAMESPACE {
}

temporary_vector() = default;
temporary_vector(temporary_buffer<T>& buf)
explicit temporary_vector(temporary_buffer<T>& buf)
: begin_{buf.data()}, end_{begin_}
, alloc_{begin_ + buf.size_} {}
, alloc_{begin_ + buf.size_}
{}
temporary_vector(temporary_vector&&) = delete;
temporary_vector& operator=(temporary_vector&& that) = delete;

Expand Down Expand Up @@ -160,10 +160,9 @@ STL2_OPEN_NAMESPACE {
{ emplace_back(__stl2::move(t)); }
};

template <Destructible T>
requires _Is<T, is_object>
temporary_vector<T> make_temporary_vector(temporary_buffer<T>& buf) {
return {buf};
ext::DestructibleObject{T}
auto make_temporary_vector(temporary_buffer<T>& buf) {
return temporary_vector<T>{buf};
}
}
} STL2_CLOSE_NAMESPACE
Expand Down
7 changes: 2 additions & 5 deletions include/stl2/optional.hpp
Expand Up @@ -50,9 +50,7 @@ STL2_OPEN_NAMESPACE {
: logic_error{"Attempt to access disengaged optional"} {}
};

template <class T>
requires Destructible<T> && _Is<T, is_object>
class optional;
ext::DestructibleObject{T} class optional;

namespace __optional {
template <class = void>
Expand Down Expand Up @@ -238,8 +236,7 @@ STL2_OPEN_NAMESPACE {
};
} // namespace ext

template <class T>
requires Destructible<T> && _Is<T, is_object>
ext::DestructibleObject{T}
class optional
: public meta::_t<ext::optional_storage<T>>
, detail::smf_control::copy<models::CopyConstructible<T>>
Expand Down
9 changes: 6 additions & 3 deletions test/iterator/basic_iterator.cpp
Expand Up @@ -190,40 +190,43 @@ struct always_cursor {
template <class T, T Value>
using always_iterator = stl2::basic_iterator<always_cursor<T, Value>>;

template <class T>
requires stl2::is_object<T>::value
template <stl2::ext::Object T>
struct proxy_wrapper {
stl2::detail::raw_ptr<T> ptr_ = nullptr;

proxy_wrapper() = default;
proxy_wrapper(T& t) noexcept : ptr_{stl2::addressof(t)} {}
proxy_wrapper(T&&) = delete;
proxy_wrapper(T&&) = delete; // LWG 2993?

T& get() const noexcept { return *ptr_; }

proxy_wrapper& operator=(const T& t)
noexcept(std::is_nothrow_copy_assignable<T>::value)
requires stl2::CopyConstructible<T>
{
get() = t;
return *this;
}

proxy_wrapper& operator=(T&& t)
noexcept(std::is_nothrow_move_assignable<T>::value)
requires stl2::MoveConstructible<T>
{
get() = stl2::move(t);
return *this;
}

proxy_wrapper const& operator=(const T& t) const
noexcept(std::is_nothrow_copy_assignable<T>::value)
requires stl2::Copyable<T>
{
get() = t;
return *this;
}

proxy_wrapper const& operator=(T&& t) const
noexcept(std::is_nothrow_move_assignable<T>::value)
requires stl2::Movable<T>
{
get() = stl2::move(t);
return *this;
Expand Down

0 comments on commit 6625e7d

Please sign in to comment.