Last active
August 29, 2015 14:27
-
-
Save paosidufygthrj/b2450e262beecf2ae664 to your computer and use it in GitHub Desktop.
[C++]variant 型に格納された値を異なる variant 型に格納できる場合はコピーする
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <boost/variant.hpp> | |
#include <boost/mpl/for_each.hpp> | |
#include <boost/mpl/find.hpp> | |
#include <type_traits> | |
#include <iostream> | |
using namespace boost; | |
using namespace boost::mpl; | |
// variant が格納できる型に T 型が含まれているか返すメタ関数 | |
template <typename T, typename V> | |
struct is_included_variant { | |
using types = typename V::types; | |
using itr = typename find<types, T>::type; | |
using last = typename end<types>::type; | |
static const bool value = !is_same<itr, last>::value; | |
}; | |
// variant が T 型を格納可能ならパラメータの値をコピーするメタ関数 | |
template <typename T, typename V, typename Ignore = void> | |
struct setter_if_included_variant { | |
static void set(V&, const T&) {} | |
}; | |
template <typename T, typename V> | |
struct setter_if_included_variant<T, V, typename std::enable_if<is_included_variant<T, V>::value>::type> { | |
static void set(V& container, const T& value) { | |
container = value; | |
} | |
}; | |
template <typename T, typename V> | |
inline void set_if_included_variant(V& container, const T& value) { | |
setter_if_included_variant<T, V>::set(container, value); | |
} | |
// variant V 型に格納された値を variant C 型に格納できる場合はコピーするメタ関数 | |
template <typename C, typename V> | |
struct setter_if_included_variant2 { | |
struct functor { | |
C& container; | |
const V& value; | |
functor(C& container, const V& value) | |
: container(container), value(value) | |
{} | |
template <typename T> | |
void operator () (const T&) const { | |
if (value.type() == typeid(T)) { | |
set_if_included_variant(container, get<T>(value)); | |
} | |
} | |
}; | |
static void set(C& container, const V& value) { | |
functor f(container, value); | |
for_each<typename V::types>(f); | |
} | |
}; | |
template <typename C, typename V> | |
void set_if_included_variant2(C& container, const V& value) { | |
setter_if_included_variant2<C, V>::set(container, value); | |
std::cout << "c:" << container << " v:" << value << std::endl; | |
} | |
int main() { | |
using type1 = variant<int, float>; | |
using type2 = variant<int, double>; | |
type1 c = 0; | |
set_if_included_variant2(c, type2(1)); // c:1 v:1 | |
set_if_included_variant2(c, type2(2.0)); // c:1 v:2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment