Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:34:40

0001 /*=============================================================================
0002     Copyright (c) 2014-2015 Kohei Takahashi
0003 
0004     Distributed under the Boost Software License, Version 1.0. (See accompanying
0005     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // Without variadics, we will use the PP version
0017 ///////////////////////////////////////////////////////////////////////////////
0018 #if !defined(BOOST_FUSION_HAS_VARIADIC_VECTOR)
0019 # include <boost/fusion/container/vector/detail/cpp03/vector.hpp>
0020 #else
0021 
0022 ///////////////////////////////////////////////////////////////////////////////
0023 // C++11 interface
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         // forward_at_c allows to access Nth element even if ForwardSequence
0098         // since fusion::at_c requires RandomAccessSequence.
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         // Object proxy since preserve object order
0126         template <std::size_t, typename T>
0127         struct store
0128         {
0129             BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0130             store()
0131                 : elem() // value-initialized explicitly
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         // placed outside of vector_data due to GCC < 6 bug
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; // this gets picked up by MPL
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     } // namespace boost::fusion::vector_detail
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         // XXX: constexpr become error due to pull-request #79, booooo!!
0278         //      In the (near) future release, should be fixed.
0279         /* BOOST_CONSTEXPR */ 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