1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright (c) MapBox All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: BSD-3-Clause
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker
6*89c4ff92SAndroid Build Coastguard Worker #ifndef VARIANT_CAST_HPP
7*89c4ff92SAndroid Build Coastguard Worker #define VARIANT_CAST_HPP
8*89c4ff92SAndroid Build Coastguard Worker
9*89c4ff92SAndroid Build Coastguard Worker #include <type_traits>
10*89c4ff92SAndroid Build Coastguard Worker
11*89c4ff92SAndroid Build Coastguard Worker namespace mapbox {
12*89c4ff92SAndroid Build Coastguard Worker namespace util {
13*89c4ff92SAndroid Build Coastguard Worker
14*89c4ff92SAndroid Build Coastguard Worker namespace detail {
15*89c4ff92SAndroid Build Coastguard Worker
16*89c4ff92SAndroid Build Coastguard Worker template <class T>
17*89c4ff92SAndroid Build Coastguard Worker class static_caster
18*89c4ff92SAndroid Build Coastguard Worker {
19*89c4ff92SAndroid Build Coastguard Worker public:
20*89c4ff92SAndroid Build Coastguard Worker template <class V>
operator ()(V & v) const21*89c4ff92SAndroid Build Coastguard Worker T& operator()(V& v) const
22*89c4ff92SAndroid Build Coastguard Worker {
23*89c4ff92SAndroid Build Coastguard Worker return static_cast<T&>(v);
24*89c4ff92SAndroid Build Coastguard Worker }
25*89c4ff92SAndroid Build Coastguard Worker };
26*89c4ff92SAndroid Build Coastguard Worker
27*89c4ff92SAndroid Build Coastguard Worker template <class T>
28*89c4ff92SAndroid Build Coastguard Worker class dynamic_caster
29*89c4ff92SAndroid Build Coastguard Worker {
30*89c4ff92SAndroid Build Coastguard Worker public:
31*89c4ff92SAndroid Build Coastguard Worker using result_type = T&;
32*89c4ff92SAndroid Build Coastguard Worker template <class V>
operator ()(V & v,typename std::enable_if<!std::is_polymorphic<V>::value>::type * =nullptr) const33*89c4ff92SAndroid Build Coastguard Worker T& operator()(V& v, typename std::enable_if<!std::is_polymorphic<V>::value>::type* = nullptr) const
34*89c4ff92SAndroid Build Coastguard Worker {
35*89c4ff92SAndroid Build Coastguard Worker throw std::bad_cast();
36*89c4ff92SAndroid Build Coastguard Worker }
37*89c4ff92SAndroid Build Coastguard Worker template <class V>
operator ()(V & v,typename std::enable_if<std::is_polymorphic<V>::value>::type * =nullptr) const38*89c4ff92SAndroid Build Coastguard Worker T& operator()(V& v, typename std::enable_if<std::is_polymorphic<V>::value>::type* = nullptr) const
39*89c4ff92SAndroid Build Coastguard Worker {
40*89c4ff92SAndroid Build Coastguard Worker return dynamic_cast<T&>(v);
41*89c4ff92SAndroid Build Coastguard Worker }
42*89c4ff92SAndroid Build Coastguard Worker };
43*89c4ff92SAndroid Build Coastguard Worker
44*89c4ff92SAndroid Build Coastguard Worker template <class T>
45*89c4ff92SAndroid Build Coastguard Worker class dynamic_caster<T*>
46*89c4ff92SAndroid Build Coastguard Worker {
47*89c4ff92SAndroid Build Coastguard Worker public:
48*89c4ff92SAndroid Build Coastguard Worker using result_type = T*;
49*89c4ff92SAndroid Build Coastguard Worker template <class V>
operator ()(V & v,typename std::enable_if<!std::is_polymorphic<V>::value>::type * =nullptr) const50*89c4ff92SAndroid Build Coastguard Worker T* operator()(V& v, typename std::enable_if<!std::is_polymorphic<V>::value>::type* = nullptr) const
51*89c4ff92SAndroid Build Coastguard Worker {
52*89c4ff92SAndroid Build Coastguard Worker return nullptr;
53*89c4ff92SAndroid Build Coastguard Worker }
54*89c4ff92SAndroid Build Coastguard Worker template <class V>
operator ()(V & v,typename std::enable_if<std::is_polymorphic<V>::value>::type * =nullptr) const55*89c4ff92SAndroid Build Coastguard Worker T* operator()(V& v, typename std::enable_if<std::is_polymorphic<V>::value>::type* = nullptr) const
56*89c4ff92SAndroid Build Coastguard Worker {
57*89c4ff92SAndroid Build Coastguard Worker return dynamic_cast<T*>(&v);
58*89c4ff92SAndroid Build Coastguard Worker }
59*89c4ff92SAndroid Build Coastguard Worker };
60*89c4ff92SAndroid Build Coastguard Worker }
61*89c4ff92SAndroid Build Coastguard Worker
62*89c4ff92SAndroid Build Coastguard Worker template <class T, class V>
63*89c4ff92SAndroid Build Coastguard Worker typename detail::dynamic_caster<T>::result_type
dynamic_variant_cast(V & v)64*89c4ff92SAndroid Build Coastguard Worker dynamic_variant_cast(V& v)
65*89c4ff92SAndroid Build Coastguard Worker {
66*89c4ff92SAndroid Build Coastguard Worker return mapbox::util::apply_visitor(detail::dynamic_caster<T>(), v);
67*89c4ff92SAndroid Build Coastguard Worker }
68*89c4ff92SAndroid Build Coastguard Worker
69*89c4ff92SAndroid Build Coastguard Worker template <class T, class V>
70*89c4ff92SAndroid Build Coastguard Worker typename detail::dynamic_caster<const T>::result_type
dynamic_variant_cast(const V & v)71*89c4ff92SAndroid Build Coastguard Worker dynamic_variant_cast(const V& v)
72*89c4ff92SAndroid Build Coastguard Worker {
73*89c4ff92SAndroid Build Coastguard Worker return mapbox::util::apply_visitor(detail::dynamic_caster<const T>(), v);
74*89c4ff92SAndroid Build Coastguard Worker }
75*89c4ff92SAndroid Build Coastguard Worker
76*89c4ff92SAndroid Build Coastguard Worker template <class T, class V>
static_variant_cast(V & v)77*89c4ff92SAndroid Build Coastguard Worker T& static_variant_cast(V& v)
78*89c4ff92SAndroid Build Coastguard Worker {
79*89c4ff92SAndroid Build Coastguard Worker return mapbox::util::apply_visitor(detail::static_caster<T>(), v);
80*89c4ff92SAndroid Build Coastguard Worker }
81*89c4ff92SAndroid Build Coastguard Worker
82*89c4ff92SAndroid Build Coastguard Worker template <class T, class V>
static_variant_cast(const V & v)83*89c4ff92SAndroid Build Coastguard Worker const T& static_variant_cast(const V& v)
84*89c4ff92SAndroid Build Coastguard Worker {
85*89c4ff92SAndroid Build Coastguard Worker return mapbox::util::apply_visitor(detail::static_caster<const T>(), v);
86*89c4ff92SAndroid Build Coastguard Worker }
87*89c4ff92SAndroid Build Coastguard Worker }
88*89c4ff92SAndroid Build Coastguard Worker }
89*89c4ff92SAndroid Build Coastguard Worker
90*89c4ff92SAndroid Build Coastguard Worker #endif // VARIANT_CAST_HPP
91