diff mbox

Implement P0084R2, Emplace return type, for C++17

Message ID 20161017115650.GA6908@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely Oct. 17, 2016, 11:56 a.m. UTC
In C++17 the emplace_front and emplace_back members return a
reference. There isn't a very neat way to implement this, so it's just
lots of conditional compilation.

This isn't an ABI break, because these member functions are templates
and so the return type is part of the mangled name. We can't apply it
retroactively to older standards though, because it breaks code that
is valid in C++14, such as:

  void f(std::vector<int>& v) { return v.emplace_back(1); }


	* doc/xml/manual/status_cxx2017.xml: Update status.
	* doc/html/*: Regenerate.
	* include/bits/deque.tcc (deque::emplace_front, deque::emplace_back):
	Return a reference in C++17 mode.
	* include/bits/forward_list.h (forward_list::emplace_front): Likewise.
	* include/bits/stl_bvector.h (vector<bool>::emplace_back): Likewise.
	* include/bits/stl_deque.h (deque::emplace_front, deque::emplace_back):
	Likewise.
	* include/bits/stl_list.h (list::emplace_front, list::emplace_back):
	Likewise.
	* include/bits/stl_queue.h (queue::emplace): Likewise.
	* include/bits/stl_stack.h (stack::emplace): Likewise.
	* include/bits/stl_vector.h (vector::emplace_back): Likewise.
	* include/bits/vector.tcc (vector::emplace_back): Likewise.
	* include/debug/deque (__gnu_debug::deque::emplace_front)
	(__gnu_debug::deque::emplace_back): Likewise.
	* include/debug/vector (__gnu_debug::vector::emplace_back): Likewise.
	* testsuite/23_containers/deque/modifiers/emplace/cxx17_return.cc:
	New.
	* testsuite/23_containers/forward_list/modifiers/
	emplace_cxx17_return.cc: New.
	* testsuite/23_containers/list/modifiers/emplace/cxx17_return.cc: New.
	* testsuite/23_containers/queue/members/emplace_cxx17_return.cc: New.
	* testsuite/23_containers/stack/members/emplace_cxx17_return.cc: New.
	* testsuite/23_containers/vector/bool/emplace_cxx17_return.cc: New.
	* testsuite/23_containers/vector/modifiers/emplace/cxx17_return.cc:
	New.

Tested powerpc64le-linux, committed to trunk.
commit 8e8e806cbdd4581331364153d69d39b5765f8343
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Sat Oct 15 18:56:24 2016 +0100

    Implement P0084R2, Emplace return type, for C++17
    
    	* doc/xml/manual/status_cxx2017.xml: Update status.
    	* doc/html/*: Regenerate.
    	* include/bits/deque.tcc (deque::emplace_front, deque::emplace_back):
    	Return a reference in C++17 mode.
    	* include/bits/forward_list.h (forward_list::emplace_front): Likewise.
    	* include/bits/stl_bvector.h (vector<bool>::emplace_back): Likewise.
    	* include/bits/stl_deque.h (deque::emplace_front, deque::emplace_back):
    	Likewise.
    	* include/bits/stl_list.h (list::emplace_front, list::emplace_back):
    	Likewise.
    	* include/bits/stl_queue.h (queue::emplace): Likewise.
    	* include/bits/stl_stack.h (stack::emplace): Likewise.
    	* include/bits/stl_vector.h (vector::emplace_back): Likewise.
    	* include/bits/vector.tcc (vector::emplace_back): Likewise.
    	* include/debug/deque (__gnu_debug::deque::emplace_front)
    	(__gnu_debug::deque::emplace_back): Likewise.
    	* include/debug/vector (__gnu_debug::vector::emplace_back): Likewise.
    	* testsuite/23_containers/deque/modifiers/emplace/cxx17_return.cc:
    	New.
    	* testsuite/23_containers/forward_list/modifiers/
    	emplace_cxx17_return.cc: New.
    	* testsuite/23_containers/list/modifiers/emplace/cxx17_return.cc: New.
    	* testsuite/23_containers/queue/members/emplace_cxx17_return.cc: New.
    	* testsuite/23_containers/stack/members/emplace_cxx17_return.cc: New.
    	* testsuite/23_containers/vector/bool/emplace_cxx17_return.cc: New.
    	* testsuite/23_containers/vector/modifiers/emplace/cxx17_return.cc:
    	New.

Comments

Christophe Lyon Oct. 18, 2016, 8:30 a.m. UTC | #1
Hi Jonathan,


On 17 October 2016 at 13:56, Jonathan Wakely <jwakely@redhat.com> wrote:
> In C++17 the emplace_front and emplace_back members return a
> reference. There isn't a very neat way to implement this, so it's just
> lots of conditional compilation.
>
> This isn't an ABI break, because these member functions are templates
> and so the return type is part of the mangled name. We can't apply it
> retroactively to older standards though, because it breaks code that
> is valid in C++14, such as:
>
>  void f(std::vector<int>& v) { return v.emplace_back(1); }
>
>
>         * doc/xml/manual/status_cxx2017.xml: Update status.
>         * doc/html/*: Regenerate.
>         * include/bits/deque.tcc (deque::emplace_front,
> deque::emplace_back):
>         Return a reference in C++17 mode.
>         * include/bits/forward_list.h (forward_list::emplace_front):
> Likewise.
>         * include/bits/stl_bvector.h (vector<bool>::emplace_back): Likewise.
>         * include/bits/stl_deque.h (deque::emplace_front,
> deque::emplace_back):
>         Likewise.
>         * include/bits/stl_list.h (list::emplace_front, list::emplace_back):
>         Likewise.
>         * include/bits/stl_queue.h (queue::emplace): Likewise.
>         * include/bits/stl_stack.h (stack::emplace): Likewise.
>         * include/bits/stl_vector.h (vector::emplace_back): Likewise.
>         * include/bits/vector.tcc (vector::emplace_back): Likewise.
>         * include/debug/deque (__gnu_debug::deque::emplace_front)
>         (__gnu_debug::deque::emplace_back): Likewise.
>         * include/debug/vector (__gnu_debug::vector::emplace_back):
> Likewise.
>         * testsuite/23_containers/deque/modifiers/emplace/cxx17_return.cc:
>         New.
>         * testsuite/23_containers/forward_list/modifiers/
>         emplace_cxx17_return.cc: New.
>         * testsuite/23_containers/list/modifiers/emplace/cxx17_return.cc:
> New.
>         * testsuite/23_containers/queue/members/emplace_cxx17_return.cc:
> New.
>         * testsuite/23_containers/stack/members/emplace_cxx17_return.cc:
> New.
>         * testsuite/23_containers/vector/bool/emplace_cxx17_return.cc: New.
>         * testsuite/23_containers/vector/modifiers/emplace/cxx17_return.cc:
>         New.
>
> Tested powerpc64le-linux, committed to trunk.
>

The new tests (except for
23_containers/forward_list/modifiers/emplace_cxx17_return.cc) fail on
arm-none-eabi using default cpu/fpu/arch/mode:
/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc3/arm-none-eabi/libstdc++-v3/src/.libs/libstdc++.a(future.o):
In function `__future_category_instance':
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++11/future.cc:64:
undefined reference to `__sync_synchronize'
/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc3/arm-none-eabi/libstdc++-v3/src/.libs/libstdc++.a(locale.o):
In function `get_locale_cache_mutex':
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++98/locale.cc:36:
undefined reference to `__sync_synchronize'
/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc3/arm-none-eabi/libstdc++-v3/src/.libs/libstdc++.a(locale_init.o):
In function `get_locale_mutex':
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libstdc++-v3/src/c++98/locale_init.cc:66:
undefined reference to `__sync_synchronize'

Christophe
diff mbox

Patch

diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
index ae8dfa9..a1190bc 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
@@ -542,14 +542,13 @@  Feature-testing recommendations for C++</link>.
     </row>
 
     <row>
-      <?dbhtml bgcolor="#C8B0B0" ?>
       <entry> Emplace return type </entry>
       <entry>
 	<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0084r2.pdf">
 	P0084R2
 	</link>
       </entry>
-      <entry align="center"> No </entry>
+      <entry align="center"> 7 </entry>
       <entry/>
     </row>
 
diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc
index 96ec9f8..796b0cd 100644
--- a/libstdc++-v3/include/bits/deque.tcc
+++ b/libstdc++-v3/include/bits/deque.tcc
@@ -129,7 +129,11 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 #if __cplusplus >= 201103L
   template<typename _Tp, typename _Alloc>
     template<typename... _Args>
+#if __cplusplus > 201402L
+      typename deque<_Tp, _Alloc>::reference
+#else
       void
+#endif
       deque<_Tp, _Alloc>::
       emplace_front(_Args&&... __args)
       {
@@ -142,11 +146,18 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	  }
 	else
 	  _M_push_front_aux(std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+	return front();
+#endif
       }
 
   template<typename _Tp, typename _Alloc>
     template<typename... _Args>
+#if __cplusplus > 201402L
+      typename deque<_Tp, _Alloc>::reference
+#else
       void
+#endif
       deque<_Tp, _Alloc>::
       emplace_back(_Args&&... __args)
       {
@@ -160,6 +171,9 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	  }
 	else
 	  _M_push_back_aux(std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+	return back();
+#endif
       }
 #endif
 
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index 3961509..0ea8806 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -797,10 +797,19 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  and references.
        */
       template<typename... _Args>
-        void
+#if __cplusplus > 201402L
+        reference
+#else
+	void
+#endif
         emplace_front(_Args&&... __args)
-        { this->_M_insert_after(cbefore_begin(),
-                                std::forward<_Args>(__args)...); }
+        {
+	  this->_M_insert_after(cbefore_begin(),
+                                std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+	  return front();
+#endif
+	}
 
       /**
        *  @brief  Add data to the front of the %forward_list.
diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index b3ac63f..2e231b9 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -1056,9 +1056,18 @@  template<typename _Alloc>
 
 #if __cplusplus >= 201103L
     template<typename... _Args>
+#if __cplusplus > 201402L
+      reference
+#else
       void
+#endif
       emplace_back(_Args&&... __args)
-      { push_back(bool(__args...)); }
+      {
+	push_back(bool(__args...));
+#if __cplusplus > 201402L
+	return back();
+#endif
+      }
 
     template<typename... _Args>
       iterator
diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h
index 7192f65..8539a08 100644
--- a/libstdc++-v3/include/bits/stl_deque.h
+++ b/libstdc++-v3/include/bits/stl_deque.h
@@ -1519,7 +1519,11 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       { emplace_front(std::move(__x)); }
 
       template<typename... _Args>
-        void
+#if __cplusplus > 201402L
+	reference
+#else
+	void
+#endif
         emplace_front(_Args&&... __args);
 #endif
 
@@ -1552,7 +1556,11 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       { emplace_back(std::move(__x)); }
 
       template<typename... _Args>
-        void
+#if __cplusplus > 201402L
+	reference
+#else
+	void
+#endif
         emplace_back(_Args&&... __args);
 #endif
 
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index 87c8a39..8693a6f 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -1069,9 +1069,18 @@  _GLIBCXX_BEGIN_NAMESPACE_CXX11
       { this->_M_insert(begin(), std::move(__x)); }
 
       template<typename... _Args>
-        void
+#if __cplusplus > 201402L
+        reference
+#else
+	void
+#endif
         emplace_front(_Args&&... __args)
-        { this->_M_insert(begin(), std::forward<_Args>(__args)...); }
+        {
+	  this->_M_insert(begin(), std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+	  return front();
+#endif
+	}
 #endif
 
       /**
@@ -1110,9 +1119,18 @@  _GLIBCXX_BEGIN_NAMESPACE_CXX11
       { this->_M_insert(end(), std::move(__x)); }
 
       template<typename... _Args>
-        void
+#if __cplusplus > 201402L
+        reference
+#else
+	void
+#endif
         emplace_back(_Args&&... __args)
-        { this->_M_insert(end(), std::forward<_Args>(__args)...); }
+        {
+	  this->_M_insert(end(), std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+        return back();
+#endif
+	}
 #endif
 
       /**
diff --git a/libstdc++-v3/include/bits/stl_queue.h b/libstdc++-v3/include/bits/stl_queue.h
index 843199c..178e4b2 100644
--- a/libstdc++-v3/include/bits/stl_queue.h
+++ b/libstdc++-v3/include/bits/stl_queue.h
@@ -247,11 +247,18 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       push(value_type&& __x)
       { c.push_back(std::move(__x)); }
 
+#if __cplusplus > 201402L
+      template<typename... _Args>
+	decltype(auto)
+	emplace(_Args&&... __args)
+	{ return c.emplace_back(std::forward<_Args>(__args)...); }
+#else
       template<typename... _Args>
         void
         emplace(_Args&&... __args)
 	{ c.emplace_back(std::forward<_Args>(__args)...); }
 #endif
+#endif
 
       /**
        *  @brief  Removes first element.
diff --git a/libstdc++-v3/include/bits/stl_stack.h b/libstdc++-v3/include/bits/stl_stack.h
index 612913d..ebc8816 100644
--- a/libstdc++-v3/include/bits/stl_stack.h
+++ b/libstdc++-v3/include/bits/stl_stack.h
@@ -223,11 +223,18 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       push(value_type&& __x)
       { c.push_back(std::move(__x)); }
 
+#if __cplusplus > 201402L
+      template<typename... _Args>
+	decltype(auto)
+	emplace(_Args&&... __args)
+	{ return c.emplace_back(std::forward<_Args>(__args)...); }
+#else
       template<typename... _Args>
         void
         emplace(_Args&&... __args)
 	{ c.emplace_back(std::forward<_Args>(__args)...); }
 #endif
+#endif
 
       /**
        *  @brief  Removes first element.
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 9a05dd5..efc569b 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -960,7 +960,11 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       { emplace_back(std::move(__x)); }
 
       template<typename... _Args>
+#if __cplusplus > 201402L
+        reference
+#else
 	void
+#endif
 	emplace_back(_Args&&... __args);
 #endif
 
diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc
index 6926a8b..b6050d3 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -87,7 +87,11 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 #if __cplusplus >= 201103L
   template<typename _Tp, typename _Alloc>
     template<typename... _Args>
+#if __cplusplus > 201402L
+      typename vector<_Tp, _Alloc>::reference
+#else
       void
+#endif
       vector<_Tp, _Alloc>::
       emplace_back(_Args&&... __args)
       {
@@ -99,6 +103,9 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	  }
 	else
 	  _M_realloc_insert(end(), std::forward<_Args>(__args)...);
+#if __cplusplus > 201402L
+	return back();
+#endif
       }
 #endif
 
diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque
index f15faad..bf4cba6 100644
--- a/libstdc++-v3/include/debug/deque
+++ b/libstdc++-v3/include/debug/deque
@@ -386,19 +386,33 @@  namespace __debug
       { emplace_back(std::move(__x)); }
 
       template<typename... _Args>
+#if __cplusplus > 201402L
+	reference
+#else
 	void
+#endif
 	emplace_front(_Args&&... __args)
 	{
 	  _Base::emplace_front(std::forward<_Args>(__args)...);
 	  this->_M_invalidate_all();
+#if __cplusplus > 201402L
+	  return front();
+#endif
 	}
 
       template<typename... _Args>
+#if __cplusplus > 201402L
+	reference
+#else
 	void
+#endif
 	emplace_back(_Args&&... __args)
 	{
 	  _Base::emplace_back(std::forward<_Args>(__args)...);
 	  this->_M_invalidate_all();
+#if __cplusplus > 201402L
+	  return back();
+#endif
 	}
 
       template<typename... _Args>
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index 9bcda73..b2d70bd 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -478,7 +478,11 @@  namespace __debug
 	{ emplace_back(std::move(__x)); }
 
       template<typename... _Args>
+#if __cplusplus > 201402L
+	deque<_Tp, _Alloc>::reference
+#else
 	void
+#endif
 	emplace_back(_Args&&... __args)
 	{
 	  bool __realloc = this->_M_requires_reallocation(this->size() + 1);
@@ -486,6 +490,9 @@  namespace __debug
 	  if (__realloc)
 	    this->_M_invalidate_all();
 	  this->_M_update_guaranteed_capacity();
+#if __cplusplus > 201402L
+	  return back();
+#endif
 	}
 #endif
 
diff --git a/libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/cxx17_return.cc
new file mode 100644
index 0000000..3e5da96
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/modifiers/emplace/cxx17_return.cc
@@ -0,0 +1,49 @@ 
+// Copyright (C) 2016 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <deque>
+#include <testsuite_hooks.h>
+
+using test_type = std::deque<int>;
+
+void
+test01()
+{
+  test_type x{1, 2, 3, 4};
+  test_type::reference r = x.emplace_front(0);
+  VERIFY( r == 0 );
+  VERIFY( &r == &x.front() );
+}
+
+void
+test02()
+{
+  test_type x{1, 2, 3, 4};
+  test_type::reference r = x.emplace_back(5);
+  VERIFY( r == 5 );
+  VERIFY( &r == &x.back() );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/emplace_cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/emplace_cxx17_return.cc
new file mode 100644
index 0000000..b91c1ca
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/emplace_cxx17_return.cc
@@ -0,0 +1,39 @@ 
+// Copyright (C) 2016 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <forward_list>
+#include <testsuite_hooks.h>
+
+using test_type = std::forward_list<int>;
+
+void
+test01()
+{
+  test_type x{1, 2, 3, 4};
+  test_type::reference r = x.emplace_front(0);
+  VERIFY( r == 0 );
+  VERIFY( &r == &x.front() );
+}
+
+int
+main()
+{
+  test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/emplace/cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/emplace/cxx17_return.cc
new file mode 100644
index 0000000..c88d8d2
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/emplace/cxx17_return.cc
@@ -0,0 +1,49 @@ 
+// Copyright (C) 2016 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <list>
+#include <testsuite_hooks.h>
+
+using test_type = std::list<int>;
+
+void
+test01()
+{
+  test_type x{1, 2, 3, 4};
+  test_type::reference r = x.emplace_front(0);
+  VERIFY( r == 0 );
+  VERIFY( &r == &x.front() );
+}
+
+void
+test02()
+{
+  test_type x{1, 2, 3, 4};
+  test_type::reference r = x.emplace_back(5);
+  VERIFY( r == 5 );
+  VERIFY( &r == &x.back() );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/queue/members/emplace_cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/queue/members/emplace_cxx17_return.cc
new file mode 100644
index 0000000..a618e9c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/queue/members/emplace_cxx17_return.cc
@@ -0,0 +1,39 @@ 
+// Copyright (C) 2016 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <queue>
+#include <testsuite_hooks.h>
+
+using test_type = std::queue<int>;
+
+void
+test01()
+{
+  test_type x{ test_type::container_type{1, 2, 3, 4} };
+  test_type::reference r = x.emplace(5);
+  VERIFY( r == 5 );
+  VERIFY( &r == &x.back() );
+}
+
+int
+main()
+{
+  test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/stack/members/emplace_cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/stack/members/emplace_cxx17_return.cc
new file mode 100644
index 0000000..76964eb
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/stack/members/emplace_cxx17_return.cc
@@ -0,0 +1,39 @@ 
+// Copyright (C) 2016 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <stack>
+#include <testsuite_hooks.h>
+
+using test_type = std::stack<int>;
+
+void
+test01()
+{
+  test_type x{ test_type::container_type{1, 2, 3, 4} };
+  test_type::reference r = x.emplace(5);
+  VERIFY( r == 5 );
+  VERIFY( &r == &x.top() );
+}
+
+int
+main()
+{
+  test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/emplace_cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/emplace_cxx17_return.cc
new file mode 100644
index 0000000..d4f70fb
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/emplace_cxx17_return.cc
@@ -0,0 +1,38 @@ 
+// Copyright (C) 2016 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <vector>
+#include <testsuite_hooks.h>
+
+using test_type = std::vector<bool>;
+
+void
+test02()
+{
+  test_type x{true, true};
+  test_type::reference r = x.emplace_back(false);
+  VERIFY( r == false );
+}
+
+int
+main()
+{
+  test02();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/cxx17_return.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/cxx17_return.cc
new file mode 100644
index 0000000..9006dab
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/cxx17_return.cc
@@ -0,0 +1,39 @@ 
+// Copyright (C) 2016 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/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <vector>
+#include <testsuite_hooks.h>
+
+using test_type = std::vector<int>;
+
+void
+test02()
+{
+  test_type x{1, 2, 3, 4};
+  test_type::reference r = x.emplace_back(5);
+  VERIFY( r == 5 );
+  VERIFY( &r == &x.back() );
+}
+
+int
+main()
+{
+  test02();
+}