tomoto 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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