Симуляция вариадиков с помощью макросов
От: johny5 Новая Зеландия
Дата: 13.02.13 03:35
Оценка:
Всем привет.
Есть ли способ сгенерировать этот ужас с помощью Boost.Preprocessor?
template<typename ResultType, typename ParamClass, typename ParamType, typename ParamClass2, typename ParamType2, typename ParamClass3, typename ParamType3>
ResultType  QueryParam(ParamType (ParamClass::*param), ParamType2 (ParamClass2::*param2), ParamType3 (ParamClass3::*param3), typename const Identity<ResultType>::type& defaultValue = ResultType()) const
{
    const ParamType* paramPtr1 = QueryParamPtr(param);
    if( paramPtr1 )
    {
        return QueryDataDef<ResultType>(paramPtr1, defaultValue);
    }
    const ParamType2* paramPtr2 = QueryParamPtr(param2);
    if( paramPtr2 )
    {
        return QueryDataDef<ResultType>(paramPtr2, defaultValue);
    }
    const ParamType3* paramPtr3 = QueryParamPtr(param3);
    if( paramPtr3 )
    {
        return QueryDataDef<ResultType>(paramPtr3, defaultValue);
    }

    return defaultValue;
}


Я думаю тенденция тут видна.
А так-же хотелось бы посмотреть как бы это выглядело с вариадиками.

Спасибо!
Re: Симуляция вариадиков с помощью макросов
От: jazzer Россия Skype: enerjazzer
Дата: 13.02.13 03:58
Оценка: 8 (1)
Здравствуйте, johny5, Вы писали:

J>Всем привет.

J>Есть ли способ сгенерировать этот ужас с помощью Boost.Preprocessor?
Есть, конечно, ничего сложного
http://www.boostpro.com/mplbook/preprocessor.html

Тебе нужно расширение по количеству ParamClass/ParamType?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Симуляция вариадиков с помощью макросов
От: johny5 Новая Зеландия
Дата: 13.02.13 04:24
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, johny5, Вы писали:


J>>Всем привет.

J>>Есть ли способ сгенерировать этот ужас с помощью Boost.Preprocessor?
J>Есть, конечно, ничего сложного
J>http://www.boostpro.com/mplbook/preprocessor.html
Хорошая ссылка, спасибо.

J>Тебе нужно расширение по количеству ParamClass/ParamType?

Да.
Re[3]: Симуляция вариадиков с помощью макросов
От: jazzer Россия Skype: enerjazzer
Дата: 13.02.13 05:01
Оценка: 4 (1)
Здравствуйте, johny5, Вы писали:

J>>Тебе нужно расширение по количеству ParamClass/ParamType?

J>Да.

Как-то так:
#define ARGT(z, n, _) typename ParamClass##n, typename ParamType##n
#define ARGV(z, n, _) ParamType##n (ParamClass##n::*param##n)
#define DECL(z, n, _)                                              \
    const ParamType##n* paramPtr##n = QueryParamPtr(param##n);     \
    if( paramPtr##n )                                              \
    {                                                              \
        return QueryDataDef<ResultType>(paramPtr##n, defaultValue);\
    }

#define GEN(z, n, _)                                    \
template<typename ResultType, BOOST_PP_ENUM(n, ARGT, _)>\
ResultType  QueryParam(BOOST_PP_ENUM(n, ARGV, _), typename const Identity<ResultType>::type& defaultValue = ResultType()) const \
{                                                       \
  BOOST_PP_REPEAT(n, DECL, _)                           \
    return defaultValue;                                \
}

BOOST_PP_REPEAT_FROM_TO(1,4, GEN, _)
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Симуляция вариадиков с помощью макросов
От: rg45 СССР  
Дата: 13.02.13 07:38
Оценка:
Здравствуйте, johny5, Вы писали:

J>А так-же хотелось бы посмотреть как бы это выглядело с вариадиками.


С вариадиками все выглядело бы вполне элегантно, только параметр по умолчанию придется задавать всегда явно:

template<typename ResultT, typename... ParamTT>
ResultT QueryParam(const ResultT& defaultValue, ParamTT...);

template<typename ResultT>
ResultT QueryParam(const ResultT& defaultValue)
{
   return defaultValue;
}

template<typename ResultT, typename ParamC, typename ParamT, typename... ParamTT>
ResultT QueryParam(const ResultT& defaultValue, ParamT (ParamC::*param), ParamTT... params)
{
   const ParamT* paramPtr = QueryParamPtr(param);
   return paramPtr ? QueryDataDef(paramPtr, defaultValue) : QueryParam(defaultValue, params...);
}


Использование выглядит примерно так:
  int A::*none = nullptr;
  auto result = QueryParam(42, &A::foo, none, &B::bar, &C::baz);
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: Симуляция вариадиков с помощью макросов
От: rg45 СССР  
Дата: 13.02.13 14:56
Оценка: 8 (1)
Здравствуйте, rg45, Вы писали:

R> . . . только параметр по умолчанию придется задавать всегда явно:


Хотя нет, можно сохранить возможность неявного задания значения по умолчанию, если специальным образом обработать случай, когда последний параметр не является указателем на член:

template<typename ResultT, typename... ParamTT>
struct QueryParamAux;

template<typename ResultT, typename ParamC, typename ParamT, typename... ParamTT>
struct QueryParamAux<ResultT, ParamT ParamC::*, ParamTT...>
{
   static ResultT QueryParam(ParamT ParamC::*param, ParamTT... params)
   {
      const ParamT* paramPtr = QueryParamPtr(param);
      return paramPtr ? QueryDataDef<ResultT>(paramPtr) : QueryParamAux<ResultT, ParamTT...>::QueryParam(params...);
   }
};

template<typename ResultT>
struct QueryParamAux<ResultT, ResultT>
{
   static ResultT QueryParam(const ResultT& defaultValue)
   {
      return defaultValue;
   }
};

template<typename ResultT>
struct QueryParamAux<ResultT>
{
   static ResultT QueryParam()
   {
      return ResultT();
   }
};

template<typename ResultT, typename... ParamTT>
ResultT QueryParam(ParamTT... params)
{
   return QueryParamAux<ResultT, ParamTT...>::QueryParam(params...);
}


Теперь возможны оба варианта: как явное использование значения по умолчанию, так и неявное:

  QueryParam<int>(&A::foo, &B::bar, &C::baz);
  QueryParam<int>(&A::foo, &B::bar, &C::baz, 42);


Однако, нетрудно заметить, что код стал более громоздким. Это произошло потому, что из-за известного бага gcc (вернее недоработки), реализацию пришлось выполнить на шаблонах структур.

Ну, и кроме того, что это решение выглядит более громоздким, его преимущества по сравнению с предыдущим кажутся мне достаточно сомнительными.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re: Симуляция вариадиков с помощью макросов
От: nen777w  
Дата: 13.02.13 21:33
Оценка: 1 (1)
J>Всем привет.
J>Есть ли способ сгенерировать этот ужас с помощью Boost.Preprocessor?

skip

J>Я думаю тенденция тут видна.

J>А так-же хотелось бы посмотреть как бы это выглядело с вариадиками.


Вот тут
Автор: enji
Дата: 25.08.10
была подобная тема, я там отвечал.
Вообще на BOOST_PP много чего можно сделать.

J>Спасибо!
Re[3]: Симуляция вариадиков с помощью макросов
От: niXman Ниоткуда https://github.com/niXman
Дата: 15.02.13 08:15
Оценка:
Здравствуйте, rg45, Вы писали:

R>Это произошло потому, что из-за известного бага gcc (вернее недоработки), реализацию пришлось выполнить на шаблонах структур.


он же пофикшен.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[4]: Симуляция вариадиков с помощью макросов
От: rg45 СССР  
Дата: 17.02.13 07:23
Оценка:
Здравствуйте, niXman, Вы писали:

R>>Это произошло потому, что из-за известного бага gcc (вернее недоработки), реализацию пришлось выполнить на шаблонах структур.


X>он же пофикшен.


Однако, в 4.7.2 выдает все ту же ошибку: http://liveworkspace.org/code/xooeM$0
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[5]: Симуляция вариадиков с помощью макросов
От: niXman Ниоткуда https://github.com/niXman
Дата: 17.02.13 07:36
Оценка: 12 (1)
Здравствуйте, rg45, Вы писали:

R>Однако, в 4.7.2 выдает все ту же ошибку: http://liveworkspace.org/code/xooeM$0

ну да, не пояснил то, что этот баг пофикшен в trunk(4.8.0), 4.7-branch(4.7.3), 4.6-branch(4.6.4)
все эти три версии кандидаты на ближайший релиз.
в 4.8.0 этого бага нет:
http://liveworkspace.org/code/xooeM$1
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[6]: Симуляция вариадиков с помощью макросов
От: rg45 СССР  
Дата: 17.02.13 08:48
Оценка:
Здравствуйте, niXman, Вы писали:

R>>Однако, в 4.7.2 выдает все ту же ошибку: http://liveworkspace.org/code/xooeM$0

X>ну да, не пояснил то, что этот баг пофикшен в trunk(4.8.0), 4.7-branch(4.7.3), 4.6-branch(4.6.4)
X>все эти три версии кандидаты на ближайший релиз.
X>в 4.8.0 этого бага нет:
X>http://liveworkspace.org/code/xooeM$1

Да, я сразу заметил, что в 4.8.0 этой проблемы уже нет. Тем не менее, попытка переделать мой пример
Автор: rg45
Дата: 13.02.13
на шаблонах функций (без использования шаблонных классов) оказалась неудачной. Я сейчас еще раз проверил, дефект был в моей реализации, а не в компиляторе. Спасибо.
--
Не можешь достичь желаемого — пожелай достигнутого.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.