/** * Copyright © 2018 Intel Corporation * * 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. */ #pragma once #include #include #include #include #include #include #include #include #include namespace ipmi { // forward declare Context and Request for NonIpmiArgsCount struct Context; namespace message { struct Request; } namespace utility { /** * @brief a utility template to extract the args after N from a tuple * * Given a tuple of type , provide type = tuple */ template struct StripFirstArgs; template struct StripFirstArgs> : StripFirstArgs> { }; template struct StripFirstArgs<0, std::tuple> { using type = std::tuple; }; template struct StripFirstArgs> { using type = std::tuple<>; }; /** * @brief a utility template to extract the remaining args from a tuple * * Given a tuple of type , provide type = tuple */ template using StripFirstArg = StripFirstArgs<1, T>; /** * @brief a utility template to find the number of non-special arguments * * Given a tuple, count the args after the first special args */ template struct NonIpmiArgsCount; template <> struct NonIpmiArgsCount> { constexpr static std::size_t size() { return 0; } }; template struct NonIpmiArgsCount> { constexpr static std::size_t size() { if constexpr (std::is_same< FirstArg, std::shared_ptr>::value || std::is_same>::value || std::is_same::value) { return 1 + NonIpmiArgsCount>::size(); } else { return NonIpmiArgsCount>::size(); } } }; /** * @brief a utility template to find the type of the first arg * * Given a tuple, provide the type of the first element */ template struct GetFirstArg { using type = void; }; template struct GetFirstArg> { using type = FirstArg; }; /** * @brief a utility template to remove const and reference from types * * Given a tuple, provide the type of the first element */ template struct DecayTuple; template struct DecayTuple> { using type = std::tuple::type...>; }; /** @brief Convert T[N] to T* if is_same * * @tparam Tbase - The base type expected. * @tparam T - The type to convert. */ template using ArrayToPtr_t = typename std::conditional_t< std::is_array::value, std::conditional_t>::value, std::add_pointer_t>, T>, T>; /** @brief Downcast type submembers. * * This allows std::tuple and std::pair members to be downcast to their * non-const, nonref versions of themselves to limit duplication in template * specializations * * 1. Remove references. * 2. Remove 'const' and 'volatile'. * 3. Convert 'char[N]' to 'char*'. */ template struct DowncastMembers { using type = T; }; template struct DowncastMembers> { using type = std::pair>>...>; }; template struct DowncastMembers> { using type = std::tuple>>...>; }; template using DowncastMembers_t = typename DowncastMembers::type; /** @brief Convert some C++ types to others for 'TypeId' conversion purposes. * * Similar C++ types have the same dbus type-id, so 'downcast' those to limit * duplication in TypeId template specializations. * * 1. Remove references. * 2. Remove 'const' and 'volatile'. * 3. Convert 'char[N]' to 'char*'. */ template struct TypeIdDowncast { using type = utility::ArrayToPtr_t< char, DowncastMembers_t>>>; }; template using TypeIdDowncast_t = typename TypeIdDowncast::type; /** @brief Detect if a type is a tuple * */ template struct is_tuple : std::false_type { }; template struct is_tuple> : std::true_type { }; } // namespace utility } // namespace ipmi