Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021 Project CHIP Authors
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : /**
19 : * @file
20 : * This file defines and implements a number of miscellaneous
21 : * templates for simplify code with handling types.
22 : *
23 : */
24 :
25 : #pragma once
26 :
27 : #include <type_traits>
28 :
29 : #if __has_include(<utility>) // For C++23 and later, include <utility> if available
30 : #include <utility> // Contains std::to_underlying
31 : #endif
32 :
33 : namespace chip {
34 :
35 : #if __cplusplus >= 202300L
36 :
37 : using to_underlying = std::to_underlying;
38 :
39 : #else
40 : /**
41 : * @brief Implemented std::to_underlying introduced in C++23.
42 : */
43 : template <class T>
44 713734 : constexpr std::underlying_type_t<T> to_underlying(T e)
45 : {
46 : static_assert(std::is_enum<T>::value, "to_underlying called to non-enum values.");
47 713734 : return static_cast<std::underlying_type_t<T>>(e);
48 : }
49 : #endif
50 :
51 : /**
52 : * @brief This template is not designed to be used directly. A common pattern to check the presence of a member of a class is:
53 : *
54 : * \cond
55 : * template <typename T>
56 : * class IsMagic
57 : * {
58 : * private:
59 : * template <typename Tp>
60 : * static auto TestHasMagic(int) -> TemplatedTrueType<decltype(&Tp::Magic)>;
61 : *
62 : * template <typename Tp>
63 : * static auto TestHasMagic(long) -> std::false_type;
64 : *
65 : * public:
66 : * static constexpr bool value = decltype(TestHasMagic<std::decay_t<T>>(0))::value;
67 : * };
68 : * \endcond
69 : *
70 : * The compiler will try to match TestHasMagicFunction(int) first, if MagicFunction is a member function of T, the match succeed
71 : * and HasMagicFunction is an alias of std::true_type. If MagicFunction is not a member function of T, the match of
72 : * TestHasMagicFunction(int) will result in compile error, due to SFINAE, compiler will try the next candicate, which is
73 : * TestHasMagicFunction(long), it will always success for all types, and HasMagicFunction becomes an alias of std::false_type.
74 : */
75 : template <typename T>
76 : using TemplatedTrueType = std::true_type;
77 :
78 : } // namespace chip
|