• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef CPP_ABCKIT_BASE_CONCEPTS_H
17 #define CPP_ABCKIT_BASE_CONCEPTS_H
18 
19 #include <type_traits>
20 
21 namespace abckit::traits {
22 
23 #ifdef _MSC_VER
24 #define ABCKIT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
25 #else
26 #define ABCKIT_NO_UNIQUE_ADDRESS [[no_unique_address]]
27 #endif  // _MSC_VER
28 
29 /**
30  * @brief Lightweight checker that ensures core<->target API conversion validity
31  * It is designed to be empty class type.
32  * In case of inheritance the empty base optimization will be applied
33  * (see https://en.cppreference.com/w/cpp/language/ebo for the details)
34  * In case of non-static member, it should be combined with ABCKIT_NO_UNIQUE_ADDRESS attribute
35  * @tparam TargetT - View class for a target specialized C API (not core)
36  */
37 template <class TargetT>
38 class TargetCheckCast {
39 private:
40     /**
41      * @brief Provides compile-time static contract checks
42      */
43     static void ConceptChecks();
44 
45     /**
46      * @brief Checks that T::TargetCast() method is defined using
47      * pre-C++20 concept idiom with SFINAE and decltype to check type expression valideness
48      * @tparam T - type that is inspected againts the contract
49      * @note A general case to be matched (to false) if more specialized case fail
50      */
51     template <typename T, typename = void>
52     struct HasTargetCastMethod : public std::false_type {
53     };
54 
55     /**
56      * @brief Checks that T::TargetCast() method is defined using
57      * pre-C++20 concept idiom with SFINAE and decltype to check type expression valideness
58      * @tparam T - type that is inspected againts the contract
59      * @note A more specialized case to be matched (to true) if the type expression below is valid for type T
60      */
61     template <typename T>
62     struct HasTargetCastMethod<T, std::void_t<decltype(std::declval<const T &>().TargetCast())>>
63         : public std::true_type {
64     };
65 
66     template <typename T, typename = void>
67     struct HasCoreViewT : public std::false_type {
68     };
69 
70     template <typename T>
71     struct HasCoreViewT<T, std::void_t<typename T::CoreViewT>> : public std::true_type {
72     };
73 
74 public:
75     /**
76      * @brief Checking constructor, performs runtime check for target cast validity
77      * @note requires access to TargetT::TargetCast, provide such visibility at TargetT class
78      */
79     explicit TargetCheckCast()
80     {
81         [[maybe_unused]] auto ret = static_cast<const TargetT *>(this)->TargetCast();
82     };
83 
84     /**
85      * @brief Checking constructor, performs runtime check for target cast validity
86      * use like `explicit TagetT::TargetT(const CoreT& core) : CoreT(core), typeChecker(this) { }`
87      * @param that - Target APP view pointer that will be target checked
88      * @note requires access to TargetT::TargetCast, provide such visibility at TargetT class
89      */
90     explicit TargetCheckCast(const TargetT *that)
91     {
92         [[maybe_unused]] auto ret = that->TargetCast();
93     };
94 
95     /**
96      * @brief No restrictions on destuctor
97      */
98     ~TargetCheckCast() = default;
99 
100     /**
101      * @brief No restrictions on copy constructor
102      */
103     TargetCheckCast(const TargetCheckCast &) = default;
104 
105     /**
106      * @brief No restrictions on move constructor
107      */
108     TargetCheckCast(TargetCheckCast &&) = default;
109 
110     /**
111      * @brief No restrictions on copy assignment constructor
112      * @return this `TargetCheckCast` -- default chaining idiom
113      */
114     TargetCheckCast &operator=(const TargetCheckCast &) = default;
115 
116     /**
117      * @brief No restrictions on move assignment constructor
118      * @return this `TargetCheckCast` -- default chaining idiom
119      */
120     TargetCheckCast &operator=(TargetCheckCast &&) = default;
121 };
122 
123 /**
124  * @brief Checking constructor, performs runtime check for target cast validity
125  * @tparam TargetT - View class for a target specialized C API
126  * @note requires access to TargetT::TargetCast, provide such visibility at TargetT class
127  */
128 template <class TargetT>
129 inline void TargetCheckCast<TargetT>::ConceptChecks()
130 {
131     static_assert(sizeof(TargetCheckCast) == 0, "Concept check should not affect class layout");
132     static_assert(HasTargetCastMethod<TargetT>::value, "Define `TargetT::TargetCast() const` returning C API pointer");
133     static_assert(HasCoreViewT<TargetT>::value, "Define `TargetT::CoreViewT` type referring base class");
134     static_assert(sizeof(TargetT) == sizeof(typename TargetT::CoreViewT),
135                   "Target View should have the same layout as Core");
136 }
137 
138 }  // namespace abckit::traits
139 
140 #endif  // CPP_ABCKIT_BASE_CONCEPTS_H
141