Project
Loading...
Searching...
No Matches
TypeTraits.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#ifndef O2_FRAMEWORK_TYPETRAITS_H_
12#define O2_FRAMEWORK_TYPETRAITS_H_
13
14#include <type_traits>
15#include <vector>
16#include <memory>
17#include "Framework/Traits.h"
18
19#include <gsl/gsl>
20
21namespace o2::framework
22{
23// helper struct to mark a type as non-messageable by defining a type alias
24// with name 'non-messageable'
27
28// detect if a type is forced to be non-messageable, this is done by defining
29// a type alias with name 'non-messageable' of the type MarkAsNonMessageable
30template <typename T, typename _ = void>
31struct is_forced_non_messageable : public std::false_type {
32};
33
34// specialization to detect the type a lias
35template <typename T>
37 T,
38 typename std::enable_if<std::is_same<typename T::non_messageable, MarkAsNonMessageable>::value>::type> : public std::true_type {
39};
40
41template <typename T>
42struct is_forced_trivially_copyable : std::false_type {
43};
44
45// TODO: extend this to exclude structs with pointer data members
46// see e.g. https://stackoverflow.com/questions/32880990/how-to-check-if-class-has-pointers-in-c14
47template <typename T>
48struct is_messageable : std::conditional<(std::is_trivially_copyable<T>::value || //
49 framework::is_forced_trivially_copyable<T>::value) && //
50 !std::is_polymorphic<T>::value && //
51 !std::is_pointer<T>::value && //
52 !is_forced_non_messageable<T>::value, //
53 std::true_type,
54 std::false_type>::type {
55};
56
57// FIXME: it apears that gsl:span matches the criteria for being messageable, regardless of the
58// underlying type, but our goal is to identify structures that can be sent without serialization.
59// needs investigation
60template <typename T>
61struct is_messageable<gsl::span<T>> : std::false_type {
62};
63
64// Detect a container by checking on the container properties
65// this is the default trait implementation inheriting from false_type
66template <typename T, typename _ = void>
67struct is_container : std::false_type {
68};
69
70// helper to be substituted if the specified template arguments are
71// available
72template <typename... Ts>
75
76// the specialization for container types inheriting from true_type
77// the helper can be substituted if all the specified members are available
78// in the type
79template <typename T>
81 T,
82 std::conditional_t<
83 false,
84 class_member_checker<
85 typename T::value_type,
86 typename T::size_type,
87 typename T::allocator_type,
88 typename T::iterator,
89 typename T::const_iterator,
90 decltype(std::declval<T>().size()),
91 decltype(std::declval<T>().begin()),
92 decltype(std::declval<T>().end()),
93 decltype(std::declval<T>().cbegin()),
94 decltype(std::declval<T>().cend())>,
95 void>> : public std::true_type {
96};
97
98// Detect whether a container class has a type definition `value_type` of messageable type
99template <typename T, typename _ = void>
100struct has_messageable_value_type : std::false_type {
101};
102template <typename T>
103struct has_messageable_value_type<T, std::conditional_t<false, typename T::value_type, void>> : is_messageable<typename T::value_type> {
104};
105
106template <typename T, typename _ = void>
107struct is_span : std::false_type {
108};
109template <typename T>
110struct is_span<T, std::conditional_t<false, typename T::value_type, void>> : std::is_same<gsl::span<typename T::value_type>, T> {
111};
112
113// Detect whether a class has a ROOT dictionary
114// This member detector idiom is implemented using SFINAE idiom to look for
115// a 'Class()' method.
116// This is actually only covering classes using the ClasDef/Imp macros. ROOT
117// serialization however is also possible for types only having the link
118// in the LinkDef file. Such types can only be detected at runtime.
119template <typename T, typename _ = void>
120struct has_root_dictionary : std::false_type {
121};
122
123template <typename T>
125 T,
126 std::conditional_t<
127 false,
128 class_member_checker<
129 decltype(std::declval<T>().Class())>,
130 void>> : public std::true_type {
131};
132
133// Detect whether a container class has a type definition `mapped_type` with a root dictionary
134template <typename T, typename _ = void>
135struct has_root_dictionary_mapped_type : std::false_type {
136};
137
138template <typename T>
139struct has_root_dictionary_mapped_type<T, std::conditional_t<false, typename T::mapped_type, void>> : has_root_dictionary<typename T::mapped_type> {
140};
141
142// specialization for containers
143// covers cases with T::value_type having ROOT dictionary, meaning that
144// std::map is not supported out of the box
145//
146// Note: this is only a SFINAE idiom if the default type of the second template
147// argument in the declaration is the same as the conditionally produced one in
148// the specialization (void in this case)
149template <typename T>
150class has_root_dictionary<T, typename std::enable_if<is_container<T>::value>::type>
151 : public has_root_dictionary<std::remove_pointer_t<typename T::value_type>>
152{
153};
154
155} // namespace o2::framework
156#endif // FRAMEWORK_TYPETRAITS_H
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288