поддержка кортежей на уровне языка
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.02.13 19:29
Оценка:
приветствую!

то, что кортежи стали частью стандарта — это замечательно, не спорю.
но декларация кортежей и доступ к их элементам — сводят на нет все плюсы кортежей %)

возможно, уже кто-то задавался аналогичным вопросом — нужна тулза, предоставляющая альтернативный синтаксис, и которую можно включить в pre-build степ.

в идеале, хотелось бы чего-то типа:
(int, std::string, double) result = (33, "string", .14);

auto func() -> (int, std::string, double) {}
auto result = func();
int i         = result[0];
std::string s = result[1];
double d      = result[2];

...

// как бонус, хотелось бы и чего-то типа:
int size = result.size();
static_cast(sizeof(result) == sizeof(func()), "bad size");


спасибо.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: поддержка кортежей на уровне языка
От: Abyx Россия  
Дата: 16.02.13 19:40
Оценка:
Здравствуйте, niXman, Вы писали:

X>в идеале, хотелось бы чего-то типа:

X>
X>(int, std::string, double) result = (33, "string", .14);

X>auto func() -> (int, std::string, double) {}
X>auto result = func();
X>int i         = result[0];
X>std::string s = result[1];
X>double d      = result[2];

я бы предпочел
[ccode]
auto (i, s, d) = make_tuple(33, "string", .14);


заметь, что = (a, b); это валидный С++ (operator,)
In Zen We Trust
Re: поддержка кортежей на уровне языка
От: Abyx Россия  
Дата: 16.02.13 19:43
Оценка:
Здравствуйте, niXman, Вы писали:

X>возможно, уже кто-то задавался аналогичным вопросом — нужна тулза, предоставляющая альтернативный синтаксис, и которую можно включить в pre-build степ.


я пишу код только в ИДЕ, и по этому негативно отношусь к тулзам которые в пребилде генерят код.
ИДЕ о таких тулзах ничего не знает, выдает ошибки парсинга, а худшем случае это ломает автокомплит, аутлайн и т.п.
In Zen We Trust
Re[2]: поддержка кортежей на уровне языка
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.02.13 19:51
Оценка:
Здравствуйте, Abyx, Вы писали:

A>'= (a, b);' — это валидный С++ (operator,)

кстати да. нужно подумать в этом направлении...

A>негативно отношусь к тулзам которые в пребилде генерят код.

аналогично. но другого выхода я не вижу.
хз, есть ли в планах стандартизаторов, сделать нормальным использование кортежей, как в нормальных ЯП?...

A>ИДЕ о таких тулзах ничего не знает, выдает ошибки парсинга, а худшем случае это ломает автокомплит, аутлайн и т.п.

да, согласен, но другого выхода не вижу.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: поддержка кортежей на уровне языка
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.02.13 20:05
Оценка:
Здравствуйте, Abyx, Вы писали:

A>auto (i, s, d) = make_tuple(33, "string", .14);

так это результат std::tie(). хотя тоже, удобно было бы... вот только на счет auto я тут не уверен. это выражение не создает новый тип.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: поддержка кортежей на уровне языка
От: Evgeny.Panasyuk Россия  
Дата: 16.02.13 20:36
Оценка: 160 (6) +1
Здравствуйте, niXman, Вы писали:

X>в идеале, хотелось бы чего-то типа


$$(int, std::string, double) result = $(33, "string", .14);
auto result2 = func();
int i         = result%$0;
std::string s = result%$1;
double d      = result%$2;
int sizet = size(result);
static_assert($sizeof(result) == $sizeof(func()), "bad size");

Подойдёт?

  реализация
#include <tuple>
#include <type_traits>
#include <iostream>
#include <ostream>

#define $(...) std::make_tuple(__VA_ARGS__)
#define $$(...) std::tuple<__VA_ARGS__>

template<unsigned i,typename ...Ts>
auto operator%(const std::tuple<Ts...> &t,std::integral_constant<unsigned,i>) -> decltype(std::get<i>(t))
{
   return std::get<i>(t);
}

std::integral_constant<unsigned,0> $0;
std::integral_constant<unsigned,1> $1;
std::integral_constant<unsigned,2> $2;

template<typename ...Ts>
auto custom_sizeof(const std::tuple<Ts...>&) -> char (&)[sizeof...(Ts)];

#define $sizeof(T) sizeof(custom_sizeof(T))

template<typename ...Ts>
unsigned size(const std::tuple<Ts...>&)
{
   return sizeof...(Ts);
}

auto func() -> $$(int, std::string, double) { return $(11,"ss",1.1); }


int main()
{
   using namespace std;
   $$(int, std::string, double) result = $(33, "string", .14);
   auto result2 = func();
   int i         = result%$0;
   std::string s = result%$1;
   double d      = result%$2;
   cout << i << " " << s << " " << d << endl;
   int sizet = size(result);
   static_assert($sizeof(result) == $sizeof(func()), "bad size");
   cout << $sizeof(result) << endl;
}
Re[2]: поддержка кортежей на уровне языка
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.02.13 20:46
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Подойдёт?

хех!
маладца, быстро ты сообразил...не растерялся)

пока, вроде все логично смотрится, но нужно обдумать возможные побочные эффекты...
еще, подскажи, '$' — это какой-то особенный символ для препроцессора? или препроцессор его использует ровно так же, как и любой другой символ?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: поддержка кортежей на уровне языка
От: Evgeny.Panasyuk Россия  
Дата: 16.02.13 20:50
Оценка:
Здравствуйте, niXman, Вы писали:

EP>>Подойдёт?

X>хех!
X>маладца, быстро ты сообразил...не растерялся)



X>пока, вроде все логично смотрится, но нужно обдумать возможные побочные эффекты...


да, конечно

X>еще, подскажи, '$' — это какой-то особенный символ для препроцессора? или препроцессор его использует ровно так же, как и любой другой символ?


Это простой символ из implementation-defined charset, поддерживается и в gcc и msvc — помню его использовал remark.
Можешь заменить допустим буквой T ...
Re[3]: поддержка кортежей на уровне языка
От: Abyx Россия  
Дата: 16.02.13 20:54
Оценка:
Здравствуйте, niXman, Вы писали:

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


A>>auto (i, s, d) = make_tuple(33, "string", .14);

X>так это результат std::tie(). хотя тоже, удобно было бы... вот только на счет auto я тут не уверен. это выражение не создает новый тип.

я имел ввиду чтобы auto (i, s, d) разворачивалось бы во что-то вроде

T1 i; T2 s; T3 d; tie(i, s, d) = ...


причем желательно, чтобы T1, T2, T3 могли бы быть не default-constructibe

эх, мечты-мечты...
на другой язык надо переходить, в С++ это все будет только в 202X
In Zen We Trust
Re[4]: поддержка кортежей на уровне языка
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.02.13 20:57
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>помню его использовал remark.

ах да, в своем проекте для выявления дата-рейсов в многопоточном коде.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[5]: поддержка кортежей на уровне языка
От: Evgeny.Panasyuk Россия  
Дата: 16.02.13 21:02
Оценка:
Здравствуйте, niXman, Вы писали:

EP>>помню его использовал remark.

X>ах да, в своем проекте для выявления дата-рейсов в многопоточном коде.

Да, именно.
Мне кстати было интересно как он работает, но хотелось самому додуматься. В итоге сделал мини-клон, на базе Boost.Coroutine. Из примитивов есть пока-что mutex Если выйдет что-то более менее юзабельное, тогда выложу под BSD.
Re[4]: поддержка кортежей на уровне языка
От: Evgeny.Panasyuk Россия  
Дата: 16.02.13 21:11
Оценка:
Здравствуйте, Abyx, Вы писали:

A>причем желательно, чтобы T1, T2, T3 могли бы быть не default-constructibe


$$$(some_tuple,a,b,c);
cout << a << " " << b << " " << c << endl;

так?

  реализация
#define UNIQ uniq_##__LINE__

#define AUX(r, uniq, i, elem) auto elem( std::get<i>(uniq) );
    
#define $$$(Tuple,...) \
    auto &&UNIQ=Tuple; \
    BOOST_PP_SEQ_FOR_EACH_I(AUX, UNIQ, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) )
Re[4]: поддержка кортежей на уровне языка
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.02.13 22:21
Оценка:
Здравствуйте, Abyx, Вы писали:

A>эх, мечты-мечты...

A>на другой язык надо переходить, в С++ это все будет только в 202X
я на Rust поглядываю. весьма обещающая идея. и реализация на высоте, поверх llvm.
но стандарт все еще не утвержден.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[5]: поддержка кортежей на уровне языка
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.02.13 22:37
Оценка:
Evgeny.Panasyuk, в общем, рискну заюзать твой код в проекте. вроде все должно пройти гладко.
если будут идеи по улучшению — пиши в этот же тред.

спасибо, пока что вопрос закрыт.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: поддержка кортежей на уровне языка
От: c-smile Канада http://terrainformatica.com
Дата: 16.02.13 22:38
Оценка: 5 (1)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

Может как-то так гуманнее?

#include <tuple>
#include <string>
#include <type_traits>
#include <iostream>
#include <ostream>

#define $(...) std::make_tuple(__VA_ARGS__)
#define $$(...) std::tuple<__VA_ARGS__>
#define $get(TT,I) std::get<I>(TT)
#define $length(TT) std::tuple_size<decltype(TT)>::value


Ну и тест:

auto func() -> $$(int, std::string, double) { return $(11,"ss",1.1); }

int main()
{
   using namespace std;
   $$(int, std::string, double) result = $(33, "string", .14);
   auto result2 = func();
   int i         = $get(result,0);
   std::string s = $get(result,1);
   double d      = $get(result,2);
   std::cout << i << " " << s << " " << d << endl;
   
   int sizet = $length(result);
   static_assert($length(result) == $length(func()), "bad size");
   cout << $length(result) << endl;
   return 0;
}
Re[3]: поддержка кортежей на уровне языка
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.02.13 22:42
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Может как-то так гуманнее?


если уж и рыть в этом направлении, то я бы предложил еще так:
#define $decl(...) std::make_tuple(__VA_ARGS__)
#define $make(...) std::tuple<__VA_ARGS__>
#define $get(TT,I) std::get<I>(TT)
#define $sizeof(TT) std::tuple_size<decltype(TT)>::value

т.к. размер кортежа известен в компайл-тайме, то $sizeof() как-то привычней, мне так кажется..
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[4]: поддержка кортежей на уровне языка
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.02.13 22:43
Оценка:
Здравствуйте, niXman, Вы писали:

X>#define $decl(...) std::make_tuple(__VA_ARGS__)

X>#define $make(...) std::tuple<__VA_ARGS__>

т.е. на оборот =)
#define $make(...) std::make_tuple(__VA_ARGS__)
#define $decl(...) std::tuple<__VA_ARGS__>

еще, думается мне, вместо $decl использовать $type было бы тоже более логичным...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[5]: поддержка кортежей на уровне языка
От: Abyx Россия  
Дата: 16.02.13 23:01
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

A>>причем желательно, чтобы T1, T2, T3 могли бы быть не default-constructibe


EP>
EP>$$$(some_tuple,a,b,c);
EP>cout << a << " " << b << " " << c << endl;
EP>

EP>так?

EP>
  реализация
EP>#define UNIQ uniq_##__LINE__

EP>#define AUX(r, uniq, i, elem) auto elem( std::get<i>(uniq) );
    
EP>#define $$$(Tuple,...) \
EP>    auto &&UNIQ=Tuple; \
EP>    BOOST_PP_SEQ_FOR_EACH_I(AUX, UNIQ, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) ) 
EP>


угу, только с нормальным синтаксисом, слева направо.
In Zen We Trust
Re[4]: поддержка кортежей на уровне языка
От: c-smile Канада http://terrainformatica.com
Дата: 17.02.13 02:02
Оценка:
Здравствуйте, niXman, Вы писали:

X>т.к. размер кортежа известен в компайл-тайме, то $sizeof() как-то привычней, мне так кажется..


sizeof традиционно ассоциируется с размером требуемой памяти в байтах.
tuple как вектор элементов характеризуется традиционно длиной (length or size).
Re: поддержка кортежей на уровне языка
От: jazzer Россия Skype: enerjazzer
Дата: 17.02.13 03:14
Оценка: +2
Здравствуйте, niXman, Вы писали:

X>в идеале, хотелось бы чего-то типа:

X>
X>auto func() -> (int, std::string, double) {}
X>auto result = func();
X>int i         = result[0];
X>std::string s = result[1];
X>double d      = result[2];
X>

Не пойму, чем не устраивают обычные туплы, конкретно tie?
http://www.boost.org/doc/libs/1_53_0/libs/tuple/doc/tuple_users_guide.html#tiers
будет
auto func() -> tuple(int, std::string, double) {}
int i;
std::string s;
double d;
tie(i, s, d) = func();
X>
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.