Remove tao tuple from third party libraries

We are no longer using this code. It has been replaced by vtkm::Tuple.
This commit is contained in:
Kenneth Moreland 2020-03-04 15:26:09 -07:00
parent e05588a199
commit 75a46dc2eb
25 changed files with 2 additions and 2343 deletions

@ -104,7 +104,7 @@ function(do_verify root_dir prefix)
#Step 1. Setup the extensions to check, and all file and directory
# extensions
set(files_extensions
*.hpp #needed for diy and taotuple
*.hpp #needed for diy
*.h
*.hxx
)

@ -83,7 +83,6 @@ if(VTKm_ENABLE_LOGGING)
add_subdirectory(thirdparty/loguru)
endif()
add_subdirectory(thirdparty/optionparser)
add_subdirectory(thirdparty/taotuple)
add_subdirectory(thirdparty/lcl)
add_subdirectory(testing)

@ -217,7 +217,7 @@ endif()
target_link_libraries(vtkm_cont PUBLIC vtkm_compiler_flags ${backends})
target_link_libraries(vtkm_cont PUBLIC Threads::Threads)
target_link_libraries(vtkm_cont PUBLIC vtkm_taotuple vtkm_optionparser vtkm_diy vtkm_lcl)
target_link_libraries(vtkm_cont PUBLIC vtkm_optionparser vtkm_diy vtkm_lcl)
if(TARGET vtkm_loguru)
target_link_libraries(vtkm_cont PRIVATE vtkm_loguru)
endif()

@ -1,28 +0,0 @@
##============================================================================
## 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.
##============================================================================
add_library(vtkm_taotuple INTERFACE)
vtkm_get_kit_name(kit_name kit_dir)
# taotuple needs C++11
target_compile_features(vtkm_taotuple INTERFACE cxx_std_11)
target_include_directories(vtkm_taotuple INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${VTKm_INSTALL_INCLUDE_DIR}/vtkm/thirdparty/taotuple>)
install(TARGETS vtkm_taotuple
EXPORT ${VTKm_EXPORT_NAME})
## Install headers
if(NOT VTKm_INSTALL_ONLY_LIBRARIES)
install(DIRECTORY vtkmtaotuple
DESTINATION ${VTKm_INSTALL_INCLUDE_DIR}/${kit_dir}/)
endif()

@ -1,22 +0,0 @@
#!/usr/bin/env bash
set -e
set -x
shopt -s dotglob
readonly name="taotuple"
readonly ownership="TaoCpp Tuple Upstream <kwrobot@kitware.com>"
readonly subtree="vtkm/thirdparty/$name/vtkm$name"
readonly repo="https://gitlab.kitware.com/third-party/$name.git"
readonly tag="for/vtk-m"
readonly paths="
include
LICENSE
README.md
"
extract_source () {
git_archive
}
. "${BASH_SOURCE%/*}/../update-common.sh"

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2015-2018 Daniel Frey
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,43 +0,0 @@
# The Art of C++ / Tuple
[![Release](https://img.shields.io/github/release/taocpp/tuple.svg)](https://github.com/taocpp/tuple/releases/latest)
[![TravisCI](https://travis-ci.org/taocpp/tuple.svg)](https://travis-ci.org/taocpp/tuple)
[![AppVeyor](https://ci.appveyor.com/api/projects/status/9opt30ae579kw19b/branch/master?svg=true)](https://ci.appveyor.com/project/taocpp/tuple)
[The Art of C++](https://taocpp.github.io/) / Tuple is a C++11 header-only reference implementation of
[`std::tuple`](http://en.cppreference.com/w/cpp/utility/tuple).
## Rationale
Why another implementation of `std::tuple`? To provide a proof-of-concept that,
when avoiding recursion, code can benefit in significant ways. I prepared a talk
about it, including some benchmarks.
[Download presentation](https://github.com/taocpp/tuple/blob/master/Variadic%20Templates.pdf)
TL;DR: GCC 5 on Linux with libstdc++'s `std::tuple` requires 19.6s and an instantiation
depth of at least 3.719 to compile an
[example](https://github.com/taocpp/tuple/blob/master/src/test/tuple/tuple_benchmark.cpp)
generating a tuple with 265 elements via `std::tuple_cat`.
`tao::tuple` requires 1.2s and an instantiation depth of 26 on the same system.
Apple LLVM 7.0 (~Clang 3.7) with libc++'s `std::tuple` requires 70s and an instantiation
depth of 514 to compile the example. `tao::tuple` requires 1.7s and an instantiation depth
of 15 on the same system.
## Compatibility
* Requires C++11 or newer.
* Tested with GCC 4.8+ and Clang 3.4+.
## License
The Art of C++ is certified [Open Source](http://www.opensource.org/docs/definition.html) software. It may be used for any purpose, including commercial purposes, at absolutely no cost. It is distributed under the terms of the [MIT license](http://www.opensource.org/licenses/mit-license.html) reproduced here.
> Copyright (c) 2015-2018 Daniel Frey
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -1,498 +0,0 @@
//============================================================================
// 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.
//
// Copyright 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef SimpleTuple_h
#define SimpleTuple_h
// A simple tuple implementation for simple compilers.
//
// Most platforms use the taocpp/tuple implementation in thirdparty/taotuple,
// but not all are capable of handling the metaprogramming techniques used.
// This simple recursion-based tuple implementation is used where tao fails.
#include <type_traits>
#include <utility>
#ifndef TAOCPP_ANNOTATION
#ifdef __CUDACC__
#define TAOCPP_ANNOTATION __host__ __device__
#else
#define TAOCPP_ANNOTATION
#endif // __CUDACC__
#endif // TAOCPP_ANNOTATION
// Ignore "calling a __host__ function from a __host__ _device__ function is not allowed" warnings
#ifndef TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
#ifdef __CUDACC__
#if __CUDAVER__ >= 75000
#define TAO_TUPLE_SUPPRESS_NVCC_HD_WARN #pragma nv_exec_check_disable
#else
#define TAO_TUPLE_SUPPRESS_NVCC_HD_WARN #pragma hd_warning_disable
#endif
#else
#define TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
#endif
#endif
namespace simple_tuple
{
namespace detail
{
template <std::size_t Index, typename Head>
class tuple_leaf
{
protected:
Head Value;
public:
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
TAOCPP_ANNOTATION constexpr tuple_leaf()
: Value()
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
TAOCPP_ANNOTATION constexpr tuple_leaf(const Head& value)
: Value(value)
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
TAOCPP_ANNOTATION constexpr tuple_leaf(const tuple_leaf& o)
: Value(o.Value)
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
TAOCPP_ANNOTATION constexpr tuple_leaf(tuple_leaf&& o)
: Value(std::move(o.Value))
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template <typename Other>
TAOCPP_ANNOTATION constexpr tuple_leaf(Other&& o)
: Value(std::forward<Other>(o))
{
}
static TAOCPP_ANNOTATION constexpr Head& Get(tuple_leaf& o) noexcept { return o.Value; }
static TAOCPP_ANNOTATION constexpr const Head& Get(const tuple_leaf& o) noexcept
{
return o.Value;
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
TAOCPP_ANNOTATION
tuple_leaf& operator=(tuple_leaf& o)
{
this->Value = o.Value;
return *this;
}
};
template <std::size_t Index, typename... Ts>
class tuple_impl;
template <std::size_t Idx, typename HeadT, typename... TailTs>
class tuple_impl<Idx, HeadT, TailTs...> : public tuple_impl<Idx + 1, TailTs...>,
private tuple_leaf<Idx, HeadT>
{
public:
using Tail = tuple_impl<Idx + 1, TailTs...>;
using Leaf = tuple_leaf<Idx, HeadT>;
using Head = HeadT;
static const std::size_t Index = Idx;
TAOCPP_ANNOTATION constexpr tuple_impl()
: Tail()
, Leaf()
{
}
explicit TAOCPP_ANNOTATION constexpr tuple_impl(const HeadT& h, const TailTs&... ts)
: Tail(ts...)
, Leaf(h)
{
}
// The enable_if is needed to ensure that tail lengths match (otherwise empty
// constructors would be called).
template <typename OHeadT,
typename... OTailTs,
typename = typename std::enable_if<sizeof...(TailTs) == sizeof...(OTailTs)>::type>
explicit TAOCPP_ANNOTATION constexpr tuple_impl(OHeadT&& h, OTailTs&&... ts)
: Tail(std::forward<OTailTs>(ts)...)
, Leaf(std::forward<OHeadT>(h))
{
}
constexpr tuple_impl(const tuple_impl&) = default;
TAOCPP_ANNOTATION constexpr tuple_impl(tuple_impl&& o)
: Tail(std::move(GetTail(o)))
, Leaf(std::forward<Head>(GetHead(o)))
{
}
template <typename... Ts>
TAOCPP_ANNOTATION constexpr tuple_impl(const tuple_impl<Idx, Ts...>& o)
: Tail(tuple_impl<Idx, Ts...>::GetTail(o))
, Leaf(tuple_impl<Idx, Ts...>::GetHead(o))
{
}
template <typename OHead, typename... OTailTs>
TAOCPP_ANNOTATION constexpr tuple_impl(tuple_impl<Idx, OHead, OTailTs...>&& o)
: Tail(std::move(tuple_impl<Idx, OHead, OTailTs...>::GetTail(o)))
, Leaf(std::forward<OHead>(tuple_impl<Idx, OHead, OTailTs...>::GetHead(o)))
{
}
TAOCPP_ANNOTATION
tuple_impl& operator=(const tuple_impl& o)
{
GetHead(*this) = GetHead(o);
GetTail(*this) = GetTail(o);
return *this;
}
TAOCPP_ANNOTATION
tuple_impl& operator=(tuple_impl&& o)
{
GetHead(*this) = std::forward<Head>(GetHead(o));
GetTail(*this) = std::move(GetTail(o));
return *this;
}
template <typename... Ts>
TAOCPP_ANNOTATION tuple_impl& operator=(const tuple_impl<Idx, Ts...>& o)
{
GetHead(*this) = tuple_impl<Idx, Ts...>::GetHead(o);
GetTail(*this) = tuple_impl<Idx, Ts...>::GetTail(o);
return *this;
}
template <typename OHead, typename... OTailTs>
TAOCPP_ANNOTATION tuple_impl& operator=(tuple_impl<Idx, OHead, OTailTs...>&& o)
{
using OtherImpl = tuple_impl<Idx, OHead, OTailTs...>;
GetHead(*this) = std::forward<OHead>(OtherImpl::GetHead(o));
GetTail(*this) = std::move(OtherImpl::GetTail(o));
return *this;
}
static TAOCPP_ANNOTATION constexpr Head& GetHead(tuple_impl& o) noexcept
{
return Leaf::Get(static_cast<Leaf&>(o));
}
static TAOCPP_ANNOTATION constexpr const Head& GetHead(const tuple_impl& o) noexcept
{
return Leaf::Get(static_cast<const Leaf&>(o));
}
static TAOCPP_ANNOTATION constexpr Tail& GetTail(tuple_impl& o) noexcept
{
return static_cast<Tail&>(o);
}
static TAOCPP_ANNOTATION constexpr const Tail& GetTail(const tuple_impl& o) noexcept
{
return static_cast<const Tail&>(o);
}
};
template <std::size_t Idx, typename HeadT>
class tuple_impl<Idx, HeadT> : private tuple_leaf<Idx, HeadT>
{
public:
using Leaf = tuple_leaf<Idx, HeadT>;
using Head = HeadT;
static const std::size_t Index = Idx;
TAOCPP_ANNOTATION constexpr tuple_impl()
: Leaf()
{
}
explicit TAOCPP_ANNOTATION constexpr tuple_impl(const HeadT& h)
: Leaf(h)
{
}
template <typename OHeadT>
explicit TAOCPP_ANNOTATION constexpr tuple_impl(OHeadT&& h)
: Leaf(std::forward<OHeadT>(h))
{
}
TAOCPP_ANNOTATION constexpr tuple_impl(const tuple_impl& o)
: Leaf(GetHead(o))
{
}
TAOCPP_ANNOTATION constexpr tuple_impl(tuple_impl&& o)
: Leaf(std::forward<Head>(GetHead(o)))
{
}
template <typename OHeadT>
TAOCPP_ANNOTATION constexpr tuple_impl(const tuple_impl<Idx, OHeadT>& o)
: Leaf(tuple_impl<Idx, OHeadT>::GetHead(o))
{
}
template <typename OHeadT>
TAOCPP_ANNOTATION constexpr tuple_impl(tuple_impl<Idx, OHeadT>&& o)
: Leaf(std::forward<OHeadT>(tuple_impl<Idx, OHeadT>::GetHead(o)))
{
}
TAOCPP_ANNOTATION
tuple_impl& operator=(const tuple_impl& o)
{
GetHead(*this) = GetHead(o);
return *this;
}
TAOCPP_ANNOTATION
tuple_impl& operator=(tuple_impl&& o)
{
GetHead(*this) = std::forward<Head>(GetHead(o));
return *this;
}
template <typename OHeadT>
TAOCPP_ANNOTATION tuple_impl& operator=(const tuple_impl<Idx, OHeadT>& o)
{
GetHead(*this) = tuple_impl<Idx, OHeadT>::GetHead(o);
return *this;
}
template <typename OHeadT>
TAOCPP_ANNOTATION tuple_impl& operator=(tuple_impl<Idx, OHeadT>&& o)
{
using OtherImpl = tuple_impl<Idx, OHeadT>;
GetHead(*this) = std::forward<OHeadT>(OtherImpl::GetHead(o));
return *this;
}
static TAOCPP_ANNOTATION constexpr Head& GetHead(tuple_impl& o) noexcept
{
return Leaf::Get(static_cast<Leaf&>(o));
}
static TAOCPP_ANNOTATION constexpr const Head& GetHead(const tuple_impl& o) noexcept
{
return Leaf::Get(static_cast<const Leaf&>(o));
}
};
template <std::size_t Idx, typename Head, typename... Tail>
TAOCPP_ANNOTATION constexpr Head& get_helper(tuple_impl<Idx, Head, Tail...>& t) noexcept
{
return tuple_impl<Idx, Head, Tail...>::GetHead(t);
}
template <std::size_t Idx, typename Head, typename... Tail>
TAOCPP_ANNOTATION constexpr const Head& get_helper(const tuple_impl<Idx, Head, Tail...>& t) noexcept
{
return tuple_impl<Idx, Head, Tail...>::GetHead(t);
}
// Unassignable stateless type:
struct ignore_impl
{
template <class T>
TAOCPP_ANNOTATION constexpr const ignore_impl& operator=(const T&) const
{
return *this;
}
};
} // end namespace detail
/// Reimplementation of std::tuple with markup for device support.
template <typename... Ts>
class tuple;
template <typename... Ts>
class tuple : public detail::tuple_impl<0, Ts...>
{
using Impl = detail::tuple_impl<0, Ts...>;
public:
TAOCPP_ANNOTATION constexpr tuple()
: Impl()
{
}
TAOCPP_ANNOTATION constexpr explicit tuple(const Ts&... ts)
: Impl(ts...)
{
}
template <typename... OTs>
TAOCPP_ANNOTATION constexpr explicit tuple(const OTs&... ts)
: Impl(ts...)
{
}
template <typename... OTs>
TAOCPP_ANNOTATION constexpr explicit tuple(OTs&&... ts)
: Impl(std::forward<OTs>(ts)...)
{
}
constexpr tuple(const tuple&) = default;
constexpr tuple(tuple&& o) = default;
template <typename... OTs>
TAOCPP_ANNOTATION constexpr tuple(const tuple<OTs...>& o)
: Impl(static_cast<detail::tuple_impl<0, OTs...>&>(o))
{
}
template <typename... OTs>
TAOCPP_ANNOTATION constexpr tuple(tuple<OTs...>&& o)
: Impl(static_cast<detail::tuple_impl<0, OTs...>&&>(o))
{
}
TAOCPP_ANNOTATION
tuple& operator=(const tuple& o)
{
this->Impl::operator=(o);
return *this;
}
TAOCPP_ANNOTATION
tuple& operator=(tuple&& o)
{
this->Impl::operator=(std::move(o));
return *this;
}
template <typename... OTs>
TAOCPP_ANNOTATION typename std::enable_if<sizeof...(Ts) == sizeof...(OTs), tuple&>::type
operator=(const tuple<OTs...>& o)
{
this->Impl::operator=(o);
return *this;
}
template <typename... OTs>
TAOCPP_ANNOTATION typename std::enable_if<sizeof...(Ts) == sizeof...(OTs), tuple&>::type
operator=(tuple<OTs...>&& o)
{
this->Impl::operator=(std::move(o));
return *this;
}
};
// Specialize for empty tuple:
template <>
class tuple<>
{
public:
tuple() = default;
};
/// Reimplementation of std::tuple_size with markup for device support.
template <typename TupleType>
struct tuple_size;
template <typename... Ts>
struct tuple_size<tuple<Ts...>>
: public std::integral_constant<std::size_t, static_cast<std::size_t>(sizeof...(Ts))>
{
static const std::size_t value = static_cast<std::size_t>(sizeof...(Ts));
};
/// Reimplementation of std::tuple_element with markup for device support.
template <std::size_t Idx, typename TupleType>
struct tuple_element;
template <std::size_t Idx, typename Head, typename... Tail>
struct tuple_element<Idx, tuple<Head, Tail...>> : public tuple_element<Idx - 1, tuple<Tail...>>
{
};
template <typename Head, typename... Tail>
struct tuple_element<0, tuple<Head, Tail...>>
{
using type = Head;
};
template <std::size_t Idx>
struct tuple_element<Idx, tuple<>>
{
static_assert(Idx < tuple_size<tuple<>>::value, "Tuple index valid.");
};
/// Reimplementation of std::get with markup for device support.
template <std::size_t Idx, typename... Ts>
TAOCPP_ANNOTATION constexpr const typename tuple_element<Idx, tuple<Ts...>>::type& get(
const tuple<Ts...>& t) noexcept
{
return detail::get_helper<Idx>(t);
}
template <std::size_t Idx, typename... Ts>
TAOCPP_ANNOTATION constexpr typename tuple_element<Idx, tuple<Ts...>>::type& get(
tuple<Ts...>& t) noexcept
{
return detail::get_helper<Idx>(t);
}
template <std::size_t Idx, typename... Ts>
TAOCPP_ANNOTATION constexpr typename tuple_element<Idx, tuple<Ts...>>::type&& get(
tuple<Ts...>&& t) noexcept
{
using ResultType = typename tuple_element<Idx, tuple<Ts...>>::type;
return std::forward<ResultType&&>(get<Idx>(t));
}
/// Reimplementation of std::make_tuple with markup for device support.
template <typename... Ts>
TAOCPP_ANNOTATION constexpr tuple<typename std::decay<Ts>::type...> make_tuple(Ts... ts)
{
using ResultType = tuple<typename std::decay<Ts>::type...>;
return ResultType(std::forward<Ts>(ts)...);
}
/// Reimplementation of std::tie with markup for device support.
template <typename... Ts>
TAOCPP_ANNOTATION constexpr tuple<Ts&...> tie(Ts&... ts) noexcept
{
return tuple<Ts&...>(ts...);
}
/// Reimplementation of std::ignore with markup for device support.
static const detail::ignore_impl ignore{};
} // end namespace simple_tuple
#endif // SimpleTuple_h

@ -1,58 +0,0 @@
//============================================================================
// 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.
//
// Copyright 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef Tuple_h
#define Tuple_h
// tao::tuple is a much more efficient tuple implementation, but it doesn't
// work on MSVC2015. For this compiler, fallback to a simpler implementation.
#if defined(_MSC_VER) && _MSC_VER == 1900
#define TAOCPP_USE_SIMPLE_TUPLE
// There is a bug in apple clang 9.0 that prevents tao-tuple from compiling:
#elif defined(__apple_build_version__) && defined(__clang__) && __clang_major__ == 9 && \
clang_minor == 0
#define TAOCPP_USE_SIMPLE_TUPLE
#endif
#ifdef TAOCPP_USE_SIMPLE_TUPLE
#include "SimpleTuple.h"
#else
#include "tao/tuple/tuple.hpp"
#endif
namespace vtkmstd
{
#ifdef TAOCPP_USE_SIMPLE_TUPLE
using simple_tuple::get;
using simple_tuple::make_tuple;
using simple_tuple::tuple;
using simple_tuple::tuple_element;
using simple_tuple::tuple_size;
#else
using tao::get;
using tao::make_tuple;
using tao::tuple;
using tao::tuple_element;
using tao::tuple_size;
#endif
} // end namespace vtkmstd
#endif // Tuple_h

@ -1,64 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_AT_INDEX_HPP
#define TAO_SEQ_AT_INDEX_HPP
#include <cstddef>
#include "make_integer_sequence.hpp"
namespace tao
{
namespace seq
{
// based on http://talesofcpp.fusionfenix.com/post-22/true-story-efficient-packing
namespace impl
{
template< std::size_t, typename T >
struct indexed
{
using type = T;
};
template< typename, typename... Ts >
struct indexer;
template< std::size_t... Is, typename... Ts >
struct indexer< index_sequence< Is... >, Ts... >
: indexed< Is, Ts >...
{
};
template< std::size_t I, typename T >
indexed< I, T > select( const indexed< I, T >& );
} // namespace impl
template< std::size_t I, typename... Ts >
using at_index = decltype( impl::select< I >( impl::indexer< index_sequence_for< Ts... >, Ts... >() ) );
#ifndef _MSC_VER
template< std::size_t I, typename... Ts >
using at_index_t = typename at_index< I, Ts... >::type;
#else
namespace impl
{
template< typename T >
struct get_type
{
using type = typename T::type;
};
} // namespace impl
template< std::size_t I, typename... Ts >
using at_index_t = typename impl::get_type< at_index< I, Ts... > >::type;
#endif
} // namespace seq
} // namespace tao
#endif

@ -1,33 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_CONFIG_HPP
#define TAO_SEQ_CONFIG_HPP
#include <utility>
#ifndef TAO_SEQ_USE_STD_INTEGER_SEQUENCE
#if defined( __cpp_lib_integer_sequence )
#define TAO_SEQ_USE_STD_INTEGER_SEQUENCE
#elif defined( _LIBCPP_VERSION ) && ( __cplusplus >= 201402L )
#define TAO_SEQ_USE_STD_INTEGER_SEQUENCE
#elif defined( _MSC_VER )
#define TAO_SEQ_USE_STD_INTEGER_SEQUENCE
#endif
#endif
#ifndef TAO_SEQ_USE_STD_MAKE_INTEGER_SEQUENCE
#if defined( _GLIBCXX_RELEASE ) && ( _GLIBCXX_RELEASE >= 8 ) && ( __cplusplus >= 201402L )
#define TAO_SEQ_USE_STD_MAKE_INTEGER_SEQUENCE
#elif defined( _LIBCPP_VERSION ) && ( __cplusplus >= 201402L )
#define TAO_SEQ_USE_STD_MAKE_INTEGER_SEQUENCE
#elif defined( _MSC_VER ) && ( _MSC_FULL_VER >= 190023918 )
#define TAO_SEQ_USE_STD_MAKE_INTEGER_SEQUENCE
#endif
#endif
#if defined( __cpp_fold_expressions ) && ( !defined( __GNUC__ ) || ( __GNUC__ >= 8 ) )
#define TAO_SEQ_FOLD_EXPRESSIONS
#endif
#endif

@ -1,48 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_EXCLUSIVE_SCAN_HPP
#define TAO_SEQ_EXCLUSIVE_SCAN_HPP
#include <utility>
#include "make_integer_sequence.hpp"
#include "partial_sum.hpp"
namespace tao
{
namespace seq
{
namespace impl
{
template< typename S, typename = make_index_sequence< S::size() > >
struct exclusive_scan;
template< typename S, std::size_t... Is >
struct exclusive_scan< S, index_sequence< Is... > >
{
using type = integer_sequence< typename S::value_type, partial_sum< Is, S >::value... >;
};
} // namespace impl
template< typename T, T... Ns >
struct exclusive_scan
: impl::exclusive_scan< integer_sequence< T, Ns... > >
{
};
template< typename T, T... Ns >
struct exclusive_scan< integer_sequence< T, Ns... > >
: impl::exclusive_scan< integer_sequence< T, Ns... > >
{
};
template< typename T, T... Ns >
using exclusive_scan_t = typename exclusive_scan< T, Ns... >::type;
} // namespace seq
} // namespace tao
#endif

@ -1,36 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_INCLUSIVE_SCAN_HPP
#define TAO_SEQ_INCLUSIVE_SCAN_HPP
#include <utility>
#include "exclusive_scan.hpp"
#include "integer_sequence.hpp"
#include "plus.hpp"
namespace tao
{
namespace seq
{
template< typename T, T... Ns >
struct inclusive_scan
: plus< exclusive_scan_t< T, Ns... >, integer_sequence< T, Ns... > >
{
};
template< typename T, T... Ns >
struct inclusive_scan< integer_sequence< T, Ns... > >
: plus< exclusive_scan_t< integer_sequence< T, Ns... > >, integer_sequence< T, Ns... > >
{
};
template< typename T, T... Ns >
using inclusive_scan_t = typename inclusive_scan< T, Ns... >::type;
} // namespace seq
} // namespace tao
#endif

@ -1,44 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_INTEGER_SEQUENCE_HPP
#define TAO_SEQ_INTEGER_SEQUENCE_HPP
#include <cstddef>
#include <utility>
#include "config.hpp"
namespace tao
{
namespace seq
{
#ifdef TAO_SEQ_USE_STD_INTEGER_SEQUENCE
using std::index_sequence;
using std::integer_sequence;
#else
template< typename T, T... Ns >
struct integer_sequence
{
using value_type = T;
static constexpr std::size_t size() noexcept
{
return sizeof...( Ns );
}
};
template< std::size_t... Ns >
using index_sequence = integer_sequence< std::size_t, Ns... >;
#endif
} // namespace seq
} // namespace tao
#endif

@ -1,36 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_IS_ALL_HPP
#define TAO_SEQ_IS_ALL_HPP
#include "config.hpp"
#ifndef TAO_SEQ_FOLD_EXPRESSIONS
#include "integer_sequence.hpp"
#endif
#include <type_traits>
namespace tao
{
namespace seq
{
#ifdef TAO_SEQ_FOLD_EXPRESSIONS
template< bool... Bs >
using is_all = std::integral_constant< bool, ( Bs && ... ) >;
#else
template< bool... Bs >
using is_all = std::integral_constant< bool, std::is_same< integer_sequence< bool, true, Bs... >, integer_sequence< bool, Bs..., true > >::value >;
#endif
} // namespace seq
} // namespace tao
#endif

@ -1,90 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_MAKE_INTEGER_SEQUENCE_HPP
#define TAO_SEQ_MAKE_INTEGER_SEQUENCE_HPP
#include <cstddef>
#include <type_traits>
#include <utility>
#include "config.hpp"
#include "integer_sequence.hpp"
namespace tao
{
namespace seq
{
#ifdef TAO_SEQ_USE_STD_MAKE_INTEGER_SEQUENCE
using std::index_sequence_for;
using std::make_index_sequence;
using std::make_integer_sequence;
#else
namespace impl
{
// we have four instantiations of generate_sequence<>, independent of T or N.
// V is the current bit, E is the end marker - if true, this is the last step.
template< bool V, bool E >
struct generate_sequence;
// last step: generate final integer sequence
template<>
struct generate_sequence< false, true >
{
template< typename T, T M, T N, std::size_t S, T... Ns >
using f = integer_sequence< T, Ns... >;
};
template<>
struct generate_sequence< true, true >
{
template< typename T, T M, T N, std::size_t S, T... Ns >
using f = integer_sequence< T, Ns..., S >;
};
// intermediate step: double existing values, append one more if V is set.
template<>
struct generate_sequence< false, false >
{
template< typename T, T M, T N, std::size_t S, T... Ns >
using f = typename generate_sequence< ( N & ( M / 2 ) ) != 0, ( M / 2 ) == 0 >::template f< T, M / 2, N, 2 * S, Ns..., ( Ns + S )... >;
};
template<>
struct generate_sequence< true, false >
{
template< typename T, T M, T N, std::size_t S, T... Ns >
using f = typename generate_sequence< ( N & ( M / 2 ) ) != 0, ( M / 2 ) == 0 >::template f< T, M / 2, N, 2 * S + 1, Ns..., ( Ns + S )..., 2 * S >;
};
// the final sequence per T/N should be memoized, it will probably be used multiple times.
// also checks the limit and starts the above generator properly.
template< typename T, T N >
struct memoize_sequence
{
static_assert( N < T( 1 << 20 ), "N too large" );
using type = typename generate_sequence< false, false >::template f< T, ( N < T( 1 << 1 ) ) ? T( 1 << 1 ) : ( N < T( 1 << 2 ) ) ? T( 1 << 2 ) : ( N < T( 1 << 3 ) ) ? T( 1 << 3 ) : ( N < T( 1 << 4 ) ) ? T( 1 << 4 ) : ( N < T( 1 << 5 ) ) ? T( 1 << 5 ) : ( N < T( 1 << 6 ) ) ? T( 1 << 6 ) : ( N < T( 1 << 7 ) ) ? T( 1 << 7 ) : ( N < T( 1 << 8 ) ) ? T( 1 << 8 ) : ( N < T( 1 << 9 ) ) ? T( 1 << 9 ) : ( N < T( 1 << 10 ) ) ? T( 1 << 10 ) : T( 1 << 20 ), N, 0 >;
};
} // namespace impl
template< typename T, T N >
using make_integer_sequence = typename impl::memoize_sequence< T, N >::type;
template< std::size_t N >
using make_index_sequence = make_integer_sequence< std::size_t, N >;
template< typename... Ts >
using index_sequence_for = make_index_sequence< sizeof...( Ts ) >;
#endif
} // namespace seq
} // namespace tao
#endif

@ -1,33 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_MAP_HPP
#define TAO_SEQ_MAP_HPP
#include <cstddef>
#include <utility>
#include "integer_sequence.hpp"
#include "select.hpp"
namespace tao
{
namespace seq
{
template< typename, typename >
struct map;
template< std::size_t... Ns, typename M >
struct map< index_sequence< Ns... >, M >
{
using type = integer_sequence< typename M::value_type, select< Ns, M >::value... >;
};
template< typename S, typename M >
using map_t = typename map< S, M >::type;
} // namespace seq
} // namespace tao
#endif

@ -1,35 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_MINUS_HPP
#define TAO_SEQ_MINUS_HPP
#include <type_traits>
#include "zip.hpp"
namespace tao
{
namespace seq
{
namespace impl
{
struct minus
{
template< typename T, T A, T B >
using apply = std::integral_constant< T, A - B >;
};
} // namespace impl
template< typename A, typename B >
using minus = zip< impl::minus, A, B >;
template< typename A, typename B >
using minus_t = typename minus< A, B >::type;
} // namespace seq
} // namespace tao
#endif

@ -1,47 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_PARTIAL_SUM_HPP
#define TAO_SEQ_PARTIAL_SUM_HPP
#include <cstddef>
#include <utility>
#include "make_integer_sequence.hpp"
#include "sum.hpp"
namespace tao
{
namespace seq
{
namespace impl
{
template< std::size_t, typename S, typename = make_index_sequence< S::size() > >
struct partial_sum;
template< std::size_t I, typename T, T... Ns, std::size_t... Is >
struct partial_sum< I, integer_sequence< T, Ns... >, index_sequence< Is... > >
: seq::sum< T, ( ( Is < I ) ? Ns : 0 )... >
{
static_assert( I <= sizeof...( Is ), "tao::seq::partial_sum<I, S>: I is out of range" );
};
} // namespace impl
template< std::size_t I, typename T, T... Ns >
struct partial_sum
: impl::partial_sum< I, integer_sequence< T, Ns... > >
{
};
template< std::size_t I, typename T, T... Ns >
struct partial_sum< I, integer_sequence< T, Ns... > >
: impl::partial_sum< I, integer_sequence< T, Ns... > >
{
};
} // namespace seq
} // namespace tao
#endif

@ -1,35 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_PLUS_HPP
#define TAO_SEQ_PLUS_HPP
#include <type_traits>
#include "zip.hpp"
namespace tao
{
namespace seq
{
namespace impl
{
struct plus
{
template< typename T, T A, T B >
using apply = std::integral_constant< T, A + B >;
};
} // namespace impl
template< typename A, typename B >
using plus = zip< impl::plus, A, B >;
template< typename A, typename B >
using plus_t = typename plus< A, B >::type;
} // namespace seq
} // namespace tao
#endif

@ -1,33 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_SELECT_HPP
#define TAO_SEQ_SELECT_HPP
#include <cstddef>
#include <utility>
#include "at_index.hpp"
#include "integer_sequence.hpp"
namespace tao
{
namespace seq
{
template< std::size_t I, typename T, T... Ns >
struct select
: at_index_t< I, std::integral_constant< T, Ns >... >
{
};
template< std::size_t I, typename T, T... Ns >
struct select< I, integer_sequence< T, Ns... > >
: select< I, T, Ns... >
{
};
} // namespace seq
} // namespace tao
#endif

@ -1,87 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_SUM_HPP
#define TAO_SEQ_SUM_HPP
#include <type_traits>
#include <utility>
#include "config.hpp"
#include "integer_sequence.hpp"
#ifndef TAO_SEQ_FOLD_EXPRESSIONS
#include "make_integer_sequence.hpp"
#include <cstddef>
#endif
namespace tao
{
namespace seq
{
#ifdef TAO_SEQ_FOLD_EXPRESSIONS
template< typename T, T... Ns >
struct sum
: std::integral_constant< T, ( Ns + ... + T( 0 ) ) >
{
};
#else
namespace impl
{
template< std::size_t, std::size_t N >
struct chars
{
char dummy[ N + 1 ];
};
template< typename, std::size_t... >
struct collector;
template< std::size_t... Is, std::size_t... Ns >
struct collector< index_sequence< Is... >, Ns... >
: chars< Is, Ns >...
{
};
template< bool, std::size_t N, typename T, T... Ns >
struct sum;
template< std::size_t N, typename T, T... Ns >
struct sum< true, N, T, Ns... >
{
using type = std::integral_constant< T, T( sizeof( collector< make_index_sequence< N >, Ns... > ) - N ) >;
};
template< bool, std::size_t N, typename T, T... Ns >
struct sum
{
using positive = typename sum< true, N, T, ( ( Ns > 0 ) ? Ns : 0 )... >::type;
using negative = typename sum< true, N, T, ( ( Ns < 0 ) ? -Ns : 0 )... >::type;
using type = std::integral_constant< T, positive::value - negative::value >;
};
} // namespace impl
template< typename T, T... Ns >
struct sum
: impl::sum< std::is_unsigned< T >::value, sizeof...( Ns ) + 1, T, Ns..., 0 >::type
{
};
#endif
template< typename T, T... Ns >
struct sum< integer_sequence< T, Ns... > >
: sum< T, Ns... >
{
};
} // namespace seq
} // namespace tao
#endif

@ -1,60 +0,0 @@
// The Art of C++ / Sequences
// Copyright (c) 2015 Daniel Frey
#ifndef TAOCPP_SEQUENCES_INCLUDE_TYPE_BY_INDEX_HPP
#define TAOCPP_SEQUENCES_INCLUDE_TYPE_BY_INDEX_HPP
#include <cstddef>
#include <type_traits>
#include "make_integer_sequence.hpp"
namespace tao
{
namespace seq
{
// based on http://stackoverflow.com/questions/18942322
namespace impl
{
template< std::size_t >
struct any
{
any( ... );
};
template< typename >
struct wrapper;
template< typename >
struct unwrap;
template< typename T >
struct unwrap< wrapper< T > >
{
using type = T;
};
template< typename >
struct get_nth;
template< std::size_t... Is >
struct get_nth< index_sequence< Is... > >
{
template< typename T >
static T deduce( any< Is & 0 >..., T*, ... );
};
}
template< std::size_t I, typename... Ts >
struct type_by_index
{
using type = typename impl::unwrap< decltype( impl::get_nth< make_index_sequence< I > >::deduce( std::declval< impl::wrapper< Ts >* >()... ) ) >::type;
};
template< std::size_t I, typename... Ts >
using type_by_index_t = typename type_by_index< I, Ts... >::type;
}
}
#endif // TAOCPP_SEQUENCES_INCLUDE_TYPE_BY_INDEX_HPP

@ -1,32 +0,0 @@
// Copyright (c) 2015-2018 Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/sequences/
#ifndef TAO_SEQ_ZIP_HPP
#define TAO_SEQ_ZIP_HPP
#include <type_traits>
#include "integer_sequence.hpp"
namespace tao
{
namespace seq
{
template< typename, typename, typename >
struct zip;
template< typename OP, typename TA, TA... As, typename TB, TB... Bs >
struct zip< OP, integer_sequence< TA, As... >, integer_sequence< TB, Bs... > >
{
using CT = typename std::common_type< TA, TB >::type;
using type = integer_sequence< CT, OP::template apply< CT, As, Bs >::value... >;
};
template< typename OP, typename A, typename B >
using zip_t = typename zip< OP, A, B >::type;
} // namespace seq
} // namespace tao
#endif

@ -1,957 +0,0 @@
// The Art of C++ / Tuple
// Copyright (c) 2015-2018 Daniel Frey
#ifndef TAO_TUPLE_TUPLE_HPP
#define TAO_TUPLE_TUPLE_HPP
#include "../seq/config.hpp"
#include "../seq/exclusive_scan.hpp"
#include "../seq/inclusive_scan.hpp"
#include "../seq/integer_sequence.hpp"
#include "../seq/is_all.hpp"
#include "../seq/make_integer_sequence.hpp"
#include "../seq/map.hpp"
#include "../seq/minus.hpp"
#include "../seq/sum.hpp"
#include "../seq/type_by_index.hpp"
#include <memory>
#include <type_traits>
#include <utility>
#if( __cplusplus >= 201402L )
#define TAO_TUPLE_CONSTEXPR constexpr
#else
#define TAO_TUPLE_CONSTEXPR
#endif
#ifndef TAO_TUPLE_CUDA_ANNOTATE_COMMON
#ifdef __CUDACC__
#define TAO_TUPLE_CUDA_ANNOTATE_COMMON __host__ __device__
#else
#define TAO_TUPLE_CUDA_ANNOTATE_COMMON
#endif
#endif
// Ignore "calling a __host__ function from a __host__ _device__ function is not allowed" warnings
#ifndef TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
#ifdef __CUDACC__
#if _MSC_VER
#if __CUDAVER__ >= 75000
#define TAO_TUPLE_SUPPRESS_NVCC_HD_WARN __pragma("nv_exec_check_disable")
#else
#define TAO_TUPLE_SUPPRESS_NVCC_HD_WARN __pragma("hd_warning_disable")
#endif
#else
#if __CUDAVER__ >= 75000
#define TAO_TUPLE_SUPPRESS_NVCC_HD_WARN _Pragma("nv_exec_check_disable")
#else
#define TAO_TUPLE_SUPPRESS_NVCC_HD_WARN _Pragma("hd_warning_disable")
#endif
#endif
#else
#define TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
#endif
#endif
namespace tao
{
template< typename... Ts >
struct tuple;
}
namespace std
{
// 20.4.2.8 Tuple traits [tuple.traits]
template< typename... Ts, typename A >
struct uses_allocator< tao::tuple< Ts... >, A > : true_type
{
};
} // namespace std
namespace tao
{
template< std::size_t I, typename... Ts >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON const seq::type_by_index_t< I, Ts... >& get( const tuple< Ts... >& ) noexcept;
template< std::size_t I, typename... Ts >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON seq::type_by_index_t< I, Ts... >& get( tuple< Ts... >& ) noexcept;
template< std::size_t I, typename... Ts >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON seq::type_by_index_t< I, Ts... >&& get( const tuple< Ts... >&& ) noexcept;
namespace impl
{
// TODO: std::pair support
// TODO: allocator support
using swallow = bool[];
template< typename T, typename >
struct dependent_type : T
{
};
template< bool B, typename T = void >
using enable_if_t = typename std::enable_if< B, T >::type;
// TODO: this is in namespace impl. is it harmless?
using std::swap;
template< typename T >
using is_nothrow_swappable = std::integral_constant< bool, noexcept( swap( std::declval< T& >(), std::declval< T& >() ) ) >;
#if __cplusplus >= 201402L
template< typename T >
using is_final = std::is_final< T >;
#else
template< typename T >
using is_final = std::integral_constant< bool, __is_final( T ) >;
#endif
template< bool, bool >
struct uses_alloc_ctor;
template< typename T, typename A, typename... As >
using uses_alloc_ctor_t = uses_alloc_ctor< std::uses_allocator< T, A >::value, std::is_constructible< T, std::allocator_arg_t, A, As... >::value >*;
template< std::size_t I, typename T, bool = std::is_empty< T >::value && !is_final< T >::value >
struct tuple_value
{
T value;
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
TAO_TUPLE_CUDA_ANNOTATE_COMMON
constexpr tuple_value() noexcept( std::is_nothrow_default_constructible< T >::value )
: value()
{
static_assert( !std::is_reference< T >::value, "attempted to default construct a reference element in a tuple" );
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< bool B, typename A >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_value( uses_alloc_ctor< false, B >*, const A& )
: value()
{
static_assert( !std::is_reference< T >::value, "attempted to default construct a reference element in a tuple" );
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_value( uses_alloc_ctor< true, true >*, const A& a )
: value( std::allocator_arg_t(), a )
{
static_assert( !std::is_reference< T >::value, "attempted to default construct a reference element in a tuple" );
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_value( uses_alloc_ctor< true, false >*, const A& a )
: value( a )
{
static_assert( !std::is_reference< T >::value, "attempted to default construct a reference element in a tuple" );
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename U,
typename = impl::enable_if_t< !std::is_same< typename std::decay< U >::type, tuple_value >::value >,
typename = impl::enable_if_t< std::is_constructible< T, U >::value > >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON explicit tuple_value( U&& v ) noexcept( std::is_nothrow_constructible< T, U >::value )
: value( std::forward< U >( v ) )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< bool B, typename A, typename U >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_value( uses_alloc_ctor< false, B >*, const A&, U&& v )
: value( std::forward< U >( v ) )
{
// TODO: Add check for rvalue to lvalue reference
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A, typename U >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_value( uses_alloc_ctor< true, true >*, const A& a, U&& v )
: value( std::allocator_arg_t(), a, std::forward< U >( v ) )
{
// TODO: Add check for rvalue to lvalue reference
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A, typename U >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_value( uses_alloc_ctor< true, false >*, const A& a, U&& v )
: value( std::forward< U >( v ), a )
{
// TODO: Add check for rvalue to lvalue reference
}
tuple_value( const tuple_value& ) = default;
tuple_value( tuple_value&& ) = default;
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename U >
TAO_TUPLE_CUDA_ANNOTATE_COMMON tuple_value& operator=( U&& v ) noexcept( std::is_nothrow_assignable< T&, U >::value )
{
value = std::forward< U >( v );
return *this;
}
TAO_TUPLE_CUDA_ANNOTATE_COMMON
void swap( tuple_value& v ) noexcept( is_nothrow_swappable< T >::value )
{
using std::swap;
swap( value, v.value );
}
TAO_TUPLE_CONSTEXPR
TAO_TUPLE_CUDA_ANNOTATE_COMMON
T& get_value() noexcept
{
return value;
}
TAO_TUPLE_CONSTEXPR
TAO_TUPLE_CUDA_ANNOTATE_COMMON
const T& get_value() const noexcept
{
return value;
}
};
template< std::size_t I, typename T >
struct tuple_value< I, T, true >
: private T
{
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
constexpr TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_value() noexcept( std::is_nothrow_default_constructible< T >::value )
: T()
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< bool B, typename A >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_value( uses_alloc_ctor< false, B >*, const A& )
: T()
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_value( uses_alloc_ctor< true, true >*, const A& a )
: T( std::allocator_arg_t(), a )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_value( uses_alloc_ctor< true, false >*, const A& a )
: T( a )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename U,
typename = impl::enable_if_t< !std::is_same< typename std::decay< U >::type, tuple_value >::value >,
typename = impl::enable_if_t< std::is_constructible< T, U >::value > >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON explicit tuple_value( U&& v ) noexcept( std::is_nothrow_constructible< T, U >::value )
: T( std::forward< U >( v ) )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< bool B, typename A, typename U >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_value( uses_alloc_ctor< false, B >*, const A&, U&& v )
: T( std::forward< U >( v ) )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A, typename U >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_value( uses_alloc_ctor< true, true >*, const A& a, U&& v )
: T( std::allocator_arg_t(), a, std::forward< U >( v ) )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A, typename U >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_value( uses_alloc_ctor< true, false >*, const A& a, U&& v )
: T( std::forward< U >( v ), a )
{
}
tuple_value( const tuple_value& ) = default;
tuple_value( tuple_value&& ) = default;
template< typename U >
TAO_TUPLE_CUDA_ANNOTATE_COMMON tuple_value& operator=( U&& v ) noexcept( std::is_nothrow_assignable< T&, U >::value )
{
T::operator=( std::forward< U >( v ) );
return *this;
}
TAO_TUPLE_CUDA_ANNOTATE_COMMON
void swap( tuple_value& v ) noexcept( is_nothrow_swappable< T >::value )
{
using std::swap;
swap( *this, v );
}
TAO_TUPLE_CONSTEXPR
TAO_TUPLE_CUDA_ANNOTATE_COMMON
T& get_value() noexcept
{
return static_cast< T& >( *this );
}
TAO_TUPLE_CONSTEXPR
TAO_TUPLE_CUDA_ANNOTATE_COMMON
const T& get_value() const noexcept
{
return static_cast< const T& >( *this );
}
};
template< typename, typename... >
struct tuple_base;
template< std::size_t... Is, typename... Ts >
struct tuple_base< seq::index_sequence< Is... >, Ts... >
: tuple_value< Is, Ts >...
{
constexpr tuple_base() = default;
template< typename... Us >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON explicit tuple_base( Us&&... us )
: tuple_value< Is, Ts >( std::forward< Us >( us ) )...
{
}
template< typename A, typename... Us >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON tuple_base( std::allocator_arg_t, const A& a, Us&&... us )
: tuple_value< Is, Ts >( uses_alloc_ctor_t< Ts, A, Us >(), a, std::forward< Us >( us ) )...
{
}
tuple_base( const tuple_base& ) = default;
tuple_base( tuple_base&& ) = default;
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_base& operator=( const tuple_base& v ) noexcept( seq::is_all< std::is_nothrow_copy_assignable< Ts >::value... >::value )
{
#ifdef TAO_SEQ_FOLD_EXPRESSIONS
( tuple_value< Is, Ts >::operator=( static_cast< tuple_value< Is, Ts >& >( v ).get_value() ), ... );
#else
(void)swallow{ ( tuple_value< Is, Ts >::operator=( static_cast< tuple_value< Is, Ts >& >( v ).get_value() ), true )..., true };
#endif
return *this;
}
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple_base& operator=( tuple_base&& v ) noexcept( seq::is_all< std::is_nothrow_move_assignable< Ts >::value... >::value )
{
#ifdef TAO_SEQ_FOLD_EXPRESSIONS
( tuple_value< Is, Ts >::operator=( std::forward< Ts >( static_cast< tuple_value< Is, Ts >& >( v ).get_value() ) ), ... );
#else
(void)swallow{ ( tuple_value< Is, Ts >::operator=( static_cast< tuple_value< Is, Ts >& >( v ) ), true )..., true };
#endif
return *this;
}
template< typename... Us >
TAO_TUPLE_CUDA_ANNOTATE_COMMON tuple_base& operator=( const tuple< Us... >& v ) noexcept( seq::is_all< std::is_nothrow_assignable< Ts&, const Us& >::value... >::value )
{
#ifdef TAO_SEQ_FOLD_EXPRESSIONS
( tuple_value< Is, Ts >::operator=( get< Is >( v ) ), ... );
#else
(void)swallow{ ( tuple_value< Is, Ts >::operator=( get< Is >( v ) ), true )..., true };
#endif
return *this;
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename... Us >
TAO_TUPLE_CUDA_ANNOTATE_COMMON tuple_base& operator=( tuple< Us... >&& v ) noexcept( seq::is_all< std::is_nothrow_assignable< Ts&, Us&& >::value... >::value )
{
#ifdef TAO_SEQ_FOLD_EXPRESSIONS
( tuple_value< Is, Ts >::operator=( get< Is >( std::move( v ) ) ), ... );
#else
(void)swallow{ ( tuple_value< Is, Ts >::operator=( get< Is >( std::move( v ) ) ), true )..., true };
#endif
return *this;
}
TAO_TUPLE_CUDA_ANNOTATE_COMMON
void swap( tuple_base& v ) noexcept( seq::is_all< impl::is_nothrow_swappable< Ts >::value... >::value )
{
#ifdef TAO_SEQ_FOLD_EXPRESSIONS
( static_cast< tuple_value< Is, Ts >& >( *this ).swap( static_cast< tuple_value< Is, Ts >& >( v ) ), ... );
#else
(void)swallow{ ( static_cast< tuple_value< Is, Ts >& >( *this ).swap( static_cast< tuple_value< Is, Ts >& >( v ) ), true )..., true };
#endif
}
};
} // namespace impl
// 20.4.2 Class template tuple [tuple.tuple]
// tuple
template< typename... Ts >
struct tuple
{
private:
using base_t = impl::tuple_base< seq::index_sequence_for< Ts... >, Ts... >;
base_t base;
template< std::size_t I, typename... Us >
friend TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON const seq::type_by_index_t< I, Us... >& get( const tuple< Us... >& ) noexcept;
template< std::size_t I, typename... Us >
friend TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON seq::type_by_index_t< I, Us... >& get( tuple< Us... >& ) noexcept;
template< std::size_t I, typename... Us >
friend TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON seq::type_by_index_t< I, Us... >&& get( tuple< Us... >&& ) noexcept;
public:
// 20.4.2.1 Construction [tuple.cnstr]
// TODO: Move this templated condition to base?
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename dummy = void,
typename = impl::enable_if_t< seq::is_all< impl::dependent_type< std::is_default_constructible< Ts >, dummy >::value... >::value > >
TAO_TUPLE_CUDA_ANNOTATE_COMMON constexpr tuple() noexcept( seq::is_all< std::is_nothrow_default_constructible< Ts >::value... >::value )
: base()
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename dummy = void,
typename = impl::enable_if_t< seq::is_all< impl::dependent_type< std::is_copy_constructible< Ts >, dummy >::value... >::value > >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON explicit tuple( const Ts&... ts ) noexcept( seq::is_all< std::is_nothrow_copy_constructible< Ts >::value... >::value )
: base( ts... )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename... Us,
typename = impl::enable_if_t< sizeof...( Us ) == sizeof...( Ts ) >,
typename = impl::enable_if_t< seq::is_all< std::is_constructible< Ts, Us&& >::value... >::value > >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON explicit tuple( Us&&... us ) noexcept( seq::is_all< std::is_nothrow_constructible< Ts, Us&& >::value... >::value )
: base( std::forward< Us >( us )... )
{
}
tuple( const tuple& ) = default;
tuple( tuple&& ) = default;
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename... Us,
typename = impl::enable_if_t< sizeof...( Us ) == sizeof...( Ts ) >,
typename = impl::enable_if_t< seq::is_all< std::is_constructible< Ts, const Us& >::value... >::value > >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON explicit tuple( const tuple< Us... >& v ) noexcept( seq::is_all< std::is_nothrow_constructible< Ts, const Us& >::value... >::value )
: base( v )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename... Us,
typename = impl::enable_if_t< sizeof...( Us ) == sizeof...( Ts ) >,
typename = impl::enable_if_t< seq::is_all< std::is_constructible< Ts, Us&& >::value... >::value > >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON explicit tuple( tuple< Us... >&& v ) noexcept( seq::is_all< std::is_nothrow_constructible< Ts, Us&& >::value... >::value )
: base( std::move( v ) )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A,
typename dummy = void,
typename = impl::enable_if_t< seq::is_all< impl::dependent_type< std::is_default_constructible< Ts >, dummy >::value... >::value > >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple( std::allocator_arg_t, const A& a )
: base( std::allocator_arg_t(), a )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A,
typename dummy = void,
typename = impl::enable_if_t< seq::is_all< impl::dependent_type< std::is_copy_constructible< Ts >, dummy >::value... >::value > >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple( std::allocator_arg_t, const A& a, const Ts&... ts )
: base( std::allocator_arg_t(), a, ts... )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A,
typename... Us,
typename = impl::enable_if_t< sizeof...( Us ) == sizeof...( Ts ) >,
typename = impl::enable_if_t< seq::is_all< std::is_constructible< Ts, Us&& >::value... >::value > >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple( std::allocator_arg_t, const A& a, Us&&... us )
: base( std::allocator_arg_t(), a, std::forward< Us >( us )... )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple( std::allocator_arg_t, const A& a, const tuple& v )
: base( std::allocator_arg_t(), a, v )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple( std::allocator_arg_t, const A& a, tuple&& v )
: base( std::allocator_arg_t(), a, std::move( v ) )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A,
typename... Us,
typename = impl::enable_if_t< sizeof...( Us ) == sizeof...( Ts ) >,
typename = impl::enable_if_t< seq::is_all< std::is_constructible< Ts, const Us& >::value... >::value > >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple( std::allocator_arg_t, const A& a, const tuple< Us... >& v )
: base( std::allocator_arg_t(), a, v )
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A,
typename... Us,
typename = impl::enable_if_t< sizeof...( Us ) == sizeof...( Ts ) >,
typename = impl::enable_if_t< seq::is_all< std::is_constructible< Ts, Us&& >::value... >::value > >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple( std::allocator_arg_t, const A& a, tuple< Us... >&& v )
: base( std::allocator_arg_t(), a, std::move( v ) )
{
}
// 20.4.2.2 Assignment [tuple.assign]
template< typename T,
typename = impl::enable_if_t< std::is_assignable< base_t&, T >::value > >
TAO_TUPLE_CUDA_ANNOTATE_COMMON tuple& operator=( T&& v ) noexcept( std::is_nothrow_assignable< base_t&, T >::value )
{
base = std::forward< T >( v );
return *this;
}
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple& operator=( const tuple& v )
noexcept( std::is_nothrow_assignable< base_t&, tuple >::value )
{
base = v;
return *this;
}
// 20.4.2.3 swap [tuple.swap]
TAO_TUPLE_CUDA_ANNOTATE_COMMON
void swap( tuple& v ) noexcept( noexcept( base.swap( v.base ) ) )
{
base.swap( v.base );
}
};
template<>
struct tuple<>
{
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
TAO_TUPLE_CUDA_ANNOTATE_COMMON
constexpr tuple() noexcept {}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple( std::allocator_arg_t, const A& ) noexcept
{
}
TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
template< typename A >
TAO_TUPLE_CUDA_ANNOTATE_COMMON
tuple( std::allocator_arg_t, const A&, const tuple& ) noexcept
{
}
TAO_TUPLE_CUDA_ANNOTATE_COMMON
void swap( tuple& ) noexcept {}
};
// 20.4.2.4 Tuple creation functions [tuple.creation]
// ignore helper
namespace impl
{
struct ignore_t
{
template< typename U >
TAO_TUPLE_CUDA_ANNOTATE_COMMON ignore_t& operator=( U&& )
{
return *this;
}
};
} // namespace impl
// ignore
const impl::ignore_t ignore{};
// make_tuple helper
namespace impl
{
template< typename T >
struct make_tuple_return
{
using type = T;
};
template< typename T >
struct make_tuple_return< std::reference_wrapper< T > >
{
using type = T&;
};
template< typename T >
using make_tuple_return_t = typename make_tuple_return< T >::type;
} // namespace impl
// make_tuple
template< typename... Ts, typename R = tuple< impl::make_tuple_return_t< typename std::decay< Ts >::type >... > >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON R make_tuple( Ts&&... ts )
{
return R( std::forward< Ts >( ts )... );
}
// forward_as_tuple
template< typename... Ts >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON tuple< Ts&&... > forward_as_tuple( Ts&&... ts ) noexcept
{
return tuple< Ts&&... >( std::forward< Ts >( ts )... );
}
// tie
template< typename... Ts >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON tuple< Ts&... > tie( Ts&... ts ) noexcept
{
return tuple< Ts&... >( ts... );
}
// tuple_cat is found at the end, as it requires access to tuple_element_t and get<I>
// 20.4.2.5 Tuple helper classes [tuple.helper]
// tuple_size
template< typename T >
struct tuple_size;
template< typename T >
struct tuple_size< const T >
: tuple_size< T >
{
};
template< typename T >
struct tuple_size< volatile T >
: tuple_size< T >
{
};
template< typename T >
struct tuple_size< const volatile T >
: tuple_size< T >
{
};
template< typename... Ts >
struct tuple_size< tuple< Ts... > >
: std::integral_constant< std::size_t, sizeof...( Ts ) >
{
};
// tuple_element
template< std::size_t I, typename T >
struct tuple_element;
template< std::size_t I, typename T >
struct tuple_element< I, const T >
: tuple_element< I, T >
{
};
template< std::size_t I, typename T >
struct tuple_element< I, volatile T >
: tuple_element< I, T >
{
};
template< std::size_t I, typename T >
struct tuple_element< I, const volatile T >
: tuple_element< I, T >
{
};
template< std::size_t I, typename... Ts >
struct tuple_element< I, tuple< Ts... > >
: seq::type_by_index< I, Ts... >
{
};
#if __cplusplus >= 201402L
template< std::size_t I, typename T >
using tuple_element_t = typename tuple_element< I, T >::type;
#endif
// 20.4.2.6 Element access [tuple.elem]
// get<I>
template< std::size_t I, typename... Ts >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON const seq::type_by_index_t< I, Ts... >& get( const tuple< Ts... >& v ) noexcept
{
return static_cast< const impl::tuple_value< I, seq::type_by_index_t< I, Ts... > >& >( v.base ).get_value();
}
template< std::size_t I, typename... Ts >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON seq::type_by_index_t< I, Ts... >& get( tuple< Ts... >& v ) noexcept
{
return static_cast< impl::tuple_value< I, seq::type_by_index_t< I, Ts... > >& >( v.base ).get_value();
}
template< std::size_t I, typename... Ts >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON seq::type_by_index_t< I, Ts... >&& get( tuple< Ts... >&& v ) noexcept
{
using type = seq::type_by_index_t< I, Ts... >;
return static_cast< type&& >( static_cast< impl::tuple_value< I, type >& >( v.base ).get_value() );
}
// get<T> helper
namespace impl
{
template< typename T, typename... Ts >
using count_of = seq::sum< std::size_t, ( std::is_same< T, Ts >::value ? 1 : 0 )... >;
template< typename, typename, typename... >
struct index_of_impl;
template< std::size_t... Is, typename T, typename... Ts >
struct index_of_impl< seq::index_sequence< Is... >, T, Ts... >
: seq::sum< std::size_t, ( std::is_same< T, Ts >::value ? Is : 0 )... >
{
static_assert( count_of< T, Ts... >::value > 0, "T not found within Ts..." );
static_assert( count_of< T, Ts... >::value < 2, "T must be unique within Ts..." );
};
template< typename T, typename... Ts >
using index_of = index_of_impl< seq::index_sequence_for< Ts... >, T, Ts... >;
} // namespace impl
// get<T>
template< typename T, typename... Ts >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON const T& get( const tuple< Ts... >& v ) noexcept
{
return get< impl::index_of< T, Ts... >::value >( v );
}
template< typename T, typename... Ts >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON T& get( tuple< Ts... >& v ) noexcept
{
return get< impl::index_of< T, Ts... >::value >( v );
}
template< typename T, typename... Ts >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON T&& get( tuple< Ts... >&& v ) noexcept
{
return get< impl::index_of< T, Ts... >::value >( std::move( v ) );
}
// 20.4.2.7 Relational operators [tuple.rel]
// operators helper
// here, recursion seems to be the better choice, especially wrt constexpr
namespace impl
{
template< std::size_t I, std::size_t S >
struct tuple_equal;
template< std::size_t I >
struct tuple_equal< I, I >
{
template< typename T, typename U >
static TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON bool apply( const T&, const U& ) noexcept
{
return true;
}
};
template< std::size_t I, std::size_t S >
struct tuple_equal
{
template< typename T, typename U >
static TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON bool apply( const T& lhs, const U& rhs ) noexcept( noexcept( static_cast< bool >( get< I >( lhs ) == get< I >( rhs ) ) && tuple_equal< I + 1, S >::apply( lhs, rhs ) ) )
{
return static_cast< bool >( get< I >( lhs ) == get< I >( rhs ) ) && tuple_equal< I + 1, S >::apply( lhs, rhs );
}
};
template< std::size_t I, std::size_t S >
struct tuple_less;
template< std::size_t I >
struct tuple_less< I, I >
{
template< typename T, typename U >
static TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON bool apply( const T&, const U& ) noexcept
{
return false;
}
};
template< std::size_t I, std::size_t S >
struct tuple_less
{
template< typename T, typename U >
static TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON bool apply( const T& lhs, const U& rhs ) noexcept( noexcept( static_cast< bool >( get< I >( lhs ) < get< I >( rhs ) ) || ( !static_cast< bool >( get< I >( rhs ) < get< I >( lhs ) ) && tuple_less< I + 1, S >::apply( lhs, rhs ) ) ) )
{
return static_cast< bool >( get< I >( lhs ) < get< I >( rhs ) ) || ( !static_cast< bool >( get< I >( rhs ) < get< I >( lhs ) ) && tuple_less< I + 1, S >::apply( lhs, rhs ) );
}
};
} // namespace impl
// operators
template< typename... Ts, typename... Us, typename = impl::enable_if_t< sizeof...( Ts ) == sizeof...( Us ) > >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON bool operator==( const tuple< Ts... >& lhs, const tuple< Us... >& rhs ) noexcept( noexcept( impl::tuple_equal< 0, sizeof...( Ts ) >::apply( lhs, rhs ) ) )
{
return impl::tuple_equal< 0, sizeof...( Ts ) >::apply( lhs, rhs );
}
template< typename... Ts, typename... Us >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON bool operator!=( const tuple< Ts... >& lhs, const tuple< Us... >& rhs ) noexcept( noexcept( !( lhs == rhs ) ) )
{
return !( lhs == rhs );
}
template< typename... Ts, typename... Us, typename = impl::enable_if_t< sizeof...( Ts ) == sizeof...( Us ) > >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON bool operator<( const tuple< Ts... >& lhs, const tuple< Us... >& rhs ) noexcept( noexcept( impl::tuple_less< 0, sizeof...( Ts ) >::apply( lhs, rhs ) ) )
{
return impl::tuple_less< 0, sizeof...( Ts ) >::apply( lhs, rhs );
}
template< typename... Ts, typename... Us >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON bool operator>=( const tuple< Ts... >& lhs, const tuple< Us... >& rhs ) noexcept( noexcept( !( lhs < rhs ) ) )
{
return !( lhs < rhs );
}
template< typename... Ts, typename... Us >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON bool operator>( const tuple< Ts... >& lhs, const tuple< Us... >& rhs ) noexcept( noexcept( rhs < lhs ) )
{
return rhs < lhs;
}
template< typename... Ts, typename... Us >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON bool operator<=( const tuple< Ts... >& lhs, const tuple< Us... >& rhs ) noexcept( noexcept( !( rhs < lhs ) ) )
{
return !( rhs < lhs );
}
// 20.4.2.9 Tuple specialized algorithms [tuple.special]
// swap
template< typename... Ts >
TAO_TUPLE_CUDA_ANNOTATE_COMMON void swap( tuple< Ts... >& lhs, tuple< Ts... >& rhs ) noexcept( noexcept( lhs.swap( rhs ) ) )
{
lhs.swap( rhs );
}
// (continued:) 20.4.2.4 Tuple creation functions [tuple.creation]
// tuple_cat helper
namespace impl
{
template< std::size_t M, std::size_t... Ns >
struct count_less_or_equal
: seq::sum< std::size_t, ( ( Ns <= M ) ? 1 : 0 )... >
{
};
template< typename, typename >
struct expand;
template< std::size_t... Is, std::size_t... Ns >
struct expand< seq::index_sequence< Is... >, seq::index_sequence< Ns... > >
{
using type = seq::index_sequence< count_less_or_equal< Is, Ns... >::value... >;
};
template< typename I, typename S >
using expand_t = typename expand< I, S >::type;
template< typename... >
struct tuple_cat_result;
template< std::size_t... Os, std::size_t... Is, typename... Ts >
struct tuple_cat_result< seq::index_sequence< Os... >, seq::index_sequence< Is... >, Ts... >
{
using type = tuple< typename tuple_element< Is, seq::type_by_index_t< Os, Ts... > >::type... >;
};
template< typename... Ts >
using tuple_cat_result_t = typename tuple_cat_result< Ts... >::type;
template< typename... Ts >
struct tuple_cat_helper
{
using tuple_size_sequence = seq::index_sequence< tuple_size< Ts >::value... >;
using result_index_sequence = seq::make_index_sequence< seq::sum< tuple_size_sequence >::value >;
using outer_index_sequence = expand_t< result_index_sequence, seq::inclusive_scan_t< tuple_size_sequence > >;
using inner_index_sequence = seq::minus_t< result_index_sequence, seq::map_t< outer_index_sequence, seq::exclusive_scan_t< tuple_size_sequence > > >;
using result_type = tuple_cat_result_t< outer_index_sequence, inner_index_sequence, Ts... >;
};
template< typename R, std::size_t... Os, std::size_t... Is, typename T >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON R tuple_cat( seq::index_sequence< Os... >, seq::index_sequence< Is... >, T v )
{
return R( get< Is >( get< Os >( v ) )... );
}
} // namespace impl
// tuple_cat
template< typename... Ts, typename H = impl::tuple_cat_helper< typename std::remove_reference< Ts >::type... >, typename R = typename H::result_type >
TAO_TUPLE_CONSTEXPR TAO_TUPLE_CUDA_ANNOTATE_COMMON R tuple_cat( Ts&&... ts )
{
return impl::tuple_cat< R >( typename H::outer_index_sequence(), typename H::inner_index_sequence(), tao::forward_as_tuple( std::forward< Ts >( ts )... ) );
}
} // namespace tao
#undef TAO_TUPLE_CONSTEXPR
#undef TAO_TUPLE_CUDA_ANNOTATE_COMMON
#undef TAO_TUPLE_SUPPRESS_NVCC_HD_WARN
#endif