// TR2 <type_traits> -*- C++ -*-

// Copyright (C) 2011-2023 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, 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 General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file tr2/type_traits
 *  This is a TR2 C++ Library header.
 */

#ifndef _GLIBCXX_TR2_TYPE_TRAITS
#define _GLIBCXX_TR2_TYPE_TRAITS 1

#pragma GCC system_header
#include <type_traits>
#include <bits/c++config.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

namespace tr2
{
  /**
   * @addtogroup metaprogramming
   * @{
   */

  /**
   *  See N2965: Type traits and base classes
   *  by Michael Spertus
   */

  /**
   *  Simple typelist. Compile-time list of types.
   */
  template<typename... _Elements>
    struct __reflection_typelist;

  /// Specialization for an empty typelist.
  template<>
    struct __reflection_typelist<>
    {
      typedef std::true_type					empty;
    };

  /// Partial specialization.
  template<typename _First, typename... _Rest>
    struct __reflection_typelist<_First, _Rest...>
    {
      typedef std::false_type					empty;

      struct first
      {
	typedef _First						type;
      };

      struct rest
      {
	typedef __reflection_typelist<_Rest...>			type;
      };
    };

  /// Sequence abstraction metafunctions for manipulating a typelist.


#if __has_builtin(__bases)
  /// Enumerate all the base classes of a class. Form of a typelist.
  template<typename _Tp>
    struct bases
    {
      typedef __reflection_typelist<__bases(_Tp)...>		type;
    };
#endif

#if __has_builtin(__direct_bases)
  /// Enumerate all the direct base classes of a class. Form of a typelist.
  template<typename _Tp>
    struct direct_bases
    {
      typedef __reflection_typelist<__direct_bases(_Tp)...>	type;
    };
#endif

  /// @} group metaprogramming
}

_GLIBCXX_END_NAMESPACE_VERSION
}

#endif // _GLIBCXX_TR2_TYPE_TRAITS
