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 namespace boost { namespace fusion
17 {
18     struct fusion_sequence_tag;
19 }}
20 
21 namespace boost { namespace fusion { namespace detail
22 {
23     struct nil_keyed_element
24     {
25         typedef fusion_sequence_tag tag;
26         BOOST_FUSION_GPU_ENABLED
27         void get();
28 
29         template<typename It>
30         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
31         static nil_keyed_element
from_iteratorboost::fusion::detail::nil_keyed_element32         from_iterator(It const&)
33         {
34             return nil_keyed_element();
35         }
36     };
37 
38     template <typename Key, typename Value, typename Rest>
39     struct keyed_element : Rest
40     {
41         typedef Rest base;
42         typedef fusion_sequence_tag tag;
43         using Rest::get;
44 
45         template <typename It>
46         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
47         static keyed_element
from_iteratorboost::fusion::detail::keyed_element48         from_iterator(It const& it)
49         {
50             return keyed_element(
51                 *it, base::from_iterator(fusion::next(it)));
52         }
53 
54         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
keyed_elementboost::fusion::detail::keyed_element55         keyed_element(keyed_element const& rhs)
56           : Rest(rhs.get_base()), value_(rhs.value_)
57         {}
58 
59 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
60         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
keyed_elementboost::fusion::detail::keyed_element61         keyed_element(keyed_element&& rhs)
62           : Rest(rhs.forward_base())
63           , value_(BOOST_FUSION_FWD_ELEM(Value, rhs.value_))
64         {}
65 #endif
66 
67         template <typename U, typename Rst>
68         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
keyed_elementboost::fusion::detail::keyed_element69         keyed_element(keyed_element<Key, U, Rst> const& rhs
70           , typename enable_if<is_convertible<U, Value> >::type* = 0)
71           : Rest(rhs.get_base()), value_(rhs.value_)
72         {}
73 
74 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
75 #endif
76 
77         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
get_baseboost::fusion::detail::keyed_element78         Rest& get_base() BOOST_NOEXCEPT
79         {
80             return *this;
81         }
82 
83         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
get_baseboost::fusion::detail::keyed_element84         Rest const& get_base() const BOOST_NOEXCEPT
85         {
86             return *this;
87         }
88 
89 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
90         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
forward_baseboost::fusion::detail::keyed_element91         Rest&& forward_base() BOOST_NOEXCEPT
92         {
93             return std::move(*static_cast<Rest*>(this));
94         }
95 #endif
96 
97         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
getboost::fusion::detail::keyed_element98         typename cref_result<Value>::type get(Key) const
99         {
100             return value_;
101         }
102 
103         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
getboost::fusion::detail::keyed_element104         typename ref_result<Value>::type get(Key)
105         {
106             return value_;
107         }
108 
109         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
keyed_elementboost::fusion::detail::keyed_element110         keyed_element(
111             typename detail::call_param<Value>::type value
112           , Rest const& rest)
113             : Rest(rest), value_(value)
114         {}
115 
116 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
117         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
keyed_elementboost::fusion::detail::keyed_element118         keyed_element(Value&& value, Rest&& rest)
119             : Rest(std::move(rest))
120             , value_(BOOST_FUSION_FWD_ELEM(Value, value))
121         {}
122 #endif
123 
124         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
keyed_elementboost::fusion::detail::keyed_element125         keyed_element()
126             : Rest(), value_()
127         {}
128 
129         template<typename U, typename Rst>
130         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
operator =boost::fusion::detail::keyed_element131         keyed_element& operator=(keyed_element<Key, U, Rst> const& rhs)
132         {
133             base::operator=(static_cast<Rst const&>(rhs)); // cast for msvc-7.1
134             value_ = rhs.value_;
135             return *this;
136         }
137 
138         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
operator =boost::fusion::detail::keyed_element139         keyed_element& operator=(keyed_element const& rhs)
140         {
141             base::operator=(rhs);
142             value_ = rhs.value_;
143             return *this;
144         }
145 
146 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
147         BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
operator =boost::fusion::detail::keyed_element148         keyed_element& operator=(keyed_element&& rhs)
149         {
150             base::operator=(rhs.forward_base());
151             value_ = std::move(rhs.value_);
152             return *this;
153         }
154 #endif
155 
156         Value value_;
157     };
158 
159     template<typename Elem, typename Key>
160     struct keyed_element_value_at
161       : keyed_element_value_at<typename Elem::base, Key>
162     {};
163 
164     template<typename Key, typename Value, typename Rest>
165     struct keyed_element_value_at<keyed_element<Key, Value, Rest>, Key>
166     {
167         typedef Value type;
168     };
169 }}}
170 
171 #endif
172