Здравствуйте, SomeOne_TT, Вы писали:
SO_>Есть три внешние иерархии типов, которые надо маппить друг в друга.
SO_>Первая иерархия построена на enum-like int
SO_>Третья — весьма странный (не понимаю, зачем?) способ
SO_>Задача — написать конвертер, который маппит значение из одной иерархии в другую.
SO_>Желаемый интерфейс — что-то вроде
SO_>Что ни придумаю — выходят какие-то уродцы, да еще и ns_crap::Fruit как темплейт аргумент применить невозможно, т.к. это не тип и не значение.
SO_>Какие есть варианты?
Я вот здесь набросал. Интерфейс сохранил в точности, как ты показал:
https://ideone.com/Fiv1OQ
Единственное изменение — статические ссылки на объеты Fruit пришлось заменить "живыми" объектами, иначе не удается сделать их параметрами шаблона.
Поддержка:
template <int V, typename T, const ns_crap::Fruit& O>
struct MapEntry
{
static constexpr int value = V;
using type = T;
static constexpr const ns_crap::Fruit& object = O;
};
template <int> struct from_val;
template <typename> struct from_type;
template <const ns_crap::Fruit&> struct from_crap;
#define MAKE_MAP_ENTRY(value, type, object) \
template <> struct from_val<value> : MapEntry<value, type, object> {}; \
template <> struct from_type<type> : MapEntry<value, type, object> {}; \
template <> struct from_crap<object> : MapEntry<value, type, object> {};
Использование:
MAKE_MAP_ENTRY(ns_val::APPLE, ns_types::Apple, ns_crap::Fruit::Apple)
MAKE_MAP_ENTRY(ns_val::PINEAPPLE, ns_types::Pineapple, ns_crap::Fruit::Pinapple)
MAKE_MAP_ENTRY(ns_val::PEAR, ns_types::Pear, ns_crap::Fruit::Pear)
// getting values
static_assert(from_val<ns_val::APPLE>::value == ns_val::APPLE, "");
static_assert(from_type<ns_types::Pineapple>::value == ns_val::PINEAPPLE, "");
static_assert(from_crap<ns_crap::Fruit::Pear>::value == ns_val::PEAR, "");
// getting types
static_assert(std::is_same<from_val<ns_val::APPLE>::type, ns_types::Apple>::value, "");
static_assert(std::is_same<from_type<ns_types::Pineapple>::type, ns_types::Pineapple>::value, "");
static_assert(std::is_same<from_crap<ns_crap::Fruit::Pear>::type, ns_types::Pear>::value, "");
// getting objects
static_assert(&from_val<ns_val::APPLE>::object == &ns_crap::Fruit::Apple, "");
static_assert(&from_type<ns_types::Pineapple>::object == &ns_crap::Fruit::Pinapple, "");
static_assert(&from_crap<ns_crap::Fruit::Pear>::object == &ns_crap::Fruit::Pear, "");