Add std::scoped_lock for C++17
authorJonathan Wakely <jwakely@redhat.com>
Sun, 5 Mar 2017 18:38:35 +0000 (18:38 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Sun, 5 Mar 2017 18:38:35 +0000 (18:38 +0000)
* doc/xml/manual/status_cxx2017.xml: Document P0156R2 status.
* doc/html/*: Regenerate.
* include/std/mutex (scoped_lock): Implement new C++17 template.
* testsuite/30_threads/scoped_lock/cons/1.cc: New test.
* testsuite/30_threads/scoped_lock/requirements/
explicit_instantiation.cc: New test.
* testsuite/30_threads/scoped_lock/requirements/typedefs.cc: New test.

From-SVN: r245903

16 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/doc/html/manual/debug.html
libstdc++-v3/doc/html/manual/debug_mode_design.html
libstdc++-v3/doc/html/manual/documentation_hacking.html
libstdc++-v3/doc/html/manual/fstreams.html
libstdc++-v3/doc/html/manual/memory.html
libstdc++-v3/doc/html/manual/policy_data_structures.html
libstdc++-v3/doc/html/manual/policy_data_structures_ack.html
libstdc++-v3/doc/html/manual/profile_mode.html
libstdc++-v3/doc/html/manual/profile_mode_design.html
libstdc++-v3/doc/html/manual/status.html
libstdc++-v3/doc/xml/manual/status_cxx2017.xml
libstdc++-v3/include/std/mutex
libstdc++-v3/testsuite/30_threads/scoped_lock/cons/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/explicit_instantiation.cc [new file with mode: 0644]
libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/typedefs.cc [new file with mode: 0644]

index 6a63daf0b7cf44e4b222762a5a0f672232096a7c..ef48d8767cffbf71d246c8d7201e281390658a52 100644 (file)
@@ -1,3 +1,13 @@
+2017-03-05  Jonathan Wakely  <jwakely@redhat.com>
+
+       * doc/xml/manual/status_cxx2017.xml: Document P0156R2 status.
+       * doc/html/*: Regenerate.
+       * include/std/mutex (scoped_lock): Implement new C++17 template.
+       * testsuite/30_threads/scoped_lock/cons/1.cc: New test.
+       * testsuite/30_threads/scoped_lock/requirements/
+       explicit_instantiation.cc: New test.
+       * testsuite/30_threads/scoped_lock/requirements/typedefs.cc: New test.
+
 2017-03-02  Gerald Pfeifer  <gerald@pfeifer.com>
            François Dumont  <frs.dumont@gmail.com>
            Jonathan Wakely  <jwakely@redhat.com>
index 4f88c0764f88a515af878607f7d06a1191166de5..c0dc2d29b0a24f4df2c8eceba2b4f17e9ff2c77d 100644 (file)
   DRD</a>,
   <a class="link" href="http://valgrind.org/docs/manual/hg-manual.html" target="_top"> 
   Helgrind</a>, and
-  <a class="link" href="https://code.google.com/p/data-race-test/" target="_top"> 
+  <a class="link" href="https://github.com/google/sanitizers" target="_top"> 
   ThreadSanitizer</a> (this refers to ThreadSanitizer v1, not the
   new "tsan" feature built-in to GCC itself).
 </p><p>
index 3fcdb2db8852dcc3ba984bdc6c93fd5828c0b228..b8d391f185c20c48f4c9717fff798c8421cf5e3b 100644 (file)
@@ -191,15 +191,11 @@ template&lt;typename _Tp, typename _Allocator = allocator&lt;_Tp&gt;
   perform, shortening the detect-compile-debug bug hunting cycle
   and making the debug mode easier to incorporate into development
   environments by minimizing dependencies.</p><p>Achieving link- and run-time coexistence is not a trivial
-  implementation task. To achieve this goal we required a small
-  extension to the GNU C++ compiler (since incorporated into the C++11 language specification, described in the GCC Manual for the C++ language as
-  <a class="link" href="http://gcc.gnu.org/onlinedocs/gcc/Namespace-Association.html#Namespace-Association" target="_top">namespace
-  association</a>), and a complex organization of debug- and
-  release-modes. The end result is that we have achieved per-use
-  recompilation but have had to give up some checking of the
-  <code class="code">std::basic_string</code> class template (namely, safe
-  iterators).
-</p><div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="methods.coexistence.compile"></a>Compile-time coexistence of release- and debug-mode components</h5></div></div></div><p>Both the release-mode components and the debug-mode
+  implementation task. To achieve this goal we use inline namespaces and
+  a complex organization of debug- and release-modes. The end result is
+  that we have achieved per-use recompilation but have had to give up
+  some checking of the <code class="code">std::basic_string</code> class template
+  (namely, safe iterators).</p><div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="methods.coexistence.compile"></a>Compile-time coexistence of release- and debug-mode components</h5></div></div></div><p>Both the release-mode components and the debug-mode
   components need to exist within a single translation unit so that
   the debug versions can wrap the release versions. However, only one
   of these components should be user-visible at any particular
index 5cada1a0df4847a0f7b1ab22f6ba3177f85a792b..f3e372603a94180de4029a7a8dde89bd41d98803 100644 (file)
       <span class="emphasis"><em>ps</em></span>, and <span class="emphasis"><em>dvi</em></span>.
     </p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="doc.doxygen"></a>Doxygen</h3></div></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="doxygen.prereq"></a>Prerequisites</h4></div></div></div><div class="table"><a id="table.doxygen_prereq"></a><p class="title"><strong>Table B.1. Doxygen Prerequisites</strong></p><div class="table-contents"><table summary="Doxygen Prerequisites" border="1"><colgroup><col align="center" class="c1" /><col align="center" class="c2" /><col align="center" class="c3" /></colgroup><thead><tr><th align="center">Tool</th><th align="center">Version</th><th align="center">Required By</th></tr></thead><tbody><tr><td align="center">coreutils</td><td align="center">8.5</td><td align="center">all</td></tr><tr><td align="center">bash</td><td align="center">4.1</td><td align="center">all</td></tr><tr><td align="center">doxygen</td><td align="center">1.7.6.1</td><td align="center">all</td></tr><tr><td align="center">graphviz</td><td align="center">2.26</td><td align="center">graphical hierarchies</td></tr><tr><td align="center">pdflatex</td><td align="center">2007-59</td><td align="center">pdf output</td></tr></tbody></table></div></div><br class="table-break" /><p>
        Prerequisite tools are Bash 2.0 or later,
-       <a class="link" href="http://www.doxygen.org/" target="_top">Doxygen</a>, and
+       <a class="link" href="http://www.doxygen.org" target="_top">Doxygen</a>, and
        the <a class="link" href="http://www.gnu.org/software/coreutils/" target="_top">GNU
        coreutils</a>. (GNU versions of find, xargs, and possibly
        sed and grep are used, just because the GNU versions make
index 0b9b30d7532364b546c44d331f90bafbbfd335f8..897057600f92b7dfe87a3fb44ffd888d8348f38b 100644 (file)
    </p><p>
       An instructive thread from comp.lang.c++.moderated delved off into
       this topic starting more or less at
-      <a class="link" href="http://groups.google.com/group/comp.std.c++/browse_thread/thread/f87b4abd7954a87/946a3eb9921e382d?q=comp.std.c%2B%2B+binary+iostream#946a3eb9921e382d" target="_top">this</a>
-      post and continuing to the end of the thread. (The subject heading is "binary iostreams" on both comp.std.c++
+      <a class="link" href="https://groups.google.com/forum/#!topic/comp.std.c++/D4e0q9eVSoc" target="_top">this post</a>
+      and continuing to the end of the thread. (The subject heading is "binary iostreams" on both comp.std.c++
       and comp.lang.c++.moderated.) Take special note of the replies by James Kanze and Dietmar Kühl.
    </p><p>Briefly, the problems of byte ordering and type sizes mean that
       the unformatted functions like <code class="code">ostream::put()</code> and
index cf58f632b78dd71c1c6894854153afdfe9d730d8..d310b6954719a115130b540115d3dd0e302dc006 100644 (file)
@@ -671,7 +671,7 @@ be private.
       </em>. </span><span class="subtitle">
       N2461
     . </span></p></div><div class="biblioentry"><a id="id-1.3.4.4.4.5.8.5"></a><p><span class="title"><em>
-       <a class="link" href="http://boost.org/libs/smart_ptr/shared_ptr.htm" target="_top">
+       <a class="link" href="http://www.boost.org/libs/smart_ptr/shared_ptr.htm" target="_top">
       Boost C++ Libraries documentation, shared_ptr
        </a>
       </em>. </span><span class="subtitle">
index 0345490f82b916e8d2d3ef94d96b2315a0669f3f..bd0d18e21f5706351564fc1adec1b8f0cb318eb1 100644 (file)
          </span>. </span><span class="publisher"><span class="publishername">
          Generic Programming
        . </span></span></p></div><div class="biblioentry"><a id="biblio.dawestimer"></a><p>[biblio.dawestimer] <span class="title"><em>
-       <a class="link" href="http://www.boost.org/doc/libs/release/libs/timer/" target="_top">
+       <a class="link" href="http://www.boost.org/libs/timer/" target="_top">
          Boost Timer Library
        </a>
       </em>. </span><span class="author"><span class="firstname">
          </span>. </span><span class="publisher"><span class="publishername">
          Boost
        . </span></span></p></div><div class="biblioentry"><a id="biblio.clearypool"></a><p>[biblio.clearypool] <span class="title"><em>
-       <a class="link" href="http://www.boost.org/doc/libs/release/libs/pool/" target="_top">
+       <a class="link" href="http://www.boost.org/libs/pool/" target="_top">
          Boost Pool Library
        </a>
       </em>. </span><span class="author"><span class="firstname">
          </span>. </span><span class="publisher"><span class="publishername">
          Boost
        . </span></span></p></div><div class="biblioentry"><a id="biblio.maddocktraits"></a><p>[biblio.maddocktraits] <span class="title"><em>
-       <a class="link" href="http://www.boost.org/doc/libs/release/libs/type_traits/" target="_top">
+       <a class="link" href="http://www.boost.org/libs/type_traits/" target="_top">
          Boost Type Traits Library
        </a>
       </em>. </span><span class="authorgroup"><span class="firstname">
index 7eb8f15cf38b9b7a6b74a90a24f84d4b2b0f7645..e450da28cb694c6d8aa77704bb4ad1bf601ea72f 100644 (file)
@@ -18,7 +18,7 @@
          reverse iteration can be performed efficiently.
        </p></li></ol></div><p>
       Some test utilities borrow ideas from
-      <a class="link" href="http://www.boost.org/doc/libs/release/libs/timer/index.html" target="_top">boost::timer</a>.
+      <a class="link" href="http://www.boost.org/libs/timer/" target="_top">boost::timer</a>.
     </p><p>
       We would like to thank Scott Meyers for useful comments (without
       attributing to him any flaws in the design or implementation of the
index 0c4464711852e45f72d4842ba446bd22ee2f47f4..3f32b30b9f8e47403ea9144000427830fc8bb0ac 100644 (file)
@@ -11,7 +11,7 @@
   various components at interesting entry/exit points to/from the standard
   library.  Process trace, recognize suboptimal patterns, give advice.
   For details, see the
-  <a class="link" href="http://http://ieeexplore.ieee.org/document/4907670/" target="_top">Perflint
+  <a class="link" href="http://ieeexplore.ieee.org/document/4907670/" target="_top">Perflint
   paper presented at CGO 2009</a>.
   </p><p>
   <span class="emphasis"><em>Strengths: </em></span>
index 2d49e3388042c3b32f572d0e1b105e8f7ab6ac31..8fe9eddba2a8219616beee12bff98d252733704c 100644 (file)
@@ -60,7 +60,7 @@
   call stack of its constructor location.
   </p><p>
   For details, see
-   <a class="link" href="http://dx.doi.org/10.1109/CGO.2009.36" target="_top">paper presented at
+   <a class="link" href="http://ieeexplore.ieee.org/document/4907670/" target="_top">paper presented at
    CGO 2009</a>.
   </p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="manual.ext.profile_mode.design.analysis"></a>Analysis and Diagnostics</h3></div></div></div><p>
   Final analysis takes place offline, and it is based entirely on the
index 842e8d4e61aa62ed46aade78405ba9ef810dcaea..0507cc7545a5d18d4a7ccb14673e23f43074c957 100644 (file)
@@ -776,11 +776,11 @@ Feature-testing recommendations for C++</a>.
        <a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4508.html" target="_top">
          N4508
        </a>
-      </td><td align="center"> 6.1 </td><td align="left"><code class="code"> __cpp_lib_shared_mutex &gt;= 201505 </code></td></tr><tr bgcolor="#C8B0B0"><td align="left"> Variadic <code class="code">lock_guard</code> </td><td align="left">
-       <a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0156r0.html" target="_top">
-       P0156R0
+      </td><td align="center"> 6.1 </td><td align="left"><code class="code"> __cpp_lib_shared_mutex &gt;= 201505 </code></td></tr><tr><td align="left"> Variadic <code class="code">lock_guard</code> </td><td align="left">
+       <a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0156r2.html" target="_top">
+       P0156R2
        </a>
-      </td><td align="center"> No </td><td align="left"><code class="code"> __cpp_lib_lock_guard_variadic &gt;= 201510 </code></td></tr></tbody></table></div></div><br class="table-break" /><div class="table"><a id="table.cxx1z_ts_status"></a><p class="title"><strong>Table 1.6. C++ Technical Specifications Implementation Status</strong></p><div class="table-contents"><table summary="C++ Technical Specifications Implementation Status" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /><col align="left" class="c3" /><col align="left" class="c4" /></colgroup><thead><tr><th align="left">Paper</th><th align="left">Title</th><th align="left">Status</th><th align="left">Comments</th></tr></thead><tbody><tr><td align="left">
+      </td><td align="center"> 7 </td><td align="left"><code class="code"> __cpp_lib_scoped_lock &gt;= 201703 </code></td></tr></tbody></table></div></div><br class="table-break" /><div class="table"><a id="table.cxx1z_ts_status"></a><p class="title"><strong>Table 1.6. C++ Technical Specifications Implementation Status</strong></p><div class="table-contents"><table summary="C++ Technical Specifications Implementation Status" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /><col align="left" class="c3" /><col align="left" class="c4" /></colgroup><thead><tr><th align="left">Paper</th><th align="left">Title</th><th align="left">Status</th><th align="left">Comments</th></tr></thead><tbody><tr><td align="left">
        <a class="link" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4076.html" target="_top">
          N4076
        </a>
index add0514ad9a2a09484c230dc31f031018bc5a6b6..1053f2dd84bad904ef2f5f76c299498b3182848f 100644 (file)
@@ -719,15 +719,14 @@ Feature-testing recommendations for C++</link>.
     </row>
 
     <row>
-      <?dbhtml bgcolor="#C8B0B0" ?>
       <entry> Variadic <code>lock_guard</code> </entry>
       <entry>
-       <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0156r0.html">
-       P0156R0
+       <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0156r2.html">
+       P0156R2
        </link>
       </entry>
-      <entry align="center"> No </entry>
-      <entry><code> __cpp_lib_lock_guard_variadic >= 201510 </code></entry>
+      <entry align="center"> 7 </entry>
+      <entry><code> __cpp_lib_scoped_lock >= 201703 </code></entry>
     </row>
 
   </tbody>
index d6f3899e4f64356631886221b892aaede5442406..6c3f92022beb3e779d0482aa14632a86683fe972 100644 (file)
@@ -556,6 +556,74 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         }
     }
 
+#if __cplusplus > 201402L
+#define __cpp_lib_scoped_lock 201703
+  /** @brief A scoped lock type for multiple lockable objects.
+   *
+   * A scoped_lock controls mutex ownership within a scope, releasing
+   * ownership in the destructor.
+   */
+  template<typename... _MutexTypes>
+    class scoped_lock
+    {
+    public:
+      explicit scoped_lock(_MutexTypes&... __m) : _M_devices(std::tie(__m...))
+      { std::lock(__m...); }
+
+      explicit scoped_lock(_MutexTypes&... __m, adopt_lock_t) noexcept
+      : _M_devices(std::tie(__m...))
+      { } // calling thread owns mutex
+
+      ~scoped_lock()
+      {
+       std::apply([](_MutexTypes&... __m) {
+         char __i[] __attribute__((__unused__)) = { (__m.unlock(), 0)... };
+       }, _M_devices);
+      }
+
+      scoped_lock(const scoped_lock&) = delete;
+      scoped_lock& operator=(const scoped_lock&) = delete;
+
+    private:
+      tuple<_MutexTypes&...> _M_devices;
+    };
+
+  template<>
+    class scoped_lock<>
+    {
+    public:
+      explicit scoped_lock() = default;
+      explicit scoped_lock(adopt_lock_t) noexcept { }
+      ~scoped_lock() = default;
+
+      scoped_lock(const scoped_lock&) = delete;
+      scoped_lock& operator=(const scoped_lock&) = delete;
+    };
+
+  template<typename _Mutex>
+    class scoped_lock<_Mutex>
+    {
+    public:
+      using mutex_type = _Mutex;
+
+      explicit scoped_lock(mutex_type& __m) : _M_device(__m)
+      { _M_device.lock(); }
+
+      explicit scoped_lock(mutex_type& __m, adopt_lock_t) noexcept
+      : _M_device(__m)
+      { } // calling thread owns mutex
+
+      ~scoped_lock()
+      { _M_device.unlock(); }
+
+      scoped_lock(const scoped_lock&) = delete;
+      scoped_lock& operator=(const scoped_lock&) = delete;
+
+    private:
+      mutex_type&  _M_device;
+    };
+#endif // C++17
+
 #ifdef _GLIBCXX_HAS_GTHREADS
   /// once_flag
   struct once_flag
diff --git a/libstdc++-v3/testsuite/30_threads/scoped_lock/cons/1.cc b/libstdc++-v3/testsuite/30_threads/scoped_lock/cons/1.cc
new file mode 100644 (file)
index 0000000..9f1b48c
--- /dev/null
@@ -0,0 +1,133 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2017 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 <mutex>
+#include <testsuite_hooks.h>
+
+struct BasicLockable
+{
+  BasicLockable() : locked(false) { }
+
+  ~BasicLockable() noexcept(false)
+  {
+    if (locked)
+      throw 0;
+  }
+
+  void lock()
+  {
+    if (locked)
+      throw 0;
+    locked = true;
+  }
+
+  void unlock()
+  {
+    if (!locked)
+      throw 0;
+    locked = false;
+  }
+
+  bool locked;
+};
+
+template<int>
+struct Lockable
+{
+  BasicLockable m;
+  void lock() { m.lock(); }
+  void unlock() { m.unlock(); }
+  bool try_lock() { if (m.locked) return false; m.lock(); return true; }
+};
+
+void test01()
+{
+  BasicLockable m;
+
+  try
+    {
+      std::scoped_lock<BasicLockable> l(m);
+      VERIFY( m.locked );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  VERIFY( !m.locked );
+
+  m.lock();
+
+  try
+    {
+      std::scoped_lock<BasicLockable> l(m, std::adopt_lock);
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  VERIFY( !m.locked );
+}
+
+void test02()
+{
+  Lockable<1> m1;
+  Lockable<2> m2;
+
+  try
+    {
+      std::scoped_lock<Lockable<1>, Lockable<2>> l(m1, m2);
+      VERIFY( m1.m.locked );
+      VERIFY( m2.m.locked );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  VERIFY( !m1.m.locked );
+  VERIFY( !m2.m.locked );
+
+  m1.lock();
+  m2.lock();
+
+  try
+    {
+      std::scoped_lock<Lockable<1>, Lockable<2>> l(m1, m2, std::adopt_lock);
+      VERIFY( m1.m.locked );
+      VERIFY( m2.m.locked );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  VERIFY( !m1.m.locked );
+  VERIFY( !m2.m.locked );
+}
+
+int main()
+{
+  test01();
+  test02();
+}
diff --git a/libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/explicit_instantiation.cc
new file mode 100644 (file)
index 0000000..cbf1075
--- /dev/null
@@ -0,0 +1,33 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2017 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 with NO OTHER INCLUDES.
+
+#include <mutex>
+
+namespace std
+{
+  template class scoped_lock<>;
+  template class scoped_lock<mutex>;
+  template class scoped_lock<recursive_mutex, mutex>;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/typedefs.cc b/libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/typedefs.cc
new file mode 100644 (file)
index 0000000..55756d8
--- /dev/null
@@ -0,0 +1,33 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++1z } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2017 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 with NO OTHER INCLUDES.
+
+#include <mutex>
+
+void test01()
+{
+  // Check for required typedefs
+  typedef std::scoped_lock<std::mutex> test_type;
+  typedef test_type::mutex_type mutex_type;
+}