proxygen
|
Classes | |
struct | has_IsRelocatable__folly_traits_impl__ |
struct | has_IsZeroInitializable__folly_traits_impl__ |
struct | has_true_IsRelocatable |
struct | has_true_IsZeroInitializable |
struct | IsRelocatable_is_true |
struct | IsZeroInitializable_is_true |
struct | type_t_ |
Typedefs | |
template<typename TTheClass_ > | |
using | has_IsRelocatable = typename std::conditional< has_IsRelocatable__folly_traits_impl__< TTheClass_ >::template test< TTheClass_ >(nullptr), std::true_type, std::false_type >::type |
template<typename TTheClass_ > | |
using | has_IsZeroInitializable = typename std::conditional< has_IsZeroInitializable__folly_traits_impl__< TTheClass_ >::template test< TTheClass_ >(nullptr), std::true_type, std::false_type >::type |
type_t
A type alias for the first template type argument. type_t
is useful for controlling class-template and function-template partial specialization.
Example:
template <typename value>=""> class Container { public: template <typename... Args> Container( type_t<in_place_t, decltype(Value(std::declval<Args>()...))>, Args&&...); };
void_t
A type alias for void
. void_t
is useful for controling class-template and function-template partial specialization.
Example:
// has_value_type<T>::value is true if T has a nested type value_type
template <class T, class = void> struct has_value_type : std::false_type {};
template <class t>=""> struct has_value_type<T, folly::void_t<typename T::value_type>> : std::true_type {}; There is a bug in libstdc++, libc++, and MSVC's STL that causes it to ignore unused template parameter arguments in template aliases and does not cause substitution failures. This defect has been recorded here: http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1558.
This causes the implementation of std::void_t to be buggy, as it is likely defined as something like the following:
template <typename...> using void_t = void;
This causes the compiler to ignore all the template arguments and does not help when one wants to cause substitution failures. Rather declarations which have void_t in orthogonal specializations are treated as the same. For example, assuming the possible T
types are only allowed to have either the alias one
or two
and never both or none:
template <typename T, typename std::void_t<std::decay_t<T>::one>* = nullptr> void foo(T&&) {} template <typename T, typename std::void_t<std::decay_t<T>::two>* = nullptr> void foo(T&&) {}
The second foo() will be a redefinition because it conflicts with the first one; void_t does not cause substitution failures - the template types are just ignored.
IsRelocatable<T>::value describes the ability of moving around memory a value of type T by using memcpy (as opposed to the conservative approach of calling the copy constructor and then destroying the old temporary. Essentially for a relocatable type, the following two sequences of code should be semantically equivalent:
void move1(T * from, T * to) { new(to) T(from); (*from).~T(); }
void move2(T * from, T * to) { memcpy(to, from, sizeof(T)); }
Most C++ types are relocatable; the ones that aren't would include internal pointers or (very rarely) would need to update remote pointers to pointers tracking them. All C++ primitive types and type constructors are relocatable.
This property can be used in a variety of optimizations. Currently fbvector uses this property intensively.
The default conservatively assumes the type is not relocatable. Several specializations are defined for known types. You may want to add your own specializations. Do so in namespace folly and make sure you keep the specialization of IsRelocatable<SomeStruct> in the same header as SomeStruct.
You may also declare a type to be relocatable by including typedef std::true_type IsRelocatable;
in the class header.
It may be unset in a base class by overriding the typedef to false_type.
using folly::traits_detail::has_IsRelocatable = typedef typename std::conditional< has_IsRelocatable__folly_traits_impl__<TTheClass_>::template test<TTheClass_>( nullptr), std::true_type, std::false_type>::type |
using folly::traits_detail::has_IsZeroInitializable = typedef typename std::conditional< has_IsZeroInitializable__folly_traits_impl__<TTheClass_>::template test<TTheClass_>( nullptr), std::true_type, std::false_type>::type |