整理
This commit is contained in:
180
include/boost/scope/defer.hpp
Normal file
180
include/boost/scope/defer.hpp
Normal file
@@ -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_
|
||||
102
include/boost/scope/detail/compact_storage.hpp
Normal file
102
include/boost/scope/detail/compact_storage.hpp
Normal file
@@ -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_
|
||||
50
include/boost/scope/detail/config.hpp
Normal file
50
include/boost/scope/detail/config.hpp
Normal file
@@ -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_
|
||||
22
include/boost/scope/detail/footer.hpp
Normal file
22
include/boost/scope/detail/footer.hpp
Normal file
@@ -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)
|
||||
49
include/boost/scope/detail/header.hpp
Normal file
49
include/boost/scope/detail/header.hpp
Normal file
@@ -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)
|
||||
@@ -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_
|
||||
49
include/boost/scope/detail/is_not_like.hpp
Normal file
49
include/boost/scope/detail/is_not_like.hpp
Normal file
@@ -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_
|
||||
52
include/boost/scope/detail/move_or_copy_assign_ref.hpp
Normal file
52
include/boost/scope/detail/move_or_copy_assign_ref.hpp
Normal file
@@ -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_
|
||||
52
include/boost/scope/detail/move_or_copy_construct_ref.hpp
Normal file
52
include/boost/scope/detail/move_or_copy_construct_ref.hpp
Normal file
@@ -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_
|
||||
53
include/boost/scope/detail/type_traits/conjunction.hpp
Normal file
53
include/boost/scope/detail/type_traits/conjunction.hpp
Normal file
@@ -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_
|
||||
53
include/boost/scope/detail/type_traits/disjunction.hpp
Normal file
53
include/boost/scope/detail/type_traits/disjunction.hpp
Normal file
@@ -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_
|
||||
53
include/boost/scope/detail/type_traits/is_final.hpp
Normal file
53
include/boost/scope/detail/type_traits/is_final.hpp
Normal file
@@ -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_
|
||||
65
include/boost/scope/detail/type_traits/is_invocable.hpp
Normal file
65
include/boost/scope/detail/type_traits/is_invocable.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#include <utility> // std::declval
|
||||
|
||||
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_
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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 <utility> // std::declval
|
||||
#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_
|
||||
@@ -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_
|
||||
53
include/boost/scope/detail/type_traits/is_swappable.hpp
Normal file
53
include/boost/scope/detail/type_traits/is_swappable.hpp
Normal file
@@ -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_
|
||||
53
include/boost/scope/detail/type_traits/negation.hpp
Normal file
53
include/boost/scope/detail/type_traits/negation.hpp
Normal file
@@ -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_
|
||||
103
include/boost/scope/error_code_checker.hpp
Normal file
103
include/boost/scope/error_code_checker.hpp
Normal file
@@ -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_
|
||||
106
include/boost/scope/exception_checker.hpp
Normal file
106
include/boost/scope/exception_checker.hpp
Normal file
@@ -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_
|
||||
82
include/boost/scope/fd_deleter.hpp
Normal file
82
include/boost/scope/fd_deleter.hpp
Normal file
@@ -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_
|
||||
49
include/boost/scope/fd_resource_traits.hpp
Normal file
49
include/boost/scope/fd_resource_traits.hpp
Normal file
@@ -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_
|
||||
560
include/boost/scope/scope_exit.hpp
Normal file
560
include/boost/scope/scope_exit.hpp
Normal file
@@ -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_
|
||||
265
include/boost/scope/scope_fail.hpp
Normal file
265
include/boost/scope/scope_fail.hpp
Normal file
@@ -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_
|
||||
309
include/boost/scope/scope_success.hpp
Normal file
309
include/boost/scope/scope_success.hpp
Normal file
@@ -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_
|
||||
38
include/boost/scope/unique_fd.hpp
Normal file
38
include/boost/scope/unique_fd.hpp
Normal file
@@ -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_
|
||||
1653
include/boost/scope/unique_resource.hpp
Normal file
1653
include/boost/scope/unique_resource.hpp
Normal file
File diff suppressed because it is too large
Load Diff
46
include/boost/scope/unique_resource_fwd.hpp
Normal file
46
include/boost/scope/unique_resource_fwd.hpp
Normal file
@@ -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_
|
||||
Reference in New Issue
Block a user