1 // Copyright 2022 Google LLC 2 // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 3 4 #ifndef SkTypeTraits_DEFINED 5 #define SkTypeTraits_DEFINED 6 7 #include <memory> 8 #include <type_traits> 9 10 // Trait for identifying types which are relocatable via memcpy, for container optimizations. 11 template<typename, typename = void> 12 struct sk_has_trivially_relocatable_member : std::false_type {}; 13 14 // Types can declare themselves trivially relocatable with a public 15 // using sk_is_trivially_relocatable = std::true_type; 16 template<typename T> 17 struct sk_has_trivially_relocatable_member<T, std::void_t<typename T::sk_is_trivially_relocatable>> 18 : T::sk_is_trivially_relocatable {}; 19 20 // By default, all trivially copyable types are trivially relocatable. 21 template <typename T> 22 struct sk_is_trivially_relocatable 23 : std::disjunction<std::is_trivially_copyable<T>, sk_has_trivially_relocatable_member<T>>{}; 24 25 // Here be some dragons: while technically not guaranteed, we count on all sane unique_ptr 26 // implementations to be trivially relocatable. 27 template <typename T> 28 struct sk_is_trivially_relocatable<std::unique_ptr<T>> : std::true_type {}; 29 30 template <typename T> 31 inline constexpr bool sk_is_trivially_relocatable_v = sk_is_trivially_relocatable<T>::value; 32 33 #endif // SkTypeTraits_DEFINED 34