/* * Copyright (c) 2018 Jaroslav Jindrak * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LIBCPP_TUPLE_CAT #define LIBCPP_TUPLE_CAT #include namespace std { // forward declarations template struct tuple; template struct tuple_element; template constexpr typename tuple_element>::type& get(tuple& tpl) noexcept; template struct integer_sequence; template using index_sequence = integer_sequence; } namespace std::aux { template struct tuple_append; template struct tuple_append, tuple, Vs...> : type_is> { /* DUMMY BODY */ }; template using tuple_append_t = typename tuple_append::type; template struct remove_first_tuple; template struct remove_first_tuple, Tuples...> : type_is { /* DUMMY BODY */ }; template using remove_first_tuple_t = typename remove_first_tuple::type; template struct get_first_tuple; template struct get_first_tuple, Tuples...> : type_is> { /* DUMMY BODY */ }; template using get_first_tuple_t = typename get_first_tuple::type; template struct tuple_cat_type_impl; template struct tuple_cat_type_impl, Tuples...> : type_is< typename tuple_cat_type_impl< tuple_append_t, get_first_tuple_t>, remove_first_tuple_t >::type > { /* DUMMY BODY */ }; template using tuple_cat_type_impl_t = typename tuple_cat_type_impl::type; template struct tuple_cat_type; template struct tuple_cat_type, Tuples...> : type_is, Tuples...>> { /* DUMMY BODY */ }; template using tuple_cat_type_t = typename tuple_cat_type::type; template struct concatenate_sequences; template struct concatenate_sequences, index_sequence> : type_is> { /* DUMMY BODY */ }; template using concatenate_sequences_t = typename concatenate_sequences::type; template struct append_indices; template struct append_indices, tuple, Tuples...> : append_indices< concatenate_sequences_t< index_sequence, make_index_sequence >, Tuples... > { /* DUMMY BODY */ }; template using append_indices_t = typename append_indices::types; template struct generate_indices; template struct generate_indices, Tuples...> : type_is< append_indices_t< make_index_sequence, Tuples... > > { /* DUMMY BODY */ }; template using generate_indices_t = typename generate_indices::type; template tuple_cat_type_t tuple_cat(Tuples&&... tpls, index_sequence, index_sequence) { return tuple_cat_type_t{ get( get( forward(tpls) ) )... }; } } #endif