Browse Source

Trompeloeil updated to v32.

main
offa 6 years ago
parent
commit
6aead08184
1 changed files with 171 additions and 97 deletions
  1. +171
    -97
      test/trompeloeil/trompeloeil.hpp

+ 171
- 97
test/trompeloeil/trompeloeil.hpp View File

* Trompeloeil C++ mocking framework * Trompeloeil C++ mocking framework
* *
* Copyright Björn Fahller 2014-2018 * Copyright Björn Fahller 2014-2018
* Copyright (C) 2017 Andrew Paxie
* Copyright (C) 2017, 2018 Andrew Paxie
* *
* Use, modification and distribution is subject to the * Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying * Boost Software License, Version 1.0. (See accompanying


#if defined(__clang__) #if defined(__clang__)


#define TROMPELOEIL_CLANG 1
#define TROMPELOEIL_GCC 0
#define TROMPELOEIL_MSVC 0
# define TROMPELOEIL_CLANG 1
# define TROMPELOEIL_GCC 0
# define TROMPELOEIL_MSVC 0


#define TROMPELOEIL_GCC_VERSION 0
# define TROMPELOEIL_CLANG_VERSION \
(__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)


#define TROMPELOEIL_CPLUSPLUS __cplusplus
# define TROMPELOEIL_GCC_VERSION 0

# define TROMPELOEIL_CPLUSPLUS __cplusplus


#elif defined(__GNUC__) #elif defined(__GNUC__)


#define TROMPELOEIL_CLANG 0
#define TROMPELOEIL_GCC 1
#define TROMPELOEIL_MSVC 0
# define TROMPELOEIL_CLANG 0
# define TROMPELOEIL_GCC 1
# define TROMPELOEIL_MSVC 0


#define TROMPELOEIL_GCC_VERSION \
# define TROMPELOEIL_CLANG_VERSION 0
# define TROMPELOEIL_GCC_VERSION \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)


#define TROMPELOEIL_CPLUSPLUS __cplusplus
# define TROMPELOEIL_CPLUSPLUS __cplusplus


#elif defined(_MSC_VER) #elif defined(_MSC_VER)


#define TROMPELOEIL_CLANG 0
#define TROMPELOEIL_GCC 0
#define TROMPELOEIL_MSVC 1
# define TROMPELOEIL_CLANG 0
# define TROMPELOEIL_GCC 0
# define TROMPELOEIL_MSVC 1


#define TROMPELOEIL_GCC_VERSION 0
# define TROMPELOEIL_CLANG_VERSION 0
# define TROMPELOEIL_GCC_VERSION 0


/* MSVC is an amalgam of C++ versions, with no provision to
* force C++11 mode. It also has a __cplusplus macro stuck at 199711L.
* Assume the C++14 code path.
*/
#define TROMPELOEIL_CPLUSPLUS 201401L
# if defined(_MSVC_LANG)

// Compiler is at least Microsoft Visual Studio 2015 Update 3.
# define TROMPELOEIL_CPLUSPLUS _MSVC_LANG

# else /* defined(_MSVC_LANG) */

/*
* This version of Microsoft Visual C++ is released
* in a version of Microsoft Visual Studio between
* 2015 RC and less than 2015 Update 3.
*
* It is an amalgam of C++ versions, with no provision
* to specify C++11 mode.
*
* It also has a __cplusplus macro stuck at 199711L with
* no way to change it, such as /Zc:__cplusplus.
*
* Assume the C++14 code path, but don't promise that it is a
* fully conforming implementation of C++14 either.
* Hence a value of 201401L, which less than 201402L,
* the standards conforming value of __cplusplus.
*/
# define TROMPELOEIL_CPLUSPLUS 201401L

# endif /* !defined(_MSVC_LANG) */


#endif #endif


return {}; return {};
} }


template <typename ...>
struct void_t_
{
using type = void;
};

template <typename ... T>
using void_t = typename void_t_<T...>::type;

template <template <typename ...> class, typename, typename ...>
struct is_detected_{
using type = std::false_type;
};

template <template <typename ...> class D, typename ... Ts>
struct is_detected_<D, void_t<D<Ts...>>, Ts...>
{
using type = std::true_type;
};

template <template <typename ...> class D, typename ... Ts>
using is_detected = typename is_detected_<D, void, Ts...>::type;

# if (TROMPELOEIL_CPLUSPLUS == 201103L) # if (TROMPELOEIL_CPLUSPLUS == 201103L)


namespace detail namespace detail


# endif /* !(TROMPELOEIL_CPLUSPLUS == 201103L) */ # endif /* !(TROMPELOEIL_CPLUSPLUS == 201103L) */


# if TROMPELOEIL_CPLUSPLUS >= 201703L
# if TROMPELOEIL_CLANG && TROMPELOEIL_CLANG_VERSION >= 60000

// these are mostly added to work around clang++ bugs
// https://bugs.llvm.org/show_bug.cgi?id=38033
// https://bugs.llvm.org/show_bug.cgi?id=38010

template <typename T>
using move_construct_type = decltype(T(std::declval<T&&>()));

template <typename T>
using copy_construct_type = decltype(T(std::declval<const T&>()));

template <typename T>
using can_move_construct = is_detected<move_construct_type, detail::decay_t<T>>;

template <typename T>
using can_copy_construct = is_detected<copy_construct_type, detail::decay_t<T>>;

# else
template <typename T>
using can_move_construct = std::is_move_constructible<T>;

template <typename T>
using can_copy_construct = std::is_copy_constructible<T>;
# endif

template <typename F, typename ... A>
using invoke_result_type = decltype(std::declval<F&>()(std::declval<A>()...));

# else

template <typename T>
using can_move_construct = std::is_move_constructible<T>;

template <typename T>
using can_copy_construct = std::is_copy_constructible<T>;

template <typename F, typename ... A>
using invoke_result_type = decltype(std::declval<F&>()(std::declval<A>()...));

# endif

class specialized; class specialized;


namespace { namespace {
unsigned long line, unsigned long line,
std::string const &call) = 0; std::string const &call) = 0;
protected: protected:
tracer()
noexcept
: previous{set_tracer(this)} {}
tracer() = default;
tracer(tracer const&) = delete; tracer(tracer const&) = delete;
tracer& operator=(tracer const&) = delete; tracer& operator=(tracer const&) = delete;
virtual virtual
set_tracer(previous); set_tracer(previous);
} }
private: private:
tracer* previous = nullptr;
tracer* previous = set_tracer(this);
}; };


class stream_tracer : public tracer class stream_tracer : public tracer
} }
}; };


template <typename ...>
struct void_t_
struct matcher { };

struct wildcard : public matcher
{ {
using type = void;
};
// This abomination of constructor seems necessary for g++ 4.9 and 5.1
template <typename ... T>
constexpr
wildcard(
T&& ...)
noexcept
{}


template <typename ... T>
using void_t = typename void_t_<T...>::type;
#if (!TROMPELOEIL_GCC) || \
(TROMPELOEIL_GCC && TROMPELOEIL_GCC_VERSION >= 40900)


template <template <typename ...> class, typename, typename ...>
struct is_detected_{
using type = std::false_type;
};
// g++ 4.8 gives a "conversion from <T> to <U> is ambiguous" error
// if this operator is defined.
template <typename T,
typename = detail::enable_if_t<!std::is_lvalue_reference<T>::value>>
operator T&&()
const;


template <template <typename ...> class D, typename ... Ts>
struct is_detected_<D, void_t<D<Ts...>>, Ts...>
{
using type = std::true_type;
#endif

template <
typename T,
typename = detail::enable_if_t<
can_copy_construct<T>::value
|| !can_move_construct<T>::value
>
>
operator T&()
const;

template <typename T>
constexpr
bool
matches(
T const&)
const
noexcept
{
return true;
}

friend
std::ostream&
operator<<(
std::ostream& os,
wildcard const&)
noexcept
{
return os << " matching _";
}
}; };


template <template <typename ...> class D, typename ... Ts>
using is_detected = typename is_detected_<D, void, Ts...>::type;
static constexpr wildcard const _{};


struct matcher { };


template <typename T>
template <typename T>
using matcher_access = decltype(static_cast<matcher*>(std::declval<typename std::add_pointer<T>::type>())); using matcher_access = decltype(static_cast<matcher*>(std::declval<typename std::add_pointer<T>::type>()));


template <typename T> template <typename T>


template <typename T, template <typename T,
typename = decltype(std::declval<T>() == nullptr), typename = decltype(std::declval<T>() == nullptr),
typename = detail::enable_if_t<std::is_copy_constructible<T>::value>>
typename = detail::enable_if_t<can_copy_construct<T>::value>>
operator T&()const; operator T&()const;


template <typename T, typename C> template <typename T, typename C>
// g++ 4.8 gives a "conversion from <T> to <U> is ambiguous" error // g++ 4.8 gives a "conversion from <T> to <U> is ambiguous" error
// if this operator is defined. // if this operator is defined.
template <typename V, template <typename V,
typename = decltype(std::declval<Pred>()(std::declval<V&&>(), std::declval<T>()...))>
typename = detail::enable_if_t<!is_matcher<V>{}>,
typename = invoke_result_type<Pred, V&&, T...>>
operator V&&() const; operator V&&() const;


#endif #endif


template <typename V, template <typename V,
typename = decltype(std::declval<Pred>()(std::declval<V&>(), std::declval<T>()...))>
typename = detail::enable_if_t<!is_matcher<V>{}>,
typename = invoke_result_type<Pred, V&, T...>>
operator V&() const; operator V&() const;
}; };


matchers.push_back(m); matchers.push_back(m);
} }


struct wildcard : public matcher
{
// This abomination of constructor seems necessary for g++ 4.9 and 5.1
template <typename ... T>
constexpr
wildcard(
T&& ...)
noexcept
{}

#if (!TROMPELOEIL_GCC) || \
(TROMPELOEIL_GCC && TROMPELOEIL_GCC_VERSION >= 40900)

// g++ 4.8 gives a "conversion from <T> to <U> is ambiguous" error
// if this operator is defined.
template <typename T,
typename = detail::enable_if_t<!std::is_lvalue_reference<T>::value>>
operator T&&()
const;

#endif

template <typename T,
typename = detail::enable_if_t<std::is_copy_constructible<T>::value
|| !std::is_move_constructible<T>::value>>
operator T&()
const;

template <typename T>
constexpr
bool
matches(
T const&)
const
noexcept
{
return true;
}

friend
std::ostream&
operator<<(
std::ostream& os,
wildcard const&)
noexcept
{
return os << " matching _";
}
};

static constexpr wildcard const _{};

template <typename T> template <typename T>
void can_match_parameter(T&); void can_match_parameter(T&);



Loading…
Cancel
Save