Skip to content

Commit cea7a2c

Browse files
committed
Framework: helper to decompose structs to tuples
This should come handy, among other things, for the AnalysisTask business.
1 parent 6bd8276 commit cea7a2c

3 files changed

Lines changed: 136 additions & 0 deletions

File tree

Framework/Foundation/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,8 @@ o2_add_test(test_Traits NAME test_FrameworkFoundation_test_Traits
1414
COMPONENT_NAME FrameworkFoundation
1515
SOURCES test/test_Traits.cxx
1616
PUBLIC_LINK_LIBRARIES O2::FrameworkFoundation)
17+
18+
o2_add_test(test_StructToTuple NAME test_FrameworkFoundation_StructToTuple
19+
COMPONENT_NAME FrameworkFoundation
20+
SOURCES test/test_StructToTuple.cxx
21+
PUBLIC_LINK_LIBRARIES O2::FrameworkFoundation)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
#include <Framework/Traits.h>
12+
#include <tuple>
13+
#include <type_traits>
14+
15+
namespace o2::framework
16+
{
17+
struct any_type {
18+
template <class T>
19+
constexpr operator T(); // non explicit
20+
};
21+
22+
template <class T, typename... Args>
23+
decltype(void(T{ std::declval<Args>()... }), std::true_type())
24+
test(int);
25+
26+
template <class T, typename... Args>
27+
std::false_type
28+
test(...);
29+
30+
template <class T, typename... Args>
31+
struct is_braces_constructible : decltype(test<T, Args...>(0)) {
32+
};
33+
34+
/// Helper function to convert a brace-initialisable struct to
35+
/// a tuple.
36+
template <class T>
37+
auto constexpr to_tuple(T&& object) noexcept
38+
{
39+
using type = std::decay_t<T>;
40+
if constexpr (is_braces_constructible<type, any_type, any_type, any_type, any_type>{}) {
41+
auto&& [p1, p2, p3] = object;
42+
return std::make_tuple(p1, p2, p3);
43+
} else if constexpr (is_braces_constructible<type, any_type, any_type, any_type>{}) {
44+
auto&& [p1, p2] = object;
45+
return std::make_tuple(p1, p2);
46+
} else if constexpr (is_braces_constructible<type, any_type, any_type>{}) {
47+
auto&& [p1] = object;
48+
return std::make_tuple(p1);
49+
} else if constexpr (is_braces_constructible<type, any_type>{}) {
50+
return std::make_tuple();
51+
} else {
52+
static_assert(always_static_assert<type>(), "You must inherit from AnalysisTask");
53+
}
54+
}
55+
56+
/// Helper function to convert a brace-initialisable struct to
57+
/// a tuple.
58+
template <class T>
59+
auto constexpr to_tuple_refs(T&& object) noexcept
60+
{
61+
using type = std::decay_t<T>;
62+
if constexpr (is_braces_constructible<type, any_type, any_type, any_type, any_type>{}) {
63+
auto&& [p1, p2, p3] = object;
64+
return std::tie(p1, p2, p3);
65+
} else if constexpr (is_braces_constructible<type, any_type, any_type, any_type>{}) {
66+
auto&& [p1, p2] = object;
67+
return std::tie(p1, p2);
68+
} else if constexpr (is_braces_constructible<type, any_type, any_type>{}) {
69+
auto&& [p1] = object;
70+
return std::tie(p1);
71+
} else if constexpr (is_braces_constructible<type, any_type>{}) {
72+
return std::make_tuple();
73+
} else {
74+
static_assert(always_static_assert<type>(), "You must inherit from AnalysisTask");
75+
}
76+
}
77+
78+
} // namespace o2::framework
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
#define BOOST_TEST_MODULE Test Framework Traits
12+
#define BOOST_TEST_MAIN
13+
#define BOOST_TEST_DYN_LINK
14+
15+
#include <boost/test/unit_test.hpp>
16+
#include "Framework/StructToTuple.h"
17+
18+
struct Foo {
19+
};
20+
21+
// FIXME: this should really struct Bar : Foo, but a c++17 bug
22+
// in GCC 7.3 (solved in 7.4 / 8.x) prevents us from doing so
23+
// for now.
24+
struct Bar : Foo {
25+
int foo = 1;
26+
int bar = 2;
27+
};
28+
29+
BOOST_AUTO_TEST_CASE(TestStructToTuple)
30+
{
31+
Foo foo;
32+
//auto t1 = o2::framework::to_tuple(foo);
33+
//#BOOST_CHECK_EQUAL(std::get<0>(t1), 1);
34+
// Expand a struct which inherits from
35+
// another..
36+
Bar bar{ {}, 4, 5 };
37+
BOOST_CHECK_EQUAL(bar.foo, 4);
38+
BOOST_CHECK_EQUAL(bar.bar, 5);
39+
auto t2 = o2::framework::to_tuple(bar);
40+
BOOST_CHECK_EQUAL(std::get<0>(t2), 4);
41+
BOOST_CHECK_EQUAL(std::get<1>(t2), 5);
42+
std::get<0>(t2) = 10;
43+
BOOST_CHECK_EQUAL(std::get<0>(t2), 10);
44+
BOOST_CHECK_EQUAL(bar.foo, 4);
45+
46+
auto t3 = o2::framework::to_tuple_refs(bar);
47+
BOOST_CHECK_EQUAL(std::get<0>(t3), 4);
48+
BOOST_CHECK_EQUAL(std::get<1>(t3), 5);
49+
50+
std::get<0>(t3) = 10;
51+
BOOST_CHECK_EQUAL(std::get<0>(t3), 10);
52+
BOOST_CHECK_EQUAL(bar.foo, 10);
53+
}

0 commit comments

Comments
 (0)