#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace tf { //----------------------------------------------------------------------------- // Traits //----------------------------------------------------------------------------- // Macro to check whether a class has a member function #define TF_DEFINE_HAS_MEMBER(member_name) \ template \ class has_member_##member_name \ { \ typedef char yes_type; \ typedef long no_type; \ template static yes_type test(decltype(&U::member_name)); \ template static no_type test(...); \ public: \ static constexpr bool value = sizeof(test(0)) == sizeof(yes_type); \ } #define TF_HAS_MEMBER(class_, member_name) has_member_##member_name::value // Struct: dependent_false template struct dependent_false { static constexpr bool value = false; }; template constexpr auto dependent_false_v = dependent_false::value; //----------------------------------------------------------------------------- // Move-On-Copy //----------------------------------------------------------------------------- // Struct: MoC template struct MoC { MoC(T&& rhs) : object(std::move(rhs)) {} MoC(const MoC& other) : object(std::move(other.object)) {} T& get() { return object; } mutable T object; }; template auto make_moc(T&& m) { return MoC(std::forward(m)); } //----------------------------------------------------------------------------- // Functors. //----------------------------------------------------------------------------- // Overloadded. template struct Functors : Ts... { using Ts::operator()... ; }; template Functors(Ts...) -> Functors; // ---------------------------------------------------------------------------- // Function Traits // reference: https://github.com/ros2/rclcpp // ---------------------------------------------------------------------------- template struct tuple_tail; template struct tuple_tail> { using type = std::tuple; }; // std::function template struct function_traits { using arguments = typename tuple_tail< typename function_traits::argument_tuple_type >::type; static constexpr size_t arity = std::tuple_size_v; template struct argument { static_assert(N < arity, "error: invalid parameter index."); using type = std::tuple_element_t; }; template using argument_t = typename argument::type; using return_type = typename function_traits::return_type; }; // Free functions template struct function_traits { using return_type = R; using argument_tuple_type = std::tuple; static constexpr size_t arity = sizeof...(Args); template struct argument { static_assert(N < arity, "error: invalid parameter index."); using type = std::tuple_element_t>; }; template using argument_t = typename argument::type; }; // function pointer template struct function_traits : function_traits { }; // function reference template struct function_traits : function_traits { }; // immutable lambda template struct function_traits : function_traits {}; // mutable lambda template struct function_traits : function_traits {}; /*// std::bind for object methods template #if defined _LIBCPP_VERSION // libc++ (Clang) struct function_traits> #elif defined _GLIBCXX_RELEASE // glibc++ (GNU C++ >= 7.1) struct function_traits> #elif defined __GLIBCXX__ // glibc++ (GNU C++) struct function_traits(FArgs ...)>> #elif defined _MSC_VER // MS Visual Studio struct function_traits< std::_Binder> #else #error "Unsupported C++ compiler / standard library" #endif : function_traits {}; // std::bind for object const methods template #if defined _LIBCPP_VERSION // libc++ (Clang) struct function_traits> #elif defined _GLIBCXX_RELEASE // glibc++ (GNU C++ >= 7.1) struct function_traits> #elif defined __GLIBCXX__ // glibc++ (GNU C++) struct function_traits(FArgs ...)>> #elif defined _MSC_VER // MS Visual Studio struct function_traits< std::_Binder> #else #error "Unsupported C++ compiler / standard library" #endif : function_traits {}; // std::bind for free functions template #if defined _LIBCPP_VERSION // libc++ (Clang) struct function_traits> #elif defined __GLIBCXX__ // glibc++ (GNU C++) struct function_traits> #elif defined _MSC_VER // MS Visual Studio struct function_traits> #else #error "Unsupported C++ compiler / standard library" #endif : function_traits {}; */ // decay to the raw type template struct function_traits : function_traits {}; template struct function_traits : function_traits {}; // ---------------------------------------------------------------------------- // std::variant // ---------------------------------------------------------------------------- template struct get_index; template struct get_index_impl {}; template struct get_index_impl : std::integral_constant{}; template struct get_index_impl : get_index_impl{}; template struct get_index> : get_index_impl<0, T, Ts...>{}; template constexpr auto get_index_v = get_index::value; // ---------------------------------------------------------------------------- // is_pod //----------------------------------------------------------------------------- template struct is_pod { static const bool value = std::is_trivial_v && std::is_standard_layout_v; }; template constexpr bool is_pod_v = is_pod::value; // ---------------------------------------------------------------------------- // bit_cast //----------------------------------------------------------------------------- template typename std::enable_if< (sizeof(To) == sizeof(From)) && std::is_trivially_copyable_v && std::is_trivial_v, // this implementation requires that To is trivially default constructible To >::type // constexpr support needs compiler magic bit_cast(const From &src) noexcept { To dst; std::memcpy(&dst, &src, sizeof(To)); return dst; } // ---------------------------------------------------------------------------- // unwrap_reference // ---------------------------------------------------------------------------- template struct unwrap_reference { using type = T; }; template struct unwrap_reference> { using type = U&; }; template using unwrap_reference_t = typename unwrap_reference::type; template< class T > struct unwrap_ref_decay : unwrap_reference> {}; template using unwrap_ref_decay_t = typename unwrap_ref_decay::type; // ---------------------------------------------------------------------------- // stateful iterators // ---------------------------------------------------------------------------- // STL-styled iterator template struct stateful_iterator { using TB = std::decay_t>; using TE = std::decay_t>; static_assert(std::is_same_v, "decayed iterator types must match"); using type = TB; }; template using stateful_iterator_t = typename stateful_iterator::type; // raw integral index template struct stateful_index { using TB = std::decay_t>; using TE = std::decay_t>; using TS = std::decay_t>; static_assert( std::is_integral_v, "decayed beg index must be an integral type" ); static_assert( std::is_integral_v, "decayed end index must be an integral type" ); static_assert( std::is_integral_v, "decayed step must be an integral type" ); static_assert( std::is_same_v && std::is_same_v, "decayed index and step types must match" ); using type = TB; }; template using stateful_index_t = typename stateful_index::type; } // end of namespace tf. ----------------------------------------------------