//============================================================================ // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt for details. // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ #ifndef vtk_m_std_integer_sequence_h #define vtk_m_std_integer_sequence_h #include #include #include #if defined(__cpp_lib_integer_sequence) #define VTK_M_USE_STD_INTEGER_SEQUENCE #elif (__cplusplus >= 201402L) #define VTK_M_USE_STD_INTEGER_SEQUENCE #elif defined(VTKM_MSVC) #define VTK_M_USE_STD_INTEGER_SEQUENCE #endif #if (__cplusplus >= 201402L) #define VTK_M_USE_STD_MAKE_INTEGER_SEQUENCE #elif defined(VTKM_MSVC) && (_MSC_FULL_VER >= 190023918) #define VTK_M_USE_STD_MAKE_INTEGER_SEQUENCE #endif namespace vtkmstd { #ifndef VTK_M_USE_STD_INTEGER_SEQUENCE template struct integer_sequence { using value_type = T; static constexpr std::size_t size() noexcept { return sizeof...(Ns); } }; template using index_sequence = integer_sequence; #else // VTK_M_USE_STD_INTEGER_SEQUENCE using std::index_sequence; using std::integer_sequence; #endif // VTK_M_USE_STD_INTEGER_SEQUENCE #ifndef VTK_M_USE_STD_MAKE_INTEGER_SEQUENCE namespace detail { // Implementation note: ideally these implementation classes would define "Num" // as the type for the sequence (i.e. T). However, compilers have trouble // resolving template partial specialization for a number whose type is one of // the other template parameters. (Most compilers allow you to specify them in // an integral_constant, but versions of GCC fail at that, too.) Instead, we are // using std::size_t for the num, which should be large enough. using SeqSizeT = std::size_t; template struct MakeSequenceImpl; template struct DoubleSequence; template struct DoubleSequence> { using type = vtkmstd::integer_sequence; }; template struct CombineSequences; template struct CombineSequences, vtkmstd::integer_sequence> { using type = vtkmstd::integer_sequence; }; template struct ExpandSequence; template struct ExpandSequence> { static constexpr SeqSizeT OldSize = sizeof...(Ns); static constexpr SeqSizeT RemainingAfter = Num - OldSize; static constexpr bool CanDoubleNext = RemainingAfter >= OldSize * 2; using type = typename ExpandSequence< CanDoubleNext, RemainingAfter, typename DoubleSequence>::type>::type; }; template struct ExpandSequence> { using type = typename CombineSequences, typename MakeSequenceImpl::type>::type; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { using type = vtkmstd::integer_sequence; }; template struct MakeSequenceImpl { VTKM_STATIC_ASSERT(Num >= 16); VTKM_STATIC_ASSERT_MSG(Num < (1 << 20), "Making an unexpectedly long integer sequence."); using type = typename ExpandSequence<(Num >= 32), Num - 16, typename MakeSequenceImpl::type>::type; }; } // namespace detail template using make_integer_sequence = typename detail::MakeSequenceImpl(N)>::type; template using make_index_sequence = make_integer_sequence; #else // VTK_M_USE_STD_MAKE_INTEGER_SEQUENCE using std::make_index_sequence; using std::make_integer_sequence; #endif // VTK_M_USE_STD_MAKE_INTEGER_SEQUENCE } // namespace vtkmstd #ifdef VTK_M_USE_STD_INTEGER_SEQUENCE #undef VTK_M_USE_STD_INTEGER_SEQUENCE #endif #ifdef VTK_M_USE_STD_MAKE_INTEGER_SEQUENCE #undef VTK_M_USE_STD_MAKE_INTEGER_SEQUENCE #endif #endif //vtk_m_std_integer_sequence_h