File indexing completed on 2025-01-18 09:34:40
0001
0002
0003
0004
0005
0006
0007 #ifndef FUSION_VECTOR_11052014_1625
0008 #define FUSION_VECTOR_11052014_1625
0009
0010 #include <boost/config.hpp>
0011 #include <boost/fusion/support/config.hpp>
0012 #include <boost/fusion/container/vector/detail/config.hpp>
0013 #include <boost/fusion/container/vector/vector_fwd.hpp>
0014
0015
0016
0017
0018 #if !defined(BOOST_FUSION_HAS_VARIADIC_VECTOR)
0019 # include <boost/fusion/container/vector/detail/cpp03/vector.hpp>
0020 #else
0021
0022
0023
0024
0025 #include <boost/fusion/support/sequence_base.hpp>
0026 #include <boost/fusion/support/is_sequence.hpp>
0027 #include <boost/fusion/support/detail/and.hpp>
0028 #include <boost/fusion/support/detail/index_sequence.hpp>
0029 #include <boost/fusion/container/vector/detail/at_impl.hpp>
0030 #include <boost/fusion/container/vector/detail/value_at_impl.hpp>
0031 #include <boost/fusion/container/vector/detail/begin_impl.hpp>
0032 #include <boost/fusion/container/vector/detail/end_impl.hpp>
0033 #include <boost/fusion/sequence/intrinsic/begin.hpp>
0034 #include <boost/fusion/sequence/intrinsic/size.hpp>
0035 #include <boost/fusion/iterator/advance.hpp>
0036 #include <boost/fusion/iterator/deref.hpp>
0037 #include <boost/core/enable_if.hpp>
0038 #include <boost/mpl/int.hpp>
0039 #include <boost/type_traits/integral_constant.hpp>
0040 #include <boost/type_traits/is_base_of.hpp>
0041 #include <boost/type_traits/is_convertible.hpp>
0042 #include <boost/type_traits/remove_reference.hpp>
0043 #include <cstddef>
0044 #include <utility>
0045
0046 namespace boost { namespace fusion
0047 {
0048 struct vector_tag;
0049 struct random_access_traversal_tag;
0050
0051 namespace vector_detail
0052 {
0053 struct each_elem {};
0054
0055 template <
0056 typename This, typename T, typename T_, std::size_t Size, bool IsSeq
0057 >
0058 struct can_convert_impl : false_type {};
0059
0060 template <typename This, typename T, typename Sequence, std::size_t Size>
0061 struct can_convert_impl<This, T, Sequence, Size, true> : true_type {};
0062
0063 template <typename This, typename Sequence, typename T>
0064 struct can_convert_impl<This, Sequence, T, 1, true>
0065 : integral_constant<
0066 bool
0067 , !is_convertible<
0068 Sequence
0069 , typename fusion::extension::value_at_impl<vector_tag>::
0070 template apply< This, mpl::int_<0> >::type
0071 >::value
0072 >
0073 {};
0074
0075 template <typename This, typename T, typename T_, std::size_t Size>
0076 struct can_convert
0077 : can_convert_impl<
0078 This, T, T_, Size, traits::is_sequence<T_>::value
0079 >
0080 {};
0081
0082 template <typename T, bool IsSeq, std::size_t Size>
0083 struct is_longer_sequence_impl : false_type {};
0084
0085 template <typename Sequence, std::size_t Size>
0086 struct is_longer_sequence_impl<Sequence, true, Size>
0087 : integral_constant<
0088 bool, (fusion::result_of::size<Sequence>::value >= Size)
0089 >
0090 {};
0091
0092 template<typename T, std::size_t Size>
0093 struct is_longer_sequence
0094 : is_longer_sequence_impl<T, traits::is_sequence<T>::value, Size>
0095 {};
0096
0097
0098
0099 namespace result_of
0100 {
0101 template <typename Sequence, int N>
0102 struct forward_at_c
0103 : fusion::result_of::deref<
0104 typename fusion::result_of::advance_c<
0105 typename fusion::result_of::begin<
0106 typename remove_reference<Sequence>::type
0107 >::type
0108 , N
0109 >::type
0110 >
0111 {};
0112 }
0113
0114 template <int N, typename Sequence>
0115 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0116 inline typename result_of::forward_at_c<Sequence, N>::type
0117 forward_at_c(Sequence&& seq)
0118 {
0119 typedef typename
0120 result_of::forward_at_c<Sequence, N>::type
0121 result;
0122 return std::forward<result>(*advance_c<N>(begin(seq)));
0123 }
0124
0125
0126 template <std::size_t, typename T>
0127 struct store
0128 {
0129 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0130 store()
0131 : elem()
0132 {}
0133
0134 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0135 store(store const& rhs)
0136 : elem(rhs.elem)
0137 {}
0138
0139 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0140 store&
0141 operator=(store const& rhs)
0142 {
0143 elem = rhs.elem;
0144 return *this;
0145 }
0146
0147 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0148 store(store&& rhs)
0149 : elem(static_cast<T&&>(rhs.elem))
0150 {}
0151
0152 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0153 store&
0154 operator=(store&& rhs)
0155 {
0156 elem = static_cast<T&&>(rhs.elem);
0157 return *this;
0158 }
0159
0160 template <
0161 typename U
0162 , typename = typename boost::disable_if<
0163 is_base_of<store, typename remove_reference<U>::type>
0164 >::type
0165 >
0166 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0167 store(U&& rhs)
0168 : elem(std::forward<U>(rhs))
0169 {}
0170
0171 using elem_type = T;
0172 T elem;
0173 };
0174
0175
0176 template <std::size_t J, typename U>
0177 static inline BOOST_FUSION_GPU_ENABLED
0178 store<J, U> store_at_impl(store<J, U>*);
0179
0180 template <typename I, typename ...T>
0181 struct vector_data;
0182
0183 template <std::size_t ...I, typename ...T>
0184 struct vector_data<detail::index_sequence<I...>, T...>
0185 : store<I, T>...
0186 , sequence_base<vector_data<detail::index_sequence<I...>, T...> >
0187 {
0188 typedef vector_tag fusion_tag;
0189 typedef fusion_sequence_tag tag;
0190 typedef mpl::false_ is_view;
0191 typedef random_access_traversal_tag category;
0192 typedef mpl::int_<sizeof...(T)> size;
0193 typedef vector<T...> type_sequence;
0194
0195 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0196 BOOST_DEFAULTED_FUNCTION(vector_data(), {})
0197
0198 template <
0199 typename Sequence
0200 , typename Sequence_ = typename remove_reference<Sequence>::type
0201 , typename = typename boost::enable_if<
0202 can_convert<vector_data, Sequence, Sequence_, sizeof...(I)>
0203 >::type
0204 >
0205 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0206 explicit
0207 vector_data(each_elem, Sequence&& rhs)
0208 : store<I, T>(forward_at_c<I>(std::forward<Sequence>(rhs)))...
0209 {}
0210
0211 template <typename ...U>
0212 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0213 explicit
0214 vector_data(each_elem, U&&... var)
0215 : store<I, T>(std::forward<U>(var))...
0216 {}
0217
0218 template <typename Sequence>
0219 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0220 void
0221 assign_sequence(Sequence&& seq)
0222 {
0223 #ifndef BOOST_NO_CXX17_FOLD_EXPRESSIONS
0224 (void(store<I, T>::elem = vector_detail::forward_at_c<I>(static_cast<Sequence&&>(seq))), ...);
0225 #else
0226 int nofold[] = { (void(store<I, T>::elem = vector_detail::forward_at_c<I>(static_cast<Sequence&&>(seq))), 0)..., 0 };
0227 (void)nofold;
0228 #endif
0229 }
0230
0231 private:
0232 template <std::size_t J>
0233 using store_at = decltype(store_at_impl<J>(static_cast<vector_data*>(nullptr)));
0234
0235 public:
0236 template <typename J>
0237 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0238 typename store_at<J::value>::elem_type& at_impl(J)
0239 {
0240 return store_at<J::value>::elem;
0241 }
0242
0243 template <typename J>
0244 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0245 typename store_at<J::value>::elem_type const& at_impl(J) const
0246 {
0247 return store_at<J::value>::elem;
0248 }
0249 };
0250 }
0251
0252 template <typename... T>
0253 struct vector
0254 : vector_detail::vector_data<
0255 typename detail::make_index_sequence<sizeof...(T)>::type
0256 , T...
0257 >
0258 {
0259 typedef vector_detail::vector_data<
0260 typename detail::make_index_sequence<sizeof...(T)>::type
0261 , T...
0262 > base;
0263
0264 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0265 BOOST_DEFAULTED_FUNCTION(vector(), {})
0266
0267 template <
0268 typename... U
0269 , typename = typename boost::enable_if_c<(
0270 sizeof...(U) >= 1 &&
0271 fusion::detail::and_<is_convertible<U, T>...>::value &&
0272 !fusion::detail::and_<
0273 is_base_of<vector, typename remove_reference<U>::type>...
0274 >::value
0275 )>::type
0276 >
0277
0278
0279 BOOST_FUSION_GPU_ENABLED
0280 explicit vector(U&&... u)
0281 : base(vector_detail::each_elem(), std::forward<U>(u)...)
0282 {}
0283
0284 template <
0285 typename Sequence
0286 , typename = typename boost::enable_if_c<
0287 vector_detail::is_longer_sequence<
0288 typename remove_reference<Sequence>::type, sizeof...(T)
0289 >::value
0290 >::type
0291 >
0292 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0293 vector(Sequence&& seq)
0294 : base(vector_detail::each_elem(), std::forward<Sequence>(seq))
0295 {}
0296
0297 template <typename Sequence>
0298 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0299 vector&
0300 operator=(Sequence&& rhs)
0301 {
0302 base::assign_sequence(std::forward<Sequence>(rhs));
0303 return *this;
0304 }
0305 };
0306 }}
0307
0308 #endif
0309 #endif
0310