2
0
mirror of https://github.com/boostorg/leaf.git synced 2026-01-19 16:32:08 +00:00

Deploying to gh-pages from @ 394d6d7762 🚀

This commit is contained in:
zajo
2022-01-06 03:12:43 +00:00
parent cb3f408760
commit 526f8564bf
3 changed files with 4723 additions and 2690 deletions

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.16">
<meta name="generator" content="Asciidoctor 2.0.17">
<meta name="author" content="Lightweight Error Augmentation Framework written in C&#43;&#43;11 | Emil Dotchevski">
<title>LEAF</title>
<link rel="stylesheet" href="./zajo-dark.css">
@@ -218,7 +218,11 @@ function switch_style()
<li><a href="#_boost_build">Boost Build</a></li>
</ul>
</li>
<li><a href="#configuration">Configuration Macros</a></li>
<li><a href="#configuration">Configuration</a>
<ul class="sectlevel2">
<li><a href="#_embedded_platforms">Embedded Platforms</a></li>
</ul>
</li>
<li><a href="#_limitations">Limitations</a></li>
<li><a href="#_acknowledgements">Acknowledgements</a></li>
</ul>
@@ -309,7 +313,7 @@ function switch_style()
<p>LEAF requires only C&#43;&#43;11, but is tested on many compiler versions and C++ standards.</p>
</div>
<div class="paragraph">
<p>The library uses thread-local storage, except when multi-threading is disabled (e.g. on some embedded platforms). See <a href="#configuration">Configuration Macros</a>.</p>
<p>The library uses thread-local storage for pointers only. By default, this is implemented via the C&#43;&#43;11 <code>thread_local</code> storage class specifier, however it is easy to use a platform-specific TLS API instead; for example LEAF ships with built-in support for FreeRTOS. See <a href="#configuration">Configuration</a>.</p>
</div>
</div>
</div>
@@ -8542,7 +8546,7 @@ meson <span class="nb">test</span></code></pre>
</div>
</div>
<div class="sect1">
<h2 id="configuration">Configuration Macros</h2>
<h2 id="configuration">Configuration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The following configuration macros are recognized:</p>
@@ -8550,31 +8554,95 @@ meson <span class="nb">test</span></code></pre>
<div class="ulist">
<ul>
<li>
<p><code>BOOST_LEAF_DIAGNOSTICS</code>: Defining this macro to <code>0</code> stubs out both <a href="#diagnostic_info"><code>diagnostic_info</code></a> and <a href="#verbose_diagnostic_info"><code>verbose_diagnostic_info</code></a>, which could improve the performance of the error path in some programs (if the macro is left undefined, LEAF defines it as <code>1</code>).</p>
<p><code>BOOST_LEAF_DIAGNOSTICS</code>: Defining this macro as <code>0</code> stubs out both <a href="#diagnostic_info"><code>diagnostic_info</code></a> and <a href="#verbose_diagnostic_info"><code>verbose_diagnostic_info</code></a> (if the macro is left undefined, LEAF defines it as <code>1</code>).</p>
</li>
<li>
<p><code>BOOST_LEAF_NO_EXCEPTIONS</code>: Disables all exception handling support. If left undefined, LEAF defines it based on the compiler configuration (e.g. <code>-fno-exceptions</code>).</p>
<p><code>BOOST_LEAF_USE_STD_SYSTEM_ERROR</code>: Defining this macro as <code>0</code> disables the <code>std::error_code</code> / <code>std::error_condition</code> integration. In this case LEAF does not <code>#include &lt;system_error&gt;</code>, which may be too heavy for embedded platforms (if the macro is left undefined, LEAF defines it as <code>1</code>).</p>
</li>
<li>
<p><code>BOOST_LEAF_NO_THREADS</code>: Disables all multi-thread support.</p>
<p><code>BOOST_LEAF_USE_STD_STRING</code>: Defining this macro as <code>0</code> disables all use of <code>std::string</code> (this requires <code>BOOST_LEAF_DIAGNOSTICS=0</code> as well). In this case LEAF does not <code>#include &lt;string&gt;</code> which may be too heavy for embedded platforms (if the macro is left undefined, LEAF defines it as <code>1</code>).</p>
</li>
<li>
<p><code>BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR</code>: Disables the <code>std::error_code</code> / <code>std::error_condition</code> integration. In this case LEAF does not <code>#include &lt;system_error&gt;</code>, which is considered too heavy for embedded platforms.</p>
<p><code>BOOST_LEAF_NO_EXCEPTIONS</code>: Disables all exception handling support. If left undefined, LEAF defines it automatically based on the compiler configuration (e.g. <code>-fno-exceptions</code>).</p>
</li>
<li>
<p><code>BOOST_LEAF_DISABLE_STD_STRING</code>: Disables all use of <code>std::string</code> (available only under <code>BOOST_LEAF_DIAGNOSTICS=0</code>). In this case LEAF does not <code>#include &lt;string&gt;</code> which is considered too heavy for embedded platforms.</p>
<p><code>BOOST_LEAF_NO_THREADS</code>: Disables all thread safety in LEAF.</p>
</li>
</ul>
</div>
<div class="sect2">
<h3 id="_embedded_platforms">Embedded Platforms</h3>
<div class="paragraph">
<p>Defining <code>BOOST_LEAF_EMBEDDED</code> is equivalent to the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="c++"><span class="cp">#ifndef BOOST_LEAF_NO_EXCEPTIONS
# define BOOST_LEAF_NO_EXCEPTIONS
#endif
</span>
<span class="cp">#ifndef BOOST_LEAF_DIAGNOSTICS
# define BOOST_LEAF_DIAGNOSTICS 0
#endif
</span>
<span class="cp">#ifndef BOOST_LEAF_USE_STD_SYSTEM_ERROR
# define BOOST_LEAF_USE_STD_SYSTEM_ERROR 0
#endif
</span>
<span class="cp">#ifndef BOOST_LEAF_USE_STD_STRING
# define BOOST_LEAF_USE_STD_STRING 0
#endif</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>LEAF supports FreeRTOS out of the box, please define <code>BOOST_LEAF_TLS_FREERTOS</code> (in which case LEAF automatically defines <code>BOOST_LEAF_EMBEDDED</code> if it is not defined already).</p>
</div>
<div class="paragraph">
<p>For other embedded platforms, please define <code>BOOST_LEAF_TLS_ARRAY</code> and make sure your project defines the following two functions to implement TLS pointer access:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span> <span class="k">namespace</span> <span class="n">leaf</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">tls</span>
<span class="p">{</span>
<span class="kt">void</span> <span class="o">*</span> <span class="n">read_void_ptr</span><span class="p">(</span> <span class="kt">int</span> <span class="n">tls_index</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="kt">void</span> <span class="n">write_void_ptr</span><span class="p">(</span> <span class="kt">int</span> <span class="n">tls_index</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span> <span class="n">p</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span> <span class="p">}</span></code></pre>
</div>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
For efficiency, <code>read_void_ptr</code> and <code>write_void_ptr</code> should be defined <code>inline</code>.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Under <code>BOOST_LEAF_TLS_ARRAY</code> (which includes <code>BOOST_LEAF_TLS_FREERTOS</code>):</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Each error type is assigned a unique index in the TLS pointer array. By default, assigned TLS indices start from <code>0</code>; this can be changed by defining <code>BOOST_LEAF_TLS_ARRAY_START_INDEX</code>.</p>
</li>
<li>
<p>If <code>BOOST_LEAF_TLS_ARRAY_SIZE</code> is defined, LEAF will use it to <code>BOOST_LEAF_ASSERT</code> that TLS indices are within bounds (which is of course deactivated under <code>NDEBUG</code>).</p>
</li>
<li>
<p>Under <code>BOOST_LEAF_TLS_FREERTOS</code>, <code>BOOST_LEAF_TLS_ARRAY_SIZE</code> defaults to <a href="https://www.freertos.org/a00110.html#configNUM_THREAD_LOCAL_STORAGE_POINTERS"><code>configNUM_THREAD_LOCAL_STORAGE_POINTERS</code></a>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In addition, defining <code>BOOST_LEAF_EMBEDDED</code> is equivalent to the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="c++"><span class="cp">#define BOOST_LEAF_NO_EXCEPTIONS
#define BOOST_LEAF_DIAGNOSTICS 0
#define BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
#define BOOST_LEAF_DISABLE_STD_STRING</span></code></pre>
<p>If your program does not use concurrency at all, simply define <code>BOOST_LEAF_NO_THREADS</code>, which requires no TLS support at all (but is NOT thread-safe).</p>
</div>
</div>
</div>
@@ -8583,9 +8651,6 @@ meson <span class="nb">test</span></code></pre>
<h2 id="_limitations">Limitations</h2>
<div class="sectionbody">
<div class="paragraph">
<p>LEAF requires C&#43;&#43;11, including <code>thread_local</code> support, except when compiled with <code>BOOST_LEAF_NO_THREADS</code> (which can be useful on some embedded platforms).</p>
</div>
<div class="paragraph">
<p>When using dynamic linking, it is required that error types are declared with <code>default</code> visibility, e.g.:</p>
</div>
<div class="listingblock">

627
leaf.hpp
View File

@@ -3,8 +3,8 @@
// LEAF single header distribution. Do not edit.
// Generated from https://github.com/boostorg/leaf on January 03, 2022,
// Git hash 97560735977aac88111bfefae95119cd6fc6ad58.
// Generated from https://github.com/boostorg/leaf on January 06, 2022,
// Git hash 8563ed0874acfa965e3dad203d92fb7708eb762b.
// Latest version: https://boostorg.github.io/leaf/leaf.hpp
@@ -43,8 +43,8 @@
#ifndef BOOST_LEAF_DETAIL_OPTIONAL_HPP_INCLUDED
#define BOOST_LEAF_DETAIL_OPTIONAL_HPP_INCLUDED
// >>> #include <boost/leaf/detail/config.hpp>
#line 1 "boost/leaf/detail/config.hpp"
// >>> #include <boost/leaf/config.hpp>
#line 1 "boost/leaf/config.hpp"
#ifndef BOOST_LEAF_CONFIG_HPP_INCLUDED
#define BOOST_LEAF_CONFIG_HPP_INCLUDED
@@ -54,14 +54,59 @@
// (C) Copyright Martin Wille 2003.
// (C) Copyright Guillaume Melquiond 2003.
#ifdef BOOST_LEAF_EMBEDDED
# define BOOST_LEAF_NO_EXCEPTIONS
# define BOOST_LEAF_DIAGNOSTICS 0
# define BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
# define BOOST_LEAF_DISABLE_STD_STRING
#ifdef BOOST_LEAF_TLS_FREERTOS
# ifndef BOOST_LEAF_EMBEDDED
# define BOOST_LEAF_EMBEDDED
# endif
#endif
#if BOOST_LEAF_DIAGNOSTICS && defined(BOOST_LEAF_DISABLE_STD_STRING)
#ifdef BOOST_LEAF_EMBEDDED
# ifndef BOOST_LEAF_NO_EXCEPTIONS
# define BOOST_LEAF_NO_EXCEPTIONS
# endif
# ifndef BOOST_LEAF_DIAGNOSTICS
# define BOOST_LEAF_DIAGNOSTICS 0
# endif
# ifndef BOOST_LEAF_USE_STD_SYSTEM_ERROR
# define BOOST_LEAF_USE_STD_SYSTEM_ERROR 0
# endif
# ifndef BOOST_LEAF_USE_STD_STRING
# define BOOST_LEAF_USE_STD_STRING 0
# endif
#endif
#ifndef BOOST_LEAF_DIAGNOSTICS
# define BOOST_LEAF_DIAGNOSTICS 1
#endif
#ifndef BOOST_LEAF_USE_STD_SYSTEM_ERROR
# define BOOST_LEAF_USE_STD_SYSTEM_ERROR 1
#endif
#ifndef BOOST_LEAF_USE_STD_STRING
# define BOOST_LEAF_USE_STD_STRING 1
#endif
#if BOOST_LEAF_DIAGNOSTICS!=0 && BOOST_LEAF_DIAGNOSTICS!=1
# error BOOST_LEAF_DIAGNOSTICS must be 0 or 1.
#endif
#if BOOST_LEAF_USE_STD_SYSTEM_ERROR!=0 && BOOST_LEAF_USE_STD_SYSTEM_ERROR!=1
# error BOOST_LEAF_USE_STD_SYSTEM_ERROR must be 0 or 1.
#endif
#if BOOST_LEAF_USE_STD_STRING!=0 && BOOST_LEAF_USE_STD_STRING!=1
# error BOOST_LEAF_USE_STD_STRING must be 0 or 1.
#endif
#if BOOST_LEAF_DIAGNOSTICS && !BOOST_LEAF_USE_STD_STRING
# error BOOST_LEAF_DIAGNOSTICS requires the use of std::string
#endif
@@ -165,14 +210,6 @@
# define BOOST_LEAF_NORETURN
#endif
#ifndef BOOST_LEAF_DIAGNOSTICS
# define BOOST_LEAF_DIAGNOSTICS 1
#endif
#if BOOST_LEAF_DIAGNOSTICS!=0 && BOOST_LEAF_DIAGNOSTICS!=1
# error BOOST_LEAF_DIAGNOSTICS must be 0 or 1.
#endif
#ifdef _MSC_VER
# define BOOST_LEAF_ALWAYS_INLINE __forceinline
#else
@@ -219,12 +256,377 @@
# define BOOST_LEAF_SYMBOL_VISIBLE
#endif
#ifdef BOOST_LEAF_NO_THREADS
# define BOOST_LEAF_DISABLE_CAPTURE
// Configure TLS access
// >>> #include <boost/leaf/config/tls.hpp>
#line 1 "boost/leaf/config/tls.hpp"
#ifndef BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED
#define BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED
#if defined(BOOST_LEAF_TLS_FREERTOS)
// >>> # include <boost/leaf/config/tls_freertos.hpp>
#line 1 "boost/leaf/config/tls_freertos.hpp"
#ifndef BOOST_LEAF_CONFIG_TLS_FREERTOS_HPP_INCLUDED
#define BOOST_LEAF_CONFIG_TLS_FREERTOS_HPP_INCLUDED
// LEAF requires thread local storage support for pointers and for uin32_t values.
// This header implements thread local storage for pointers and for uint32_t
// values via the FreeRTOS API, as an alternative to the default implementation
// (found in tls_cpp11.hpp) which relies on C++11 thread_local support.
// See https://www.freertos.org/thread-local-storage-pointers.html.
#include <task.h>
#ifndef BOOST_LEAF_TLS_ARRAY
# define BOOST_LEAF_TLS_ARRAY
#endif
#ifndef BOOST_LEAF_TLS_INDEX_TYPE
# define BOOST_LEAF_TLS_INDEX_TYPE BaseType_t
#endif
#ifndef BOOST_LEAF_TLS_ARRAY_SIZE
# define BOOST_LEAF_TLS_ARRAY_SIZE configNUM_THREAD_LOCAL_STORAGE_POINTERS
#endif
static_assert(
BOOST_LEAF_TLS_ARRAY_SIZE <= configNUM_THREAD_LOCAL_STORAGE_POINTERS,
"Bad BOOST_LEAF_TLS_ARRAY_SIZE");
namespace boost { namespace leaf {
namespace tls
{
inline void * read_void_ptr( int tls_index ) noexcept
{
return pvTaskGetThreadLocalStoragePointer(0, tls_index);
}
inline void write_void_ptr( int tls_index, void * p ) noexcept
{
vTaskSetThreadLocalStoragePointer(0, tls_index, p);
}
}
} }
#endif
// <<< # include <boost/leaf/config/tls_freertos.hpp>
#line 11 "boost/leaf/config/tls.hpp"
#endif
#if defined BOOST_LEAF_TLS_ARRAY
// >>> # include <boost/leaf/config/tls_array.hpp>
#line 1 "boost/leaf/config/tls_array.hpp"
#ifndef BOOST_LEAF_CONFIG_TLS_ARRAY_HPP_INCLUDED
#define BOOST_LEAF_CONFIG_TLS_ARRAY_HPP_INCLUDED
// LEAF requires thread local storage support for pointers and for uin32_t values.
// This header implements thread local storage for pointers and for uint32_t
// values for platforms that support thread local pointers by index.
#ifndef BOOST_LEAF_TLS_INDEX_TYPE
# define BOOST_LEAF_TLS_INDEX_TYPE int
#endif
#ifndef BOOST_LEAF_TLS_ARRAY_START_INDEX
# define BOOST_LEAF_TLS_ARRAY_START_INDEX 0
#endif
static_assert(BOOST_LEAF_TLS_ARRAY_START_INDEX >= 0,
"Bad BOOST_LEAF_TLS_ARRAY_START_INDEX");
#ifdef BOOST_LEAF_TLS_ARRAY_SIZE
static_assert(BOOST_LEAF_TLS_ARRAY_SIZE > 0,
"Bad BOOST_LEAF_TLS_ARRAY_SIZE");
static_assert(BOOST_LEAF_TLS_ARRAY_START_INDEX < BOOST_LEAF_TLS_ARRAY_SIZE,
"Bad BOOST_LEAF_TLS_ARRAY_START_INDEX");
#endif
#include <atomic>
#include <cstdint>
namespace boost { namespace leaf {
namespace tls
{
// The TLS support defined in this header requires the following two
// functions to be defined elsewhere:
void * read_void_ptr( int tls_index ) noexcept;
void write_void_ptr( int tls_index, void * ) noexcept;
}
} }
namespace boost { namespace leaf {
namespace leaf_detail
{
using atomic_unsigned_int = std::atomic<unsigned int>;
}
namespace tls
{
template <class=void>
class BOOST_LEAF_SYMBOL_VISIBLE index_counter
{
static BOOST_LEAF_TLS_INDEX_TYPE c;
public:
template <class T>
static BOOST_LEAF_TLS_INDEX_TYPE get_index() noexcept
{
BOOST_LEAF_TLS_INDEX_TYPE idx = c++;
#ifdef BOOST_LEAF_TLS_ARRAY_SIZE
BOOST_LEAF_ASSERT(idx < BOOST_LEAF_TLS_ARRAY_SIZE);
#endif
// Set breakpoint here to inspect TLS index assignment.
return idx;
}
};
template <class T>
BOOST_LEAF_TLS_INDEX_TYPE index_counter<T>::c = BOOST_LEAF_TLS_ARRAY_START_INDEX;
template <class T>
struct BOOST_LEAF_SYMBOL_VISIBLE index
{
static BOOST_LEAF_TLS_INDEX_TYPE const idx;
};
template <class T>
BOOST_LEAF_TLS_INDEX_TYPE const index<T>::idx = index_counter<>::get_index<T>();
template <class T>
T * read_ptr() noexcept
{
int const tls_index = index<T>::idx;
BOOST_LEAF_ASSERT(tls_index >= BOOST_LEAF_TLS_ARRAY_START_INDEX);
#ifdef BOOST_LEAF_TLS_ARRAY_SIZE
BOOST_LEAF_ASSERT(tls_index < BOOST_LEAF_TLS_ARRAY_SIZE);
#endif
return reinterpret_cast<T *>(read_void_ptr(tls_index));
}
template <class T>
void write_ptr( T * p ) noexcept
{
int const tls_index = index<T>::idx;
BOOST_LEAF_ASSERT(tls_index >= BOOST_LEAF_TLS_ARRAY_START_INDEX);
#ifdef BOOST_LEAF_TLS_ARRAY_SIZE
BOOST_LEAF_ASSERT(tls_index < BOOST_LEAF_TLS_ARRAY_SIZE);
#endif
write_void_ptr(tls_index, p);
BOOST_LEAF_ASSERT(read_void_ptr(tls_index) == p);
}
template <class Tag>
std::uint32_t read_uint32() noexcept
{
Tag * p = read_ptr<Tag>();
return (std::intptr_t)(void *)p;
}
template <class Tag>
void write_uint32( std::uint32_t x ) noexcept
{
write_ptr<Tag>((Tag *)x);
}
template <class Tag>
void uint32_increment() noexcept
{
write_uint32<Tag>(read_uint32<Tag>() + 1);
}
template <class Tag>
void uint32_decrement() noexcept
{
write_uint32<Tag>(read_uint32<Tag>() - 1);
}
}
} }
#endif
// <<< # include <boost/leaf/config/tls_array.hpp>
#line 15 "boost/leaf/config/tls.hpp"
#elif defined(BOOST_LEAF_NO_THREADS)
// >>> # include <boost/leaf/config/tls_globals.hpp>
#line 1 "boost/leaf/config/tls_globals.hpp"
#ifndef BOOST_LEAF_CONFIG_TLS_GLOBALS_HPP_INCLUDED
#define BOOST_LEAF_CONFIG_TLS_GLOBALS_HPP_INCLUDED
// LEAF requires thread local storage support for pointers and for uin32_t values.
// This header implements "thread local" storage for pointers and for uint32_t
// values using globals, which is suitable for single thread environments.
#include <cstdint>
namespace boost { namespace leaf {
namespace leaf_detail
{
using atomic_unsigned_int = unsigned int;
}
namespace tls
{
template <class T>
struct BOOST_LEAF_SYMBOL_VISIBLE ptr
{
static T * p;
};
template <class T>
T * ptr<T>::p;
template <class T>
T * read_ptr() noexcept
{
return ptr<T>::p;
}
template <class T>
void write_ptr( T * p ) noexcept
{
ptr<T>::p = p;
}
template <class Tag>
struct BOOST_LEAF_SYMBOL_VISIBLE tagged_uint32
{
static std::uint32_t x;
};
template <class Tag>
std::uint32_t tagged_uint32<Tag>::x;
template <class Tag>
std::uint32_t read_uint32() noexcept
{
return tagged_uint32<Tag>::x;
}
template <class Tag>
void write_uint32( std::uint32_t x ) noexcept
{
tagged_uint32<Tag>::x = x;
}
template <class Tag>
void uint32_increment() noexcept
{
++tagged_uint32<Tag>::x;
}
template <class Tag>
void uint32_decrement() noexcept
{
--tagged_uint32<Tag>::x;
}
}
} }
#endif
// <<< # include <boost/leaf/config/tls_globals.hpp>
#line 17 "boost/leaf/config/tls.hpp"
#else
// >>> # include <boost/leaf/config/tls_cpp11.hpp>
#line 1 "boost/leaf/config/tls_cpp11.hpp"
#ifndef BOOST_LEAF_CONFIG_TLS_CPP11_HPP_INCLUDED
#define BOOST_LEAF_CONFIG_TLS_CPP11_HPP_INCLUDED
// LEAF requires thread local storage support for pointers and for uin32_t values.
// This header implements thread local storage for pointers and for uint32_t
// values using the C++11 built-in thread_local storage class specifier.
#include <cstdint>
#include <atomic>
namespace boost { namespace leaf {
namespace leaf_detail
{
using atomic_unsigned_int = std::atomic<unsigned int>;
}
namespace tls
{
template <class T>
struct BOOST_LEAF_SYMBOL_VISIBLE ptr
{
static thread_local T * p;
};
template <class T>
thread_local T * ptr<T>::p;
template <class T>
T * read_ptr() noexcept
{
return ptr<T>::p;
}
template <class T>
void write_ptr( T * p ) noexcept
{
ptr<T>::p = p;
}
template <class Tag>
struct BOOST_LEAF_SYMBOL_VISIBLE tagged_uint32
{
static thread_local std::uint32_t x;
};
template <class Tag>
thread_local std::uint32_t tagged_uint32<Tag>::x;
template <class Tag>
std::uint32_t read_uint32() noexcept
{
return tagged_uint32<Tag>::x;
}
template <class Tag>
void write_uint32( std::uint32_t x ) noexcept
{
tagged_uint32<Tag>::x = x;
}
template <class Tag>
void uint32_increment() noexcept
{
++tagged_uint32<Tag>::x;
}
template <class Tag>
void uint32_decrement() noexcept
{
--tagged_uint32<Tag>::x;
}
}
} }
#endif
// <<< # include <boost/leaf/config/tls_cpp11.hpp>
#line 19 "boost/leaf/config/tls.hpp"
#endif
#endif
// <<< #include <boost/leaf/detail/config.hpp>
// <<< #include <boost/leaf/config/tls.hpp>
#line 251 "boost/leaf/config.hpp"
#endif
// <<< #include <boost/leaf/config.hpp>
#line 20 "boost/leaf/detail/optional.hpp"
#include <utility>
#include <new>
@@ -445,21 +847,6 @@ char const * t =
} }
#ifdef BOOST_LEAF_DISABLE_STD_STRING
namespace boost { namespace leaf {
inline char const * demangle( char const * name )
{
return name;
}
} }
#else
#include <string>
#if defined(__has_include) && ((__GNUC__ + 0) >= 5)
# if __has_include(<cxxabi.h>)
# define BOOST_LEAF_HAS_CXXABI_H
@@ -480,6 +867,10 @@ namespace boost { namespace leaf {
# endif
#endif
#if BOOST_LEAF_USE_STD_STRING
#include <string>
namespace boost { namespace leaf {
namespace leaf_detail
@@ -514,7 +905,7 @@ namespace leaf_detail
scoped_demangled_name& operator= ( scoped_demangled_name const& ) = delete;
};
#if defined(BOOST_LEAF_HAS_CXXABI_H) and !defined(BOOST_LEAF_DISABLE_STD_STRING)
#ifdef BOOST_LEAF_HAS_CXXABI_H
inline char const * demangle_alloc( char const * name ) noexcept
{
@@ -558,10 +949,24 @@ namespace leaf_detail
} }
#ifdef BOOST_LEAF_HAS_CXXABI_H
# undef BOOST_LEAF_HAS_CXXABI_H
#else
namespace boost { namespace leaf {
namespace leaf_detail
{
inline char const * demangle( char const * name )
{
return name;
}
}
} }
#endif
#ifdef BOOST_LEAF_HAS_CXXABI_H
# undef BOOST_LEAF_HAS_CXXABI_H
#endif
#endif
@@ -1100,7 +1505,7 @@ namespace leaf_detail
# include <set>
#endif
#ifndef BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
#if BOOST_LEAF_USE_STD_SYSTEM_ERROR
# include <system_error>
#endif
@@ -1134,6 +1539,9 @@ class error_id;
namespace leaf_detail
{
struct BOOST_LEAF_SYMBOL_VISIBLE tls_tag_unexpected_enabled_counter;
struct BOOST_LEAF_SYMBOL_VISIBLE tls_tag_id_factory_current_id;
struct inject_loc
{
char const * const file;
@@ -1182,30 +1590,6 @@ BOOST_LEAF_NORETURN void throw_exception( T const & e )
#endif
#ifdef BOOST_LEAF_NO_THREADS
# define BOOST_LEAF_THREAD_LOCAL
namespace boost { namespace leaf {
namespace leaf_detail
{
using atomic_unsigned_int = unsigned int;
}
} }
#else
# include <atomic>
# include <thread>
# define BOOST_LEAF_THREAD_LOCAL BOOST_LEAF_SYMBOL_VISIBLE thread_local
namespace boost { namespace leaf {
namespace leaf_detail
{
using atomic_unsigned_int = std::atomic<unsigned int>;
}
} }
#endif
namespace boost { namespace leaf {
#if BOOST_LEAF_DIAGNOSTICS
@@ -1287,14 +1671,6 @@ namespace leaf_detail
BOOST_LEAF_CONSTEXPR static void print( std::basic_ostream<CharT, Traits> &, e_unexpected_info const &) noexcept { }
};
template <class=void>
struct BOOST_LEAF_SYMBOL_VISIBLE tl_unexpected_enabled
{
static BOOST_LEAF_THREAD_LOCAL int counter;
};
template <class T>
BOOST_LEAF_THREAD_LOCAL int tl_unexpected_enabled<T>::counter;
}
#endif
@@ -1319,54 +1695,38 @@ struct BOOST_LEAF_SYMBOL_VISIBLE e_source_location
namespace leaf_detail
{
template <class E>
class slot;
template <class E>
struct BOOST_LEAF_SYMBOL_VISIBLE tl_slot_ptr
{
static BOOST_LEAF_THREAD_LOCAL slot<E> * p;
};
template <class E>
BOOST_LEAF_THREAD_LOCAL slot<E> * tl_slot_ptr<E>::p;
template <class E>
class slot:
class BOOST_LEAF_SYMBOL_VISIBLE slot:
optional<E>
{
slot( slot const & ) = delete;
slot & operator=( slot const & ) = delete;
using impl = optional<E>;
slot<E> * * top_;
slot<E> * prev_;
public:
BOOST_LEAF_CONSTEXPR slot() noexcept:
top_(0)
prev_(0)
{
}
BOOST_LEAF_CONSTEXPR slot( slot && x ) noexcept:
optional<E>(std::move(x)),
top_(0)
prev_(0)
{
BOOST_LEAF_ASSERT(x.top_==0);
BOOST_LEAF_ASSERT(x.prev_==0);
}
BOOST_LEAF_CONSTEXPR void activate() noexcept
{
BOOST_LEAF_ASSERT(top_==0 || *top_!=this);
top_ = &tl_slot_ptr<E>::p;
prev_ = *top_;
*top_ = this;
prev_ = tls::read_ptr<slot<E>>();
tls::write_ptr<slot<E>>(this);
}
BOOST_LEAF_CONSTEXPR void deactivate() noexcept
{
BOOST_LEAF_ASSERT(top_!=0 && *top_==this);
*top_ = prev_;
tls::write_ptr<slot<E>>(prev_);
}
BOOST_LEAF_CONSTEXPR void propagate() noexcept;
@@ -1401,7 +1761,7 @@ namespace leaf_detail
template <class E>
BOOST_LEAF_CONSTEXPR inline void load_unexpected_count( int err_id ) noexcept
{
if( slot<e_unexpected_count> * sl = tl_slot_ptr<e_unexpected_count>::p )
if( slot<e_unexpected_count> * sl = tls::read_ptr<slot<e_unexpected_count>>() )
if( e_unexpected_count * unx = sl->has_value(err_id) )
++unx->count;
else
@@ -1411,7 +1771,7 @@ namespace leaf_detail
template <class E>
BOOST_LEAF_CONSTEXPR inline void load_unexpected_info( int err_id, E && e ) noexcept
{
if( slot<e_unexpected_info> * sl = tl_slot_ptr<e_unexpected_info>::p )
if( slot<e_unexpected_info> * sl = tls::read_ptr<slot<e_unexpected_info>>() )
if( e_unexpected_info * unx = sl->has_value(err_id) )
unx->add(std::forward<E>(e));
else
@@ -1430,7 +1790,6 @@ namespace leaf_detail
template <class E>
BOOST_LEAF_CONSTEXPR inline void slot<E>::propagate() noexcept
{
BOOST_LEAF_ASSERT(top_!=0 && (*top_==prev_ || *top_==this));
if( prev_ )
{
impl & that_ = *prev_;
@@ -1443,7 +1802,7 @@ namespace leaf_detail
#if BOOST_LEAF_DIAGNOSTICS
else
{
int c = tl_unexpected_enabled<>::counter;
int c = tls::read_uint32<tls_tag_unexpected_enabled_counter>();
BOOST_LEAF_ASSERT(c>=0);
if( c )
if( int err_id = impl::key() )
@@ -1459,12 +1818,12 @@ namespace leaf_detail
static_assert(!std::is_same<typename std::decay<E>::type, error_id>::value, "Error objects of type error_id are not allowed");
using T = typename std::decay<E>::type;
BOOST_LEAF_ASSERT((err_id&3)==1);
if( slot<T> * p = tl_slot_ptr<T>::p )
if( slot<T> * p = tls::read_ptr<slot<T>>() )
(void) p->put(err_id, std::forward<E>(e));
#if BOOST_LEAF_DIAGNOSTICS
else
{
int c = tl_unexpected_enabled<>::counter;
int c = tls::read_uint32<tls_tag_unexpected_enabled_counter>();
BOOST_LEAF_ASSERT(c>=0);
if( c )
load_unexpected(err_id, std::forward<E>(e));
@@ -1480,7 +1839,7 @@ namespace leaf_detail
using E = typename std::decay<fn_arg_type<F,0>>::type;
static_assert(!std::is_pointer<E>::value, "Error objects of pointer types are not allowed");
BOOST_LEAF_ASSERT((err_id&3)==1);
if( auto sl = tl_slot_ptr<E>::p )
if( auto sl = tls::read_ptr<slot<E>>() )
if( auto v = sl->has_value(err_id) )
(void) std::forward<F>(f)(*v);
else
@@ -1495,7 +1854,6 @@ namespace leaf_detail
struct BOOST_LEAF_SYMBOL_VISIBLE id_factory
{
static atomic_unsigned_int counter;
static BOOST_LEAF_THREAD_LOCAL unsigned current_id;
BOOST_LEAF_CONSTEXPR static unsigned generate_next_id() noexcept
{
@@ -1508,12 +1866,9 @@ namespace leaf_detail
template <class T>
atomic_unsigned_int id_factory<T>::counter(-3);
template <class T>
BOOST_LEAF_THREAD_LOCAL unsigned id_factory<T>::current_id(0);
inline int current_id() noexcept
{
auto id = id_factory<>::current_id;
auto id = tls::read_uint32<tls_tag_id_factory_current_id>();
BOOST_LEAF_ASSERT(id==0 || (id&3)==1);
return id;
}
@@ -1521,7 +1876,8 @@ namespace leaf_detail
inline int new_id() noexcept
{
auto id = id_factory<>::generate_next_id();
return id_factory<>::current_id = id;
tls::write_uint32<tls_tag_id_factory_current_id>(id);
return id;
}
}
@@ -1561,7 +1917,7 @@ namespace leaf_detail
};
}
#ifndef BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
#if BOOST_LEAF_USE_STD_SYSTEM_ERROR
namespace leaf_detail
{
class leaf_category final: public std::error_category
@@ -1637,7 +1993,7 @@ public:
{
}
#ifndef BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
#if BOOST_LEAF_USE_STD_SYSTEM_ERROR
error_id( std::error_code const & ec ) noexcept:
value_(leaf_detail::import_error_code(ec))
{
@@ -1831,8 +2187,6 @@ struct is_result_type<R const>: is_result_type<R>
} }
#undef BOOST_LEAF_THREAD_LOCAL
#endif
// <<< #include <boost/leaf/error.hpp>
#line 20 "boost/leaf/exception.hpp"
@@ -2137,7 +2491,7 @@ namespace leaf_detail
public:
BOOST_LEAF_CONSTEXPR preloaded_item( E && e ):
s_(tl_slot_ptr<decay_E>::p),
s_(tls::read_ptr<slot<decay_E>>()),
e_(std::forward<E>(e))
{
}
@@ -2153,7 +2507,7 @@ namespace leaf_detail
#if BOOST_LEAF_DIAGNOSTICS
else
{
int c = tl_unexpected_enabled<>::counter;
int c = tls::read_uint32<tls_tag_unexpected_enabled_counter>();
BOOST_LEAF_ASSERT(c>=0);
if( c )
load_unexpected(err_id, std::move(e_));
@@ -2172,7 +2526,7 @@ namespace leaf_detail
public:
BOOST_LEAF_CONSTEXPR deferred_item( F && f ) noexcept:
s_(tl_slot_ptr<E>::p),
s_(tls::read_ptr<slot<E>>()),
f_(std::forward<F>(f))
{
}
@@ -2188,7 +2542,7 @@ namespace leaf_detail
#if BOOST_LEAF_DIAGNOSTICS
else
{
int c = tl_unexpected_enabled<>::counter;
int c = tls::read_uint32<tls_tag_unexpected_enabled_counter>();
BOOST_LEAF_ASSERT(c>=0);
if( c )
load_unexpected(err_id, std::forward<E>(f_()));
@@ -2210,7 +2564,7 @@ namespace leaf_detail
public:
BOOST_LEAF_CONSTEXPR accumulating_item( F && f ) noexcept:
s_(tl_slot_ptr<E>::p),
s_(tls::read_ptr<slot<E>>()),
f_(std::forward<F>(f))
{
}
@@ -2387,7 +2741,7 @@ namespace leaf_detail
{
BOOST_LEAF_ASSERT(ctx_->captured_id_);
auto active_context = activate_context(*ctx_);
id_factory<>::current_id = ctx_->captured_id_.value();
tls::write_uint32<tls_tag_id_factory_current_id>(ctx_->captured_id_.value());
std::rethrow_exception(ex_);
}
@@ -2521,7 +2875,7 @@ future_get( Future & fut )
#define BOOST_LEAF_COMMON_HPP_INCLUDED
#include <iosfwd>
#ifndef BOOST_LEAF_DISABLE_STD_STRING
#if BOOST_LEAF_USE_STD_STRING
# include <string>
#endif
#include <cerrno>
@@ -2540,19 +2894,19 @@ namespace boost { namespace leaf {
struct BOOST_LEAF_SYMBOL_VISIBLE e_api_function { char const * value; };
#ifdef BOOST_LEAF_DISABLE_STD_STRING
#if BOOST_LEAF_USE_STD_STRING
struct BOOST_LEAF_SYMBOL_VISIBLE e_file_name
{
constexpr static char const * const value = "<unavailable>";
BOOST_LEAF_CONSTEXPR explicit e_file_name( char const * ) { }
std::string value;
};
#else
struct BOOST_LEAF_SYMBOL_VISIBLE e_file_name
{
std::string value;
constexpr static char const * const value = "<unavailable>";
BOOST_LEAF_CONSTEXPR explicit e_file_name( char const * ) { }
};
#endif
@@ -2628,6 +2982,9 @@ namespace windows
#ifndef BOOST_LEAF_CONTEXT_HPP_INCLUDED
#define BOOST_LEAF_CONTEXT_HPP_INCLUDED
#if !defined(BOOST_LEAF_NO_THREADS) && !defined(NDEBUG)
# include <thread>
#endif
namespace boost { namespace leaf {
@@ -2936,7 +3293,7 @@ public:
tuple_for_each<std::tuple_size<Tup>::value,Tup>::activate(tup_);
#if BOOST_LEAF_DIAGNOSTICS
if( unexpected_requested<Tup>::value )
++tl_unexpected_enabled<>::counter;
tls::uint32_increment<tls_tag_unexpected_enabled_counter>();
#endif
#if !defined(BOOST_LEAF_NO_THREADS) && !defined(NDEBUG)
thread_id_ = std::this_thread::get_id();
@@ -2955,7 +3312,7 @@ public:
#endif
#if BOOST_LEAF_DIAGNOSTICS
if( unexpected_requested<Tup>::value )
--tl_unexpected_enabled<>::counter;
tls::uint32_decrement<tls_tag_unexpected_enabled_counter>();
#endif
tuple_for_each<std::tuple_size<Tup>::value,Tup>::deactivate(tup_);
}
@@ -3083,7 +3440,7 @@ class BOOST_LEAF_SYMBOL_VISIBLE error_info
#ifndef BOOST_LEAF_NO_EXCEPTIONS
static error_id unpack_error_id( std::exception const * ex ) noexcept
{
#ifndef BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
#if BOOST_LEAF_USE_STD_SYSTEM_ERROR
if( std::system_error const * se = dynamic_cast<std::system_error const *>(ex) )
if( is_error_id(se->code()) )
return leaf_detail::make_error_id(se->code().value());
@@ -3423,7 +3780,7 @@ namespace leaf_detail
}
};
#ifndef BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
#if BOOST_LEAF_USE_STD_SYSTEM_ERROR
template <>
struct peek_exception<std::error_code const, true>
{
@@ -4023,7 +4380,7 @@ namespace leaf_detail
}
}
#ifndef BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
#if BOOST_LEAF_USE_STD_SYSTEM_ERROR
template <class E, class Enum = E>
struct condition
{
@@ -4054,7 +4411,7 @@ namespace leaf_detail
using type = T;
};
#ifndef BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
#if BOOST_LEAF_USE_STD_SYSTEM_ERROR
template <class Enum>
struct match_enum_type<condition<Enum, Enum>>
{
@@ -4082,7 +4439,7 @@ struct match
}
};
#ifndef BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
#if BOOST_LEAF_USE_STD_SYSTEM_ERROR
template <class Enum, BOOST_LEAF_MATCH_ARGS(BOOST_LEAF_ESC(match_enum_type<condition<Enum, Enum>>), V1, V)>
struct match<condition<Enum, Enum>, V1, V...>
{
@@ -4109,7 +4466,7 @@ namespace leaf_detail
using type = typename std::remove_reference<decltype(std::declval<E>().value)>::type;
};
#ifndef BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
#if BOOST_LEAF_USE_STD_SYSTEM_ERROR
template <class E, class Enum>
struct match_value_enum_type<condition<E, Enum>>
{
@@ -4136,7 +4493,7 @@ struct match_value
}
};
#ifndef BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
#if BOOST_LEAF_USE_STD_SYSTEM_ERROR
template <class E, class Enum, BOOST_LEAF_MATCH_ARGS(BOOST_LEAF_ESC(match_value_enum_type<condition<E, Enum>>), V1, V)>
struct match_value<condition<E, Enum>, V1, V...>
{
@@ -4431,7 +4788,7 @@ class result
#else
{
error_id captured_id = r_.ctx_->propagate_captured_errors();
leaf_detail::id_factory<>::current_id = captured_id.value();
tls::write_uint32<leaf_detail::tls_tag_id_factory_current_id>(captured_id.value());
return captured_id;
}
#endif
@@ -4592,7 +4949,7 @@ public:
#endif
#ifndef BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
#if BOOST_LEAF_USE_STD_SYSTEM_ERROR
result( std::error_code const & ec ) noexcept:
what_(error_id(ec))
{
@@ -4758,7 +5115,7 @@ public:
{
}
#ifndef BOOST_LEAF_DISABLE_STD_SYSTEM_ERROR
#if BOOST_LEAF_USE_STD_SYSTEM_ERROR
result( std::error_code const & ec ) noexcept:
base(ec)
{

6681
leaf.pdf

File diff suppressed because it is too large Load Diff