mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-05 17:52:29 +00:00
111 lines
3.2 KiB
C++
111 lines
3.2 KiB
C++
#ifndef LIBTORRENT_HELPERS_MOCK_COMPARE_H
|
|
#define LIBTORRENT_HELPERS_MOCK_COMPARE_H
|
|
|
|
#include <algorithm>
|
|
#include <map>
|
|
#include <type_traits>
|
|
#include <torrent/net/socket_address.h>
|
|
#include <torrent/system/event.h>
|
|
|
|
// Compare arguments to mock functions with what is expected. The lhs
|
|
// are the expected arguments, rhs are the ones called with.
|
|
|
|
template <typename Arg>
|
|
inline bool mock_compare_arg(Arg lhs, Arg rhs) { return lhs == rhs; }
|
|
|
|
template <int I, typename A, typename... Args>
|
|
std::enable_if_t<I == 1, int>
|
|
mock_compare_tuple(const std::tuple<A, Args...>& lhs, const std::tuple<Args...>& rhs) {
|
|
return mock_compare_arg(std::get<I>(lhs), std::get<I - 1>(rhs)) ? 0 : 1;
|
|
}
|
|
|
|
template <int I, typename A, typename... Args>
|
|
std::enable_if_t<1 < I, int>
|
|
mock_compare_tuple(const std::tuple<A, Args...>& lhs, const std::tuple<Args...>& rhs) {
|
|
auto res = mock_compare_tuple<I - 1>(lhs, rhs);
|
|
|
|
if (res != 0)
|
|
return res;
|
|
|
|
return mock_compare_arg(std::get<I>(lhs), std::get<I - 1>(rhs)) ? 0 : I;
|
|
}
|
|
|
|
//template <typename T, typename std::enable_if<!std::is_const<T>::value, int>::type = 0>
|
|
template <typename T>
|
|
struct mock_compare_map {
|
|
typedef std::map<const T*, const T*> values_type;
|
|
|
|
static T* begin_pointer() { return reinterpret_cast<T*>(0x1000); }
|
|
static T* end_pointer() { return reinterpret_cast<T*>(0x2000); }
|
|
|
|
static bool is_key(const T* k) {
|
|
return k >= begin_pointer() && k < end_pointer();
|
|
}
|
|
|
|
static bool has_key(const T* k) {
|
|
return values.find(k) != values.end();
|
|
}
|
|
|
|
static bool has_value(const T* v) {
|
|
return std::find_if(values.begin(), values.end(), [v](typename values_type::value_type& kv) { return v == kv.second; }) != values.end();
|
|
}
|
|
|
|
static const T* get(const T* k) {
|
|
auto itr = values.find(k);
|
|
CPPUNIT_ASSERT_MESSAGE("mock_compare_map get failed, not inserted", itr != values.end());
|
|
return itr->second;
|
|
}
|
|
|
|
static values_type values;
|
|
};
|
|
|
|
template<typename T>
|
|
typename mock_compare_map<T>::values_type mock_compare_map<T>::values;
|
|
|
|
template<typename T>
|
|
void mock_compare_add(T* v) {
|
|
mock_compare_map<T>::add_value(v);
|
|
}
|
|
|
|
//
|
|
// Specialize:
|
|
//
|
|
|
|
constexpr int mock_compare_gt_two_int = -0xFD30;
|
|
|
|
template <>
|
|
inline bool mock_compare_arg<int>(int lhs, int rhs) {
|
|
if (lhs == mock_compare_gt_two_int)
|
|
return rhs > 2;
|
|
if (rhs == mock_compare_gt_two_int)
|
|
return lhs > 2;
|
|
|
|
return lhs == rhs;
|
|
}
|
|
|
|
template <>
|
|
inline bool mock_compare_arg<sockaddr*>(sockaddr* lhs, sockaddr* rhs) {
|
|
return lhs != nullptr && rhs != nullptr && torrent::sa_equal(lhs, rhs);
|
|
}
|
|
|
|
template <>
|
|
inline bool mock_compare_arg<const sockaddr*>(const sockaddr* lhs, const sockaddr* rhs) {
|
|
return lhs != nullptr && rhs != nullptr && torrent::sa_equal(lhs, rhs);
|
|
}
|
|
|
|
template <>
|
|
inline bool mock_compare_arg<torrent::system::Event*>(torrent::system::Event* lhs, torrent::system::Event* rhs) {
|
|
if (mock_compare_map<torrent::system::Event>::is_key(lhs)) {
|
|
if (!mock_compare_map<torrent::system::Event>::has_value(rhs)) {
|
|
mock_compare_map<torrent::system::Event>::values[lhs] = rhs;
|
|
return true;
|
|
}
|
|
|
|
return mock_compare_map<torrent::system::Event>::has_key(lhs) && mock_compare_map<torrent::system::Event>::get(lhs) == rhs;
|
|
}
|
|
|
|
return lhs == rhs;
|
|
}
|
|
|
|
#endif
|