Skip to content

Commit e1ef919

Browse files
committed
DPL: split FunctionalHelpers.h in three
Including <functional> brings 200 ms alone. Splitting header so that pack and call_if_defined can be used without such an overhead.
1 parent 92ad52b commit e1ef919

File tree

7 files changed

+212
-167
lines changed

7 files changed

+212
-167
lines changed

Framework/Core/include/Framework/ASoA.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#ifndef O2_FRAMEWORK_ASOA_H_
1212
#define O2_FRAMEWORK_ASOA_H_
1313

14+
#include "Framework/Pack.h"
15+
#include "Framework/CheckTypes.h"
1416
#include "Framework/FunctionalHelpers.h"
1517
#include "Framework/CompilerBuiltins.h"
1618
#include "Framework/Traits.h"

Framework/Core/include/Framework/DataAllocator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "Framework/TypeTraits.h"
2727
#include "Framework/Traits.h"
2828
#include "Framework/SerializationMethods.h"
29-
#include "Framework/FunctionalHelpers.h"
29+
#include "Framework/CheckTypes.h"
3030

3131
#include "Headers/DataHeader.h"
3232
#include <TClass.h>

Framework/Core/include/Framework/Expressions.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212

1313
#include "Framework/BasicOps.h"
1414
#include "Framework/CompilerBuiltins.h"
15-
#include "Framework/FunctionalHelpers.h"
15+
#include "Framework/Pack.h"
16+
#include "Framework/CheckTypes.h"
1617
#include <arrow/type.h>
1718
#include <arrow/table.h>
1819
#include <gandiva/selection_vector.h>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
#ifndef O2_FRAMEWORK_CHECKTYPES_H_
11+
#define O2_FRAMEWORK_CHECKTYPES_H_
12+
13+
namespace o2::framework
14+
{
15+
16+
/// Helper to understand if a given type is complete (declared fully) or not (forward declared).
17+
/// See also: https://devblogs.microsoft.com/oldnewthing/20190710-00/?p=102678
18+
template <typename, typename = void>
19+
constexpr bool is_type_complete_v = false;
20+
21+
template <typename T>
22+
constexpr bool is_type_complete_v<T, std::void_t<decltype(sizeof(T))>> = true;
23+
24+
/// Helper which will invoke lambda if the type T is actually available.
25+
/// Can be used to check for existence or not of a given type.
26+
template <typename T, typename TLambda>
27+
void call_if_defined(TLambda&& lambda)
28+
{
29+
if constexpr (is_type_complete_v<T>) {
30+
lambda(static_cast<T*>(nullptr));
31+
}
32+
}
33+
34+
} // namespace o2::framework
35+
36+
#endif // O2_FRAMEWORK_CHECKTYPES_H_

Framework/Foundation/include/Framework/FunctionalHelpers.h

Lines changed: 4 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
// In applying this license CERN does not waive the privileges and immunities
88
// granted to it by virtue of its status as an Intergovernmental Organization
99
// or submit itself to any jurisdiction.
10-
#ifndef o2_framework_FunctionalHelpers_H_INCLUDED
11-
#define o2_framework_FunctionalHelpers_H_INCLUDED
10+
#ifndef O2_FRAMEWORK_FUNCTIONALHELPERS_H_
11+
#define O2_FRAMEWORK_FUNCTIONALHELPERS_H_
1212

13+
#include "Framework/Pack.h"
1314
#include <functional>
1415

1516
namespace o2::framework
@@ -23,150 +24,6 @@ struct memfun_type {
2324
};
2425
} // namespace
2526

26-
/// Type helper to hold a parameter pack. This is different from a tuple
27-
/// as there is no data associated to it.
28-
template <typename...>
29-
struct pack {
30-
};
31-
32-
/// template function to determine number of types in a pack
33-
template <typename... Ts>
34-
constexpr std::size_t pack_size(pack<Ts...> const&)
35-
{
36-
return sizeof...(Ts);
37-
}
38-
39-
template <std::size_t I, typename T>
40-
struct pack_element;
41-
42-
// recursive case
43-
template <std::size_t I, typename Head, typename... Tail>
44-
struct pack_element<I, pack<Head, Tail...>>
45-
: pack_element<I - 1, pack<Tail...>> {
46-
};
47-
48-
// base case
49-
template <typename Head, typename... Tail>
50-
struct pack_element<0, pack<Head, Tail...>> {
51-
typedef Head type;
52-
};
53-
54-
template <std::size_t I, typename T>
55-
using pack_element_t = typename pack_element<I, T>::type;
56-
57-
/// Templates for manipulating type lists in pack
58-
/// (see https://codereview.stackexchange.com/questions/201209/filter-template-meta-function/201222#201222)
59-
/// Example of use:
60-
/// template<typename T>
61-
/// struct is_not_double: std::true_type{};
62-
/// template<>
63-
/// struct is_not_double<double>: std::false_type{};
64-
/// The following will return a pack, excluding double
65-
/// filtered_pack<is_not_double, double, int, char, float*, double, char*, double>()
66-
///
67-
template <typename... Args1, typename... Args2>
68-
constexpr auto concatenate_pack(pack<Args1...>, pack<Args2...>)
69-
{
70-
return pack<Args1..., Args2...>{};
71-
}
72-
73-
template <typename P1, typename P2, typename... Ps>
74-
constexpr auto concatenate_pack(P1 p1, P2 p2, Ps... ps)
75-
{
76-
return concatenate_pack(p1, concatenate_pack(p2, ps...));
77-
};
78-
79-
template <typename... Ps>
80-
using concatenated_pack_t = decltype(concatenate_pack(Ps{}...));
81-
82-
/// Selects from the pack types that satisfy the Condition
83-
template <template <typename> typename Condition, typename Result>
84-
constexpr auto select_pack(Result result, pack<>)
85-
{
86-
return result;
87-
}
88-
89-
template <template <typename> typename Condition, typename Result, typename T, typename... Ts>
90-
constexpr auto select_pack(Result result, pack<T, Ts...>)
91-
{
92-
if constexpr (Condition<T>())
93-
return select_pack<Condition>(concatenate_pack(result, pack<T>{}), pack<Ts...>{});
94-
else
95-
return select_pack<Condition>(result, pack<Ts...>{});
96-
}
97-
98-
template <template <typename> typename Condition, typename... Types>
99-
using selected_pack = std::decay_t<decltype(select_pack<Condition>(pack<>{}, pack<Types...>{}))>;
100-
101-
/// Select only the items of a pack which match Condition
102-
template <template <typename> typename Condition, typename Result>
103-
constexpr auto filter_pack(Result result, pack<>)
104-
{
105-
return result;
106-
}
107-
108-
template <template <typename> typename Condition, typename Result, typename T, typename... Ts>
109-
constexpr auto filter_pack(Result result, pack<T, Ts...>)
110-
{
111-
if constexpr (Condition<T>())
112-
return filter_pack<Condition>(result, pack<Ts...>{});
113-
else
114-
return filter_pack<Condition>(concatenate_pack(result, pack<T>{}), pack<Ts...>{});
115-
}
116-
117-
template <typename T>
118-
void print_pack()
119-
{
120-
puts(__PRETTY_FUNCTION__);
121-
}
122-
123-
template <template <typename> typename Condition, typename... Types>
124-
using filtered_pack = std::decay_t<decltype(filter_pack<Condition>(pack<>{}, pack<Types...>{}))>;
125-
126-
/// Check if a given pack Pack has a type T inside.
127-
template <typename T, typename Pack>
128-
struct has_type;
129-
130-
template <typename T, typename... Us>
131-
struct has_type<T, pack<Us...>> : std::disjunction<std::is_same<T, Us>...> {
132-
};
133-
134-
template <typename T, typename... Us>
135-
inline constexpr bool has_type_v = has_type<T, Us...>::value;
136-
137-
template <typename T>
138-
constexpr size_t has_type_at(pack<> const&)
139-
{
140-
return static_cast<size_t>(-1);
141-
}
142-
143-
template <typename T, typename T1, typename... Ts>
144-
constexpr size_t has_type_at(pack<T1, Ts...> const&)
145-
{
146-
if constexpr (std::is_same_v<T, T1>)
147-
return 0;
148-
if constexpr (has_type_v<T, pack<T1, Ts...>>)
149-
return 1 + has_type_at<T>(pack<Ts...>{});
150-
return sizeof...(Ts) + 2;
151-
}
152-
153-
/// Intersect two packs
154-
template <typename S1, typename S2>
155-
struct intersect_pack {
156-
template <std::size_t... Indices>
157-
static constexpr auto make_intersection(std::index_sequence<Indices...>)
158-
{
159-
return filtered_pack<std::is_void,
160-
std::conditional_t<
161-
has_type_v<pack_element_t<Indices, S1>, S2>,
162-
pack_element_t<Indices, S1>, void>...>{};
163-
}
164-
using type = decltype(make_intersection(std::make_index_sequence<pack_size(S1{})>{}));
165-
};
166-
167-
template <typename S1, typename S2>
168-
using intersected_pack_t = typename intersect_pack<S1, S2>::type;
169-
17027
/// Type helper to hold metadata about a lambda or a class
17128
/// method.
17229
template <typename Ret, typename Class, typename... Args>
@@ -197,24 +54,6 @@ memfun_type<decltype(&F::operator())>
19754
return memfun_type<decltype(&F::operator())>();
19855
}
19956

200-
/// Helper to understand if a given type is complete (declared fully) or not (forward declared).
201-
/// See also: https://devblogs.microsoft.com/oldnewthing/20190710-00/?p=102678
202-
template <typename, typename = void>
203-
constexpr bool is_type_complete_v = false;
204-
205-
template <typename T>
206-
constexpr bool is_type_complete_v<T, std::void_t<decltype(sizeof(T))>> = true;
207-
208-
/// Helper which will invoke lambda if the type T is actually available.
209-
/// Can be used to check for existence or not of a given type.
210-
template <typename T, typename TLambda>
211-
void call_if_defined(TLambda&& lambda)
212-
{
213-
if constexpr (is_type_complete_v<T>) {
214-
lambda(static_cast<T*>(nullptr));
215-
}
216-
}
217-
21857
} // namespace o2::framework
21958

220-
#endif // o2_framework_FunctionalHelpers_H_INCLUDED
59+
#endif // O2_FRAMEWORK_FUNCTIONALHELPERS_H_

0 commit comments

Comments
 (0)