19 #include <type_traits>
39 template <
typename Tag>
55 template <
typename Tagged>
278 template <
typename...
Data>
285 template <std::
size_t I>
291 template <std::
size_t I>
292 auto get() -> decltype(
auto) {
return std::get<I>(
data); }
294 template <std::
size_t I>
295 auto get()
const -> decltype(
auto) {
return std::get<I>(
data); }
297 template <
typename T>
298 auto get() -> decltype(
auto) {
return std::get<T>(
data); }
300 template <
typename T>
301 auto get()
const -> decltype(
auto) {
return std::get<T>(
data); }
305 {
return std::tuple_size<tuple_t>(); }
310 template <
typename...
Data>
312 {
return MyTuple<
Data...>{ std::forward<Data>(data)... }; }
315 template <std::size_t
I,
typename... T>
316 auto get(
MyTuple<T...>
const& t) -> decltype(
auto)
317 {
return t.template get<I>(); }
319 template <
typename Target,
typename... T>
320 auto get(MyTuple<T...>
const& t) -> decltype(
auto)
321 {
return t.template get<Target>(); }
330 template <std::size_t
I,
typename... T>
331 class tuple_element<I,
my::MyTuple<T...>> {
336 template <
typename... T>
337 class tuple_size<
my::MyTuple<T...>>
338 :
public std::integral_constant<std::size_t, my::MyTuple<T...>::tuple_size()>
347 template <
typename Tag,
typename Payload =
void>
354 template <
typename Tag>
373 MyStonedData heavyStone;
375 decltype(
auto) lightDataTagged = util::makeTagged<TagA>(lightData );
376 decltype(
auto) heavyStoneTagged = util::makeTagged<TagA>(heavyStone );
377 decltype(
auto) lightDataCopyTagged = util::makeTagged<TagA>(MyData(lightData));
379 static_assert( std::is_lvalue_reference<decltype(util::makeTagged<TagA>(lightData) )>(),
"makeTagged(moveable lvalue) does not produce a reference");
380 static_assert( std::is_lvalue_reference<decltype(util::makeTagged<TagA>(heavyStone) )>(),
"makeTagged(unmoveable lvalue) does not produce a reference");
381 static_assert(!std::is_lvalue_reference<decltype(util::makeTagged<TagA>(MyData(lightData)))>(),
"makeTagged(rvalue) produces a (lvalue) reference" );
382 static_assert(!std::is_rvalue_reference<decltype(util::makeTagged<TagA>(MyData(lightData)))>(),
"makeTagged(rvalue) produces a (rvalue) reference" );
384 assert(std::addressof(lightDataTagged ) == std::addressof(lightData ));
385 assert(std::addressof(heavyStoneTagged ) == std::addressof(heavyStone));
386 assert(std::addressof(lightDataCopyTagged) != std::addressof(lightData ));
396 auto const testTuple = std::make_tuple<TestTaggedA, TestTaggedB, TestTaggedA>( 1, 2, 3 );
397 assert((std::get<0>(testTuple).
value == 1));
398 assert((std::get<1>(testTuple).
value == 2));
399 assert((std::get<2>(testTuple).
value == 3));
403 assert(get<1U>(testTuple).
value == 2);
406 assert((util::getByExtractedType<TestExtractTag, TestTagB>(testTuple).value == 2));
413 auto data = my::make_my_tuple<DataA, DataC, DataB>(64,
'b', 66);
414 auto dataWithDupl = my::make_my_tuple<DataA, DataC, DataA>(64,
'b', 66);
420 static_assert(std::is_same<std::decay_t<decltype(get<0U>(data ))>, DataA>(),
"Unexpected type 1");
421 static_assert(std::is_same<std::decay_t<decltype(get<1U>(data ))>, DataC>(),
"Unexpected type 2");
422 static_assert(std::is_same<std::decay_t<decltype(get<2U>(data ))>, DataB>(),
"Unexpected type 3");
423 static_assert(std::is_same<std::decay_t<decltype(get<0U>(dataWithDupl))>, DataA>(),
"Unexpected type 1 (dupl)");
424 static_assert(std::is_same<std::decay_t<decltype(get<1U>(dataWithDupl))>, DataC>(),
"Unexpected type 2 (dupl)");
425 static_assert(std::is_same<std::decay_t<decltype(get<2U>(dataWithDupl))>, DataA>(),
"Unexpected type 3 (dupl)");
431 static_assert(std::is_same<std::decay_t<decltype(get<DataA>(data))>, DataA>(),
"Unexpected type 1" );
432 static_assert(std::is_same<std::decay_t<decltype(get<DataC>(data))>, DataC>(),
"Unexpected type 2" );
433 static_assert(std::is_same<std::decay_t<decltype(get<DataB>(data))>, DataB>(),
"Unexpected type 3" );
435 static_assert(std::is_same<std::decay_t<decltype(get<DataC>(dataWithDupl))>, DataC>(),
"Unexpected type 2 (dupl)");
442 static_assert(std::is_same<std::tuple_element_t<0U, decltype(data )>, DataA>(),
"Unexpected type 1");
443 static_assert(std::is_same<std::tuple_element_t<1U, decltype(data )>, DataC>(),
"Unexpected type 2");
444 static_assert(std::is_same<std::tuple_element_t<2U, decltype(data )>, DataB>(),
"Unexpected type 3");
445 static_assert(std::is_same<std::tuple_element_t<0U, decltype(dataWithDupl)>, DataA>(),
"Unexpected type 1 (dupl)");
446 static_assert(std::is_same<std::tuple_element_t<1U, decltype(dataWithDupl)>, DataC>(),
"Unexpected type 2 (dupl)");
447 static_assert(std::is_same<std::tuple_element_t<2U, decltype(dataWithDupl)>, DataA>(),
"Unexpected type 3 (dupl)");
452 static_assert(std::tuple_size<decltype(data )>() == 3U,
"Unexpected tuple size");
453 static_assert(std::tuple_size<decltype(dataWithDupl)>() == 3U,
"Unexpected tuple size (dupl)");
463 static_assert(
util::index_of_type<DataC, decltype(dataWithDupl)>() == 1U,
"Unexpected type 2 (dupl)");
473 static_assert(
util::index_of_tag<
TagC, decltype(dataWithDupl)>() == 1U,
"Unexpected tagged type 2 (dupl)");
483 static_assert(std::is_same<
util::type_with_tag_t<
TagC, decltype(dataWithDupl)>, DataC>(),
"Unexpected tagged type 2 (dupl)");
489 static_assert(
util::has_type<DataA, decltype(data) >(),
"Unexpected type 1");
490 static_assert(
util::has_type<DataC, decltype(data) >(),
"Unexpected type 2");
491 static_assert(
util::has_type<DataB, decltype(data) >(),
"Unexpected type 3");
492 static_assert(
util::has_type<DataA, decltype(dataWithDupl)>(),
"Unexpected type 1 (dupl)");
493 static_assert(
util::has_type<DataC, decltype(dataWithDupl)>(),
"Unexpected type 2 (dupl)");
494 static_assert(!
util::has_type<DataB, decltype(dataWithDupl)>(),
"Unexpected type 3 (dupl)");
499 static_assert(
util::has_tag<
TagA, decltype(data) >(),
"Unexpected tagged type 1");
500 static_assert(
util::has_tag<
TagC, decltype(data) >(),
"Unexpected tagged type 2");
501 static_assert(
util::has_tag<
TagB, decltype(data) >(),
"Unexpected tagged type 3");
502 static_assert(
util::has_tag<
TagA, decltype(dataWithDupl)>(),
"Unexpected tagged type 1 (dupl)");
503 static_assert(
util::has_tag<
TagC, decltype(dataWithDupl)>(),
"Unexpected tagged type 2 (dupl)");
504 static_assert(!
util::has_tag<
TagB, decltype(dataWithDupl)>(),
"Unexpected tagged type 3 (dupl)");
509 static_assert(
util::count_types<DataA, decltype(data) >() == 1,
"Unexpected type 1");
510 static_assert(
util::count_types<DataC, decltype(data) >() == 1,
"Unexpected type 2");
511 static_assert(
util::count_types<DataB, decltype(data) >() == 1,
"Unexpected type 3");
512 static_assert(
util::count_types<DataA, decltype(dataWithDupl)>() == 2,
"Unexpected type 1 (dupl)");
513 static_assert(
util::count_types<DataC, decltype(dataWithDupl)>() == 1,
"Unexpected type 2 (dupl)");
514 static_assert(
util::count_types<DataB, decltype(dataWithDupl)>() == 0,
"Unexpected type 3 (dupl)");
522 static_assert(
util::count_tags<
TagA, decltype(dataWithDupl)>() == 2,
"Unexpected type 1 (dupl)");
523 static_assert(
util::count_tags<
TagC, decltype(dataWithDupl)>() == 1,
"Unexpected type 2 (dupl)");
524 static_assert(
util::count_tags<
TagB, decltype(dataWithDupl)>() == 0,
"Unexpected type 3 (dupl)");
541 static_assert(std::is_same<std::decay_t<decltype(util::getByTag<TagA>(data) .data)>,
int >(),
"Unexpected type 1" );
542 static_assert(std::is_same<std::decay_t<decltype(util::getByTag<TagC>(data) .data)>,
char>(),
"Unexpected type 2" );
543 static_assert(std::is_same<std::decay_t<decltype(util::getByTag<TagB>(data) .data)>,
int >(),
"Unexpected type 3" );
545 static_assert(std::is_same<std::decay_t<decltype(util::getByTag<TagC>(dataWithDupl).data)>,
char>(),
"Unexpected type 2 (dupl)");
548 assert((util::getByTag<TagA>(data) ).data == 64);
549 assert((util::getByTag<TagC>(data) ).data ==
'b');
550 assert((util::getByTag<TagB>(data) ).data == 66);
552 assert((util::getByTag<TagC>(dataWithDupl)).data ==
'b');
see a below echo or echo I(indirect symbol).'echo" If the symbol is local (non-external)
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
An empty class that can't be copied nor moved.
auto make_my_tuple(Data &&...data)
Defines classes that can't be copied nor moved.
std::tuple< int, char, int > TestTuple_t
Holds whether the Target type is element of the specified std::tuple.
Tag class parametrized by a sequence of numbers.
my($xml, $fcl, $workdir, $check, $merge)
static constexpr std::size_t tuple_size()
std::tuple< TestTaggedA, TestTaggedB, TestTaggedA > TestTaggedTuple_t
Utilities to address elements of a tuple-like class by tag.
std::tuple< Data...> tuple_t
std::tuple_element_t< I, tuple_t > element_type
int main(int argc, char **argv)