early-access version 3088

This commit is contained in:
pineappleEA
2022-11-05 15:35:56 +01:00
parent 4e4fc25ce3
commit b601909c6d
35519 changed files with 5996896 additions and 860 deletions

View File

@@ -0,0 +1,4 @@
html
xml
temp
out.txt

View File

@@ -0,0 +1,81 @@
[/
/ Copyright (c) 2012 Marshall Clow
/ Copyright (c) 2021, Alan Freitas
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[/===============]
[#sec:BOOST_BINARY]
[section Binary Integer Literals]
[/===============]
[section Introduction]
The macro `BOOST_BINARY` is used for the representation of binary
literals. It takes as an argument a binary number arranged as an
arbitrary amount of 1s and 0s in groupings of length 1 to 8, with
groups separated by spaces. The macro serves as a replacement for
[@https://en.cppreference.com/w/cpp/language/integer_literal binary integer literals],
adopted in C++14.
The type of the literal yielded is determined by the same rules as
those of [@https://en.cppreference.com/w/cpp/language/integer_literal hex and octal literals].
By implementation, this macro expands directly to an octal literal during preprocessing, so
there is no overhead at runtime and the result is usable in any place that an octal literal
would be.
In order to directly support binary literals with suffixes,
additional macros of the form `BOOST_BINARY_XXX` are also
provided, where `XXX` is a standard integer suffix in all capital
letters.
In addition, LL and ULL suffixes may be used for representing
`long long` and `unsigned long long` types in compilers which provide
them as an extension.
The `BOOST_BINARY` family of macros resides in the header
[@../../../../boost/utility/binary.hpp <boost/utility/binary.hpp>].
[endsect]
[section Example]
```
void foo( int );
void foo( unsigned long );
void bar()
{
int value1 = BOOST_BINARY( 100 111000 01 1 110 );
unsigned long value2 = BOOST_BINARY_UL( 100 001 ); // unsigned long
long long value3 = BOOST_BINARY_LL( 11 000 ); // long long if supported
__assert__( BOOST_BINARY( 10010 )
& BOOST_BINARY( 11000 )
== BOOST_BINARY( 10000 )
);
foo( BOOST_BINARY( 1010 ) ); // calls the first foo
foo( BOOST_BINARY_LU( 1010 ) ); // calls the second foo
}
```
[endsect]
[/===============]
[xinclude tmp/boost_binary_reference.xml]
[/===============]
[section Acknowledgments]
Contributed by Matt Calabrese.
[endsect]
[endsect]

View File

@@ -0,0 +1,413 @@
# Copyright John Maddock 2005. Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import project ;
import doxygen ;
import quickbook ;
project boost/libs/utility/doc ;
path-constant INCLUDES : ../../.. ;
path-constant boost-images : ../../../doc/src/images ;
# Generate XML doxygen reference for base_from_member component in base_from_member_reference.xml
doxygen base_from_member_reference
:
$(INCLUDES)/boost/utility/base_from_member.hpp
:
<location>tmp
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>EXTRACT_ALL=NO
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED= \\
BOOST_UTILITY_DOCS \\
BOOST_SYMBOL_VISIBLE= \\
BOOST_FORCEINLINE=inline \\
BOOST_GPU_ENABLED= \\
BOOST_STATIC_ASSERT(x)= \\
BOOST_STATIC_ASSERT_MSG(x,y)= \\
BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\
BOOST_RV_REF(x)=\"x&&\" \\
BOOST_NESTED_TEMPLATE=template \\
BOOST_CONSTEXPR=constexpr \\
BOOST_CXX14_CONSTEXPR=constexpr \\
BOOST_OPERATORS_CONSTEXPR=constexpr \\
BOOST_CONSTEXPR_OR_CONST=constexpr \\
BOOST_NOEXCEPT=noexcept \\
BOOST_NOEXCEPT_IF(x)=noexcept(x) \\
BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\
BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\
BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\
BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\
BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\
BOOST_REF_CONST=const"
<doxygen:param>"EXCLUDE_SYMBOLS= \\
detail \\
F \\
result_of_has_result_type_impl \\
conditional \\
boost::operators_impl"
<xsl:param>"boost.doxygen.reftitle=Reference"
<xsl:param>"boost.doxygen.refid=base_from_member.reference"
;
# Generate XML doxygen reference for boost_binary component in boost_binary_reference.xml
doxygen boost_binary_reference
:
$(INCLUDES)/boost/utility/binary.hpp
:
<location>tmp
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>EXTRACT_ALL=NO
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED= \\
BOOST_UTILITY_DOCS \\
BOOST_SYMBOL_VISIBLE= \\
BOOST_FORCEINLINE=inline \\
BOOST_GPU_ENABLED= \\
BOOST_STATIC_ASSERT(x)= \\
BOOST_STATIC_ASSERT_MSG(x,y)= \\
BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\
BOOST_RV_REF(x)=\"x&&\" \\
BOOST_NESTED_TEMPLATE=template \\
BOOST_CONSTEXPR=constexpr \\
BOOST_CXX14_CONSTEXPR=constexpr \\
BOOST_OPERATORS_CONSTEXPR=constexpr \\
BOOST_CONSTEXPR_OR_CONST=constexpr \\
BOOST_NOEXCEPT=noexcept \\
BOOST_NOEXCEPT_IF(x)=noexcept(x) \\
BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\
BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\
BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\
BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\
BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\
BOOST_REF_CONST=const"
<doxygen:param>"EXCLUDE_SYMBOLS= \\
detail \\
F \\
result_of_has_result_type_impl \\
conditional \\
boost::operators_impl"
<xsl:param>"boost.doxygen.reftitle=Reference"
<xsl:param>"boost.doxygen.refid=boost_binary.reference"
;
# Generate XML doxygen reference for call_traits component in call_traits_reference.xml
doxygen call_traits_reference
:
$(INCLUDES)/boost/call_traits.hpp
$(INCLUDES)/boost/detail/call_traits.hpp
:
<location>tmp
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>EXTRACT_ALL=NO
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED= \\
BOOST_UTILITY_DOCS \\
BOOST_SYMBOL_VISIBLE= \\
BOOST_FORCEINLINE=inline \\
BOOST_GPU_ENABLED= \\
BOOST_STATIC_ASSERT(x)= \\
BOOST_STATIC_ASSERT_MSG(x,y)= \\
BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\
BOOST_RV_REF(x)=\"x&&\" \\
BOOST_NESTED_TEMPLATE=template \\
BOOST_CONSTEXPR=constexpr \\
BOOST_CXX14_CONSTEXPR=constexpr \\
BOOST_OPERATORS_CONSTEXPR=constexpr \\
BOOST_CONSTEXPR_OR_CONST=constexpr \\
BOOST_NOEXCEPT=noexcept \\
BOOST_NOEXCEPT_IF(x)=noexcept(x) \\
BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\
BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\
BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\
BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\
BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\
BOOST_REF_CONST=const"
<doxygen:param>"EXCLUDE_SYMBOLS= \\
detail \\
F \\
result_of_has_result_type_impl \\
conditional \\
boost::operators_impl"
<xsl:param>"boost.doxygen.reftitle=Reference"
<xsl:param>"boost.doxygen.refid=call_traits.reference"
;
# Generate XML doxygen reference for compressed_pair component in compressed_pair_reference.xml
doxygen compressed_pair_reference
:
$(INCLUDES)/boost/compressed_pair.hpp
$(INCLUDES)/boost/detail/compressed_pair.hpp
:
<location>tmp
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>EXTRACT_ALL=NO
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED= \\
BOOST_UTILITY_DOCS \\
BOOST_SYMBOL_VISIBLE= \\
BOOST_FORCEINLINE=inline \\
BOOST_GPU_ENABLED= \\
BOOST_STATIC_ASSERT(x)= \\
BOOST_STATIC_ASSERT_MSG(x,y)= \\
BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\
BOOST_RV_REF(x)=\"x&&\" \\
BOOST_NESTED_TEMPLATE=template \\
BOOST_CONSTEXPR=constexpr \\
BOOST_CXX14_CONSTEXPR=constexpr \\
BOOST_OPERATORS_CONSTEXPR=constexpr \\
BOOST_CONSTEXPR_OR_CONST=constexpr \\
BOOST_NOEXCEPT=noexcept \\
BOOST_NOEXCEPT_IF(x)=noexcept(x) \\
BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\
BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\
BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\
BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\
BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\
BOOST_REF_CONST=const"
<doxygen:param>"EXCLUDE_SYMBOLS= \\
detail \\
F \\
result_of_has_result_type_impl \\
conditional \\
boost::operators_impl"
<xsl:param>"boost.doxygen.reftitle=Reference"
<xsl:param>"boost.doxygen.refid=compressed_pair.reference"
;
# Generate XML doxygen reference for in_place_factory component in in_place_factory_reference.xml
doxygen in_place_factory_reference
:
$(INCLUDES)/boost/utility/in_place_factory.hpp
$(INCLUDES)/boost/utility/typed_in_place_factory.hpp
:
<location>tmp
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>EXTRACT_ALL=NO
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED= \\
BOOST_UTILITY_DOCS \\
BOOST_SYMBOL_VISIBLE= \\
BOOST_FORCEINLINE=inline \\
BOOST_GPU_ENABLED= \\
BOOST_STATIC_ASSERT(x)= \\
BOOST_STATIC_ASSERT_MSG(x,y)= \\
BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\
BOOST_RV_REF(x)=\"x&&\" \\
BOOST_NESTED_TEMPLATE=template \\
BOOST_CONSTEXPR=constexpr \\
BOOST_CXX14_CONSTEXPR=constexpr \\
BOOST_OPERATORS_CONSTEXPR=constexpr \\
BOOST_CONSTEXPR_OR_CONST=constexpr \\
BOOST_NOEXCEPT=noexcept \\
BOOST_NOEXCEPT_IF(x)=noexcept(x) \\
BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\
BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\
BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\
BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\
BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\
BOOST_REF_CONST=const"
<doxygen:param>"EXCLUDE_SYMBOLS= \\
detail \\
F \\
result_of_has_result_type_impl \\
conditional \\
boost::operators_impl"
<xsl:param>"boost.doxygen.reftitle=Reference"
<xsl:param>"boost.doxygen.refid=in_place_factory.reference"
;
# Generate XML doxygen reference for operators component in operators_reference.xml
# we skip operators_reference because operators.hpp is not adapted for doxygen
# Generate XML doxygen reference for result_of component in result_of_reference.xml
doxygen result_of_reference
:
$(INCLUDES)/boost/utility/result_of.hpp
:
<location>tmp
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>EXTRACT_ALL=NO
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED= \\
BOOST_UTILITY_DOCS \\
BOOST_SYMBOL_VISIBLE= \\
BOOST_FORCEINLINE=inline \\
BOOST_GPU_ENABLED= \\
BOOST_STATIC_ASSERT(x)= \\
BOOST_STATIC_ASSERT_MSG(x,y)= \\
BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\
BOOST_RV_REF(x)=\"x&&\" \\
BOOST_NESTED_TEMPLATE=template \\
BOOST_CONSTEXPR=constexpr \\
BOOST_CXX14_CONSTEXPR=constexpr \\
BOOST_OPERATORS_CONSTEXPR=constexpr \\
BOOST_CONSTEXPR_OR_CONST=constexpr \\
BOOST_NOEXCEPT=noexcept \\
BOOST_NOEXCEPT_IF(x)=noexcept(x) \\
BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\
BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\
BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\
BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\
BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\
BOOST_REF_CONST=const"
<doxygen:param>"EXCLUDE_SYMBOLS= \\
detail \\
F \\
result_of_has_result_type_impl \\
conditional \\
boost::operators_impl"
<xsl:param>"boost.doxygen.reftitle=Reference"
<xsl:param>"boost.doxygen.refid=result_of.reference"
;
# Generate XML doxygen reference for string_view component in string_view_reference.xml
doxygen string_view_reference
:
$(INCLUDES)/boost/utility/string_view.hpp
:
<location>tmp
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>EXTRACT_ALL=NO
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED= \\
BOOST_UTILITY_DOCS \\
BOOST_SYMBOL_VISIBLE= \\
BOOST_FORCEINLINE=inline \\
BOOST_GPU_ENABLED= \\
BOOST_STATIC_ASSERT(x)= \\
BOOST_STATIC_ASSERT_MSG(x,y)= \\
BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\
BOOST_RV_REF(x)=\"x&&\" \\
BOOST_NESTED_TEMPLATE=template \\
BOOST_CONSTEXPR=constexpr \\
BOOST_CXX14_CONSTEXPR=constexpr \\
BOOST_OPERATORS_CONSTEXPR=constexpr \\
BOOST_CONSTEXPR_OR_CONST=constexpr \\
BOOST_NOEXCEPT=noexcept \\
BOOST_NOEXCEPT_IF(x)=noexcept(x) \\
BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\
BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\
BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\
BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\
BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\
BOOST_REF_CONST=const"
<doxygen:param>"EXCLUDE_SYMBOLS= \\
detail \\
F \\
result_of_has_result_type_impl \\
conditional \\
boost::operators_impl"
<xsl:param>"boost.doxygen.reftitle=Reference"
<xsl:param>"boost.doxygen.refid=string_view.reference"
;
# Generate XML doxygen reference for value_init component in value_init_reference.xml
doxygen value_init_reference
:
$(INCLUDES)/boost/utility/value_init.hpp
:
<location>tmp
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>EXTRACT_ALL=NO
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED= \\
BOOST_UTILITY_DOCS \\
BOOST_SYMBOL_VISIBLE= \\
BOOST_FORCEINLINE=inline \\
BOOST_GPU_ENABLED= \\
BOOST_STATIC_ASSERT(x)= \\
BOOST_STATIC_ASSERT_MSG(x,y)= \\
BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\
BOOST_RV_REF(x)=\"x&&\" \\
BOOST_NESTED_TEMPLATE=template \\
BOOST_CONSTEXPR=constexpr \\
BOOST_CXX14_CONSTEXPR=constexpr \\
BOOST_OPERATORS_CONSTEXPR=constexpr \\
BOOST_CONSTEXPR_OR_CONST=constexpr \\
BOOST_NOEXCEPT=noexcept \\
BOOST_NOEXCEPT_IF(x)=noexcept(x) \\
BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\
BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\
BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\
BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\
BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\
BOOST_REF_CONST=const"
<doxygen:param>"EXCLUDE_SYMBOLS= \\
detail \\
F \\
result_of_has_result_type_impl \\
conditional \\
boost::operators_impl"
<xsl:param>"boost.doxygen.reftitle=Reference"
<xsl:param>"boost.doxygen.refid=value_init.reference"
;
# Generate main.xml boostbook documentation from main.qbk quickbook documentation
xml main : main.qbk ;
# Generate ./html documentation from main.xml boostbook documentation
# Each doxygen reference in quickbook files with [xinclude tmp/<component>_reference.xml] becomes:
# <xi:include href="../../../../libs/utility/doc/tmp/<component>_reference.xml"/>
# in boostbook.
# All of these <xi:include> commands give the reference the id "utility.reference"
boostbook standalone_main
:
main
:
<dependency>base_from_member_reference
<dependency>boost_binary_reference
<dependency>call_traits_reference
<dependency>compressed_pair_reference
<dependency>in_place_factory_reference
<dependency>result_of_reference
<dependency>string_view_reference
<dependency>value_init_reference
# File name of HTML output:
# <xsl:param>root.filename=main
<xsl:param>boost.root=../../../..
<format>pdf:<xsl:param>"boost.url.prefix=http://www.boost.org/doc/libs/release/libs/utility/doc/html"
# How far down we chunk nested sections: no more than two so utility component pages include their reference
<xsl:param>chunk.section.depth=2 # 8
# Don't put the first section on the same page as the TOC:
<xsl:param>chunk.first.sections=1 # 1
# How far down sections get TOC: 2 so we show each Utility component in main page but no more than that
<xsl:param>toc.section.depth=2 # 2
# Max depth in each TOC: 2 so we show each Utility component in main page but no more than that
<xsl:param>toc.max.depth=2 # 2
# How far down we go with TOC's in main page: 2 so each Utility component page has 1 level TOC
<xsl:param>generate.section.toc.level=2 # 2
;
###############################################################################
alias boostdoc ;
explicit boostdoc ;
alias boostrelease : standalone_main ;
explicit boostrelease ;

View File

@@ -0,0 +1,376 @@
[/
Copyright 2001, 2003, 2004, 2012 Daryle Walker.
Copyright (c) 2021, Alan Freitas
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt
or copy at http://boost.org/LICENSE_1_0.txt
]
[section:base_from_member Base from Member]
[block'''<?dbhtml stop-chunking?>''']
[section Introduction]
The class templates __base_from_member__ support the base-from-member idiom.
When developing a class, sometimes a base class needs to be initialized
with a member of the current class. As a na\u00EFve example:
```
#include <streambuf> /* for std::streambuf */
#include <ostream> /* for std::ostream */
class fdoutbuf
: public __std_streambuf__
{
public:
explicit fdoutbuf( int fd );
//...
};
class fdostream
: public __std_ostream__
{
protected:
fdoutbuf buf;
public:
explicit fdostream( int fd )
: buf( fd ), __std_ostream__( &buf ) {}
//...
};
```
This is undefined because C++'s initialization order mandates that the base
class is initialized before the member it uses. [@http://www.moocat.org R.
Samuel Klatchko] developed a way around this by using the initialization
order in his favor. Base classes are initialized in order of declaration, so
moving the desired member to another base class, that is initialized before
the desired base class, can ensure proper initialization.
A custom base class can be made for this idiom:
#include <streambuf> /* for std::streambuf */
#include <ostream> /* for std::ostream */
class fdoutbuf
: public __std_streambuf__
{
public:
explicit fdoutbuf( int fd );
//...
};
struct fdostream_pbase
{
fdoutbuf sbuffer;
explicit fdostream_pbase( int fd )
: sbuffer( fd ) {}
};
class fdostream
: private fdostream_pbase
, public __std_ostream__
{
typedef fdostream_pbase pbase_type;
typedef __std_ostream__ base_type;
public:
explicit fdostream( int fd )
: pbase_type( fd ), base_type( &sbuffer ) {}
//...
};
Other projects can use similar custom base classes. The technique is basic
enough to make a template, with a sample template class in this library.
The main template parameter is the type of the enclosed member. The
template class has several (explicit) constructor member templates, which
implicitly type the constructor arguments and pass them to the member. The
template class uses implicit copy construction and assignment, cancelling
them if the enclosed member is non-copyable.
Manually coding a base class may be better if the construction and/or
copying needs are too complex for the supplied template class, or if the
compiler is not advanced enough to use it.
Since base classes are unnamed, a class cannot have multiple (direct) base
classes of the same type. The supplied template class has an extra template
parameter, an integer, that exists solely to provide type differentiation.
This parameter has a default value so a single use of a particular member
type does not need to concern itself with the integer.
[endsect]
[section Synopsis]
#include <type_traits> /* exposition only */
#ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY
#define BOOST_BASE_FROM_MEMBER_MAX_ARITY 10
#endif
template < typename MemberType, int UniqueID = 0 >
class __base_from_member__
{
protected:
MemberType member;
#if ``['C++11 is in use]``
template< typename ...T >
explicit constexpr __base_from_member__( T&& ...x )
noexcept( __std_is_nothrow_constructible__<MemberType, T...>::value );
#else
__base_from_member__();
template< typename T1 >
explicit __base_from_member__( T1 x1 );
template< typename T1, typename T2 >
__base_from_member__( T1 x1, T2 x2 );
//...
template< typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10 >
__base_from_member__( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7,
T8 x8, T9 x9, T10 x10 );
#endif
};
template < typename MemberType, int UniqueID >
class __base_from_member__<MemberType&, UniqueID>
{
protected:
MemberType& member;
explicit constexpr __base_from_member__( MemberType& x )
noexcept;
};
The class template has a first template parameter `MemberType` representing
the type of the based-member. It has a last template parameter `UniqueID`,
that is an `int`, to differentiate between multiple base classes that use
the same based-member type. The last template parameter has a default value
of zero if it is omitted. The class template has a protected data member
called `member` that the derived class can use for later base classes or
itself.
If the appropriate features of C++11 are present, there will be a single
constructor template. It implements ['perfect forwarding] to the best
constructor call of `member` if any. The constructor template is marked
both `constexpr` and `explicit`. The former will be ignored if the
corresponding inner constructor call of `member` does not have the marker.
The latter binds the other way; always taking effect, even when the inner
constructor call does not have the marker. The constructor template
propagates the `noexcept` status of the inner constructor call. The
constructor template has a trailing parameter with a default value that
disables the template when its signature is too close to the signatures of
the automatically-defined non-template copy- and/or move-constructors of
__base_from_member__.
On earlier-standard compilers, there is a default constructor and several
constructor member templates. These constructor templates can take as many
arguments (currently up to ten) as possible and pass them to a constructor
of the data member.
A specialization for member references offers a single constructor taking
a `MemberType&`, which is the only way to initialize a reference.
Since C++ does not allow any way to explicitly state the template parameters
of a templated constructor, make sure that the arguments are already close
as possible to the actual type used in the data member's desired constructor.
Explicit conversions may be necessary.
The `BOOST_BASE_FROM_MEMBER_MAX_ARITY` macro constant specifies the maximum
argument length for the constructor templates. The constant may be overridden
if more (or less) argument configurations are needed. The constant may be
read for code that is expandable like the class template and needs to
maintain the same maximum size. (Example code would be a class that uses
this class template as a base class for a member with a flexible set of
constructors.) This constant is ignored when C++11 features are present.
[endsect]
[section Basic Usage]
With the starting example, the `fdoutbuf` sub-object needs to be
encapsulated in a base class that is inherited before `__std_ostream__`.
```
#include <boost/utility/base_from_member.hpp>
#include <streambuf> // for std::streambuf
#include <ostream> // for __std_ostream__
class fdoutbuf
: public __std_streambuf__
{
public:
explicit fdoutbuf( int fd );
//...
};
class fdostream
: private __boost_base_from_member__<fdoutbuf>
, public __std_ostream__
{
// Helper typedef's
typedef __boost_base_from_member__<fdoutbuf> pbase_type;
typedef __std_ostream__ base_type;
public:
explicit fdostream( int fd )
: pbase_type( fd ), base_type( &member ){}
//...
};
```
The base-from-member idiom is an implementation detail, so it should not
be visible to the clients (or any derived classes) of `fdostream`. Due to
the initialization order, the `fdoutbuf` sub-object will get initialized
before the `__std_ostream__` sub-object does, making the former sub-object
safe to use in the latter sub-object's construction. Since the `fdoutbuf`
sub-object of the final type is the only sub-object with the name `member`
that name can be used unqualified within the final class.
[endsect]
[section Multiple Sub-Objects]
The base-from-member class templates should commonly involve only one
base-from-member sub-object, usually for attaching a stream-buffer to an
I/O stream. The next example demonstrates how to use multiple
base-from-member sub-objects and the resulting qualification issues.
```
#include <boost/utility/base_from_member.hpp>
#include <cstddef> /* for NULL */
struct an_int
{
int y;
an_int( float yf );
};
class switcher
{
public:
switcher();
switcher( double, int * );
//...
};
class flow_regulator
{
public:
flow_regulator( switcher &, switcher & );
//...
};
template < unsigned Size >
class fan
{
public:
explicit fan( switcher );
//...
};
class system
: private __boost_base_from_member__<an_int>
, private __boost_base_from_member__<switcher>
, private __boost_base_from_member__<switcher, 1>
, private __boost_base_from_member__<switcher, 2>
, protected flow_regulator
, public fan<6>
{
// Helper typedef's
typedef __boost_base_from_member__<an_int> pbase0_type;
typedef __boost_base_from_member__<switcher> pbase1_type;
typedef __boost_base_from_member__<switcher, 1> pbase2_type;
typedef __boost_base_from_member__<switcher, 2> pbase3_type;
typedef flow_regulator base1_type;
typedef fan<6> base2_type;
public:
system( double x );
//...
};
system::system( double x )
: pbase0_type( 0.2 )
, pbase1_type()
, pbase2_type( -16, &this->pbase0_type::member.y )
, pbase3_type( x, static_cast<int *>(NULL) )
, base1_type( pbase3_type::member, pbase1_type::member )
, base2_type( pbase2_type::member )
{
//...
}
```
The final class has multiple sub-objects with the name `member`, so any
use of that name needs qualification by a name of the appropriate base
type. Using `typedef`s ease mentioning the base types.
However, the fix introduces a new problem when a pointer is needed. Using the
address operator with a sub-object qualified with its class's name results in a
pointer-to-member (here, having a type of `an_int __boost_base_from_member__<an_int, 0>::*`)
instead of a pointer to the member (having a type of `an_int*`).
The new problem is fixed by qualifying the sub-object with `this->` and is needed
just for pointers, and not for references or values.
There are some argument conversions in the initialization. The constructor
argument for `pbase0_type` is converted from `double` to `float`. The first
constructor argument for `pbase2_type` is converted from `int` to `double`.
The second constructor argument for `pbase3_type` is a special case of
necessary conversion; all forms of the null-pointer literal in C++ (except
`nullptr` from C++11) also look like compile-time integral expressions, so
C++ always interprets such code as an integer when it has overloads that can
take either an integer or a pointer.
The last conversion is necessary for the compiler to call a constructor form
with the exact pointer type used in `switcher`'s constructor. (If C++11's
__nullptr__ is used, it still needs a conversion if multiple pointer types can
be accepted in a constructor call but `__std_nullptr_t__` cannot.)
[endsect]
[/===============]
[xinclude tmp/base_from_member_reference.xml]
[/===============]
[section Acknowledgments]
Author: Walker, Daryle
Copyright 2001, 2003, 2004, 2012 Daryle Walker
* [@http://www.boost.org/people/ed_brey.htm Ed Brey] suggested some interface
changes.
* [@http://www.moocat.org R. Samuel Klatchko] ([@mailto:rsk@moocat.org
rsk@moocat.org], [@mailto:rsk@brightmail.com rsk@brightmail.com]) invented
the idiom of how to use a class member for initializing a base class.
* [@http://www.boost.org/people/dietmar_kuehl.htm Dietmar Kuehl] popularized the
base-from-member idiom in his [@http://www.informatik.uni-konstanz.de/~kuehl/c++/iostream/
IOStream example classes].
* Jonathan Turkanis supplied an implementation of generating the constructor
templates that can be controlled and automated with macros. The
implementation uses the [@boost:/libs/preprocessor/index.html Preprocessor library].
* [@http://www.boost.org/people/daryle_walker.html">Daryle Walker] started the
library. Contributed the test file [@../../../test/base_from_member_test.cpp
base_from_member_test.cpp].
[endsect]
[endsect]

View File

@@ -0,0 +1,443 @@
[/
/ Copyright (c) 2012 Marshall Clow
/ Copyright (c) 2021, Alan Freitas
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[/===============]
[section Call Traits]
[/===============]
[section Introduction]
All of the contents of [@../../../../boost/call_traits.hpp `<boost/call_traits.hpp>`] are
defined inside `namespace boost`.
The template class __call_traits_T__ encapsulates the
"best" method to pass a parameter of some type `T` to or
from a function, and consists of a collection of `typedef`s defined
as in the table below. The purpose of __call_traits__ is to ensure
that problems like [link sec:refs "references to references"]
never occur, and that parameters are passed in the most efficient
manner possible, as in the [link sec:examples examples]. In each
case, if your existing practice is to use the type defined on the
left, then replace it with the __call_traits__ defined type on the
right.
Note that for compilers that do not support either partial
specialization or member templates, no benefit will occur from
using __call_traits__: the __call_traits__ defined types will always be
the same as the existing practice in this case. In addition if
only member templates and not partial template specialisation is
support by the compiler (for example Visual C++ 6) then
__call_traits__ cannot be used with array types, although it can still be
used to solve the reference to reference problem.
[table __call_traits__ types
[[Existing practice] [__call_traits__ equivalent] [Description] [Notes]]
[
[`T`
(return by value)
]
[
__call_traits_T__`::value_type`
]
[
Defines a type that represents the "value" of type `T`.
Use this for functions that return by value, or possibly for stored values of type `T`.
]
[2]
]
[
[`T&`
(return value)
]
[
__call_traits_T__`::reference`
]
[
Defines a type that represents a reference to type `T`.
Use for functions that would normally return a `T&`.
]
[1]
]
[
[`const T&`
(return value)
]
[
__call_traits_T__`::const_reference`
]
[
Defines a type that represents a constant reference to type `T`.
Use for functions that would normally return a `const T&`.
]
[1]
]
[
[`const T&`
(function parameter)
]
[
__call_traits_T__`::param_type`
]
[
Defines a type that represents the "best" way to pass a parameter of type `T` to a function.
]
[1,3]
]
]
Notes:
# If `T` is already reference type, then __call_traits__ is
defined such that [link sec:refs "references to references"]
do not occur (requires partial specialization).
# If `T` is an array type, then __call_traits__ defines `value_type`
as a "constant pointer to type" rather than an
"array of type" (requires partial specialization).
Note that if you are using `value_type` as a stored value
then this will result in storing a "constant pointer to
an array" rather than the array itself. This may or may
not be a good thing depending upon what you actually
need (in other words take care!).
# If `T` is a small built in type or a pointer, then `param_type`
is defined as `T const`, instead of `T const&`. This can
improve the ability of the compiler to optimize loops in
the body of the function if they depend upon the passed
parameter, the semantics of the passed parameter is
otherwise unchanged (requires partial specialization).
[endsect]
[section Copy constructibility]
The following table defines which __call_traits__ types can always
be copy-constructed from which other types:
[table Which __call_traits__ types can always be copy-constructed from which other types
[[] [To `T`] [To `value_type`] [To `reference`] [To `const_reference`] [To `param_type`]]
[[From `T`] [iff `T` is copy constructible] [iff `T` is copy constructible] [Yes] [Yes] [Yes]]
[[From `value_type`] [iff `T` is copy constructible] [iff `T` is copy constructible] [No] [No] [Yes]]
[[From `reference`] [iff `T` is copy constructible] [iff `T` is copy constructible] [Yes] [Yes] [Yes]]
[[From `const_reference`] [iff `T` is copy constructible] [No] [No] [Yes] [Yes]]
[[From `param_type`] [iff `T` is copy constructible] [iff `T` is copy constructible] [No] [No] [Yes]]
]
If `T` is an assignable type the following assignments are possible:
[table Which __call_traits__ types are assignable from which other types
[[] [To `T`] [To `value_type`] [To `reference`] [To `const_reference`] [To `param_type`]]
[[From `T`] [Yes] [Yes] [-] [-] [-]]
[[From `value_type`] [Yes] [Yes] [-] [-] [-]]
[[From `reference`] [Yes] [Yes] [-] [-] [-]]
[[From `const_reference`] [Yes] [Yes] [-] [-] [-]]
[[From `param_type`] [Yes] [Yes] [-] [-] [-]]
]
[endsect]
[#sec:examples]
[section Examples]
The following table shows the effect that __call_traits__ has on
various types.
[table Examples of __call_traits__ types
[[] [__call_traits__::`value_type`] [__call_traits__::`reference`] [__call_traits__::`const_reference`] [__call_traits__::`param_type`] [Applies to:]]
[[From `my_class`] [`my_class`] [`my_class&`] [`const my_class&`] [`my_class const&`] [All user-defined types]]
[[From `int`] [`int`] [`int&`] [`const int&`] [`int const`] [All small built-in types]]
[[From `int*`] [`int*`] [`int*&`] [`int* const &`] [`int* const`] [All pointer types]]
[[From `int&`] [`int&`] [`int&`] [`const int&`] [`int&`] [All reference types]]
[[From `const int&`] [`const int&`] [`const int&`] [`const int&`] [`const int&`] [All constant reference types]]
[[From `int[3]`] [`const int*`] [`int(&)[3]`] [`const int(&)[3]`] [`const int* const`] [All array types]]
[[From `const int[3]`] [`const int*`] [`const int(&)[3]`] [`const int(&)[3]`] [`const int* const`] [All constant array types]]
]
The table assumes the compiler supports partial
specialization: if it does not then all types behave in
the same way as the entry for "`my_class`", and
__call_traits__ can not be used with reference or array types.
[section Example 1:]
The following class is a trivial class that stores some type `T`
by value (see the [@../../../test/call_traits_test.cpp `call_traits_test.cpp`]
file). The aim is to illustrate how each of the available
__call_traits__ `typedef`s may be used:
```
template <class T>
struct contained
{
// define our typedefs first, arrays are stored by value
// so value_type is not the same as result_type:
typedef typename __boost_call_traits__<T>::param_type param_type;
typedef typename __boost_call_traits__<T>::reference reference;
typedef typename __boost_call_traits__<T>::const_reference const_reference;
typedef T value_type;
typedef typename __boost_call_traits__<T>::value_type result_type;
// stored value:
value_type v_;
// constructors:
contained() {}
contained(param_type p) : v_(p){}
// return byval:
result_type value() { return v_; }
// return by_ref:
reference get() { return v_; }
const_reference const_get()const { return v_; }
// pass value:
void call(param_type p){}
};
```
[endsect]
[#sec:refs]
[section Example 2 (the reference to reference problem):]
Consider the definition of __std_binder1st__:
```
template <class Operation>
class binder1st :
public __std_unary_function__<typename Operation::second_argument_type, typename Operation::result_type>
{
protected:
Operation op;
typename Operation::first_argument_type value;
public:
binder1st(const Operation& x, const typename Operation::first_argument_type& y);
typename Operation::result_type operator()(const typename Operation::second_argument_type& x) const;
};
```
Now consider what happens in the relatively common case that
the functor takes its second argument as a reference, that
implies that `Operation::second_argument_type` is a
reference type, `operator()` will now end up taking a
reference to a reference as an argument, and that is not
currently legal. The solution here is to modify `operator()`
to use __call_traits__:
```
typename Operation::result_type operator()(typename __call_traits__<typename Operation::second_argument_type>::param_type x) const;
```
Now in the case that `Operation::second_argument_type`
is a reference type, the argument is passed as a reference, and
the no "reference to reference" occurs.
[endsect]
[#sec:example3]
[section Example 3 (the `make_pair` problem):]
If we pass the name of an array as one (or both) arguments to `__std_make_pair__`,
then template argument deduction deduces the passed parameter as
"const reference to array of `T`", this also applies to
string literals (which are really array literals). Consequently
instead of returning a pair of pointers, it tries to return a
pair of arrays, and since an array type is not copy-constructible
the code fails to compile. One solution is to explicitly cast the
arguments to __std_make_pair__ to pointers, but __call_traits__ provides a
better automatic solution that works safely even in generic code where the
cast might do the wrong thing:
```
template <class T1, class T2>
__std_pair__<
typename __boost_call_traits__<T1>::value_type,
typename __boost_call_traits__<T2>::value_type>
make_pair(const T1& t1, const T2& t2)
{
return __std_pair__<
typename __boost_call_traits__<T1>::value_type,
typename __boost_call_traits__<T2>::value_type>(t1, t2);
}
```
Here, the deduced argument types will be automatically
degraded to pointers if the deduced types are arrays, similar
situations occur in the standard binders and adapters: in
principle in any function that "wraps" a temporary
whose type is deduced. Note that the function arguments to
__std_make_pair__ are not expressed in terms of __call_traits__: doing so
would prevent template argument deduction from functioning.
[endsect]
[#sec:example4]
[section Example 4 (optimising fill):]
The __call_traits__ template will "optimize" the passing
of a small built-in type as a function parameter. This mainly has
an effect when the parameter is used within a loop body.
In the following example (see [@boost:/libs/type_traits/examples/fill_example.cpp `fill_example.cpp`]),
a version of __std_fill__ is optimized in two ways: if the type
passed is a single byte built-in type then __std_memset__ is used to
effect the fill, otherwise a conventional C++ implementation is
used, but with the passed parameter "optimized" using
__call_traits__:
```
template <bool opt>
struct filler
{
template <typename I, typename T>
static void do_fill(I first, I last, typename __boost_call_traits__<T>::param_type val)
{
while(first != last)
{
*first = val;
++first;
}
}
};
template <>
struct filler<true>
{
template <typename I, typename T>
static void do_fill(I first, I last, T val)
{
__std_memset__(first, val, last-first);
}
};
template <class I, class T>
inline void fill(I first, I last, const T& val)
{
enum { can_opt = boost::is_pointer<I>::value
&& boost::is_arithmetic<T>::value
&& (sizeof(T) == 1) };
typedef filler<can_opt> filler_t;
filler_t::template do_fill<I,T>(first, last, val);
}
```
The reason that this is "optimal" for small built-in types is that
with the value passed as `T const` instead of `const T&` the compiler is
able to tell both that the value is constant and that it is free
of aliases. With this information the compiler is able to cache
the passed value in a register, unroll the loop, or use
explicitly parallel instructions: if any of these are supported.
Exactly how much mileage you will get from this depends upon your
compiler - we could really use some accurate benchmarking
software as part of boost for cases like this.
Note that the function arguments to fill are not expressed in
terms of __call_traits__: doing so would prevent template argument
deduction from functioning. Instead fill acts as a "thin
wrapper" that is there to perform template argument
deduction, the compiler will optimise away the call to fill all
together, replacing it with the call to `filler<>::do_fill`,
which does use __call_traits__.
[endsect]
[endsect]
[section Rationale]
The following notes are intended to briefly describe the
rationale behind choices made in __call_traits__.
All user-defined types follow "existing practice" and need no comment.
Small built-in types, what the standard calls [@https://en.cppreference.com/w/cpp/language/types fundamental
types], differ from existing practice only in the `param_type`
`typedef`. In this case passing `T const` is compatible
with existing practice, but may improve performance in some cases
(see [link sec:example4 Example 4]). In any case this should never
be any worse than existing practice.
Pointers follow the same rationale as small built-in types.
For reference types the rationale follows [link sec:refs Example 2]
- references to references are not allowed, so the __call_traits__
members must be defined such that these problems do
not occur. There is a proposal to modify the language such that
"a reference to a reference is a reference" (issue #106,
submitted by Bjarne Stroustrup). __call_traits_T__`::value_type`
and __call_traits_T__`::param_type` both provide the same effect
as that proposal, without the need for a language change. In
other words, it's a workaround.
For array types, a function that takes an array as an argument
will degrade the array type to a pointer type: this means that
the type of the actual parameter is different from its declared
type, something that can cause endless problems in template code
that relies on the declared type of a parameter.
For example:
```
template <class T>
struct A
{
void foo(T t);
};
```
In this case if we instantiate `A<int[2]>` then the declared type of
the parameter passed to member function `foo` is `int[2]`, but its
actual type is `const int*`. If we try to use the type `T` within the
function body, then there is a strong likelihood that our code will not compile:
```
template <class T>
void A<T>::foo(T t)
{
T dup(t); // doesn't compile for case that T is an array.
}
```
By using __call_traits__ the degradation from array to pointer is
explicit, and the type of the parameter is the same as it's
declared type:
```
template <class T>
struct A
{
void foo(typename __call_traits__<T>::value_type t);
};
template <class T>
void A<T>::foo(typename __call_traits__<T>::value_type t)
{
typename __call_traits__<T>::value_type dup(t); // OK even if T is an array type.
}
```
For `value_type` (return by value), again only a pointer may be
returned, not a copy of the whole array, and again __call_traits__
makes the degradation explicit. The `value_type` member is useful
whenever an array must be explicitly degraded to a pointer -
[link sec:example3 Example 3] provides the test case.
Footnote: the array specialisation for __call_traits__ is the least
well understood of all the __call_traits__ specialisations. If the given
semantics cause specific problems for you, or does not solve a particular
array-related problem, then I would be interested to hear about
it. Most people though will probably never need to use this
specialisation.
[endsect]
[/===============]
[xinclude tmp/call_traits_reference.xml]
[/===============]
[endsect]

View File

@@ -0,0 +1,98 @@
[/
Copyright 2000 Beman Dawes & John Maddock.
Copyright (c) 2021, Alan Freitas
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt
or copy at http://boost.org/LICENSE_1_0.txt
]
[section Compressed Pair]
[section Introduction]
All of the contents of [@../../../../boost/compressed_pair.hpp `<boost/compressed_pair.hpp>`] are defined inside
`namespace boost`.
The class __compressed_pair__ is very similar to __std_pair__. However, if either of
the template arguments are empty classes, then the
[@https://en.cppreference.com/w/cpp/language/ebo ['empty base-class optimisation]]
is applied to compress the size of the pair.
[endsect]
[section Synopsis]
```cpp
template <class T1, class T2>
class __compressed_pair__
{
public:
typedef T1 first_type;
typedef T2 second_type;
typedef typename __call_traits__<first_type>::param_type first_param_type;
typedef typename __call_traits__<second_type>::param_type second_param_type;
typedef typename __call_traits__<first_type>::reference first_reference;
typedef typename __call_traits__<second_type>::reference second_reference;
typedef typename __call_traits__<first_type>::const_reference first_const_reference;
typedef typename __call_traits__<second_type>::const_reference second_const_reference;
compressed_pair() : base() {}
compressed_pair(first_param_type x, second_param_type y);
explicit compressed_pair(first_param_type x);
explicit compressed_pair(second_param_type y);
compressed_pair& operator=(const compressed_pair&);
first_reference first();
first_const_reference first() const;
second_reference second();
second_const_reference second() const;
void swap(compressed_pair& y);
};
```
The two members of the pair can be accessed using the member functions
`first()` and `second()`. Note that not all member functions can be
instantiated for all template parameter types. In particular
__compressed_pair__ can be instantiated for reference and array types,
however in these cases the range of constructors that can be used is
limited. If types `T1` and `T2` are the same type, then there is only
one version of the single-argument constructor, and this constructor
initialises both values in the pair to the passed value.
Note that if either member is a [@https://en.cppreference.com/w/cpp/named_req/PODType POD]
type, then that member is not zero-initialized by the __compressed_pair__ default constructor:
it is up to you to supply an initial value for these types if you want them to have
a default value.
Note that __compressed_pair__ can not be instantiated if either of the
template arguments is a union type, unless there is compiler support for
[@boost:/libs/type_traits/index.html `boost::is_union`], or
if [@boost:/libs/type_traits/index.html `boost::is_union`] is
specialised for the union type.
Finally, a word of caution for Visual C++ 6 users: if either argument is an
empty type, then assigning to that member will produce memory corruption,
unless the empty type has a "do nothing" assignment operator defined. This
is due to a bug in the way VC6 generates implicit assignment operators.
[endsect]
[/===============]
[xinclude tmp/compressed_pair_reference.xml]
[/===============]
[section Acknowledgments]
Based on contributions by Steve Cleary, Beman Dawes, Howard Hinnant and
John Maddock.
Maintained by [@mailto:john@johnmaddock.co.uk John Maddock].
[endsect]
[endsect]

View File

@@ -0,0 +1,308 @@
[/
/ Copyright (c) 2012 Marshall Clow
/ Copyright (c) 2021, Alan Freitas
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[/===============]
[#sec:in_place_factory]
[section In-place Factory]
[/===============]
[section Introduction]
Suppose we have a class
```
struct X
{
X ( int, __std_string__ ) ;
};
```
And a container for it which supports an empty state. That is, a container which can contain zero objects:
```
struct C
{
C() : contained_(0) {}
~C() { delete contained_ ; }
X* contained_ ;
};
```
A container designed to support an empty state typically does not require the contained type to be
__DefaultConstructible__, but it typically requires it to be __CopyConstructible__ as a mechanism to
initialize the object to store:
```
struct C
{
C() : contained_(0) {}
C ( X const& v ) : contained_ ( new X(v) ) {}
~C() { delete contained_ ; }
X* contained_ ;
};
```
There is a subtle problem with this: since the mechanism used to initialize the stored object is copy construction,
there must exist a previously constructed source object to copy from. This object is likely to be temporary and serve
no purpose besides being the source:
```
void foo()
{
// Temporary object created.
C c( X(123,"hello") ) ;
}
```
A solution to this problem is to support direct construction of the contained
object right in the container's storage.
In this scheme, the user supplies the arguments for the `X` constructor
directly to the container:
```
struct C
{
C() : contained_(0) {}
C ( X const& v ) : contained_ ( new X(v) ) {}
C ( int a0, __std_string__ a1 ) : contained_ ( new X(a0,a1) ) {}
~C() { delete contained_ ; }
X* contained_ ;
};
```
```
void foo()
{
// Wrapped object constructed in-place
// No temporary created.
C c(123,"hello");
}
```
Clearly, this solution does not scale well since the container must duplicate all the constructor overloads
from the contained type, or at least all those which are to be supported directly in the container.
[endsect]
[section Framework]
This library proposes a framework to allow some containers to directly construct contained objects in-place without requiring
the entire set of constructor overloads from the contained type. It also allows the container to remove the __CopyConstructible__
requirement from the contained type since objects can be directly constructed in-place without need of a copy.
The only requirement on the container is that it must provide proper storage. That is, the container should be
correctly aligned and sized. Naturally, the container will typically support uninitialized storage to avoid the
in-place construction to override a fully-constructed object, as this would defeat the purpose of in-place construction.
For this purpose, the framework provides two concepts called: InPlaceFactories and TypedInPlaceFactories.
Helpers to declare these classes are declared in [@../../../../boost/utility/in_place_factory.hpp `<boost/utility/in_place_factory.hpp>`]
and [@../../../../boost/utility/typed_in_place_factory.hpp `<boost/utility/typed_in_place_factory.hpp>`].
Essentially, these classes hold a sequence of actual parameters and a method to construct an object in place using these parameters.
Each member of the family differs only in the number and type of the parameter list. The first family
takes the type of the object to construct directly in method provided for that
purpose, whereas the second family incorporates that type in the factory class
itself. From the container point of view, using the framework amounts to calling the
factory's method to contruct the object in place. From the user point of view, it amounts to creating
the right factory object to hold the parameters and pass it to the container.
The following simplified example shows the basic idea. A complete example follows the formal specification of the framework:
```
struct C
{
template <class InPlaceFactory>
C ( InPlaceFactory const& aFactory )
:
contained_ ( uninitialized_storage() )
{
aFactory.template apply<X>(contained_);
}
~C()
{
contained_ -> X::~X();
delete[] contained_ ;
}
char* uninitialized_storage() { return new char[sizeof(X)] ; }
char* contained_ ;
};
void foo()
{
C c( in_place(123,"hello") ) ;
}
```
[endsect]
[section Specification]
The following is the first member of the family of `InPlaceFactory` classes, along with its corresponding helper template function.
The rest of the family varies only in the number and type of template and constructor parameters.
```
namespace boost {
struct __in_place_factory_base__ {};
template<class A0>
class in_place_factory : public __in_place_factory_base__
{
public:
in_place_factory ( A0 const& a0 ) : m_a0(a0) {}
template< class T >
void apply ( void* address ) const
{
new (address) T(m_a0);
}
private:
A0 const& m_a0 ;
};
template<class A0>
in_place_factory<A0> in_place ( A0 const& a0 )
{
return in_place_factory<A0>(a0);
}
}
```
Similarly, the following is the first member of the family of `typed_in_place_factory` classes, along with its corresponding
helper template function. The rest of the family varies only in the number and type of template and constructor parameters.
```
namespace boost {
struct __typed_in_place_factory_base__ {};
template<class T, class A0>
class typed_in_place_factory : public __typed_in_place_factory_base__
{
public:
typed_in_place_factory ( A0 const& a0 ) : m_a0(a0) {}
void apply ( void* address ) const
{
new (address) T(m_a0);
}
private:
A0 const& m_a0 ;
};
template<class T, class A0>
typed_in_place_factory<A0> in_place ( A0 const& a0 )
{
return typed_in_place_factory<T,A0>(a0);
}
}
```
As you can see, the `in_place_factory` and `typed_in_place_factory` template classes vary only in the way they specify
the target type: in the first family, the type is given as a template argument to the apply member function while in the
second it is given directly as part of the factory class.
When the container holds a unique non-polymorphic type, such as the case of [@boost:/libs/optional/index.html Boost.Optional],
it knows the exact dynamic-type of the contained object and can pass it to the `apply()` method of a non-typed factory.
In this case, end users can use an `in_place_factory` instance which can be constructed without the type of the object to construct.
However, if the container holds heterogeneous or polymorphic objects, such as the case of [@boost:/libs/variant/index.html Boost.Variant],
the dynamic-type of the object to be constructed must be known by the factory. In this case, end users must use a `typed_in_place_factory`
instead.
[endsect]
[section Container-side Usage]
As shown in the introductory simplified example, the container class must contain methods that accept an instance of
these factories and pass the object's storage to the factory's apply method.
However, the type of the factory class cannot be completely specified in the container class because that would
defeat the whole purpose of the factories which is to allow the container to accept a variadic argument list
for the constructor of its contained object.
The correct function overload must be based on the only distinctive and common
characteristic of all the classes in each family: the base class.
Depending on the container class, you can use `enable_if` to generate the right overload, or use the following
dispatch technique, which is used in the [@boost:/libs/optional/index.html Boost.Optional] class:
```
struct C
{
C() : contained_(0) {}
C ( X const& v ) : contained_ ( new X(v) ) {}
template <class Expr>
C ( Expr const& expr )
:
contained_ ( uninitialized_storage() )
{
construct(expr,&expr);
}
~C() { delete contained_ ; }
template<class InPlaceFactory>
void construct ( InPlaceFactory const& aFactory, boost::__in_place_factory_base__* )
{
aFactory.template apply<X>(contained_);
}
template<class TypedInPlaceFactory>
void construct ( TypedInPlaceFactory const& aFactory, boost::__typed_in_place_factory_base__* )
{
aFactory.apply(contained_);
}
X* uninitialized_storage() { return static_cast<X*>(new char[sizeof(X)]) ; }
X* contained_ ;
};
```
[endsect]
[section User-side Usage]
End users pass to the container an instance of a factory object holding the actual parameters needed to construct the
contained object directly within the container. For this, the helper template function `in_place` is used.
The call `in_place(a0,a1,a2,...,an)` constructs a (non-typed) `in_place_factory` instance with the given argument list.
The call `in_place<T>(a0,a1,a2,...,an)` constructs a `typed_in_place_factory` instance with the given argument list for the
type `T`.
```
void foo()
{
C a( in_place(123, "hello") ) ; // in_place_factory passed
C b( in_place<X>(456, "world") ) ; // typed_in_place_factory passed
}
```
[endsect]
[/===============]
[#boost.typed_in_place_factory_base]
[xinclude tmp/in_place_factory_reference.xml]
[/===============]
[section Acknowledgments]
Copyright Fernando Luis Cacciola Carballal, 2004
[endsect]
[endsect]

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,539 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg6858"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="utility.svg">
<defs
id="defs6860">
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4453-7-8-6-7-3-5"
id="linearGradient10687-2-5"
gradientUnits="userSpaceOnUse"
x1="753.02301"
y1="3132.0801"
x2="1146.25"
y2="3132.0801" />
<linearGradient
id="linearGradient4453-7-8-6-7-3-5">
<stop
style="stop-color:#aac4dd;stop-opacity:1;"
offset="0"
id="stop4455-61-8-7-1-2-8" />
<stop
style="stop-color:#c2dbe9;stop-opacity:1;"
offset="1"
id="stop4457-4-1-9-1-12-1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4453-7-8-6-7-3-5"
id="linearGradient10685-2-2"
gradientUnits="userSpaceOnUse"
x1="753.02301"
y1="3132.0801"
x2="1146.25"
y2="3132.0801" />
<linearGradient
id="linearGradient6749">
<stop
style="stop-color:#aac4dd;stop-opacity:1;"
offset="0"
id="stop6751" />
<stop
style="stop-color:#c2dbe9;stop-opacity:1;"
offset="1"
id="stop6753" />
</linearGradient>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3387-3-6-4-2-8-4">
<path
inkscape:connector-curvature="0"
d="m 862.109,3289.75 -109.086,-190.45 69.122,-124.42 164.511,-0.47 c 0,0 111.044,188.28 116.564,197.63 7.66,0 43.03,0 43.03,0 l -67.03,117.71 -217.111,0 z"
id="path3389-2-0-7-7-8-9" />
</clipPath>
<linearGradient
y2="3132.0801"
x2="1146.25"
y1="3132.0801"
x1="753.02301"
gradientUnits="userSpaceOnUse"
id="linearGradient4492-8-8"
xlink:href="#linearGradient4453-7-8-6-7-3-5"
inkscape:collect="always" />
<linearGradient
id="linearGradient6758">
<stop
style="stop-color:#aac4dd;stop-opacity:1;"
offset="0"
id="stop6760" />
<stop
style="stop-color:#c2dbe9;stop-opacity:1;"
offset="1"
id="stop6762" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4453-7-8-6-7-3-5"
id="linearGradient10691-7-8"
gradientUnits="userSpaceOnUse"
x1="1026.6899"
y1="2937.73"
x2="1463.14"
y2="2937.73" />
<linearGradient
id="linearGradient6765">
<stop
style="stop-color:#aac4dd;stop-opacity:1;"
offset="0"
id="stop6767" />
<stop
style="stop-color:#c2dbe9;stop-opacity:1;"
offset="1"
id="stop6769" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4453-7-8-6-7-3-5"
id="linearGradient10689-4-2"
gradientUnits="userSpaceOnUse"
x1="1026.6899"
y1="2937.73"
x2="1463.14"
y2="2937.73" />
<linearGradient
id="linearGradient6772">
<stop
style="stop-color:#aac4dd;stop-opacity:1;"
offset="0"
id="stop6774" />
<stop
style="stop-color:#c2dbe9;stop-opacity:1;"
offset="1"
id="stop6776" />
</linearGradient>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3369-1-5-6-1-0-7">
<path
inkscape:connector-curvature="0"
d="m 1131.64,3128.5 -104.95,-181.12 116.38,-200.42 208.05,0.94 112.02,191.63 -112.08,188.97 -219.42,0 z"
id="path3371-89-4-1-6-0-1" />
</clipPath>
<linearGradient
y2="2937.73"
x2="1463.14"
y1="2937.73"
x1="1026.6899"
gradientUnits="userSpaceOnUse"
id="linearGradient4498-5-7"
xlink:href="#linearGradient4453-7-8-6-7-3-5"
inkscape:collect="always" />
<linearGradient
id="linearGradient6781">
<stop
style="stop-color:#aac4dd;stop-opacity:1;"
offset="0"
id="stop6783" />
<stop
style="stop-color:#c2dbe9;stop-opacity:1;"
offset="1"
id="stop6785" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4459-1-2-8-9-9-5"
id="linearGradient10695-9-9"
gradientUnits="userSpaceOnUse"
x1="646.55499"
y1="2736.25"
x2="1088.27"
y2="2736.25" />
<linearGradient
id="linearGradient4459-1-2-8-9-9-5">
<stop
id="stop4461-2-1-5-2-5-0"
offset="0"
style="stop-color:#839bc2;stop-opacity:1;" />
<stop
id="stop4463-3-2-8-7-30-3"
offset="1"
style="stop-color:#9fb6d4;stop-opacity:1;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4459-1-2-8-9-9-5"
id="linearGradient10693-9-4"
gradientUnits="userSpaceOnUse"
x1="646.55499"
y1="2736.25"
x2="1088.27"
y2="2736.25" />
<linearGradient
id="linearGradient6792">
<stop
id="stop6794"
offset="0"
style="stop-color:#839bc2;stop-opacity:1;" />
<stop
id="stop6796"
offset="1"
style="stop-color:#9fb6d4;stop-opacity:1;" />
</linearGradient>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3351-4-7-3-5-95-0">
<path
inkscape:connector-curvature="0"
d="m 757.242,2926.25 -110.687,-189.11 110.656,-190.89 219.437,0 111.622,189.1 -111.59,190.9 -219.438,0 z"
id="path3353-1-9-3-4-1-1" />
</clipPath>
<linearGradient
y2="2736.25"
x2="1088.27"
y1="2736.25"
x1="646.55499"
gradientUnits="userSpaceOnUse"
id="linearGradient4510-1-5"
xlink:href="#linearGradient4459-1-2-8-9-9-5"
inkscape:collect="always" />
<linearGradient
id="linearGradient6801">
<stop
id="stop6803"
offset="0"
style="stop-color:#839bc2;stop-opacity:1;" />
<stop
id="stop6805"
offset="1"
style="stop-color:#9fb6d4;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#radialGradient3327-8-4-8-0-2-4"
id="radialGradient10699-1-3"
gradientUnits="userSpaceOnUse"
cx="997.46997"
cy="2896.25"
fx="997.46997"
fy="2896.25"
r="583.73999" />
<radialGradient
fx="0"
fy="0"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(58.375,0,0,-58.375,99.75,289.625)"
spreadMethod="pad"
id="radialGradient3327-8-4-8-0-2-4">
<stop
style="stop-opacity:1;stop-color:#aeaeb3"
offset="0"
id="stop3329-7-0-1-0-33-2" />
<stop
style="stop-opacity:1;stop-color:#ffffff"
offset="0.949438"
id="stop3331-4-3-0-0-97-3" />
<stop
style="stop-opacity:1;stop-color:#ffffff"
offset="1"
id="stop3333-2-4-9-7-2-2" />
</radialGradient>
<radialGradient
r="583.73999"
fy="2896.25"
fx="997.46997"
cy="2896.25"
cx="997.46997"
gradientUnits="userSpaceOnUse"
id="radialGradient13050"
xlink:href="#radialGradient3327-8-4-8-0-2-4"
inkscape:collect="always" />
<radialGradient
fx="0"
fy="0"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(58.375,0,0,-58.375,99.75,289.625)"
spreadMethod="pad"
id="radialGradient6813">
<stop
style="stop-opacity:1;stop-color:#aeaeb3"
offset="0"
id="stop6815" />
<stop
style="stop-opacity:1;stop-color:#ffffff"
offset="0.949438"
id="stop6817" />
<stop
style="stop-opacity:1;stop-color:#ffffff"
offset="1"
id="stop6819" />
</radialGradient>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3323-7-2-4-5-3-4">
<path
inkscape:connector-curvature="0"
d="m 997.469,2312.51 c -322.379,0 -583.739,261.36 -583.739,583.74 0,322.38 261.36,583.74 583.739,583.74 322.381,0 583.741,-261.36 583.741,-583.74 0,-322.38 -261.36,-583.74 -583.741,-583.74"
id="path3325-9-2-9-5-04-9" />
</clipPath>
<radialGradient
r="583.73999"
fy="2896.25"
fx="997.46997"
cy="2896.25"
cx="997.46997"
gradientUnits="userSpaceOnUse"
id="radialGradient4516-8-2"
xlink:href="#radialGradient3327-8-4-8-0-2-4"
inkscape:collect="always" />
<radialGradient
fx="0"
fy="0"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(58.375,0,0,-58.375,99.75,289.625)"
spreadMethod="pad"
id="radialGradient6824">
<stop
style="stop-opacity:1;stop-color:#aeaeb3"
offset="0"
id="stop6826" />
<stop
style="stop-opacity:1;stop-color:#ffffff"
offset="0.949438"
id="stop6828" />
<stop
style="stop-opacity:1;stop-color:#ffffff"
offset="1"
id="stop6830" />
</radialGradient>
<radialGradient
r="583.73999"
fy="2896.25"
fx="997.46997"
cy="2896.25"
cx="997.46997"
gradientUnits="userSpaceOnUse"
id="radialGradient6856"
xlink:href="#radialGradient3327-8-4-8-0-2-4"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="234.05635"
inkscape:cy="581.46313"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1680"
inkscape:window-height="982"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid3066" />
</sodipodi:namedview>
<metadata
id="metadata6863">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g3319-1-2-5-1-4-4"
transform="matrix(0.10419818,0,0,-0.10419818,137.10955,897.00327)"
style="fill:url(#radialGradient10699-1-3);fill-opacity:1"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523">
<g
clip-path="url(#clipPath3323-7-2-4-5-3-4)"
id="g3321-9-2-7-4-3-9"
style="fill:url(#radialGradient6856);fill-opacity:1">
<path
id="path3335-8-7-3-8-92-0"
style="fill:url(#radialGradient4516-8-2);fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 997.469,2312.51 c -322.379,0 -583.739,261.36 -583.739,583.74 0,322.38 261.36,583.74 583.739,583.74 322.381,0 583.741,-261.36 583.741,-583.74 0,-322.38 -261.36,-583.74 -583.741,-583.74"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g3347-6-8-3-7-4-4"
transform="matrix(0.125,0,0,-0.125,112.08304,959.82207)"
style="fill:url(#linearGradient10695-9-9);fill-opacity:1"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523">
<g
clip-path="url(#clipPath3351-4-7-3-5-95-0)"
id="g3349-5-5-4-7-9-4"
style="fill:url(#linearGradient10693-9-4);fill-opacity:1">
<path
id="path3361-0-8-2-9-0-9"
style="fill:url(#linearGradient4510-1-5);fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 757.242,2926.25 -110.687,-189.11 110.656,-190.89 219.437,0 111.622,189.1 -111.59,190.9 -219.438,0"
inkscape:connector-curvature="0" />
</g>
</g>
<path
id="path3363-6-9-0-1-5-8"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 194.34816,617.68335 13.106,-22.3925 25.99649,0 13.21487,22.60874 -13.21487,22.39125 -25.99649,0 -13.106,-22.60749 z m 40.53761,-24.8925 -28.86524,0 -0.72412,1.23749 -13.106,22.39251 -0.73575,1.25625 0.73087,1.26 13.106,22.60744 0.72263,1.24634 28.86374,0 0.72512,-1.22884 13.215,-22.39119 0.74625,-1.265 -0.74,-1.26751 -13.21537,-22.60875 -0.72313,-1.23874"
inkscape:connector-curvature="0"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523" />
<g
id="g3365-0-4-1-9-7-5"
transform="matrix(0.125,0,0,-0.125,112.08304,959.82207)"
style="fill:url(#linearGradient10691-7-8);fill-opacity:1"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523">
<g
clip-path="url(#clipPath3369-1-5-6-1-0-7)"
id="g3367-2-4-2-8-4-3"
style="fill:url(#linearGradient10689-4-2);fill-opacity:1">
<path
id="path3379-4-6-7-6-7-2"
style="fill:url(#linearGradient4498-5-7);fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 1131.64,3128.5 -104.95,-181.12 116.38,-200.42 208.05,0.94 112.02,191.63 -112.08,188.97 -219.42,0"
inkscape:connector-curvature="0" />
</g>
</g>
<path
id="path3381-6-8-0-0-66-3"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 241.86427,591.39959 12.3925,-21.38999 25.99625,0 13.27125,22.37625 -13.27125,22.7025 -24.56875,0.11 -13.82,-23.79876 z m 39.8125,-23.88999 -28.86125,0 -0.7225,1.24625 -12.3925,21.39 -0.72625,1.255 0.7275,1.25374 13.82,23.79876 0.7275,1.25125 1.44625,-0.006 24.56875,-0.11 1.4275,-0.006 0.72,-1.2325 13.27125,-22.7025 0.7425,-1.27 -0.75125,-1.26625 -13.27125,-22.37625 -0.72625,-1.225"
inkscape:connector-curvature="0"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523" />
<g
id="g3383-5-5-2-2-3-0"
transform="matrix(0.125,0,0,-0.125,112.08304,959.82207)"
style="fill:url(#linearGradient10687-2-5);fill-opacity:1"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523">
<g
clip-path="url(#clipPath3387-3-6-4-2-8-4)"
id="g3385-0-6-4-8-0-1"
style="fill:url(#linearGradient10685-2-2);fill-opacity:1">
<path
id="path3397-9-6-1-6-9-7"
style="fill:url(#linearGradient4492-8-8);fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 862.109,3289.75 -109.086,-190.45 69.122,-124.42 164.511,-0.47 c 0,0 111.044,188.28 116.564,197.63 7.66,0 43.03,0 43.03,0 l -67.03,117.71 -217.111,0"
inkscape:connector-curvature="0" />
</g>
</g>
<path
id="path3399-6-7-3-2-0-1"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 207.64603,572.41959 12.92424,-22.56624 25.68775,0 6.95625,12.21375 -3.94375,0 -14.56837,24.7025 -19.11525,-0.055 -7.94087,-14.295 z m 40.06574,-25.06624 -28.59012,0 -0.71975,1.2575 -12.92537,22.56625 -0.70112,1.22375 0.68512,1.23249 7.94137,14.295 0.71087,1.2825 1.46638,0.004 19.11525,0.055 1.43212,0.004 0.729,-1.23375 13.84375,-23.47249 6.81625,0 -2.12875,-3.7375 -6.95625,-12.21375 -0.71875,-1.2625"
inkscape:connector-curvature="0"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523" />
<g
transform="matrix(1.25,0,0,-1.25,105.02062,972.84257)"
id="g3465-0-8-9"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523">
<text
id="text3467-9-0-8"
transform="matrix(1,0,-0.17627963,-1,0,0)"
x="116.98372"
y="-267.77499"
style="font-size:11.81779194px">
<tspan
sodipodi:role="line"
style="font-size:46.39999771px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#49608a;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:Denmark;-inkscape-font-specification:Denmark"
x="116.98372"
y="-267.77499"
id="tspan13239">UTILITY</tspan>
<tspan
sodipodi:role="line"
style="font-size:46.39999771px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#49608a;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:Denmark;-inkscape-font-specification:Denmark"
x="116.98372"
y="-209.77499"
id="tspan11278-3" />
</text>
<text
id="text3471-0-51-2"
transform="matrix(0.99235617,0,-0.17763746,-1.0077027,0,0)"
style="font-size:38.40000153px"
x="112.74373"
y="-306.75479">
<tspan
id="tspan3473-6-0-9"
sodipodi:role="line"
style="font-size:38.40000153px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#49608a;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:Denmark;-inkscape-font-specification:Denmark"
x="112.74373"
y="-306.75479">boost</tspan>
</text>
</g>
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 201.43967,613.81579 4.64114,4.2175 3.3738,-3.71306 -0.92817,-0.84354 1.68708,-1.85636 20.53445,20.81026 4.2175,-4.64111 -22.22144,-18.95384 c 0,0 1.69594,-1.83698 2.53062,-2.78454 2.53905,-2.76559 5.98925,-4.72587 5.98925,-4.72587 0,0 -6.03647,0.58224 -8.76507,2.21476 -0.84428,0.92751 -6.75676,7.40649 -6.75676,7.40649 l -0.92819,-0.84355 -3.37382,3.71308"
id="path13283"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccc" />
<g
id="g3086"
transform="matrix(0.99872217,-0.05053738,0.05053738,0.99872217,-31.539183,11.181538)">
<path
sodipodi:nodetypes="ccccccccc"
inkscape:connector-curvature="0"
id="path13243"
d="m 227.74101,611.16418 -15.09943,12.783 2.55659,3.01989 15.09944,-12.78302 c 3.56324,2.16769 7.58975,-1.2411 7.0464,-5.96538 l -4.02652,3.40879 -2.55659,-3.01989 4.02652,-3.40879 c -3.56324,-2.16769 -8.59639,2.0933 -7.04641,5.9654 z"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="ccccccccc"
inkscape:connector-curvature="0"
id="path13243-1"
d="m 215.25729,626.9851 15.08951,-12.7947 -2.55893,-3.01791 -15.08952,12.79471 c -3.56492,-2.16491 -7.58878,1.24699 -7.04177,5.97085 l 4.02388,-3.41192 2.55892,3.01791 -4.02387,3.41192 c 3.56491,2.16492 8.59476,-2.09997 7.04178,-5.97086 z"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,234 @@
[/
Copyright (c) 2021, Alan Freitas
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Official repository: https://github.com/boostorg/utility
]
[/#############################################
DOCUMENT INFO
###############################################]
[library Boost.Utility
[id utility]
[quickbook 1.6]
[copyright 2001 Beman Dawes]
[purpose Utility Library]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
[@http://www.boost.org/LICENSE_1_0.txt])
]
[authors [Dawes, Beman]]
[category template]
[category generic]
]
[template mdash[]'''&mdash;''']
[template ndash[]'''&ndash;''']
[template sect[]'''&sect;''']
[template hellip[]'''&hellip;''']
[template indexterm1[term1]'''<indexterm><primary>'''[term1]'''</primary></indexterm>''']
[template indexterm2[term1 term2]'''<indexterm><primary>'''[term1]'''</primary><secondary>'''[term2]'''</secondary></indexterm>''']
[template include_file[path][^<'''<ulink url="https://github.com/boostorg/utility/blob/master/include/'''[path]'''">'''[path]'''</ulink>'''>]]
[template issue[n]'''<ulink url="https://github.com/boostorg/utility/issues/'''[n]'''">#'''[n]'''</ulink>''']
[/ Named Requirements ]
[def __Handler__ ['Handler]]
[def __Allocator__ [@https://en.cppreference.com/w/cpp/named_req/Allocator ['Allocator]]]
[def __CopyAssignable__ [@https://en.cppreference.com/w/cpp/named_req/CopyAssignable ['CopyAssignable]]]
[def __CopyConstructible__ [@https://en.cppreference.com/w/cpp/named_req/CopyConstructible ['CopyConstructible]]]
[def __Copyable__ [@https://en.cppreference.com/w/cpp/concepts/copyable ['Copyable]]]
[def __DefaultConstructible__ [@https://en.cppreference.com/w/cpp/named_req/DefaultConstructible ['DefaultConstructible]]]
[def __Hash__ [@https://en.cppreference.com/w/cpp/named_req/Hash ['Hash]]]
[def __InputIterator__ [@https://en.cppreference.com/w/cpp/named_req/InputIterator ['InputIterator]]]
[def __MoveAssignable__ [@https://en.cppreference.com/w/cpp/named_req/MoveAssignable ['MoveAssignable]]]
[def __MoveConstructible__ [@https://en.cppreference.com/w/cpp/named_req/MoveConstructible ['MoveConstructible]]]
[def __RandomAccessIterator__ [@https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator ['RandomAccessIterator]]]
[def __Regular__ [@https://en.cppreference.com/w/cpp/concepts/regular ['Regular]]]
[def __Swappable__ [@https://en.cppreference.com/w/cpp/named_req/Swappable ['Swappable]]]
[/ Boost types ]
[/ (Macros are defined here because these macros are often referenced in other components) ]
[/ (operators macros link to the a table of operators because there's no doxygen reference for the operators) ]
[def __BOOST_BINARY__ [link sec:BOOST_BINARY `BOOST_BINARY`]]
[def __in_place_factory__ [link sec:in_place_factory `in_place_factory`]]
[def __boost_base_from_member__ [link boost.base_from_member `boost::base_from_member`]]
[def __boost_call_traits__ [link boost.call_traits `boost::call_traits`]]
[def __boost_result_of__ [link boost.result_of `boost::result_of`]]
[def __boost_tr1_result_of__ [link boost.tr1_result_of `boost::tr1_result_of`]]
[def __boost_string_view__ [link boost.basic_string_view `boost::string_view`]]
[def __boost_basic_string_view__ [link boost.basic_string_view `boost::basic_string_view`]]
[def __additive1__ [link sec:arithmetic `additive1`]]
[def __additive2__ [link sec:arithmetic `additive2`]]
[def __arithmetic1__ [link sec:arithmetic `arithmetic1`]]
[def __arithmetic2__ [link sec:arithmetic `arithmetic2`]]
[def __base_from_member__ [link boost.base_from_member `base_from_member`]]
[def __basic_string_ref__ [link boost.basic_string_view `basic_string_ref`]]
[def __basic_string_view__ [link boost.basic_string_view `basic_string_view`]]
[def __bidirectional_iteratable__ [link sec:arithmetic `bidirectional_iteratable`]]
[def __bidirectional_iterator_helper__ [link sec:arithmetic `bidirectional_iterator_helper`]]
[def __bitwise1__ [link sec:arithmetic `bitwise1`]]
[def __bitwise2__ [link sec:arithmetic `bitwise2`]]
[def __call_traits__ [link boost.call_traits `call_traits`]]
[def __call_traits_T__ [link boost.call_traits `call_traits<T>`]]
[def __call_traits_lt__T___ [link boost.call_traits `call_traits<T&>`]]
[def __call_traits_lt__T_lb_N_rb__gt___ [link boost.call_traits `call_traits< T[N]>`]]
[def __call_traits_lt__const_T_lb_N_rb__gt___ [link boost.call_traits `call_traits< const T[N]>`]]
[def __compressed_pair__ [link boost.compressed_pair `compressed_pair`]]
[def __decrementable__ [link sec:arithmetic `decrementable`]]
[def __dereferenceable__ [link sec:arithmetic `dereferenceable`]]
[def __equal_pointees__ [link sec:arithmetic `equal_pointees`]]
[def __equal_pointees_t__ [link sec:arithmetic `equal_pointees_t`]]
[def __equality_comparable1__ [link sec:arithmetic `equality_comparable1`]]
[def __equality_comparable2__ [link sec:arithmetic `equality_comparable2`]]
[def __equivalent1__ [link sec:arithmetic `equivalent1`]]
[def __equivalent2__ [link sec:arithmetic `equivalent2`]]
[def __euclidean_ring_operators1__ [link sec:arithmetic `euclidean_ring_operators1`]]
[def __euclidean_ring_operators2__ [link sec:arithmetic `euclidean_ring_operators2`]]
[def __field_operators1__ [link sec:arithmetic `field_operators1`]]
[def __field_operators2__ [link sec:arithmetic `field_operators2`]]
[def __forward_iteratable__ [link sec:arithmetic `forward_iteratable`]]
[def __forward_iterator_helper__ [link sec:arithmetic `forward_iterator_helper`]]
[def __get__ [link boost.get `get`]]
[def __hash_range__ [link boost.hash_range `hash_range`]]
[def __hash_value__ [link boost.hash_value `hash_value`]]
[def __in_place_factory_base__ [link boost.in_place_factory_base `in_place_factory_base`]]
[def __incrementable__ [link sec:arithmetic `incrementable`]]
[def __indexable__ [link sec:arithmetic `indexable`]]
[def __initialized__ [link boost.initialized `initialized`]]
[def __initialized_value__ [link boost.initialized_value `initialized_value`]]
[def __initialized_value_t__ [link boost.initialized_value_t `initialized_value_t`]]
[def __input_iteratable__ [link sec:arithmetic `input_iteratable`]]
[def __input_iterator_helper__ [link sec:arithmetic `input_iterator_helper`]]
[def __integer_arithmetic1__ [link sec:arithmetic `integer_arithmetic1`]]
[def __integer_arithmetic2__ [link sec:arithmetic `integer_arithmetic2`]]
[def __integer_multiplicative1__ [link sec:arithmetic `integer_multiplicative1`]]
[def __integer_multiplicative2__ [link sec:arithmetic `integer_multiplicative2`]]
[def __is_chained_base__ [link sec:arithmetic `is_chained_base`]]
[def __less_pointees__ [link boost.less_pointees `less_pointees`]]
[def __less_pointees_t__ [link boost.less_pointees_t `less_pointees_t`]]
[def __less_than_comparable1__ [link sec:arithmetic `less_than_comparable1`]]
[def __less_than_comparable2__ [link sec:arithmetic `less_than_comparable2`]]
[def __multiplicative1__ [link sec:arithmetic `multiplicative1`]]
[def __multiplicative2__ [link sec:arithmetic `multiplicative2`]]
[def __operator_eq__eq__ [link sec:arithmetic `operator==`]]
[def __operator_gt__ [link sec:arithmetic `operator_gt_`]]
[def __operator_gt__eq__ [link sec:arithmetic `operator&gt;`]]
[def __operator_lt__ [link sec:arithmetic `operator&lt;`]]
[def __operator_lt__eq__ [link sec:arithmetic `operator&lt;=`]]
[def __operator_lt__lt__ [link sec:arithmetic `operator&lt;&lt;`]]
[def __operator_not__eq__ [link sec:arithmetic `operator!=`]]
[def __operators2__ [link sec:arithmetic `operators2`]]
[def __operators__ [link sec:arithmetic `operators`]]
[def __operators_lt_T__ [link sec:arithmetic `operators<T,T>`]]
[def __ordered_euclidean_ring_operators1__ [link sec:arithmetic `ordered_euclidean_ring_operators1`]]
[def __ordered_euclidean_ring_operators2__ [link sec:arithmetic `ordered_euclidean_ring_operators2`]]
[def __ordered_euclidian_ring_operators1__ [link sec:arithmetic `ordered_euclidian_ring_operators1`]]
[def __ordered_euclidian_ring_operators2__ [link sec:arithmetic `ordered_euclidian_ring_operators2`]]
[def __ordered_field_operators1__ [link sec:arithmetic `ordered_field_operators1`]]
[def __ordered_field_operators2__ [link sec:arithmetic `ordered_field_operators2`]]
[def __ordered_ring_operators1__ [link sec:arithmetic `ordered_ring_operators1`]]
[def __ordered_ring_operators2__ [link sec:arithmetic `ordered_ring_operators2`]]
[def __output_iteratable__ [link sec:arithmetic `output_iteratable`]]
[def __output_iterator_helper__ [link sec:arithmetic `output_iterator_helper`]]
[def __partially_ordered1__ [link sec:arithmetic `partially_ordered1`]]
[def __partially_ordered2__ [link sec:arithmetic `partially_ordered2`]]
[def __random_access_iteratable__ [link sec:arithmetic `random_access_iteratable`]]
[def __random_access_iterator_helper__ [link sec:arithmetic `random_access_iterator_helper`]]
[def __result_of__ [link boost.result_of `result_of`]]
[def __ring_operators1__ [link sec:arithmetic `ring_operators1`]]
[def __ring_operators2__ [link sec:arithmetic `ring_operators2`]]
[def __shiftable1__ [link sec:arithmetic `shiftable1`]]
[def __shiftable2__ [link sec:arithmetic `shiftable2`]]
[def __string_ref__ [link boost.basic_string_view `string_ref`]]
[def __string_view__ [link boost.basic_string_view `string_view`]]
[def __swap__ [link sec:arithmetic `swap`]]
[def __totally_ordered1__ [link sec:arithmetic `totally_ordered1`]]
[def __totally_ordered2__ [link sec:arithmetic `totally_ordered2`]]
[def __tr1_result_of__ [link boost.tr1_result_of `tr1_result_of`]]
[def __typed_in_place_factory_base__ [link boost.typed_in_place_factory_base `typed_in_place_factory_base`]]
[def __u16string_ref__ [link boost.basic_string_view `u16string_ref`]]
[def __u16string_view__ [link boost.basic_string_view `u16string_view`]]
[def __u32string_ref__ [link boost.basic_string_view `u32string_ref`]]
[def __u32string_view__ [link boost.basic_string_view `u32string_view`]]
[def __unit_steppable__ [link sec:arithmetic `unit_steppable`]]
[def __value_initialized__ [link boost.value_initialized `value_initialized`]]
[def __wstring_ref__ [link boost.basic_string_view `wstring_ref`]]
[def __wstring_view__ [link boost.basic_string_view `wstring_view`]]
[/ std:: types ]
[def __assert__ [@https://en.cppreference.com/w/cpp/error/assert `assert`]]
[def __decltype__ [@https://en.cppreference.com/w/cpp/language/decltype `decltype`]]
[def __initializer_list__ [@https://en.cppreference.com/w/cpp/utility/initializer_list `std::initializer_list`]]
[def __nullptr__ [@https://en.cppreference.com/w/cpp/language/nullptr `nullptr`]]
[def __std_addressof__ [@https://en.cppreference.com/w/cpp/memory/addressof `std::addressof`]]
[def __std_array__ [@https://en.cppreference.com/w/cpp/container/array `std::array`]]
[def __std_basic_string__ [@https://en.cppreference.com/w/cpp/string/basic_string `std::basic_string`]]
[def __std_basic_string_view__ [@https://en.cppreference.com/w/cpp/string/basic_string_view `std::basic_string_view`]]
[def __std_binder1st__ [@https://en.cppreference.com/w/cpp/utility/functional/binder12 `std::binder1st`]]
[def __std_complex__ [@https://en.cppreference.com/w/cpp/numeric/complex `std::complex`]]
[def __std_declval__ [@https://en.cppreference.com/w/cpp/utility/declval `std::declval`]]
[def __std_enable_if__ [@https://en.cppreference.com/w/cpp/types/enable_if `std::enable_if`]]
[def __std_enable_if_t__ [@https://en.cppreference.com/w/cpp/types/enable_if `std::enable_if_t`]]
[def __std_fill__ [@https://en.cppreference.com/w/cpp/algorithm/fill `std::fill`]]
[def __std_hash__ [@https://en.cppreference.com/w/cpp/utility/hash `std::hash`]]
[def __std_initializer_list__ [@https://en.cppreference.com/w/cpp/utility/initializer_list `std::initializer_list`]]
[def __std_is_nothrow_constructible__ [@https://en.cppreference.com/w/cpp/types/is_constructible `std::is_nothrow_constructible`]]
[def __std_make_pair__ [@https://en.cppreference.com/w/cpp/utility/pair/make_pair `std::make_pair`]]
[def __std_memory_resource__ [@https://en.cppreference.com/w/cpp/memory/memory_resource `std::pmr::memory_resource`]]
[def __std_memset__ [@https://en.cppreference.com/w/cpp/string/byte/memset `std::memset`]]
[def __std_next__ [@https://en.cppreference.com/w/cpp/iterator/next `std::next`]]
[def __std_nullptr_t__ [@https://en.cppreference.com/w/cpp/types/nullptr_t `std::nullptr_t`]]
[def __std_ostream__ [@https://en.cppreference.com/w/cpp/io/basic_ostream `std::ostream`]]
[def __std_ostream__ [@https://en.cppreference.com/w/cpp/io/basic_ostream `__std_ostream__`]]
[def __std_pair__ [@https://en.cppreference.com/w/cpp/utility/pair `std::pair`]]
[def __std_polymorphic_allocator__ [@https://en.cppreference.com/w/cpp/memory/polymorphic_allocator `std::pmr::polymorphic_allocator`]]
[def __std_prev__ [@https://en.cppreference.com/w/cpp/iterator/prev `std::prev`]]
[def __std_ptrdiff_t__ [@https://en.cppreference.com/w/cpp/types/ptrdiff_t `std::ptrdiff_t`]]
[def __std_remove__ [@https://en.cppreference.com/w/cpp/algorithm/remove `std::remove`]]
[def __std_result_of__ [@https://en.cppreference.com/w/cpp/types/result_of `std::result_of`]]
[def __std_sort__ [@https://en.cppreference.com/w/cpp/algorithm/sort `std::sort`]]
[def __std_streambuf__ [@https://en.cppreference.com/w/cpp/header/streambuf `std::streambuf`]]
[def __std_string__ [@https://en.cppreference.com/w/cpp/string/basic_string `std::string`]]
[def __std_string_view__ [@https://en.cppreference.com/w/cpp/string/basic_string_view `std::string_view`]]
[def __std_unary_function__ [@https://en.cppreference.com/w/cpp/utility/functional/unary_function `std::unary_function`]]
[def __std_unordered_map__ [@https://en.cppreference.com/w/cpp/container/unordered_map `std::unordered_map`]]
[def __std_uses_allocator__ [@https://en.cppreference.com/w/cpp/memory/uses_allocator `std::uses_allocator`]]
[def __std_vector__ [@https://en.cppreference.com/w/cpp/container/vector `std::vector`]]
[/ Dingbats ]
[def __good__ [role green \u2714]]
[def __bad__ [role red \u2718]]
[/-----------------------------------------------------------------------------]
[include overview.qbk]
[include utilities.qbk]
[include other.qbk]
[#sec:reference]
[section:ref Quick Reference]
[/ Reference table ]
[xinclude quickref.xml]
[/ Generated reference files ]
[/ [include reference.qbk] ]
[/ Generated index ]
[/ [xinclude index.xml] ]
[endsect]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
[/
Copyright (c) 2021 Alan de Freitas (alandefreitas@gmail.com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Official repository: https://github.com/boostorg/utility
]
[section:utilities More Utilities]
Some utilities have been moved from Boost.Utilities to more appropriate Boost libraries:
# Moved to [@boost:/libs/core/index.html Boost.Core]
# [@boost:/libs/core/doc/html/core/addressof.html addressof]
# [@boost:/libs/core/doc/html/core/checked_delete.html checked_delete]
# [@boost:/libs/core/doc/html/core/enable_if.html enable_if]
# [@boost:/libs/core/doc/html/core/noncopyable.html noncopyable]
# Moved to [@boost:/libs/type_traits/index.html Boost.TypeTraits]
# [@boost:/libs/type_traits/doc/html/boost_typetraits/reference/declval.html declval]
# Moved to [@boost:/libs/iterator/index.html Boost.Iterator]
# [@boost:/libs/iterator/doc/generator_iterator.htm generator iterator adaptors]
# [@boost:/libs/iterator/doc/html/iterator/algorithms/next_prior.html next/prior]
# Moved to [@boost:/libs/io/index.html Boost.IO]
# [@boost:/libs/io/doc/html/io.html ostream_string]
# Moved to [@boost:/libs/throw_exception/index.html Boost.ThrowException]
# [@boost:/libs/throw_exception/doc/html/throw_exception.html#using_boost_throw_exception throw_exception]
[endsect]

View File

@@ -0,0 +1,46 @@
[/
Copyright (c) 2021 Alan de Freitas (alandefreitas@gmail.com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Official repository: https://github.com/boostorg/utility
]
[section Overview]
[block'''<?dbhtml stop-chunking?>''']
Boost.Utility is a collection of small, useful, and general-purpose components for language support.
Over time,
* several components have been moved to more appropriate Boost libraries and
* many of these components had variants accepted into the C++ standard
When the component has moved to another Boost library, Boost.Utility headers still lead to the appropriate headers
in other libraries.
[table:id Components
[[Boost.Utility] [Moved to Boost] [C++ Standard variant]]
[[[@boost:/libs/core/doc/html/core/addressof.html `addressof`]] [[@boost:/libs/core/index.html Boost.Core]] [C++11 __std_addressof__]]
[[__base_from_member__] [] []]
[[__BOOST_BINARY__] [] [C++14 [@https://en.cppreference.com/w/cpp/language/integer_literal Binary integer literal]]]
[[__call_traits__] [] []]
[[[@boost:/libs/core/doc/html/core/checked_delete.html `checked_delete`]] [[@boost:/libs/core/index.html Boost.Core]] []]
[[__compressed_pair__] [] []]
[[[@boost:/libs/type_traits/doc/html/boost_typetraits/reference/declval.html `declval`]] [[@boost:/libs/type_traits/index.html Boost.TypeTraits]] [C++11 __std_declval__]]
[[[@boost:/libs/core/doc/html/core/enable_if.html `enable_if`]] [[@boost:/libs/core/index.html Boost.Core]] [C++11 __std_enable_if__]]
[[[@boost:/libs/iterator/doc/generator_iterator.htm generator iterator adaptors]] [[@boost:/libs/iterator/index.html Boost.Iterator]] []]
[[__in_place_factory__] [] []]
[[[@boost:/libs/iterator/index.html `iterator_adaptors`]] [[@boost:/libs/iterator/index.html Boost.Iterator]] []]
[[[@boost:/libs/iterator/doc/html/iterator/algorithms/next_prior.html `next` / `prior`]] [[@boost:/libs/iterator/index.html Boost.Iterator]] [C++11 __std_next__ / __std_prev__]]
[[[@boost:/libs/core/doc/html/core/noncopyable.html `noncopyable`]] [[@boost:/libs/core/index.html Boost.Core]] []]
[[[link sec:operators `operators`]] [] []]
[[[@boost:/libs/io/doc/html/io.html `ostream_string`]] [[@boost:/libs/io/index.html Boost.IO]] []]
[[__result_of__] [] [C++11 __std_result_of__]]
[[__string_view__] [] [C++17 __std_string_view__]]
[[[@boost:/libs/throw_exception/doc/html/throw_exception.html#using_boost_throw_exception `throw_exception`]] [[@boost:/libs/throw_exception/index.html Boost.ThrowException]] []]
[[[link sec:value_init `value_init`]] [] [C++11 [@https://en.cppreference.com/w/cpp/language/list_initialization List initialization]]]
]
[endsect]

View File

@@ -0,0 +1,497 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "../../../tools/boostbook/dtd/boostbook.dtd">
<!--
Copyright (c) 2021, Alan Freitas
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt
or copy at http://boost.org/LICENSE_1_0.txt
-->
<!-- See also https://tdg.docbook.org/tdg/5.1/ -->
<!-- Doxygen reference -->
<informaltable frame="all">
<tgroup cols="4">
<colspec colname="a"/>
<colspec colname="b"/>
<colspec colname="c"/>
<colspec colname="d"/>
<thead>
<row>
<entry valign="center" namest="a" nameend="a">
<bridgehead renderas="sect2">Base from Member</bridgehead>
</entry>
<entry valign="center" namest="b" nameend="b">
<bridgehead renderas="sect2">Call Traits</bridgehead>
</entry>
<entry valign="center" namest="c" nameend="c">
<bridgehead renderas="sect2">Compressed Pair</bridgehead>
</entry>
<entry valign="center" namest="d" nameend="d">
<bridgehead renderas="sect2">In-place Factory</bridgehead>
</entry>
</row>
</thead>
<tbody>
<row>
<!-- base_from_member -->
<entry valign="top">
<bridgehead renderas="sect3">Classes</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="boost.base_from_member">base_from_member</link>
</member>
</simplelist>
</entry>
<!-- call_traits -->
<entry valign="top">
<bridgehead renderas="sect3">Type Traits</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="boost.call_traits">call_traits</link>
</member>
<member>
<link linkend="boost.call_traits">call_traits&lt;T&amp;&gt;</link>
</member>
<member>
<link linkend="boost.call_traits">call_traits&lt;T[N]&gt;
</link>
</member>
<member>
<link linkend="boost.call_traits">call_traits&lt;const
T[N]&gt;
</link>
</member>
</simplelist>
</entry>
<!-- compressed_pair -->
<entry valign="top">
<bridgehead renderas="sect3">Classes</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="boost.compressed_pair">compressed_pair</link>
</member>
</simplelist>
<bridgehead renderas="sect3">Functions</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="header.boost.detail.compressed_pair_hpp">swap</link>
</member>
</simplelist>
</entry>
<!-- in_place_factory -->
<entry valign="top">
<bridgehead renderas="sect3">Classes</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="boost.in_place_factory_base">in_place_factory_base</link>
</member>
<member>
<link linkend="boost.typed_in_place_factory_base">typed_in_place_factory_base
</link>
</member>
</simplelist>
</entry>
</row>
</tbody>
</tgroup>
<tgroup cols="5">
<colspec colname="a"/>
<colspec colname="b"/>
<colspec colname="c"/>
<colspec colname="d"/>
<colspec colname="e"/>
<thead>
<row>
<entry valign="center" namest="a" nameend="e">
<bridgehead renderas="sect2">Operators</bridgehead>
</entry>
</row>
</thead>
<tbody>
<row>
<entry valign="top">
<!-- 13 classes per cell -->
<bridgehead renderas="sect3">Classes (1 of 5)</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="sec:arithmetic">additive1</link>
</member>
<member>
<link linkend="sec:arithmetic">additive2</link>
</member>
<member>
<link linkend="sec:arithmetic">arithmetic1</link>
</member>
<member>
<link linkend="sec:arithmetic">arithmetic2</link>
</member>
<member>
<link linkend="sec:arithmetic">bidirectional_iteratable</link>
</member>
<member>
<link linkend="sec:arithmetic">
bidirectional_iterator_helper
</link>
</member>
<member>
<link linkend="sec:arithmetic">bitwise1</link>
</member>
<member>
<link linkend="sec:arithmetic">bitwise2</link>
</member>
<member>
<link linkend="sec:arithmetic">decrementable</link>
</member>
<member>
<link linkend="sec:arithmetic">dereferenceable</link>
</member>
<member>
<link linkend="sec:arithmetic">equality_comparable1</link>
</member>
<member>
<link linkend="sec:arithmetic">equality_comparable2</link>
</member>
<member>
<link linkend="sec:arithmetic">equivalent1</link>
</member>
</simplelist>
</entry>
<entry valign="top">
<bridgehead renderas="sect3">Classes (2 of 5)</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="sec:arithmetic">equivalent2</link>
</member>
<member>
<link linkend="sec:arithmetic">euclidean_ring_operators1
</link>
</member>
<member>
<link linkend="sec:arithmetic">euclidean_ring_operators2
</link>
</member>
<member>
<link linkend="sec:arithmetic">field_operators1</link>
</member>
<member>
<link linkend="sec:arithmetic">field_operators2</link>
</member>
<member>
<link linkend="sec:arithmetic">forward_iteratable</link>
</member>
<member>
<link linkend="sec:arithmetic">forward_iterator_helper</link>
</member>
<member>
<link linkend="sec:arithmetic">incrementable</link>
</member>
<member>
<link linkend="sec:arithmetic">indexable</link>
</member>
<member>
<link linkend="sec:arithmetic">input_iteratable</link>
</member>
<member>
<link linkend="sec:arithmetic">input_iterator_helper</link>
</member>
<member>
<link linkend="sec:arithmetic">integer_arithmetic1</link>
</member>
<member>
<link linkend="sec:arithmetic">integer_arithmetic2</link>
</member>
</simplelist>
</entry>
<entry valign="top">
<bridgehead renderas="sect3">Classes (3 of 5)</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="sec:arithmetic">integer_multiplicative1</link>
</member>
<member>
<link linkend="sec:arithmetic">integer_multiplicative2</link>
</member>
<member>
<link linkend="sec:arithmetic">is_chained_base</link>
</member>
<member>
<link linkend="sec:arithmetic">less_than_comparable1</link>
</member>
<member>
<link linkend="sec:arithmetic">less_than_comparable2</link>
</member>
<member>
<link linkend="sec:arithmetic">multiplicative1</link>
</member>
<member>
<link linkend="sec:arithmetic">multiplicative2</link>
</member>
<member>
<link linkend="sec:arithmetic">operators</link>
</member>
<member>
<link linkend="sec:arithmetic">operators2</link>
</member>
<member>
<link linkend="sec:arithmetic">operators&lt;T,T&gt;</link>
</member>
<member>
<link linkend="sec:arithmetic">
ordered_euclidean_ring_operators1
</link>
</member>
<member>
<link linkend="sec:arithmetic">
ordered_euclidean_ring_operators2
</link>
</member>
<member>
<link linkend="sec:arithmetic">
ordered_euclidian_ring_operators1
</link>
</member>
</simplelist>
</entry>
<entry valign="top">
<bridgehead renderas="sect3">Classes (4 of 5)</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="sec:arithmetic">
ordered_euclidian_ring_operators2
</link>
</member>
<member>
<link linkend="sec:arithmetic">ordered_field_operators1</link>
</member>
<member>
<link linkend="sec:arithmetic">ordered_field_operators2</link>
</member>
<member>
<link linkend="sec:arithmetic">ordered_ring_operators1</link>
</member>
<member>
<link linkend="sec:arithmetic">ordered_ring_operators2</link>
</member>
<member>
<link linkend="sec:arithmetic">output_iteratable</link>
</member>
<member>
<link linkend="sec:arithmetic">output_iterator_helper</link>
</member>
<member>
<link linkend="sec:arithmetic">partially_ordered1</link>
</member>
<member>
<link linkend="sec:arithmetic">partially_ordered2</link>
</member>
<member>
<link linkend="sec:arithmetic">random_access_iteratable</link>
</member>
<member>
<link linkend="sec:arithmetic">
random_access_iterator_helper
</link>
</member>
<member>
<link linkend="sec:arithmetic">ring_operators1</link>
</member>
<member>
<link linkend="sec:arithmetic">ring_operators2</link>
</member>
</simplelist>
</entry>
<entry valign="top">
<bridgehead renderas="sect3">Classes (5 of 5)</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="sec:arithmetic">shiftable1</link>
</member>
<member>
<link linkend="sec:arithmetic">shiftable2</link>
</member>
<member>
<link linkend="sec:arithmetic">totally_ordered1</link>
</member>
<member>
<link linkend="sec:arithmetic">totally_ordered2</link>
</member>
<member>
<link linkend="sec:arithmetic">unit_steppable</link>
</member>
</simplelist>
<bridgehead renderas="sect3">Type Traits</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="sec:arithmetic">is_chained_base</link>
</member>
</simplelist>
</entry>
</row>
</tbody>
</tgroup>
<tgroup cols="5">
<colspec colname="a"/>
<colspec colname="b"/>
<colspec colname="c"/>
<colspec colname="d"/>
<colspec colname="e"/>
<thead>
<row>
<entry valign="center" namest="a" nameend="a">
<bridgehead renderas="sect2">Result of</bridgehead>
</entry>
<entry valign="center" namest="b" nameend="d">
<bridgehead renderas="sect2">String View</bridgehead>
</entry>
<entry valign="center" namest="e" nameend="e">
<bridgehead renderas="sect2">Value Init</bridgehead>
</entry>
</row>
</thead>
<tbody>
<row>
<!-- result_of -->
<entry valign="top">
<bridgehead renderas="sect3">Type Traits</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="boost.result_of">result_of</link>
</member>
<member>
<link linkend="boost.tr1_result_of">tr1_result_of</link>
</member>
</simplelist>
</entry>
<!-- string_view -->
<entry valign="top">
<bridgehead renderas="sect3">Aliases</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="boost.basic_string_view">string_view</link>
</member>
<member>
<link linkend="boost.basic_string_view">u16string_ref</link>
</member>
<member>
<link linkend="boost.basic_string_view">u16string_view</link>
</member>
<member>
<link linkend="boost.basic_string_view">u32string_ref</link>
</member>
<member>
<link linkend="boost.basic_string_view">u32string_view</link>
</member>
<member>
<link linkend="boost.basic_string_view">wstring_ref</link>
</member>
<member>
<link linkend="boost.basic_string_view">wstring_view</link>
</member>
<member>
<link linkend="boost.basic_string_view">string_ref</link>
</member>
</simplelist>
</entry>
<entry valign="top">
<bridgehead renderas="sect3">Classes</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="boost.basic_string_view">basic_string_ref</link>
</member>
<member>
<link linkend="boost.basic_string_view">basic_string_view</link>
</member>
</simplelist>
<bridgehead renderas="sect3">Functions</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="boost.hash_range">hash_range</link>
</member>
<member>
<link linkend="boost.hash_value">hash_value</link>
</member>
</simplelist>
</entry>
<entry valign="top">
<bridgehead renderas="sect3">Operators</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="header.boost.utility.string_view_hpp">operator==</link>
</member>
<member>
<link linkend="header.boost.utility.string_view_hpp">operator!=</link>
</member>
<member>
<link linkend="header.boost.utility.string_view_hpp">operator&lt;</link>
</member>
<member>
<link linkend="header.boost.utility.string_view_hpp">operator&lt;=</link>
</member>
<member>
<link linkend="header.boost.utility.string_view_hpp">operator&gt;</link>
</member>
<member>
<link linkend="header.boost.utility.string_view_hpp">operator&gt;=</link>
</member>
<member>
<link linkend="header.boost.utility.string_view_hpp">operator&lt;&lt;</link>
</member>
</simplelist>
</entry>
<!-- value_init -->
<entry valign="top">
<bridgehead renderas="sect3">Classes</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="boost.initialized">initialized</link>
</member>
<member>
<link linkend="boost.initialized_value_t">initialized_value_t</link>
</member>
<member>
<link linkend="boost.value_initialized">value_initialized</link>
</member>
</simplelist>
<bridgehead renderas="sect3">Functions</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="header.boost.utility.value_init_hpp">get</link>
</member>
<member>
<link linkend="header.boost.utility.value_init_hpp">swap</link>
</member>
</simplelist>
<bridgehead renderas="sect3">Constants</bridgehead>
<simplelist type="vert" columns="1">
<member>
<link linkend="boost.initialized_value">initialized_value</link>
</member>
</simplelist>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>

View File

@@ -0,0 +1,421 @@
[/
/ Copyright (c) 2012 Marshall Clow
/ Copyright (c) 2021, Alan Freitas
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[/===============]
[section Result of]
[/===============]
[section Introduction]
The class template __result_of__ helps determine the type of a
call expression. For example, given an lvalue `f` of type `F`
and lvalues `t1`,`t2`, ..., `tN` of types `T1`, `T2`, ..., `TN`,
respectively, the type __result_of__`<F(T1, T2, ..., TN)>::type` defines
the result type of the expression `f(t1, t2, ...,tN)`.
This implementation permits the type `F` to be a function pointer,
function reference, member function pointer, or class type. By default,
N may be any value between 0 and 16. To change the upper limit, define
the macro `BOOST_RESULT_OF_NUM_ARGS` to the maximum value for N. Class
template __result_of__ resides in the header
[@../../../../boost/utility/result_of.hpp `<boost/utility/result_of.hpp>`].
If your compiler's support for __decltype__ is adequate, __result_of__
automatically uses it to deduce the type of the call expression, in
which case __result_of__`<F(T1, T2, ..., TN)>::type` names the type
__decltype__`(boost::declval<F>()(boost::declval<T1>(),
boost::declval<T2>(), ..., boost::declval<TN>()))`, as in the
following example.
```
struct functor {
template<class T>
T operator()(T x)
{
return x;
}
};
typedef __boost_result_of__<functor(int)>::type type; // type is int
```
You can test whether __result_of__ is using __decltype__ by checking if
the macro `BOOST_RESULT_OF_USE_DECLTYPE` is defined after
including `result_of.hpp`. You can also force __result_of__ to use
__decltype__ by defining `BOOST_RESULT_OF_USE_DECLTYPE` prior
to including `result_of.hpp`.
If __decltype__ is not used, then automatic result type deduction of function
objects is not possible. Instead, __result_of__ uses the following protocol
to allow the programmer to specify a type. When `F` is a class type with a
member type `result_type`, `result_of<F(T1, T2, ..., TN)>::type` is
`F::result_type`. When `F` does not contain `result_type`,
`result_of<F(T1, T2, ..., TN)>::type` is
`F::result<F(T1, T2, ..., TN)>::type` when
`N > 0` or `void` when `N = 0`.
Note that it is the responsibility of the programmer to ensure that
function objects accurately advertise their result
type via this protocol, as in the following example.
```
struct functor {
template <class> struct result;
template<class F, class T>
struct result<F(T)> {
typedef T type;
};
template<class T>
T operator()(T x)
{
return x;
}
};
typedef __boost_result_of__<functor(int)>::type type; // type is int
```
Since __decltype__ is a language feature standardized in C++11, if you are
writing a function object to be used with __result_of__, for maximum
portability, you might consider following the above protocol
even if your compiler has proper __decltype__ support.
If you wish to continue to use the protocol on compilers that
support __decltype__, there are two options:
* You can use __boost_tr1_result_of__, which is also defined in
[@../../../boost/utility/result_of.hpp `<boost/utility/result_of.hpp>`].
* Alternatively, you can define the macro `BOOST_RESULT_OF_USE_TR1`,
which causes __result_of__ to use the protocol described above instead
of __decltype__. If you choose to follow the protocol, take care to
ensure that the `result_type` and `result<>` members accurately
represent the return type of `operator()` given a call expression.
Additionally, __boost_result_of__ provides a third mode of operation,
which some users may find convenient. When
`BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK` is defined,
__boost_result_of__ behaves as follows. If the function object has a member
type `result_type` or member template `result<>`, then __boost_result_of__
will use the TR1 protocol.
Otherwise, __boost_result_of__ will use __decltype__. Using TR1 with
a __decltype__ fallback may workaround certain problems at the cost of portability.
For example:
* Deficient compiler: If your code requires __boost_result_of__ to work
with incomplete return types but your compiler's __decltype__ implementation
does not support incomplete return types, then you can use the TR1 protocol
as a workaround. Support for incomplete return types was added late in the
C++11 standardization process
(see [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf N3276])
and is not implemented by some compilers.
* Deficient legacy code: If your existing TR1 function object advertises a different type than
the actual result type deduced by __decltype__, then using TR1 with a __decltype__ fallback
will allow you to work with both your existing TR1 function objects and new C++11
function object. This situation could occur if your legacy function objects
misused the TR1 protocol. See the documentation on known [link sec:result_of_tr1_diff differences]
between __boost_result_of__ and TR1.
* [#BOOST_NO_RESULT_OF] This implementation of __result_of__ requires class template
partial specialization, the ability to parse function types properly, and support
for SFINAE. If __result_of__ is not supported by your compiler, including the header
[@../../../boost/utility/result_of.hpp `<boost/utility/result_of.hpp>`] will define
the macro `BOOST_NO_RESULT_OF`.
For additional information about __result_of__, see the C++ Library
Technical Report, [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf N1836],
or, for motivation and design rationale, the __result_of__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html proposal].
[endsect]
[#sec:result_of_guidelines]
[section Usage guidelines for __boost_result_of__]
The following are general suggestions about when and how to use __boost_result_of__.
# If you are targeting C++11 and are not concerned about portability to
non-compliant compilers or previous versions of the standard, then use
`__std_result_of__`. If `__std_result_of__` meets your needs, then
there's no reason to stop using it.
# If you are targeting C++11 but may port your code to legacy compilers
at some time in the future, then use __boost_result_of__ with __decltype__.
When __decltype__ is used __boost_result_of__ and `__std_result_of__` are usually
interchangeable. See the documentation on known [link sec:result_of_cxx11_diff differences]
between __boost_result_of__ and C++11 __std_result_of__.
# If compiler portability is required, use __boost_result_of__ with the TR1 protocol
Regardless of how you configure __boost_result_of__, it is
important to bear in mind that the return type of a
function may change depending on its arguments, and
additionally, the return type of a member function may
change depending on the cv-qualification of the
object. __boost_result_of__ must be passed
the appropriately cv-qualified types in order to
deduce the corresponding return type.
For example:
```
struct functor {
int& operator()(int);
int const& operator()(int) const;
float& operator()(float&);
float const& operator()(float const&);
};
typedef __boost_result_of__<
functor(int)
>::type type1; // type1 is int &
typedef __boost_result_of__<
const functor(int)
>::type type2; // type2 is int const &
typedef __boost_result_of__<
functor(float&)
>::type type3; // type3 is float &
typedef __boost_result_of__<
functor(float const&)
>::type type4; // type4 is float const &
```
[endsect]
[#sec:result_of_tr1_protocol_guidelines]
[section Usage guidelines for the TR1 result_of protocol]
On compliant C++11 compilers, __boost_result_of__ can
use __decltype__ to deduce the type of any
call expression, including calls to function
objects. However, on pre-C++11 compilers or on
compilers without adequate decltype support,
additional scaffolding is needed from function
objects as described above. The following are
suggestions about how to use the TR1 protocol.
* When the return type does not depend on the
argument types or the cv-qualification of the
function object, simply
define `result_type`. There is no need
to use the `result` template unless the
return type varies.</li>
* Use the protocol specified type when defining
function prototypes. This can help ensure the
actual return type does not get out of sync with
the protocol specification. For example:
```
struct functor {
typedef int result_type;
result_type operator()(int);
};
```
* Always specify the `result` specialization near the corresponding
`operator()` overload. This can make it easier to keep the specializations
in sync with the overloads. For example:
```
struct functor {
template<class> struct result;
template<class F>
struct result<F(int)> {
typedef int& type;
};
result<functor(int)>::type operator()(int);
template<class F>
struct result<const F(int)> {
typedef int const& type;
};
result<const functor(int)>::type operator()(int) const;
};
```
* Use type transformations to simplify
the `result` template specialization. For
example, the following uses [@../type_traits/doc/html/index.html Boost.TypeTraits]
to specialize the `result` template for
a single `operator()` that can be called on
both a const and non-const function object with
either an lvalue or rvalue argument.
```
struct functor {
template<class> struct result;
template<class F, class T>
struct result<F(T)>
: boost::remove_cv<
typename boost::remove_reference<T>::type
>
{};
template<class T>
T operator()(T const&amp; x) const;
};
```
[endsect]
[#sec:result_of_tr1_diff]
[section Known differences between __boost_result_of__ and __boost_tr1_result_of__]
When using __decltype__, __boost_result_of__ ignores the TR1 protocol and instead deduces the
return type of function objects directly via __decltype__. In most situations, users
will not notice a difference, so long as they use the protocol correctly. The following are situations in
which the type deduced by __boost_result_of__ is known to differ depending on whether
__decltype__ or the TR1 protocol is used.
TR1 protocol misusage: When using the TR1 protocol, __boost_result_of__ cannot
detect whether the actual type of a call to a function object is the same as the
type specified by the protocol, which allows for the possibility of inadvertent
mismatches between the specified type and the actual type. When using __decltype__,
these subtle bugs may result in compilation errors. For example:
```
struct functor {
typedef short result_type;
int operator()(short);
};
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
BOOST_STATIC_ASSERT((
boost::is_same<__boost_result_of__<functor(short)>::type, int>::value
));
#else
BOOST_STATIC_ASSERT((
boost::is_same<__boost_result_of__<functor(short)>::type, short>::value
));
#endif
```
Note that the user can force __boost_result_of__ to use the TR1
protocol even on platforms that support __decltype__ by
defining `BOOST_RESULT_OF_USE_TR1`.
Nullary function objects: When using the TR1 protocol, __boost_result_of__
cannot always deduce the type of calls to nullary function objects, in which case the
type defaults to void. When using __decltype__, __boost_result_of__ always gives the
actual type of the call expression. For example:
```
struct functor {
template<class> struct result {
typedef int type;
};
int operator()();
};
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
BOOST_STATIC_ASSERT((
boost::is_same<__boost_result_of__<functor()>::type, int>::value
));
#else
BOOST_STATIC_ASSERT((
boost::is_same<__boost_result_of__<functor()>::type, void>::value
));
#endif
```
Note that there are some workarounds for the nullary function problem.
So long as the return type does not vary, `result_type` can always be used to
specify the return type regardless of arity. If the return type does vary,
then the user can specialize __boost_result_of__ itself for nullary calls.
Non-class prvalues and cv-qualification: When using the TR1 protocol, __boost_result_of__ will
report the cv-qualified type specified by `result_type` or the `result` template regardless of
the actual cv-qualification of the call expression. When using __decltype__, __boost_result_of__
will report the actual type of the call expression, which is not cv-qualified when the expression
is a non-class prvalue. For example:
```
struct functor {
template<class> struct result;
template<class F, class T> struct result<F(const T)> {
typedef const T type;
};
const short operator()(const short);
int const & operator()(int const &);
};
// Non-prvalue call expressions work the same with or without decltype.
BOOST_STATIC_ASSERT((
boost::is_same<
__boost_result_of__<functor(int const &)>::type,
int const &
::value
));
// Non-class prvalue call expressions are not actually cv-qualified,
// but only the decltype-based result_of reports this accurately.
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
BOOST_STATIC_ASSERT((
boost::is_same<
__boost_result_of__<functor(const short)>::type,
short
::value
));
#else
BOOST_STATIC_ASSERT((
boost::is_same<
__boost_result_of__<functor(const short)>::type,
const short
::value
));
#endif
```
[endsect]
[#sec:result_of_cxx11_diff]
[section Known differences between __boost_result_of__ and C++11 result_of]
When using __decltype__, __boost_result_of__ implements most of the C++11 __std_result_of__
specification. One known exception is that __boost_result_of__ does not implement the
requirements regarding pointers to member data.
[endsect]
[/===============]
[xinclude tmp/result_of_reference.xml]
[/===============]
[section Acknowledgments]
Created by Doug Gregor. Contributions from Daniel Walker, Eric Niebler, Michel Morin and others.
[endsect]
[endsect]

View File

@@ -0,0 +1,209 @@
[/
/ Copyright (c) 2012 Marshall Clow
/ Copyright (c) 2021, Alan Freitas
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[/===============]
[section String View]
[/===============]
[section Introduction]
The class __boost_string_view__ and other classes derived from __basic_string_view__ represent references to strings or substrings. When you are parsing/processing strings from some external source, frequently you want to pass a piece of text to a procedure for specialized processing. Before __std_string_view__, the canonical way to do this used to be a __std_string__, but that has certain drawbacks:
1) If you are processing a buffer of text (say a HTTP response or the contents of a file), then you have to create the string from the text you want to pass, which involves memory allocation and copying of data.
2) If a routine receives a constant __std_string__ and wants to pass a portion of that string to another routine, then it must create a new string of that substring.
3) If a routine receives a constant __std_string__ and wants to return a portion of the string, then it must create a new string to return.
__boost_string_view__ is designed to solve these efficiency problems. A __boost_string_view__ is a read-only reference to a contiguous sequence of characters, and provides much of the functionality of __std_string__. A __boost_string_view__ is cheap to create, copy and pass by value, because it does not actually own the storage that it points to.
A __boost_string_view__ is implemented as a small struct that contains a pointer to the start of the character `data` and a `count`. A __boost_string_view__ is cheap to create and cheap to copy.
__boost_string_view__ acts as a container; it includes all the methods that you would expect in a container, including iteration support, `operator[]`, `at` and `size`. It can be used with any of the iterator-based algorithms in the STL - as long as you do not need to change the underlying data. For example, __std_sort__ and __std_remove__ will not work.
Besides generic container functionality, __boost_string_view__ provides a subset of the interface of __std_string__. This makes it easy to replace parameters of type `const __std_string__ &` with __boost_string_view__. Like __std_string__, __boost_string_view__ has a static member variable named `npos` to denote the result of failed searches, and to mean "the end".
[caution Because a __boost_string_view__ does not own the data that it refers to, it introduces lifetime issues into code that uses it. The programmer must ensure that the data that a __string_view__ refers to exists as long as the __string_view__ does.]
[note
Boost.Utility also includes the class __string_ref__:
- __string_ref__ is the initial implementation of Jeffrey Yaskin's [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html N3442:
string_ref: a non-owning reference to a string].
- __string_view__ is an updated implementation to reflect the Library Fundamentals TS [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html N4480: \[string.view\]].
Please prefer __string_view__ / __basic_string_view__ over __string_ref__ / __basic_string_ref__:
- The __basic_string_view__ class better matches __std_basic_string_view__.
- __basic_string_view__ has WAY more constexpr support.
- Code that uses __basic_string_ref__ should continue to work.
- Not much code depends on __basic_string_ref__ anymore.
]
[endsect]
[/===============]
[section Examples]
[/===============]
Integrating __string_view__ into your code is fairly simple. Wherever you pass a `const __std_string__ &` or __std_string__ as a parameter, that's a candidate for passing a __boost_string_view__.
```
__std_string__ extract_part ( const __std_string__ &bar ) {
return bar.substr ( 2, 3 );
}
if ( extract_part ( "ABCDEFG" ).front() == 'C' ) { /* do something */ }
```
Let's figure out what happens in this contrived example.
* First, a temporary string is created from the string literal `"ABCDEFG"`, and it is passed (by reference) to the routine `extract_part`.
* Then a second string is created in the call `__std_string__::substr` and returned to `extract_part` (this copy may be elided by RVO).
* Then `extract_part` returns that string back to the caller (again this copy may be elided).
* The first temporary string is deallocated, and `front` is called on the second string, and then it is deallocated as well.
Two __std_string__ s are created, and two copy operations. That is potentially four memory allocations and deallocations, and the associated copying of data.
Now let's look at the same code with __string_view__:
```
__boost_string_view__ extract_part ( __boost_string_view__ bar ) {
return bar.substr ( 2, 3 );
}
if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ }
```
No memory allocations. No copying of character data. No changes to the code other than the types. There are two __string_view__ s created, and two __string_view__ s copied, but those are cheap operations.
[endsect]
[/=================]
[section:reference Synopsis]
[/=================]
The header file [@../../../../boost/utility/string_view.hpp `<boost/utility/string_view.hpp>`] defines a template __boost_basic_string_view__, and four specializations __string_view__, __wstring_view__, __u16string_view__, __u32string_view__ - for `char` / `wchar_t` / `char16_t` / `char32_t`.
`#include <boost/utility/string_view.hpp>`
Construction and copying:
```
constexpr basic_string_view (); // Constructs an empty string_view
constexpr basic_string_view(const charT* str); // Constructs from a NULL-terminated string
constexpr basic_string_view(const charT* str, size_type len); // Constructs from a pointer, length pair
template<typename Allocator>
basic_string_view(const __std_basic_string__<charT, traits, Allocator>& str); // Constructs from a std::string
basic_string_view (const basic_string_view &rhs);
basic_string_view& operator=(const basic_string_view &rhs);
```
__string_view__ does not define a move constructor nor a move-assignment operator because copying a __string_view__ is just a cheap as moving one.
Basic container-like functions:
```
constexpr size_type size() const ;
constexpr size_type length() const ;
constexpr size_type max_size() const ;
constexpr bool empty() const ;
// All iterators are const_iterators
constexpr const_iterator begin() const ;
constexpr const_iterator cbegin() const ;
constexpr const_iterator end() const ;
constexpr const_iterator cend() const ;
const_reverse_iterator rbegin() const ;
const_reverse_iterator crbegin() const ;
const_reverse_iterator rend() const ;
const_reverse_iterator crend() const ;
```
Access to the individual elements (all of which are const):
```
constexpr const charT& operator[](size_type pos) const ;
const charT& at(size_t pos) const ;
constexpr const charT& front() const ;
constexpr const charT& back() const ;
constexpr const charT* data() const ;
```
Modifying the __string_view__ (but not the underlying data):
```
void clear();
void remove_prefix(size_type n);
void remove_suffix(size_type n);
```
Searching:
```
size_type find(basic_string_view s) const ;
size_type find(charT c) const ;
size_type rfind(basic_string_view s) const ;
size_type rfind(charT c) const ;
size_type find_first_of(charT c) const ;
size_type find_last_of (charT c) const ;
size_type find_first_of(basic_string_view s) const ;
size_type find_last_of(basic_string_view s) const ;
size_type find_first_not_of(basic_string_view s) const ;
size_type find_first_not_of(charT c) const ;
size_type find_last_not_of(basic_string_view s) const ;
size_type find_last_not_of(charT c) const ;
```
String-like operations:
```
constexpr basic_string_view substr(size_type pos, size_type n=npos) const ; // Creates a new string_view
bool starts_with(charT c) const ;
bool starts_with(basic_string_view x) const ;
bool ends_with(charT c) const ;
bool ends_with(basic_string_view x) const ;
```
[endsect]
[/===============]
[section History]
[/===============]
[h5 boost 1.71]
* Glen Fernandes updated the implementation of the stream insertion operator to
write directly to the `basic_streambuf` and refactored that functionality into
a common utility.
[h5 boost 1.53]
* Introduced
[endsect]
[/===============]
[xinclude tmp/string_view_reference.xml]
[/===============]
[/===============]
[section Acknowledgments]
[/===============]
Author: Clow, Marshall
Copyright 2012 Marshall Clow
[endsect]
[endsect]

View File

@@ -0,0 +1,2 @@
*.qbk
*.xml

View File

@@ -0,0 +1,32 @@
[/
Copyright (c) 2021 Alan de Freitas (alandefreitas@gmail.com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Official repository: https://github.com/boostorg/utility
]
[section:utilities Utilities]
The entire contents of Boost.Utility are in `namespace boost`.
[warning
Direct use of the header [@../../../../boost/utility.hpp `<boost/utility.hpp>`] is discouraged and it will be deprecated.
Please include the headers relative to individual components instead.
]
[include base_from_member.qbk]
[include BOOST_BINARY.qbk]
[include call_traits.qbk]
[include compressed_pair.qbk]
[include in_place_factory.qbk]
[include operators.qbk]
[include result_of.qbk]
[include string_view.qbk]
[include value_init.qbk]
[endsect]

View File

@@ -0,0 +1,584 @@
[/
/ Copyright (c) 2012 Marshall Clow
/ Copyright (c) 2021, Alan Freitas
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[/===============]
[#sec:value_init]
[section Value Init]
[/===============]
[section Introduction]
Constructing and initializing objects in a generic way is difficult in
C++. The problem is that there are several different rules that apply
for initialization. Depending on the type, the value of a newly constructed
object can be zero-initialized (logically 0), default-constructed (using
the default constructor), or indeterminate. When writing generic code,
this problem must be addressed. The template __value_initialized__ provides
a solution with consistent syntax for value initialization of scalar,
union and class types. Moreover, __value_initialized__ offers a workaround to various
compiler issues regarding value-initialization.
Furthermore, a `const` object __initialized_value__ is provided,
to avoid repeating the type name when retrieving the value from a
`__value_initialized__<T>` object.
There are various ways to initialize a variable, in C++. The following
declarations all ['may] have a local variable initialized to its default
value:
```
T1 var1;
T2 var2 = 0;
T3 var3 = {};
T4 var4 = T4();
```
Unfortunately, whether or not any of those declarations correctly
initialize the variable very much depends on its type. The first
declaration is valid for any __DefaultConstructible__ type by definition.
However, it does not always do an initialization. It correctly initializes
the variable when it's an instance of a class, and the author of the class
has provided a proper default constructor. On the other hand, the value of
`var1` is ['indeterminate] when its type is an arithmetic type, like `int`,
`float`, or `char`.
An arithmetic variable is of course initialized properly by the second declaration,
`T2 var2 = 0`. But this initialization form will not usually work for a
class type, unless the class was especially written to support being
initialized that way.
The third form, `T3 var3 = {}`, initializes an aggregate, typically a "C-style"
`struct` or a "C-style" array. However, at the time this library was developed,
the syntax did not allow for a class that has an explicitly declared constructor.
The fourth form is the most generic form of them, as it can be used to initialize
arithmetic types, class types, aggregates, pointers, and other types.
The declaration, `T4 var4 = T4()`, should be read as follows: First a temporary
object is created, by `T4()`. This object is [link sec:valueinit value-initialized].
Next the temporary object is copied to the named variable, `var4`. Afterwards,
the temporary is destroyed. While the copying and the destruction are likely to
be optimized away, C++ still requires the type `T4` to be __CopyConstructible__.
So `T4` needs to be ['both] __DefaultConstructible__ ['and] __CopyConstructible__.
A class may not be CopyConstructible, for example because it may have a
private and undefined copy constructor, or because it may be derived from
`boost::noncopyable`. Scott Meyers \[[link sec:references 2]\] explains why a
class would be defined like that.
There is another, less obvious disadvantage to the fourth form, `T4 var4 = T4()`:
It suffers from various [link sec:compiler_issues compiler issues], causing
a variable to be left uninitialized in some compiler specific cases.
The template __value_initialized__ offers a generic way to initialize
an object, like `T4 var4 = T4()`, but without requiring its type
to be __CopyConstructible__. And it offers a workaround to those compiler issues
regarding value-initialization as well. It allows getting an initialized
variable of any type; it ['only] requires the type to be __DefaultConstructible__.
A properly ['value-initialized] object of type `T` is constructed by the following
declaration:
```
value_initialized<T> var;
```
The template __initialized__ offers both value-initialization and direct-initialization.
It is especially useful as a data member type, allowing the very same object
to be either direct-initialized or value-initialized.
The `const` object __initialized_value__ allows value-initializing a variable as follows:
```
T var = initialized_value;
```
This form of initialization is semantically equivalent to `T4 var4 = T4()`,
but robust against the aforementioned compiler issues.
[endsect]
[#sec:details]
[section Details]
The C++ standard \[[link sec:references 3]\] contains the definitions
of `zero-initialization` and `default-initialization`. Informally, zero-initialization
means that the object is given the initial value `0` converted to the type and
default-initialization means that [@https://en.cppreference.com/w/cpp/named_req/PODType POD] \[[link sec:references 4]\] types are zero-initialized,
while non-POD class types are initialized with their corresponding default constructors.
A ['declaration] can contain an ['initializer], which specifies the
object's initial value. The initializer can be just '()', which states that
the object shall be value-initialized (but see below). However, if a ['declaration]
has no ['initializer] and it is of a non-`const`, non-`static` POD type, the
initial value is indeterminate: (see [sect]8.5, \[dcl.init\], for the
accurate definitions).
```
int x; // no initializer. x value is indeterminate.
__std_string__ s; // no initializer, s is default-constructed.
int y = int();
// y is initialized using copy-initialization
// but the temporary uses an empty set of parentheses as the initializer,
// so it is default-constructed.
// A default constructed POD type is zero-initialized,
// therefore, y == 0.
void foo ( __std_string__ ) ;
foo ( __std_string__() ) ;
// the temporary string is default constructed
// as indicated by the initializer ()
```
[#sec:valueinit]
[h5 value-initialization]
The first [@http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html Technical
Corrigendum for the C++ Standard] (TC1), whose draft was released to the public in
November 2001, introduced [@http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#178 Core
Issue 178], among many other issues.
That issue introduced the new concept of `value-initialization`, and also fixed the
wording for zero-initialization. Informally, value-initialization is similar to
default-initialization with the exception that in some cases non-static data members
and base class sub-objects are also value-initialized.
The difference is that an object that is value-initialized will not have, or at least
is less likely to have, indeterminate values for data members and base class sub-objects;
unlike the case of an object default constructed (see Core Issue 178 for a
normative description).
In order to specify value-initialization of an object we need to use the
empty-set initializer: `()`.
As before, a declaration with no initializer specifies default-initialization,
and a declaration with a non-empty initializer specifies copy (`=xxx`) or
direct (`xxx`) initialization.
```
template<class T> void eat(T);
int x ; // indeterminate initial value.
__std_string__ s; // default-initialized.
eat ( int() ) ; // value-initialized
eat ( __std_string__() ) ; // value-initialized
```
[#sec:valueinitsyn]
[h5 value-initialization syntax]
Value initialization is specified using `()`. However, the empty set of
parentheses is not permitted by the syntax of initializers because it is
parsed as the declaration of a function taking no arguments:
```
int x() ; // declares function int(*)()
```
Thus, the empty `()` must be put in some other initialization context.
One alternative is to use copy-initialization syntax:
```
int x = int();
```
This works perfectly fine for POD types. But for non-POD class types,
copy-initialization searches for a suitable constructor, which could be,
for instance, the copy-constructor. It also searches for a suitable conversion
sequence but this does not apply in this context.
For an arbitrary unknown type, using this syntax may not have the
value-initialization effect intended because we don't know if a copy
from a default constructed object is exactly the same as a default
constructed object, and the compiler is allowed, in
some cases, but never required to, optimize the copy away.
One possible generic solution is to use value-initialization of a non static
data member:
```
template<class T>
struct W
{
// value-initialization of 'data' here.
W() : data() {}
T data;
};
W<int> w;
// w.data is value-initialized for any type.
```
This is the solution as it was supplied by earlier versions of the
`__value_initialized__<T>` template class. Unfortunately this approach
suffered from various compiler issues.
[#sec:compiler_issues]
[h5 Compiler issues]
Various compilers have not yet fully implemented value-initialization.
So when an object should be ['value-initialized] according to the C++ Standard,
it ['may] in practice still be left uninitialized, because of those
compiler issues. It is hard to make a general statement on what those issues
are like, because they depend on the compiler you are using, its version number,
and the type of object you would like to have value-initialized.
All compilers we have tested so far support value-initialization for arithmetic types properly.
However, various compilers may leave some types of ['aggregates] uninitialized, when they
should be value-initialized. Value-initialization of objects of a pointer-to-member type may also
go wrong on various compilers.
At the moment of writing, May 2010, the following reported issues regarding
value-initialization are still there in current compiler releases:
* [@https://connect.microsoft.com/VisualStudio/feedback/details/100744 Microsoft Visual Studio Feedback ID 100744, Value-initialization in new-expression]: Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005.
* [@http://connect.microsoft.com/VisualStudio/feedback/details/484295 Microsoft Visual Studio Feedback ID 484295, VC++ does not value-initialize members of derived classes without user-declared constructor] Reported by Sylvester Hesp, 2009.
* [@https://connect.microsoft.com/VisualStudio/feedback/details/499606 Microsoft Visual Studio Feedback ID 499606, Presence of copy constructor breaks member class initialization] Reported by Alex Vakulenko, 2009
* [@http://qc.embarcadero.com/wc/qcmain.aspx?d=83751 Embarcadero/C++Builder Report 83751, Value-initialization: arrays should have each element value-initialized] Reported by Niels Dekker (LKEB), 2010.
* [@http://qc.embarcadero.com/wc/qcmain.aspx?d=83851 Embarcadero/C++Builder Report 83851, Value-initialized temporary triggers internal backend error C1798] Reported by Niels Dekker, 2010.
* [@http://qc.embarcadero.com/wc/qcmain.aspx?d=84279 Embarcadero/C++Builder Report 84279, Internal compiler error (F1004), value-initializing member function pointer by "new T()"] Reported by Niels Dekker, 2010
* Sun CR 6947016, Sun 5.10 may fail to value-initialize an object of a non-POD aggregate. Reported to Steve Clamage by Niels Dekker, 2010.
* IBM's XL V10.1 and V11.1 may fail to value-initialize a temporary of a non-POD aggregate. Reported to Michael Wong by Niels Dekker, 2010.
* Intel support issue 589832, Attempt to value-initialize pointer-to-member triggers internal error on Intel 11.1. Reported by John Maddock, 2010.
Note that all known GCC issues regarding value-initialization are fixed with GCC version 4.4, including
[@http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 GCC Bug 30111]. Clang also has completely implemented
value-initialization, as far as we know, now that [@http://llvm.org/bugs/show_bug.cgi?id=7139 Clang Bug 7139]
is fixed.
New versions of __value_initialized__ (Boost release version 1.35 or higher) offer a workaround to these
issues: __value_initialized__ may now clear its internal data, prior to constructing the object that it
contains. It will do so for those compilers that need to have such a workaround, based on the
[@boost:/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_defects
compiler defect macro] `BOOST_NO_COMPLETE_VALUE_INITIALIZATION`.
[endsect]
[#sec:types]
[section Types and objects]
[#sec:val_init]
[section `template class value_initialized<T>`]
```
namespace boost {
template<class T>
class __value_initialized__
{
public :
__value_initialized__() : x() {}
operator T const &() const { return x ; }
operator T&() { return x ; }
T const &data() const { return x ; }
T& data() { return x ; }
void swap( __value_initialized__& );
private :
[unspecified] x ;
} ;
template<class T>
T const& get ( __value_initialized__<T> const& x )
{
return x.data();
}
template<class T>
T& get ( __value_initialized__<T>& x )
{
return x.data();
}
template<class T>
void swap ( __value_initialized__<T>& lhs, __value_initialized__<T>& rhs )
{
lhs.swap(rhs);
}
} // namespace boost
```
An object of this template class is a `T`-wrapper convertible to `'T&'` whose
wrapped object (data member of type `T`) is [link sec:valueinit value-initialized] upon default-initialization
of this wrapper class:
```
int zero = 0;
__value_initialized__<int> x;
assert( x == zero ) ;
__std_string__ def;
__value_initialized__< __std_string__ > y;
assert( y == def ) ;
```
The purpose of this wrapper is to provide a consistent syntax for value initialization
of scalar, union and class types (POD and non-POD) since the correct syntax for value
initialization varies (see [link sec:valueinitsyn value-initialization syntax]).
The wrapped object can be accessed either through the conversion operator
`T&`, the member function `data()`, or the non-member function `get()`:
```
void watch(int);
__value_initialized__<int> x;
watch(x) ; // operator T& used.
watch(x.data());
watch( get(x) ) // function get() used
```
Both `const` and non-`const` objects can be wrapped. Mutable objects can be
modified directly from within the wrapper but constant objects cannot:
When `T` is a __Swappable__ type, `__value_initialized__<T>`
is swappable as well, by calling its `swap` member function
as well as by calling `boost::swap`.
```
__value_initialized__<int> x;
static_cast<int&>(x) = 1 ; // OK
get(x) = 1 ; // OK
__value_initialized__<int const> y ;
static_cast<int&>(y) = 1 ; // ERROR: cannot cast to int&
static_cast<int const&>(y) = 1 ; // ERROR: cannot modify a const value
get(y) = 1 ; // ERROR: cannot modify a const value
```
[warning
The __value_initialized__ implementation of Boost version 1.40.0 and older
allowed ['non-const] access to the wrapped object, from a constant wrapper,
both by its conversion operator and its `data()` member function.
For example:
```
__value_initialized__<int> const x_c;
int& xr = x_c ; // OK, conversion to int& available even though x_c is itself const.
xr = 2 ;
```
The reason for this obscure behavior was that some compilers did not accept the following valid code:
```
struct X
{
operator int&() ;
operator int const&() const ;
};
X x ;
(x == 1) ; // ERROR HERE!
```
The current version of __value_initialized__ no longer has this obscure behavior.
As compilers nowadays widely support overloading the conversion operator by having a `const`
and a `non-const` version, we have decided to fix the issue accordingly. So the current version
supports the idea of logical constness.
]
[h5 Recommended practice: The non-member get() idiom]
The obscure behavior of being able to modify a non-`const`
wrapped object from within a constant wrapper (as was supported by previous
versions of __value_initialized__) can be avoided if access to the wrapped object
is always performed with the `get()` idiom:
```
value_initialized<int> x;
get(x) = 1; // OK
value_initialized<int const> cx;
get(x) = 1; // ERROR: Cannot modify a const object
value_initialized<int> const x_c;
get(x_c) = 1; // ERROR: Cannot modify a const object
value_initialized<int const> const cx_c;
get(cx_c) = 1; // ERROR: Cannot modify a const object
```
[endsect]
[#sec:initialized]
[section `template class initialized<T>`]
```
namespace boost {
template<class T>
class __initialized__
{
public :
__initialized__() : x() {}
explicit __initialized__(T const & arg) : x(arg) {}
operator T const &() const;
operator T&();
T const &data() const;
T& data();
void swap( __initialized__& );
private :
[unspecified] x ;
};
template<class T>
T const& get ( __initialized__<T> const& x );
template<class T>
T& get ( __initialized__<T>& x );
template<class T>
void swap ( __initialized__<T>& lhs, __initialized__<T>& rhs );
} // namespace boost
```
The template class `boost::__initialized__<T>` supports both value-initialization
and direct-initialization, so its interface is a superset of the interface
of `__value_initialized__<T>`: Its default-constructor value-initializes the
wrapped object just like the default-constructor of `__value_initialized__<T>`,
but `boost::__initialized__<T>` also offers an extra `explicit`
constructor, which direct-initializes the wrapped object by the specified value.
`__initialized__<T>` is especially useful when the wrapped
object must be either value-initialized or direct-initialized, depending on
runtime conditions. For example, `__initialized__<T>` could
hold the value of a data member that may be value-initialized by some
constructors, and direct-initialized by others.
On the other hand, if it is known beforehand that the
object must ['always] be value-initialized, `__value_initialized__<T>`
may be preferable. And if the object must always be
direct-initialized, none of the two wrappers really needs to be used.
[endsect]
[#sec:initialized_value]
[section `initialized_value`]
```
namespace boost {
class __initialized_value_t__
{
public :
template <class T> operator T() const ;
};
__initialized_value_t__ const initialized_value = {} ;
} // namespace boost
```
__initialized_value__ provides a convenient way to get
an initialized value: its conversion operator provides an appropriate
['value-initialized] object for any __CopyConstructible__ type.
Suppose you need to have an initialized variable of type `T`.
You could do it as follows:
```
T var = T();
```
But as mentioned before, this form suffers from various compiler issues.
The template __value_initialized__ offers a workaround:
```
T var = get( __value_initialized__<T>() );
```
Unfortunately both forms repeat the type name, which
is rather short now (`T`), but could of course be
more like `Namespace::Template<Arg>::Type`.
Instead, one could use __initialized_value__ as follows:
```
T var = __initialized_value__;
```
[endsect]
[endsect]
[#sec:references]
[section References]
# Bjarne Stroustrup, Gabriel Dos Reis, and J. Stephen Adamczyk wrote various papers,
proposing to extend the support for brace-enclosed ['initializer lists]
in C++. This [@https://en.cppreference.com/w/cpp/language/list_initialization feature] has
now been available since C++11. This would allow a variable `var` of any __DefaultConstructible__ type
`T` to be ['value-initialized] by doing `T var = {}`. The papers are listed at Bjarne's web page,
[@http://www.research.att.com/~bs/WG21.html My C++ Standards committee papers].
# Scott Meyers, Effective C++, Third Edition, item 6, ['Explicitly disallow the use of
compiler-generated functions you do not want], [@http://www.aristeia.com/books.html Scott Meyers: Books and CDs]
# The C++ Standard, Second edition (2003), ISO/IEC 14882:2003
# POD stands for [@https://en.cppreference.com/w/cpp/named_req/PODType "Plain Old Data"]
[endsect]
[/===============]
[xinclude tmp/value_init_reference.xml]
[/===============]
[#sec:acknowledgements]
[section Acknowledgements]
__value_initialized__ was developed by Fernando Cacciola, with help and suggestions
from David Abrahams and Darin Adler.
Special thanks to Bjorn Karlsson who carefully edited and completed this documentation.
__value_initialized__ was reimplemented by Fernando Cacciola and Niels Dekker
for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
`boost::__initialized__` was very much inspired by feedback from Edward Diener and Jeffrey Hellrung.
__initialized_value__ was written by Niels Dekker, and added to Boost release version 1.36 (2008).
Developed by [@mailto:fernando_cacciola@hotmail.com Fernando Cacciola]. The latest version of
this file can be found at [@http://www.boost.org www.boost.org].
[endsect]
[endsect]