1 /*============================================================================= 2 Copyright (c) 2005-2012 Joel de Guzman 3 Copyright (c) 2005-2006 Dan Marsden 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 ==============================================================================*/ 8 #if !defined(BOOST_FUSION_DEQUE_DETAIL_KEYED_ELEMENT_26112006_1330) 9 #define BOOST_FUSION_DEQUE_DETAIL_KEYED_ELEMENT_26112006_1330 10 11 #include <boost/fusion/support/config.hpp> 12 #include <boost/fusion/support/detail/access.hpp> 13 #include <boost/fusion/iterator/deref.hpp> 14 #include <boost/fusion/iterator/next.hpp> 15 16 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && BOOST_WORKAROUND(BOOST_GCC, / 100 == 404) 17 #include <boost/core/enable_if.hpp> 18 #include <boost/type_traits/is_same.hpp> 19 #endif 20 21 namespace boost { namespace fusion 22 { 23 struct fusion_sequence_tag; 24 }} 25 26 namespace boost { namespace fusion { namespace detail 27 { 28 struct nil_keyed_element 29 { 30 typedef fusion_sequence_tag tag; 31 BOOST_FUSION_GPU_ENABLED 32 void get(); 33 34 template<typename It> 35 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 36 static nil_keyed_element from_iteratorboost::fusion::detail::nil_keyed_element37 from_iterator(It const&) 38 { 39 return nil_keyed_element(); 40 } 41 }; 42 43 template <typename Key, typename Value, typename Rest> 44 struct keyed_element : Rest 45 { 46 typedef Rest base; 47 typedef fusion_sequence_tag tag; 48 using Rest::get; 49 50 template <typename It> 51 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 52 static keyed_element from_iteratorboost::fusion::detail::keyed_element53 from_iterator(It const& it) 54 { 55 return keyed_element( 56 *it, base::from_iterator(fusion::next(it))); 57 } 58 59 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED keyed_elementboost::fusion::detail::keyed_element60 keyed_element(keyed_element const& rhs) 61 : Rest(rhs.get_base()), value_(rhs.value_) 62 {} 63 64 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 65 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED keyed_elementboost::fusion::detail::keyed_element66 keyed_element(keyed_element&& rhs) 67 : Rest(rhs.forward_base()) 68 , value_(BOOST_FUSION_FWD_ELEM(Value, rhs.value_)) 69 {} 70 #endif 71 72 template <typename U, typename Rst> 73 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED keyed_elementboost::fusion::detail::keyed_element74 keyed_element(keyed_element<Key, U, Rst> const& rhs 75 , typename enable_if<is_convertible<U, Value> >::type* = 0) 76 : Rest(rhs.get_base()), value_(rhs.value_) 77 {} 78 79 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 80 #endif 81 82 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED get_baseboost::fusion::detail::keyed_element83 Rest& get_base() BOOST_NOEXCEPT 84 { 85 return *this; 86 } 87 88 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED get_baseboost::fusion::detail::keyed_element89 Rest const& get_base() const BOOST_NOEXCEPT 90 { 91 return *this; 92 } 93 94 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 95 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED forward_baseboost::fusion::detail::keyed_element96 Rest&& forward_base() BOOST_NOEXCEPT 97 { 98 return std::move(*static_cast<Rest*>(this)); 99 } 100 #endif 101 102 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED getboost::fusion::detail::keyed_element103 typename cref_result<Value>::type get(Key) const 104 { 105 return value_; 106 } 107 108 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED getboost::fusion::detail::keyed_element109 typename ref_result<Value>::type get(Key) 110 { 111 return value_; 112 } 113 114 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED keyed_elementboost::fusion::detail::keyed_element115 keyed_element( 116 typename detail::call_param<Value>::type value 117 , Rest const& rest) 118 : Rest(rest), value_(value) 119 {} 120 121 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 122 #if BOOST_WORKAROUND(BOOST_GCC, / 100 == 404) 123 template <typename Value_, typename = typename enable_if<is_same<Value_, Value> >::type> 124 #else 125 typedef Value Value_; 126 #endif 127 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED keyed_elementboost::fusion::detail::keyed_element128 keyed_element(Value_&& value, Rest&& rest) 129 : Rest(std::move(rest)) 130 , value_(BOOST_FUSION_FWD_ELEM(Value, value)) 131 {} 132 #endif 133 134 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED keyed_elementboost::fusion::detail::keyed_element135 keyed_element() 136 : Rest(), value_() 137 {} 138 139 template<typename U, typename Rst> 140 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED operator =boost::fusion::detail::keyed_element141 keyed_element& operator=(keyed_element<Key, U, Rst> const& rhs) 142 { 143 base::operator=(static_cast<Rst const&>(rhs)); // cast for msvc-7.1 144 value_ = rhs.value_; 145 return *this; 146 } 147 148 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED operator =boost::fusion::detail::keyed_element149 keyed_element& operator=(keyed_element const& rhs) 150 { 151 base::operator=(rhs); 152 value_ = rhs.value_; 153 return *this; 154 } 155 156 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 157 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED operator =boost::fusion::detail::keyed_element158 keyed_element& operator=(keyed_element&& rhs) 159 { 160 base::operator=(rhs.forward_base()); 161 value_ = std::move(rhs.value_); 162 return *this; 163 } 164 #endif 165 166 Value value_; 167 }; 168 169 template<typename Elem, typename Key> 170 struct keyed_element_value_at 171 : keyed_element_value_at<typename Elem::base, Key> 172 {}; 173 174 template<typename Key, typename Value, typename Rest> 175 struct keyed_element_value_at<keyed_element<Key, Value, Rest>, Key> 176 { 177 typedef Value type; 178 }; 179 }}} 180 181 #endif 182