mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
Reduce number of template instantiations
Combine result_type, function_arity, parameter_types into 1 trait. This reduces the amount of template classes instantiated by a factor of 3 which should improve compile times and memory consumption. Also improve tests and documentation of touched classes/traits.
This commit is contained in:
parent
0c20ca1ce9
commit
b802c51c2d
5 changed files with 157 additions and 103 deletions
|
|
@ -11,17 +11,26 @@
|
|||
|
||||
#include "function.hpp"
|
||||
#include "functor.hpp"
|
||||
#include "parameter.hpp"
|
||||
#include "signature.hpp"
|
||||
#include "signature_traits.hpp"
|
||||
#include "type_name.hpp"
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mock { namespace detail {
|
||||
/// Used in MOCK_PROTECT_SIGNATURE to unwrap the passed function signature
|
||||
/// Simplified trait to extract the argument type of a function signature with 1 argument
|
||||
template<typename T>
|
||||
using unwrap_signature_t = std::remove_pointer_t<parameter_type_t<T>>;
|
||||
struct arg_type;
|
||||
template<typename T, typename U>
|
||||
struct arg_type<T(U)>
|
||||
{
|
||||
using type = U;
|
||||
};
|
||||
/// Used in MOCK_PROTECT_SIGNATURE to unwrap the passed function signature
|
||||
/// T is something like `void(std::map<int, float>)`
|
||||
template<typename T>
|
||||
using unwrap_signature_t = std::remove_pointer_t<typename arg_type<T>::type>;
|
||||
}} // namespace mock::detail
|
||||
|
||||
#define MOCK_HELPER(t) t##_mock(mock::detail::root, BOOST_PP_STRINGIZE(t))
|
||||
|
|
@ -47,8 +56,8 @@ namespace mock { namespace detail {
|
|||
|
||||
#define MOCK_FORWARD_PARAM(z, n, d) BOOST_PP_COMMA_IF(n) d, n >> (p##n)
|
||||
#define MOCK_FORWARD_PARAMS(n, S) BOOST_PP_REPEAT(n, MOCK_FORWARD_PARAM, std::forward < MOCK_PARAM(S))
|
||||
#define MOCK_METHOD_AUX(M, n, S, t, c) \
|
||||
static_assert(n == mock::detail::function_arity<S>::value, "Arity mismatch"); \
|
||||
#define MOCK_METHOD_AUX(M, n, S, t, c) \
|
||||
static_assert(n == mock::detail::function_arity_t<S>::value, "Arity mismatch"); \
|
||||
MOCK_DECL(M, n, S, c) { return MOCK_ANONYMOUS_HELPER(t)(MOCK_FORWARD_PARAMS(n, S)); }
|
||||
|
||||
#define MOCK_METHOD_EXT(M, n, S, t) \
|
||||
|
|
@ -73,13 +82,10 @@ namespace mock { namespace detail {
|
|||
T(MOCK_DECL_PARAMS(n, void A)) { MOCK_HELPER(t)(MOCK_FORWARD_PARAMS(n, void A)); } \
|
||||
MOCK_FUNCTION_HELPER(void A, t, static)
|
||||
|
||||
#define MOCK_FUNCTION_AUX(F, n, S, t, s) \
|
||||
MOCK_FUNCTION_HELPER(S, t, s) \
|
||||
s MOCK_DECL(F, n, S, ) \
|
||||
{ \
|
||||
static_assert(n == mock::detail::function_arity<S>::value, "Arity mismatch"); \
|
||||
return MOCK_HELPER(t)(MOCK_FORWARD_PARAMS(n, S)); \
|
||||
}
|
||||
#define MOCK_FUNCTION_AUX(F, n, S, t, s) \
|
||||
MOCK_FUNCTION_HELPER(S, t, s) \
|
||||
static_assert(n == mock::detail::function_arity_t<S>::value, "Arity mismatch"); \
|
||||
s MOCK_DECL(F, n, S, ) { return MOCK_HELPER(t)(MOCK_FORWARD_PARAMS(n, S)); }
|
||||
|
||||
#define MOCK_VARIADIC_ELEM_0(e0, ...) e0
|
||||
#define MOCK_VARIADIC_ELEM_1(e0, e1, ...) e1
|
||||
|
|
|
|||
|
|
@ -1,82 +0,0 @@
|
|||
// http://turtle.sourceforge.net
|
||||
//
|
||||
// Copyright Mathieu Champlon 2012
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef MOCK_PARAMETER_HPP_INCLUDED
|
||||
#define MOCK_PARAMETER_HPP_INCLUDED
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
namespace mock { namespace detail {
|
||||
template<class...>
|
||||
struct tuple;
|
||||
|
||||
template<std::size_t I, class T>
|
||||
struct tuple_element;
|
||||
|
||||
template<std::size_t I, class H, class... T>
|
||||
struct tuple_element<I, tuple<H, T...>> : tuple_element<I - 1, tuple<T...>>
|
||||
{};
|
||||
|
||||
template<class H, class... T>
|
||||
struct tuple_element<0, tuple<H, T...>>
|
||||
{
|
||||
using type = H;
|
||||
};
|
||||
|
||||
template<typename Signature>
|
||||
struct result_type;
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct result_type<R(Args...)>
|
||||
{
|
||||
using type = R;
|
||||
};
|
||||
template<typename Signature>
|
||||
using result_type_t = typename result_type<Signature>::type;
|
||||
|
||||
template<typename Signature>
|
||||
struct function_arity;
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct function_arity<R(Args...)>
|
||||
{
|
||||
static constexpr size_t value = sizeof...(Args);
|
||||
};
|
||||
|
||||
template<typename Signature>
|
||||
struct parameter_types;
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct parameter_types<R(Args...)>
|
||||
{
|
||||
using type = tuple<Args...>;
|
||||
};
|
||||
|
||||
template<typename Signature, std::size_t n>
|
||||
struct parameter
|
||||
{
|
||||
// This assertion is usually triggered when the arity passed to e.g. MOCK_METHOD exceeds the number of
|
||||
// parameters of the mocked function or the passed function signature
|
||||
static_assert(n < function_arity<Signature>::value, "Parameter index exceeds the number of parameters");
|
||||
using type = typename tuple_element<n, typename parameter_types<Signature>::type>::type;
|
||||
};
|
||||
template<typename T, std::size_t n>
|
||||
using parameter_t = typename parameter<T, n>::type;
|
||||
|
||||
template<typename T>
|
||||
struct parameter_type;
|
||||
template<typename T, typename U>
|
||||
struct parameter_type<T(U)>
|
||||
{
|
||||
using type = U;
|
||||
};
|
||||
template<typename T>
|
||||
using parameter_type_t = typename parameter_type<T>::type;
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_PARAMETER_HPP_INCLUDED
|
||||
|
|
@ -54,19 +54,21 @@ namespace mock { namespace detail {
|
|||
struct signature<Sig(C::*)> : signature<typename strip_function_qualifiers<Sig>::type>
|
||||
{};
|
||||
|
||||
/// Return the (non-member) function signature out of (any) signature
|
||||
template<typename M>
|
||||
using signature_t = typename signature<std::remove_cv_t<std::remove_reference_t<M>>>::type;
|
||||
using signature_t = typename signature<M>::type;
|
||||
|
||||
/// CRTP class to define the base_type typedef
|
||||
template<typename T>
|
||||
struct base
|
||||
{
|
||||
typedef T base_type;
|
||||
using base_type = T;
|
||||
};
|
||||
|
||||
// if an error is generated by the line below it means the method is ambiguous:
|
||||
// specify its signature to disambiguate
|
||||
// If an error is generated by the line below it means the method is ambiguous.
|
||||
// Specify its signature to disambiguate
|
||||
template<typename T>
|
||||
T& ambiguous_method_requires_to_specify_signature(const T&);
|
||||
T ambiguous_method_requires_to_specify_signature(const T&);
|
||||
}} // namespace mock::detail
|
||||
|
||||
#define MOCK_SIGNATURE(M) \
|
||||
|
|
|
|||
62
include/turtle/detail/signature_traits.hpp
Normal file
62
include/turtle/detail/signature_traits.hpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
// http://turtle.sourceforge.net
|
||||
//
|
||||
// Copyright Mathieu Champlon 2012
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef MOCK_PARAMETER_HPP_INCLUDED
|
||||
#define MOCK_PARAMETER_HPP_INCLUDED
|
||||
|
||||
#include "../config.hpp"
|
||||
#include <cstddef>
|
||||
|
||||
namespace mock { namespace detail {
|
||||
/// Helper class to store a tuple/list of types
|
||||
template<class...>
|
||||
struct tuple;
|
||||
|
||||
/// Get the type at the given index in the tuple
|
||||
template<std::size_t index, class Tuple>
|
||||
struct tuple_element;
|
||||
|
||||
template<std::size_t I, class H, class... T>
|
||||
struct tuple_element<I, tuple<H, T...>> : tuple_element<I - 1, tuple<T...>>
|
||||
{};
|
||||
|
||||
template<class H, class... T>
|
||||
struct tuple_element<0, tuple<H, T...>>
|
||||
{
|
||||
using type = H;
|
||||
};
|
||||
|
||||
/// Provides information about a given function signature
|
||||
/// Member types: return_type, args
|
||||
/// Member constant: arity
|
||||
template<typename Signature>
|
||||
struct signature_traits;
|
||||
|
||||
template<typename R, typename... Args>
|
||||
struct signature_traits<R(Args...)>
|
||||
{
|
||||
using return_type = R;
|
||||
static constexpr std::size_t arity = sizeof...(Args);
|
||||
using args = tuple<Args...>;
|
||||
};
|
||||
|
||||
/// Return the result type of the function signature
|
||||
template<typename Signature>
|
||||
using result_type_t = typename signature_traits<Signature>::return_type;
|
||||
|
||||
/// Return the arity of the function signature
|
||||
template<typename Signature>
|
||||
using function_arity_t = std::integral_constant<std::size_t, signature_traits<Signature>::arity>;
|
||||
|
||||
/// Return the type at the given index of the function signature
|
||||
template<typename Signature, std::size_t idx>
|
||||
using parameter_t = typename tuple_element<idx, typename signature_traits<Signature>::args>::type;
|
||||
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_PARAMETER_HPP_INCLUDED
|
||||
Loading…
Add table
Add a link
Reference in a new issue