From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id 224C13887F78; Thu, 16 Feb 2023 14:40:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 224C13887F78 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1676558408; bh=VTYQbmyPGDA07DNqcCcTHXNgx+35SwuKHoNsjFgczaQ=; h=From:To:Subject:Date:From; b=s23mY5YBm5fIFEbndR9ddqdC0Qwcr1HOKooVWlRLTKSEl2blyhpw2PE9ZqFvcyUmL FWat4YUHkl94RgsHVDYrJMMCZpQiqXni4dEfVqUoL9OnB6FapWNgOTXJ/jPwn1UeBB MgU57qhzAIyUofXcc91wkAfeEQglfvdl5FMznStQ= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jonathan Wakely To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r13-6087] libstdc++: Implement (P0290) X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/master X-Git-Oldrev: 38f321793ae18d25399f0396ac1371caa7cc7043 X-Git-Newrev: b85c77e19ad9c40231c4050e6ad373b30de7b2b9 Message-Id: <20230216144008.224C13887F78@sourceware.org> Date: Thu, 16 Feb 2023 14:40:08 +0000 (GMT) List-Id: https://gcc.gnu.org/g:b85c77e19ad9c40231c4050e6ad373b30de7b2b9 commit r13-6087-gb85c77e19ad9c40231c4050e6ad373b30de7b2b9 Author: Jonathan Wakely Date: Wed Feb 15 15:07:15 2023 +0000 libstdc++: Implement (P0290) This was approved for the Concurrency TS v2 in Issaquah. Although the TS is based on C++20, this enables the new header for C++17 as well. This will make it available to more users, and I hope that will get more feedback on the feature. libstdc++-v3/ChangeLog: * include/Makefile.am: Add new header. * include/Makefile.in: Regenerate. * include/experimental/synchronized_value: New file. * testsuite/experimental/synchronized_value.cc: New test. Diff: --- libstdc++-v3/include/Makefile.am | 1 + libstdc++-v3/include/Makefile.in | 1 + .../include/experimental/synchronized_value | 100 +++++++++++++++++++++ .../testsuite/experimental/synchronized_value.cc | 42 +++++++++ 4 files changed, 144 insertions(+) diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 5b501272830..a880e8ee227 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -798,6 +798,7 @@ experimental_headers = \ ${experimental_srcdir}/source_location \ ${experimental_srcdir}/string \ ${experimental_srcdir}/string_view \ + ${experimental_srcdir}/synchronized_value \ ${experimental_srcdir}/system_error \ ${experimental_srcdir}/timer \ ${experimental_srcdir}/tuple \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 36e35e13806..0ff875b280b 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -1144,6 +1144,7 @@ experimental_headers = \ ${experimental_srcdir}/source_location \ ${experimental_srcdir}/string \ ${experimental_srcdir}/string_view \ + ${experimental_srcdir}/synchronized_value \ ${experimental_srcdir}/system_error \ ${experimental_srcdir}/timer \ ${experimental_srcdir}/tuple \ diff --git a/libstdc++-v3/include/experimental/synchronized_value b/libstdc++-v3/include/experimental/synchronized_value new file mode 100644 index 00000000000..9a91da912ca --- /dev/null +++ b/libstdc++-v3/include/experimental/synchronized_value @@ -0,0 +1,100 @@ +// -*- C++ -*- + +// Copyright The GNU Toolchain Authors. +// +// 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 +// . + +/** @file include/experimental/synchronized_value + * This is a TS C++ Library header. + * @ingroup libfund-ts + */ + +#ifndef _GLIBCXX_EXPERIMENTAL_SYNCVAL +#define _GLIBCXX_EXPERIMENTAL_SYNCVAL 1 + +#pragma GCC system_header + +#include // for std::mutex + +#if __cplusplus >= 201703L +#include +#include + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION +namespace experimental::inline concurrency_v2 +{ +#define __cpp_lib_concurrency_v2_synchronized_value 202302 + + template + class synchronized_value + { + // TODO: Use partial specialization after PR c++/71954 is fixed. + template + static inline constexpr bool __is_self + = sizeof...(_Args) == 1 + && (is_same_v<__remove_cvref_t<_Args>, synchronized_value> && ...); + +#if ! __cpp_concepts + template + using __not_self = bool_constant>; +#endif + + public: + synchronized_value(const synchronized_value&) = delete; + synchronized_value& operator=(const synchronized_value&) = delete; + +#if __cpp_concepts + template + requires (!__is_self<_Args...>) && is_constructible_v<_Tp, _Args...> +#else + template>, + typename = _Require>> +#endif + synchronized_value(_Args&&... __args) + noexcept(is_nothrow_constructible_v<_Tp, _Args...>) + : _M_val(std::forward<_Args>(__args)...) + { } + + template + friend invoke_result_t<_Fn, _Up&, _Types&...> + apply(_Fn&&, synchronized_value<_Up>&, synchronized_value<_Types>&...); + + private: + mutex _M_mut; + _Tp _M_val; + }; + + template + inline invoke_result_t<_Fn, _Tp&, _Types&...> + apply(_Fn&& __f, synchronized_value<_Tp>& __val, + synchronized_value<_Types>&... __vals) + { + scoped_lock __l(__val._M_mut, __vals._M_mut...); + return std::__invoke(std::forward<_Fn>(__f), __val._M_val, + __vals._M_val...); + } +} // namespace experimental::concurrency_v2 +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std +#endif // C++20 +#endif // _GLIBCXX_EXPERIMENTAL_SYNCVAL diff --git a/libstdc++-v3/testsuite/experimental/synchronized_value.cc b/libstdc++-v3/testsuite/experimental/synchronized_value.cc new file mode 100644 index 00000000000..8e8134699a2 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/synchronized_value.cc @@ -0,0 +1,42 @@ +// { dg-do run { target c++17 } } + +#include +#include +#include + +using std::experimental::synchronized_value; + +synchronized_value s; + +std::string read_value(){ + return apply([](auto& x){return x;},s); +} + +void set_value(std::string const& new_val){ + apply([&](auto& x){ x = new_val; }, s); +} + +void +test_single() +{ + set_value("new value"); + VERIFY( read_value() == "new value" ); +} + +void +test_multi() +{ + synchronized_value a(1), b(2), c(3); + int sum = apply([](auto&... ints) { return (ints++ + ...); }, a, b, c); + VERIFY( sum == 6 ); + auto get = [](int& i) { return i; }; + VERIFY( apply(get, a) == 2 ); + VERIFY( apply(get, b) == 3 ); + VERIFY( apply(get, c) == 4 ); +} + +int main() +{ + test_single(); + test_multi(); +}