bungeman@google.com | f5cc5b1 | 2013-07-12 18:22:49 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2013 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | * |
| 7 | * |
Mike Klein | dc976a9 | 2020-04-30 06:45:25 -0500 | [diff] [blame] | 8 | * This header provides some std:: features early in the skstd namespace |
| 9 | * and several Skia-specific additions in the sknonstd namespace. |
bungeman@google.com | f5cc5b1 | 2013-07-12 18:22:49 +0000 | [diff] [blame] | 10 | */ |
| 11 | |
| 12 | #ifndef SkTLogic_DEFINED |
| 13 | #define SkTLogic_DEFINED |
| 14 | |
Ben Wagner | 0b9b1f1 | 2019-04-04 18:00:05 -0400 | [diff] [blame] | 15 | #include <cstddef> |
bungeman | 221524d | 2016-01-05 14:59:40 -0800 | [diff] [blame] | 16 | #include <type_traits> |
Mike Klein | dc976a9 | 2020-04-30 06:45:25 -0500 | [diff] [blame] | 17 | #include <utility> |
bungeman | 2bd0285 | 2015-08-05 12:09:57 -0700 | [diff] [blame] | 18 | |
bungeman | 761cf61 | 2015-08-28 07:09:20 -0700 | [diff] [blame] | 19 | namespace skstd { |
| 20 | |
Mike Klein | dc976a9 | 2020-04-30 06:45:25 -0500 | [diff] [blame] | 21 | // C++17, <variant> |
Herb Derby | cbd235c | 2019-07-03 18:05:12 -0400 | [diff] [blame] | 22 | struct monostate {}; |
| 23 | |
Mike Klein | dc976a9 | 2020-04-30 06:45:25 -0500 | [diff] [blame] | 24 | // C++17, <type_traits> |
Herbert Derby | fb5e64d | 2019-10-07 10:41:30 -0400 | [diff] [blame] | 25 | template<typename...> struct conjunction : std::true_type { }; |
deepak1556 | b22d7a3 | 2019-10-21 15:20:20 -0700 | [diff] [blame] | 26 | template<typename T> struct conjunction<T> : T { }; |
| 27 | template<typename T, typename... Ts> |
| 28 | struct conjunction<T, Ts...> : std::conditional<bool(T::value), conjunction<Ts...>, T>::type { }; |
Mike Klein | dc976a9 | 2020-04-30 06:45:25 -0500 | [diff] [blame] | 29 | |
Herb Derby | a80ce1a | 2020-05-26 12:58:59 -0400 | [diff] [blame] | 30 | // C++17, std::data, std::size |
| 31 | template<typename Container> |
| 32 | constexpr auto data(Container& c) -> decltype(c.data()) { return c.data(); } |
| 33 | template<typename Container> |
| 34 | constexpr auto data(const Container& c) -> decltype(c.data()) { return c.data(); } |
| 35 | template<typename Array, size_t N> |
| 36 | constexpr auto data(Array(&a)[N]) -> decltype(a) { return a; } |
| 37 | template<typename T> |
| 38 | constexpr const T* data(std::initializer_list<T> i) { return i.begin(); } |
| 39 | |
| 40 | template<typename Container> |
| 41 | constexpr auto size(Container& c) -> decltype(c.size()) { return c.size(); } |
| 42 | template<typename Array, size_t N> |
| 43 | constexpr size_t size(Array(&)[N]) { return N; } |
| 44 | template<typename T> |
| 45 | constexpr const T* size(std::initializer_list<T> i) { return i.end() - i.begin(); } |
bungeman | 761cf61 | 2015-08-28 07:09:20 -0700 | [diff] [blame] | 46 | } // namespace skstd |
bungeman@google.com | f5cc5b1 | 2013-07-12 18:22:49 +0000 | [diff] [blame] | 47 | |
bungeman | 761cf61 | 2015-08-28 07:09:20 -0700 | [diff] [blame] | 48 | // The sknonstd namespace contains things we would like to be proposed and feel std-ish. |
| 49 | namespace sknonstd { |
bungeman@google.com | f5cc5b1 | 2013-07-12 18:22:49 +0000 | [diff] [blame] | 50 | |
bungeman | 761cf61 | 2015-08-28 07:09:20 -0700 | [diff] [blame] | 51 | // The name 'copy' here is fraught with peril. In this case it means 'append', not 'overwrite'. |
| 52 | // Alternate proposed names are 'propagate', 'augment', or 'append' (and 'add', but already taken). |
| 53 | // std::experimental::propagate_const already exists for other purposes in TSv2. |
| 54 | // These also follow the <dest, source> pattern used by boost. |
| 55 | template <typename D, typename S> struct copy_const { |
Mike Klein | dc976a9 | 2020-04-30 06:45:25 -0500 | [diff] [blame] | 56 | using type = std::conditional_t<std::is_const<S>::value, std::add_const_t<D>, D>; |
commit-bot@chromium.org | 2e0c32a | 2014-04-28 16:19:45 +0000 | [diff] [blame] | 57 | }; |
bungeman | 761cf61 | 2015-08-28 07:09:20 -0700 | [diff] [blame] | 58 | template <typename D, typename S> using copy_const_t = typename copy_const<D, S>::type; |
commit-bot@chromium.org | 2e0c32a | 2014-04-28 16:19:45 +0000 | [diff] [blame] | 59 | |
bungeman | 761cf61 | 2015-08-28 07:09:20 -0700 | [diff] [blame] | 60 | template <typename D, typename S> struct copy_volatile { |
Mike Klein | dc976a9 | 2020-04-30 06:45:25 -0500 | [diff] [blame] | 61 | using type = std::conditional_t<std::is_volatile<S>::value, std::add_volatile_t<D>, D>; |
bungeman | 761cf61 | 2015-08-28 07:09:20 -0700 | [diff] [blame] | 62 | }; |
| 63 | template <typename D, typename S> using copy_volatile_t = typename copy_volatile<D, S>::type; |
| 64 | |
| 65 | template <typename D, typename S> struct copy_cv { |
| 66 | using type = copy_volatile_t<copy_const_t<D, S>, S>; |
| 67 | }; |
| 68 | template <typename D, typename S> using copy_cv_t = typename copy_cv<D, S>::type; |
| 69 | |
| 70 | // The name 'same' here means 'overwrite'. |
| 71 | // Alternate proposed names are 'replace', 'transfer', or 'qualify_from'. |
| 72 | // same_xxx<D, S> can be written as copy_xxx<remove_xxx_t<D>, S> |
Mike Klein | dc976a9 | 2020-04-30 06:45:25 -0500 | [diff] [blame] | 73 | template <typename D, typename S> using same_const = copy_const<std::remove_const_t<D>, S>; |
bungeman | 761cf61 | 2015-08-28 07:09:20 -0700 | [diff] [blame] | 74 | template <typename D, typename S> using same_const_t = typename same_const<D, S>::type; |
Mike Klein | dc976a9 | 2020-04-30 06:45:25 -0500 | [diff] [blame] | 75 | template <typename D, typename S> using same_volatile =copy_volatile<std::remove_volatile_t<D>,S>; |
bungeman | 761cf61 | 2015-08-28 07:09:20 -0700 | [diff] [blame] | 76 | template <typename D, typename S> using same_volatile_t = typename same_volatile<D, S>::type; |
Mike Klein | dc976a9 | 2020-04-30 06:45:25 -0500 | [diff] [blame] | 77 | template <typename D, typename S> using same_cv = copy_cv<std::remove_cv_t<D>, S>; |
bungeman | 761cf61 | 2015-08-28 07:09:20 -0700 | [diff] [blame] | 78 | template <typename D, typename S> using same_cv_t = typename same_cv<D, S>::type; |
| 79 | |
| 80 | } // namespace sknonstd |
commit-bot@chromium.org | 2e0c32a | 2014-04-28 16:19:45 +0000 | [diff] [blame] | 81 | |
bungeman@google.com | 4b3ef5a | 2013-07-12 18:31:59 +0000 | [diff] [blame] | 82 | #endif |