• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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