annotate DEPENDENCIES/generic/include/boost/variant/detail/multivisitors_cpp11_based.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 // Boost.Varaint
Chris@102 2 // Contains multivisitors that are implemented via variadic templates and std::tuple
Chris@102 3 //
Chris@102 4 // See http://www.boost.org for most recent version, including documentation.
Chris@102 5 //
Chris@102 6 // Copyright Antony Polukhin, 2013-2014.
Chris@102 7 //
Chris@102 8 // Distributed under the Boost
Chris@102 9 // Software License, Version 1.0. (See accompanying file
Chris@102 10 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
Chris@102 11
Chris@102 12 #ifndef BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP11_BASED_HPP
Chris@102 13 #define BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP11_BASED_HPP
Chris@102 14
Chris@102 15 #if defined(_MSC_VER)
Chris@102 16 # pragma once
Chris@102 17 #endif
Chris@102 18
Chris@102 19 #include <boost/variant/detail/apply_visitor_unary.hpp>
Chris@102 20 #include "boost/variant/variant_fwd.hpp" // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
Chris@102 21
Chris@102 22 #if defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_HDR_TUPLE)
Chris@102 23 # error "This file requires <tuple> and variadic templates support"
Chris@102 24 #endif
Chris@102 25
Chris@102 26 #include <tuple>
Chris@102 27
Chris@102 28 namespace boost {
Chris@102 29
Chris@102 30 namespace detail { namespace variant {
Chris@102 31
Chris@102 32 // Implementing some of the C++14 features in C++11
Chris@102 33 template <std::size_t... I> class index_sequence {};
Chris@102 34
Chris@102 35 template <std::size_t N, std::size_t... I>
Chris@102 36 struct make_index_sequence
Chris@102 37 : make_index_sequence<N-1, N-1, I...>
Chris@102 38 {};
Chris@102 39 template <std::size_t... I>
Chris@102 40 struct make_index_sequence<0, I...>
Chris@102 41 : index_sequence<I...>
Chris@102 42 {};
Chris@102 43
Chris@102 44 template <class... Types>
Chris@102 45 std::tuple<Types&...> forward_as_tuple_simple(Types&... args) BOOST_NOEXCEPT
Chris@102 46 {
Chris@102 47 return std::tuple<Types&...>(args...);
Chris@102 48 }
Chris@102 49
Chris@102 50 // Implementing some of the helper tuple methods
Chris@102 51 template <std::size_t... I, typename Tuple>
Chris@102 52 std::tuple<typename std::tuple_element<I + 1, Tuple>::type...>
Chris@102 53 tuple_tail_impl(const Tuple& tpl, index_sequence<I...>)
Chris@102 54 {
Chris@102 55 return std::tuple<
Chris@102 56 typename std::tuple_element<I + 1, Tuple>::type...
Chris@102 57 > (std::get<I + 1>(tpl)...);
Chris@102 58 }
Chris@102 59
Chris@102 60 template <typename Head, typename... Tail>
Chris@102 61 std::tuple<Tail...> tuple_tail(const std::tuple<Head, Tail...>& tpl)
Chris@102 62 {
Chris@102 63 return tuple_tail_impl(tpl, make_index_sequence<sizeof...(Tail)>());
Chris@102 64 }
Chris@102 65
Chris@102 66
Chris@102 67
Chris@102 68 // Forward declaration
Chris@102 69 template <typename Visitor, typename Visitables, typename... Values>
Chris@102 70 class one_by_one_visitor_and_value_referer;
Chris@102 71
Chris@102 72 template <typename Visitor, typename Visitables, typename... Values>
Chris@102 73 inline one_by_one_visitor_and_value_referer<Visitor, Visitables, Values... >
Chris@102 74 make_one_by_one_visitor_and_value_referer(
Chris@102 75 Visitor& visitor, Visitables visitables, std::tuple<Values&...> values
Chris@102 76 )
Chris@102 77 {
Chris@102 78 return one_by_one_visitor_and_value_referer<Visitor, Visitables, Values... > (
Chris@102 79 visitor, visitables, values
Chris@102 80 );
Chris@102 81 }
Chris@102 82
Chris@102 83 template <typename Visitor, typename Visitables, typename... Values>
Chris@102 84 class one_by_one_visitor_and_value_referer
Chris@102 85 {
Chris@102 86 Visitor& visitor_;
Chris@102 87 std::tuple<Values&...> values_;
Chris@102 88 Visitables visitables_;
Chris@102 89
Chris@102 90 public: // structors
Chris@102 91 one_by_one_visitor_and_value_referer(
Chris@102 92 Visitor& visitor, Visitables visitables, std::tuple<Values&...> values
Chris@102 93 ) BOOST_NOEXCEPT
Chris@102 94 : visitor_(visitor)
Chris@102 95 , values_(values)
Chris@102 96 , visitables_(visitables)
Chris@102 97 {}
Chris@102 98
Chris@102 99 public: // visitor interfaces
Chris@102 100 typedef typename Visitor::result_type result_type;
Chris@102 101
Chris@102 102 template <typename Value>
Chris@102 103 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) operator()(Value& value) const
Chris@102 104 {
Chris@102 105 return ::boost::apply_visitor(
Chris@102 106 make_one_by_one_visitor_and_value_referer(
Chris@102 107 visitor_,
Chris@102 108 tuple_tail(visitables_),
Chris@102 109 std::tuple_cat(values_, std::tuple<Value&>(value))
Chris@102 110 )
Chris@102 111 , std::get<0>(visitables_) // getting Head element
Chris@102 112 );
Chris@102 113 }
Chris@102 114
Chris@102 115 private:
Chris@102 116 one_by_one_visitor_and_value_referer& operator=(const one_by_one_visitor_and_value_referer&);
Chris@102 117 };
Chris@102 118
Chris@102 119 template <typename Visitor, typename... Values>
Chris@102 120 class one_by_one_visitor_and_value_referer<Visitor, std::tuple<>, Values...>
Chris@102 121 {
Chris@102 122 Visitor& visitor_;
Chris@102 123 std::tuple<Values&...> values_;
Chris@102 124
Chris@102 125 public:
Chris@102 126 one_by_one_visitor_and_value_referer(
Chris@102 127 Visitor& visitor, std::tuple<> /*visitables*/, std::tuple<Values&...> values
Chris@102 128 ) BOOST_NOEXCEPT
Chris@102 129 : visitor_(visitor)
Chris@102 130 , values_(values)
Chris@102 131 {}
Chris@102 132
Chris@102 133 typedef typename Visitor::result_type result_type;
Chris@102 134
Chris@102 135 template <class Tuple, std::size_t... I>
Chris@102 136 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) do_call(Tuple t, index_sequence<I...>) const {
Chris@102 137 return visitor_(std::get<I>(t)...);
Chris@102 138 }
Chris@102 139
Chris@102 140 template <typename Value>
Chris@102 141 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) operator()(Value& value) const
Chris@102 142 {
Chris@102 143 return do_call(
Chris@102 144 std::tuple_cat(values_, std::tuple<Value&>(value)),
Chris@102 145 make_index_sequence<sizeof...(Values) + 1>()
Chris@102 146 );
Chris@102 147 }
Chris@102 148 };
Chris@102 149
Chris@102 150 }} // namespace detail::variant
Chris@102 151
Chris@102 152 template <class Visitor, class T1, class T2, class T3, class... TN>
Chris@102 153 inline BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
Chris@102 154 apply_visitor(const Visitor& visitor, T1& v1, T2& v2, T3& v3, TN&... vn)
Chris@102 155 {
Chris@102 156 return ::boost::apply_visitor(
Chris@102 157 ::boost::detail::variant::make_one_by_one_visitor_and_value_referer(
Chris@102 158 visitor,
Chris@102 159 ::boost::detail::variant::forward_as_tuple_simple(v2, v3, vn...),
Chris@102 160 std::tuple<>()
Chris@102 161 ),
Chris@102 162 v1
Chris@102 163 );
Chris@102 164 }
Chris@102 165
Chris@102 166 template <class Visitor, class T1, class T2, class T3, class... TN>
Chris@102 167 inline BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
Chris@102 168 apply_visitor(Visitor& visitor, T1& v1, T2& v2, T3& v3, TN&... vn)
Chris@102 169 {
Chris@102 170 return ::boost::apply_visitor(
Chris@102 171 ::boost::detail::variant::make_one_by_one_visitor_and_value_referer(
Chris@102 172 visitor,
Chris@102 173 ::boost::detail::variant::forward_as_tuple_simple(v2, v3, vn...),
Chris@102 174 std::tuple<>()
Chris@102 175 ),
Chris@102 176 v1
Chris@102 177 );
Chris@102 178 }
Chris@102 179
Chris@102 180 } // namespace boost
Chris@102 181
Chris@102 182 #endif // BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP11_BASED_HPP
Chris@102 183