This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Intrinsics for N2965: Type traits and base classes


> OK. Here is a new diff that hopefully takes into account all of
> Jason's and Benjamin's comments. Benjamin's TR2 build patch is not
> repeated (or tested!) here. Benjamin, I'd really appreciate if you
> wouldn't mind confirming I handled that correctly in tr2/type_traits
> (Including the inclusion of std/type_traits).

Hey! Here is a preliminary test suite. Just the basics on this one.
There's a bit of an issue with fundamental types, ICEs, but seems
fixable.

From here on in, just populate the testsuite/tr2/* directories with .cc
files. They will be tested by the testsuite machinery.

Your typelist interface looks pretty good. We should start here for the
interface, and can embellish it after it goes in.

-benjamin
diff --git a/libstdc++-v3/include/tr2/type_traits b/libstdc++-v3/include/tr2/type_traits
new file mode 100644
index 0000000..94aebf0
--- /dev/null
+++ b/libstdc++-v3/include/tr2/type_traits
@@ -0,0 +1,102 @@
+// TR2 type_traits -*- C++ -*-
+
+// Copyright (C) 2011 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)
+{
+namespace tr2
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   * @defgroup metaprogramming Type Traits
+   * @ingroup utilities
+   *
+   * Compile time type transformation and information.
+   * @{
+   */
+
+  template<typename... _Elements> 
+    struct typelist;
+
+  template<>
+    struct typelist<>
+    {
+      typedef std::true_type 			empty;
+    };
+
+  template<typename _First, typename... _Rest>
+    struct typelist<_First, _Rest...>
+    {
+      typedef std::false_type 			empty;
+
+      struct first
+      {
+	typedef _First 				type;
+      };
+
+      struct rest
+      {
+	typedef typelist<_Rest...> 		type;
+      };
+    };
+
+  // Sequence abstraction metafunctions default to looking in the type
+  template<typename _Tp>
+    struct first : public _Tp::first { };
+
+  template<typename _Tp>
+    struct rest : public _Tp::rest { };
+
+  template<typename _Tp>
+    struct empty : public _Tp::empty { };
+
+
+  template<typename _Tp>
+    struct bases
+    {
+      typedef typelist<__bases(_Tp)...> 	type;
+    };
+
+  template<typename _Tp>
+    struct direct_bases
+    {
+      typedef typelist<__direct_bases(_Tp)...> 	type;
+    };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+}
+
+#endif // _GLIBCXX_TR2_TYPE_TRAITS
diff --git a/libstdc++-v3/scripts/create_testsuite_files b/libstdc++-v3/scripts/create_testsuite_files
index f4a0bcd..a427eef 100755
--- a/libstdc++-v3/scripts/create_testsuite_files
+++ b/libstdc++-v3/scripts/create_testsuite_files
@@ -32,7 +32,7 @@ cd $srcdir
 # This is the ugly version of "everything but the current directory".  It's
 # what has to happen when find(1) doesn't support -mindepth, or -xtype.
 dlist=`echo [0-9][0-9]*`
-dlist="$dlist abi backward ext performance tr1 decimal"
+dlist="$dlist abi backward ext performance tr1 tr2 decimal"
 find $dlist "(" -type f -o -type l ")" -name "*.cc" -print > $tmp.01
 find $dlist "(" -type f -o -type l ")" -name "*.c" -print > $tmp.02
 cat  $tmp.01 $tmp.02 | sort > $tmp.1
diff --git a/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp b/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp
index 8642eb7..19fa0e2 100644
--- a/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp
+++ b/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp
@@ -58,6 +58,7 @@ if {[info exists tests_file] && [file exists $tests_file]} {
     lappend subdirs "$srcdir/ext"
     lappend subdirs "$srcdir/performance"
     lappend subdirs "$srcdir/tr1"
+    lappend subdirs "$srcdir/tr2"
     lappend subdirs "$srcdir/decimal"
     verbose "subdirs are $subdirs"
 
diff --git a/libstdc++-v3/testsuite/tr2/bases/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/tr2/bases/requirements/explicit_instantiation.cc
new file mode 100644
index 0000000..ddd6d6f
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr2/bases/requirements/explicit_instantiation.cc
@@ -0,0 +1,32 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2011 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <tr2/type_traits>
+
+namespace std
+{
+  namespace tr2
+  {
+    typedef short test_type;
+    template struct bases<test_type>;
+  }
+}
diff --git a/libstdc++-v3/testsuite/tr2/bases/requirements/typedefs.cc b/libstdc++-v3/testsuite/tr2/bases/requirements/typedefs.cc
new file mode 100644
index 0000000..a62acff
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr2/bases/requirements/typedefs.cc
@@ -0,0 +1,31 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2011 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 
+// NB: This file is for testing tr1/type_traits with NO OTHER INCLUDES.
+
+#include <tr2/type_traits>
+
+void test01()
+{
+  // Check for required typedefs
+  typedef std::tr2::bases<int>            test_type;
+  typedef test_type::type            value_type;
+}
diff --git a/libstdc++-v3/testsuite/tr2/bases/value.cc b/libstdc++-v3/testsuite/tr2/bases/value.cc
new file mode 100644
index 0000000..415e974
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr2/bases/value.cc
@@ -0,0 +1,97 @@
+// { dg-options "-std=gnu++0x" }
+//
+// Copyright (C) 2011 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <tr2/type_traits>
+#include <typeinfo>
+#include <stdexcept>
+
+struct A { };
+struct B1 : virtual public A { };
+struct B2 : virtual public A { };
+struct C : public B1, public B2 { };
+
+void test()
+{
+  bool test __attribute__((unused)) = true;
+
+  // 1
+  {
+    typedef std::tr2::bases<A>::type tl;
+    static_assert(tl::empty::value, "error");
+  }
+
+  // 2
+  {
+    typedef std::tr2::bases<B1>::type tl1;
+    typedef std::tr2::bases<B2>::type tl2;
+
+    // Sanity check w/ runtime.
+    bool eq = typeid(tl1) == typeid(tl2);
+    if (!eq)
+      throw std::logic_error("typelist not equal");
+
+    // Sanity check.
+    static_assert(tl1::empty::value != std::true_type::value, "!empty");
+    static_assert(tl2::empty::value != std::true_type::value, "!empty");
+
+    typedef tl1::first::type		tl1_first;
+    typedef tl1::rest::type		tl1_rest;
+    typedef tl2::first::type		tl2_first;
+    typedef tl2::rest::type		tl2_rest;
+
+    eq = typeid(tl1_first) == typeid(tl2_first);
+    if (!eq)
+      throw std::logic_error("base not equal");
+
+    static_assert(tl1_rest::empty::value == std::true_type::value, "empty");
+    static_assert(tl2_rest::empty::value == std::true_type::value, "empty");
+  }
+
+  // 3
+  {
+    typedef std::tr2::bases<C>::type tl;
+
+    // Sanity check.
+    static_assert(tl::empty::value != std::true_type::value, "!empty");
+  
+    typedef tl::first::type		tl1_first;
+    typedef tl::rest::type		tl2;
+    typedef tl2::first::type		tl2_first;
+    typedef tl2::rest::type		tl3;
+    typedef tl3::first::type		tl3_first;
+    typedef tl3::rest::type		tl4;
+
+    bool eq = typeid(tl1_first) == typeid(tl2_first);
+    if (eq)
+      throw std::logic_error("bases are not equal");
+
+    eq = typeid(tl2_first) == typeid(tl3_first);
+    if (eq)
+      throw std::logic_error("bases are not equal");
+
+    static_assert(tl4::empty::value == std::true_type::value, "empty");
+  }
+
+}
+
+int main()
+{
+  test();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/tr2/direct_bases/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/tr2/direct_bases/requirements/explicit_instantiation.cc
new file mode 100644
index 0000000..d7fb96a
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr2/direct_bases/requirements/explicit_instantiation.cc
@@ -0,0 +1,32 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2011 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <tr2/type_traits>
+
+namespace std
+{
+  namespace tr2
+  {
+    typedef short test_type;
+    template struct direct_bases<test_type>;
+  }
+}
diff --git a/libstdc++-v3/testsuite/tr2/direct_bases/requirements/typedefs.cc b/libstdc++-v3/testsuite/tr2/direct_bases/requirements/typedefs.cc
new file mode 100644
index 0000000..7d219ea
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr2/direct_bases/requirements/typedefs.cc
@@ -0,0 +1,31 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2011 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 
+// NB: This file is for testing tr1/type_traits with NO OTHER INCLUDES.
+
+#include <tr2/type_traits>
+
+void test01()
+{
+  // Check for required typedefs
+  typedef std::tr2::direct_bases<int>            test_type;
+  typedef test_type::type            value_type;
+}
diff --git a/libstdc++-v3/testsuite/tr2/direct_bases/value.cc b/libstdc++-v3/testsuite/tr2/direct_bases/value.cc
new file mode 100644
index 0000000..81d0269
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr2/direct_bases/value.cc
@@ -0,0 +1,91 @@
+// { dg-options "-std=gnu++0x" }
+//
+// Copyright (C) 2011 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <tr2/type_traits>
+#include <typeinfo>
+#include <stdexcept>
+
+struct A { };
+struct B1 : virtual public A { };
+struct B2 : virtual public A { };
+struct C : public B1, public B2 { };
+
+void test()
+{
+  bool test __attribute__((unused)) = true;
+
+  // 1
+  {
+    typedef std::tr2::direct_bases<A>::type tl;
+    static_assert(tl::empty::value, "error");
+  }
+
+  // 2
+  {
+    typedef std::tr2::direct_bases<B1>::type tl1;
+    typedef std::tr2::direct_bases<B2>::type tl2;
+
+    // Sanity check w/ runtime.
+    bool eq = typeid(tl1) == typeid(tl2);
+    if (!eq)
+      throw std::logic_error("typelist not equal");
+
+    // Sanity check.
+    static_assert(tl1::empty::value != std::true_type::value, "!empty");
+    static_assert(tl2::empty::value != std::true_type::value, "!empty");
+
+    typedef tl1::first::type		tl1_first;
+    typedef tl1::rest::type		tl1_rest;
+    typedef tl2::first::type		tl2_first;
+    typedef tl2::rest::type		tl2_rest;
+
+    eq = typeid(tl1_first) == typeid(tl2_first);
+    if (!eq)
+      throw std::logic_error("base not equal");
+
+    static_assert(tl1_rest::empty::value == std::true_type::value, "empty");
+    static_assert(tl2_rest::empty::value == std::true_type::value, "empty");
+  }
+
+  // 3
+  {
+    typedef std::tr2::direct_bases<C>::type tl;
+
+    // Sanity check.
+    static_assert(tl::empty::value != std::true_type::value, "!empty");
+  
+    typedef tl::first::type		tl1_first;
+    typedef tl::rest::type		tl2;
+    typedef tl2::first::type		tl2_first;
+    typedef tl2::rest::type		tl3;
+
+    bool eq = typeid(tl1_first) == typeid(tl2_first);
+    if (eq)
+      throw std::logic_error("bases are not equal");
+
+    static_assert(tl3::empty::value == std::true_type::value, "empty");
+  }
+
+}
+
+int main()
+{
+  test();
+  return 0;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]