diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 4de8634dc4200be705d4bb4bae40bcd5f4eb115f..b79cee21fd088c0067e8e78230bc3d26d5e2c021 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,21 @@
+2004-12-12  Paolo Carlini  <pcarlini@suse.de>
+
+	* include/tr1/type_traits: Implement is_pointer, remove_pointer,
+	and add_pointer; reformat. 
+	(_DEFINE_PRIMARY_SPEC_HELPER, _DEFINE_PRIMARY_SPEC): Generalize
+	and rename to _DEFINE_SPEC_HELPER and _DEFINE_SPEC; update uses.
+	* testsuite/tr1/4_metaprogramming/pointer_modifications/
+	add_pointer.cc: New.
+	* testsuite/tr1/4_metaprogramming/pointer_modifications/
+	remove_pointer.cc: Likewise.
+	* testsuite/tr1/4_metaprogramming/primary_type_categories/
+	is_pointer/is_pointer.cc: Likewise.
+	* testsuite/tr1/4_metaprogramming/primary_type_categories/
+	is_pointer/typedefs.cc: Likewise.
+
+	* testsuite/tr1/4_metaprogramming/primary_type_categories/
+	is_reference/is_reference.cc: Slightly tweak consistently.
+
 2004-12-11  Paolo Carlini  <pcarlini@suse.de>
 
 	* include/tr1/type_traits: Implement rank.
diff --git a/libstdc++-v3/include/tr1/type_traits b/libstdc++-v3/include/tr1/type_traits
index 5e16637e46d7a22f20d6ed51d0be73d821f7cbae..6fef185b5b397d0894510dc52cf327cf20ab76b5 100644
--- a/libstdc++-v3/include/tr1/type_traits
+++ b/libstdc++-v3/include/tr1/type_traits
@@ -43,49 +43,49 @@ namespace tr1
     };
   typedef integral_constant<bool, true>     true_type;
   typedef integral_constant<bool, false>    false_type;
-  
-#define _DEFINE_PRIMARY_SPEC_HELPER(_Primary, _Type)           \
-  template<>                                                   \
-    struct _Primary<_Type>                                     \
-    : public true_type { };                            
-
-#define _DEFINE_PRIMARY_SPEC(_Primary, _Type)                  \
-  _DEFINE_PRIMARY_SPEC_HELPER(_Primary, _Type)                 \
-  _DEFINE_PRIMARY_SPEC_HELPER(_Primary, _Type const)           \
-  _DEFINE_PRIMARY_SPEC_HELPER(_Primary, _Type volatile)        \
-  _DEFINE_PRIMARY_SPEC_HELPER(_Primary, _Type const volatile)
-  
+
+#define _DEFINE_SPEC_HELPER(_Header, _Spec)                      \
+  template _Header                                               \
+    struct _Spec                                                 \
+    : public true_type { };
+      
+#define _DEFINE_SPEC(_Header, _Primary, _Type)                   \
+  _DEFINE_SPEC_HELPER(_Header, _Primary<_Type>)                  \
+  _DEFINE_SPEC_HELPER(_Header, _Primary<_Type const>)            \
+  _DEFINE_SPEC_HELPER(_Header, _Primary<_Type volatile>)         \
+  _DEFINE_SPEC_HELPER(_Header, _Primary<_Type const volatile>)
+
   /// @brief  primary type categories [4.5.1].
   template<typename>
     struct is_void
     : public false_type { };
-  _DEFINE_PRIMARY_SPEC(is_void, void)
+  _DEFINE_SPEC(<>, is_void, void)
 
   template<typename>
     struct is_integral
     : public false_type { };
-  _DEFINE_PRIMARY_SPEC(is_integral, bool)
-  _DEFINE_PRIMARY_SPEC(is_integral, char)
-  _DEFINE_PRIMARY_SPEC(is_integral, signed char)
-  _DEFINE_PRIMARY_SPEC(is_integral, unsigned char)
+  _DEFINE_SPEC(<>, is_integral, bool)
+  _DEFINE_SPEC(<>, is_integral, char)
+  _DEFINE_SPEC(<>, is_integral, signed char)
+  _DEFINE_SPEC(<>, is_integral, unsigned char)
 #ifdef _GLIBCXX_USE_WCHAR_T
-  _DEFINE_PRIMARY_SPEC(is_integral, wchar_t)
+  _DEFINE_SPEC(<>, is_integral, wchar_t)
 #endif
-  _DEFINE_PRIMARY_SPEC(is_integral, short)
-  _DEFINE_PRIMARY_SPEC(is_integral, unsigned short)
-  _DEFINE_PRIMARY_SPEC(is_integral, int)
-  _DEFINE_PRIMARY_SPEC(is_integral, unsigned int)
-  _DEFINE_PRIMARY_SPEC(is_integral, long)
-  _DEFINE_PRIMARY_SPEC(is_integral, unsigned long)
-  _DEFINE_PRIMARY_SPEC(is_integral, long long)
-  _DEFINE_PRIMARY_SPEC(is_integral, unsigned long long)
+  _DEFINE_SPEC(<>, is_integral, short)
+  _DEFINE_SPEC(<>, is_integral, unsigned short)
+  _DEFINE_SPEC(<>, is_integral, int)
+  _DEFINE_SPEC(<>, is_integral, unsigned int)
+  _DEFINE_SPEC(<>, is_integral, long)
+  _DEFINE_SPEC(<>, is_integral, unsigned long)
+  _DEFINE_SPEC(<>, is_integral, long long)
+  _DEFINE_SPEC(<>, is_integral, unsigned long long)
 
   template<typename>
     struct is_floating_point
     : public false_type { };
-  _DEFINE_PRIMARY_SPEC(is_floating_point, float)
-  _DEFINE_PRIMARY_SPEC(is_floating_point, double)
-  _DEFINE_PRIMARY_SPEC(is_floating_point, long double)
+  _DEFINE_SPEC(<>, is_floating_point, float)
+  _DEFINE_SPEC(<>, is_floating_point, double)
+  _DEFINE_SPEC(<>, is_floating_point, long double)
 
   template<typename>
     struct is_array
@@ -99,9 +99,11 @@ namespace tr1
     struct is_array<_Tp[]>
     : public true_type { };
   
-  template<typename _Tp>
-    struct is_pointer;
-  
+  template<typename>
+    struct is_pointer
+    : public false_type { };
+  _DEFINE_SPEC(<typename _Tp>, is_pointer, _Tp*)
+ 
   template<typename>
     struct is_reference
     : public false_type { };
@@ -128,9 +130,6 @@ namespace tr1
   template<typename _Tp>
     struct is_function;
 
-#undef _DEFINE_PRIMARY_SPEC_HELPER
-#undef _DEFINE_PRIMARY_SPEC
-
   /// @brief  composite type traits [4.5.2].
   template<typename _Tp>
     struct is_arithmetic
@@ -266,27 +265,19 @@ namespace tr1
   /// @brief  const-volatile modifications [4.7.1].
   template<typename _Tp>
     struct remove_const
-    {
-      typedef _Tp     type;
-    };
+    { typedef _Tp     type; };
 
   template<typename _Tp>
     struct remove_const<_Tp const>
-    {
-      typedef _Tp     type;
-    };
+    { typedef _Tp     type; };
   
   template<typename _Tp>
     struct remove_volatile
-    {
-      typedef _Tp     type;
-    };
+    { typedef _Tp     type; };
 
   template<typename _Tp>
     struct remove_volatile<_Tp volatile>
-    {
-      typedef _Tp     type;
-    };
+    { typedef _Tp     type; };
   
   template<typename _Tp>
     struct remove_cv
@@ -307,75 +298,68 @@ namespace tr1
   /// @brief  reference modifications [4.7.2].
   template<typename _Tp>
     struct remove_reference
-    {
-      typedef _Tp     type;
-    };
+    { typedef _Tp     type; };
 
   template<typename _Tp>
     struct remove_reference<_Tp&>
-    {
-      typedef _Tp     type;
-    };
+    { typedef _Tp     type; };
   
   template<typename _Tp>
     struct add_reference
-    {
-      typedef _Tp&    type;
-    };
+    { typedef _Tp&    type; };
 
   template<typename _Tp>
     struct add_reference<_Tp&>
-    {
-      typedef _Tp&    type;
-    };
+    { typedef _Tp&    type; };
 
   /// @brief  array modififications [4.7.3].
   template<typename _Tp>
     struct remove_extent
-    {
-      typedef _Tp     type;
-    };
+    { typedef _Tp     type; };
 
   template<typename _Tp, std::size_t _Size>
     struct remove_extent<_Tp[_Size]>
-    {
-      typedef _Tp     type;
-    };
+    { typedef _Tp     type; };
 
   template<typename _Tp>
     struct remove_extent<_Tp[]>
-    {
-      typedef _Tp     type;
-    };
+    { typedef _Tp     type; };
 
   template<typename _Tp>
     struct remove_all_extents
-    {
-      typedef _Tp     type;
-    };
+    { typedef _Tp     type; };
 
   template<typename _Tp, std::size_t _Size>
     struct remove_all_extents<_Tp[_Size]>
-    {
-      typedef typename remove_all_extents<_Tp>::type   type;
-    };
+    { typedef typename remove_all_extents<_Tp>::type     type; };
 
   template<typename _Tp>
     struct remove_all_extents<_Tp[]>
-    {
-      typedef typename remove_all_extents<_Tp>::type   type;
-    };
+    { typedef typename remove_all_extents<_Tp>::type     type; };
 
   /// @brief  pointer modifications [4.7.4].
+#undef _DEFINE_SPEC_HELPER
+#define _DEFINE_SPEC_HELPER(_Header, _Spec)                      \
+  template _Header                                               \
+    struct _Spec                                                 \
+    { typedef _Tp     type; };
+
   template<typename _Tp>
-    struct remove_pointer;
+    struct remove_pointer
+    { typedef _Tp     type; };
+  _DEFINE_SPEC(<typename _Tp>, remove_pointer, _Tp*)
   
   template<typename _Tp>
-    struct add_pointer;
+    struct add_pointer
+    { typedef typename remove_reference<_Tp>::type*     type; };
 
   /// @brief  other transformations [4.8].
   template<std::size_t _Len, std::size_t _Align>
     struct aligned_storage;
+
+#undef _DEFINE_SPEC_HELPER
+#undef _DEFINE_SPEC
+
 }
 }
 
diff --git a/libstdc++-v3/testsuite/tr1/4_metaprogramming/pointer_modifications/add_pointer.cc b/libstdc++-v3/testsuite/tr1/4_metaprogramming/pointer_modifications/add_pointer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..71d1719de9949ee517ebb5a7a5a28c2164711c4a
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr1/4_metaprogramming/pointer_modifications/add_pointer.cc
@@ -0,0 +1,46 @@
+// 2004-12-12  Paolo Carlini  <pcarlini@suse.de>
+//
+// Copyright (C) 2004 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 2, 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 COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 4.7.2 Reference modifications
+
+#include <tr1/type_traits>
+#include <testsuite_hooks.h>
+#include <testsuite_tr1.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using std::tr1::add_pointer;
+  using std::tr1::is_same;
+  using namespace __gnu_test;
+
+  VERIFY( (is_same<add_pointer<int>::type, int*>::value) );
+  VERIFY( (is_same<add_pointer<int*>::type, int**>::value) );
+  VERIFY( (is_same<add_pointer<const int>::type, const int*>::value) );
+  VERIFY( (is_same<add_pointer<int&>::type, int*>::value) );
+  VERIFY( (is_same<add_pointer<ClassType*>::type, ClassType**>::value) );
+  VERIFY( (is_same<add_pointer<ClassType>::type, ClassType*>::value) );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/tr1/4_metaprogramming/pointer_modifications/remove_pointer.cc b/libstdc++-v3/testsuite/tr1/4_metaprogramming/pointer_modifications/remove_pointer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b3ba25bd324b60f601a45f5edba713001d5f3cc2
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr1/4_metaprogramming/pointer_modifications/remove_pointer.cc
@@ -0,0 +1,46 @@
+// 2004-12-12  Paolo Carlini  <pcarlini@suse.de>
+//
+// Copyright (C) 2004 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 2, 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 COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 4.7.2 Reference modifications
+
+#include <tr1/type_traits>
+#include <testsuite_hooks.h>
+#include <testsuite_tr1.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using std::tr1::remove_pointer;
+  using std::tr1::is_same;
+  using namespace __gnu_test;
+
+  VERIFY( (is_same<remove_pointer<int*>::type, int>::value) );
+  VERIFY( (is_same<remove_pointer<int>::type, int>::value) );
+  VERIFY( (is_same<remove_pointer<const int*>::type, const int>::value) );
+  VERIFY( (is_same<remove_pointer<int**>::type, int*>::value) );
+  VERIFY( (is_same<remove_pointer<ClassType*>::type, ClassType>::value) );
+  VERIFY( (is_same<remove_pointer<ClassType>::type, ClassType>::value) );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/tr1/4_metaprogramming/primary_type_categories/is_pointer/is_pointer.cc b/libstdc++-v3/testsuite/tr1/4_metaprogramming/primary_type_categories/is_pointer/is_pointer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..fd9a33a6caca3ced76edd2e42211eac40b54166c
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr1/4_metaprogramming/primary_type_categories/is_pointer/is_pointer.cc
@@ -0,0 +1,45 @@
+// 2004-12-12  Paolo Carlini  <pcarlini@suse.de>
+//
+// Copyright (C) 2004 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 2, 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 COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 4.5.1 Primary type categories
+
+#include <tr1/type_traits>
+#include <testsuite_hooks.h>
+#include <testsuite_tr1.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using std::tr1::is_pointer;
+  using namespace __gnu_test;
+
+  VERIFY( (test_category<is_pointer, int*>(true)) );
+  VERIFY( (test_category<is_pointer, ClassType*>(true)) );
+  VERIFY( (test_category<is_pointer, int(*)(int)>(true)) );
+
+  // Sanity check.
+  VERIFY( (test_category<is_pointer, ClassType>(false)) );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/tr1/4_metaprogramming/primary_type_categories/is_pointer/typedefs.cc b/libstdc++-v3/testsuite/tr1/4_metaprogramming/primary_type_categories/is_pointer/typedefs.cc
new file mode 100644
index 0000000000000000000000000000000000000000..69141b27c1979d567e5086eacb39076d169adc31
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr1/4_metaprogramming/primary_type_categories/is_pointer/typedefs.cc
@@ -0,0 +1,36 @@
+// 2004-12-12  Paolo Carlini  <pcarlini@suse.de>
+//
+// Copyright (C) 2004 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 2, 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 COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 
+// NB: This file is for testing tr1/type_traits with NO OTHER INCLUDES.
+
+#include <tr1/type_traits>
+
+// { dg-do compile }
+
+void test01()
+{
+  // Check for required typedefs
+  typedef std::tr1::is_pointer<int>           test_type;
+  typedef test_type::value_type               value_type;
+  typedef test_type::type                     type;
+  typedef test_type::type::value_type         type_value_type;
+  typedef test_type::type::type               type_type;
+}
diff --git a/libstdc++-v3/testsuite/tr1/4_metaprogramming/primary_type_categories/is_reference/is_reference.cc b/libstdc++-v3/testsuite/tr1/4_metaprogramming/primary_type_categories/is_reference/is_reference.cc
index 7409368c9b6a8e8f60aea6c79abbd17acb01e631..d3c6b95e66b4dfc2869e4a9f19b7812fc0e88c38 100644
--- a/libstdc++-v3/testsuite/tr1/4_metaprogramming/primary_type_categories/is_reference/is_reference.cc
+++ b/libstdc++-v3/testsuite/tr1/4_metaprogramming/primary_type_categories/is_reference/is_reference.cc
@@ -30,13 +30,9 @@ void test01()
   using std::tr1::is_reference;
   using namespace __gnu_test;
 
-  typedef int&           int_ref;
-  typedef ClassType&     ClassType_ref;
-  typedef int (&fun_ref) (int);
-
-  VERIFY( (test_category<is_reference, int_ref>(true)) );
-  VERIFY( (test_category<is_reference, ClassType_ref>(true)) );
-  VERIFY( (test_category<is_reference, fun_ref>(true)) );
+  VERIFY( (test_category<is_reference, int&>(true)) );
+  VERIFY( (test_category<is_reference, ClassType&>(true)) );
+  VERIFY( (test_category<is_reference, int(&)(int)>(true)) );
 
   // Sanity check.
   VERIFY( (test_category<is_reference, ClassType>(false)) );