From e578bdd0a6046391089f2f223963f34cc93f7a71 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Tue, 4 Jun 2013 23:15:05 +0900 Subject: [PATCH] support constexpr: get(optional&), get(optional&&) --- libs/optional/test/optional.cpp | 10 +-- sprout/optional/get.hpp | 65 +++++++++++-------- sprout/optional/optional.hpp | 60 ++++++++++++------ sprout/tuple/tuple/get.hpp | 2 +- sprout/utility/value_holder/get.hpp | 47 ++++++++------ sprout/utility/value_holder/value_holder.hpp | 67 +++++++++++++++++--- 6 files changed, 174 insertions(+), 77 deletions(-) diff --git a/libs/optional/test/optional.cpp b/libs/optional/test/optional.cpp index 37f5b9e9..257e688d 100644 --- a/libs/optional/test/optional.cpp +++ b/libs/optional/test/optional.cpp @@ -434,18 +434,18 @@ namespace testspr { TESTSPR_ASSERT(*sprout::get_pointer(opt3) == 12345); } - // get_optional_value_or - TESTSPR_BOTH_ASSERT(sprout::get_optional_value_or(opt1, 12345) == 1234); - TESTSPR_BOTH_ASSERT(sprout::get_optional_value_or(opt2, 12345) == 12345); + // get_value_or + TESTSPR_BOTH_ASSERT(sprout::get_value_or(opt1, 12345) == 1234); + TESTSPR_BOTH_ASSERT(sprout::get_value_or(opt2, 12345) == 12345); { auto opt3 = sprout::optional(1234); int v = 12345; - TESTSPR_ASSERT(sprout::get_optional_value_or(opt3, v) == 1234); + TESTSPR_ASSERT(sprout::get_value_or(opt3, v) == 1234); } { auto opt3 = sprout::optional(); int v = 12345; - TESTSPR_ASSERT(sprout::get_optional_value_or(opt3, v) == 12345); + TESTSPR_ASSERT(sprout::get_value_or(opt3, v) == 12345); } // sprout::to_hash, sprout::hash diff --git a/sprout/optional/get.hpp b/sprout/optional/get.hpp index 8c2078b3..cd7334e3 100644 --- a/sprout/optional/get.hpp +++ b/sprout/optional/get.hpp @@ -9,52 +9,67 @@ namespace sprout { // get // template - inline SPROUT_CONSTEXPR typename sprout::optional::reference_const_type - get(sprout::optional const& x) { - return x.get(); + inline SPROUT_CONSTEXPR typename sprout::optional::reference_type + get(sprout::optional& x) { + return sprout::optional::get(x); } template - inline typename sprout::optional::reference_type - get(sprout::optional& x) { - return x.get(); + inline SPROUT_CONSTEXPR typename sprout::optional::rvalue_reference_type + get(sprout::optional&& x) { + return sprout::optional::get(sprout::move(x)); + } + template + inline SPROUT_CONSTEXPR typename sprout::optional::reference_const_type + get(sprout::optional const& x) { + return sprout::optional::get(x); + } + template + inline SPROUT_CONSTEXPR typename sprout::optional::pointer_type + get(sprout::optional* x) { + return sprout::optional::get_pointer(*x); } template inline SPROUT_CONSTEXPR typename sprout::optional::pointer_const_type get(sprout::optional const* x) { - return x->get_pointer(); - } - template - inline typename sprout::optional::pointer_type - get(sprout::optional* x) { - return x->get_pointer(); + return sprout::optional::get_pointer(*x); } // // get_pointer // template - inline SPROUT_CONSTEXPR typename sprout::optional::pointer_const_type - get_pointer(sprout::optional const& x) { - return x.get_pointer(); + inline SPROUT_CONSTEXPR typename sprout::optional::pointer_type + get_pointer(sprout::optional& x) { + return sprout::optional::get_pointer(x); } template - inline typename sprout::optional::pointer_type - get_pointer(sprout::optional& x) { - return x.get_pointer(); + inline SPROUT_CONSTEXPR typename sprout::optional::pointer_type + get_pointer(sprout::optional&& x) { + return sprout::optional::get_pointer(sprout::move(x)); + } + template + inline SPROUT_CONSTEXPR typename sprout::optional::pointer_const_type + get_pointer(sprout::optional const& x) { + return sprout::optional::get_pointer(x); } // - // get_optional_value_or + // get_value_or // template - inline SPROUT_CONSTEXPR typename sprout::optional::reference_const_type - get_optional_value_or(sprout::optional const& x, typename sprout::optional::reference_const_type v) { - return x.get_value_or(v); + inline SPROUT_CONSTEXPR typename sprout::optional::reference_type + get_value_or(sprout::optional& x, typename sprout::optional::reference_type v) { + return sprout::optional::get_value_or(x, v); } template - inline typename sprout::optional::reference_type - get_optional_value_or(sprout::optional& x, typename sprout::optional::reference_type v) { - return x.get_value_or(v); + inline SPROUT_CONSTEXPR typename sprout::optional::rvalue_reference_type + get_value_or(sprout::optional&& x, typename sprout::optional::rvalue_reference_type v) { + return sprout::optional::get_value_or(sprout::move(x), static_cast::rvalue_reference_type>(v)); + } + template + inline SPROUT_CONSTEXPR typename sprout::optional::reference_const_type + get_value_or(sprout::optional const& x, typename sprout::optional::reference_const_type v) { + return sprout::optional::get_value_or(x, v); } } // namespace sprout diff --git a/sprout/optional/optional.hpp b/sprout/optional/optional.hpp index 93089a2d..f1d5f244 100644 --- a/sprout/optional/optional.hpp +++ b/sprout/optional/optional.hpp @@ -5,10 +5,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include @@ -28,16 +28,52 @@ namespace sprout { typedef sprout::value_holder holder_type; public: typedef typename holder_type::value_type value_type; + typedef typename holder_type::lvalue_reference lvalue_reference; + typedef typename holder_type::rvalue_reference rvalue_reference; typedef typename holder_type::reference reference; + typedef typename holder_type::const_lvalue_reference const_lvalue_reference; + typedef typename holder_type::const_rvalue_reference const_rvalue_reference; typedef typename holder_type::const_reference const_reference; typedef typename holder_type::pointer pointer; typedef typename holder_type::const_pointer const_pointer; + typedef typename holder_type::lvalue_reference_type lvalue_reference_type; + typedef typename holder_type::rvalue_reference_type rvalue_reference_type; typedef typename holder_type::reference_type reference_type; typedef typename holder_type::reference_const_type reference_const_type; typedef typename holder_type::pointer_type pointer_type; typedef typename holder_type::pointer_const_type pointer_const_type; - typedef typename holder_type::argument_type argument_type; - typedef typename holder_type::movable_argument_type movable_argument_type; + public: + static SPROUT_CONSTEXPR reference_type get(optional& t) SPROUT_NOEXCEPT { + return sprout::get(t.val); + } + static SPROUT_CONSTEXPR rvalue_reference_type get(optional&& t) SPROUT_NOEXCEPT { + return static_cast(get(t)); + } + static SPROUT_CONSTEXPR reference_const_type get(optional const& t) SPROUT_NOEXCEPT { + return sprout::get(t.val); + } + static SPROUT_CONSTEXPR pointer_type get_pointer(optional& t) SPROUT_NOEXCEPT { + return sprout::get_pointer(t.val); + } + static SPROUT_CONSTEXPR pointer_type get_pointer(optional&& t) SPROUT_NOEXCEPT { + return get_pointer(t); + } + static SPROUT_CONSTEXPR pointer_const_type get_pointer(optional const& t) SPROUT_NOEXCEPT { + return sprout::get_pointer(t.val); + } + static SPROUT_CONSTEXPR reference_type get_value_or(optional& t, reference_type v) SPROUT_NOEXCEPT { + return t.is_initialized() ? sprout::get(t.val) + : v + ; + } + static SPROUT_CONSTEXPR rvalue_reference_type get_value_or(optional&& t, rvalue_reference_type v) SPROUT_NOEXCEPT { + return static_cast(get_value_or(t, v)); + } + static SPROUT_CONSTEXPR reference_const_type get_value_or(optional const& t, reference_const_type v) SPROUT_NOEXCEPT { + return t.is_initialized() ? sprout::get(t.val) + : v + ; + } private: bool init; holder_type val; @@ -57,16 +93,10 @@ namespace sprout { : init(v.init) , val(v.is_initialized() ? holder_type(*v) : holder_type()) {} - // constexpr support -// SPROUT_CONSTEXPR optional(optional&& v) -// SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_constructible::value) -// : init(v.init) -// , val(v.is_initialized() ? holder_type(sprout::move(*v)) : holder_type()) -// {} SPROUT_CONSTEXPR optional(optional&& v) - SPROUT_NOEXCEPT_EXPR(std::is_nothrow_copy_constructible::value) + SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_constructible::value) : init(v.init) - , val(v.is_initialized() ? holder_type(*sprout::as_const(v)) : holder_type()) + , val(v.is_initialized() ? holder_type(sprout::move(get(v))) : holder_type()) {} SPROUT_CONSTEXPR optional(T const& v) : init(true) @@ -105,16 +135,10 @@ namespace sprout { : init(v.is_initialized()) , val(v.is_initialized() ? holder_type(*v) : holder_type()) {} - // constexpr support -// template -// explicit SPROUT_CONSTEXPR optional(optional&& v) -// : init(v.is_initialized()) -// , val(v.is_initialized() ? holder_type(sprout::move(*v)) : holder_type()) -// {} template explicit SPROUT_CONSTEXPR optional(optional&& v) : init(v.is_initialized()) - , val(v.is_initialized() ? holder_type(*sprout::as_const(v)) : holder_type()) + , val(v.is_initialized() ? holder_type(sprout::move(optional::get(v))) : holder_type()) {} // 20.6.4.3, assignment optional& operator=(sprout::nullopt_t v) SPROUT_NOEXCEPT { diff --git a/sprout/tuple/tuple/get.hpp b/sprout/tuple/tuple/get.hpp index 7b515061..b1871ac9 100644 --- a/sprout/tuple/tuple/get.hpp +++ b/sprout/tuple/tuple/get.hpp @@ -37,7 +37,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element >::type&& tuple_get(sprout::tuples::tuple&& t) SPROUT_NOEXCEPT { - return sprout::forward >::type&&>( + return sprout::forward >::type>( sprout::tuples::tuple_get(t) ); } diff --git a/sprout/utility/value_holder/get.hpp b/sprout/utility/value_holder/get.hpp index 648c4252..30de79df 100644 --- a/sprout/utility/value_holder/get.hpp +++ b/sprout/utility/value_holder/get.hpp @@ -3,44 +3,55 @@ #include #include +#include namespace sprout { // // get // template - inline SPROUT_CONSTEXPR typename sprout::value_holder::reference_const_type - get(sprout::value_holder const& x) { - return x.get(); + inline SPROUT_CONSTEXPR typename sprout::value_holder::reference_type + get(sprout::value_holder& x) { + return sprout::value_holder::get(x); } template - inline typename sprout::value_holder::reference_type - get(sprout::value_holder& x) { - return x.get(); + inline SPROUT_CONSTEXPR typename sprout::value_holder::rvalue_reference + get(sprout::value_holder&& x) { + return sprout::value_holder::get(sprout::move(x)); + } + template + inline SPROUT_CONSTEXPR typename sprout::value_holder::reference_const_type + get(sprout::value_holder const& x) { + return sprout::value_holder::get(x); + } + template + inline SPROUT_CONSTEXPR typename sprout::value_holder::pointer_type + get(sprout::value_holder* x) { + return sprout::value_holder::get_pointer(*x); } template inline SPROUT_CONSTEXPR typename sprout::value_holder::pointer_const_type get(sprout::value_holder const* x) { - return x->get_pointer(); - } - template - inline typename sprout::value_holder::pointer_type - get(sprout::value_holder* x) { - return x->get_pointer(); + return sprout::value_holder::get_pointer(*x); } // // get_pointer // template - inline SPROUT_CONSTEXPR typename sprout::value_holder::pointer_const_type - get_pointer(sprout::value_holder const& x) { - return x.get_pointer(); + inline SPROUT_CONSTEXPR typename sprout::value_holder::pointer_type + get_pointer(sprout::value_holder& x) { + return sprout::value_holder::get_pointer(x); } template - inline typename sprout::value_holder::pointer_type - get_pointer(sprout::value_holder& x) { - return x.get_pointer(); + inline SPROUT_CONSTEXPR typename sprout::value_holder::pointer_type + get_pointer(sprout::value_holder&& x) { + return sprout::value_holder::get_pointer(sprout::move(x)); + } + template + inline SPROUT_CONSTEXPR typename sprout::value_holder::pointer_const_type + get_pointer(sprout::value_holder const& x) { + return sprout::value_holder::get_pointer(x); } } // namespace sprout diff --git a/sprout/utility/value_holder/value_holder.hpp b/sprout/utility/value_holder/value_holder.hpp index e5c6c23a..7f011009 100644 --- a/sprout/utility/value_holder/value_holder.hpp +++ b/sprout/utility/value_holder/value_holder.hpp @@ -15,8 +15,12 @@ namespace sprout { struct holder_helper { public: typedef T value_type; - typedef T& reference; - typedef T const& const_reference; + typedef T& lvalue_reference; + typedef T&& rvalue_reference; + typedef lvalue_reference reference; + typedef T const& const_lvalue_reference; + typedef T const&& const_rvalue_reference; + typedef const_lvalue_reference const_reference; typedef T const& mutable_or_const_reference; typedef T* pointer; typedef T const* const_pointer; @@ -48,8 +52,12 @@ namespace sprout { struct holder_helper { public: typedef T value_type; - typedef T const& reference; - typedef T const& const_reference; + typedef T const& lvalue_reference; + typedef T const&& rvalue_reference; + typedef lvalue_reference reference; + typedef T const& const_lvalue_reference; + typedef T const&& const_rvalue_reference; + typedef const_lvalue_reference const_reference; typedef T const& mutable_or_const_reference; typedef T const* pointer; typedef T const* const_pointer; @@ -81,8 +89,12 @@ namespace sprout { struct holder_helper { public: typedef T value_type; - typedef T& reference; - typedef T const& const_reference; + typedef T& lvalue_reference; + typedef T& rvalue_reference; + typedef lvalue_reference reference; + typedef T const& const_lvalue_reference; + typedef T const& const_rvalue_reference; + typedef const_lvalue_reference const_reference; typedef T& mutable_or_const_reference; typedef T* pointer; typedef T const* const_pointer; @@ -105,8 +117,12 @@ namespace sprout { struct holder_helper { public: typedef T value_type; - typedef T const& reference; - typedef T const& const_reference; + typedef T const& lvalue_reference; + typedef T const& rvalue_reference; + typedef lvalue_reference reference; + typedef T const& const_lvalue_reference; + typedef T const& const_rvalue_reference; + typedef const_lvalue_reference const_reference; typedef T const& mutable_or_const_reference; typedef T const* pointer; typedef T const* const_pointer; @@ -138,7 +154,11 @@ namespace sprout { typedef typename helper_type::holder_type holder_type; public: typedef typename helper_type::value_type value_type; + typedef typename helper_type::lvalue_reference lvalue_reference; + typedef typename helper_type::rvalue_reference rvalue_reference; typedef typename helper_type::reference reference; + typedef typename helper_type::const_lvalue_reference const_lvalue_reference; + typedef typename helper_type::const_rvalue_reference const_rvalue_reference; typedef typename helper_type::const_reference const_reference; typedef typename helper_type::mutable_or_const_reference mutable_or_const_reference; typedef typename helper_type::pointer pointer; @@ -146,12 +166,33 @@ namespace sprout { typedef typename helper_type::mutable_or_const_pointer mutable_or_const_pointer; typedef typename helper_type::param_type param_type; typedef typename helper_type::movable_param_type movable_param_type; + typedef lvalue_reference lvalue_reference_type; + typedef rvalue_reference rvalue_reference_type; typedef reference reference_type; typedef mutable_or_const_reference reference_const_type; typedef pointer pointer_type; typedef mutable_or_const_pointer pointer_const_type; typedef param_type argument_type; typedef movable_param_type movable_argument_type; + public: + static SPROUT_CONSTEXPR reference get(value_holder& t) SPROUT_NOEXCEPT { + return helper_type::ref(t.holder_); + } + static SPROUT_CONSTEXPR rvalue_reference get(value_holder&& t) SPROUT_NOEXCEPT { + return static_cast(get(t)); + } + static SPROUT_CONSTEXPR mutable_or_const_reference get(value_holder const& t) SPROUT_NOEXCEPT { + return helper_type::ref(t.holder_); + } + static SPROUT_CONSTEXPR pointer get_pointer(value_holder& t) SPROUT_NOEXCEPT { + return helper_type::ptr(t.holder_); + } + static SPROUT_CONSTEXPR pointer get_pointer(value_holder&& t) SPROUT_NOEXCEPT { + return get_pointer(t); + } + static SPROUT_CONSTEXPR mutable_or_const_pointer get_pointer(value_holder const& t) SPROUT_NOEXCEPT { + return helper_type::ptr(t.holder_); + } private: holder_type holder_; public: @@ -160,7 +201,7 @@ namespace sprout { {} SPROUT_CONSTEXPR value_holder(value_holder const&) = default; SPROUT_CONSTEXPR value_holder(value_holder&&) = default; - explicit SPROUT_CONSTEXPR value_holder(param_type p) + explicit SPROUT_CONSTEXPR value_holder(argument_type p) : holder_(helper_type::hold(p)) {} explicit SPROUT_CONSTEXPR value_holder(movable_argument_type p) @@ -183,7 +224,7 @@ namespace sprout { value_holder& operator=(value_holder const&) = default; value_holder& operator=(value_holder&&) = default; - value_holder& operator=(param_type p) { + value_holder& operator=(argument_type p) { value_holder temp(helper_type::hold(p)); temp.swap(p); return *this; @@ -218,6 +259,12 @@ namespace sprout { SPROUT_CONSTEXPR mutable_or_const_reference get() const { return helper_type::ref(holder_); } + reference value() { + return get(); + } + SPROUT_CONSTEXPR mutable_or_const_reference value() const { + return get(); + } pointer operator->() SPROUT_NOEXCEPT { return helper_type::ptr(holder_);