ssp/include/ss/function_traits.hpp
red0124 55d0a4e598
Updated and added new functions related to headers, resolved ODR issues, resolved clang-tidy warnings (#50)
* 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
2024-03-14 17:22:57 +01:00

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 */