public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [v3 PATCH] PR libstdc++/66693
@ 2015-12-19 14:50 Ville Voutilainen
  2015-12-21 11:08 ` Jonathan Wakely
  0 siblings, 1 reply; 2+ messages in thread
From: Ville Voutilainen @ 2015-12-19 14:50 UTC (permalink / raw)
  To: gcc-patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 934 bytes --]

Tested on Linux-PPC64. The patch changes some testcases
to dg-do compile instead of dg-do run, and changes VERIFYs
to static_asserts, since those tests can be done statically.

2015-12-19  Ville Voutilainen  <ville.voutilainen@gmail.com>

    PR libstdc++/66693
    * include/std/tuple (tuple_element, tuple_size, tuple_element_t,
    __tuple_element_t): Move to...
    * include/std/utility: ...here.
    * testsuite/20_util/pair/astuple/astuple.cc: Adjust.
    * testsuite/20_util/pair/astuple/astuple_cpp14.cc: New.
    * testsuite/20_util/tuple/tuple_element.cc: Adjust.
    * testsuite/20_util/tuple/tuple_element_t.cc: Likewise.
    * testsuite/20_util/tuple/tuple_size.cc: Likewise.
    * testsuite/23_containers/array/tuple_interface/tuple_element.cc:
    Likewise.
    * testsuite/23_containers/array/tuple_interface/tuple_element_cpp14.cc:
    New.
    * testsuite/23_containers/array/tuple_interface/tuple_size.cc: Adjust.

[-- Attachment #2: 66693.diff --]
[-- Type: text/plain, Size: 18832 bytes --]

diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index e6c32b3..78f58b4 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -1197,10 +1197,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
 
-  /// Gives the type of the ith element of a given tuple type.
-  template<std::size_t __i, typename _Tp>
-    struct tuple_element;
-
   /**
    * Recursive case for tuple_element: strip off the first element in
    * the tuple and retrieve the (i-1)th element of the remaining tuple.
@@ -1218,53 +1214,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef _Head type;
     };
 
-  // Duplicate of C++14's tuple_element_t for internal use in C++11 mode
-  template<std::size_t __i, typename _Tp>
-    using __tuple_element_t = typename tuple_element<__i, _Tp>::type;
-
-  template<std::size_t __i, typename _Tp>
-    struct tuple_element<__i, const _Tp>
-    {
-      typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type;
-    };
-
-  template<std::size_t __i, typename _Tp>
-    struct tuple_element<__i, volatile _Tp>
-    {
-      typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type;
-    };
-
-  template<std::size_t __i, typename _Tp>
-    struct tuple_element<__i, const volatile _Tp>
-    {
-      typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type;
-    };
-
-#if __cplusplus > 201103L
-#define __cpp_lib_tuple_element_t 201402
-
-  template<std::size_t __i, typename _Tp>
-    using tuple_element_t = typename tuple_element<__i, _Tp>::type;
-#endif
-
-  /// Finds the size of a given tuple type.
-  template<typename _Tp>
-    struct tuple_size;
-
-  // _GLIBCXX_RESOLVE_LIB_DEFECTS
-  // 2313. tuple_size should always derive from integral_constant<size_t, N>
-  template<typename _Tp>
-    struct tuple_size<const _Tp>
-    : integral_constant<size_t, tuple_size<_Tp>::value> { };
-
-  template<typename _Tp>
-    struct tuple_size<volatile _Tp>
-    : integral_constant<size_t, tuple_size<_Tp>::value> { };
-
-  template<typename _Tp>
-    struct tuple_size<const volatile _Tp>
-    : integral_constant<size_t, tuple_size<_Tp>::value> { };
-
   /// class tuple_size
   template<typename... _Elements>
     struct tuple_size<tuple<_Elements...>>
diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility
index 985bcb2..2115d73 100644
--- a/libstdc++-v3/include/std/utility
+++ b/libstdc++-v3/include/std/utility
@@ -79,11 +79,56 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  template<class _Tp>
-    class tuple_size;
+  /// Finds the size of a given tuple type.
+  template<typename _Tp>
+    struct tuple_size;
+
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 2313. tuple_size should always derive from integral_constant<size_t, N>
+  template<typename _Tp>
+    struct tuple_size<const _Tp>
+    : integral_constant<size_t, tuple_size<_Tp>::value> { };
+
+  template<typename _Tp>
+    struct tuple_size<volatile _Tp>
+    : integral_constant<size_t, tuple_size<_Tp>::value> { };
+
+  template<typename _Tp>
+    struct tuple_size<const volatile _Tp>
+    : integral_constant<size_t, tuple_size<_Tp>::value> { };
+
+  /// Gives the type of the ith element of a given tuple type.
+  template<std::size_t __i, typename _Tp>
+    struct tuple_element;
+
+  // Duplicate of C++14's tuple_element_t for internal use in C++11 mode
+  template<std::size_t __i, typename _Tp>
+    using __tuple_element_t = typename tuple_element<__i, _Tp>::type;
+
+  template<std::size_t __i, typename _Tp>
+    struct tuple_element<__i, const _Tp>
+    {
+      typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type;
+    };
+
+  template<std::size_t __i, typename _Tp>
+    struct tuple_element<__i, volatile _Tp>
+    {
+      typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type;
+    };
 
-  template<std::size_t _Int, class _Tp>
-    class tuple_element;
+  template<std::size_t __i, typename _Tp>
+    struct tuple_element<__i, const volatile _Tp>
+    {
+      typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type;
+    };
+
+#if __cplusplus > 201103L
+#define __cpp_lib_tuple_element_t 201402
+
+  template<std::size_t __i, typename _Tp>
+    using tuple_element_t = typename tuple_element<__i, _Tp>::type;
+#endif
 
   template<typename>
     struct __is_tuple_like_impl : false_type
diff --git a/libstdc++-v3/testsuite/20_util/pair/astuple/astuple.cc b/libstdc++-v3/testsuite/20_util/pair/astuple/astuple.cc
index 11e3fce..15ab872 100644
--- a/libstdc++-v3/testsuite/20_util/pair/astuple/astuple.cc
+++ b/libstdc++-v3/testsuite/20_util/pair/astuple/astuple.cc
@@ -24,6 +24,10 @@
 typedef std::pair<int, long> test_type;
 
 static_assert( std::tuple_size<test_type>::value == 2, "size is 2" );
+static_assert( std::tuple_size<const test_type>::value == 2, "size is 2" );
+static_assert( std::tuple_size<volatile test_type>::value == 2, "size is 2" );
+static_assert( std::tuple_size<const volatile test_type>::value == 2,
+               "size is 2" );
 
 template<std::size_t N, typename T>
   using Tuple_elt = typename std::tuple_element<N, T>::type;
@@ -35,3 +39,27 @@ static_assert( is_same<Tuple_elt<0, test_type>, test_type::first_type>::value,
 
 static_assert( is_same<Tuple_elt<1, test_type>, test_type::second_type>::value,
                "second type is long" );
+
+static_assert( is_same<Tuple_elt<0, const test_type>,
+               const test_type::first_type>::value,
+               "first type is const int" );
+
+static_assert( is_same<Tuple_elt<1, const test_type>,
+               const test_type::second_type>::value,
+               "second type is const long" );
+
+static_assert( is_same<Tuple_elt<0, volatile test_type>,
+               volatile test_type::first_type>::value,
+               "first type is volatile int" );
+
+static_assert( is_same<Tuple_elt<1, volatile test_type>,
+               volatile test_type::second_type>::value,
+               "second type is volatile long" );
+
+static_assert( is_same<Tuple_elt<0, const volatile test_type>,
+               const volatile test_type::first_type>::value,
+               "first type is const volatile int" );
+
+static_assert( is_same<Tuple_elt<1, const volatile test_type>,
+               const volatile test_type::second_type>::value,
+               "second type is const volatile long" );
diff --git a/libstdc++-v3/testsuite/20_util/pair/astuple/astuple_cpp14.cc b/libstdc++-v3/testsuite/20_util/pair/astuple/astuple_cpp14.cc
new file mode 100644
index 0000000..9a0a3e5
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/pair/astuple/astuple_cpp14.cc
@@ -0,0 +1,59 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++14" }
+
+// Copyright (C) 2015 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 <utility>
+#include <type_traits>
+
+typedef std::pair<int, long> test_type;
+
+template<std::size_t N, typename T>
+  using Tuple_elt = std::tuple_element_t<N, T>;
+
+using std::is_same;
+
+static_assert( is_same<Tuple_elt<0, test_type>, test_type::first_type>::value,
+               "first type is int" );
+
+static_assert( is_same<Tuple_elt<1, test_type>, test_type::second_type>::value,
+               "second type is long" );
+
+static_assert( is_same<Tuple_elt<0, const test_type>,
+               const test_type::first_type>::value,
+               "first type is const int" );
+
+static_assert( is_same<Tuple_elt<1, const test_type>,
+               const test_type::second_type>::value,
+               "second type is const long" );
+
+static_assert( is_same<Tuple_elt<0, volatile test_type>,
+               volatile test_type::first_type>::value,
+               "first type is volatile int" );
+
+static_assert( is_same<Tuple_elt<1, volatile test_type>,
+               volatile test_type::second_type>::value,
+               "second type is volatile long" );
+
+static_assert( is_same<Tuple_elt<0, const volatile test_type>,
+               const volatile test_type::first_type>::value,
+               "first type is const volatile int" );
+
+static_assert( is_same<Tuple_elt<1, const volatile test_type>,
+               const volatile test_type::second_type>::value,
+               "second type is const volatile long" );
diff --git a/libstdc++-v3/testsuite/20_util/tuple/tuple_element.cc b/libstdc++-v3/testsuite/20_util/tuple/tuple_element.cc
index 78231cb..9e6224c 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/tuple_element.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/tuple_element.cc
@@ -35,4 +35,10 @@ main()
   foo q1;
   tuple_element<0,tuple<foo,void,int> >::type q2(q1);
   tuple_element<2,tuple<void,int,foo> >::type q3(q1);
+  tuple_element<0,const tuple<foo,void,int> >::type q4(q1);
+  tuple_element<2,const tuple<void,int,foo> >::type q5(q1);
+  tuple_element<0,volatile tuple<foo,void,int> >::type q6(q1);
+  tuple_element<2,volatile tuple<void,int,foo> >::type q7(q1);
+  tuple_element<0,const volatile tuple<foo,void,int> >::type q8(q1);
+  tuple_element<2,const volatile tuple<void,int,foo> >::type q9(q1);
 }
diff --git a/libstdc++-v3/testsuite/20_util/tuple/tuple_element_t.cc b/libstdc++-v3/testsuite/20_util/tuple/tuple_element_t.cc
index 481666b..079e7f9 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/tuple_element_t.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/tuple_element_t.cc
@@ -33,4 +33,10 @@ main()
   foo q1;
   tuple_element_t<0,tuple<foo,void,int> > q2(q1);
   tuple_element_t<2,tuple<void,int,foo> > q3(q1);
+  tuple_element_t<0,const tuple<foo,void,int> > q4(q1);
+  tuple_element_t<2,const tuple<void,int,foo> > q5(q1);
+  tuple_element_t<0,volatile tuple<foo,void,int> > q6(q1);
+  tuple_element_t<2,volatile tuple<void,int,foo> > q7(q1);
+  tuple_element_t<0,const volatile tuple<foo,void,int> > q8(q1);
+  tuple_element_t<2,const volatile tuple<void,int,foo> > q9(q1);
 }
diff --git a/libstdc++-v3/testsuite/20_util/tuple/tuple_size.cc b/libstdc++-v3/testsuite/20_util/tuple/tuple_size.cc
index 98b2477..d6f6ec5 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/tuple_size.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/tuple_size.cc
@@ -1,3 +1,4 @@
+// { dg-do compile }
 // { dg-options "-std=gnu++11" }
 
 // Copyright (C) 2007-2015 Free Software Foundation, Inc.
@@ -29,10 +30,28 @@ main()
 {
   bool test __attribute__((unused)) = true;
 
-  VERIFY(tuple_size<tuple<> >::value == 0);
-  VERIFY(tuple_size<tuple<int> >::value == 1);
-  VERIFY(tuple_size<tuple<void> >::value == 1);
+  static_assert(tuple_size<tuple<>>::value == 0, "");
+  static_assert(tuple_size<tuple<int>>::value == 1, "");
+  static_assert(tuple_size<tuple<void>>::value == 1, "");
   typedef tuple<int,const int&,void> test_tuple1;
-  VERIFY(tuple_size<test_tuple1>::value == 3);
-  VERIFY(tuple_size<tuple<tuple<void> > >::value == 1);
+  static_assert(tuple_size<test_tuple1>::value == 3, "");
+  static_assert(tuple_size<tuple<tuple<void>>>::value == 1, "");
+
+  static_assert(tuple_size<const tuple<>>::value == 0, "");
+  static_assert(tuple_size<const tuple<int>>::value == 1, "");
+  static_assert(tuple_size<const tuple<void>>::value == 1, "");
+  static_assert(tuple_size<const test_tuple1>::value == 3, "");
+  static_assert(tuple_size<const tuple<tuple<void>>>::value == 1, "");
+
+  static_assert(tuple_size<volatile tuple<>>::value == 0, "");
+  static_assert(tuple_size<volatile tuple<int>>::value == 1, "");
+  static_assert(tuple_size<volatile tuple<void>>::value == 1, "");
+  static_assert(tuple_size<volatile test_tuple1>::value == 3, "");
+  static_assert(tuple_size<volatile tuple<tuple<void>>>::value == 1, "");
+
+  static_assert(tuple_size<const volatile tuple<>>::value == 0, "");
+  static_assert(tuple_size<const volatile tuple<int>>::value == 1, "");
+  static_assert(tuple_size<const volatile tuple<void>>::value == 1, "");
+  static_assert(tuple_size<const volatile test_tuple1>::value == 3, "");
+  static_assert(tuple_size<const volatile tuple<tuple<void>>>::value == 1,"");
 }
diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element.cc
index dda293d..09ba7a2 100644
--- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element.cc
@@ -1,3 +1,4 @@
+// { dg-do compile }
 // { dg-options "-std=gnu++11" }
 //
 // Copyright (C) 2011-2015 Free Software Foundation, Inc.
@@ -29,9 +30,31 @@ test01()
 
   const size_t len = 3;
   typedef array<int, len> array_type;
-  VERIFY( (is_same<tuple_element<0, array_type>::type, int>::value == true) );
-  VERIFY( (is_same<tuple_element<1, array_type>::type, int>::value == true) );
-  VERIFY( (is_same<tuple_element<2, array_type>::type, int>::value == true) );
+
+  static_assert(is_same<tuple_element<0, array_type>::type, int>::value, "" );
+  static_assert(is_same<tuple_element<1, array_type>::type, int>::value, "" );
+  static_assert(is_same<tuple_element<2, array_type>::type, int>::value, "");
+
+  static_assert(is_same<tuple_element<0, const array_type>::type,
+                const int>::value, "");
+  static_assert(is_same<tuple_element<1, const array_type>::type,
+                const int>::value, "");
+  static_assert(is_same<tuple_element<2, const array_type>::type,
+                const int>::value, "");
+
+  static_assert(is_same<tuple_element<0, volatile array_type>::type,
+                volatile int>::value, "");
+  static_assert(is_same<tuple_element<1, volatile array_type>::type,
+                volatile int>::value, "");
+  static_assert( (is_same<tuple_element<2, volatile array_type>::type,
+           volatile int>::value == true) );
+
+  static_assert(is_same<tuple_element<0, const volatile array_type>::type,
+                const volatile int>::value, "");
+  static_assert(is_same<tuple_element<1, const volatile array_type>::type,
+                const volatile int>::value, "");
+  static_assert(is_same<tuple_element<2, const volatile array_type>::type,
+                const volatile int>::value, "");
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_cpp14.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_cpp14.cc
new file mode 100644
index 0000000..b885ea3
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_cpp14.cc
@@ -0,0 +1,64 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++14" }
+//
+// Copyright (C) 2015 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 <array>
+#include <type_traits>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  const size_t len = 3;
+  typedef array<int, len> array_type;
+
+  static_assert(is_same<tuple_element_t<0, array_type>, int>::value, "");
+  static_assert(is_same<tuple_element_t<1, array_type>, int>::value, "");
+  static_assert(is_same<tuple_element_t<2, array_type>, int>::value, "");
+
+  static_assert(is_same<tuple_element_t<0, const array_type>,
+                const int>::value, "");
+  static_assert(is_same<tuple_element_t<1, const array_type>,
+                const int>::value, "");
+  static_assert(is_same<tuple_element_t<2, const array_type>,
+                const int>::value, "");
+
+  static_assert(is_same<tuple_element_t<0, volatile array_type>,
+                volatile int>::value, "");
+  static_assert(is_same<tuple_element_t<1, volatile array_type>,
+                volatile int>::value, "");
+  static_assert(is_same<tuple_element_t<2, volatile array_type>,
+                volatile int>::value, "");
+
+  static_assert(is_same<tuple_element_t<0, const volatile array_type>,
+                const volatile int>::value, "");
+  static_assert(is_same<tuple_element_t<1, const volatile array_type>,
+                const volatile int>::value, "");
+  static_assert(is_same<tuple_element_t<2, const volatile array_type>,
+                const volatile int>::value, "");
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_size.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_size.cc
index 5932685..a821fde 100644
--- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_size.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_size.cc
@@ -1,3 +1,4 @@
+// { dg-do compile }
 // { dg-options "-std=gnu++11" }
 //
 // Copyright (C) 2011-2015 Free Software Foundation, Inc.
@@ -29,13 +30,19 @@ test01()
   {
     const size_t len = 5;
     typedef array<int, len> array_type;
-    VERIFY( tuple_size<array_type>::value == 5 );
+    static_assert(tuple_size<array_type>::value == 5, "");
+    static_assert(tuple_size<const array_type>::value == 5, "");
+    static_assert(tuple_size<volatile array_type>::value == 5, "");
+    static_assert(tuple_size<const volatile array_type>::value == 5, "");
   }
 
   {
     const size_t len = 0;
     typedef array<float, len> array_type;
-    VERIFY( tuple_size<array_type>::value == 0 );
+    static_assert(tuple_size<array_type>::value == 0, "");
+    static_assert(tuple_size<const array_type>::value == 0, "");
+    static_assert(tuple_size<volatile array_type>::value == 0, "");
+    static_assert(tuple_size<const volatile array_type>::value == 0, "");
   }
 }
 

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [v3 PATCH] PR libstdc++/66693
  2015-12-19 14:50 [v3 PATCH] PR libstdc++/66693 Ville Voutilainen
@ 2015-12-21 11:08 ` Jonathan Wakely
  0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Wakely @ 2015-12-21 11:08 UTC (permalink / raw)
  To: Ville Voutilainen; +Cc: gcc-patches, libstdc++

On 19/12/15 16:50 +0200, Ville Voutilainen wrote:
>
>    PR libstdc++/66693
>    * include/std/tuple (tuple_element, tuple_size, tuple_element_t,
>    __tuple_element_t): Move to...
>    * include/std/utility: ...here.
>    * testsuite/20_util/pair/astuple/astuple.cc: Adjust.
>    * testsuite/20_util/pair/astuple/astuple_cpp14.cc: New.
>    * testsuite/20_util/tuple/tuple_element.cc: Adjust.
>    * testsuite/20_util/tuple/tuple_element_t.cc: Likewise.
>    * testsuite/20_util/tuple/tuple_size.cc: Likewise.
>    * testsuite/23_containers/array/tuple_interface/tuple_element.cc:
>    Likewise.
>    * testsuite/23_containers/array/tuple_interface/tuple_element_cpp14.cc:
>    New.
>    * testsuite/23_containers/array/tuple_interface/tuple_size.cc: Adjust.

OK, thanks.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-12-21 11:08 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-19 14:50 [v3 PATCH] PR libstdc++/66693 Ville Voutilainen
2015-12-21 11:08 ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).