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
41// TODO: extend this to exclude structs with pointer data members
42// see e.g. https://stackoverflow.com/questions/32880990/how-to-check-if-class-has-pointers-in-c14
43template <typename T>
44struct is_messageable : std::conditional<std::is_trivially_copyable<T>::value && //
45 !std::is_polymorphic<T>::value && //
46 !std::is_pointer<T>::value && //
47 !is_forced_non_messageable<T>::value, //
48 std::true_type,
49 std::false_type>::type {
50};
51
52// FIXME: it apears that gsl:span matches the criteria for being messageable, regardless of the
53// underlying type, but our goal is to identify structures that can be sent without serialization.
54// needs investigation
55template <typename T>
56struct is_messageable<gsl::span<T>> : std::false_type {
57};
58
59// Detect a container by checking on the container properties
60// this is the default trait implementation inheriting from false_type
61template <typename T, typename _ = void>
62struct is_container : std::false_type {
63};
64
65// helper to be substituted if the specified template arguments are
66// available
67template <typename... Ts>
70
71// the specialization for container types inheriting from true_type
72// the helper can be substituted if all the specified members are available
73// in the type
74template <typename T>
76 T,
77 std::conditional_t<
78 false,
79 class_member_checker<
80 typename T::value_type,
81 typename T::size_type,
82 typename T::allocator_type,
83 typename T::iterator,
84 typename T::const_iterator,
85 decltype(std::declval<T>().size()),
86 decltype(std::declval<T>().begin()),
87 decltype(std::declval<T>().end()),
88 decltype(std::declval<T>().cbegin()),
89 decltype(std::declval<T>().cend())>,
90 void>> : public std::true_type {
91};
92
93// Detect whether a container class has a type definition `value_type` of messageable type
94template <typename T, typename _ = void>
95struct has_messageable_value_type : std::false_type {
96};
97template <typename T>
98struct has_messageable_value_type<T, std::conditional_t<false, typename T::value_type, void>> : is_messageable<typename T::value_type> {
99};
100
101template <typename T, typename _ = void>
102struct is_span : std::false_type {
103};
104template <typename T>
105struct is_span<T, std::conditional_t<false, typename T::value_type, void>> : std::is_same<gsl::span<typename T::value_type>, T> {
106};
107
108// Detect whether a class has a ROOT dictionary
109// This member detector idiom is implemented using SFINAE idiom to look for
110// a 'Class()' method.
111// This is actually only covering classes using the ClasDef/Imp macros. ROOT
112// serialization however is also possible for types only having the link
113// in the LinkDef file. Such types can only be detected at runtime.
114template <typename T, typename _ = void>
115struct has_root_dictionary : std::false_type {
116};
117
118template <typename T>
120 T,
121 std::conditional_t<
122 false,
123 class_member_checker<
124 decltype(std::declval<T>().Class())>,
125 void>> : public std::true_type {
126};
127
128// Detect whether a container class has a type definition `mapped_type` with a root dictionary
129template <typename T, typename _ = void>
130struct has_root_dictionary_mapped_type : std::false_type {
131};
132
133template <typename T>
134struct has_root_dictionary_mapped_type<T, std::conditional_t<false, typename T::mapped_type, void>> : has_root_dictionary<typename T::mapped_type> {
135};
136
137// specialization for containers
138// covers cases with T::value_type having ROOT dictionary, meaning that
139// std::map is not supported out of the box
140//
141// Note: this is only a SFINAE idiom if the default type of the second template
142// argument in the declaration is the same as the conditionally produced one in
143// the specialization (void in this case)
144template <typename T>
145class has_root_dictionary<T, typename std::enable_if<is_container<T>::value>::type>
146 : public has_root_dictionary<std::remove_pointer_t<typename T::value_type>>
147{
148};
149
150} // namespace o2::framework
151#endif // FRAMEWORK_TYPETRAITS_H
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
Defining DataPointCompositeObject explicitly as copiable.