Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:32

0001 //  Boost.Varaint
0002 //  Contains multivisitors that are implemented via variadic templates, std::tuple
0003 //  and decltype(auto)
0004 //
0005 //  See http://www.boost.org for most recent version, including documentation.
0006 //
0007 //  Copyright Antony Polukhin, 2013-2014.
0008 //
0009 //  Distributed under the Boost
0010 //  Software License, Version 1.0. (See accompanying file
0011 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
0012 
0013 #ifndef BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP14_BASED_HPP
0014 #define BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP14_BASED_HPP
0015 
0016 #if defined(_MSC_VER)
0017 # pragma once
0018 #endif
0019 
0020 #include <tuple>
0021 
0022 namespace boost {
0023 
0024 namespace detail { namespace variant {
0025 
0026     // Forward declaration
0027     template <typename Visitor, typename Visitables, typename... Values>
0028     class one_by_one_visitor_and_value_referer_cpp14;
0029 
0030     template <typename Visitor, typename Visitables, typename... Values>
0031     inline one_by_one_visitor_and_value_referer_cpp14<Visitor, Visitables, Values... >
0032         make_one_by_one_visitor_and_value_referer_cpp14(
0033             Visitor& visitor, Visitables visitables, std::tuple<Values...> values
0034         )
0035     {
0036         return one_by_one_visitor_and_value_referer_cpp14<Visitor, Visitables, Values... > (
0037             visitor, visitables, values
0038         );
0039     }
0040 
0041     template <typename Visitor, typename Visitables, typename... Values>
0042     class one_by_one_visitor_and_value_referer_cpp14
0043     {
0044         Visitor&                        visitor_;
0045         std::tuple<Values...>           values_;
0046         Visitables                      visitables_;
0047 
0048     public: // structors
0049         one_by_one_visitor_and_value_referer_cpp14(
0050                     Visitor& visitor, Visitables visitables, std::tuple<Values...> values
0051                 ) BOOST_NOEXCEPT
0052             : visitor_(visitor)
0053             , values_(values)
0054             , visitables_(visitables)
0055         {}
0056 
0057     public: // visitor interfaces
0058         template <typename Value>
0059         decltype(auto) operator()(Value&& value) const
0060         {
0061             return ::boost::apply_visitor(
0062                 make_one_by_one_visitor_and_value_referer_cpp14(
0063                     visitor_,
0064                     tuple_tail(visitables_),
0065                     std::tuple_cat(values_, std::make_tuple(wrap<Value, ! ::boost::is_lvalue_reference<Value>::value>(value)))
0066                 )
0067                 , unwrap(std::get<0>(visitables_)) // getting Head element
0068             );
0069         }
0070 
0071     private:
0072         one_by_one_visitor_and_value_referer_cpp14& operator=(const one_by_one_visitor_and_value_referer_cpp14&);
0073     };
0074 
0075     template <typename Visitor, typename... Values>
0076     class one_by_one_visitor_and_value_referer_cpp14<Visitor, std::tuple<>, Values...>
0077     {
0078         Visitor&                        visitor_;
0079         std::tuple<Values...>           values_;
0080 
0081     public:
0082         one_by_one_visitor_and_value_referer_cpp14(
0083                     Visitor& visitor, std::tuple<> /*visitables*/, std::tuple<Values...> values
0084                 ) BOOST_NOEXCEPT
0085             : visitor_(visitor)
0086             , values_(values)
0087         {}
0088 
0089         template <class Tuple, std::size_t... I>
0090         decltype(auto) do_call(Tuple t, index_sequence<I...>) const {
0091             return visitor_(unwrap(std::get<I>(t))...);
0092         }
0093 
0094         template <typename Value>
0095         decltype(auto) operator()(Value&& value) const
0096         {
0097             return do_call(
0098                 std::tuple_cat(values_, std::make_tuple(wrap<Value, ! ::boost::is_lvalue_reference<Value>::value>(value))),
0099                 make_index_sequence<sizeof...(Values) + 1>()
0100             );
0101         }
0102     };
0103 
0104 }} // namespace detail::variant
0105 
0106     template <class Visitor, class T1, class T2, class T3, class... TN>
0107     inline decltype(auto) apply_visitor(const Visitor& visitor, T1&& v1, T2&& v2, T3&& v3, TN&&... vn,
0108         typename boost::disable_if<
0109             boost::detail::variant::has_result_type<Visitor>,
0110             bool
0111         >::type = true)
0112     {
0113         return boost::apply_visitor(
0114             ::boost::detail::variant::make_one_by_one_visitor_and_value_referer_cpp14(
0115                 visitor,
0116                 std::make_tuple(
0117                     ::boost::detail::variant::wrap<T2, ! ::boost::is_lvalue_reference<T2>::value>(v2),
0118                     ::boost::detail::variant::wrap<T3, ! ::boost::is_lvalue_reference<T3>::value>(v3),
0119                     ::boost::detail::variant::wrap<TN, ! ::boost::is_lvalue_reference<TN>::value>(vn)...
0120                     ),
0121                 std::tuple<>()
0122             ),
0123             std::forward<T1>(v1)
0124         );
0125     }
0126 
0127 
0128     template <class Visitor, class T1, class T2, class T3, class... TN>
0129     inline decltype(auto) apply_visitor(Visitor& visitor, T1&& v1, T2&& v2, T3&& v3, TN&&... vn,
0130         typename boost::disable_if<
0131             boost::detail::variant::has_result_type<Visitor>,
0132             bool
0133         >::type = true)
0134     {
0135         return ::boost::apply_visitor(
0136             ::boost::detail::variant::make_one_by_one_visitor_and_value_referer_cpp14(
0137                 visitor,
0138                 std::make_tuple(
0139                     ::boost::detail::variant::wrap<T2, ! ::boost::is_lvalue_reference<T2>::value>(v2),
0140                     ::boost::detail::variant::wrap<T3, ! ::boost::is_lvalue_reference<T3>::value>(v3),
0141                     ::boost::detail::variant::wrap<TN, ! ::boost::is_lvalue_reference<TN>::value>(vn)...
0142                     ),
0143                 std::tuple<>()
0144             ),
0145             std::forward<T1>(v1)
0146         );
0147     }
0148 
0149 } // namespace boost
0150 
0151 #endif // BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP14_BASED_HPP
0152