4 Implements traits complementary to those provided in <type_traits>
6 * Implements `IsRelocatable` trait.
7 * Implements `IsOneOf` trait
8 * Macros to state the assumptions easily
13 `<type_traits>` is the Standard type-traits library defining a variety of traits
14 such as `is_integral` or `is_floating_point`. This helps to gain more
15 information about a given type.
17 `folly/Traits.h` implements traits complementing those present in the Standard.
23 In C++, the default way to move an object is by
24 calling the copy constructor and destroying the old copy
25 instead of directly copying the memory contents by using memcpy().
26 The conservative approach of moving an object assumes that the copied
27 object is not relocatable.
28 The two following code sequences should be semantically equivalent for a
33 void conservativeMove(T * from, T * to) {
40 void optimizedMove(T * from, T * to) {
41 memcpy(to, from, sizeof(T));
46 Very few C++ types are non-relocatable.
47 The type defined below maintains a pointer inside an embedded buffer and
48 hence would be non-relocatable. Moving the object by simply copying its
49 memory contents would leave the internal pointer pointing to the old buffer.
52 class NonRelocatableType {
55 char * pointerToBuffer;
58 NonRelocatableType() : pointerToBuffer(buffer) {}
63 We can optimize the task of moving a relocatable type T using memcpy.
64 IsRelocatable<T>::value describes the ability of moving around memory
65 a value of type T by using memcpy.
73 template <class T1, class T2>
74 class MyParameterizedType;
79 * Declaring a type as relocatable
81 Appending the lines below after definition of My*Type
82 (`MyParameterizedType` or `MySimpleType`) will declare it as relocatable
85 /* Definition of My*Type goes here */
86 // global namespace (not inside any namespace)
88 // defining specialization of IsRelocatable for MySimpleType
90 struct IsRelocatable<MySimpleType> : std::true_type {};
91 // defining specialization of IsRelocatable for MyParameterizedType
92 template <class T1, class T2>
93 struct IsRelocatable<MyParameterizedType<T1, T2>>
94 : ::std::true_type {};
98 * To make it easy to state assumptions for a regular type or a family of
99 parameterized type, various macros can be used as shown below.
101 * Stating that a type is Relocatable using a macro
106 // For a Regular Type
107 FOLLY_ASSUME_RELOCATABLE(MySimpleType);
108 // For a Parameterized Type
109 FOLLY_ASSUME_RELOCATABLE(MyParameterizedType<T1, T2>);
113 `fbvector` only works with relocatable objects. If assumptions are not stated
114 explicitly, `fbvector<MySimpleType>` or `fbvector<MyParameterizedType>`
115 will fail to compile due to assertion below:
118 static_assert(IsRelocatable<My*Type>::value, "");
121 FOLLY_ASSUME_FBVECTOR_COMPATIBLE*(type) macros can be used to state that type
122 is relocatable and has nothrow constructor.
124 * Stating that a type is `fbvector-compatible` using macros
125 i.e. relocatable and has nothrow default constructor
128 // at global level, i.e no namespace
129 // macro for regular type
130 FOLLY_ASSUME_FBVECTOR_COMPATIBLE(MySimpleType);
131 // macro for types having 2 template parameters (MyParameterizedType)
132 FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(MyParameterizedType);
137 * FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(MyTypeHavingOneParameter) macro is
138 for family of parameterized types having 1 parameter
140 * FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(MyTypeHavingThreeParameters) macro is
141 for family of parameterized types having 3 parameters
143 * FOLLY_ASSUME_FBVECTOR_COMPATIBLE_4(MyTypeHavingFourParameters) macro is
144 for family of parameterized types having 4 parameters
146 Few common types, namely `std::basic_string`, `std::vector`, `std::list`,
147 `std::map`, `std::deque`, `std::set`, `std::unique_ptr`, `std::shared_ptr`,
148 `std::function`, which are compatible with `fbvector` are already instantiated
149 and declared compatible with `fbvector`. `fbvector` can be directly used with
150 any of these C++ types.
152 `std::pair` can be safely assumed to be compatible with `fbvector` if both of
158 `std::is_same<T1, T2>::value` can be used to test if types of T1 and T2 are
159 same. `folly::IsOneOf<T, T1, Ts...>::value` can be used to test if type of T1
160 matches the type of one of the other template parameter, T1, T2, ...Tn.
161 Recursion is used to implement this type trait.