Skip to content

Instantly share code, notes, and snippets.

@mpark
Last active August 24, 2017 06:15
Show Gist options
  • Save mpark/52cac57dcc1b45d5df919afe2c0ca1a2 to your computer and use it in GitHub Desktop.
Save mpark/52cac57dcc1b45d5df919afe2c0ca1a2 to your computer and use it in GitHub Desktop.
A tuple that propagates implicit conversion properly
#include <iostream>
#include <type_traits>
#include <utility>
namespace mpark {
struct Implicit {};
struct Explicit {};
template <typename T>
struct copy_init {
template <typename Arg>
std::enable_if_t<std::is_convertible<Arg &&, T>::value,
T> operator()(Arg &&arg) const {
return std::forward<Arg>(arg);
}
};
template <std::size_t, typename T>
struct tuple_leaf {
template <typename U>
explicit tuple_leaf(Implicit, U&& u) : t(copy_init<T>{}(std::forward<U>(u))) {}
template <typename U>
explicit tuple_leaf(Explicit, U&& u) : t(std::forward<U>(u)) {}
T t;
};
template <typename Is, typename... Ts>
struct tuple_impl;
template <std::size_t... Is, typename... Ts>
struct tuple_impl<std::index_sequence<Is...>, Ts...> : tuple_leaf<Is, Ts>... {
template <typename... Us,
std::enable_if_t<(... && std::is_convertible<Us, Ts>::value), int> = 0>
tuple_impl(Us&&... us)
: tuple_leaf<Is, Ts>(Implicit{}, std::forward<Us>(us))... {}
template <typename... Dummies,
typename... Us,
std::enable_if_t<(... && std::is_constructible<Ts, Us>::value), int> = 0>
explicit tuple_impl(Dummies..., Us&&... us)
: tuple_leaf<Is, Ts>(Explicit{}, std::forward<Us>(us))... {}
};
template <typename... Ts>
using tuple = tuple_impl<std::index_sequence_for<Ts...>, Ts...>;
} // namespace mpark
struct X {
X(int) { std::cout << "X(int)\n"; }
explicit X(long) { std::cout << "X(long)\n"; }
X(const X&) { std::cout << "X(const X&)\n"; }
X(X&&) { std::cout << "X(X&&)\n"; }
};
int main() {
mpark::tuple<X> x0 = 42;
mpark::tuple<X> x1 = 42L;
mpark::tuple<X> x2(42);
mpark::tuple<X> x3(42L);
(void)x0;
(void)x1;
(void)x2;
(void)x3;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment