From c8b47ca3ca8b1dcb312d98150a53fa01e08012e1 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Fri, 31 Aug 2012 14:33:12 +0000 Subject: [PATCH] Added move ctors for vector and deque (deque for gcc partially working for now) no preprocessed files yet [SVN r80331] --- .../boost/fusion/container/deque/deque.hpp | 28 +++++++++++++-- .../container/deque/detail/cpp03_deque.hpp | 26 ++++++++++++-- .../deque/detail/cpp03_deque_keyed_values.hpp | 5 +++ .../deque/detail/deque_forward_ctor.hpp | 12 ++++++- .../deque/detail/deque_keyed_values_call.hpp | 18 +++++++++- .../container/deque/detail/keyed_element.hpp | 34 +++++++++++++++++-- .../vector/detail/vector_forward_ctor.hpp | 13 ++++++- .../container/vector/detail/vector_n.hpp | 28 +++++++++++++++ .../boost/fusion/container/vector/vector.hpp | 5 +++ 9 files changed, 159 insertions(+), 10 deletions(-) diff --git a/include/boost/fusion/container/deque/deque.hpp b/include/boost/fusion/container/deque/deque.hpp index 215981e4..5ebf03d9 100644 --- a/include/boost/fusion/container/deque/deque.hpp +++ b/include/boost/fusion/container/deque/deque.hpp @@ -71,11 +71,35 @@ namespace boost { namespace fusion : base(seq) {} - explicit deque(typename detail::call_param::type head - , typename detail::call_param::type... tail) +#if !defined(BOOST_NO_RVALUE_REFERENCES) + template + deque(deque&& seq) + : base(std::forward>(seq)) + {} +#endif + + deque(deque const& seq) + : base(seq) + {} + +#if !defined(BOOST_NO_RVALUE_REFERENCES) + deque(deque&& seq) + : base(std::forward(seq)) + {} +#endif + + explicit deque(Head const& head, Tail const&... tail) : base(detail::deque_keyed_values::call(head, tail...)) {} +//~ #if !defined(BOOST_NO_RVALUE_REFERENCES) + //~ template + //~ explicit deque(Head_&& head, Tail_&&... tail) + //~ : base(detail::deque_keyed_values + //~ ::call(std::forward(head), std::forward(tail)...)) + //~ {} +//~ #endif + template explicit deque(Sequence const& seq , typename disable_if >::type* /*dummy*/ = 0) diff --git a/include/boost/fusion/container/deque/detail/cpp03_deque.hpp b/include/boost/fusion/container/deque/detail/cpp03_deque.hpp index 5804d890..19629fcc 100644 --- a/include/boost/fusion/container/deque/detail/cpp03_deque.hpp +++ b/include/boost/fusion/container/deque/detail/cpp03_deque.hpp @@ -87,13 +87,34 @@ namespace boost { namespace fusion { : base(t0, detail::nil_keyed_element()) {} + explicit deque(deque const& rhs) + : base(rhs) + {} + +#if !defined(BOOST_NO_RVALUE_REFERENCES) + explicit deque(T0&& t0) + : base(std::forward(t0), detail::nil_keyed_element()) + {} + + explicit deque(deque&& rhs) + : base(std::forward(rhs)) + {} +#endif + template - deque(deque const& seq) + deque(deque const& seq) : base(seq) {} +#if !defined(BOOST_NO_RVALUE_REFERENCES) + template + deque(deque&& seq) + : base(std::forward>(seq)) + {} +#endif + template - deque(Sequence const& seq, typename disable_if >::type* /*dummy*/ = 0) + deque(Sequence const& seq, typename disable_if >::type* /*dummy*/ = 0) : base(base::from_iterator(fusion::begin(seq))) {} @@ -112,7 +133,6 @@ namespace boost { namespace fusion { base::operator=(rhs); return *this; } - }; }} diff --git a/include/boost/fusion/container/deque/detail/cpp03_deque_keyed_values.hpp b/include/boost/fusion/container/deque/detail/cpp03_deque_keyed_values.hpp index 2fee4700..d32c13a5 100644 --- a/include/boost/fusion/container/deque/detail/cpp03_deque_keyed_values.hpp +++ b/include/boost/fusion/container/deque/detail/cpp03_deque_keyed_values.hpp @@ -72,6 +72,11 @@ namespace boost { namespace fusion { namespace detail { return type(); } + + static type forward_() + { + return type(); + } }; template diff --git a/include/boost/fusion/container/deque/detail/deque_forward_ctor.hpp b/include/boost/fusion/container/deque/detail/deque_forward_ctor.hpp index b76916eb..09d10223 100644 --- a/include/boost/fusion/container/deque/detail/deque_forward_ctor.hpp +++ b/include/boost/fusion/container/deque/detail/deque_forward_ctor.hpp @@ -13,6 +13,8 @@ #error "C++03 only! This file should not have been included" #endif +#define FUSION_DEQUE_FORWARD_CTOR_FORWARD(z, n, _) std::forward(t##n) + #include #include #include @@ -22,14 +24,22 @@ #define BOOST_PP_ITERATION_LIMITS (2, FUSION_MAX_DEQUE_SIZE) #include BOOST_PP_ITERATE() +#undef FUSION_DEQUE_FORWARD_CTOR_FORWARD #endif #else #define N BOOST_PP_ITERATION() deque(BOOST_PP_ENUM_BINARY_PARAMS(N, typename add_reference::type>::type t)) - : base(detail::deque_keyed_values::call(BOOST_PP_ENUM_PARAMS(N, t))) + : base(detail::deque_keyed_values::construct(BOOST_PP_ENUM_PARAMS(N, t))) {} +#if !defined(BOOST_NO_RVALUE_REFERENCES) +deque(BOOST_PP_ENUM_BINARY_PARAMS(N, T, && t)) + : base(detail::deque_keyed_values:: + forward_(BOOST_PP_ENUM(N, FUSION_DEQUE_FORWARD_CTOR_FORWARD, _))) +{} +#endif + #undef N #endif diff --git a/include/boost/fusion/container/deque/detail/deque_keyed_values_call.hpp b/include/boost/fusion/container/deque/detail/deque_keyed_values_call.hpp index f95960bc..eea7e8c3 100644 --- a/include/boost/fusion/container/deque/detail/deque_keyed_values_call.hpp +++ b/include/boost/fusion/container/deque/detail/deque_keyed_values_call.hpp @@ -15,19 +15,24 @@ #include #include +#include #include +#define FUSION_DEQUE_KEYED_VALUES_FORWARD(z, n, _) \ + std::forward(BOOST_PP_CAT(t, n)) + #define BOOST_PP_FILENAME_1 \ #define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_DEQUE_SIZE) #include BOOST_PP_ITERATE() +#undef FUSION_DEQUE_KEYED_VALUES_FORWARD #endif #else #define N BOOST_PP_ITERATION() - static type call(BOOST_PP_ENUM_BINARY_PARAMS(N, typename add_reference::type>::type t)) + static type construct(BOOST_PP_ENUM_BINARY_PARAMS(N, typename add_reference::type>::type t)) { return type(t0, deque_keyed_values_impl< @@ -38,5 +43,16 @@ >::call(BOOST_PP_ENUM_SHIFTED_PARAMS(N, t))); } + static type forward_(BOOST_PP_ENUM_BINARY_PARAMS(N, T, && t)) + { + return type(std::forward(t0), + deque_keyed_values_impl< + next_index + #if N > 1 + , BOOST_PP_ENUM_SHIFTED_PARAMS(N, T) + #endif + >::forward_(BOOST_PP_ENUM_SHIFTED(N, FUSION_DEQUE_KEYED_VALUES_FORWARD, _))); + } + #undef N #endif diff --git a/include/boost/fusion/container/deque/detail/keyed_element.hpp b/include/boost/fusion/container/deque/detail/keyed_element.hpp index d1b219de..d8f988a5 100644 --- a/include/boost/fusion/container/deque/detail/keyed_element.hpp +++ b/include/boost/fusion/container/deque/detail/keyed_element.hpp @@ -47,16 +47,39 @@ namespace boost { namespace fusion { namespace detail *it, base::from_iterator(fusion::next(it))); } + keyed_element(keyed_element const& rhs) + : Rest(rhs.get_base()), value_(rhs.value_) + {} + +#if !defined(BOOST_NO_RVALUE_REFERENCES) + keyed_element(keyed_element&& rhs) + : Rest(std::forward(rhs.forward_base())) + , value_(std::forward(rhs.value_)) + {} +#endif + template keyed_element(keyed_element const& rhs) : Rest(rhs.get_base()), value_(rhs.value_) {} - Rest const get_base() const + Rest& get_base() { return *this; } + Rest const& get_base() const + { + return *this; + } + +#if !defined(BOOST_NO_RVALUE_REFERENCES) + Rest&& forward_base() + { + return std::forward(*static_cast(this)); + } +#endif + typename cref_result::type get(Key) const { return value_; @@ -67,10 +90,17 @@ namespace boost { namespace fusion { namespace detail return value_; } - keyed_element(typename call_param::type value, Rest const& rest) + keyed_element(Value const& value, Rest const& rest) : Rest(rest), value_(value) {} +#if !defined(BOOST_NO_RVALUE_REFERENCES) + keyed_element(Value&& value, Rest&& rest) + : Rest(std::forward(rest)) + , value_(std::forward(value)) + {} +#endif + keyed_element() : Rest(), value_() {} diff --git a/include/boost/fusion/container/vector/detail/vector_forward_ctor.hpp b/include/boost/fusion/container/vector/detail/vector_forward_ctor.hpp index 92f7aa6c..8d8865f1 100644 --- a/include/boost/fusion/container/vector/detail/vector_forward_ctor.hpp +++ b/include/boost/fusion/container/vector/detail/vector_forward_ctor.hpp @@ -1,7 +1,7 @@ /*============================================================================= Copyright (c) 2001-2011 Joel de Guzman - Distributed under the Boost Software License, Version 1.0. (See accompanying + Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ #ifndef BOOST_PP_IS_ITERATING @@ -12,11 +12,14 @@ #include #include +#define FUSION_FORWARD_CTOR_MOVE(z, n, _) std::move(_##n) + #define BOOST_PP_FILENAME_1 \ #define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE) #include BOOST_PP_ITERATE() +#undef FUSION_FORWARD_CTOR_MOVE #endif #else // defined(BOOST_PP_IS_ITERATING) /////////////////////////////////////////////////////////////////////////////// @@ -34,6 +37,14 @@ N, typename detail::call_param::type _)) : vec(BOOST_PP_ENUM_PARAMS(N, _)) {} +#if !defined(BOOST_NO_RVALUE_REFERENCES) +#if N == 1 + explicit +#endif + vector(BOOST_PP_ENUM_BINARY_PARAMS(N, T, && _)) + : vec(BOOST_PP_ENUM(N, FUSION_FORWARD_CTOR_MOVE, _)) {} +#endif + #undef N #endif // defined(BOOST_PP_IS_ITERATING) diff --git a/include/boost/fusion/container/vector/detail/vector_n.hpp b/include/boost/fusion/container/vector/detail/vector_n.hpp index 4e249c7f..4652303b 100644 --- a/include/boost/fusion/container/vector/detail/vector_n.hpp +++ b/include/boost/fusion/container/vector/detail/vector_n.hpp @@ -12,7 +12,10 @@ #define FUSION_MEMBER_DEFAULT_INIT(z, n, _) m##n() #define FUSION_MEMBER_INIT(z, n, _) m##n(_##n) #define FUSION_COPY_INIT(z, n, _) m##n(other.m##n) +#define FUSION_MOVE_FROM_OTHER(z, n, _) m##n(std::move(other.m##n)) +#define FUSION_MOVE(z, n, _) m##n(std::move(_##n)) #define FUSION_MEMBER_DECL(z, n, _) T##n m##n; +#define FUSION_FORWARD(z, n, _) std::forward(_##n) #define FUSION_MEMBER_ASSIGN(z, n, _) \ this->BOOST_PP_CAT(m, n) = vec.BOOST_PP_CAT(m, n); @@ -42,6 +45,11 @@ BOOST_PP_CAT(vector_data, N)() : BOOST_PP_ENUM(N, FUSION_MEMBER_DEFAULT_INIT, _) {} +#if !defined(BOOST_NO_RVALUE_REFERENCES) + BOOST_PP_CAT(vector_data, N)(BOOST_PP_ENUM_BINARY_PARAMS(N, T, && _)) + : BOOST_PP_ENUM(N, FUSION_MOVE, _) {} +#endif + BOOST_PP_CAT(vector_data, N)( BOOST_PP_ENUM_BINARY_PARAMS( N, typename detail::call_param::type _)) @@ -51,6 +59,12 @@ BOOST_PP_CAT(vector_data, N) const& other) : BOOST_PP_ENUM(N, FUSION_COPY_INIT, _) {} +#if !defined(BOOST_NO_RVALUE_REFERENCES) + BOOST_PP_CAT(vector_data, N)( + BOOST_PP_CAT(vector_data, N)&& other) + : BOOST_PP_ENUM(N, FUSION_MOVE_FROM_OTHER, _) {} +#endif + BOOST_PP_CAT(vector_data, N)& operator=(BOOST_PP_CAT(vector_data, N) const& vec) { @@ -105,6 +119,19 @@ N, typename detail::call_param::type _)) : base_type(BOOST_PP_ENUM_PARAMS(N, _)) {} +#if !defined(BOOST_NO_RVALUE_REFERENCES) +#if (N == 1) + explicit +#endif + BOOST_PP_CAT(vector, N)(BOOST_PP_ENUM_BINARY_PARAMS(N, T, && _)) + : base_type(BOOST_PP_ENUM(N, FUSION_FORWARD, _)) {} +#endif + +#if !defined(BOOST_NO_RVALUE_REFERENCES) + BOOST_PP_CAT(vector, N)(BOOST_PP_CAT(vector, N)&& rhs) + : base_type(std::move(rhs)) {} +#endif + template BOOST_PP_CAT(vector, N)( BOOST_PP_CAT(vector, N) const& vec) @@ -166,3 +193,4 @@ #undef N + diff --git a/include/boost/fusion/container/vector/vector.hpp b/include/boost/fusion/container/vector/vector.hpp index 6563bc93..c672bb3e 100644 --- a/include/boost/fusion/container/vector/vector.hpp +++ b/include/boost/fusion/container/vector/vector.hpp @@ -106,6 +106,11 @@ namespace boost { namespace fusion vector(vector const& rhs) : vec(rhs.vec) {} +#if !defined(BOOST_NO_RVALUE_REFERENCES) + vector(vector&& rhs) + : vec(std::move(rhs.vec)) {} +#endif + template vector(Sequence const& rhs) : vec(BOOST_FUSION_VECTOR_COPY_INIT()) {}