Created
September 21, 2017 23:33
-
-
Save nlyan/daf49e3d5226837822e3a161ab8b626e to your computer and use it in GitHub Desktop.
This file contains hidden or 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/mpl/at.hpp> | |
#include <boost/mpl/size.hpp> | |
#include <boost/variant/variant.hpp> | |
#include <type_traits> | |
namespace { | |
template <size_t N> | |
struct emplace_nth_helper { | |
template <typename Variant, typename Transform> | |
Variant | |
emplace (int const n, bool* const success, Transform&& transform) { | |
using type_vector = typename Variant::types; | |
using nth_type = typename boost::mpl::at_c<type_vector, N>::type; | |
if (n == N) { | |
*success = true; | |
return Variant (transform (nth_type ())); | |
} else { | |
return emplace_nth_helper<N - 1> ().template emplace<Variant> ( | |
n, success, std::forward<Transform> (transform)); | |
} | |
} | |
}; | |
template <> | |
struct emplace_nth_helper<0> { | |
template <typename Variant, typename Transform> | |
Variant | |
emplace (int const n, bool* const success, Transform&& transform) { | |
using type_vector = typename Variant::types; | |
using nth_type = typename boost::mpl::at_c<type_vector, 0>::type; | |
if (n) { | |
*success = false; | |
return Variant (); | |
} | |
*success = true; | |
return Variant (transform (nth_type ())); | |
} | |
}; | |
template <typename Variant, typename Transform> | |
inline Variant | |
emplace_nth (int n, bool* success, Transform&& transform) { | |
using type_vector = typename Variant::types; | |
auto const max = boost::mpl::size<type_vector>::value - 1; | |
if ((n < 0) || (n > max)) { | |
*success = false; | |
return Variant (); | |
} | |
emplace_nth_helper<boost::mpl::size<type_vector>::value - 1> next; | |
return next.template emplace<Variant> ( | |
n, success, std::forward<Transform> (transform)); | |
} | |
} // namespace | |
struct SomeOperation { | |
template <typename T> | |
T | |
operator() (T x) { | |
return x; | |
} | |
}; | |
int | |
main (int argc, char** argv) { | |
bool success; | |
auto var = emplace_nth<boost::variant<int, float>> ( | |
argc, &success, SomeOperation ()); | |
return var.which (); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Result of
g++ -std=c++14 -DNDEBUG -O3 variant.cpp
under GCC 7.2.0