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

@@ -2,7 +2,7 @@
* Trompeloeil C++ mocking framework
*
* 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
* Boost Software License, Version 1.0. (See accompanying
@@ -47,38 +47,64 @@

#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__)

#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__)

#define TROMPELOEIL_CPLUSPLUS __cplusplus
# define TROMPELOEIL_CPLUSPLUS __cplusplus

#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

@@ -291,6 +317,29 @@ namespace trompeloeil
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)

namespace detail
@@ -558,6 +607,49 @@ namespace trompeloeil

# 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;

namespace {
@@ -709,9 +801,7 @@ namespace trompeloeil
unsigned long line,
std::string const &call) = 0;
protected:
tracer()
noexcept
: previous{set_tracer(this)} {}
tracer() = default;
tracer(tracer const&) = delete;
tracer& operator=(tracer const&) = delete;
virtual
@@ -720,7 +810,7 @@ namespace trompeloeil
set_tracer(previous);
}
private:
tracer* previous = nullptr;
tracer* previous = set_tracer(this);
};

class stream_tracer : public tracer
@@ -826,32 +916,66 @@ namespace trompeloeil
}
};

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>()));

template <typename T>
@@ -871,7 +995,7 @@ namespace trompeloeil

template <typename T,
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;

template <typename T, typename C>
@@ -888,13 +1012,15 @@ namespace trompeloeil
// g++ 4.8 gives a "conversion from <T> to <U> is ambiguous" error
// if this operator is defined.
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;

#endif

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;
};

@@ -1632,58 +1758,6 @@ namespace trompeloeil
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>
void can_match_parameter(T&);


Loading…
Cancel
Save