WarptenLe 16/09/2018 à 00:49
./3881#include <type_traits>
#include <unordered_map>
#include <vector>
#include <queue>
#include <iostream>
#include <map>
#include <memory>
#include <functional>
#include <cmath>
#include <list>
#include <unordered_set>
#include <boost/core/demangle.hpp>
namespace xstd
{
template <typename Source, typename Target>
struct forward_modifiers {
using type = Target;
};
template <typename Source, typename Target>
struct forward_modifiers<const Source, Target> {
using type = typename forward_modifiers<Source, const Target>::type;
};
template <typename Source, typename Target>
struct forward_modifiers<volatile Source, Target> {
using type = typename forward_modifiers<Source, volatile Target>::type;
};
template <typename Source, typename Target>
struct forward_modifiers<Source*, Target> {
using type = typename forward_modifiers<Source, Target*>::type;
};
template <typename Source, typename Target>
struct forward_modifiers<Source&, Target> {
using type = typename forward_modifiers<Source, Target&>::type;
};
template <typename Source, typename Target>
struct forward_modifiers<Source&&, Target> {
using type = typename forward_modifiers<Source, Target&&>::type;
};
template <typename T>
struct pack_arity {
constexpr static const size_t arity = 0;
};
template <template <typename...> typename Base, typename... Args>
struct pack_arity<Base<Args...>> {
constexpr static const size_t arity = sizeof...(Args);
};
namespace details
{
template <typename Source,
typename Target,
typename Container>
struct rebind_lookup {
using corrected_type = Container;
};
// Replaces every occurence of Source in Args by Target.
template <typename Source,
typename Target,
template <typename...> typename Container,
typename... Args>
struct rebind_lookup<Source, Target, Container<Args...>> {
private:
template <size_t Idx>
using nth_element_t = typename std::decay<decltype(std::get<Idx>(std::tuple<Args...>{}))>::type;
template <size_t Idx>
using corrected_type_i = typename std::conditional<
std::is_same<
Source,
nth_element_t<Idx>
>::value,
typename forward_modifiers<nth_element_t<Idx>, Target>::type,
//nth_element_t<Idx>
typename rebind_lookup<Source, Target, nth_element_t<Idx>>::corrected_type
>::type;
template <size_t... Is>
constexpr static auto rebind_all(std::index_sequence<Is...>) {
return Container<corrected_type_i<Is>...>{};
}
public:
template <size_t... Is>
using corrected_types = Container<corrected_type_i<Is>...>;
using corrected_type = decltype(rebind_all(std::make_index_sequence<pack_arity<Container<Args...>>::arity>()));
};
}
template <typename Container>
struct container_traits;
template <template <typename...> typename Container, typename... Args>
struct container_traits<Container<Args...>> {
using container_type = Container<Args...>;
using allocator_type = typename container_type::allocator_type;
using value_type = typename container_type::value_type;
template <typename T>
using rebound_container_type = typename details::rebind_lookup<
value_type,
T,
Container<Args...>
>::corrected_type;
};
}
int main() {
std::vector<int> v;
using vector_traits = xstd::container_traits<std::vector<int>>;
using rebound_vector = typename vector_traits::template rebound_container_type<float>;
std::cout << boost::core::demangle(typeid(v).name()) << std::endl;
return 0;
}
