tomoto 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +3 -3
  5. data/ext/tomoto/ext.cpp +34 -9
  6. data/ext/tomoto/extconf.rb +2 -1
  7. data/lib/tomoto/dmr.rb +1 -1
  8. data/lib/tomoto/gdmr.rb +1 -1
  9. data/lib/tomoto/version.rb +1 -1
  10. data/vendor/tomotopy/LICENSE +1 -1
  11. data/vendor/tomotopy/README.kr.rst +32 -3
  12. data/vendor/tomotopy/README.rst +30 -1
  13. data/vendor/tomotopy/src/Labeling/FoRelevance.cpp +133 -147
  14. data/vendor/tomotopy/src/Labeling/FoRelevance.h +158 -5
  15. data/vendor/tomotopy/src/TopicModel/DMR.h +1 -16
  16. data/vendor/tomotopy/src/TopicModel/DMRModel.hpp +15 -34
  17. data/vendor/tomotopy/src/TopicModel/DT.h +1 -16
  18. data/vendor/tomotopy/src/TopicModel/DTModel.hpp +15 -32
  19. data/vendor/tomotopy/src/TopicModel/GDMRModel.hpp +18 -37
  20. data/vendor/tomotopy/src/TopicModel/HDPModel.hpp +16 -20
  21. data/vendor/tomotopy/src/TopicModel/HLDAModel.hpp +3 -3
  22. data/vendor/tomotopy/src/TopicModel/LDA.h +0 -11
  23. data/vendor/tomotopy/src/TopicModel/LDAModel.hpp +9 -21
  24. data/vendor/tomotopy/src/TopicModel/LLDA.h +0 -15
  25. data/vendor/tomotopy/src/TopicModel/LLDAModel.hpp +12 -30
  26. data/vendor/tomotopy/src/TopicModel/MGLDA.h +0 -15
  27. data/vendor/tomotopy/src/TopicModel/MGLDAModel.hpp +59 -72
  28. data/vendor/tomotopy/src/TopicModel/PLDAModel.hpp +12 -30
  29. data/vendor/tomotopy/src/TopicModel/SLDA.h +0 -15
  30. data/vendor/tomotopy/src/TopicModel/SLDAModel.hpp +17 -35
  31. data/vendor/tomotopy/src/TopicModel/TopicModel.hpp +158 -38
  32. data/vendor/tomotopy/src/Utils/Dictionary.h +40 -2
  33. data/vendor/tomotopy/src/Utils/EigenAddonOps.hpp +122 -3
  34. data/vendor/tomotopy/src/Utils/SharedString.hpp +181 -0
  35. data/vendor/tomotopy/src/Utils/math.h +1 -1
  36. data/vendor/tomotopy/src/Utils/sample.hpp +1 -1
  37. data/vendor/tomotopy/src/Utils/serializer.hpp +17 -0
  38. data/vendor/variant/LICENSE +25 -0
  39. data/vendor/variant/LICENSE_1_0.txt +23 -0
  40. data/vendor/variant/README.md +102 -0
  41. data/vendor/variant/include/mapbox/optional.hpp +74 -0
  42. data/vendor/variant/include/mapbox/recursive_wrapper.hpp +122 -0
  43. data/vendor/variant/include/mapbox/variant.hpp +974 -0
  44. data/vendor/variant/include/mapbox/variant_io.hpp +45 -0
  45. metadata +15 -7
@@ -0,0 +1,25 @@
1
+ Copyright (c) MapBox
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ - Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ - Redistributions in binary form must reproduce the above copyright notice, this
10
+ list of conditions and the following disclaimer in the documentation and/or
11
+ other materials provided with the distribution.
12
+ - Neither the name "MapBox" nor the names of its contributors may be
13
+ used to endorse or promote products derived from this software without
14
+ specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
20
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,23 @@
1
+ Boost Software License - Version 1.0 - August 17th, 2003
2
+
3
+ Permission is hereby granted, free of charge, to any person or organization
4
+ obtaining a copy of the software and accompanying documentation covered by
5
+ this license (the "Software") to use, reproduce, display, distribute,
6
+ execute, and transmit the Software, and to prepare derivative works of the
7
+ Software, and to permit third-parties to whom the Software is furnished to
8
+ do so, all subject to the following:
9
+
10
+ The copyright notices in the Software and this entire statement, including
11
+ the above license grant, this restriction and the following disclaimer,
12
+ must be included in all copies of the Software, in whole or in part, and
13
+ all derivative works of the Software, unless such copies or derivative
14
+ works are solely in the form of machine-executable object code generated by
15
+ a source language processor.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
20
+ SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
21
+ FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
22
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,102 @@
1
+ # Mapbox Variant
2
+
3
+ An alternative to `boost::variant` for C++11 and C++14
4
+
5
+ [![Build Status](https://secure.travis-ci.org/mapbox/variant.svg)](https://travis-ci.org/mapbox/variant)
6
+ [![Build status](https://ci.appveyor.com/api/projects/status/v9tatx21j1k0fcgy)](https://ci.appveyor.com/project/Mapbox/variant)
7
+ [![Coverage Status](https://coveralls.io/repos/mapbox/variant/badge.svg?branch=master&service=github)](https://coveralls.io/r/mapbox/variant?branch=master)
8
+
9
+
10
+ ## Why use Mapbox Variant?
11
+
12
+ Mapbox variant has the same speedy performance of `boost::variant` but is
13
+ faster to compile, results in smaller binaries, and has no dependencies.
14
+
15
+ For example on OS X 10.9 with clang++ and libc++:
16
+
17
+ Test | Mapbox Variant | Boost Variant
18
+ ---- | -------------- | -------------
19
+ Size of pre-compiled header (release / debug) | 2.8/2.8 MB | 12/15 MB
20
+ Size of simple program linking variant (release / debug) | 8/24 K | 12/40 K
21
+ Time to compile header | 185 ms | 675 ms
22
+
23
+ (Numbers from an older version of Mapbox variant.)
24
+
25
+
26
+ ## Goals
27
+
28
+ Mapbox `variant` has been a very valuable, lightweight alternative for apps
29
+ that can use c++11 or c++14 but that do not want a boost dependency.
30
+ Mapbox `variant` has also been useful in apps that do depend on boost, like
31
+ mapnik, to help (slightly) with compile times and to majorly lessen dependence
32
+ on boost in core headers. The original goal and near term goal is to maintain
33
+ external API compatibility with `boost::variant` such that Mapbox `variant`
34
+ can be a "drop in". At the same time the goal is to stay minimal: Only
35
+ implement the features that are actually needed in existing software. So being
36
+ an "incomplete" implementation is just fine.
37
+
38
+ Currently Mapbox variant doesn't try to be API compatible with the upcoming
39
+ variant standard, because the standard is not finished and it would be too much
40
+ work. But we'll revisit this decision in the future if needed.
41
+
42
+ If Mapbox variant is not for you, have a look at [these other
43
+ implementations](doc/other_implementations.md).
44
+
45
+ Want to know more about the upcoming standard? Have a look at our
46
+ [overview](doc/standards_effort.md).
47
+
48
+
49
+ ## Depends
50
+
51
+ - Compiler supporting `-std=c++11` or `-std=c++14`
52
+
53
+ Tested with:
54
+
55
+ - g++-4.7
56
+ - g++-4.8
57
+ - g++-4.9
58
+ - g++-5.2
59
+ - clang++-3.5
60
+ - clang++-3.6
61
+ - clang++-3.7
62
+ - clang++-3.8
63
+ - clang++-3.9
64
+ - Visual Studio 2015
65
+
66
+ ## Usage
67
+
68
+ There is nothing to build, just include `variant.hpp` in your project. Include `variant_io.hpp` if you need
69
+ the `operator<<` overload for variant.
70
+
71
+
72
+ ## Unit Tests
73
+
74
+ On Unix systems compile and run the unit tests with `make test`.
75
+
76
+ On Windows run `scripts/build-local.bat`.
77
+
78
+
79
+ ## Limitations
80
+
81
+ * The `variant` can not hold references (something like `variant<int&>` is
82
+ not possible). You might want to try `std::reference_wrapper` instead.
83
+
84
+
85
+ ## Deprecations
86
+
87
+ * The included implementation of `optional` is deprecated and will be removed
88
+ in a future version. See https://github.com/mapbox/variant/issues/64.
89
+ * Old versions of the code needed visitors to derive from `static_visitor`.
90
+ This is not needed any more and marked as deprecated. The `static_visitor`
91
+ class will be removed in future versions.
92
+
93
+
94
+ ## Benchmarks
95
+
96
+ make bench
97
+
98
+
99
+ ## Check object sizes
100
+
101
+ make sizes /path/to/boost/variant.hpp
102
+
@@ -0,0 +1,74 @@
1
+ #ifndef MAPBOX_UTIL_OPTIONAL_HPP
2
+ #define MAPBOX_UTIL_OPTIONAL_HPP
3
+
4
+ #pragma message("This implementation of optional is deprecated. See https://github.com/mapbox/variant/issues/64.")
5
+
6
+ #include <type_traits>
7
+ #include <utility>
8
+
9
+ #include <mapbox/variant.hpp>
10
+
11
+ namespace mapbox {
12
+ namespace util {
13
+
14
+ template <typename T>
15
+ class optional
16
+ {
17
+ static_assert(!std::is_reference<T>::value, "optional doesn't support references");
18
+
19
+ struct none_type
20
+ {
21
+ };
22
+
23
+ variant<none_type, T> variant_;
24
+
25
+ public:
26
+ optional() = default;
27
+
28
+ optional(optional const& rhs)
29
+ {
30
+ if (this != &rhs)
31
+ { // protect against invalid self-assignment
32
+ variant_ = rhs.variant_;
33
+ }
34
+ }
35
+
36
+ optional(T const& v) { variant_ = v; }
37
+
38
+ explicit operator bool() const noexcept { return variant_.template is<T>(); }
39
+
40
+ T const& get() const { return variant_.template get<T>(); }
41
+ T& get() { return variant_.template get<T>(); }
42
+
43
+ T const& operator*() const { return this->get(); }
44
+ T operator*() { return this->get(); }
45
+
46
+ optional& operator=(T const& v)
47
+ {
48
+ variant_ = v;
49
+ return *this;
50
+ }
51
+
52
+ optional& operator=(optional const& rhs)
53
+ {
54
+ if (this != &rhs)
55
+ {
56
+ variant_ = rhs.variant_;
57
+ }
58
+ return *this;
59
+ }
60
+
61
+ template <typename... Args>
62
+ void emplace(Args&&... args)
63
+ {
64
+ variant_ = T{std::forward<Args>(args)...};
65
+ }
66
+
67
+ void reset() { variant_ = none_type{}; }
68
+
69
+ }; // class optional
70
+
71
+ } // namespace util
72
+ } // namespace mapbox
73
+
74
+ #endif // MAPBOX_UTIL_OPTIONAL_HPP
@@ -0,0 +1,122 @@
1
+ #ifndef MAPBOX_UTIL_RECURSIVE_WRAPPER_HPP
2
+ #define MAPBOX_UTIL_RECURSIVE_WRAPPER_HPP
3
+
4
+ // Based on variant/recursive_wrapper.hpp from boost.
5
+ //
6
+ // Original license:
7
+ //
8
+ // Copyright (c) 2002-2003
9
+ // Eric Friedman, Itay Maman
10
+ //
11
+ // Distributed under the Boost Software License, Version 1.0. (See
12
+ // accompanying file LICENSE_1_0.txt or copy at
13
+ // http://www.boost.org/LICENSE_1_0.txt)
14
+
15
+ #include <cassert>
16
+ #include <utility>
17
+
18
+ namespace mapbox {
19
+ namespace util {
20
+
21
+ template <typename T>
22
+ class recursive_wrapper
23
+ {
24
+
25
+ T* p_;
26
+
27
+ void assign(T const& rhs)
28
+ {
29
+ this->get() = rhs;
30
+ }
31
+
32
+ public:
33
+ using type = T;
34
+
35
+ /**
36
+ * Default constructor default initializes the internally stored value.
37
+ * For POD types this means nothing is done and the storage is
38
+ * uninitialized.
39
+ *
40
+ * @throws std::bad_alloc if there is insufficient memory for an object
41
+ * of type T.
42
+ * @throws any exception thrown by the default constructur of T.
43
+ */
44
+ recursive_wrapper()
45
+ : p_(new T){}
46
+
47
+ ~recursive_wrapper() noexcept { delete p_; }
48
+
49
+ recursive_wrapper(recursive_wrapper const& operand)
50
+ : p_(new T(operand.get())) {}
51
+
52
+ recursive_wrapper(T const& operand)
53
+ : p_(new T(operand)) {}
54
+
55
+ recursive_wrapper(recursive_wrapper&& operand)
56
+ : p_(new T(std::move(operand.get()))) {}
57
+
58
+ recursive_wrapper(T&& operand)
59
+ : p_(new T(std::move(operand))) {}
60
+
61
+ inline recursive_wrapper& operator=(recursive_wrapper const& rhs)
62
+ {
63
+ assign(rhs.get());
64
+ return *this;
65
+ }
66
+
67
+ inline recursive_wrapper& operator=(T const& rhs)
68
+ {
69
+ assign(rhs);
70
+ return *this;
71
+ }
72
+
73
+ inline void swap(recursive_wrapper& operand) noexcept
74
+ {
75
+ T* temp = operand.p_;
76
+ operand.p_ = p_;
77
+ p_ = temp;
78
+ }
79
+
80
+ recursive_wrapper& operator=(recursive_wrapper&& rhs) noexcept
81
+ {
82
+ swap(rhs);
83
+ return *this;
84
+ }
85
+
86
+ recursive_wrapper& operator=(T&& rhs)
87
+ {
88
+ get() = std::move(rhs);
89
+ return *this;
90
+ }
91
+
92
+ T& get()
93
+ {
94
+ assert(p_);
95
+ return *get_pointer();
96
+ }
97
+
98
+ T const& get() const
99
+ {
100
+ assert(p_);
101
+ return *get_pointer();
102
+ }
103
+
104
+ T* get_pointer() { return p_; }
105
+
106
+ const T* get_pointer() const { return p_; }
107
+
108
+ operator T const&() const { return this->get(); }
109
+
110
+ operator T&() { return this->get(); }
111
+
112
+ }; // class recursive_wrapper
113
+
114
+ template <typename T>
115
+ inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs) noexcept
116
+ {
117
+ lhs.swap(rhs);
118
+ }
119
+ } // namespace util
120
+ } // namespace mapbox
121
+
122
+ #endif // MAPBOX_UTIL_RECURSIVE_WRAPPER_HPP
@@ -0,0 +1,974 @@
1
+ #ifndef MAPBOX_UTIL_VARIANT_HPP
2
+ #define MAPBOX_UTIL_VARIANT_HPP
3
+
4
+ #include <cassert>
5
+ #include <cstddef> // size_t
6
+ #include <new> // operator new
7
+ #include <stdexcept> // runtime_error
8
+ #include <string>
9
+ #include <tuple>
10
+ #include <type_traits>
11
+ #include <typeinfo>
12
+ #include <utility>
13
+
14
+ #include <mapbox/recursive_wrapper.hpp>
15
+
16
+ // clang-format off
17
+ // [[deprecated]] is only available in C++14, use this for the time being
18
+ #if __cplusplus <= 201103L
19
+ # ifdef __GNUC__
20
+ # define MAPBOX_VARIANT_DEPRECATED __attribute__((deprecated))
21
+ # elif defined(_MSC_VER)
22
+ # define MAPBOX_VARIANT_DEPRECATED __declspec(deprecated)
23
+ # else
24
+ # define MAPBOX_VARIANT_DEPRECATED
25
+ # endif
26
+ #else
27
+ # define MAPBOX_VARIANT_DEPRECATED [[deprecated]]
28
+ #endif
29
+
30
+
31
+ #ifdef _MSC_VER
32
+ // https://msdn.microsoft.com/en-us/library/bw1hbe6y.aspx
33
+ # ifdef NDEBUG
34
+ # define VARIANT_INLINE __forceinline
35
+ # else
36
+ # define VARIANT_INLINE //__declspec(noinline)
37
+ # endif
38
+ #else
39
+ # ifdef NDEBUG
40
+ # define VARIANT_INLINE //inline __attribute__((always_inline))
41
+ # else
42
+ # define VARIANT_INLINE __attribute__((noinline))
43
+ # endif
44
+ #endif
45
+ // clang-format on
46
+
47
+ // Exceptions
48
+ #if defined( __EXCEPTIONS) || defined( _MSC_VER)
49
+ #define HAS_EXCEPTIONS
50
+ #endif
51
+
52
+ #define VARIANT_MAJOR_VERSION 1
53
+ #define VARIANT_MINOR_VERSION 1
54
+ #define VARIANT_PATCH_VERSION 0
55
+
56
+ #define VARIANT_VERSION (VARIANT_MAJOR_VERSION * 100000) + (VARIANT_MINOR_VERSION * 100) + (VARIANT_PATCH_VERSION)
57
+
58
+ namespace mapbox {
59
+ namespace util {
60
+
61
+ // XXX This should derive from std::logic_error instead of std::runtime_error.
62
+ // See https://github.com/mapbox/variant/issues/48 for details.
63
+ class bad_variant_access : public std::runtime_error
64
+ {
65
+
66
+ public:
67
+ explicit bad_variant_access(const std::string& what_arg)
68
+ : runtime_error(what_arg) {}
69
+
70
+ explicit bad_variant_access(const char* what_arg)
71
+ : runtime_error(what_arg) {}
72
+
73
+ }; // class bad_variant_access
74
+
75
+ template <typename R = void>
76
+ struct MAPBOX_VARIANT_DEPRECATED static_visitor
77
+ {
78
+ using result_type = R;
79
+
80
+ protected:
81
+ static_visitor() {}
82
+ ~static_visitor() {}
83
+ };
84
+
85
+ namespace detail {
86
+
87
+ static constexpr std::size_t invalid_value = std::size_t(-1);
88
+
89
+ template <typename T, typename... Types>
90
+ struct direct_type;
91
+
92
+ template <typename T, typename First, typename... Types>
93
+ struct direct_type<T, First, Types...>
94
+ {
95
+ static constexpr std::size_t index = std::is_same<T, First>::value
96
+ ? sizeof...(Types)
97
+ : direct_type<T, Types...>::index;
98
+ };
99
+
100
+ template <typename T>
101
+ struct direct_type<T>
102
+ {
103
+ static constexpr std::size_t index = invalid_value;
104
+ };
105
+
106
+ #if __cpp_lib_logical_traits >= 201510L
107
+
108
+ using std::disjunction;
109
+
110
+ #else
111
+
112
+ template <typename...>
113
+ struct disjunction : std::false_type {};
114
+
115
+ template <typename B1>
116
+ struct disjunction<B1> : B1 {};
117
+
118
+ template <typename B1, typename B2>
119
+ struct disjunction<B1, B2> : std::conditional<B1::value, B1, B2>::type {};
120
+
121
+ template <typename B1, typename... Bs>
122
+ struct disjunction<B1, Bs...> : std::conditional<B1::value, B1, disjunction<Bs...>>::type {};
123
+
124
+ #endif
125
+
126
+ template <typename T, typename... Types>
127
+ struct convertible_type;
128
+
129
+ template <typename T, typename First, typename... Types>
130
+ struct convertible_type<T, First, Types...>
131
+ {
132
+ static constexpr std::size_t index = std::is_convertible<T, First>::value
133
+ ? disjunction<std::is_convertible<T, Types>...>::value ? invalid_value : sizeof...(Types)
134
+ : convertible_type<T, Types...>::index;
135
+ };
136
+
137
+ template <typename T>
138
+ struct convertible_type<T>
139
+ {
140
+ static constexpr std::size_t index = invalid_value;
141
+ };
142
+
143
+ template <typename T, typename... Types>
144
+ struct value_traits
145
+ {
146
+ using value_type = typename std::remove_const<typename std::remove_reference<T>::type>::type;
147
+ static constexpr std::size_t direct_index = direct_type<value_type, Types...>::index;
148
+ static constexpr bool is_direct = direct_index != invalid_value;
149
+ static constexpr std::size_t index = is_direct ? direct_index : convertible_type<value_type, Types...>::index;
150
+ static constexpr bool is_valid = index != invalid_value;
151
+ static constexpr std::size_t tindex = is_valid ? sizeof...(Types)-index : 0;
152
+ using target_type = typename std::tuple_element<tindex, std::tuple<void, Types...>>::type;
153
+ };
154
+
155
+ template <typename T, typename R = void>
156
+ struct enable_if_type
157
+ {
158
+ using type = R;
159
+ };
160
+
161
+ template <typename F, typename V, typename Enable = void>
162
+ struct result_of_unary_visit
163
+ {
164
+ using type = typename std::result_of<F(V&)>::type;
165
+ };
166
+
167
+ template <typename F, typename V>
168
+ struct result_of_unary_visit<F, V, typename enable_if_type<typename F::result_type>::type>
169
+ {
170
+ using type = typename F::result_type;
171
+ };
172
+
173
+ template <typename F, typename V, typename Enable = void>
174
+ struct result_of_binary_visit
175
+ {
176
+ using type = typename std::result_of<F(V&, V&)>::type;
177
+ };
178
+
179
+ template <typename F, typename V>
180
+ struct result_of_binary_visit<F, V, typename enable_if_type<typename F::result_type>::type>
181
+ {
182
+ using type = typename F::result_type;
183
+ };
184
+
185
+ template <std::size_t arg1, std::size_t... others>
186
+ struct static_max;
187
+
188
+ template <std::size_t arg>
189
+ struct static_max<arg>
190
+ {
191
+ static const std::size_t value = arg;
192
+ };
193
+
194
+ template <std::size_t arg1, std::size_t arg2, std::size_t... others>
195
+ struct static_max<arg1, arg2, others...>
196
+ {
197
+ static const std::size_t value = arg1 >= arg2 ? static_max<arg1, others...>::value : static_max<arg2, others...>::value;
198
+ };
199
+
200
+ template <typename... Types>
201
+ struct variant_helper;
202
+
203
+ template <typename T, typename... Types>
204
+ struct variant_helper<T, Types...>
205
+ {
206
+ VARIANT_INLINE static void destroy(const std::size_t type_index, void* data)
207
+ {
208
+ if (type_index == sizeof...(Types))
209
+ {
210
+ reinterpret_cast<T*>(data)->~T();
211
+ }
212
+ else
213
+ {
214
+ variant_helper<Types...>::destroy(type_index, data);
215
+ }
216
+ }
217
+
218
+ VARIANT_INLINE static void move(const std::size_t old_type_index, void* old_value, void* new_value)
219
+ {
220
+ if (old_type_index == sizeof...(Types))
221
+ {
222
+ new (new_value) T(std::move(*reinterpret_cast<T*>(old_value)));
223
+ }
224
+ else
225
+ {
226
+ variant_helper<Types...>::move(old_type_index, old_value, new_value);
227
+ }
228
+ }
229
+
230
+ VARIANT_INLINE static void copy(const std::size_t old_type_index, const void* old_value, void* new_value)
231
+ {
232
+ if (old_type_index == sizeof...(Types))
233
+ {
234
+ new (new_value) T(*reinterpret_cast<const T*>(old_value));
235
+ }
236
+ else
237
+ {
238
+ variant_helper<Types...>::copy(old_type_index, old_value, new_value);
239
+ }
240
+ }
241
+ };
242
+
243
+ template <>
244
+ struct variant_helper<>
245
+ {
246
+ VARIANT_INLINE static void destroy(const std::size_t, void*) {}
247
+ VARIANT_INLINE static void move(const std::size_t, void*, void*) {}
248
+ VARIANT_INLINE static void copy(const std::size_t, const void*, void*) {}
249
+ };
250
+
251
+ template <typename T>
252
+ struct unwrapper
253
+ {
254
+ static T const& apply_const(T const& obj) { return obj; }
255
+ static T& apply(T& obj) { return obj; }
256
+ };
257
+
258
+ template <typename T>
259
+ struct unwrapper<recursive_wrapper<T>>
260
+ {
261
+ static auto apply_const(recursive_wrapper<T> const& obj)
262
+ -> typename recursive_wrapper<T>::type const&
263
+ {
264
+ return obj.get();
265
+ }
266
+ static auto apply(recursive_wrapper<T>& obj)
267
+ -> typename recursive_wrapper<T>::type&
268
+ {
269
+ return obj.get();
270
+ }
271
+ };
272
+
273
+ template <typename T>
274
+ struct unwrapper<std::reference_wrapper<T>>
275
+ {
276
+ static auto apply_const(std::reference_wrapper<T> const& obj)
277
+ -> typename std::reference_wrapper<T>::type const&
278
+ {
279
+ return obj.get();
280
+ }
281
+ static auto apply(std::reference_wrapper<T>& obj)
282
+ -> typename std::reference_wrapper<T>::type&
283
+ {
284
+ return obj.get();
285
+ }
286
+ };
287
+
288
+ template <typename F, typename V, typename R, typename... Types>
289
+ struct dispatcher;
290
+
291
+ template <typename F, typename V, typename R, typename T, typename... Types>
292
+ struct dispatcher<F, V, R, T, Types...>
293
+ {
294
+ VARIANT_INLINE static R apply_const(V const& v, F&& f)
295
+ {
296
+ if (v.template is<T>())
297
+ {
298
+ return f(unwrapper<T>::apply_const(v.template get_unchecked<T>()));
299
+ }
300
+ else
301
+ {
302
+ return dispatcher<F, V, R, Types...>::apply_const(v, std::forward<F>(f));
303
+ }
304
+ }
305
+
306
+ VARIANT_INLINE static R apply(V& v, F&& f)
307
+ {
308
+ if (v.template is<T>())
309
+ {
310
+ return f(unwrapper<T>::apply(v.template get_unchecked<T>()));
311
+ }
312
+ else
313
+ {
314
+ return dispatcher<F, V, R, Types...>::apply(v, std::forward<F>(f));
315
+ }
316
+ }
317
+ };
318
+
319
+ template <typename F, typename V, typename R, typename T>
320
+ struct dispatcher<F, V, R, T>
321
+ {
322
+ VARIANT_INLINE static R apply_const(V const& v, F&& f)
323
+ {
324
+ return f(unwrapper<T>::apply_const(v.template get_unchecked<T>()));
325
+ }
326
+
327
+ VARIANT_INLINE static R apply(V& v, F&& f)
328
+ {
329
+ return f(unwrapper<T>::apply(v.template get_unchecked<T>()));
330
+ }
331
+ };
332
+
333
+ template <typename F, typename V, typename R, typename T, typename... Types>
334
+ struct binary_dispatcher_rhs;
335
+
336
+ template <typename F, typename V, typename R, typename T0, typename T1, typename... Types>
337
+ struct binary_dispatcher_rhs<F, V, R, T0, T1, Types...>
338
+ {
339
+ VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f)
340
+ {
341
+ if (rhs.template is<T1>()) // call binary functor
342
+ {
343
+ return f(unwrapper<T0>::apply_const(lhs.template get_unchecked<T0>()),
344
+ unwrapper<T1>::apply_const(rhs.template get_unchecked<T1>()));
345
+ }
346
+ else
347
+ {
348
+ return binary_dispatcher_rhs<F, V, R, T0, Types...>::apply_const(lhs, rhs, std::forward<F>(f));
349
+ }
350
+ }
351
+
352
+ VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f)
353
+ {
354
+ if (rhs.template is<T1>()) // call binary functor
355
+ {
356
+ return f(unwrapper<T0>::apply(lhs.template get_unchecked<T0>()),
357
+ unwrapper<T1>::apply(rhs.template get_unchecked<T1>()));
358
+ }
359
+ else
360
+ {
361
+ return binary_dispatcher_rhs<F, V, R, T0, Types...>::apply(lhs, rhs, std::forward<F>(f));
362
+ }
363
+ }
364
+ };
365
+
366
+ template <typename F, typename V, typename R, typename T0, typename T1>
367
+ struct binary_dispatcher_rhs<F, V, R, T0, T1>
368
+ {
369
+ VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f)
370
+ {
371
+ return f(unwrapper<T0>::apply_const(lhs.template get_unchecked<T0>()),
372
+ unwrapper<T1>::apply_const(rhs.template get_unchecked<T1>()));
373
+ }
374
+
375
+ VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f)
376
+ {
377
+ return f(unwrapper<T0>::apply(lhs.template get_unchecked<T0>()),
378
+ unwrapper<T1>::apply(rhs.template get_unchecked<T1>()));
379
+ }
380
+ };
381
+
382
+ template <typename F, typename V, typename R, typename T, typename... Types>
383
+ struct binary_dispatcher_lhs;
384
+
385
+ template <typename F, typename V, typename R, typename T0, typename T1, typename... Types>
386
+ struct binary_dispatcher_lhs<F, V, R, T0, T1, Types...>
387
+ {
388
+ VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f)
389
+ {
390
+ if (lhs.template is<T1>()) // call binary functor
391
+ {
392
+ return f(unwrapper<T1>::apply_const(lhs.template get_unchecked<T1>()),
393
+ unwrapper<T0>::apply_const(rhs.template get_unchecked<T0>()));
394
+ }
395
+ else
396
+ {
397
+ return binary_dispatcher_lhs<F, V, R, T0, Types...>::apply_const(lhs, rhs, std::forward<F>(f));
398
+ }
399
+ }
400
+
401
+ VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f)
402
+ {
403
+ if (lhs.template is<T1>()) // call binary functor
404
+ {
405
+ return f(unwrapper<T1>::apply(lhs.template get_unchecked<T1>()),
406
+ unwrapper<T0>::apply(rhs.template get_unchecked<T0>()));
407
+ }
408
+ else
409
+ {
410
+ return binary_dispatcher_lhs<F, V, R, T0, Types...>::apply(lhs, rhs, std::forward<F>(f));
411
+ }
412
+ }
413
+ };
414
+
415
+ template <typename F, typename V, typename R, typename T0, typename T1>
416
+ struct binary_dispatcher_lhs<F, V, R, T0, T1>
417
+ {
418
+ VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f)
419
+ {
420
+ return f(unwrapper<T1>::apply_const(lhs.template get_unchecked<T1>()),
421
+ unwrapper<T0>::apply_const(rhs.template get_unchecked<T0>()));
422
+ }
423
+
424
+ VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f)
425
+ {
426
+ return f(unwrapper<T1>::apply(lhs.template get_unchecked<T1>()),
427
+ unwrapper<T0>::apply(rhs.template get_unchecked<T0>()));
428
+ }
429
+ };
430
+
431
+ template <typename F, typename V, typename R, typename... Types>
432
+ struct binary_dispatcher;
433
+
434
+ template <typename F, typename V, typename R, typename T, typename... Types>
435
+ struct binary_dispatcher<F, V, R, T, Types...>
436
+ {
437
+ VARIANT_INLINE static R apply_const(V const& v0, V const& v1, F&& f)
438
+ {
439
+ if (v0.template is<T>())
440
+ {
441
+ if (v1.template is<T>())
442
+ {
443
+ return f(unwrapper<T>::apply_const(v0.template get_unchecked<T>()),
444
+ unwrapper<T>::apply_const(v1.template get_unchecked<T>())); // call binary functor
445
+ }
446
+ else
447
+ {
448
+ return binary_dispatcher_rhs<F, V, R, T, Types...>::apply_const(v0, v1, std::forward<F>(f));
449
+ }
450
+ }
451
+ else if (v1.template is<T>())
452
+ {
453
+ return binary_dispatcher_lhs<F, V, R, T, Types...>::apply_const(v0, v1, std::forward<F>(f));
454
+ }
455
+ return binary_dispatcher<F, V, R, Types...>::apply_const(v0, v1, std::forward<F>(f));
456
+ }
457
+
458
+ VARIANT_INLINE static R apply(V& v0, V& v1, F&& f)
459
+ {
460
+ if (v0.template is<T>())
461
+ {
462
+ if (v1.template is<T>())
463
+ {
464
+ return f(unwrapper<T>::apply(v0.template get_unchecked<T>()),
465
+ unwrapper<T>::apply(v1.template get_unchecked<T>())); // call binary functor
466
+ }
467
+ else
468
+ {
469
+ return binary_dispatcher_rhs<F, V, R, T, Types...>::apply(v0, v1, std::forward<F>(f));
470
+ }
471
+ }
472
+ else if (v1.template is<T>())
473
+ {
474
+ return binary_dispatcher_lhs<F, V, R, T, Types...>::apply(v0, v1, std::forward<F>(f));
475
+ }
476
+ return binary_dispatcher<F, V, R, Types...>::apply(v0, v1, std::forward<F>(f));
477
+ }
478
+ };
479
+
480
+ template <typename F, typename V, typename R, typename T>
481
+ struct binary_dispatcher<F, V, R, T>
482
+ {
483
+ VARIANT_INLINE static R apply_const(V const& v0, V const& v1, F&& f)
484
+ {
485
+ return f(unwrapper<T>::apply_const(v0.template get_unchecked<T>()),
486
+ unwrapper<T>::apply_const(v1.template get_unchecked<T>())); // call binary functor
487
+ }
488
+
489
+ VARIANT_INLINE static R apply(V& v0, V& v1, F&& f)
490
+ {
491
+ return f(unwrapper<T>::apply(v0.template get_unchecked<T>()),
492
+ unwrapper<T>::apply(v1.template get_unchecked<T>())); // call binary functor
493
+ }
494
+ };
495
+
496
+ // comparator functors
497
+ struct equal_comp
498
+ {
499
+ template <typename T>
500
+ bool operator()(T const& lhs, T const& rhs) const
501
+ {
502
+ return lhs == rhs;
503
+ }
504
+ };
505
+
506
+ struct less_comp
507
+ {
508
+ template <typename T>
509
+ bool operator()(T const& lhs, T const& rhs) const
510
+ {
511
+ return lhs < rhs;
512
+ }
513
+ };
514
+
515
+ template <typename Variant, typename Comp>
516
+ class comparer
517
+ {
518
+ public:
519
+ explicit comparer(Variant const& lhs) noexcept
520
+ : lhs_(lhs) {}
521
+ comparer& operator=(comparer const&) = delete;
522
+ // visitor
523
+ template <typename T>
524
+ bool operator()(T const& rhs_content) const
525
+ {
526
+ T const& lhs_content = lhs_.template get_unchecked<T>();
527
+ return Comp()(lhs_content, rhs_content);
528
+ }
529
+
530
+ private:
531
+ Variant const& lhs_;
532
+ };
533
+
534
+ } // namespace detail
535
+
536
+ struct no_init
537
+ {
538
+ };
539
+
540
+ template <typename... Types>
541
+ class variant
542
+ {
543
+ static_assert(sizeof...(Types) > 0, "Template parameter type list of variant can not be empty");
544
+ static_assert(!detail::disjunction<std::is_reference<Types>...>::value, "Variant can not hold reference types. Maybe use std::reference_wrapper?");
545
+
546
+ private:
547
+ static const std::size_t data_size = detail::static_max<sizeof(Types)...>::value;
548
+ static const std::size_t data_align = detail::static_max<alignof(Types)...>::value;
549
+ public:
550
+ struct adapted_variant_tag;
551
+ using types = std::tuple<Types...>;
552
+ private:
553
+ using first_type = typename std::tuple_element<0, types>::type;
554
+ using data_type = typename std::aligned_storage<data_size, data_align>::type;
555
+ using helper_type = detail::variant_helper<Types...>;
556
+
557
+ std::size_t type_index;
558
+ data_type data;
559
+
560
+ public:
561
+ VARIANT_INLINE variant() noexcept(std::is_nothrow_default_constructible<first_type>::value)
562
+ : type_index(sizeof...(Types)-1)
563
+ {
564
+ static_assert(std::is_default_constructible<first_type>::value, "First type in variant must be default constructible to allow default construction of variant");
565
+ new (&data) first_type();
566
+ }
567
+
568
+ VARIANT_INLINE variant(no_init) noexcept
569
+ : type_index(detail::invalid_value) {}
570
+
571
+ // http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
572
+ template <typename T, typename Traits = detail::value_traits<T, Types...>,
573
+ typename Enable = typename std::enable_if<Traits::is_valid && !std::is_same<variant<Types...>, typename Traits::value_type>::value>::type >
574
+ VARIANT_INLINE variant(T&& val) noexcept(std::is_nothrow_constructible<typename Traits::target_type, T&&>::value)
575
+ : type_index(Traits::index)
576
+ {
577
+ new (&data) typename Traits::target_type(std::forward<T>(val));
578
+ }
579
+
580
+ VARIANT_INLINE variant(variant<Types...> const& old)
581
+ : type_index(old.type_index)
582
+ {
583
+ helper_type::copy(old.type_index, &old.data, &data);
584
+ }
585
+
586
+ VARIANT_INLINE variant(variant<Types...>&& old) noexcept(std::is_nothrow_move_constructible<types>::value)
587
+ : type_index(old.type_index)
588
+ {
589
+ helper_type::move(old.type_index, &old.data, &data);
590
+ }
591
+
592
+ private:
593
+ VARIANT_INLINE void copy_assign(variant<Types...> const& rhs)
594
+ {
595
+ helper_type::destroy(type_index, &data);
596
+ type_index = detail::invalid_value;
597
+ helper_type::copy(rhs.type_index, &rhs.data, &data);
598
+ type_index = rhs.type_index;
599
+ }
600
+
601
+ VARIANT_INLINE void move_assign(variant<Types...>&& rhs)
602
+ {
603
+ helper_type::destroy(type_index, &data);
604
+ type_index = detail::invalid_value;
605
+ helper_type::move(rhs.type_index, &rhs.data, &data);
606
+ type_index = rhs.type_index;
607
+ }
608
+
609
+ public:
610
+ VARIANT_INLINE variant<Types...>& operator=(variant<Types...>&& other)
611
+ {
612
+ move_assign(std::move(other));
613
+ return *this;
614
+ }
615
+
616
+ VARIANT_INLINE variant<Types...>& operator=(variant<Types...> const& other)
617
+ {
618
+ copy_assign(other);
619
+ return *this;
620
+ }
621
+
622
+ // conversions
623
+ // move-assign
624
+ template <typename T>
625
+ VARIANT_INLINE variant<Types...>& operator=(T&& rhs) noexcept
626
+ {
627
+ variant<Types...> temp(std::forward<T>(rhs));
628
+ move_assign(std::move(temp));
629
+ return *this;
630
+ }
631
+
632
+ // copy-assign
633
+ template <typename T>
634
+ VARIANT_INLINE variant<Types...>& operator=(T const& rhs)
635
+ {
636
+ variant<Types...> temp(rhs);
637
+ copy_assign(temp);
638
+ return *this;
639
+ }
640
+
641
+ template <typename T, typename std::enable_if<
642
+ (detail::direct_type<T, Types...>::index != detail::invalid_value)>::type* = nullptr>
643
+ VARIANT_INLINE bool is() const
644
+ {
645
+ return type_index == detail::direct_type<T, Types...>::index;
646
+ }
647
+
648
+ template <typename T,typename std::enable_if<
649
+ (detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)>::type* = nullptr>
650
+ VARIANT_INLINE bool is() const
651
+ {
652
+ return type_index == detail::direct_type<recursive_wrapper<T>, Types...>::index;
653
+ }
654
+
655
+ VARIANT_INLINE bool valid() const
656
+ {
657
+ return type_index != detail::invalid_value;
658
+ }
659
+
660
+ template <typename T, typename... Args>
661
+ VARIANT_INLINE void set(Args&&... args)
662
+ {
663
+ helper_type::destroy(type_index, &data);
664
+ type_index = detail::invalid_value;
665
+ new (&data) T(std::forward<Args>(args)...);
666
+ type_index = detail::direct_type<T, Types...>::index;
667
+ }
668
+
669
+ // get_unchecked<T>()
670
+ template <typename T, typename std::enable_if<
671
+ (detail::direct_type<T, Types...>::index != detail::invalid_value)>::type* = nullptr>
672
+ VARIANT_INLINE T& get_unchecked()
673
+ {
674
+ return *reinterpret_cast<T*>(&data);
675
+ }
676
+
677
+ #ifdef HAS_EXCEPTIONS
678
+ // get<T>()
679
+ template <typename T, typename std::enable_if<
680
+ (detail::direct_type<T, Types...>::index != detail::invalid_value)>::type* = nullptr>
681
+ VARIANT_INLINE T& get()
682
+ {
683
+ if (type_index == detail::direct_type<T, Types...>::index)
684
+ {
685
+ return *reinterpret_cast<T*>(&data);
686
+ }
687
+ else
688
+ {
689
+ throw bad_variant_access("in get<T>()");
690
+ }
691
+ }
692
+ #endif
693
+
694
+ template <typename T, typename std::enable_if<
695
+ (detail::direct_type<T, Types...>::index != detail::invalid_value)>::type* = nullptr>
696
+ VARIANT_INLINE T const& get_unchecked() const
697
+ {
698
+ return *reinterpret_cast<T const*>(&data);
699
+ }
700
+
701
+ #ifdef HAS_EXCEPTIONS
702
+ template <typename T, typename std::enable_if<
703
+ (detail::direct_type<T, Types...>::index != detail::invalid_value)>::type* = nullptr>
704
+ VARIANT_INLINE T const& get() const
705
+ {
706
+ if (type_index == detail::direct_type<T, Types...>::index)
707
+ {
708
+ return *reinterpret_cast<T const*>(&data);
709
+ }
710
+ else
711
+ {
712
+ throw bad_variant_access("in get<T>()");
713
+ }
714
+ }
715
+ #endif
716
+
717
+ // get_unchecked<T>() - T stored as recursive_wrapper<T>
718
+ template <typename T, typename std::enable_if<
719
+ (detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)>::type* = nullptr>
720
+ VARIANT_INLINE T& get_unchecked()
721
+ {
722
+ return (*reinterpret_cast<recursive_wrapper<T>*>(&data)).get();
723
+ }
724
+
725
+ #ifdef HAS_EXCEPTIONS
726
+ // get<T>() - T stored as recursive_wrapper<T>
727
+ template <typename T, typename std::enable_if<
728
+ (detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)>::type* = nullptr>
729
+ VARIANT_INLINE T& get()
730
+ {
731
+ if (type_index == detail::direct_type<recursive_wrapper<T>, Types...>::index)
732
+ {
733
+ return (*reinterpret_cast<recursive_wrapper<T>*>(&data)).get();
734
+ }
735
+ else
736
+ {
737
+ throw bad_variant_access("in get<T>()");
738
+ }
739
+ }
740
+ #endif
741
+
742
+ template <typename T, typename std::enable_if<
743
+ (detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)>::type* = nullptr>
744
+ VARIANT_INLINE T const& get_unchecked() const
745
+ {
746
+ return (*reinterpret_cast<recursive_wrapper<T> const*>(&data)).get();
747
+ }
748
+
749
+ #ifdef HAS_EXCEPTIONS
750
+ template <typename T, typename std::enable_if<
751
+ (detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)>::type* = nullptr>
752
+ VARIANT_INLINE T const& get() const
753
+ {
754
+ if (type_index == detail::direct_type<recursive_wrapper<T>, Types...>::index)
755
+ {
756
+ return (*reinterpret_cast<recursive_wrapper<T> const*>(&data)).get();
757
+ }
758
+ else
759
+ {
760
+ throw bad_variant_access("in get<T>()");
761
+ }
762
+ }
763
+ #endif
764
+
765
+ // get_unchecked<T>() - T stored as std::reference_wrapper<T>
766
+ template <typename T, typename std::enable_if<
767
+ (detail::direct_type<std::reference_wrapper<T>, Types...>::index != detail::invalid_value)>::type* = nullptr>
768
+ VARIANT_INLINE T& get_unchecked()
769
+ {
770
+ return (*reinterpret_cast<std::reference_wrapper<T>*>(&data)).get();
771
+ }
772
+
773
+ #ifdef HAS_EXCEPTIONS
774
+ // get<T>() - T stored as std::reference_wrapper<T>
775
+ template <typename T, typename std::enable_if<
776
+ (detail::direct_type<std::reference_wrapper<T>, Types...>::index != detail::invalid_value)>::type* = nullptr>
777
+ VARIANT_INLINE T& get()
778
+ {
779
+ if (type_index == detail::direct_type<std::reference_wrapper<T>, Types...>::index)
780
+ {
781
+ return (*reinterpret_cast<std::reference_wrapper<T>*>(&data)).get();
782
+ }
783
+ else
784
+ {
785
+ throw bad_variant_access("in get<T>()");
786
+ }
787
+ }
788
+ #endif
789
+
790
+ template <typename T, typename std::enable_if<
791
+ (detail::direct_type<std::reference_wrapper<T const>, Types...>::index != detail::invalid_value)>::type* = nullptr>
792
+ VARIANT_INLINE T const& get_unchecked() const
793
+ {
794
+ return (*reinterpret_cast<std::reference_wrapper<T const> const*>(&data)).get();
795
+ }
796
+
797
+ #ifdef HAS_EXCEPTIONS
798
+ template <typename T, typename std::enable_if<
799
+ (detail::direct_type<std::reference_wrapper<T const>, Types...>::index != detail::invalid_value)>::type* = nullptr>
800
+ VARIANT_INLINE T const& get() const
801
+ {
802
+ if (type_index == detail::direct_type<std::reference_wrapper<T const>, Types...>::index)
803
+ {
804
+ return (*reinterpret_cast<std::reference_wrapper<T const> const*>(&data)).get();
805
+ }
806
+ else
807
+ {
808
+ throw bad_variant_access("in get<T>()");
809
+ }
810
+ }
811
+ #endif
812
+
813
+ // This function is deprecated because it returns an internal index field.
814
+ // Use which() instead.
815
+ MAPBOX_VARIANT_DEPRECATED VARIANT_INLINE std::size_t get_type_index() const
816
+ {
817
+ return type_index;
818
+ }
819
+
820
+ VARIANT_INLINE int which() const noexcept
821
+ {
822
+ return static_cast<int>(sizeof...(Types)-type_index - 1);
823
+ }
824
+
825
+ template <typename T, typename std::enable_if<
826
+ (detail::direct_type<T, Types...>::index != detail::invalid_value)>::type* = nullptr>
827
+ VARIANT_INLINE static constexpr int which() noexcept
828
+ {
829
+ return static_cast<int>(sizeof...(Types)-detail::direct_type<T, Types...>::index - 1);
830
+ }
831
+
832
+ // visitor
833
+ // unary
834
+ template <typename F, typename V, typename R = typename detail::result_of_unary_visit<F, first_type>::type>
835
+ auto VARIANT_INLINE static visit(V const& v, F&& f)
836
+ -> decltype(detail::dispatcher<F, V, R, Types...>::apply_const(v, std::forward<F>(f)))
837
+ {
838
+ return detail::dispatcher<F, V, R, Types...>::apply_const(v, std::forward<F>(f));
839
+ }
840
+ // non-const
841
+ template <typename F, typename V, typename R = typename detail::result_of_unary_visit<F, first_type>::type>
842
+ auto VARIANT_INLINE static visit(V& v, F&& f)
843
+ -> decltype(detail::dispatcher<F, V, R, Types...>::apply(v, std::forward<F>(f)))
844
+ {
845
+ return detail::dispatcher<F, V, R, Types...>::apply(v, std::forward<F>(f));
846
+ }
847
+
848
+ // binary
849
+ // const
850
+ template <typename F, typename V, typename R = typename detail::result_of_binary_visit<F, first_type>::type>
851
+ auto VARIANT_INLINE static binary_visit(V const& v0, V const& v1, F&& f)
852
+ -> decltype(detail::binary_dispatcher<F, V, R, Types...>::apply_const(v0, v1, std::forward<F>(f)))
853
+ {
854
+ return detail::binary_dispatcher<F, V, R, Types...>::apply_const(v0, v1, std::forward<F>(f));
855
+ }
856
+ // non-const
857
+ template <typename F, typename V, typename R = typename detail::result_of_binary_visit<F, first_type>::type>
858
+ auto VARIANT_INLINE static binary_visit(V& v0, V& v1, F&& f)
859
+ -> decltype(detail::binary_dispatcher<F, V, R, Types...>::apply(v0, v1, std::forward<F>(f)))
860
+ {
861
+ return detail::binary_dispatcher<F, V, R, Types...>::apply(v0, v1, std::forward<F>(f));
862
+ }
863
+
864
+ ~variant() noexcept // no-throw destructor
865
+ {
866
+ helper_type::destroy(type_index, &data);
867
+ }
868
+
869
+ // comparison operators
870
+ // equality
871
+ VARIANT_INLINE bool operator==(variant const& rhs) const
872
+ {
873
+ assert(valid() && rhs.valid());
874
+ if (this->which() != rhs.which())
875
+ {
876
+ return false;
877
+ }
878
+ detail::comparer<variant, detail::equal_comp> visitor(*this);
879
+ return visit(rhs, visitor);
880
+ }
881
+
882
+ VARIANT_INLINE bool operator!=(variant const& rhs) const
883
+ {
884
+ return !(*this == rhs);
885
+ }
886
+
887
+ // less than
888
+ VARIANT_INLINE bool operator<(variant const& rhs) const
889
+ {
890
+ assert(valid() && rhs.valid());
891
+ if (this->which() != rhs.which())
892
+ {
893
+ return this->which() < rhs.which();
894
+ }
895
+ detail::comparer<variant, detail::less_comp> visitor(*this);
896
+ return visit(rhs, visitor);
897
+ }
898
+ VARIANT_INLINE bool operator>(variant const& rhs) const
899
+ {
900
+ return rhs < *this;
901
+ }
902
+ VARIANT_INLINE bool operator<=(variant const& rhs) const
903
+ {
904
+ return !(*this > rhs);
905
+ }
906
+ VARIANT_INLINE bool operator>=(variant const& rhs) const
907
+ {
908
+ return !(*this < rhs);
909
+ }
910
+ };
911
+
912
+ // unary visitor interface
913
+ // const
914
+ template <typename F, typename V>
915
+ auto VARIANT_INLINE apply_visitor(F&& f, V const& v) -> decltype(V::visit(v, std::forward<F>(f)))
916
+ {
917
+ return V::visit(v, std::forward<F>(f));
918
+ }
919
+
920
+ // non-const
921
+ template <typename F, typename V>
922
+ auto VARIANT_INLINE apply_visitor(F&& f, V& v) -> decltype(V::visit(v, std::forward<F>(f)))
923
+ {
924
+ return V::visit(v, std::forward<F>(f));
925
+ }
926
+
927
+ // binary visitor interface
928
+ // const
929
+ template <typename F, typename V>
930
+ auto VARIANT_INLINE apply_visitor(F&& f, V const& v0, V const& v1) -> decltype(V::binary_visit(v0, v1, std::forward<F>(f)))
931
+ {
932
+ return V::binary_visit(v0, v1, std::forward<F>(f));
933
+ }
934
+
935
+ // non-const
936
+ template <typename F, typename V>
937
+ auto VARIANT_INLINE apply_visitor(F&& f, V& v0, V& v1) -> decltype(V::binary_visit(v0, v1, std::forward<F>(f)))
938
+ {
939
+ return V::binary_visit(v0, v1, std::forward<F>(f));
940
+ }
941
+
942
+ // getter interface
943
+
944
+ #ifdef HAS_EXCEPTIONS
945
+ template <typename ResultType, typename T>
946
+ auto get(T& var)->decltype(var.template get<ResultType>())
947
+ {
948
+ return var.template get<ResultType>();
949
+ }
950
+ #endif
951
+
952
+ template <typename ResultType, typename T>
953
+ ResultType& get_unchecked(T& var)
954
+ {
955
+ return var.template get_unchecked<ResultType>();
956
+ }
957
+
958
+ #ifdef HAS_EXCEPTIONS
959
+ template <typename ResultType, typename T>
960
+ auto get(T const& var)->decltype(var.template get<ResultType>())
961
+ {
962
+ return var.template get<ResultType>();
963
+ }
964
+ #endif
965
+
966
+ template <typename ResultType, typename T>
967
+ ResultType const& get_unchecked(T const& var)
968
+ {
969
+ return var.template get_unchecked<ResultType>();
970
+ }
971
+ } // namespace util
972
+ } // namespace mapbox
973
+
974
+ #endif // MAPBOX_UTIL_VARIANT_HPP