diff --git a/sprout/optional.hpp b/sprout/optional.hpp index bf137694..f832d0a8 100644 --- a/sprout/optional.hpp +++ b/sprout/optional.hpp @@ -9,5 +9,6 @@ #include #include #include +#include #endif // #ifndef SPROUT_OPTIONAL_HPP diff --git a/sprout/optional/exceptions.hpp b/sprout/optional/exceptions.hpp new file mode 100644 index 00000000..3dcb40f7 --- /dev/null +++ b/sprout/optional/exceptions.hpp @@ -0,0 +1,25 @@ +#ifndef SPROUT_OPTIONAL_EXCEPTIONS_HPP +#define SPROUT_OPTIONAL_EXCEPTIONS_HPP + +#include +#include +#include + +namespace sprout { + // + // bad_optional_access + // + class bad_optional_access + : public std::logic_error + { + public: + explicit bad_optional_access(std::string const& what_arg) + : std::logic_error(what_arg) + {} + explicit bad_optional_access(char const* what_arg) + : std::logic_error(what_arg) + {} + }; +} // namespace sprout + +#endif // SPROUT_OPTIONAL_EXCEPTIONS_HPP diff --git a/sprout/optional/optional.hpp b/sprout/optional/optional.hpp index 7420b2e8..d2b061af 100644 --- a/sprout/optional/optional.hpp +++ b/sprout/optional/optional.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace sprout { @@ -53,12 +54,12 @@ namespace sprout { {} SPROUT_CONSTEXPR optional(optional const& v) : init(v.init) - , val(v.val) + , val(v.is_initialized() ? holder_type(*v) : holder_type()) {} template explicit SPROUT_CONSTEXPR optional(optional const& v) : init(v.is_initialized()) - , val(v.is_initialized() ? v.get() : holder_type()) + , val(v.is_initialized() ? holder_type(*v) : holder_type()) {} optional& operator=(sprout::nullopt_t v) SPROUT_NOEXCEPT { @@ -114,21 +115,25 @@ namespace sprout { } SPROUT_CONSTEXPR reference_const_type operator*() const { - return get(); - } - reference_type operator*() { - return get(); - } - SPROUT_CONSTEXPR reference_const_type get() const { return (SPROUT_ASSERT(is_initialized()), true) ? val.get() : val.get() ; } - reference_type get() { + reference_type operator*() { return (SPROUT_ASSERT(is_initialized()), true) ? val.get() : val.get() ; } + SPROUT_CONSTEXPR reference_const_type get() const { + return is_initialized() ? val.get() + : (throw sprout::bad_optional_access("optional<>: bad optional access"), val.get()) + ; + } + reference_type get() { + return is_initialized() ? val.get() + : (throw sprout::bad_optional_access("optional<>: bad optional access"), val.get()) + ; + } SPROUT_CONSTEXPR reference_const_type get_value_or(reference_const_type& v) const { return is_initialized() ? val.get() : v @@ -140,6 +145,19 @@ namespace sprout { ; } + SPROUT_CONSTEXPR reference_const_type value() const { + return get(); + } + reference_type value() { + return get(); + } + SPROUT_CONSTEXPR reference_const_type value_or(reference_const_type& v) const { + return get_value_or(v); + } + reference_type value_or(reference_type& v) { + return get_value_or(v); + } + SPROUT_CONSTEXPR pointer_const_type operator->() const { return SPROUT_ASSERT(is_initialized()), val.get_pointer() @@ -151,13 +169,13 @@ namespace sprout { ; } SPROUT_CONSTEXPR pointer_const_type get_pointer() const { - return SPROUT_ASSERT(is_initialized()), - val.get_pointer() + return is_initialized() ? val.get_pointer() + : 0 ; } pointer_type get_pointer() { - return SPROUT_ASSERT(is_initialized()), - val.get_pointer() + return is_initialized() ? val.get_pointer() + : 0 ; } SPROUT_CONSTEXPR pointer_const_type get_ptr() const { diff --git a/sprout/tuple/tuple/flexibly_construct.hpp b/sprout/tuple/flexibly_construct.hpp similarity index 68% rename from sprout/tuple/tuple/flexibly_construct.hpp rename to sprout/tuple/flexibly_construct.hpp index 7ebffbf4..2a71fc5b 100644 --- a/sprout/tuple/tuple/flexibly_construct.hpp +++ b/sprout/tuple/flexibly_construct.hpp @@ -1,5 +1,5 @@ -#ifndef SPROUT_TUPLE_TUPLE_FREXIBLY_CONSTRUCT_HPP -#define SPROUT_TUPLE_TUPLE_FREXIBLY_CONSTRUCT_HPP +#ifndef SPROUT_TUPLE_FREXIBLY_CONSTRUCT_HPP +#define SPROUT_TUPLE_FREXIBLY_CONSTRUCT_HPP #include @@ -17,4 +17,4 @@ namespace sprout { using sprout::tuples::flexibly_construct; } // namespace sprout -#endif // #ifndef SPROUT_TUPLE_TUPLE_FREXIBLY_CONSTRUCT_HPP +#endif // #ifndef SPROUT_TUPLE_FREXIBLY_CONSTRUCT_HPP diff --git a/sprout/tuple/tuple.hpp b/sprout/tuple/tuple.hpp index 448fb9f2..32363633 100644 --- a/sprout/tuple/tuple.hpp +++ b/sprout/tuple/tuple.hpp @@ -11,6 +11,6 @@ #include #include #include -#include +#include #endif // #ifndef SPROUT_TUPLE_TUPLE_HPP diff --git a/sprout/tuple/tuple/tuple.hpp b/sprout/tuple/tuple/tuple.hpp index 15e7841d..814f02b4 100644 --- a/sprout/tuple/tuple/tuple.hpp +++ b/sprout/tuple/tuple/tuple.hpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include namespace sprout { namespace tuples { @@ -71,6 +71,7 @@ namespace sprout { inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::pair&& t) : impl_type(sprout::forward::first_type>(t.first), sprout::forward::second_type>(t.second)) {} + template template< typename... UTypes, diff --git a/sprout/tuple/tuple/tuple_decl.hpp b/sprout/tuple/tuple/tuple_decl.hpp index 8ef46639..a0bcaaf2 100644 --- a/sprout/tuple/tuple/tuple_decl.hpp +++ b/sprout/tuple/tuple/tuple_decl.hpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include namespace sprout { namespace tuples { @@ -245,9 +245,9 @@ namespace sprout { typedef sprout::tuples::detail::tuple_impl<0, Types...> impl_type; private: template - struct is_flexibly_constructible_impl; + struct is_flexibly_convert_constructible_impl; template - struct is_flexibly_constructible_impl, Utypes...> + struct is_flexibly_convert_constructible_impl, Utypes...> : public sprout::tpp::all_of< sprout::is_convert_constructible< typename sprout::tppack_at::type, @@ -262,19 +262,19 @@ namespace sprout { > {}; template - struct is_flexibly_constructible - : public is_flexibly_constructible_impl< + struct is_flexibly_convert_constructible + : public is_flexibly_convert_constructible_impl< typename sprout::index_range<0, (sizeof...(UTypes) < sizeof...(Types) ? sizeof...(UTypes) : sizeof...(Types))>::type, UTypes... > {}; template - struct is_rvref_flexibly_constructible - : public is_flexibly_constructible + struct is_rvref_flexibly_convert_constructible + : public is_flexibly_convert_constructible {}; template - struct is_clvref_flexibly_constructible - : public is_flexibly_constructible + struct is_clvref_flexibly_convert_constructible + : public is_flexibly_convert_constructible {}; public: // tuple construction @@ -317,38 +317,39 @@ namespace sprout { >::type > SPROUT_CONSTEXPR tuple(sprout::pair&& t); + template< typename... UTypes, typename = typename std::enable_if< - is_rvref_flexibly_constructible::value + is_rvref_flexibly_convert_constructible::value >::type > explicit SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, UTypes&&... elements); template< typename... UTypes, typename = typename std::enable_if< - is_clvref_flexibly_constructible::value + is_clvref_flexibly_convert_constructible::value >::type > SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple const& t); template< typename... UTypes, typename = typename std::enable_if< - is_rvref_flexibly_constructible::value + is_rvref_flexibly_convert_constructible::value >::type > SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple&& t); template< typename... UTypes, typename = typename std::enable_if< - is_clvref_flexibly_constructible::value + is_clvref_flexibly_convert_constructible::value >::type > SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair const& t); template< typename... UTypes, typename = typename std::enable_if< - is_rvref_flexibly_constructible::value + is_rvref_flexibly_convert_constructible::value >::type > SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair&& t); diff --git a/sprout/utility/pair/pair.hpp b/sprout/utility/pair/pair.hpp index 1110d6f3..de6d9c27 100644 --- a/sprout/utility/pair/pair.hpp +++ b/sprout/utility/pair/pair.hpp @@ -1,11 +1,11 @@ #ifndef SPROUT_UTILITY_PAIR_PAIR_HPP #define SPROUT_UTILITY_PAIR_PAIR_HPP +#include #include #include #include #include -#include #include #include #include @@ -41,29 +41,41 @@ namespace sprout { , second(y) {} template - template + template< + typename U, typename V, + typename + > inline SPROUT_CONSTEXPR sprout::pair::pair(U&& x, V&& y) : first(sprout::forward(x)) , second(sprout::forward(y)) {} template - template + template< + typename U, typename V, + typename + > inline SPROUT_CONSTEXPR sprout::pair::pair(sprout::pair const& other) : first(other.first) , second(other.second) {} template - template + template< + typename U, typename V, + typename + > inline SPROUT_CONSTEXPR sprout::pair::pair(sprout::pair&& other) - : first(sprout::move(other.first)) - , second(sprout::move(other.second)) + : first(sprout::forward(other.first)) + , second(sprout::forward(other.second)) {} #if SPROUT_USE_DELEGATING_CONSTRUCTORS template - template + template< + typename... Args1, typename... Args2, + typename + > inline SPROUT_CONSTEXPR sprout::pair::pair( - sprout::tuples::tuple first_args, - sprout::tuples::tuple second_args + std::piecewise_construct_t, + sprout::tuples::tuple first_args, sprout::tuples::tuple second_args ) : pair( first_args, @@ -74,29 +86,75 @@ namespace sprout { {} #endif // #if SPROUT_USE_DELEGATING_CONSTRUCTORS template - inline sprout::pair& sprout::pair::operator=(pair const& other) = default; + template< + typename U, typename V, + typename + > + inline SPROUT_CONSTEXPR sprout::pair::pair(sprout::tuples::tuple const& other) + : first(sprout::tuples::get<0>(other)) + , second(sprout::tuples::get<1>(other)) + {} template - template - inline sprout::pair& sprout::pair::operator=(sprout::pair const& other) { - first = other.first; - second = other.second; - return *this; - } + template< + typename U, typename V, + typename + > + inline SPROUT_CONSTEXPR sprout::pair::pair(sprout::tuples::tuple&& other) + : first(sprout::forward(sprout::tuples::get<0>(other))) + , second(sprout::forward(sprout::tuples::get<1>(other))) + {} + template - inline sprout::pair& sprout::pair::operator=(pair&& other) + inline sprout::pair& sprout::pair::operator=(pair const& rhs) = default; + template + inline sprout::pair& sprout::pair::operator=(pair&& rhs) SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_assignable::value && std::is_nothrow_move_assignable::value) { - first = sprout::move(other.first); - second = sprout::move(other.second); + first = sprout::forward(rhs.first); + second = sprout::forward(rhs.second); return *this; } template - template - inline sprout::pair& sprout::pair::operator=(sprout::pair&& other) { - first = sprout::move(other.first); - second = sprout::move(other.second); + template< + typename U, typename V, + typename + > + inline sprout::pair& sprout::pair::operator=(sprout::pair const& rhs) { + first = rhs.first; + second = rhs.second; return *this; } + template + template< + typename U, typename V, + typename + > + inline sprout::pair& sprout::pair::operator=(sprout::pair&& rhs) { + first = sprout::forward(rhs.first); + second = sprout::forward(rhs.second); + return *this; + } + template + template< + typename U, typename V, + typename + > + inline sprout::pair& sprout::pair::operator=(sprout::tuples::tuple const& rhs) { + first = sprout::tuples::get<0>(rhs); + second = sprout::tuples::get<0>(rhs); + return *this; + } + template + template< + typename U, typename V, + typename + > + inline sprout::pair& sprout::pair::operator=(sprout::tuples::tuple&& rhs) { + first = sprout::forward(sprout::tuples::get<0>(rhs)); + second = sprout::forward(sprout::tuples::get<1>(rhs)); + return *this; + } + template inline void sprout::pair::swap(pair& other) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::swap(first, other.first)) && SPROUT_NOEXCEPT_EXPR(sprout::swap(second, other.second))) { diff --git a/sprout/utility/pair/pair_decl.hpp b/sprout/utility/pair/pair_decl.hpp index 124fae1b..0062c4ff 100644 --- a/sprout/utility/pair/pair_decl.hpp +++ b/sprout/utility/pair/pair_decl.hpp @@ -1,6 +1,7 @@ #ifndef SPROUT_UTILITY_PAIR_PAIR_DECL_HPP #define SPROUT_UTILITY_PAIR_PAIR_DECL_HPP +#include #include #include #include @@ -34,24 +35,85 @@ namespace sprout { SPROUT_CONSTEXPR pair(pair&&); SPROUT_CONSTEXPR pair(); SPROUT_CONSTEXPR pair(T1 const& x, T2 const& y); - template + template< + typename U, typename V, + typename = typename std::enable_if< + std::is_constructible::value && std::is_constructible::value + >::type + > SPROUT_CONSTEXPR pair(U&& x, V&& y); - template + template< + typename U, typename V, + typename = typename std::enable_if< + std::is_constructible::value && std::is_constructible::value + >::type + > SPROUT_CONSTEXPR pair(sprout::pair const& other); - template + template< + typename U, typename V, + typename = typename std::enable_if< + std::is_constructible::value && std::is_constructible::value + >::type + > SPROUT_CONSTEXPR pair(sprout::pair&& other); - template + template< + typename... Args1, typename... Args2, + typename = typename std::enable_if< + std::is_constructible::value && std::is_constructible::value + >::type + > SPROUT_CONSTEXPR pair( - sprout::tuples::tuple first_args, - sprout::tuples::tuple second_args + std::piecewise_construct_t, + sprout::tuples::tuple first_args, sprout::tuples::tuple second_args ); - pair& operator=(pair const& other); - template - pair& operator=(sprout::pair const& other); - pair& operator=(pair&& other) + + template< + typename U, typename V, + typename = typename std::enable_if< + std::is_constructible::value && std::is_constructible::value + >::type + > + SPROUT_CONSTEXPR pair(sprout::tuples::tuple const& other); + template< + typename U, typename V, + typename = typename std::enable_if< + std::is_constructible::value && std::is_constructible::value + >::type + > + SPROUT_CONSTEXPR pair(sprout::tuples::tuple&& other); + + pair& operator=(pair const& rhs); + pair& operator=(pair&& rhs) SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_assignable::value && std::is_nothrow_move_assignable::value); - template - pair& operator=(sprout::pair&& other); + template< + typename U, typename V, + typename = typename std::enable_if< + std::is_assignable::value && std::is_assignable::value + >::type + > + pair& operator=(sprout::pair const& rhs); + template< + typename U, typename V, + typename = typename std::enable_if< + std::is_assignable::value && std::is_assignable::value + >::type + > + pair& operator=(sprout::pair&& rhs); + template< + typename U, typename V, + typename = typename std::enable_if< + std::is_assignable::value && std::is_assignable::value + >::type + > + pair& operator=(sprout::tuples::tuple const& rhs); + template< + typename U, typename V, + typename = typename std::enable_if< + std::is_assignable::value && std::is_assignable::value + >::type + > + pair& operator=(sprout::tuples::tuple&& rhs); + void swap(pair& other) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::swap(first, other.first)) && SPROUT_NOEXCEPT_EXPR(sprout::swap(second, other.second))); };