aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/boost/scope
diff options
context:
space:
mode:
authorAlexander Smirnov <alex@ydb.tech>2024-10-16 12:11:24 +0000
committerAlexander Smirnov <alex@ydb.tech>2024-10-16 12:11:24 +0000
commit40811e93f3fdf9342a9295369994012420fac548 (patch)
treea8d85e094a9c21e10aa250f537c101fc2016a049 /contrib/restricted/boost/scope
parent30ebe5357bb143648c6be4d151ecd4944af81ada (diff)
parent28a0c4a9f297064538a018c512cd9bbd00a1a35d (diff)
downloadydb-40811e93f3fdf9342a9295369994012420fac548.tar.gz
Merge branch 'rightlib' into mergelibs-241016-1210
Diffstat (limited to 'contrib/restricted/boost/scope')
-rw-r--r--contrib/restricted/boost/scope/.yandex_meta/devtools.copyrights.report91
-rw-r--r--contrib/restricted/boost/scope/.yandex_meta/devtools.licenses.report108
-rw-r--r--contrib/restricted/boost/scope/.yandex_meta/licenses.list.txt48
-rw-r--r--contrib/restricted/boost/scope/LICENSE23
-rw-r--r--contrib/restricted/boost/scope/README.md28
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/defer.hpp180
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/compact_storage.hpp102
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/config.hpp50
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/footer.hpp22
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/header.hpp49
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/is_nonnull_default_constructible.hpp66
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/is_not_like.hpp49
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/move_or_copy_assign_ref.hpp52
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/move_or_copy_construct_ref.hpp52
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/conjunction.hpp53
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/disjunction.hpp53
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_final.hpp53
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_invocable.hpp63
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_nothrow_invocable.hpp69
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_nothrow_swappable.hpp53
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_swappable.hpp53
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/negation.hpp53
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/error_code_checker.hpp103
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/exception_checker.hpp106
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/fd_deleter.hpp82
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/fd_resource_traits.hpp49
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/scope_exit.hpp560
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/scope_fail.hpp265
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/scope_success.hpp309
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/unique_fd.hpp38
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/unique_resource.hpp1642
-rw-r--r--contrib/restricted/boost/scope/include/boost/scope/unique_resource_fwd.hpp46
-rw-r--r--contrib/restricted/boost/scope/ya.make27
33 files changed, 4597 insertions, 0 deletions
diff --git a/contrib/restricted/boost/scope/.yandex_meta/devtools.copyrights.report b/contrib/restricted/boost/scope/.yandex_meta/devtools.copyrights.report
new file mode 100644
index 0000000000..25c80d389e
--- /dev/null
+++ b/contrib/restricted/boost/scope/.yandex_meta/devtools.copyrights.report
@@ -0,0 +1,91 @@
+# File format ($ symbol means the beginning of a line):
+#
+# $ # this message
+# $ # =======================
+# $ # comments (all commentaries should starts with some number of spaces and # symbol)
+# $ IGNORE_FILES {file1.ext1} {file2.ext2} - (optional) ignore listed files when generating license macro and credits
+# $ RENAME {original license id} TO {new license id} # user comments - (optional) use {new license id} instead {original license id} in ya.make files
+# $ # user comments
+# $
+# ${action} {license id} {license text hash}
+# $BELONGS ./ya/make/file/relative/path/1/ya.make ./ya/make/2/ya.make
+# ${all_file_action} filename
+# $ # user commentaries (many lines)
+# $ generated description - files with this license, license text... (some number of lines that starts with some number of spaces, do not modify)
+# ${action} {license spdx} {license text hash}
+# $BELONGS ./ya/make/file/relative/path/3/ya.make
+# ${all_file_action} filename
+# $ # user commentaries
+# $ generated description
+# $ ...
+#
+# You can modify action, all_file_action and add commentaries
+# Available actions:
+# keep - keep license in contrib and use in credits
+# skip - skip license
+# remove - remove all files with this license
+# rename - save license text/links into licenses texts file, but not store SPDX into LINCENSE macro. You should store correct license id into devtools.license.spdx.txt file
+#
+# {all file action} records will be generated when license text contains filename that exists on filesystem (in contrib directory)
+# We suppose that that files can contain some license info
+# Available all file actions:
+# FILE_IGNORE - ignore file (do nothing)
+# FILE_INCLUDE - include all file data into licenses text file
+# =======================
+
+KEEP COPYRIGHT_SERVICE_LABEL 3244b00e8ab273a03f19b20a64c26a96
+BELONGS ya.make
+ License text:
+ * Copyright (c) 2023 Andrey Semashev
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/scope/detail/config.hpp [6:6]
+ include/boost/scope/detail/footer.hpp [6:6]
+ include/boost/scope/detail/header.hpp [6:6]
+ include/boost/scope/detail/is_nonnull_default_constructible.hpp [6:6]
+ include/boost/scope/detail/is_not_like.hpp [6:6]
+ include/boost/scope/detail/type_traits/conjunction.hpp [6:6]
+ include/boost/scope/detail/type_traits/disjunction.hpp [6:6]
+ include/boost/scope/detail/type_traits/is_final.hpp [6:6]
+ include/boost/scope/detail/type_traits/is_invocable.hpp [6:6]
+ include/boost/scope/detail/type_traits/is_nothrow_invocable.hpp [6:6]
+ include/boost/scope/detail/type_traits/is_nothrow_swappable.hpp [6:6]
+ include/boost/scope/detail/type_traits/is_swappable.hpp [6:6]
+ include/boost/scope/detail/type_traits/negation.hpp [6:6]
+ include/boost/scope/error_code_checker.hpp [6:6]
+ include/boost/scope/exception_checker.hpp [6:6]
+ include/boost/scope/fd_deleter.hpp [6:6]
+ include/boost/scope/fd_resource_traits.hpp [6:6]
+ include/boost/scope/scope_exit.hpp [6:6]
+ include/boost/scope/unique_fd.hpp [6:6]
+
+KEEP COPYRIGHT_SERVICE_LABEL 3f6ec3343e75c2c0c0e1e8956ffabc65
+BELONGS ya.make
+ License text:
+ * Copyright (c) 2022-2024 Andrey Semashev
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/scope/defer.hpp [6:6]
+ include/boost/scope/unique_resource.hpp [6:6]
+
+KEEP COPYRIGHT_SERVICE_LABEL 45666b61e7d8667b41556a93c064e0e8
+BELONGS ya.make
+ License text:
+ * Copyright (c) 2022 Andrey Semashev
+ Scancode info:
+ Original SPDX id: COPYRIGHT_SERVICE_LABEL
+ Score : 100.00
+ Match type : COPYRIGHT
+ Files with this license:
+ include/boost/scope/detail/compact_storage.hpp [6:6]
+ include/boost/scope/detail/move_or_copy_assign_ref.hpp [6:6]
+ include/boost/scope/detail/move_or_copy_construct_ref.hpp [6:6]
+ include/boost/scope/scope_fail.hpp [6:6]
+ include/boost/scope/scope_success.hpp [6:6]
+ include/boost/scope/unique_resource_fwd.hpp [6:6]
diff --git a/contrib/restricted/boost/scope/.yandex_meta/devtools.licenses.report b/contrib/restricted/boost/scope/.yandex_meta/devtools.licenses.report
new file mode 100644
index 0000000000..6fe13bd0ea
--- /dev/null
+++ b/contrib/restricted/boost/scope/.yandex_meta/devtools.licenses.report
@@ -0,0 +1,108 @@
+# File format ($ symbol means the beginning of a line):
+#
+# $ # this message
+# $ # =======================
+# $ # comments (all commentaries should starts with some number of spaces and # symbol)
+# $ IGNORE_FILES {file1.ext1} {file2.ext2} - (optional) ignore listed files when generating license macro and credits
+# $ RENAME {original license id} TO {new license id} # user comments - (optional) use {new license id} instead {original license id} in ya.make files
+# $ # user comments
+# $
+# ${action} {license id} {license text hash}
+# $BELONGS ./ya/make/file/relative/path/1/ya.make ./ya/make/2/ya.make
+# ${all_file_action} filename
+# $ # user commentaries (many lines)
+# $ generated description - files with this license, license text... (some number of lines that starts with some number of spaces, do not modify)
+# ${action} {license spdx} {license text hash}
+# $BELONGS ./ya/make/file/relative/path/3/ya.make
+# ${all_file_action} filename
+# $ # user commentaries
+# $ generated description
+# $ ...
+#
+# You can modify action, all_file_action and add commentaries
+# Available actions:
+# keep - keep license in contrib and use in credits
+# skip - skip license
+# remove - remove all files with this license
+# rename - save license text/links into licenses texts file, but not store SPDX into LINCENSE macro. You should store correct license id into devtools.license.spdx.txt file
+#
+# {all file action} records will be generated when license text contains filename that exists on filesystem (in contrib directory)
+# We suppose that that files can contain some license info
+# Available all file actions:
+# FILE_IGNORE - ignore file (do nothing)
+# FILE_INCLUDE - include all file data into licenses text file
+# =======================
+
+KEEP BSL-1.0 2077ca9d01c7e6d6029ec1763233c5b0
+BELONGS ya.make
+ License text:
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 100.00
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ include/boost/scope/defer.hpp [2:4]
+ include/boost/scope/detail/compact_storage.hpp [2:4]
+ include/boost/scope/detail/config.hpp [2:4]
+ include/boost/scope/detail/footer.hpp [2:4]
+ include/boost/scope/detail/header.hpp [2:4]
+ include/boost/scope/detail/is_nonnull_default_constructible.hpp [2:4]
+ include/boost/scope/detail/is_not_like.hpp [2:4]
+ include/boost/scope/detail/move_or_copy_assign_ref.hpp [2:4]
+ include/boost/scope/detail/move_or_copy_construct_ref.hpp [2:4]
+ include/boost/scope/detail/type_traits/conjunction.hpp [2:4]
+ include/boost/scope/detail/type_traits/disjunction.hpp [2:4]
+ include/boost/scope/detail/type_traits/is_final.hpp [2:4]
+ include/boost/scope/detail/type_traits/is_invocable.hpp [2:4]
+ include/boost/scope/detail/type_traits/is_nothrow_invocable.hpp [2:4]
+ include/boost/scope/detail/type_traits/is_nothrow_swappable.hpp [2:4]
+ include/boost/scope/detail/type_traits/is_swappable.hpp [2:4]
+ include/boost/scope/detail/type_traits/negation.hpp [2:4]
+ include/boost/scope/error_code_checker.hpp [2:4]
+ include/boost/scope/exception_checker.hpp [2:4]
+ include/boost/scope/fd_deleter.hpp [2:4]
+ include/boost/scope/fd_resource_traits.hpp [2:4]
+ include/boost/scope/scope_exit.hpp [2:4]
+ include/boost/scope/scope_fail.hpp [2:4]
+ include/boost/scope/scope_success.hpp [2:4]
+ include/boost/scope/unique_fd.hpp [2:4]
+ include/boost/scope/unique_resource.hpp [2:4]
+ include/boost/scope/unique_resource_fwd.hpp [2:4]
+
+KEEP BSL-1.0 2c7a3fa82e66676005cd4ee2608fd7d2
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 100.00
+ Match type : TEXT
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ LICENSE [1:23]
+
+KEEP BSL-1.0 49af97cadb10453f2b05003f793e4adc
+BELONGS ya.make
+ License text:
+ Distributed under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 94.44
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ README.md [28:28]
+
+KEEP BSL-1.0 a5006bb276a0e8fcc0c080cd5a14814e
+BELONGS ya.make
+ Note: matched license text is too long. Read it in the source files.
+ Scancode info:
+ Original SPDX id: BSL-1.0
+ Score : 55.00
+ Match type : NOTICE
+ Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
+ Files with this license:
+ README.md [17:17]
diff --git a/contrib/restricted/boost/scope/.yandex_meta/licenses.list.txt b/contrib/restricted/boost/scope/.yandex_meta/licenses.list.txt
new file mode 100644
index 0000000000..6790a8ddab
--- /dev/null
+++ b/contrib/restricted/boost/scope/.yandex_meta/licenses.list.txt
@@ -0,0 +1,48 @@
+====================BSL-1.0====================
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+
+
+====================BSL-1.0====================
+* Submit your patches as [pull requests](https://github.com/boostorg/scope/compare) against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
+
+
+====================BSL-1.0====================
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+====================BSL-1.0====================
+Distributed under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
+
+====================COPYRIGHT====================
+ * Copyright (c) 2022 Andrey Semashev
+
+
+====================COPYRIGHT====================
+ * Copyright (c) 2022-2024 Andrey Semashev
+
+
+====================COPYRIGHT====================
+ * Copyright (c) 2023 Andrey Semashev
diff --git a/contrib/restricted/boost/scope/LICENSE b/contrib/restricted/boost/scope/LICENSE
new file mode 100644
index 0000000000..36b7cd93cd
--- /dev/null
+++ b/contrib/restricted/boost/scope/LICENSE
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/contrib/restricted/boost/scope/README.md b/contrib/restricted/boost/scope/README.md
new file mode 100644
index 0000000000..21bc1f403c
--- /dev/null
+++ b/contrib/restricted/boost/scope/README.md
@@ -0,0 +1,28 @@
+# Boost.Scope
+
+Boost.Scope provides a number of scope guard utilities and a `unique_resource` wrapper, similar to those described in
+[C++ Extensions for Library Fundamentals, Version 3](https://github.com/cplusplus/fundamentals-ts/releases/tag/n4908),
+Section 3.3 Scope guard support \[scopeguard\]. The implementation also provides a few non-standard extensions.
+
+### Directories
+
+* **doc** - QuickBook documentation sources
+* **include** - Interface headers of Boost.Scope
+* **test** - Boost.Scope unit tests
+
+### More information
+
+* Read the [documentation](https://www.boost.org/libs/scope/).
+* [Report bugs](https://github.com/boostorg/scope/issues/new). Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
+* Submit your patches as [pull requests](https://github.com/boostorg/scope/compare) against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
+
+### Build status
+
+Branch | GitHub Actions| Test Matrix | Dependencies |
+:-------------: | --------------| ----------- | ------------ |
+[`master`](https://github.com/boostorg/scope/tree/master) | [![GitHub Actions](https://github.com/boostorg/scope/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/scope/actions?query=branch%3Amaster) | [![Tests](https://img.shields.io/badge/matrix-master-brightgreen.svg)](https://www.boost.org/development/tests/master/developer/scope.html) | [![Dependencies](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/scope.html)
+[`develop`](https://github.com/boostorg/scope/tree/develop) | [![GitHub Actions](https://github.com/boostorg/scope/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/scope/actions?query=branch%3Adevelop) | [![Tests](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](https://www.boost.org/development/tests/develop/developer/scope.html) | [![Dependencies](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/scope.html)
+
+### License
+
+Distributed under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
diff --git a/contrib/restricted/boost/scope/include/boost/scope/defer.hpp b/contrib/restricted/boost/scope/include/boost/scope/defer.hpp
new file mode 100644
index 0000000000..988f976536
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/defer.hpp
@@ -0,0 +1,180 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2022-2024 Andrey Semashev
+ */
+/*!
+ * \file scope/defer.hpp
+ *
+ * This header contains definition of \c defer_guard template.
+ */
+
+#ifndef BOOST_SCOPE_DEFER_HPP_INCLUDED_
+#define BOOST_SCOPE_DEFER_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/detail/is_not_like.hpp>
+#include <boost/scope/detail/move_or_copy_construct_ref.hpp>
+#include <boost/scope/detail/type_traits/conjunction.hpp>
+#include <boost/scope/detail/type_traits/is_nothrow_invocable.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+
+template< typename Func >
+class defer_guard;
+
+namespace detail {
+
+// Workaround for clang < 5.0 which can't pass defer_guard as a template template parameter from within defer_guard definition
+template< typename T >
+using is_not_like_defer_guard = detail::is_not_like< T, defer_guard >;
+
+} // namespace detail
+
+/*!
+ * \brief Defer guard that invokes a function upon leaving the scope.
+ *
+ * The scope guard wraps a function object callable with no arguments
+ * that can be one of:
+ *
+ * \li A user-defined class with a public `operator()`.
+ * \li An lvalue reference to such class.
+ * \li An lvalue reference or pointer to function taking no arguments.
+ *
+ * The defer guard unconditionally invokes the wrapped function object
+ * on destruction.
+ */
+template< typename Func >
+class defer_guard
+{
+//! \cond
+private:
+ struct data
+ {
+ Func m_func;
+
+ template< typename F, typename = typename std::enable_if< std::is_constructible< Func, F >::value >::type >
+ explicit data(F&& func, std::true_type) noexcept :
+ m_func(static_cast< F&& >(func))
+ {
+ }
+
+ template< typename F, typename = typename std::enable_if< std::is_constructible< Func, F >::value >::type >
+ explicit data(F&& func, std::false_type) try :
+ m_func(static_cast< F&& >(func))
+ {
+ }
+ catch (...)
+ {
+ func();
+ }
+ };
+
+ data m_data;
+
+//! \endcond
+public:
+ /*!
+ * \brief Constructs a defer guard with a given callable function object.
+ *
+ * **Requires:** \c Func is constructible from \a func.
+ *
+ * **Effects:** If \c Func is nothrow constructible from `F&&` then constructs \c Func from
+ * `std::forward< F >(func)`, otherwise constructs from `func`.
+ *
+ * If \c Func construction throws, invokes \a func before returning with the exception.
+ *
+ * **Throws:** Nothing, unless construction of the function object throws.
+ *
+ * \param func The callable function object to invoke on destruction.
+ */
+ template<
+ typename F
+ //! \cond
+ , typename = typename std::enable_if< detail::conjunction<
+ std::is_constructible<
+ data,
+ typename detail::move_or_copy_construct_ref< F, Func >::type,
+ typename std::is_nothrow_constructible< Func, typename detail::move_or_copy_construct_ref< F, Func >::type >::type
+ >,
+ detail::is_not_like_defer_guard< F >
+ >::value >::type
+ //! \endcond
+ >
+ defer_guard(F&& func)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
+ std::is_nothrow_constructible<
+ data,
+ typename detail::move_or_copy_construct_ref< F, Func >::type,
+ typename std::is_nothrow_constructible< Func, typename detail::move_or_copy_construct_ref< F, Func >::type >::type
+ >::value
+ )) :
+ m_data
+ (
+ static_cast< typename detail::move_or_copy_construct_ref< F, Func >::type >(func),
+ typename std::is_nothrow_constructible< Func, typename detail::move_or_copy_construct_ref< F, Func >::type >::type()
+ )
+ {
+ }
+
+ defer_guard(defer_guard const&) = delete;
+ defer_guard& operator= (defer_guard const&) = delete;
+
+ /*!
+ * \brief Invokes the wrapped callable function object and destroys the callable.
+ *
+ * **Throws:** Nothing, unless invoking the callable throws.
+ */
+ ~defer_guard() noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(detail::is_nothrow_invocable< Func& >::value))
+ {
+ m_data.m_func();
+ }
+};
+
+#if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
+template< typename Func >
+defer_guard(Func) -> defer_guard< Func >;
+#endif // !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
+
+} // namespace scope
+
+//! \cond
+#if defined(BOOST_MSVC)
+#define BOOST_SCOPE_DETAIL_UNIQUE_VAR_TAG __COUNTER__
+#else
+#define BOOST_SCOPE_DETAIL_UNIQUE_VAR_TAG __LINE__
+#endif
+//! \endcond
+
+/*!
+ * \brief The macro creates a uniquely named defer guard.
+ *
+ * The macro should be followed by a function object that should be called
+ * on leaving the current scope. Usage example:
+ *
+ * ```
+ * BOOST_SCOPE_DEFER []
+ * {
+ * std::cout << "Hello world!" << std::endl;
+ * };
+ * ```
+ *
+ * \note Using this macro requires C++17.
+ */
+#define BOOST_SCOPE_DEFER \
+ boost::scope::defer_guard BOOST_JOIN(_boost_defer_guard_, BOOST_SCOPE_DETAIL_UNIQUE_VAR_TAG) =
+
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_DEFER_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/compact_storage.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/compact_storage.hpp
new file mode 100644
index 0000000000..b619e3f7d3
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/compact_storage.hpp
@@ -0,0 +1,102 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2022 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/compact_storage.hpp
+ *
+ * This header contains utility helpers for implementing compact storage
+ * for class members. In particular, it allows to leverage empty base optimization (EBO).
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_COMPACT_STORAGE_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_COMPACT_STORAGE_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/detail/type_traits/is_final.hpp>
+#include <boost/scope/detail/type_traits/negation.hpp>
+#include <boost/scope/detail/type_traits/conjunction.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+//! The class allows to place data members in the tail padding of type \a T if the user's class derives from it
+template<
+ typename T,
+ typename Tag = void,
+ bool = detail::conjunction< std::is_class< T >, detail::negation< detail::is_final< T > > >::value
+>
+class compact_storage :
+ private T
+{
+public:
+ template< typename... Args >
+ constexpr compact_storage(Args&&... args) noexcept(std::is_nothrow_constructible< T, Args... >::value) :
+ T(static_cast< Args&& >(args)...)
+ {
+ }
+
+ compact_storage(compact_storage&&) = default;
+ compact_storage& operator= (compact_storage&&) = default;
+
+ compact_storage(compact_storage const&) = default;
+ compact_storage& operator= (compact_storage const&) = default;
+
+ T& get() noexcept
+ {
+ return *static_cast< T* >(this);
+ }
+
+ T const& get() const noexcept
+ {
+ return *static_cast< const T* >(this);
+ }
+};
+
+template< typename T, typename Tag >
+class compact_storage< T, Tag, false >
+{
+private:
+ T m_data;
+
+public:
+ template< typename... Args >
+ constexpr compact_storage(Args&&... args) noexcept(std::is_nothrow_constructible< T, Args... >::value) :
+ m_data(static_cast< Args&& >(args)...)
+ {
+ }
+
+ compact_storage(compact_storage&&) = default;
+ compact_storage& operator= (compact_storage&&) = default;
+
+ compact_storage(compact_storage const&) = default;
+ compact_storage& operator= (compact_storage const&) = default;
+
+ T& get() noexcept
+ {
+ return m_data;
+ }
+
+ T const& get() const noexcept
+ {
+ return m_data;
+ }
+};
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_DETAIL_COMPACT_STORAGE_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/config.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/config.hpp
new file mode 100644
index 0000000000..26821ea344
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/config.hpp
@@ -0,0 +1,50 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/config.hpp
+ *
+ * This header contains Boost.Scope common configuration.
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_CONFIG_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_CONFIG_HPP_INCLUDED_
+
+#include <boost/config.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if !(defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510l) && !defined(_NOEXCEPT_TYPES_SUPPORTED)
+#define BOOST_SCOPE_NO_CXX17_NOEXCEPT_FUNCTION_TYPES
+#endif
+
+#if !defined(BOOST_SCOPE_DETAIL_DOC_ALT)
+#if !defined(BOOST_SCOPE_DOXYGEN)
+#define BOOST_SCOPE_DETAIL_DOC_ALT(alt, ...) __VA_ARGS__
+#else
+#define BOOST_SCOPE_DETAIL_DOC_ALT(alt, ...) alt
+#endif
+#endif
+
+#if !defined(BOOST_SCOPE_DETAIL_DOC_HIDDEN)
+#define BOOST_SCOPE_DETAIL_DOC_HIDDEN(...) BOOST_SCOPE_DETAIL_DOC_ALT(..., __VA_ARGS__)
+#endif
+
+#if !defined(BOOST_SCOPE_DETAIL_DOC)
+#if !defined(BOOST_SCOPE_DOXYGEN)
+#define BOOST_SCOPE_DETAIL_DOC(...)
+#else
+#define BOOST_SCOPE_DETAIL_DOC(...) __VA_ARGS__
+#endif
+#endif
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_DETAIL_CONFIG_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/footer.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/footer.hpp
new file mode 100644
index 0000000000..2d9b12e6ba
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/footer.hpp
@@ -0,0 +1,22 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+
+#if !defined(BOOST_SCOPE_ENABLE_WARNINGS)
+
+#if defined(_MSC_VER) && !defined(__clang__)
+
+#pragma warning(pop)
+
+#elif (defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) \
+ && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406) || defined(__clang__)
+
+#pragma GCC diagnostic pop
+
+#endif
+
+#endif // !defined(BOOST_SCOPE_ENABLE_WARNINGS)
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/header.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/header.hpp
new file mode 100644
index 0000000000..fc99f16cf1
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/header.hpp
@@ -0,0 +1,49 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+
+#if !defined(BOOST_SCOPE_ENABLE_WARNINGS)
+
+#if defined(_MSC_VER) && !defined(__clang__)
+
+#pragma warning(push, 3)
+// unreferenced formal parameter
+#pragma warning(disable: 4100)
+// conditional expression is constant
+#pragma warning(disable: 4127)
+// function marked as __forceinline not inlined
+#pragma warning(disable: 4714)
+// decorated name length exceeded, name was truncated
+#pragma warning(disable: 4503)
+// qualifier applied to function type has no meaning; ignored
+#pragma warning(disable: 4180)
+// qualifier applied to reference type; ignored
+#pragma warning(disable: 4181)
+// unreachable code
+#pragma warning(disable: 4702)
+// destructor never returns, potential memory leak
+#pragma warning(disable: 4722)
+
+#elif (defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) \
+ && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406) || defined(__clang__)
+
+// Note: clang-cl goes here as well, as it seems to support gcc-style warning control pragmas.
+
+#pragma GCC diagnostic push
+// unused parameter 'arg'
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+// unused function 'foo'
+#pragma GCC diagnostic ignored "-Wunused-function"
+
+#if defined(__clang__)
+// template argument uses unnamed type
+#pragma clang diagnostic ignored "-Wunnamed-type-template-args"
+#endif // defined(__clang__)
+
+#endif
+
+#endif // !defined(BOOST_SCOPE_ENABLE_WARNINGS)
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/is_nonnull_default_constructible.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/is_nonnull_default_constructible.hpp
new file mode 100644
index 0000000000..e6e86474f4
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/is_nonnull_default_constructible.hpp
@@ -0,0 +1,66 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/is_nonnull_default_constructible.hpp
+ *
+ * This header contains definition of \c is_nonnull_default_constructible
+ * and \c is_nothrow_nonnull_default_constructible type traits. The type
+ * traits are useful for preventing default-construction of pointers to
+ * functions where a default-constructed function object is expected.
+ * Without it, default- or value-constructing a pointer to function would
+ * produce a function object that is not callable.
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_IS_NONNULL_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_IS_NONNULL_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+//! The type trait checks if \c T is not a pointer and is default-constructible
+template< typename T >
+struct is_nonnull_default_constructible :
+ public std::is_default_constructible< T >
+{
+};
+
+template< typename T >
+struct is_nonnull_default_constructible< T* > :
+ public std::false_type
+{
+};
+
+//! The type trait checks if \c T is not a pointer and is nothrow-default-constructible
+template< typename T >
+struct is_nothrow_nonnull_default_constructible :
+ public std::is_nothrow_default_constructible< T >
+{
+};
+
+template< typename T >
+struct is_nothrow_nonnull_default_constructible< T* > :
+ public std::false_type
+{
+};
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_DETAIL_IS_NONNULL_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/is_not_like.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/is_not_like.hpp
new file mode 100644
index 0000000000..3f07fa8023
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/is_not_like.hpp
@@ -0,0 +1,49 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/is_not_like.hpp
+ *
+ * This header contains definition of \c is_not_like type trait.
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_IS_NOT_LIKE_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_IS_NOT_LIKE_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+//! The type trait checks if \c T is not a possibly cv-reference-qualified specialization of \c Template
+template< typename T, template< typename... > class Template >
+struct is_not_like : public std::true_type { };
+template< typename T, template< typename... > class Template >
+struct is_not_like< T&, Template > : public is_not_like< T, Template > { };
+template< template< typename... > class Template, typename... Ts >
+struct is_not_like< Template< Ts... >, Template > : public std::false_type { };
+template< template< typename... > class Template, typename... Ts >
+struct is_not_like< const Template< Ts... >, Template > : public std::false_type { };
+template< template< typename... > class Template, typename... Ts >
+struct is_not_like< volatile Template< Ts... >, Template > : public std::false_type { };
+template< template< typename... > class Template, typename... Ts >
+struct is_not_like< const volatile Template< Ts... >, Template > : public std::false_type { };
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_DETAIL_IS_NOT_LIKE_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/move_or_copy_assign_ref.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/move_or_copy_assign_ref.hpp
new file mode 100644
index 0000000000..0e270f8c1b
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/move_or_copy_assign_ref.hpp
@@ -0,0 +1,52 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2022 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/move_or_copy_assign_ref.hpp
+ *
+ * This header contains definition of \c move_or_copy_assign_ref type trait.
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_MOVE_OR_COPY_ASSIGN_REF_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_MOVE_OR_COPY_ASSIGN_REF_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+//! The type trait produces an rvalue reference to \a From if \a To has a non-throwing assignment from a \a From rvalue and an lvalue reference otherwise.
+template< typename From, typename To = From >
+struct move_or_copy_assign_ref
+{
+ using type = typename std::conditional<
+ std::is_nothrow_assignable< To, From >::value,
+ From&&,
+ From const&
+ >::type;
+};
+
+template< typename From, typename To >
+struct move_or_copy_assign_ref< From&, To >
+{
+ using type = From&;
+};
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_DETAIL_MOVE_OR_COPY_ASSIGN_REF_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/move_or_copy_construct_ref.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/move_or_copy_construct_ref.hpp
new file mode 100644
index 0000000000..b3d3796868
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/move_or_copy_construct_ref.hpp
@@ -0,0 +1,52 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2022 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/move_or_copy_construct_ref.hpp
+ *
+ * This header contains definition of \c move_or_copy_construct_ref type trait.
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_MOVE_OR_COPY_CONSTRUCT_REF_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_MOVE_OR_COPY_CONSTRUCT_REF_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+//! The type trait produces an rvalue reference to \a From if \a To has a non-throwing constructor from a \a From rvalue and an lvalue reference otherwise.
+template< typename From, typename To = From >
+struct move_or_copy_construct_ref
+{
+ using type = typename std::conditional<
+ std::is_nothrow_constructible< To, From >::value,
+ From&&,
+ From const&
+ >::type;
+};
+
+template< typename From, typename To >
+struct move_or_copy_construct_ref< From&, To >
+{
+ using type = From&;
+};
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_DETAIL_MOVE_OR_COPY_CONSTRUCT_REF_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/conjunction.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/conjunction.hpp
new file mode 100644
index 0000000000..497f5721d2
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/conjunction.hpp
@@ -0,0 +1,53 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/type_traits/conjunction.hpp
+ *
+ * This header contains definition of \c conjunction type trait.
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_TYPE_TRAITS_CONJUNCTION_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_TYPE_TRAITS_CONJUNCTION_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if (defined(__cpp_lib_logical_traits) && (__cpp_lib_logical_traits >= 201510l)) || \
+ (defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190023918) && (BOOST_CXX_VERSION >= 201703l))
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using std::conjunction;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#else
+
+#include <boost/type_traits/conjunction.hpp>
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using boost::conjunction;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#endif
+
+#endif // BOOST_SCOPE_DETAIL_TYPE_TRAITS_CONJUNCTION_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/disjunction.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/disjunction.hpp
new file mode 100644
index 0000000000..af1532dede
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/disjunction.hpp
@@ -0,0 +1,53 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/type_traits/disjunction.hpp
+ *
+ * This header contains definition of \c disjunction type trait.
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_TYPE_TRAITS_DISJUNCTION_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_TYPE_TRAITS_DISJUNCTION_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if (defined(__cpp_lib_logical_traits) && (__cpp_lib_logical_traits >= 201510l)) || \
+ (defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190023918) && (BOOST_CXX_VERSION >= 201703l))
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using std::disjunction;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#else
+
+#include <boost/type_traits/disjunction.hpp>
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using boost::disjunction;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#endif
+
+#endif // BOOST_SCOPE_DETAIL_TYPE_TRAITS_DISJUNCTION_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_final.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_final.hpp
new file mode 100644
index 0000000000..57a2bf255b
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_final.hpp
@@ -0,0 +1,53 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/type_traits/is_final.hpp
+ *
+ * This header contains definition of \c is_final type trait.
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_FINAL_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_FINAL_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if (defined(__cpp_lib_is_final) && (__cpp_lib_is_final >= 201402l)) || \
+ (defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (BOOST_CXX_VERSION >= 201402l))
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using std::is_final;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#else
+
+#include <boost/type_traits/is_final.hpp>
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using boost::is_final;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#endif
+
+#endif // BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_FINAL_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_invocable.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_invocable.hpp
new file mode 100644
index 0000000000..987bf1b10b
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_invocable.hpp
@@ -0,0 +1,63 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/type_traits/is_invocable.hpp
+ *
+ * This header contains definition of \c is_invocable type trait.
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_INVOCABLE_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_INVOCABLE_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if (defined(__cpp_lib_is_invocable) && (__cpp_lib_is_invocable >= 201703l)) || \
+ (defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (BOOST_CXX_VERSION >= 201703l))
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using std::is_invocable;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#else
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+// A simplified implementation that does not support member function pointers
+template< typename Func, typename... Args >
+struct is_invocable_impl
+{
+ template< typename F = Func, typename = decltype(std::declval< F >()(std::declval< Args >()...)) >
+ static std::true_type _check_invocable(int);
+ static std::false_type _check_invocable(...);
+
+ using type = decltype(is_invocable_impl::_check_invocable(0));
+};
+
+template< typename Func, typename... Args >
+struct is_invocable : public is_invocable_impl< Func, Args... >::type { };
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#endif
+
+#endif // BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_INVOCABLE_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_nothrow_invocable.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_nothrow_invocable.hpp
new file mode 100644
index 0000000000..5510a5fb0a
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_nothrow_invocable.hpp
@@ -0,0 +1,69 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/type_traits/is_nothrow_invocable.hpp
+ *
+ * This header contains definition of \c is_nothrow_invocable type trait.
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_NOTHROW_INVOCABLE_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_NOTHROW_INVOCABLE_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if (defined(__cpp_lib_is_invocable) && (__cpp_lib_is_invocable >= 201703l)) || \
+ (defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (BOOST_CXX_VERSION >= 201703l))
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using std::is_nothrow_invocable;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#else
+
+#include <boost/scope/detail/type_traits/is_invocable.hpp>
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+template< bool, typename Func, typename... Args >
+struct is_nothrow_invocable_impl
+{
+ using type = std::false_type;
+};
+
+template< typename Func, typename... Args >
+struct is_nothrow_invocable_impl< true, Func, Args... >
+{
+ using type = std::integral_constant< bool, noexcept(std::declval< Func >()(std::declval< Args >()...)) >;
+};
+
+template< typename Func, typename... Args >
+struct is_nothrow_invocable :
+ public is_nothrow_invocable_impl< detail::is_invocable< Func, Args... >::value, Func, Args... >::type
+{
+};
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#endif
+
+#endif // BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_NOTHROW_INVOCABLE_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_nothrow_swappable.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_nothrow_swappable.hpp
new file mode 100644
index 0000000000..08e3171655
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_nothrow_swappable.hpp
@@ -0,0 +1,53 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/type_traits/is_nothrow_swappable.hpp
+ *
+ * This header contains definition of \c is_nothrow_swappable type trait.
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_NOTHROW_SWAPPABLE_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_NOTHROW_SWAPPABLE_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if (defined(__cpp_lib_is_swappable) && (__cpp_lib_is_swappable >= 201603l)) || \
+ (defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190024210) && (BOOST_CXX_VERSION >= 201703l))
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using std::is_nothrow_swappable;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#else
+
+#include <boost/type_traits/is_nothrow_swappable.hpp>
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using boost::is_nothrow_swappable;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#endif
+
+#endif // BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_NOTHROW_SWAPPABLE_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_swappable.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_swappable.hpp
new file mode 100644
index 0000000000..c84a147913
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/is_swappable.hpp
@@ -0,0 +1,53 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/type_traits/is_swappable.hpp
+ *
+ * This header contains definition of \c is_swappable type trait.
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_SWAPPABLE_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_SWAPPABLE_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if (defined(__cpp_lib_is_swappable) && (__cpp_lib_is_swappable >= 201603l)) || \
+ (defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190024210) && (BOOST_CXX_VERSION >= 201703l))
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using std::is_swappable;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#else
+
+#include <boost/type_traits/is_swappable.hpp>
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using boost::is_swappable;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#endif
+
+#endif // BOOST_SCOPE_DETAIL_TYPE_TRAITS_IS_SWAPPABLE_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/negation.hpp b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/negation.hpp
new file mode 100644
index 0000000000..f78f52f22c
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/detail/type_traits/negation.hpp
@@ -0,0 +1,53 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/detail/type_traits/negation.hpp
+ *
+ * This header contains definition of \c negation type trait.
+ */
+
+#ifndef BOOST_SCOPE_DETAIL_TYPE_TRAITS_NEGATION_HPP_INCLUDED_
+#define BOOST_SCOPE_DETAIL_TYPE_TRAITS_NEGATION_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if (defined(__cpp_lib_logical_traits) && (__cpp_lib_logical_traits >= 201510l)) || \
+ (defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190023918) && (BOOST_CXX_VERSION >= 201703l))
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using std::negation;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#else
+
+#include <boost/type_traits/negation.hpp>
+
+namespace boost {
+namespace scope {
+namespace detail {
+
+using boost::negation;
+
+} // namespace detail
+} // namespace scope
+} // namespace boost
+
+#endif
+
+#endif // BOOST_SCOPE_DETAIL_TYPE_TRAITS_NEGATION_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/error_code_checker.hpp b/contrib/restricted/boost/scope/include/boost/scope/error_code_checker.hpp
new file mode 100644
index 0000000000..1481e14f52
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/error_code_checker.hpp
@@ -0,0 +1,103 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/error_code_checker.hpp
+ *
+ * This header contains definition of \c error_code_checker type.
+ */
+
+#ifndef BOOST_SCOPE_ERROR_CODE_CHECKER_HPP_INCLUDED_
+#define BOOST_SCOPE_ERROR_CODE_CHECKER_HPP_INCLUDED_
+
+#include <boost/core/addressof.hpp>
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+
+/*!
+ * \brief A predicate for checking whether an error code indicates error.
+ *
+ * The predicate captures a reference to an external error code object, which it
+ * tests for an error indication when called. The error code object must remain
+ * valid for the whole lifetime duration of the predicate.
+ *
+ * For an error code object `ec`, an expression `!ec` must be valid, never throw exceptions,
+ * and return a value contextually convertible to `bool`. If the returned value converts
+ * to `false`, then this is taken as an error indication, and the predicate returns `true`.
+ * Otherwise, the predicate returns `false`.
+ *
+ * A few examples of error code types:
+ *
+ * \li `std::error_code` or `boost::system::error_code`,
+ * \li `std::expected`, `boost::outcome_v2::basic_outcome` or `boost::outcome_v2::basic_result`,
+ * \li `int`, where the value of 0 indicates no error,
+ * \li `bool`, where the value of `false` indicates no error,
+ * \li `T*`, where a null pointer indicates no error.
+ *
+ * \tparam ErrorCode Error code type.
+ */
+template< typename ErrorCode >
+class error_code_checker
+{
+public:
+ //! Predicate result type
+ using result_type = bool;
+
+private:
+ ErrorCode* m_error_code;
+
+public:
+ /*!
+ * \brief Constructs the predicate.
+ *
+ * Upon construction, the predicate saves a reference to the external error code object.
+ * The referenced object must remain valid for the whole lifetime duration of the predicate.
+ *
+ * **Throws:** Nothing.
+ */
+ explicit error_code_checker(ErrorCode& ec) noexcept :
+ m_error_code(boost::addressof(ec))
+ {
+ }
+
+ /*!
+ * \brief Checks if the error code indicates error.
+ *
+ * **Throws:** Nothing.
+ *
+ * \returns As if `!!ec`, where `ec` is the error code object passed to the predicate constructor.
+ */
+ result_type operator()() const noexcept
+ {
+ return !!(*m_error_code);
+ }
+};
+
+/*!
+ * \brief Creates a predicate for checking whether an exception is being thrown
+ *
+ * **Throws:** Nothing.
+ */
+template< typename ErrorCode >
+inline error_code_checker< ErrorCode > check_error_code(ErrorCode& ec) noexcept
+{
+ return error_code_checker< ErrorCode >(ec);
+}
+
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_ERROR_CODE_CHECKER_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/exception_checker.hpp b/contrib/restricted/boost/scope/include/boost/scope/exception_checker.hpp
new file mode 100644
index 0000000000..a46b4801b7
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/exception_checker.hpp
@@ -0,0 +1,106 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/exception_checker.hpp
+ *
+ * This header contains definition of \c exception_checker type.
+ */
+
+#ifndef BOOST_SCOPE_EXCEPTION_CHECKER_HPP_INCLUDED_
+#define BOOST_SCOPE_EXCEPTION_CHECKER_HPP_INCLUDED_
+
+#include <boost/assert.hpp>
+#include <boost/scope/detail/config.hpp>
+#include <boost/core/uncaught_exceptions.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+
+/*!
+ * \brief A predicate for checking whether an exception is being thrown.
+ *
+ * On construction, the predicate captures the current number of uncaught exceptions,
+ * which it then compares with the number of uncaught exceptions at the point when it
+ * is called. If the number increased then a new exception is detected and the predicate
+ * returns \c true.
+ *
+ * \note This predicate is designed for a specific use case with scope guards created on
+ * the stack. It is incompatible with C++20 coroutines and similar facilities (e.g.
+ * fibers and userspace context switching), where the thread of execution may be
+ * suspended after the predicate captures the number of uncaught exceptions and
+ * then resumed in a different context, where the number of uncaught exceptions
+ * has changed. Similarly, it is incompatible with usage patterns where the predicate
+ * is cached after construction and is invoked after the thread has left the scope
+ * where the predicate was constructed (e.g. when the predicate is stored as a class
+ * data member or a namespace-scope variable).
+ */
+class exception_checker
+{
+public:
+ //! Predicate result type
+ using result_type = bool;
+
+private:
+ unsigned int m_uncaught_count;
+
+public:
+ /*!
+ * \brief Constructs the predicate.
+ *
+ * Upon construction, the predicate saves the current number of uncaught exceptions.
+ * This information will be used when calling the predicate to detect if a new
+ * exception is being thrown.
+ *
+ * **Throws:** Nothing.
+ */
+ exception_checker() noexcept :
+ m_uncaught_count(boost::core::uncaught_exceptions())
+ {
+ }
+
+ /*!
+ * \brief Checks if an exception is being thrown.
+ *
+ * **Throws:** Nothing.
+ *
+ * \returns \c true if the number of uncaught exceptions at the point of call is
+ * greater than that at the point of construction of the predicate,
+ * otherwise \c false.
+ */
+ result_type operator()() const noexcept
+ {
+ const unsigned int uncaught_count = boost::core::uncaught_exceptions();
+ // If this assertion fails, the predicate is likely being used in an unsupported
+ // way, where it is called in a different scope or thread context from where
+ // it was constructed.
+ BOOST_ASSERT((uncaught_count - m_uncaught_count) <= 1u);
+ return uncaught_count > m_uncaught_count;
+ }
+};
+
+/*!
+ * \brief Creates a predicate for checking whether an exception is being thrown
+ *
+ * **Throws:** Nothing.
+ */
+inline exception_checker check_exception() noexcept
+{
+ return exception_checker();
+}
+
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_EXCEPTION_CHECKER_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/fd_deleter.hpp b/contrib/restricted/boost/scope/include/boost/scope/fd_deleter.hpp
new file mode 100644
index 0000000000..92f3ee21f5
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/fd_deleter.hpp
@@ -0,0 +1,82 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/fd_deleter.hpp
+ *
+ * This header contains definition of a deleter function object for
+ * POSIX-like file descriptors for use with \c unique_resource.
+ */
+
+#ifndef BOOST_SCOPE_FD_DELETER_HPP_INCLUDED_
+#define BOOST_SCOPE_FD_DELETER_HPP_INCLUDED_
+
+#include <boost/scope/detail/config.hpp>
+
+#if !defined(BOOST_WINDOWS)
+#include <unistd.h>
+#if defined(hpux) || defined(_hpux) || defined(__hpux)
+#include <cerrno>
+#endif
+#else // !defined(BOOST_WINDOWS)
+#include <io.h>
+#endif // !defined(BOOST_WINDOWS)
+
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+
+//! POSIX-like file descriptor deleter
+struct fd_deleter
+{
+ using result_type = void;
+
+ //! Closes the file descriptor
+ result_type operator() (int fd) const noexcept
+ {
+#if !defined(BOOST_WINDOWS)
+#if defined(hpux) || defined(_hpux) || defined(__hpux)
+ // Some systems don't close the file descriptor in case if the thread is interrupted by a signal and close(2) returns EINTR.
+ // Other (most) systems do close the file descriptor even when when close(2) returns EINTR, and attempting to close it
+ // again could close a different file descriptor that was opened by a different thread.
+ //
+ // Future POSIX standards will likely fix this by introducing posix_close (see https://www.austingroupbugs.net/view.php?id=529)
+ // and prohibiting returning EINTR from close(2), but we still have to support older systems where this new behavior is not available and close(2)
+ // behaves differently between systems.
+ int res;
+ while (true)
+ {
+ res = ::close(fd);
+ if (BOOST_UNLIKELY(res < 0))
+ {
+ int err = errno;
+ if (err == EINTR)
+ continue;
+ }
+
+ break;
+ }
+#else
+ ::close(fd);
+#endif
+#else // !defined(BOOST_WINDOWS)
+ ::_close(fd);
+#endif // !defined(BOOST_WINDOWS)
+ }
+};
+
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_FD_DELETER_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/fd_resource_traits.hpp b/contrib/restricted/boost/scope/include/boost/scope/fd_resource_traits.hpp
new file mode 100644
index 0000000000..76177979ca
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/fd_resource_traits.hpp
@@ -0,0 +1,49 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/fd_resource_traits.hpp
+ *
+ * This header contains definition of \c unique_resource traits
+ * for compatibility with POSIX-like file descriptors.
+ */
+
+#ifndef BOOST_SCOPE_FD_RESOURCE_TRAITS_HPP_INCLUDED_
+#define BOOST_SCOPE_FD_RESOURCE_TRAITS_HPP_INCLUDED_
+
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+
+//! POSIX-like file descriptor resource traits
+struct fd_resource_traits
+{
+ //! Creates a default fd value
+ static int make_default() noexcept
+ {
+ return -1;
+ }
+
+ //! Tests if the fd is allocated (valid)
+ static bool is_allocated(int fd) noexcept
+ {
+ return fd >= 0;
+ }
+};
+
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_FD_RESOURCE_TRAITS_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/scope_exit.hpp b/contrib/restricted/boost/scope/include/boost/scope/scope_exit.hpp
new file mode 100644
index 0000000000..0f03ff4c47
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/scope_exit.hpp
@@ -0,0 +1,560 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/scope_exit.hpp
+ *
+ * This header contains definition of \c scope_exit template.
+ */
+
+#ifndef BOOST_SCOPE_SCOPE_EXIT_HPP_INCLUDED_
+#define BOOST_SCOPE_SCOPE_EXIT_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/detail/is_not_like.hpp>
+#include <boost/scope/detail/compact_storage.hpp>
+#include <boost/scope/detail/move_or_copy_construct_ref.hpp>
+#include <boost/scope/detail/is_nonnull_default_constructible.hpp>
+#include <boost/scope/detail/type_traits/conjunction.hpp>
+#include <boost/scope/detail/type_traits/is_invocable.hpp>
+#include <boost/scope/detail/type_traits/is_nothrow_invocable.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+
+template< typename Func, typename Cond >
+class scope_exit;
+
+namespace detail {
+
+// Workaround for clang < 5.0 which can't pass scope_exit as a template template parameter from within scope_exit definition
+template< typename T >
+using is_not_like_scope_exit = detail::is_not_like< T, scope_exit >;
+
+//! The scope guard used to invoke the condition and action functions in case of exception during scope guard construction
+template< typename Func, typename Cond >
+class init_guard
+{
+private:
+ Func& m_func;
+ Cond& m_cond;
+ bool m_active;
+
+public:
+ init_guard(Func& func, Cond& cond, bool active) noexcept :
+ m_func(func),
+ m_cond(cond),
+ m_active(active)
+ {
+ }
+
+ init_guard(init_guard const&) = delete;
+ init_guard& operator= (init_guard const&) = delete;
+
+ ~init_guard()
+ noexcept(detail::conjunction<
+ detail::is_nothrow_invocable< Func& >,
+ detail::is_nothrow_invocable< Cond& >
+ >::value)
+ {
+ if (m_active && m_cond())
+ m_func();
+ }
+
+ Func&& get_func() noexcept
+ {
+ return static_cast< Func&& >(m_func);
+ }
+
+ Cond&& get_cond() noexcept
+ {
+ return static_cast< Cond&& >(m_cond);
+ }
+
+ void deactivate() noexcept
+ {
+ m_active = false;
+ }
+};
+
+} // namespace detail
+
+/*!
+ * \brief A predicate that always returns \c true.
+ *
+ * This predicate can be used as the default condition function object for
+ * \c scope_exit and similar scope guards.
+ */
+class always_true
+{
+public:
+ //! Predicate result type
+ using result_type = bool;
+
+ /*!
+ * **Throws:** Nothing.
+ *
+ * \returns \c true.
+ */
+ result_type operator()() const noexcept
+ {
+ return true;
+ }
+};
+
+/*!
+ * \brief Scope exit guard that conditionally invokes a function upon leaving the scope.
+ *
+ * The scope guard wraps two function objects: the scope guard action and
+ * a condition for invoking the action. Both function objects must be
+ * callable with no arguments and can be one of:
+ *
+ * \li A user-defined class with a public `operator()`.
+ * \li An lvalue reference to such class.
+ * \li An lvalue reference or pointer to function taking no arguments.
+ *
+ * The condition function object `operator()` must return a value
+ * contextually convertible to \c true, if the action function object
+ * is allowed to be executed, and \c false otherwise. Additionally,
+ * the condition function object `operator()` must not throw, as
+ * otherwise the action function object may not be called.
+ *
+ * The condition function object is optional, and if not specified in
+ * template parameters, the scope guard will operate as if the condition
+ * always returns \c true.
+ *
+ * The scope guard can be in either active or inactive state. By default,
+ * the constructed scope guard is active. When active, and condition
+ * function object returns \c true, the scope guard invokes the wrapped
+ * action function object on destruction. Otherwise, the scope guard
+ * does not call the wrapped action function object.
+ *
+ * The scope guard can be made inactive by moving-from the scope guard
+ * or calling `set_active(false)`. An inactive scope guard can be made
+ * active by calling `set_active(true)`. If a moved-from scope guard
+ * is active on destruction, the behavior is undefined.
+ *
+ * \tparam Func Scope guard action function object type.
+ * \tparam Cond Scope guard condition function object type.
+ */
+template< typename Func, typename Cond = always_true >
+class scope_exit
+{
+//! \cond
+private:
+ struct func_holder :
+ public detail::compact_storage< Func >
+ {
+ using func_base = detail::compact_storage< Func >;
+
+ template<
+ typename F,
+ typename C,
+ typename = typename std::enable_if< std::is_constructible< Func, F >::value >::type
+ >
+ explicit func_holder(F&& func, C&& cond, bool active, std::true_type) noexcept :
+ func_base(static_cast< F&& >(func))
+ {
+ }
+
+ template<
+ typename F,
+ typename C,
+ typename = typename std::enable_if< std::is_constructible< Func, F >::value >::type
+ >
+ explicit func_holder(F&& func, C&& cond, bool active, std::false_type) :
+ func_holder(detail::init_guard< F, C >(func, cond, active))
+ {
+ }
+
+ private:
+ template< typename F, typename C >
+ explicit func_holder(detail::init_guard< F, C >&& init) :
+ func_base(init.get_func())
+ {
+ init.deactivate();
+ }
+ };
+
+ struct cond_holder :
+ public detail::compact_storage< Cond >
+ {
+ using cond_base = detail::compact_storage< Cond >;
+
+ template<
+ typename C,
+ typename = typename std::enable_if< std::is_constructible< Cond, C >::value >::type
+ >
+ explicit cond_holder(C&& cond, Func& func, bool active, std::true_type) noexcept :
+ cond_base(static_cast< C&& >(cond))
+ {
+ }
+
+ template<
+ typename C,
+ typename = typename std::enable_if< std::is_constructible< Cond, C >::value >::type
+ >
+ explicit cond_holder(C&& cond, Func& func, bool active, std::false_type) :
+ cond_holder(detail::init_guard< Func&, C >(func, cond, active))
+ {
+ }
+
+ private:
+ template< typename C >
+ explicit cond_holder(detail::init_guard< Func&, C >&& init) :
+ cond_base(init.get_cond())
+ {
+ init.deactivate();
+ }
+ };
+
+ struct data :
+ public func_holder,
+ public cond_holder
+ {
+ bool m_active;
+
+ template<
+ typename F,
+ typename C,
+ typename = typename std::enable_if< detail::conjunction<
+ std::is_constructible< func_holder, F, C, bool, typename std::is_nothrow_constructible< Func, F >::type >,
+ std::is_constructible< cond_holder, C, Func&, bool, typename std::is_nothrow_constructible< Cond, C >::type >
+ >::value >::type
+ >
+ explicit data(F&& func, C&& cond, bool active)
+ noexcept(detail::conjunction< std::is_nothrow_constructible< Func, F >, std::is_nothrow_constructible< Cond, C > >::value) :
+ func_holder(static_cast< F&& >(func), static_cast< C&& >(cond), active, typename std::is_nothrow_constructible< Func, F >::type()),
+ cond_holder(static_cast< C&& >(cond), func_holder::get(), active, typename std::is_nothrow_constructible< Cond, C >::type()),
+ m_active(active)
+ {
+ }
+
+ Func& get_func() noexcept
+ {
+ return func_holder::get();
+ }
+
+ Func const& get_func() const noexcept
+ {
+ return func_holder::get();
+ }
+
+ Cond& get_cond() noexcept
+ {
+ return cond_holder::get();
+ }
+
+ Cond const& get_cond() const noexcept
+ {
+ return cond_holder::get();
+ }
+
+ bool deactivate() noexcept
+ {
+ bool active = m_active;
+ m_active = false;
+ return active;
+ }
+ };
+
+ data m_data;
+
+//! \endcond
+public:
+ /*!
+ * \brief Constructs a scope guard with a given callable action function object.
+ *
+ * **Requires:** \c Func is constructible from \a func. \c Cond is nothrow default-constructible
+ * and is not a pointer to function.
+ *
+ * \note The requirement for \c Cond default constructor to be non-throwing is to allow for
+ * the condition function object to be called in case if constructing either function
+ * object throws.
+ *
+ * **Effects:** Constructs the scope guard as if by calling
+ * `scope_exit(std::forward< F >(func), Cond(), active)`.
+ *
+ * **Throws:** Nothing, unless construction of the function objects throw.
+ *
+ * \param func The callable action function object to invoke on destruction.
+ * \param active Indicates whether the scope guard should be active upon construction.
+ *
+ * \post `this->active() == active`
+ */
+ template<
+ typename F
+ //! \cond
+ , typename = typename std::enable_if< detail::conjunction<
+ detail::is_nothrow_nonnull_default_constructible< Cond >,
+ std::is_constructible<
+ data,
+ typename detail::move_or_copy_construct_ref< F, Func >::type,
+ typename detail::move_or_copy_construct_ref< Cond >::type,
+ bool
+ >,
+ detail::is_not_like_scope_exit< F >
+ >::value >::type
+ //! \endcond
+ >
+ explicit scope_exit(F&& func, bool active = true)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
+ std::is_nothrow_constructible<
+ data,
+ typename detail::move_or_copy_construct_ref< F, Func >::type,
+ typename detail::move_or_copy_construct_ref< Cond >::type,
+ bool
+ >::value
+ )) :
+ m_data
+ (
+ static_cast< typename detail::move_or_copy_construct_ref< F, Func >::type >(func),
+ static_cast< typename detail::move_or_copy_construct_ref< Cond >::type >(Cond()),
+ active
+ )
+ {
+ }
+
+ /*!
+ * \brief Constructs a scope guard with a given callable action and condition function objects.
+ *
+ * **Requires:** \c Func is constructible from \a func. \c Cond is constructible from \a cond.
+ *
+ * **Effects:** If \c Func is nothrow constructible from `F&&` then constructs \c Func from
+ * `std::forward< F >(func)`, otherwise constructs from `func`. If \c Cond is
+ * nothrow constructible from `C&&` then constructs \c Cond from
+ * `std::forward< C >(cond)`, otherwise constructs from `cond`.
+ *
+ * If \c Func or \c Cond construction throws and \a active is \c true, invokes
+ * \a cond and, if it returns \c true, \a func before returning with the exception.
+ *
+ * **Throws:** Nothing, unless construction of the function objects throw.
+ *
+ * \param func The callable action function object to invoke on destruction.
+ * \param cond The callable condition function object.
+ * \param active Indicates whether the scope guard should be active upon construction.
+ *
+ * \post `this->active() == active`
+ */
+ template<
+ typename F,
+ typename C
+ //! \cond
+ , typename = typename std::enable_if< detail::conjunction<
+ detail::is_invocable< C const& >,
+ std::is_constructible<
+ data,
+ typename detail::move_or_copy_construct_ref< F, Func >::type,
+ typename detail::move_or_copy_construct_ref< C, Cond >::type,
+ bool
+ >
+ >::value >::type
+ //! \endcond
+ >
+ explicit scope_exit(F&& func, C&& cond, bool active = true)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
+ std::is_nothrow_constructible<
+ data,
+ typename detail::move_or_copy_construct_ref< F, Func >::type,
+ typename detail::move_or_copy_construct_ref< C, Cond >::type,
+ bool
+ >::value
+ )) :
+ m_data
+ (
+ static_cast< typename detail::move_or_copy_construct_ref< F, Func >::type >(func),
+ static_cast< typename detail::move_or_copy_construct_ref< C, Cond >::type >(cond),
+ active
+ )
+ {
+ }
+
+ /*!
+ * \brief Move-constructs a scope guard.
+ *
+ * **Requires:** \c Func and \c Cond are nothrow move-constructible or copy-constructible.
+ *
+ * **Effects:** If \c Func is nothrow move-constructible then move-constructs \c Func from
+ * a member of \a that, otherwise copy-constructs \c Func. If \c Cond is nothrow
+ * move-constructible then move-constructs \c Cond from a member of \a that,
+ * otherwise copy-constructs \c Cond.
+ *
+ * If \c Func or \c Cond construction throws and `that.active() == true`, invokes
+ * \c Cond object stored in \a that and, if it returns \c true, \a Func object
+ * (either the newly constructed one, if its construction succeeded, or the original
+ * one stored in \a that) before returning with the exception.
+ *
+ * If the construction succeeds, marks \a that as inactive.
+ *
+ * **Throws:** Nothing, unless move-construction of the function objects throw.
+ *
+ * \param that Move source.
+ *
+ * \post `that.active() == false`
+ */
+ //! \cond
+ template<
+ bool Requires = std::is_constructible<
+ data,
+ typename detail::move_or_copy_construct_ref< Func >::type,
+ typename detail::move_or_copy_construct_ref< Cond >::type,
+ bool
+ >::value,
+ typename = typename std::enable_if< Requires >::type
+ >
+ //! \endcond
+ scope_exit(scope_exit&& that)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
+ std::is_nothrow_constructible<
+ data,
+ typename detail::move_or_copy_construct_ref< Func >::type,
+ typename detail::move_or_copy_construct_ref< Cond >::type,
+ bool
+ >::value
+ )) :
+ m_data
+ (
+ static_cast< typename detail::move_or_copy_construct_ref< Func >::type >(that.m_data.get_func()),
+ static_cast< typename detail::move_or_copy_construct_ref< Cond >::type >(that.m_data.get_cond()),
+ that.m_data.deactivate()
+ )
+ {
+ }
+
+ scope_exit& operator= (scope_exit&&) = delete;
+
+ scope_exit(scope_exit const&) = delete;
+ scope_exit& operator= (scope_exit const&) = delete;
+
+ /*!
+ * \brief If `active() == true`, and invoking the condition function object returns \c true, invokes
+ * the wrapped callable action function object. Destroys the function objects.
+ *
+ * **Throws:** Nothing, unless invoking a function object throws.
+ */
+ ~scope_exit()
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
+ detail::conjunction<
+ detail::is_nothrow_invocable< Func& >,
+ detail::is_nothrow_invocable< Cond& >
+ >::value
+ ))
+ {
+ if (BOOST_LIKELY(m_data.m_active && m_data.get_cond()()))
+ m_data.get_func()();
+ }
+
+ /*!
+ * \brief Returns \c true if the scope guard is active, otherwise \c false.
+ *
+ * \note This method does not call the condition function object specified on construction.
+ *
+ * **Throws:** Nothing.
+ */
+ bool active() const noexcept
+ {
+ return m_data.m_active;
+ }
+
+ /*!
+ * \brief Activates or deactivates the scope guard.
+ *
+ * **Throws:** Nothing.
+ *
+ * \param active The active status to set.
+ *
+ * \post `this->active() == active`
+ */
+ void set_active(bool active) noexcept
+ {
+ m_data.m_active = active;
+ }
+};
+
+#if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
+template< typename Func >
+explicit scope_exit(Func) -> scope_exit< Func >;
+
+template< typename Func >
+explicit scope_exit(Func, bool) -> scope_exit< Func >;
+
+template< typename Func, typename Cond >
+explicit scope_exit(Func, Cond) -> scope_exit< Func, Cond >;
+
+template< typename Func, typename Cond >
+explicit scope_exit(Func, Cond, bool) -> scope_exit< Func, Cond >;
+#endif // !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
+
+/*!
+ * \brief Creates a scope guard with a given action function object.
+ *
+ * **Effects:** Constructs a scope guard as if by calling
+ * `scope_exit< std::decay_t< F > >(std::forward< F >(func), active)`.
+ *
+ * \param func The callable action function object to invoke on destruction.
+ * \param active Indicates whether the scope guard should be active upon construction.
+ */
+template< typename F >
+inline scope_exit< typename std::decay< F >::type > make_scope_exit(F&& func, bool active = true)
+ noexcept(std::is_nothrow_constructible<
+ scope_exit< typename std::decay< F >::type >,
+ F,
+ bool
+ >::value)
+{
+ return scope_exit< typename std::decay< F >::type >(static_cast< F&& >(func), active);
+}
+
+/*!
+ * \brief Creates a conditional scope guard with given callable function objects.
+ *
+ * **Effects:** Constructs a scope guard as if by calling
+ * `scope_exit< std::decay_t< F >, std::decay_t< C > >(
+ * std::forward< F >(func), std::forward< C >(cond), active)`.
+ *
+ * \param func The callable action function object to invoke on destruction.
+ * \param cond The callable condition function object.
+ * \param active Indicates whether the scope guard should be active upon construction.
+ */
+template< typename F, typename C >
+inline
+#if !defined(BOOST_SCOPE_DOXYGEN)
+typename std::enable_if<
+ std::is_constructible<
+ scope_exit< typename std::decay< F >::type, typename std::decay< C >::type >,
+ F,
+ C,
+ bool
+ >::value,
+ scope_exit< typename std::decay< F >::type, typename std::decay< C >::type >
+>::type
+#else
+scope_exit< typename std::decay< F >::type, typename std::decay< C >::type >
+#endif
+make_scope_exit(F&& func, C&& cond, bool active = true)
+ noexcept(std::is_nothrow_constructible<
+ scope_exit< typename std::decay< F >::type, typename std::decay< C >::type >,
+ F,
+ C,
+ bool
+ >::value)
+{
+ return scope_exit< typename std::decay< F >::type, typename std::decay< C >::type >(static_cast< F&& >(func), static_cast< C&& >(cond), active);
+}
+
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_SCOPE_EXIT_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/scope_fail.hpp b/contrib/restricted/boost/scope/include/boost/scope/scope_fail.hpp
new file mode 100644
index 0000000000..a9c2368c57
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/scope_fail.hpp
@@ -0,0 +1,265 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2022 Andrey Semashev
+ */
+/*!
+ * \file scope/scope_fail.hpp
+ *
+ * This header contains definition of \c scope_fail template.
+ */
+
+#ifndef BOOST_SCOPE_SCOPE_FAIL_HPP_INCLUDED_
+#define BOOST_SCOPE_SCOPE_FAIL_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/exception_checker.hpp>
+#include <boost/scope/scope_exit.hpp>
+#include <boost/scope/detail/is_not_like.hpp>
+#include <boost/scope/detail/type_traits/conjunction.hpp>
+#include <boost/scope/detail/type_traits/is_invocable.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+
+template< typename Func, typename Cond >
+class scope_fail;
+
+namespace detail {
+
+// Workaround for clang < 5.0 which can't pass scope_fail as a template template parameter from within scope_fail definition
+template< typename T >
+using is_not_like_scope_fail = detail::is_not_like< T, scope_fail >;
+
+} // namespace detail
+
+/*!
+ * \brief Scope exit guard that invokes a function upon leaving the scope, if
+ * a failure condition is satisfied.
+ *
+ * The scope guard wraps two function objects: the scope guard action and
+ * a failure condition for invoking the action. Both function objects must
+ * be callable with no arguments and can be one of:
+ *
+ * \li A user-defined class with a public `operator()`.
+ * \li An lvalue reference to such class.
+ * \li An lvalue reference or pointer to function taking no arguments.
+ *
+ * The condition function object `operator()` must return a value
+ * contextually convertible to \c true, if the failure is detected and the
+ * action function object is allowed to be executed, and \c false otherwise.
+ * Additionally, the failure condition function object `operator()` must not
+ * throw, as otherwise the action function object may not be called. If not
+ * specified, the default failure condition checks whether the scope is left
+ * due to an exception - the action function object will not be called if
+ * the scope is left normally.
+ *
+ * \sa scope_exit
+ * \sa scope_success
+ *
+ * \tparam Func Scope guard action function object type.
+ * \tparam Cond Scope guard failure condition function object type.
+ */
+template< typename Func, typename Cond = exception_checker >
+class scope_fail :
+ public scope_exit< Func, Cond >
+{
+//! \cond
+private:
+ using base_type = scope_exit< Func, Cond >;
+
+//! \endcond
+public:
+ /*!
+ * \brief Constructs a scope guard with a given callable function object.
+ *
+ * **Requires:** \c Func is constructible from \a func. \c Cond is nothrow default-constructible.
+ *
+ * **Effects:** Constructs the scope guard as if by calling
+ * `scope_fail(std::forward< F >(func), Cond(), active)`.
+ *
+ * **Throws:** Nothing, unless construction of the function objects throw.
+ *
+ * \param func The callable action function object to invoke on destruction.
+ * \param active Indicates whether the scope guard should be active upon construction.
+ *
+ * \post `this->active() == active`
+ */
+ template<
+ typename F
+ //! \cond
+ , typename = typename std::enable_if< detail::conjunction<
+ std::is_constructible< base_type, F, bool >,
+ detail::is_not_like_scope_fail< F >
+ >::value >::type
+ //! \endcond
+ >
+ explicit scope_fail(F&& func, bool active = true)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_constructible< base_type, F, bool >::value)) :
+ base_type(static_cast< F&& >(func), active)
+ {
+ }
+
+ /*!
+ * \brief Constructs a scope guard with a given callable action and failure condition function objects.
+ *
+ * **Requires:** \c Func is constructible from \a func. \c Cond is constructible from \a cond.
+ *
+ * **Effects:** If \c Func is nothrow constructible from `F&&` then constructs \c Func from
+ * `std::forward< F >(func)`, otherwise constructs from `func`. If \c Cond is
+ * nothrow constructible from `C&&` then constructs \c Cond from
+ * `std::forward< C >(cond)`, otherwise constructs from `cond`.
+ *
+ * If \c Func or \c Cond construction throws and \a active is \c true, invokes
+ * \a cond and, if it returns \c true, \a func before returning with the exception.
+ *
+ * **Throws:** Nothing, unless construction of the function objects throw.
+ *
+ * \param func The callable action function object to invoke on destruction.
+ * \param cond The callable failure condition function object.
+ * \param active Indicates whether the scope guard should be active upon construction.
+ *
+ * \post `this->active() == active`
+ */
+ template<
+ typename F,
+ typename C
+ //! \cond
+ , typename = typename std::enable_if< std::is_constructible< base_type, F, C, bool >::value >::type
+ //! \endcond
+ >
+ explicit scope_fail(F&& func, C&& cond, bool active = true)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_constructible< base_type, F, C, bool >::value)) :
+ base_type(static_cast< F&& >(func), static_cast< C&& >(cond), active)
+ {
+ }
+
+ /*!
+ * \brief Move-constructs a scope guard.
+ *
+ * **Requires:** \c Func and \c Cond are nothrow move-constructible or copy-constructible.
+ *
+ * **Effects:** If \c Func is nothrow move-constructible then move-constructs \c Func from
+ * a member of \a that, otherwise copy-constructs \c Func. If \c Cond is nothrow
+ * move-constructible then move-constructs \c Cond from a member of \a that,
+ * otherwise copy-constructs \c Cond.
+ *
+ * If \c Func or \c Cond construction throws and `that.active() == true`, invokes
+ * \c Cond object stored in \a that and, if it returns \c true, \a Func object
+ * (either the newly constructed one, if its construction succeeded, or the original
+ * one stored in \a that) before returning with the exception.
+ *
+ * If the construction succeeds, marks \a that as inactive.
+ *
+ * **Throws:** Nothing, unless move-construction of the function objects throw.
+ *
+ * \param that Move source.
+ *
+ * \post `that.active() == false`
+ */
+ //! \cond
+ template<
+ bool Requires = std::is_move_constructible< base_type >::value,
+ typename = typename std::enable_if< Requires >::type
+ >
+ //! \endcond
+ scope_fail(scope_fail&& that)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_move_constructible< base_type >::value)) :
+ base_type(static_cast< base_type&& >(that))
+ {
+ }
+
+ scope_fail& operator= (scope_fail&&) = delete;
+
+ scope_fail(scope_fail const&) = delete;
+ scope_fail& operator= (scope_fail const&) = delete;
+};
+
+#if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
+template< typename Func >
+explicit scope_fail(Func) -> scope_fail< Func >;
+
+template< typename Func >
+explicit scope_fail(Func, bool) -> scope_fail< Func >;
+
+template<
+ typename Func,
+ typename Cond,
+ typename = typename std::enable_if< detail::is_invocable< Cond const& >::value >::type
+>
+explicit scope_fail(Func, Cond) -> scope_fail< Func, Cond >;
+
+template<
+ typename Func,
+ typename Cond,
+ typename = typename std::enable_if< detail::is_invocable< Cond const& >::value >::type
+>
+explicit scope_fail(Func, Cond, bool) -> scope_fail< Func, Cond >;
+#endif // !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
+
+/*!
+ * \brief Creates a scope fail guard with a given action function object.
+ *
+ * **Effects:** Constructs a scope guard as if by calling
+ * `scope_fail< std::decay_t< F > >(std::forward< F >(func), active)`.
+ *
+ * \param func The callable function object to invoke on destruction.
+ * \param active Indicates whether the scope guard should be active upon construction.
+ */
+template< typename F >
+inline scope_fail< typename std::decay< F >::type > make_scope_fail(F&& func, bool active = true)
+ noexcept(std::is_nothrow_constructible<
+ scope_fail< typename std::decay< F >::type >,
+ F,
+ bool
+ >::value)
+{
+ return scope_fail< typename std::decay< F >::type >(static_cast< F&& >(func), active);
+}
+
+/*!
+ * \brief Creates a scope fail with given callable function objects.
+ *
+ * **Effects:** Constructs a scope guard as if by calling
+ * `scope_fail< std::decay_t< F >, std::decay_t< C > >(
+ * std::forward< F >(func), std::forward< C >(cond), active)`.
+ *
+ * \param func The callable action function object to invoke on destruction.
+ * \param cond The callable failure condition function object.
+ * \param active Indicates whether the scope guard should be active upon construction.
+ */
+template< typename F, typename C >
+inline
+#if !defined(BOOST_SCOPE_DOXYGEN)
+typename std::enable_if<
+ detail::is_invocable< C const& >::value,
+ scope_fail< typename std::decay< F >::type, typename std::decay< C >::type >
+>::type
+#else
+scope_fail< typename std::decay< F >::type, typename std::decay< C >::type >
+#endif
+make_scope_fail(F&& func, C&& cond, bool active = true)
+ noexcept(std::is_nothrow_constructible<
+ scope_fail< typename std::decay< F >::type, typename std::decay< C >::type >,
+ F,
+ C,
+ bool
+ >::value)
+{
+ return scope_fail< typename std::decay< F >::type, typename std::decay< C >::type >(static_cast< F&& >(func), static_cast< C&& >(cond), active);
+}
+
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_SCOPE_FAIL_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/scope_success.hpp b/contrib/restricted/boost/scope/include/boost/scope/scope_success.hpp
new file mode 100644
index 0000000000..a5cd3c160d
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/scope_success.hpp
@@ -0,0 +1,309 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2022 Andrey Semashev
+ */
+/*!
+ * \file scope/scope_success.hpp
+ *
+ * This header contains definition of \c scope_success template.
+ */
+
+#ifndef BOOST_SCOPE_SCOPE_SUCCESS_HPP_INCLUDED_
+#define BOOST_SCOPE_SCOPE_SUCCESS_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/exception_checker.hpp>
+#include <boost/scope/scope_exit.hpp>
+#include <boost/scope/detail/is_not_like.hpp>
+#include <boost/scope/detail/type_traits/conjunction.hpp>
+#include <boost/scope/detail/type_traits/is_invocable.hpp>
+#include <boost/scope/detail/type_traits/is_nothrow_invocable.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+
+template< typename Func, typename Cond >
+class scope_success;
+
+namespace detail {
+
+// Workaround for clang < 5.0 which can't pass scope_success as a template template parameter from within scope_success definition
+template< typename T >
+using is_not_like_scope_success = detail::is_not_like< T, scope_success >;
+
+template< typename Func >
+class logical_not;
+
+template< typename T >
+using is_not_like_logical_not = detail::is_not_like< T, logical_not >;
+
+template< typename Func >
+class logical_not
+{
+public:
+ using result_type = bool;
+
+private:
+ Func m_func;
+
+public:
+ template<
+ bool Requires = std::is_default_constructible< Func >::value,
+ typename = typename std::enable_if< Requires >::type
+ >
+ logical_not() noexcept(std::is_nothrow_default_constructible< Func >::value) :
+ m_func()
+ {
+ }
+
+ template<
+ typename F,
+ typename = typename std::enable_if< detail::conjunction<
+ std::is_constructible< Func, F >,
+ detail::is_not_like_logical_not< F >
+ >::value >::type
+ >
+ explicit logical_not(F&& func) noexcept(std::is_nothrow_constructible< Func, F >::value) :
+ m_func(static_cast< F&& >(func))
+ {
+ }
+
+ result_type operator()() const noexcept(detail::is_nothrow_invocable< Func const& >::value)
+ {
+ return !m_func();
+ }
+};
+
+} // namespace detail
+
+/*!
+ * \brief Scope exit guard that invokes a function upon leaving the scope, if
+ * a failure condition is not satisfied.
+ *
+ * The scope guard wraps two function objects: the scope guard action and
+ * a failure condition for invoking the action. Both function objects must
+ * be callable with no arguments and can be one of:
+ *
+ * \li A user-defined class with a public `operator()`.
+ * \li An lvalue reference to such class.
+ * \li An lvalue reference or pointer to function taking no arguments.
+ *
+ * The condition function object `operator()` must return a value
+ * contextually convertible to \c true, if the failure is detected and the
+ * action function object is not allowed to be executed, and \c false otherwise.
+ * Additionally, the failure condition function object `operator()` must not
+ * throw, as otherwise the action function object may not be called. If not
+ * specified, the default failure condition checks whether the scope is left
+ * due to an exception - the action function object will only be called if
+ * the scope is left normally.
+ *
+ * \sa scope_exit
+ * \sa scope_fail
+ *
+ * \tparam Func Scope guard action function object type.
+ * \tparam Cond Scope guard failure condition function object type.
+ */
+template< typename Func, typename Cond = exception_checker >
+class scope_success :
+ public scope_exit< Func, detail::logical_not< Cond > >
+{
+//! \cond
+private:
+ using base_type = scope_exit< Func, detail::logical_not< Cond > >;
+
+//! \endcond
+public:
+ /*!
+ * \brief Constructs a scope guard with a given callable function object.
+ *
+ * **Requires:** \c Func is constructible from \a func. \c Cond is nothrow default-constructible.
+ *
+ * **Effects:** Constructs the scope guard as if by calling
+ * `scope_success(std::forward< F >(func), Cond(), active)`.
+ *
+ * **Throws:** Nothing, unless construction of the function objects throw.
+ *
+ * \param func The callable action function object to invoke on destruction.
+ * \param active Indicates whether the scope guard should be active upon construction.
+ *
+ * \post `this->active() == active`
+ */
+ template<
+ typename F
+ //! \cond
+ , typename = typename std::enable_if< detail::conjunction<
+ std::is_constructible< base_type, F, bool >,
+ detail::is_not_like_scope_success< F >
+ >::value >::type
+ //! \endcond
+ >
+ explicit scope_success(F&& func, bool active = true)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_constructible< base_type, F, bool >::value)) :
+ base_type(static_cast< F&& >(func), active)
+ {
+ }
+
+ /*!
+ * \brief Constructs a scope guard with a given callable action and failure condition function objects.
+ *
+ * **Requires:** \c Func is constructible from \a func. \c Cond is constructible from \a cond.
+ *
+ * **Effects:** If \c Func is nothrow constructible from `F&&` then constructs \c Func from
+ * `std::forward< F >(func)`, otherwise constructs from `func`. If \c Cond is
+ * nothrow constructible from `C&&` then constructs \c Cond from
+ * `std::forward< C >(cond)`, otherwise constructs from `cond`.
+ *
+ * If \c Func or \c Cond construction throws and \a active is \c true, invokes
+ * \a cond and, if it returns \c true, \a func before returning with the exception.
+ *
+ * **Throws:** Nothing, unless construction of the function objects throw.
+ *
+ * \param func The callable action function object to invoke on destruction.
+ * \param cond The callable failure condition function object.
+ * \param active Indicates whether the scope guard should be active upon construction.
+ *
+ * \post `this->active() == active`
+ */
+ template<
+ typename F,
+ typename C
+ //! \cond
+ , typename = typename std::enable_if< std::is_constructible< base_type, F, C, bool >::value >::type
+ //! \endcond
+ >
+ explicit scope_success(F&& func, C&& cond, bool active = true)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_constructible< base_type, F, C, bool >::value)) :
+ base_type(static_cast< F&& >(func), static_cast< C&& >(cond), active)
+ {
+ }
+
+ /*!
+ * \brief Move-constructs a scope guard.
+ *
+ * **Requires:** \c Func and \c Cond are nothrow move-constructible or copy-constructible.
+ *
+ * **Effects:** If \c Func is nothrow move-constructible then move-constructs \c Func from
+ * a member of \a that, otherwise copy-constructs \c Func. If \c Cond is nothrow
+ * move-constructible then move-constructs \c Cond from a member of \a that,
+ * otherwise copy-constructs \c Cond.
+ *
+ * If \c Func or \c Cond construction throws and `that.active() == true`, invokes
+ * \c Cond object stored in \a that and, if it returns \c true, \a Func object
+ * (either the newly constructed one, if its construction succeeded, or the original
+ * one stored in \a that) before returning with the exception.
+ *
+ * If the construction succeeds, marks \a that as inactive.
+ *
+ * **Throws:** Nothing, unless move-construction of the function objects throw.
+ *
+ * \param that Move source.
+ *
+ * \post `that.active() == false`
+ */
+ //! \cond
+ template<
+ bool Requires = std::is_move_constructible< base_type >::value,
+ typename = typename std::enable_if< Requires >::type
+ >
+ //! \endcond
+ scope_success(scope_success&& that)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_move_constructible< base_type >::value)) :
+ base_type(static_cast< base_type&& >(that))
+ {
+ }
+
+ scope_success& operator= (scope_success&&) = delete;
+
+ scope_success(scope_success const&) = delete;
+ scope_success& operator= (scope_success const&) = delete;
+};
+
+#if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
+template< typename Func >
+explicit scope_success(Func) -> scope_success< Func >;
+
+template< typename Func >
+explicit scope_success(Func, bool) -> scope_success< Func >;
+
+template<
+ typename Func,
+ typename Cond,
+ typename = typename std::enable_if< detail::is_invocable< Cond const& >::value >::type
+>
+explicit scope_success(Func, Cond) -> scope_success< Func, Cond >;
+
+template<
+ typename Func,
+ typename Cond,
+ typename = typename std::enable_if< detail::is_invocable< Cond const& >::value >::type
+>
+explicit scope_success(Func, Cond, bool) -> scope_success< Func, Cond >;
+#endif // !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
+
+/*!
+ * \brief Creates a scope fail guard with a given action function object.
+ *
+ * **Effects:** Constructs a scope guard as if by calling
+ * `scope_success< std::decay_t< F > >(std::forward< F >(func), active)`.
+ *
+ * \param func The callable function object to invoke on destruction.
+ * \param active Indicates whether the scope guard should be active upon construction.
+ */
+template< typename F >
+inline scope_success< typename std::decay< F >::type > make_scope_success(F&& func, bool active = true)
+ noexcept(std::is_nothrow_constructible<
+ scope_success< typename std::decay< F >::type >,
+ F,
+ bool
+ >::value)
+{
+ return scope_success< typename std::decay< F >::type >(static_cast< F&& >(func), active);
+}
+
+/*!
+ * \brief Creates a scope fail with given callable function objects.
+ *
+ * **Effects:** Constructs a scope guard as if by calling
+ * `scope_success< std::decay_t< F >, std::decay_t< C > >(
+ * std::forward< F >(func), std::forward< C >(cond), active)`.
+ *
+ * \param func The callable action function object to invoke on destruction.
+ * \param cond The callable failure condition function object.
+ * \param active Indicates whether the scope guard should be active upon construction.
+ */
+template< typename F, typename C >
+inline
+#if !defined(BOOST_SCOPE_DOXYGEN)
+typename std::enable_if<
+ detail::is_invocable< C const& >::value,
+ scope_success< typename std::decay< F >::type, typename std::decay< C >::type >
+>::type
+#else
+scope_success< typename std::decay< F >::type, typename std::decay< C >::type >
+#endif
+make_scope_success(F&& func, C&& cond, bool active = true)
+ noexcept(std::is_nothrow_constructible<
+ scope_success< typename std::decay< F >::type, typename std::decay< C >::type >,
+ F,
+ C,
+ bool
+ >::value)
+{
+ return scope_success< typename std::decay< F >::type, typename std::decay< C >::type >(static_cast< F&& >(func), static_cast< C&& >(cond), active);
+}
+
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_SCOPE_SUCCESS_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/unique_fd.hpp b/contrib/restricted/boost/scope/include/boost/scope/unique_fd.hpp
new file mode 100644
index 0000000000..305ad38867
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/unique_fd.hpp
@@ -0,0 +1,38 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2023 Andrey Semashev
+ */
+/*!
+ * \file scope/unique_fd.hpp
+ *
+ * This header contains definition of \c unique_fd type.
+ */
+
+#ifndef BOOST_SCOPE_UNIQUE_FD_HPP_INCLUDED_
+#define BOOST_SCOPE_UNIQUE_FD_HPP_INCLUDED_
+
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/unique_resource.hpp>
+#include <boost/scope/fd_deleter.hpp>
+#include <boost/scope/fd_resource_traits.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+
+//! Unique POSIX-like file descriptor resource
+using unique_fd = unique_resource< int, fd_deleter, fd_resource_traits >;
+
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_UNIQUE_FD_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/unique_resource.hpp b/contrib/restricted/boost/scope/include/boost/scope/unique_resource.hpp
new file mode 100644
index 0000000000..81683c4076
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/unique_resource.hpp
@@ -0,0 +1,1642 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2022-2024 Andrey Semashev
+ */
+/*!
+ * \file scope/unique_resource.hpp
+ *
+ * This header contains definition of \c unique_resource template.
+ */
+
+#ifndef BOOST_SCOPE_UNIQUE_RESOURCE_HPP_INCLUDED_
+#define BOOST_SCOPE_UNIQUE_RESOURCE_HPP_INCLUDED_
+
+#include <new> // for placement new
+#include <type_traits>
+#include <boost/core/addressof.hpp>
+#include <boost/core/invoke_swap.hpp>
+#include <boost/scope/unique_resource_fwd.hpp>
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/detail/compact_storage.hpp>
+#include <boost/scope/detail/move_or_copy_assign_ref.hpp>
+#include <boost/scope/detail/move_or_copy_construct_ref.hpp>
+#include <boost/scope/detail/is_nonnull_default_constructible.hpp>
+#include <boost/scope/detail/type_traits/is_swappable.hpp>
+#include <boost/scope/detail/type_traits/is_nothrow_swappable.hpp>
+#include <boost/scope/detail/type_traits/is_nothrow_invocable.hpp>
+#include <boost/scope/detail/type_traits/negation.hpp>
+#include <boost/scope/detail/type_traits/conjunction.hpp>
+#include <boost/scope/detail/type_traits/disjunction.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+
+#if !defined(BOOST_NO_CXX17_FOLD_EXPRESSIONS) && !defined(BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS)
+
+/*!
+ * \brief Simple resource traits for one or more unallocated resource values.
+ *
+ * This class template generates resource traits for `unique_resource` that specify
+ * one or more unallocated resource values. The first value, specified in the \c DefaultValue
+ * non-type template parameter, is considered the default. The other values, listed in
+ * \c UnallocatedValues, are optional. Any resource values other than \c DefaultValue
+ * or listed in \c UnallocatedValues are considered as allocated.
+ *
+ * In order for the generated resource traits to enable optimized implementation of
+ * `unique_resource`, the resource type must support non-throwing construction and assignment
+ * from, and comparison for (in)equality with \c DefaultValue or any of the resource
+ * values listed in \c UnallocatedValues.
+ */
+template< auto DefaultValue, auto... UnallocatedValues >
+struct unallocated_resource
+{
+ //! Returns the default resource value
+ static decltype(DefaultValue) make_default() noexcept
+ {
+ return DefaultValue;
+ }
+
+ //! Tests if \a res is an allocated resource value
+ template< typename Resource >
+ static bool is_allocated(Resource const& res) noexcept
+ {
+ static_assert(noexcept(res != DefaultValue && (... && (res != UnallocatedValues))),
+ "Invalid unallocated resource value types: comparing resource values with the unallocated values must be noexcept");
+ return res != DefaultValue && (... && (res != UnallocatedValues));
+ }
+};
+
+#endif // !defined(BOOST_NO_CXX17_FOLD_EXPRESSIONS) && !defined(BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS)
+
+struct default_resource_t { };
+
+//! Keyword representing default, unallocated resource argument
+BOOST_INLINE_VARIABLE constexpr default_resource_t default_resource = { };
+
+namespace detail {
+
+// The type trait indicates whether \c T is a possibly qualified \c default_resource_t type
+template< typename T >
+struct is_default_resource : public std::false_type { };
+template< >
+struct is_default_resource< default_resource_t > : public std::true_type { };
+template< >
+struct is_default_resource< const default_resource_t > : public std::true_type { };
+template< >
+struct is_default_resource< volatile default_resource_t > : public std::true_type { };
+template< >
+struct is_default_resource< const volatile default_resource_t > : public std::true_type { };
+template< typename T >
+struct is_default_resource< T& > : public is_default_resource< T >::type { };
+
+// Lightweight reference wrapper
+template< typename T >
+class ref_wrapper
+{
+private:
+ T* m_value;
+
+public:
+ explicit
+#if !defined(BOOST_CORE_NO_CONSTEXPR_ADDRESSOF)
+ constexpr
+#endif
+ ref_wrapper(T& value) noexcept :
+ m_value(boost::addressof(value))
+ {
+ }
+
+ ref_wrapper& operator= (T& value) noexcept
+ {
+ m_value = boost::addressof(value);
+ return *this;
+ }
+
+ ref_wrapper(T&&) = delete;
+ ref_wrapper& operator= (T&&) = delete;
+
+ operator T& () const noexcept
+ {
+ return *m_value;
+ }
+
+ template< typename... Args >
+ void operator() (Args&&... args) const noexcept(detail::is_nothrow_invocable< T&, Args&&... >::value)
+ {
+ (*m_value)(static_cast< Args&& >(args)...);
+ }
+};
+
+template< typename T >
+struct wrap_reference
+{
+ using type = T;
+};
+
+template< typename T >
+struct wrap_reference< T& >
+{
+ using type = ref_wrapper< T >;
+};
+
+template< typename Resource, bool UseCompactStorage >
+class resource_holder :
+ public detail::compact_storage< typename wrap_reference< Resource >::type >
+{
+public:
+ using resource_type = Resource;
+ using internal_resource_type = typename wrap_reference< resource_type >::type;
+
+private:
+ using resource_base = detail::compact_storage< internal_resource_type >;
+
+public:
+ template<
+ bool Requires = std::is_default_constructible< internal_resource_type >::value,
+ typename = typename std::enable_if< Requires >::type
+ >
+ constexpr resource_holder() noexcept(std::is_nothrow_default_constructible< internal_resource_type >::value) :
+ resource_base()
+ {
+ }
+
+ template<
+ typename R,
+ typename = typename std::enable_if< std::is_constructible< internal_resource_type, R >::value >::type
+ >
+ explicit resource_holder(R&& res) noexcept(std::is_nothrow_constructible< internal_resource_type, R >::value) :
+ resource_base(static_cast< R&& >(res))
+ {
+ }
+
+ template<
+ typename R,
+ typename D,
+ typename = typename std::enable_if< std::is_constructible< internal_resource_type, R >::value >::type
+ >
+ explicit resource_holder(R&& res, D&& del, bool allocated) noexcept(std::is_nothrow_constructible< internal_resource_type, R >::value) :
+ resource_holder(static_cast< R&& >(res), static_cast< D&& >(del), allocated, typename std::is_nothrow_constructible< resource_type, R >::type())
+ {
+ }
+
+ resource_type& get() noexcept
+ {
+ return resource_base::get();
+ }
+
+ resource_type const& get() const noexcept
+ {
+ return resource_base::get();
+ }
+
+ internal_resource_type& get_internal() noexcept
+ {
+ return resource_base::get();
+ }
+
+ internal_resource_type const& get_internal() const noexcept
+ {
+ return resource_base::get();
+ }
+
+ void move_from(internal_resource_type&& that) noexcept(std::is_nothrow_move_assignable< internal_resource_type >::value)
+ {
+ resource_base::get() = static_cast< internal_resource_type&& >(that);
+ }
+
+private:
+ template< typename R, typename D >
+ explicit resource_holder(R&& res, D&& del, bool allocated, std::true_type) noexcept :
+ resource_base(static_cast< R&& >(res))
+ {
+ }
+
+ template< typename R, typename D >
+ explicit resource_holder(R&& res, D&& del, bool allocated, std::false_type) try :
+ resource_base(res)
+ {
+ }
+ catch (...)
+ {
+ if (allocated)
+ del(res);
+ }
+};
+
+template< typename Resource >
+class resource_holder< Resource, false >
+{
+public:
+ using resource_type = Resource;
+ using internal_resource_type = typename wrap_reference< resource_type >::type;
+
+private:
+ // Note: Not using compact_storage since we will need to reuse storage for this complete object in move_from
+ internal_resource_type m_resource;
+
+public:
+ template<
+ bool Requires = std::is_default_constructible< internal_resource_type >::value,
+ typename = typename std::enable_if< Requires >::type
+ >
+ constexpr resource_holder() noexcept(std::is_nothrow_default_constructible< internal_resource_type >::value) :
+ m_resource()
+ {
+ }
+
+ template<
+ typename R,
+ typename = typename std::enable_if< std::is_constructible< internal_resource_type, R >::value >::type
+ >
+ explicit resource_holder(R&& res) noexcept(std::is_nothrow_constructible< internal_resource_type, R >::value) :
+ m_resource(static_cast< R&& >(res))
+ {
+ }
+
+ template<
+ typename R,
+ typename D,
+ typename = typename std::enable_if< std::is_constructible< internal_resource_type, R >::value >::type
+ >
+ explicit resource_holder(R&& res, D&& del, bool allocated) noexcept(std::is_nothrow_constructible< internal_resource_type, R >::value) :
+ resource_holder(static_cast< R&& >(res), static_cast< D&& >(del), allocated, typename std::is_nothrow_constructible< resource_type, R >::type())
+ {
+ }
+
+ resource_type& get() noexcept
+ {
+ return m_resource;
+ }
+
+ resource_type const& get() const noexcept
+ {
+ return m_resource;
+ }
+
+ internal_resource_type& get_internal() noexcept
+ {
+ return m_resource;
+ }
+
+ internal_resource_type const& get_internal() const noexcept
+ {
+ return m_resource;
+ }
+
+ void move_from(internal_resource_type&& that)
+ noexcept(std::is_nothrow_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >::value)
+ {
+ internal_resource_type* p = boost::addressof(m_resource);
+ p->~internal_resource_type();
+ new (p) internal_resource_type(static_cast< typename detail::move_or_copy_construct_ref< resource_type >::type >(that));
+ }
+
+private:
+ template< typename R, typename D >
+ explicit resource_holder(R&& res, D&& del, bool allocated, std::true_type) noexcept :
+ m_resource(static_cast< R&& >(res))
+ {
+ }
+
+ template< typename R, typename D >
+ explicit resource_holder(R&& res, D&& del, bool allocated, std::false_type) try :
+ m_resource(res)
+ {
+ }
+ catch (...)
+ {
+ if (allocated)
+ del(res);
+ }
+};
+
+template< typename Resource, typename Deleter >
+class deleter_holder :
+ public detail::compact_storage< typename wrap_reference< Deleter >::type >
+{
+public:
+ using resource_type = Resource;
+ using deleter_type = Deleter;
+ using internal_deleter_type = typename wrap_reference< deleter_type >::type;
+
+private:
+ using deleter_base = detail::compact_storage< internal_deleter_type >;
+
+public:
+ template<
+ bool Requires = detail::is_nonnull_default_constructible< internal_deleter_type >::value,
+ typename = typename std::enable_if< Requires >::type
+ >
+ constexpr deleter_holder() noexcept(detail::is_nothrow_nonnull_default_constructible< internal_deleter_type >::value) :
+ deleter_base()
+ {
+ }
+
+ template<
+ typename D,
+ typename = typename std::enable_if< std::is_constructible< internal_deleter_type, D >::value >::type
+ >
+ explicit deleter_holder(D&& del) noexcept(std::is_nothrow_constructible< internal_deleter_type, D >::value) :
+ deleter_base(static_cast< D&& >(del))
+ {
+ }
+
+ template<
+ typename D,
+ typename = typename std::enable_if< std::is_constructible< internal_deleter_type, D >::value >::type
+ >
+ explicit deleter_holder(D&& del, resource_type& res, bool allocated) noexcept(std::is_nothrow_constructible< internal_deleter_type, D >::value) :
+ deleter_holder(static_cast< D&& >(del), res, allocated, typename std::is_nothrow_constructible< internal_deleter_type, D >::type())
+ {
+ }
+
+ deleter_type& get() noexcept
+ {
+ return deleter_base::get();
+ }
+
+ deleter_type const& get() const noexcept
+ {
+ return deleter_base::get();
+ }
+
+ internal_deleter_type& get_internal() noexcept
+ {
+ return deleter_base::get();
+ }
+
+ internal_deleter_type const& get_internal() const noexcept
+ {
+ return deleter_base::get();
+ }
+
+private:
+ template< typename D >
+ explicit deleter_holder(D&& del, resource_type& res, bool allocated, std::true_type) noexcept :
+ deleter_base(static_cast< D&& >(del))
+ {
+ }
+
+ template< typename D >
+ explicit deleter_holder(D&& del, resource_type& res, bool allocated, std::false_type) try :
+ deleter_base(del)
+ {
+ }
+ catch (...)
+ {
+ if (BOOST_LIKELY(allocated))
+ del(res);
+ }
+};
+
+/*
+ * This metafunction indicates whether \c resource_holder should use \c compact_storage
+ * to optimize storage for the resource object. Its definition must be coherent with
+ * `resource_holder::move_from` definition and move constructor implementation in
+ * \c unique_resource_data.
+ *
+ * There is one tricky case with \c unique_resource move constructor, when the resource move
+ * constructor is noexcept and deleter's move and copy constructors are not. It is possible
+ * that \c unique_resource_data move constructor moves the resource into the object being
+ * constructed but fails to construct the deleter. In this case we want to move the resource
+ * back to the original \c unique_resource_data object (which is guaranteed to not throw since
+ * the resource's move constructor is non-throwing).
+ *
+ * However, if we use the move constructor to move the resource back, we need to use placement
+ * new, and this only lets us create a complete object of the resource type, which prohibits
+ * the use of \c compact_storage, as it may create the resource object as a base subobject of
+ * \c compact_storage. Using placement new on a base subobject may corrupt data that is placed
+ * in the trailing padding bits of the resource type.
+ *
+ * To work around this limitation, we also test if move assignment of the resource type is
+ * also non-throwing (which is reasonable to expect, given that the move constructor is
+ * non-throwing). If it is, we can avoid having to destroy and move-construct the resource and
+ * use move-assignment instead. This doesn't require a complete object of the resource type
+ * and allows us to use \c compact_storage. If move assignment is not noexcept then we have
+ * to use the move constructor and disable the \c compact_storage optimization.
+ *
+ * So this trait has to detect (a) whether we are affected by this tricky case of the
+ * \c unique_resource move constructor in the first place and (b) whether we can use move
+ * assignment to move the resource back to the original \c unique_resource object. If we're
+ * not affected or we can use move assignment then we enable \c compact_storage.
+ */
+template< typename Resource, typename Deleter >
+using use_resource_compact_storage = detail::disjunction<
+ std::is_nothrow_move_assignable< typename wrap_reference< Resource >::type >,
+ std::is_nothrow_constructible< typename wrap_reference< Deleter >::type, typename detail::move_or_copy_construct_ref< Deleter >::type >,
+ detail::negation< std::is_nothrow_constructible< typename wrap_reference< Resource >::type, typename detail::move_or_copy_construct_ref< Resource >::type > >
+>;
+
+template< typename Resource, typename Deleter, typename Traits >
+class unique_resource_data :
+ public detail::resource_holder< Resource, use_resource_compact_storage< Resource, Deleter >::value >,
+ public detail::deleter_holder< Resource, Deleter >
+{
+public:
+ using resource_type = Resource;
+ using deleter_type = Deleter;
+ using traits_type = Traits;
+
+private:
+ using resource_holder = detail::resource_holder< resource_type, use_resource_compact_storage< resource_type, deleter_type >::value >;
+ using deleter_holder = detail::deleter_holder< resource_type, deleter_type >;
+ using result_of_make_default = decltype(traits_type::make_default());
+
+public:
+ using internal_resource_type = typename resource_holder::internal_resource_type;
+ using internal_deleter_type = typename deleter_holder::internal_deleter_type;
+
+ static_assert(noexcept(traits_type::make_default()), "Invalid unique_resource resource traits: make_default must be noexcept");
+ static_assert(std::is_nothrow_assignable< internal_resource_type&, result_of_make_default >::value,
+ "Invalid unique_resource resource traits: resource must be nothrow-assignable from the result of make_default");
+ static_assert(noexcept(traits_type::is_allocated(std::declval< resource_type const& >())), "Invalid unique_resource resource traits: is_allocated must be noexcept");
+
+public:
+ template<
+ bool Requires = detail::conjunction<
+ std::is_constructible< resource_holder, result_of_make_default >,
+ std::is_default_constructible< deleter_holder >
+ >::value,
+ typename = typename std::enable_if< Requires >::type
+ >
+ constexpr unique_resource_data()
+ noexcept(detail::conjunction<
+ std::is_nothrow_constructible< resource_holder, result_of_make_default >,
+ std::is_nothrow_default_constructible< deleter_holder >
+ >::value) :
+ resource_holder(traits_type::make_default()),
+ deleter_holder()
+ {
+ }
+
+ unique_resource_data(unique_resource_data const&) = delete;
+ unique_resource_data& operator= (unique_resource_data const&) = delete;
+
+ unique_resource_data(unique_resource_data&& that)
+ noexcept(detail::conjunction<
+ std::is_nothrow_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >,
+ std::is_nothrow_constructible< internal_deleter_type, typename detail::move_or_copy_construct_ref< deleter_type >::type >
+ >::value) :
+ unique_resource_data
+ (
+ static_cast< unique_resource_data&& >(that),
+ typename std::is_nothrow_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >::type(),
+ typename std::is_nothrow_constructible< internal_deleter_type, typename detail::move_or_copy_construct_ref< deleter_type >::type >::type()
+ )
+ {
+ }
+
+ template<
+ typename D,
+ typename = typename std::enable_if< detail::conjunction<
+ std::is_constructible< resource_holder, result_of_make_default >,
+ std::is_constructible< deleter_holder, D >
+ >::value >::type
+ >
+ explicit unique_resource_data(default_resource_t, D&& del)
+ noexcept(detail::conjunction<
+ std::is_nothrow_constructible< resource_holder, result_of_make_default >,
+ std::is_nothrow_constructible< deleter_holder, D >
+ >::value) :
+ resource_holder(traits_type::make_default()),
+ deleter_holder(static_cast< D&& >(del))
+ {
+ }
+
+ template<
+ typename R,
+ typename D,
+ typename = typename std::enable_if< detail::conjunction<
+ detail::negation< detail::is_default_resource< R > >,
+ std::is_constructible< resource_holder, R, D, bool >,
+ std::is_constructible< deleter_holder, D, resource_type&, bool >
+ >::value >::type
+ >
+ explicit unique_resource_data(R&& res, D&& del)
+ noexcept(detail::conjunction<
+ std::is_nothrow_constructible< resource_holder, R, D, bool >,
+ std::is_nothrow_constructible< deleter_holder, D, resource_type&, bool >
+ >::value) :
+ unique_resource_data(static_cast< R&& >(res), static_cast< D&& >(del), traits_type::is_allocated(res)) // don't forward res to is_allocated to make sure res is not moved-from on resource construction
+ {
+ // Since res may not be of the resource type, the is_allocated call made above may require a type conversion or pick a different overload.
+ // We still require it to be noexcept, as we need to know whether we should deallocate it. Otherwise we may leak the resource.
+ static_assert(noexcept(traits_type::is_allocated(res)), "Invalid unique_resource resource traits: is_allocated must be noexcept");
+ }
+
+ template<
+ bool Requires = detail::conjunction<
+ std::is_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< resource_type >::type >,
+ std::is_assignable< internal_deleter_type&, typename detail::move_or_copy_assign_ref< deleter_type >::type >
+ >::value
+ >
+ typename std::enable_if< Requires, unique_resource_data& >::type operator= (unique_resource_data&& that)
+ noexcept(detail::conjunction<
+ std::is_nothrow_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< resource_type >::type >,
+ std::is_nothrow_assignable< internal_deleter_type&, typename detail::move_or_copy_assign_ref< deleter_type >::type >
+ >::value)
+ {
+ assign(static_cast< unique_resource_data&& >(that), typename std::is_nothrow_move_assignable< internal_deleter_type >::type());
+ return *this;
+ }
+
+ resource_type& get_resource() noexcept
+ {
+ return resource_holder::get();
+ }
+
+ resource_type const& get_resource() const noexcept
+ {
+ return resource_holder::get();
+ }
+
+ internal_resource_type& get_internal_resource() noexcept
+ {
+ return resource_holder::get_internal();
+ }
+
+ internal_resource_type const& get_internal_resource() const noexcept
+ {
+ return resource_holder::get_internal();
+ }
+
+ deleter_type& get_deleter() noexcept
+ {
+ return deleter_holder::get();
+ }
+
+ deleter_type const& get_deleter() const noexcept
+ {
+ return deleter_holder::get();
+ }
+
+ internal_deleter_type& get_internal_deleter() noexcept
+ {
+ return deleter_holder::get_internal();
+ }
+
+ internal_deleter_type const& get_internal_deleter() const noexcept
+ {
+ return deleter_holder::get_internal();
+ }
+
+ bool is_allocated() const noexcept
+ {
+ return traits_type::is_allocated(get_resource());
+ }
+
+ void set_unallocated() noexcept
+ {
+ get_internal_resource() = traits_type::make_default();
+ }
+
+ template< typename R >
+ void assign_resource(R&& res) noexcept(std::is_nothrow_assignable< internal_resource_type&, R >::value)
+ {
+ get_internal_resource() = static_cast< R&& >(res);
+ }
+
+ template<
+ bool Requires = detail::conjunction<
+ detail::is_swappable< internal_resource_type >,
+ detail::is_swappable< internal_deleter_type >,
+ detail::disjunction<
+ detail::is_nothrow_swappable< internal_resource_type >,
+ detail::is_nothrow_swappable< internal_deleter_type >
+ >
+ >::value
+ >
+ typename std::enable_if< Requires >::type swap(unique_resource_data& that)
+ noexcept(detail::conjunction< detail::is_nothrow_swappable< internal_resource_type >, detail::is_nothrow_swappable< internal_deleter_type > >::value)
+ {
+ swap_impl
+ (
+ that,
+ std::integral_constant< bool, detail::is_nothrow_swappable< internal_resource_type >::value >(),
+ std::integral_constant< bool, detail::conjunction<
+ detail::is_nothrow_swappable< internal_resource_type >,
+ detail::is_nothrow_swappable< internal_deleter_type >
+ >::value >()
+ );
+ }
+
+private:
+ unique_resource_data(unique_resource_data&& that, std::true_type, std::true_type) noexcept :
+ resource_holder(static_cast< typename detail::move_or_copy_construct_ref< resource_type >::type >(that.get_resource())),
+ deleter_holder(static_cast< typename detail::move_or_copy_construct_ref< deleter_type >::type >(that.get_deleter()))
+ {
+ that.set_unallocated();
+ }
+
+ unique_resource_data(unique_resource_data&& that, std::false_type, std::true_type) :
+ resource_holder(static_cast< resource_type const& >(that.get_resource())),
+ deleter_holder(static_cast< typename detail::move_or_copy_construct_ref< deleter_type >::type >(that.get_deleter()))
+ {
+ that.set_unallocated();
+ }
+
+ unique_resource_data(unique_resource_data&& that, std::true_type, std::false_type) try :
+ resource_holder(static_cast< typename detail::move_or_copy_construct_ref< resource_type >::type >(that.get_resource())),
+ deleter_holder(static_cast< deleter_type const& >(that.get_deleter()))
+ {
+ that.set_unallocated();
+ }
+ catch (...)
+ {
+ // Since only the deleter's constructor could have thrown an exception here, move the resource back
+ // to the original unique_resource. This is guaranteed to not throw.
+ that.resource_holder::move_from(static_cast< internal_resource_type&& >(resource_holder::get_internal()));
+ }
+
+ unique_resource_data(unique_resource_data&& that, std::false_type, std::false_type) :
+ resource_holder(static_cast< resource_type const& >(that.get_resource())),
+ deleter_holder(static_cast< deleter_type const& >(that.get_deleter()))
+ {
+ that.set_unallocated();
+ }
+
+ template<
+ typename R,
+ typename D,
+ typename = typename std::enable_if< detail::conjunction<
+ std::is_constructible< resource_holder, R, D, bool >,
+ std::is_constructible< deleter_holder, D, resource_type&, bool >
+ >::value >::type
+ >
+ explicit unique_resource_data(R&& res, D&& del, bool allocated)
+ noexcept(detail::conjunction<
+ std::is_nothrow_constructible< resource_holder, R, D, bool >,
+ std::is_nothrow_constructible< deleter_holder, D, resource_type&, bool >
+ >::value) :
+ resource_holder(static_cast< R&& >(res), static_cast< D&& >(del), allocated),
+ deleter_holder(static_cast< D&& >(del), resource_holder::get(), allocated)
+ {
+ }
+
+ void assign(unique_resource_data&& that, std::true_type)
+ noexcept(std::is_nothrow_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< resource_type >::type >::value)
+ {
+ get_internal_resource() = static_cast< typename detail::move_or_copy_assign_ref< resource_type >::type >(that.get_resource());
+ get_internal_deleter() = static_cast< typename detail::move_or_copy_assign_ref< deleter_type >::type >(that.get_deleter());
+
+ that.set_unallocated();
+ }
+
+ void assign(unique_resource_data&& that, std::false_type)
+ {
+ get_internal_deleter() = static_cast< typename detail::move_or_copy_assign_ref< deleter_type >::type >(that.get_deleter());
+ get_internal_resource() = static_cast< typename detail::move_or_copy_assign_ref< resource_type >::type >(that.get_resource());
+
+ that.set_unallocated();
+ }
+
+ void swap_impl(unique_resource_data& that, std::true_type, std::true_type) noexcept
+ {
+ boost::core::invoke_swap(get_internal_resource(), that.get_internal_resource());
+ boost::core::invoke_swap(get_internal_deleter(), that.get_internal_deleter());
+ }
+
+ void swap_impl(unique_resource_data& that, std::true_type, std::false_type)
+ {
+ boost::core::invoke_swap(get_internal_deleter(), that.get_internal_deleter());
+ boost::core::invoke_swap(get_internal_resource(), that.get_internal_resource());
+ }
+
+ void swap_impl(unique_resource_data& that, std::false_type, std::false_type)
+ {
+ boost::core::invoke_swap(get_internal_resource(), that.get_internal_resource());
+ boost::core::invoke_swap(get_internal_deleter(), that.get_internal_deleter());
+ }
+};
+
+template< typename Resource, typename Deleter >
+class unique_resource_data< Resource, Deleter, void > :
+ public detail::resource_holder< Resource, use_resource_compact_storage< Resource, Deleter >::value >,
+ public detail::deleter_holder< Resource, Deleter >
+{
+public:
+ using resource_type = Resource;
+ using deleter_type = Deleter;
+ using traits_type = void;
+
+private:
+ using resource_holder = detail::resource_holder< resource_type, use_resource_compact_storage< resource_type, deleter_type >::value >;
+ using deleter_holder = detail::deleter_holder< resource_type, deleter_type >;
+
+public:
+ using internal_resource_type = typename resource_holder::internal_resource_type;
+ using internal_deleter_type = typename deleter_holder::internal_deleter_type;
+
+private:
+ bool m_allocated;
+
+public:
+ template<
+ bool Requires = detail::conjunction< std::is_default_constructible< resource_holder >, std::is_default_constructible< deleter_holder > >::value,
+ typename = typename std::enable_if< Requires >::type
+ >
+ constexpr unique_resource_data()
+ noexcept(detail::conjunction< std::is_nothrow_default_constructible< resource_holder >, std::is_nothrow_default_constructible< deleter_holder > >::value) :
+ resource_holder(),
+ deleter_holder(),
+ m_allocated(false)
+ {
+ }
+
+ unique_resource_data(unique_resource_data const&) = delete;
+ unique_resource_data& operator= (unique_resource_data const&) = delete;
+
+ template<
+ bool Requires = detail::conjunction<
+ std::is_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >,
+ std::is_constructible< internal_deleter_type, typename detail::move_or_copy_construct_ref< deleter_type >::type >
+ >::value,
+ typename = typename std::enable_if< Requires >::type
+ >
+ unique_resource_data(unique_resource_data&& that)
+ noexcept(detail::conjunction<
+ std::is_nothrow_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >,
+ std::is_nothrow_constructible< internal_deleter_type, typename detail::move_or_copy_construct_ref< deleter_type >::type >
+ >::value) :
+ unique_resource_data
+ (
+ static_cast< unique_resource_data&& >(that),
+ typename std::is_nothrow_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >::type(),
+ typename std::is_nothrow_constructible< internal_deleter_type, typename detail::move_or_copy_construct_ref< deleter_type >::type >::type()
+ )
+ {
+ }
+
+ template<
+ typename D,
+ typename = typename std::enable_if< detail::conjunction<
+ std::is_default_constructible< resource_holder >,
+ std::is_constructible< deleter_holder, D >
+ >::value >::type
+ >
+ explicit unique_resource_data(default_resource_t, D&& del)
+ noexcept(detail::conjunction<
+ std::is_nothrow_default_constructible< resource_holder >,
+ std::is_nothrow_constructible< deleter_holder, D >
+ >::value) :
+ resource_holder(),
+ deleter_holder(static_cast< D&& >(del)),
+ m_allocated(false)
+ {
+ }
+
+ template<
+ typename R,
+ typename D,
+ typename = typename std::enable_if< detail::conjunction<
+ detail::negation< detail::is_default_resource< R > >,
+ std::is_constructible< resource_holder, R, D, bool >,
+ std::is_constructible< deleter_holder, D, resource_type&, bool >
+ >::value >::type
+ >
+ explicit unique_resource_data(R&& res, D&& del)
+ noexcept(detail::conjunction<
+ std::is_nothrow_constructible< resource_holder, R, D, bool >,
+ std::is_nothrow_constructible< deleter_holder, D, resource_type&, bool >
+ >::value) :
+ resource_holder(static_cast< R&& >(res), static_cast< D&& >(del), true),
+ deleter_holder(static_cast< D&& >(del), resource_holder::get(), true),
+ m_allocated(true)
+ {
+ }
+
+ template<
+ bool Requires = detail::conjunction<
+ std::is_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< resource_type >::type >,
+ std::is_assignable< internal_deleter_type&, typename detail::move_or_copy_assign_ref< deleter_type >::type >
+ >::value
+ >
+ typename std::enable_if< Requires, unique_resource_data& >::type operator= (unique_resource_data&& that)
+ noexcept(detail::conjunction<
+ std::is_nothrow_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< resource_type >::type >,
+ std::is_nothrow_assignable< internal_deleter_type&, typename detail::move_or_copy_assign_ref< deleter_type >::type >
+ >::value)
+ {
+ assign(static_cast< unique_resource_data&& >(that), typename std::is_nothrow_move_assignable< internal_deleter_type >::type());
+ return *this;
+ }
+
+ resource_type& get_resource() noexcept
+ {
+ return resource_holder::get();
+ }
+
+ resource_type const& get_resource() const noexcept
+ {
+ return resource_holder::get();
+ }
+
+ internal_resource_type& get_internal_resource() noexcept
+ {
+ return resource_holder::get_internal();
+ }
+
+ internal_resource_type const& get_internal_resource() const noexcept
+ {
+ return resource_holder::get_internal();
+ }
+
+ deleter_type& get_deleter() noexcept
+ {
+ return deleter_holder::get();
+ }
+
+ deleter_type const& get_deleter() const noexcept
+ {
+ return deleter_holder::get();
+ }
+
+ internal_deleter_type& get_internal_deleter() noexcept
+ {
+ return deleter_holder::get_internal();
+ }
+
+ internal_deleter_type const& get_internal_deleter() const noexcept
+ {
+ return deleter_holder::get_internal();
+ }
+
+ bool is_allocated() const noexcept
+ {
+ return m_allocated;
+ }
+
+ void set_unallocated() noexcept
+ {
+ m_allocated = false;
+ }
+
+ template< typename R >
+ void assign_resource(R&& res) noexcept(std::is_nothrow_assignable< internal_resource_type&, R >::value)
+ {
+ get_internal_resource() = static_cast< R&& >(res);
+ m_allocated = true;
+ }
+
+ template<
+ bool Requires = detail::conjunction<
+ detail::is_swappable< internal_resource_type >,
+ detail::is_swappable< internal_deleter_type >,
+ detail::disjunction<
+ detail::is_nothrow_swappable< internal_resource_type >,
+ detail::is_nothrow_swappable< internal_deleter_type >
+ >
+ >::value
+ >
+ typename std::enable_if< Requires >::type swap(unique_resource_data& that)
+ noexcept(detail::conjunction< detail::is_nothrow_swappable< internal_resource_type >, detail::is_nothrow_swappable< internal_deleter_type > >::value)
+ {
+ swap_impl
+ (
+ that,
+ std::integral_constant< bool, detail::is_nothrow_swappable< internal_resource_type >::value >(),
+ std::integral_constant< bool, detail::conjunction<
+ detail::is_nothrow_swappable< internal_resource_type >,
+ detail::is_nothrow_swappable< internal_deleter_type >
+ >::value >()
+ );
+ }
+
+private:
+ unique_resource_data(unique_resource_data&& that, std::true_type, std::true_type) noexcept :
+ resource_holder(static_cast< typename detail::move_or_copy_construct_ref< resource_type >::type >(that.get_resource())),
+ deleter_holder(static_cast< typename detail::move_or_copy_construct_ref< deleter_type >::type >(that.get_deleter())),
+ m_allocated(that.m_allocated)
+ {
+ that.m_allocated = false;
+ }
+
+ unique_resource_data(unique_resource_data&& that, std::false_type, std::true_type) :
+ resource_holder(static_cast< resource_type const& >(that.get_resource())),
+ deleter_holder(static_cast< typename detail::move_or_copy_construct_ref< deleter_type >::type >(that.get_deleter())),
+ m_allocated(that.m_allocated)
+ {
+ that.m_allocated = false;
+ }
+
+ unique_resource_data(unique_resource_data&& that, std::true_type, std::false_type) try :
+ resource_holder(static_cast< typename detail::move_or_copy_construct_ref< resource_type >::type >(that.get_resource())),
+ deleter_holder(static_cast< deleter_type const& >(that.get_deleter())),
+ m_allocated(that.m_allocated)
+ {
+ that.m_allocated = false;
+ }
+ catch (...)
+ {
+ // Since only the deleter's constructor could have thrown an exception here, move the resource back
+ // to the original unique_resource. This is guaranteed to not throw.
+ that.resource_holder::move_from(static_cast< internal_resource_type&& >(resource_holder::get_internal()));
+ }
+
+ unique_resource_data(unique_resource_data&& that, std::false_type, std::false_type) :
+ resource_holder(static_cast< resource_type const& >(that.get_resource())),
+ deleter_holder(static_cast< deleter_type const& >(that.get_deleter())),
+ m_allocated(that.m_allocated)
+ {
+ that.m_allocated = false;
+ }
+
+ void assign(unique_resource_data&& that, std::true_type)
+ noexcept(std::is_nothrow_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< resource_type >::type >::value)
+ {
+ get_internal_resource() = static_cast< typename detail::move_or_copy_assign_ref< resource_type >::type >(that.get_resource());
+ get_internal_deleter() = static_cast< typename detail::move_or_copy_assign_ref< deleter_type >::type >(that.get_deleter());
+
+ m_allocated = that.m_allocated;
+ that.m_allocated = false;
+ }
+
+ void assign(unique_resource_data&& that, std::false_type)
+ {
+ get_internal_deleter() = static_cast< typename detail::move_or_copy_assign_ref< deleter_type >::type >(that.get_deleter());
+ get_internal_resource() = static_cast< typename detail::move_or_copy_assign_ref< resource_type >::type >(that.get_resource());
+
+ m_allocated = that.m_allocated;
+ that.m_allocated = false;
+ }
+
+ void swap_impl(unique_resource_data& that, std::true_type, std::true_type) noexcept
+ {
+ boost::core::invoke_swap(get_internal_resource(), that.get_internal_resource());
+ boost::core::invoke_swap(get_internal_deleter(), that.get_internal_deleter());
+ boost::core::invoke_swap(m_allocated, that.m_allocated);
+ }
+
+ void swap_impl(unique_resource_data& that, std::true_type, std::false_type)
+ {
+ boost::core::invoke_swap(get_internal_deleter(), that.get_internal_deleter());
+ boost::core::invoke_swap(get_internal_resource(), that.get_internal_resource());
+ boost::core::invoke_swap(m_allocated, that.m_allocated);
+ }
+
+ void swap_impl(unique_resource_data& that, std::false_type, std::false_type)
+ {
+ boost::core::invoke_swap(get_internal_resource(), that.get_internal_resource());
+ boost::core::invoke_swap(get_internal_deleter(), that.get_internal_deleter());
+ boost::core::invoke_swap(m_allocated, that.m_allocated);
+ }
+};
+
+template< typename T >
+struct is_dereferenceable_impl
+{
+ template< typename U, typename R = decltype(*std::declval< U const& >()) >
+ static std::true_type _is_dereferenceable_check(int);
+ template< typename U >
+ static std::false_type _is_dereferenceable_check(...);
+
+ using type = decltype(is_dereferenceable_impl::_is_dereferenceable_check< T >(0));
+};
+
+template< typename T >
+struct is_dereferenceable : public is_dereferenceable_impl< T >::type { };
+template< >
+struct is_dereferenceable< void* > : public std::false_type { };
+template< >
+struct is_dereferenceable< const void* > : public std::false_type { };
+template< >
+struct is_dereferenceable< volatile void* > : public std::false_type { };
+template< >
+struct is_dereferenceable< const volatile void* > : public std::false_type { };
+template< >
+struct is_dereferenceable< void*& > : public std::false_type { };
+template< >
+struct is_dereferenceable< const void*& > : public std::false_type { };
+template< >
+struct is_dereferenceable< volatile void*& > : public std::false_type { };
+template< >
+struct is_dereferenceable< const volatile void*& > : public std::false_type { };
+template< >
+struct is_dereferenceable< void* const& > : public std::false_type { };
+template< >
+struct is_dereferenceable< const void* const& > : public std::false_type { };
+template< >
+struct is_dereferenceable< volatile void* const& > : public std::false_type { };
+template< >
+struct is_dereferenceable< const volatile void* const& > : public std::false_type { };
+template< >
+struct is_dereferenceable< void* volatile& > : public std::false_type { };
+template< >
+struct is_dereferenceable< const void* volatile& > : public std::false_type { };
+template< >
+struct is_dereferenceable< volatile void* volatile& > : public std::false_type { };
+template< >
+struct is_dereferenceable< const volatile void* volatile& > : public std::false_type { };
+template< >
+struct is_dereferenceable< void* const volatile& > : public std::false_type { };
+template< >
+struct is_dereferenceable< const void* const volatile& > : public std::false_type { };
+template< >
+struct is_dereferenceable< volatile void* const volatile& > : public std::false_type { };
+template< >
+struct is_dereferenceable< const volatile void* const volatile& > : public std::false_type { };
+
+template< typename T, bool = detail::is_dereferenceable< T >::value >
+struct dereference_traits { };
+template< typename T >
+struct dereference_traits< T, true >
+{
+ using result_type = decltype(*std::declval< T const& >());
+ static constexpr bool is_noexcept = noexcept(*std::declval< T const& >());
+};
+
+} // namespace detail
+
+/*!
+ * \brief RAII wrapper for automatically reclaiming arbitrary resources.
+ *
+ * A \c unique_resource object exclusively owns wrapped resource and invokes
+ * the deleter function object on it on destruction. The wrapped resource can have
+ * any type that is:
+ *
+ * \li Move-constructible, where the move constructor is marked as `noexcept`, or
+ * \li Copy-constructible, or
+ * \li An lvalue reference to an object type.
+ *
+ * The deleter must be a function object type that is callable on an lvalue
+ * of the resource type. The deleter must be copy-constructible.
+ *
+ * An optional resource traits template parameter may be specified. Resource
+ * traits can be used to optimize \c unique_resource implementation when
+ * the following conditions are met:
+ *
+ * \li There is at least one value of the resource type that is considered
+ * unallocated (that is, no allocated resource shall be equal to one of
+ * the unallocated resource values). The unallocated resource values need not
+ * be deallocated using the deleter.
+ * \li One of the unallocated resource values can be considered the default.
+ * Constructing the default resource value and assigning it to a resource
+ * object (whether allocated or not) shall not throw exceptions.
+ * \li Resource objects can be tested for being unallocated. Such a test shall
+ * not throw exceptions.
+ *
+ * If specified, the resource traits must be a class type that has the following
+ * public static members:
+ *
+ * \li `R make_default() noexcept` - must return the default resource value such
+ * that `std::is_constructible< Resource, R >::value &&
+ * std::is_nothrow_assignable< Resource&, R >::value` is \c true.
+ * \li `bool is_allocated(Resource const& res) noexcept` - must return \c true
+ * if \c res is not one of the unallocated resource values and \c false
+ * otherwise.
+ *
+ * Note that `is_allocated(make_default())` must always return \c false.
+ *
+ * When resource traits satisfying the above requirements are specified,
+ * \c unique_resource will be able to avoid storing additional indication of
+ * whether the owned resource object needs to be deallocated with the deleter
+ * on destruction. It will use the default resource value to initialize the owned
+ * resource object when \c unique_resource is not in the allocated state.
+ * Additionally, it will be possible to construct \c unique_resource with
+ * unallocated resource values, which will create \c unique_resource objects in
+ * unallocated state (the deleter will not be called on unallocated resource
+ * values).
+ *
+ * \tparam Resource Resource type.
+ * \tparam Deleter Resource deleter function object type.
+ * \tparam Traits Optional resource traits type.
+ */
+template< typename Resource, typename Deleter, typename Traits BOOST_SCOPE_DETAIL_DOC(= void) >
+class unique_resource
+{
+public:
+ //! Resource type
+ using resource_type = Resource;
+ //! Deleter type
+ using deleter_type = Deleter;
+ //! Resource traits
+ using traits_type = Traits;
+
+//! \cond
+private:
+ using data = detail::unique_resource_data< resource_type, deleter_type, traits_type >;
+ using internal_resource_type = typename data::internal_resource_type;
+ using internal_deleter_type = typename data::internal_deleter_type;
+
+ data m_data;
+
+//! \endcond
+public:
+ /*!
+ * \brief Constructs an unallocated unique resource guard.
+ *
+ * **Requires:** Default \c Resource value can be constructed. \c Deleter is default-constructible
+ * and is not a pointer to function.
+ *
+ * **Effects:** Initializes the \c Resource object with the default resource value. Default-constructs
+ * the \c Deleter object.
+ *
+ * **Throws:** Nothing, unless construction of \c Resource or \c Deleter throws.
+ *
+ * \post `this->allocated() == false`
+ */
+ //! \cond
+ template<
+ bool Requires = std::is_default_constructible< data >::value,
+ typename = typename std::enable_if< Requires >::type
+ >
+ //! \endcond
+ constexpr unique_resource() noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_default_constructible< data >::value))
+ {
+ }
+
+ /*!
+ * \brief Constructs an unallocated unique resource guard with the given deleter.
+ *
+ * **Requires:** Default \c Resource value can be constructed and \c Deleter is constructible from \a del.
+ *
+ * **Effects:** Initializes the \c Resource value with the default resource value. If \c Deleter is nothrow
+ * constructible from `D&&` then constructs \c Deleter from `std::forward< D >(del)`,
+ * otherwise constructs from `del`.
+ *
+ * **Throws:** Nothing, unless construction of \c Resource or \c Deleter throws.
+ *
+ * \param res A tag argument indicating default resource value.
+ * \param del Resource deleter function object.
+ *
+ * \post `this->allocated() == false`
+ */
+ template<
+ typename D
+ //! \cond
+ , typename = typename std::enable_if<
+ std::is_constructible< data, default_resource_t, typename detail::move_or_copy_construct_ref< D, deleter_type >::type >::value
+ >::type
+ //! \endcond
+ >
+ unique_resource(default_resource_t res, D&& del)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
+ std::is_nothrow_constructible<
+ data,
+ default_resource_t,
+ typename detail::move_or_copy_construct_ref< D, deleter_type >::type
+ >::value
+ )) :
+ m_data
+ (
+ res,
+ static_cast< typename detail::move_or_copy_construct_ref< D, deleter_type >::type >(del)
+ )
+ {
+ }
+
+ /*!
+ * \brief Constructs a unique resource guard with the given resource and a default-constructed deleter.
+ *
+ * **Requires:** \c Resource is constructible from \a res. \c Deleter is default-constructible and
+ * is not a pointer to function.
+ *
+ * **Effects:** Constructs the unique resource object as if by calling
+ * `unique_resource(std::forward< R >(res), Deleter())`.
+ *
+ * **Throws:** Nothing, unless construction of \c Resource or \c Deleter throws.
+ *
+ * \param res Resource object.
+ */
+ template<
+ typename R
+ //! \cond
+ , typename = typename std::enable_if< detail::conjunction<
+ detail::is_nothrow_nonnull_default_constructible< deleter_type >,
+ std::is_constructible< data, typename detail::move_or_copy_construct_ref< R, resource_type >::type, typename detail::move_or_copy_construct_ref< deleter_type >::type >,
+ detail::disjunction< detail::negation< std::is_reference< resource_type > >, std::is_reference< R > > // prevent binding lvalue-reference resource to an rvalue
+ >::value >::type
+ //! \endcond
+ >
+ explicit unique_resource(R&& res)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
+ std::is_nothrow_constructible<
+ data,
+ typename detail::move_or_copy_construct_ref< R, resource_type >::type,
+ typename detail::move_or_copy_construct_ref< deleter_type >::type
+ >::value
+ )) :
+ m_data
+ (
+ static_cast< typename detail::move_or_copy_construct_ref< R, resource_type >::type >(res),
+ static_cast< typename detail::move_or_copy_construct_ref< deleter_type >::type >(deleter_type())
+ )
+ {
+ }
+
+ /*!
+ * \brief Constructs a unique resource guard with the given resource and deleter.
+ *
+ * **Requires:** \c Resource is constructible from \a res and \c Deleter is constructible from \a del.
+ *
+ * **Effects:** If \c Resource is nothrow constructible from `R&&` then constructs \c Resource
+ * from `std::forward< R >(res)`, otherwise constructs from `res`. If \c Deleter
+ * is nothrow constructible from `D&&` then constructs \c Deleter from
+ * `std::forward< D >(del)`, otherwise constructs from `del`.
+ *
+ * If construction of \c Resource or \c Deleter throws and \a res is not an unallocated resource
+ * value, invokes \a del on \a res (if \c Resource construction failed) or the constructed
+ * \c Resource object (if \c Deleter construction failed).
+ *
+ * **Throws:** Nothing, unless construction of \c Resource or \c Deleter throws.
+ *
+ * \param res Resource object.
+ * \param del Resource deleter function object.
+ *
+ * \post If \a res is an unallocated resource value then `this->allocated() == false`, otherwise
+ * `this->allocated() == true`.
+ */
+ template<
+ typename R,
+ typename D
+ //! \cond
+ , typename = typename std::enable_if< detail::conjunction<
+ std::is_constructible< data, typename detail::move_or_copy_construct_ref< R, resource_type >::type, typename detail::move_or_copy_construct_ref< D, deleter_type >::type >,
+ detail::disjunction< detail::negation< std::is_reference< resource_type > >, std::is_reference< R > > // prevent binding lvalue-reference resource to an rvalue
+ >::value >::type
+ //! \endcond
+ >
+ unique_resource(R&& res, D&& del)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
+ std::is_nothrow_constructible<
+ data,
+ typename detail::move_or_copy_construct_ref< R, resource_type >::type,
+ typename detail::move_or_copy_construct_ref< D, deleter_type >::type
+ >::value
+ )) :
+ m_data
+ (
+ static_cast< typename detail::move_or_copy_construct_ref< R, resource_type >::type >(res),
+ static_cast< typename detail::move_or_copy_construct_ref< D, deleter_type >::type >(del)
+ )
+ {
+ }
+
+ unique_resource(unique_resource const&) = delete;
+ unique_resource& operator= (unique_resource const&) = delete;
+
+ /*!
+ * \brief Move-constructs a unique resource guard.
+ *
+ * **Requires:** \c Resource and \c Deleter are move-constructible.
+ *
+ * **Effects:** If \c Resource is nothrow move-constructible then move-constructs \c Resource,
+ * otherwise copy-constructs. If \c Deleter is nothrow move-constructible then move-constructs
+ * \c Deleter, otherwise copy-constructs. Deactivates the moved-from unique resource object.
+ *
+ * If an exception is thrown during construction, \a that is left in its original state.
+ *
+ * \note This logic ensures that in case of exception the resource is not leaked and remains owned by the
+ * move source.
+ *
+ * **Throws:** Nothing, unless construction of \c Resource or \c Deleter throws.
+ *
+ * \param that Move source.
+ *
+ * \post Let \c allocated be equal to `that.allocated()` prior to the operation. Then
+ * `this->allocated() == allocated` and `that.allocated() == false`.
+ */
+ //! \cond
+ template<
+ bool Requires = std::is_move_constructible< data >::value,
+ typename = typename std::enable_if< Requires >::type
+ >
+ //! \endcond
+ unique_resource(unique_resource&& that) noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_move_constructible< data >::value)) :
+ m_data(static_cast< data&& >(that.m_data))
+ {
+ }
+
+ /*!
+ * \brief Move-assigns a unique resource guard.
+ *
+ * **Requires:** \c Resource and \c Deleter are move-assignable.
+ *
+ * **Effects:** Calls `this->reset()`. Then, if \c Deleter is nothrow move-assignable, move-assigns
+ * the \c Deleter object first and the \c Resource object next. Otherwise, move-assigns
+ * the objects in reverse order. Lastly, deactivates the moved-from unique resource object.
+ *
+ * If an exception is thrown, \a that is left in its original state.
+ *
+ * \note The different orders of assignment ensure that in case of exception the resource is not leaked
+ * and remains owned by the move source.
+ *
+ * **Throws:** Nothing, unless assignment of \c Resource or \c Deleter throws.
+ *
+ * \param that Move source.
+ *
+ * \post Let \c allocated be equal to `that.allocated()` prior to the operation. Then
+ * `this->allocated() == allocated` and `that.allocated() == false`.
+ */
+#if !defined(BOOST_SCOPE_DOXYGEN)
+ template< bool Requires = std::is_move_assignable< data >::value >
+ typename std::enable_if< Requires, unique_resource& >::type
+#else
+ unique_resource&
+#endif
+ operator= (unique_resource&& that)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_move_assignable< data >::value))
+ {
+ reset();
+ m_data = static_cast< data&& >(that.m_data);
+ return *this;
+ }
+
+ /*!
+ * \brief If the resource is allocated, calls the deleter function on it. Destroys the resource and the deleter.
+ *
+ * **Throws:** Nothing, unless invoking the deleter throws.
+ */
+ ~unique_resource() noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(detail::is_nothrow_invocable< deleter_type&, resource_type& >::value))
+ {
+ if (BOOST_LIKELY(m_data.is_allocated()))
+ m_data.get_deleter()(m_data.get_resource());
+ }
+
+ /*!
+ * \brief Returns \c true if the resource is allocated and to be reclaimed by the deleter, otherwise \c false.
+ *
+ * \note This method does not test the value of the resource.
+ *
+ * **Throws:** Nothing.
+ */
+ explicit operator bool () const noexcept
+ {
+ return m_data.is_allocated();
+ }
+
+ /*!
+ * \brief Returns \c true if the resource is allocated and to be reclaimed by the deleter, otherwise \c false.
+ *
+ * **Throws:** Nothing.
+ */
+ bool allocated() const noexcept
+ {
+ return m_data.is_allocated();
+ }
+
+ /*!
+ * \brief Returns a reference to the resource object.
+ *
+ * **Throws:** Nothing.
+ */
+ resource_type const& get() const noexcept
+ {
+ return m_data.get_resource();
+ }
+
+ /*!
+ * \brief Returns a reference to the deleter object.
+ *
+ * **Throws:** Nothing.
+ */
+ deleter_type const& get_deleter() const noexcept
+ {
+ return m_data.get_deleter();
+ }
+
+ /*!
+ * \brief Marks the resource as unallocated. Does not call the deleter if the resource was previously allocated.
+ *
+ * **Throws:** Nothing.
+ *
+ * \post `this->allocated() == false`
+ */
+ void release() noexcept
+ {
+ m_data.set_unallocated();
+ }
+
+ /*!
+ * \brief If the resource is allocated, calls the deleter function on it and marks the resource as unallocated.
+ *
+ * **Throws:** Nothing, unless invoking the deleter throws.
+ *
+ * \post `this->allocated() == false`
+ */
+ void reset() noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(detail::is_nothrow_invocable< deleter_type&, resource_type& >::value))
+ {
+ if (BOOST_LIKELY(m_data.is_allocated()))
+ {
+ m_data.get_deleter()(m_data.get_resource());
+ m_data.set_unallocated();
+ }
+ }
+
+ /*!
+ * \brief Assigns a new resource object to the unique resource wrapper.
+ *
+ * **Effects:** Calls `this->reset()`. Then, if \c Resource is nothrow assignable from `R&&`,
+ * assigns `std::forward< R >(res)` to the stored resource object, otherwise assigns
+ * `res`.
+ *
+ * If \a res is not an unallocated resource value and an exception is thrown during the operation,
+ * invokes the stored deleter on \a res before returning with the exception.
+ *
+ * **Throws:** Nothing, unless invoking the deleter throws.
+ *
+ * \param res Resource object to assign.
+ *
+ * \post `this->allocated() == false`
+ */
+ template< typename R >
+#if !defined(BOOST_SCOPE_DOXYGEN)
+ typename std::enable_if< detail::conjunction<
+ std::is_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< R, resource_type >::type >,
+ detail::disjunction< detail::negation< std::is_reference< resource_type > >, std::is_reference< R > > // prevent binding lvalue-reference resource to an rvalue
+ >::value >::type
+#else
+ void
+#endif
+ reset(R&& res)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
+ detail::conjunction<
+ detail::is_nothrow_invocable< deleter_type&, resource_type& >,
+ std::is_nothrow_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< R, resource_type >::type >
+ >::value
+ ))
+ {
+ reset_impl
+ (
+ static_cast< R&& >(res),
+ typename detail::conjunction<
+ detail::is_nothrow_invocable< deleter_type&, resource_type& >,
+ std::is_nothrow_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< R, resource_type >::type >
+ >::type()
+ );
+ }
+
+ /*!
+ * \brief Invokes indirection on the resource object.
+ *
+ * **Requires:** \c Resource is dereferenceable.
+ *
+ * **Effects:** Returns a reference to the resource object as if by calling `get()`.
+ *
+ * \note If \c Resource is not a pointer type, the compiler will invoke its `operator->`.
+ * Such call sequence will continue until a pointer is obtained.
+ *
+ * **Throws:** Nothing. Note that any implicit subsequent calls to other `operator->`
+ * functions that are caused by this call may have different throw conditions.
+ */
+#if !defined(BOOST_SCOPE_DOXYGEN)
+ template< bool Requires = detail::is_dereferenceable< resource_type >::value >
+ typename std::enable_if< Requires, resource_type const& >::type
+#else
+ resource_type const&
+#endif
+ operator-> () const noexcept
+ {
+ return get();
+ }
+
+ /*!
+ * \brief Dereferences the resource object.
+ *
+ * **Requires:** \c Resource is dereferenceable.
+ *
+ * **Effects:** Returns the result of dereferencing the resource object as if by calling `*get()`.
+ *
+ * **Throws:** Nothing, unless dereferencing the resource object throws.
+ */
+#if !defined(BOOST_SCOPE_DOXYGEN)
+ template< bool Requires = detail::is_dereferenceable< resource_type >::value >
+ typename detail::dereference_traits< resource_type, Requires >::result_type
+#else
+ auto
+#endif
+ operator* () const
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(detail::dereference_traits< resource_type, Requires >::is_noexcept))
+ {
+ return *get();
+ }
+
+ /*!
+ * \brief Swaps two unique resource wrappers.
+ *
+ * **Requires:** \c Resource and \c Deleter are swappable. At least one of \c Resource and \c Deleter
+ * is nothrow swappable.
+ *
+ * **Effects:** Swaps the resource objects and deleter objects stored in `*this` and \a that
+ * as if by calling unqualified `swap` in a context where `std::swap` is
+ * found by overload resolution.
+ *
+ * If an exception is thrown, and the failed swap operation supports strong exception
+ * guarantee, both `*this` and \a that are left in their original states.
+ *
+ * **Throws:** Nothing, unless swapping the resource objects or deleters throw.
+ *
+ * \param that Unique resource wrapper to swap with.
+ */
+#if !defined(BOOST_SCOPE_DOXYGEN)
+ template< bool Requires = detail::is_swappable< data >::value >
+ typename std::enable_if< Requires >::type
+#else
+ void
+#endif
+ swap(unique_resource& that)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(detail::is_nothrow_swappable< data >::value))
+ {
+ m_data.swap(that.m_data);
+ }
+
+ /*!
+ * \brief Swaps two unique resource wrappers.
+ *
+ * **Effects:** As if `left.swap(right)`.
+ */
+#if !defined(BOOST_SCOPE_DOXYGEN)
+ template< bool Requires = detail::is_swappable< data >::value >
+ friend typename std::enable_if< Requires >::type
+#else
+ friend void
+#endif
+ swap(unique_resource& left, unique_resource& right)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(detail::is_nothrow_swappable< data >::value))
+ {
+ left.swap(right);
+ }
+
+//! \cond
+private:
+ //! Assigns a new resource object to the unique resource wrapper.
+ template< typename R >
+ void reset_impl(R&& res, std::true_type) noexcept
+ {
+ reset();
+ m_data.assign_resource(static_cast< typename detail::move_or_copy_assign_ref< R, resource_type >::type >(res));
+ }
+
+ //! Assigns a new resource object to the unique resource wrapper.
+ template< typename R >
+ void reset_impl(R&& res, std::false_type)
+ {
+ try
+ {
+ reset();
+ m_data.assign_resource(static_cast< typename detail::move_or_copy_assign_ref< R, resource_type >::type >(res));
+ }
+ catch (...)
+ {
+ m_data.get_deleter()(static_cast< R&& >(res));
+ throw;
+ }
+ }
+//! \endcond
+};
+
+#if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
+template<
+ typename Resource,
+ typename Deleter,
+ typename = typename std::enable_if< !detail::is_default_resource< Resource >::value >::type
+>
+unique_resource(Resource, Deleter) -> unique_resource< Resource, Deleter >;
+#endif // !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
+
+/*!
+ * \brief Checks if the resource is valid and creates a \c unique_resource wrapper.
+ *
+ * **Effects:** If the resource \a res is not equal to \a invalid, creates a unique resource wrapper
+ * that is in allocated state and owns \a res. Otherwise creates a unique resource wrapper
+ * in unallocated state.
+ *
+ * \note This function does not call \a del if \a res is equal to \a invalid.
+ *
+ * **Throws:** Nothing, unless \c unique_resource constructor throws.
+ *
+ * \param res Resource to wrap.
+ * \param invalid An invalid value for the resource.
+ * \param del A deleter to invoke on the resource to free it.
+ */
+template< typename Resource, typename Deleter, typename Invalid >
+inline unique_resource< typename std::decay< Resource >::type, typename std::decay< Deleter >::type >
+make_unique_resource_checked(Resource&& res, Invalid const& invalid, Deleter&& del)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
+ detail::conjunction<
+ std::is_nothrow_constructible< typename std::decay< Resource >::type, typename detail::move_or_copy_construct_ref< Resource, typename std::decay< Resource >::type >::type >,
+ std::is_nothrow_constructible< typename std::decay< Deleter >::type, typename detail::move_or_copy_construct_ref< Deleter, typename std::decay< Deleter >::type >::type >
+ >::value
+ ))
+{
+ using unique_resource_type = unique_resource< typename std::decay< Resource >::type, typename std::decay< Deleter >::type >;
+ if (!(res == invalid))
+ return unique_resource_type(static_cast< Resource&& >(res), static_cast< Deleter&& >(del));
+ else
+ return unique_resource_type(default_resource_t(), static_cast< Deleter&& >(del));
+}
+
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_UNIQUE_RESOURCE_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/include/boost/scope/unique_resource_fwd.hpp b/contrib/restricted/boost/scope/include/boost/scope/unique_resource_fwd.hpp
new file mode 100644
index 0000000000..aa9c30ec92
--- /dev/null
+++ b/contrib/restricted/boost/scope/include/boost/scope/unique_resource_fwd.hpp
@@ -0,0 +1,46 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * https://www.boost.org/LICENSE_1_0.txt)
+ *
+ * Copyright (c) 2022 Andrey Semashev
+ */
+/*!
+ * \file scope/unique_resource_fwd.hpp
+ *
+ * This header contains forward declaration of \c unique_resource template.
+ */
+
+#ifndef BOOST_SCOPE_UNIQUE_RESOURCE_FWD_HPP_INCLUDED_
+#define BOOST_SCOPE_UNIQUE_RESOURCE_FWD_HPP_INCLUDED_
+
+#include <type_traits>
+#include <boost/scope/detail/config.hpp>
+#include <boost/scope/detail/move_or_copy_construct_ref.hpp>
+#include <boost/scope/detail/type_traits/conjunction.hpp>
+#include <boost/scope/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace scope {
+
+template< typename Resource, typename Deleter, typename Traits = void >
+class unique_resource;
+
+template< typename Resource, typename Deleter, typename Invalid = typename std::decay< Resource >::type >
+unique_resource< typename std::decay< Resource >::type, typename std::decay< Deleter >::type >
+make_unique_resource_checked(Resource&& res, Invalid const& invalid, Deleter&& del)
+ noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(detail::conjunction<
+ std::is_nothrow_constructible< typename std::decay< Resource >::type, typename detail::move_or_copy_construct_ref< Resource, typename std::decay< Resource >::type >::type >,
+ std::is_nothrow_constructible< typename std::decay< Deleter >::type, typename detail::move_or_copy_construct_ref< Deleter, typename std::decay< Deleter >::type >::type >
+ >::value));
+
+} // namespace scope
+} // namespace boost
+
+#include <boost/scope/detail/footer.hpp>
+
+#endif // BOOST_SCOPE_UNIQUE_RESOURCE_FWD_HPP_INCLUDED_
diff --git a/contrib/restricted/boost/scope/ya.make b/contrib/restricted/boost/scope/ya.make
new file mode 100644
index 0000000000..b81b5900fe
--- /dev/null
+++ b/contrib/restricted/boost/scope/ya.make
@@ -0,0 +1,27 @@
+# Generated by devtools/yamaker from nixpkgs 22.11.
+
+LIBRARY()
+
+LICENSE(BSL-1.0)
+
+LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
+
+VERSION(1.86.0)
+
+ORIGINAL_SOURCE(https://github.com/boostorg/scope/archive/boost-1.86.0.tar.gz)
+
+PEERDIR(
+ contrib/restricted/boost/config
+ contrib/restricted/boost/core
+ contrib/restricted/boost/type_traits
+)
+
+ADDINCL(
+ GLOBAL contrib/restricted/boost/scope/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
+END()