mirror of
https://github.com/red0124/ssp.git
synced 2025-01-23 04:55:20 +01:00
55d0a4e598
* Bugfix/odr violations (#47) * Make common non-member functions inline, remove unreachable line from get_line_buffer * [skip ci] Fix namespace comments * Resolve clang-tidy warnings (#48) * Resolve clang-tidy warnings, update single_header_generator.py * Update single header test, resolve additional clang-tidy warnings * Add header and raw_header methods, update header usage methods error handling, write new and update existing unit tests * Update parser error messages, fix parser tests * Add [[nodiscard]] where fitting, update unit tests (#49) * Add const where fitting, make splitter class members private, add #pragma once to ssp.hpp * Modify header parsing for empty headers, update old and add new tests for header parsing * Enable the parser to accept a header with one empty field, update unit tests * Fix test CMakeLists.txt typo
80 lines
2.7 KiB
C++
80 lines
2.7 KiB
C++
#pragma once
|
|
|
|
#include <cstdlib>
|
|
#include <functional>
|
|
|
|
namespace ss {
|
|
|
|
////////////////
|
|
// function traits
|
|
////////////////
|
|
|
|
template <size_t N, typename T, typename... Ts>
|
|
struct decayed_arg_n {
|
|
static_assert(N - 1 != sizeof...(Ts), "index out of range");
|
|
using type = typename decayed_arg_n<N - 1, Ts...>::type;
|
|
};
|
|
|
|
template <typename T, typename... Ts>
|
|
struct decayed_arg_n<0, T, Ts...> {
|
|
using type = std::decay_t<T>;
|
|
};
|
|
|
|
template <typename T>
|
|
struct function_traits;
|
|
|
|
template <typename R, typename C, typename Arg>
|
|
struct function_traits<std::function<R(C&, const Arg&) const>> {
|
|
using arg_type = Arg;
|
|
};
|
|
|
|
template <typename R, typename... Ts>
|
|
struct function_traits<R(Ts...)> {
|
|
using arg0 = typename decayed_arg_n<0, Ts...>::type;
|
|
};
|
|
|
|
template <typename R, typename... Ts>
|
|
struct function_traits<R(Ts...) const> : function_traits<R(Ts...)> {};
|
|
|
|
template <typename R, typename... Ts>
|
|
struct function_traits<R(Ts...)&> : function_traits<R(Ts...)> {};
|
|
|
|
template <typename R, typename... Ts>
|
|
struct function_traits<R(Ts...) const&> : function_traits<R(Ts...)> {};
|
|
|
|
template <typename R, typename... Ts>
|
|
struct function_traits<R(Ts...) &&> : function_traits<R(Ts...)> {};
|
|
|
|
template <typename R, typename... Ts>
|
|
struct function_traits<R(Ts...) const&&> : function_traits<R(Ts...)> {};
|
|
|
|
template <typename MemberFunction>
|
|
struct member_wrapper;
|
|
|
|
template <typename R, typename T>
|
|
struct member_wrapper<R T::*> {
|
|
using arg_type = typename function_traits<R>::arg0;
|
|
};
|
|
|
|
////////////////
|
|
// has method
|
|
////////////////
|
|
|
|
#define INIT_HAS_METHOD(method) \
|
|
template <typename T> \
|
|
class has_m_##method { \
|
|
template <typename C> \
|
|
static std::true_type test(decltype(&C::method)); \
|
|
\
|
|
template <typename C> \
|
|
static std::false_type test(...); \
|
|
\
|
|
public: \
|
|
constexpr static bool value = decltype(test<T>(0))::value; \
|
|
}; \
|
|
\
|
|
template <typename T> \
|
|
constexpr bool has_m_##method##_t = has_m_##method<T>::value;
|
|
|
|
} /* namespace ss */
|