Информация об изменениях

Сообщение Re: type converter от 26.09.2018 22:42

Изменено 26.09.2018 22:50 rg45

Re: type converter
Здравствуйте, 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, "");
Re: type converter
Здравствуйте, 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, "");