Add std::index_sequence for C++11
Will be required for nasal::Ghost
This commit is contained in:
parent
ab1e2d49ab
commit
52b8f60953
@ -135,6 +135,16 @@ include (DetectArch)
|
|||||||
# keep the compatability link option as the default
|
# keep the compatability link option as the default
|
||||||
option(OSG_FSTREAM_EXPORT_FIXED "Set to ON if the osgDB fstream export patch is applied" OFF)
|
option(OSG_FSTREAM_EXPORT_FIXED "Set to ON if the osgDB fstream export patch is applied" OFF)
|
||||||
|
|
||||||
|
if (CMAKE_COMPILER_IS_GNUCXX OR CLANG)
|
||||||
|
if (CMAKE_VERSION VERSION_LESS 3.1)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++${CMAKE_CXX_STANDARD}")
|
||||||
|
elseif (CMAKE_VERSION VERSION_LESS 3.8)
|
||||||
|
# policy CMP0067 (try_compile does not honor CMAKE_CXX_STANDARD)
|
||||||
|
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++${CMAKE_CXX_STANDARD}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_BINARY_DIR} PATH)
|
GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_BINARY_DIR} PATH)
|
||||||
if (CMAKE_CL_64)
|
if (CMAKE_CL_64)
|
||||||
@ -382,10 +392,6 @@ if(CMAKE_COMPILER_IS_GNUCXX)
|
|||||||
set(WARNING_FLAGS_CXX "-Wall -fPIC")
|
set(WARNING_FLAGS_CXX "-Wall -fPIC")
|
||||||
set(WARNING_FLAGS_C "-Wall -fPIC")
|
set(WARNING_FLAGS_C "-Wall -fPIC")
|
||||||
|
|
||||||
if (CMAKE_VERSION VERSION_LESS 3.1)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
|
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
|
||||||
message(WARNING "GCC 4.4 will be required soon, please upgrade")
|
message(WARNING "GCC 4.4 will be required soon, please upgrade")
|
||||||
endif()
|
endif()
|
||||||
@ -413,10 +419,6 @@ if (CLANG)
|
|||||||
# fix Boost compilation :(
|
# fix Boost compilation :(
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||||
|
|
||||||
if (CMAKE_VERSION VERSION_LESS 3.1)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ENABLE_SIMD)
|
if(ENABLE_SIMD)
|
||||||
if (X86 OR X86_64)
|
if (X86 OR X86_64)
|
||||||
set(CMAKE_C_FLAGS_RELEASE "-O3 -msse2 -mfpmath=sse")
|
set(CMAKE_C_FLAGS_RELEASE "-O3 -msse2 -mfpmath=sse")
|
||||||
@ -489,6 +491,14 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS_C} ${MSVC_FLAGS}")
|
|||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS_CXX} ${MSVC_FLAGS} ${BOOST_CXX_FLAGS}")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS_CXX} ${MSVC_FLAGS} ${BOOST_CXX_FLAGS}")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSVC_LD_FLAGS}")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSVC_LD_FLAGS}")
|
||||||
|
|
||||||
|
check_cxx_source_compiles("
|
||||||
|
#include <utility>
|
||||||
|
#include <type_traits>
|
||||||
|
std::make_index_sequence<0> t;
|
||||||
|
int main() { return 0; }"
|
||||||
|
HAVE_STD_INDEX_SEQUENCE
|
||||||
|
)
|
||||||
|
|
||||||
# use BEFORE to ensure local directories are used first,
|
# use BEFORE to ensure local directories are used first,
|
||||||
# ahead of system-installed libs
|
# ahead of system-installed libs
|
||||||
include_directories(BEFORE ${PROJECT_BINARY_DIR}/simgear)
|
include_directories(BEFORE ${PROJECT_BINARY_DIR}/simgear)
|
||||||
|
@ -56,6 +56,10 @@ add_executable(test_CSSBorder CSSBorder_test.cxx)
|
|||||||
add_test(CSSBorder ${EXECUTABLE_OUTPUT_PATH}/test_CSSBorder)
|
add_test(CSSBorder ${EXECUTABLE_OUTPUT_PATH}/test_CSSBorder)
|
||||||
target_link_libraries(test_CSSBorder ${TEST_LIBS})
|
target_link_libraries(test_CSSBorder ${TEST_LIBS})
|
||||||
|
|
||||||
|
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_tabbed_values tabbed_values_test.cxx)
|
add_executable(test_tabbed_values tabbed_values_test.cxx)
|
||||||
add_test(tabbed_values ${EXECUTABLE_OUTPUT_PATH}/test_tabbed_values)
|
add_test(tabbed_values ${EXECUTABLE_OUTPUT_PATH}/test_tabbed_values)
|
||||||
target_link_libraries(test_tabbed_values ${TEST_LIBS})
|
target_link_libraries(test_tabbed_values ${TEST_LIBS})
|
||||||
|
86
simgear/misc/integer_sequence.hxx
Normal file
86
simgear/misc/integer_sequence.hxx
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
///@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_MISC_INTEGER_SEQUENCE_HXX_
|
||||||
|
#define SIMGEAR_MISC_INTEGER_SEQUENCE_HXX_
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#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_MISC_INTEGER_SEQUENCE_HXX_ */
|
47
simgear/misc/integer_sequence_test.cxx
Normal file
47
simgear/misc/integer_sequence_test.cxx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#include "integer_sequence.hxx"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void print(const T& v, std::size_t i)
|
||||||
|
{
|
||||||
|
std::cout << "arg #" << i << ": '" << v << "', ";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ... Args, std::size_t ... Is>
|
||||||
|
void doIt_impl(Args ... args, std::index_sequence<Is...>)
|
||||||
|
{
|
||||||
|
std::initializer_list<char>{(print(args, Is), '0')...};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ... 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;
|
||||||
|
}
|
@ -15,7 +15,7 @@
|
|||||||
#cmakedefine HAVE_WINDOWS_H
|
#cmakedefine HAVE_WINDOWS_H
|
||||||
#cmakedefine HAVE_MKDTEMP
|
#cmakedefine HAVE_MKDTEMP
|
||||||
#cmakedefine HAVE_AL_EXT_H
|
#cmakedefine HAVE_AL_EXT_H
|
||||||
|
#cmakedefine HAVE_STD_INDEX_SEQUENCE
|
||||||
|
|
||||||
#cmakedefine GCC_ATOMIC_BUILTINS_FOUND
|
#cmakedefine GCC_ATOMIC_BUILTINS_FOUND
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user