/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_TRAITS_H #define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_TRAITS_H #include #include #include namespace OHOS { namespace Traits { template struct index_of : std::integral_constant {}; template inline constexpr size_t index_of_v = index_of::value; template struct index_of : std::integral_constant ? 0 : index_of_v + 1> {}; // If there is one in the ...Types, that is equal to T. same_index_of_v is the index. // If there is no one in the ...Types, that is equal to T. same_index_of_v is sizeof ...(Types) template inline constexpr size_t same_index_of_v = index_of::value; // There is one in the ...Types, that is equal to T. If not, the same_in_v will be false. template inline constexpr bool same_in_v = (same_index_of_v < sizeof...(Types)); template struct convertible_index_of : std::integral_constant {}; // If there is one in the ...Types that can convert to T implicitly, convertible_index_v is the index. // If there is no one in the ...Types that can convert to T implicitly, convertible_index_v is sizeof ...(Types) template inline constexpr size_t convertible_index_of_v = convertible_index_of::value; template struct convertible_index_of : std::integral_constant ? 0 : convertible_index_of_v + 1> {}; // There is one in the ...Types, that can convert to T implicitly. If not, the convertible_in_v will be false. template inline constexpr bool convertible_in_v = (convertible_index_of_v < sizeof...(Types)); template struct variant_size_of { static constexpr size_t value = sizeof...(Types); }; template struct variant_index_of { static constexpr size_t value = same_index_of_v; }; template variant_size_of variant_size_test(const std::variant &); template variant_index_of variant_index_test(const T &, const std::variant &); // variant_index_of_v is the count of the variant V's types. template inline constexpr size_t variant_size_of_v = decltype(variant_size_test(std::declval()))::value; // If T is one type of the variant V, variant_index_of_v is the index. If not, variant_index_of_v is the size. template inline constexpr size_t variant_index_of_v = decltype(variant_index_test(std::declval(), std::declval()))::value; /* * Extend the template std::get_if(variant<_Types...>*) function to support these: * 1. When the _Tp is a type in the ..._Types, the get_if is equal to the std::get_if. * 2. When the _Tp is not a type in the ..._Types but someone in the ...Types can convert to _Tp implicitly, * the get_if will return it. * 3. When the _Tp is not a type in the ..._Types and can't convert, the get_if will return nullptr. * */ template std::enable_if_t, T *> get_if(std::variant *input) { return std::get_if(input); } template std::enable_if_t, const T *> get_if(const std::variant *input) { return std::get_if(input); } template ? convertible_index_of_v : 0> constexpr std::enable_if_t && convertible_in_v, std::add_pointer_t>>> get_if(std::variant *input) { return std::get_if(input); } template ? convertible_index_of_v : 0> constexpr std::enable_if_t && convertible_in_v, std::add_pointer_t>>> get_if(const std::variant *input) { return std::get_if(input); } template std::enable_if_t && !convertible_in_v, T *> get_if(std::variant *input) { (void)input; return nullptr; } template std::enable_if_t && !convertible_in_v, const T *> get_if( const std::variant *input) { (void)input; return nullptr; } } // namespace Traits } // namespace OHOS #endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_TRAITS_H