cppbind: Refactor to use C++11+ type_traits
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
include (SimGearComponent)
|
||||
|
||||
set(HEADERS
|
||||
integer_sequence.hxx
|
||||
type_traits.hxx
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
)
|
||||
|
||||
simgear_component(std std "${SOURCES}" "${HEADERS}")
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
add_executable(test_integer_sequence integer_sequence_test.cxx)
|
||||
add_test(integer_sequence ${EXECUTABLE_OUTPUT_PATH}/test_integer_sequence)
|
||||
target_link_libraries(test_integer_sequence ${TEST_LIBS})
|
||||
|
||||
add_executable(test_type_traits type_traits_test.cxx)
|
||||
add_test(type_traits ${EXECUTABLE_OUTPUT_PATH}/test_type_traits)
|
||||
target_link_libraries(test_type_traits ${TEST_LIBS})
|
||||
endif()
|
||||
@@ -0,0 +1,88 @@
|
||||
///@file
|
||||
/// Metaprogramming Integer sequence (Is in C++14 but not C++11)
|
||||
//
|
||||
// Copyright (C) 2017 Thomas Geymayer <tomgey@gmail.com>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
#ifndef SIMGEAR_STD_INTEGER_SEQUENCE_HXX_
|
||||
#define SIMGEAR_STD_INTEGER_SEQUENCE_HXX_
|
||||
|
||||
#include <simgear/simgear_config.h>
|
||||
#include "type_traits.hxx"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#ifndef HAVE_STD_INDEX_SEQUENCE
|
||||
# include <cstddef>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<class T, T... Ints>
|
||||
struct integer_sequence
|
||||
{
|
||||
static_assert(
|
||||
std::is_integral<T>::value,
|
||||
"std::integer_sequence can only be instantiated with an an integral type"
|
||||
);
|
||||
|
||||
typedef T value_type;
|
||||
static constexpr size_t size() noexcept { return sizeof...(Ints); }
|
||||
};
|
||||
}
|
||||
|
||||
namespace simgear { namespace detail
|
||||
{
|
||||
template<class T, class Seq, T El>
|
||||
struct append;
|
||||
|
||||
template<class T, T... Ints, T Int>
|
||||
struct append<T, std::integer_sequence<T, Ints...>, Int>
|
||||
{
|
||||
using type = std::integer_sequence<T, Ints..., Int>;
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct sequence_gen
|
||||
{
|
||||
using type =
|
||||
typename append<T, typename sequence_gen<T, N - 1>::type, N - 1>::type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct sequence_gen<T, 0>
|
||||
{
|
||||
using type = std::integer_sequence<T>;
|
||||
};
|
||||
}}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<size_t... Ints>
|
||||
using index_sequence = integer_sequence<size_t, Ints...>;
|
||||
|
||||
template<class T, size_t N>
|
||||
using make_integer_sequence =
|
||||
typename simgear::detail::sequence_gen<T, N>::type;
|
||||
|
||||
template<size_t N>
|
||||
using make_index_sequence = make_integer_sequence<size_t, N>;
|
||||
|
||||
template<class... T>
|
||||
using index_sequence_for = make_index_sequence<sizeof...(T)>;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SIMGEAR_STD_INTEGER_SEQUENCE_HXX_ */
|
||||
@@ -0,0 +1,46 @@
|
||||
#include <simgear/std/integer_sequence.hxx>
|
||||
#include <iostream>
|
||||
|
||||
template<class T>
|
||||
void print(const T& v, std::size_t i)
|
||||
{
|
||||
std::cout << "arg #" << i << ": '" << v << "', ";
|
||||
}
|
||||
|
||||
template<class... Args, std::size_t... Is>
|
||||
void doIt_impl(Args ... args, std::index_sequence<Is...>)
|
||||
{
|
||||
std::initializer_list<char>{(print(args, Is), '0')...};
|
||||
}
|
||||
|
||||
template<class... Args>
|
||||
void doIt(Args ... args)
|
||||
{
|
||||
static_assert(sizeof...(Args) == std::index_sequence_for<Args...>::size(), "");
|
||||
|
||||
doIt_impl<Args...>(args..., std::index_sequence_for<Args...>{});
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
static_assert(std::is_same<std::integer_sequence<char>::value_type, char>::value, "");
|
||||
static_assert(std::is_same<std::integer_sequence<long long>::value_type, long long>::value, "");
|
||||
static_assert(std::is_same<std::index_sequence<>::value_type, std::size_t>::value, "");
|
||||
|
||||
static_assert(std::is_same<std::make_index_sequence<0>, std::index_sequence<>>::value, "");
|
||||
static_assert(std::is_same<std::make_index_sequence<1>, std::index_sequence<0>>::value, "");
|
||||
static_assert(std::is_same<std::make_index_sequence<2>, std::index_sequence<0, 1>>::value, "");
|
||||
static_assert(std::is_same<std::make_index_sequence<3>, std::index_sequence<0, 1, 2>>::value, "");
|
||||
static_assert(std::is_same<std::make_index_sequence<4>, std::index_sequence<0, 1, 2, 3>>::value, "");
|
||||
static_assert(std::is_same<std::make_index_sequence<5>, std::index_sequence<0, 1, 2, 3, 4>>::value, "");
|
||||
static_assert(std::is_same<std::make_index_sequence<6>, std::index_sequence<0, 1, 2, 3, 4, 5>>::value, "");
|
||||
static_assert(std::is_same<std::make_index_sequence<7>, std::index_sequence<0, 1, 2, 3, 4, 5, 6>>::value, "");
|
||||
static_assert(std::is_same<std::make_index_sequence<8>, std::index_sequence<0, 1, 2, 3, 4, 5, 6, 7>>::value, "");
|
||||
|
||||
static_assert(std::make_index_sequence<5>::size() == 5, "");
|
||||
static_assert(std::index_sequence_for<float, int, double>::size() == 3, "");
|
||||
|
||||
std::cout << std::make_integer_sequence<int, 5>::size() << std::endl;
|
||||
doIt(1, 2, 3, "hallo", 3.4, 3.52f);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
///@file
|
||||
/// Type Traits (Provide features of later C++ standards)
|
||||
//
|
||||
// Copyright (C) 2017 Thomas Geymayer <tomgey@gmail.com>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
#ifndef SIMGEAR_STD_TYPE_TRAITS_HXX_
|
||||
#define SIMGEAR_STD_TYPE_TRAITS_HXX_
|
||||
|
||||
#include <simgear/simgear_config.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace std
|
||||
{
|
||||
#ifndef HAVE_STD_REMOVE_CV_T
|
||||
template<class T>
|
||||
using remove_cv_t = typename remove_cv<T>::type;
|
||||
|
||||
template<class T>
|
||||
using remove_const_t = typename remove_const<T>::type;
|
||||
|
||||
template<class T>
|
||||
using remove_volatile_t = typename remove_volatile<T>::type;
|
||||
|
||||
template<class T>
|
||||
using remove_reference_t = typename remove_reference<T>::type;
|
||||
|
||||
template< class T >
|
||||
using remove_pointer_t = typename remove_pointer<T>::type;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STD_REMOVE_CVREF_T
|
||||
template<class T>
|
||||
struct remove_cvref
|
||||
{
|
||||
using type = remove_cv_t<remove_reference_t<T>>;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
using remove_cvref_t = typename remove_cvref<T>::type;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STD_ENABLE_IF_T
|
||||
template<bool B, class T = void>
|
||||
using enable_if_t = typename enable_if<B, T>::type;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STD_BOOL_CONSTANT
|
||||
template <bool B>
|
||||
using bool_constant = integral_constant<bool, B>;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* SIMGEAR_STD_TYPE_TRAITS_HXX_ */
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <simgear/std/type_traits.hxx>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template<class T, class U>
|
||||
void assert_same()
|
||||
{
|
||||
static_assert(is_same<T, U>::value, "");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
assert_same<remove_cv_t<int const volatile>, int>();
|
||||
assert_same<remove_const_t<int const volatile>, int volatile>();
|
||||
assert_same<remove_volatile_t<int const volatile>, int const>();
|
||||
assert_same<remove_reference_t<int const volatile&>, int const volatile>();
|
||||
assert_same<remove_pointer_t<int const volatile*>, int const volatile>();
|
||||
assert_same<remove_cvref_t<int const volatile&>, int>();
|
||||
|
||||
assert_same<enable_if_t<true, double>, double>();
|
||||
assert_same<bool_constant<true>, integral_constant<bool, true>>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user