diff options
author | Vernon Mauery <vernon.mauery@linux.intel.com> | 2018-10-08 12:05:16 -0700 |
---|---|---|
committer | Vernon Mauery <vernon.mauery@linux.intel.com> | 2019-02-25 14:27:21 -0800 |
commit | e7329c71f3d22e010c38a7f738e81ab78330038e (patch) | |
tree | 8cb355cbde96d7a341f1c707c7f0e8c334f88e58 /include/ipmid/utility.hpp | |
parent | 1bb0c7fc55b21bb40b7afb567f2f938f15411ca1 (diff) | |
download | phosphor-host-ipmid-e7329c71f3d22e010c38a7f738e81ab78330038e.tar.gz phosphor-host-ipmid-e7329c71f3d22e010c38a7f738e81ab78330038e.zip |
ipmid: Compiler-generated unpacking and packing of messages
handler.hpp has the templated wrapping bits for ipmi command handler
callbacks implemented.
message.hpp has the serialization/deserialization of the ipmi data
stream into packed tuples for functions.
message/pack.hpp and message/unpack.hpp contain the actual serialization
and deserialization of types.
Change-Id: If997f8768c8488ab6ac022526a5ef9a1bce57fcb
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
Diffstat (limited to 'include/ipmid/utility.hpp')
-rw-r--r-- | include/ipmid/utility.hpp | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/include/ipmid/utility.hpp b/include/ipmid/utility.hpp new file mode 100644 index 0000000..3a36434 --- /dev/null +++ b/include/ipmid/utility.hpp @@ -0,0 +1,210 @@ +/** + * 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 <boost/asio/spawn.hpp> +#include <boost/callable_traits.hpp> +#include <cstdint> +#include <map> +#include <memory> +#include <string> +#include <tuple> +#include <type_traits> +#include <vector> + +namespace ipmi +{ + +struct Context; + +namespace utility +{ + +/** + * @brief a utility template to extract the args after N from a tuple + * + * Given a tuple of type <T1, ...TN, TN+1, ...>, provide type = tuple<TN+1,...> + */ +template <std::size_t N, typename FirstArg, typename... Rest> +struct StripFirstArgs; + +template <std::size_t N, typename FirstArg, typename... Rest> +struct StripFirstArgs<N, std::tuple<FirstArg, Rest...>> + : StripFirstArgs<N - 1, std::tuple<Rest...>> +{ +}; + +template <typename FirstArg, typename... Rest> +struct StripFirstArgs<0, std::tuple<FirstArg, Rest...>> +{ + using type = std::tuple<FirstArg, Rest...>; +}; +template <std::size_t N> +struct StripFirstArgs<N, std::tuple<>> +{ + using type = std::tuple<>; +}; + +/** + * @brief a utility template to extract the remaining args from a tuple + * + * Given a tuple of type <T1, T2,...>, provide type = tuple<T2,...> + */ +template <typename T> +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 <typename FirstArg, typename... Rest> +struct NonIpmiArgsCount; + +template <> +struct NonIpmiArgsCount<std::tuple<>> +{ + constexpr static std::size_t size() + { + return 0; + } +}; +template <typename FirstArg, typename... OtherArgs> +struct NonIpmiArgsCount<std::tuple<FirstArg, OtherArgs...>> +{ + constexpr static std::size_t size() + { + if constexpr (std::is_same<FirstArg, ipmi::Context>::value || + std::is_same<FirstArg, boost::asio::yield_context>::value) + { + return 1 + NonIpmiArgsCount<std::tuple<OtherArgs...>>::size(); + } + else + { + return NonIpmiArgsCount<std::tuple<OtherArgs...>>::size(); + } + } +}; + +/** + * @brief a utility template to find the type of the first arg + * + * Given a tuple, provide the type of the first element + */ +template <typename T> +struct GetFirstArg +{ + using type = void; +}; + +template <typename FirstArg, typename... Rest> +struct GetFirstArg<std::tuple<FirstArg, Rest...>> +{ + 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 <typename... Args> +struct DecayTuple; + +template <typename... Args> +struct DecayTuple<std::tuple<Args...>> +{ + using type = std::tuple<typename std::decay<Args>::type...>; +}; + +/** @brief Convert T[N] to T* if is_same<Tbase,T> + * + * @tparam Tbase - The base type expected. + * @tparam T - The type to convert. + */ +template <typename Tbase, typename T> +using ArrayToPtr_t = typename std::conditional_t< + std::is_array<T>::value, + std::conditional_t<std::is_same<Tbase, std::remove_extent_t<T>>::value, + std::add_pointer_t<std::remove_extent_t<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 <typename T> +struct DowncastMembers +{ + using type = T; +}; +template <typename... Args> +struct DowncastMembers<std::pair<Args...>> +{ + using type = std::pair<utility::ArrayToPtr_t< + char, std::remove_cv_t<std::remove_reference_t<Args>>>...>; +}; + +template <typename... Args> +struct DowncastMembers<std::tuple<Args...>> +{ + using type = std::tuple<utility::ArrayToPtr_t< + char, std::remove_cv_t<std::remove_reference_t<Args>>>...>; +}; + +template <typename T> +using DowncastMembers_t = typename DowncastMembers<T>::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 <typename T> +struct TypeIdDowncast +{ + using type = utility::ArrayToPtr_t< + char, DowncastMembers_t<std::remove_cv_t<std::remove_reference_t<T>>>>; +}; + +template <typename T> +using TypeIdDowncast_t = typename TypeIdDowncast<T>::type; + +/** @brief Detect if a type is a tuple + * + */ +template <typename> +struct is_tuple : std::false_type +{ +}; + +template <typename... T> +struct is_tuple<std::tuple<T...>> : std::true_type +{ +}; + +} // namespace utility + +} // namespace ipmi |