mirror of
https://github.com/boostorg/utility.git
synced 2025-10-16 02:25:18 +02:00
Compare commits
26 Commits
boost-1.73
...
feature/fi
Author | SHA1 | Date | |
---|---|---|---|
|
f3963f5375 | ||
|
37168a3f4b | ||
|
e56171989a | ||
|
f00a5bf0d3 | ||
|
a4feaf4f24 | ||
|
688628f764 | ||
|
8faf831bd1 | ||
|
25cb7aa122 | ||
|
0ae5cebc7f | ||
|
1caa002121 | ||
|
691f3238d7 | ||
|
8b6da499a3 | ||
|
6e6d0777e8 | ||
|
64fffa0f97 | ||
|
5da340a2a4 | ||
|
9a4cff038b | ||
|
0c059a50ad | ||
|
bdc5b5cf3a | ||
|
86e7caefea | ||
|
7953ba56ba | ||
|
46f72656b3 | ||
|
e3a2a06011 | ||
|
a4752e066d | ||
|
6b62dcc504 | ||
|
91ebdcd1dd | ||
|
e8d2b2ba76 |
37
.travis.yml
37
.travis.yml
@@ -136,6 +136,17 @@ matrix:
|
||||
sources:
|
||||
- sourceline: "ppa:ubuntu-toolchain-r/test"
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: gcc-10
|
||||
env: TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14,17,20
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-10
|
||||
sources:
|
||||
- sourceline: "ppa:ubuntu-toolchain-r/test"
|
||||
|
||||
# clang, Linux
|
||||
- os: linux
|
||||
dist: trusty
|
||||
@@ -293,17 +304,31 @@ matrix:
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang-libc++
|
||||
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a CXXFLAGS="-stdlib=libc++" LINKFLAGS="-stdlib=libc++"
|
||||
compiler: clang-10
|
||||
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,20
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-9
|
||||
- libc++-9-dev
|
||||
- libc++abi-9-dev
|
||||
- clang-10
|
||||
- libstdc++-9-dev
|
||||
sources:
|
||||
- sourceline: "ppa:ubuntu-toolchain-r/test"
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main"
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang-libc++
|
||||
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,20 CXXFLAGS="-stdlib=libc++" LINKFLAGS="-stdlib=libc++"
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-10
|
||||
- libc++-10-dev
|
||||
- libc++abi-10-dev
|
||||
sources:
|
||||
- sourceline: "ppa:ubuntu-toolchain-r/test"
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
# clang, OS X
|
||||
|
@@ -20,6 +20,7 @@ target_link_libraries(boost_utility
|
||||
Boost::config
|
||||
Boost::container_hash
|
||||
Boost::core
|
||||
Boost::io
|
||||
Boost::preprocessor
|
||||
Boost::static_assert
|
||||
Boost::throw_exception
|
||||
|
@@ -15,9 +15,10 @@ branches:
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
|
||||
- TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0
|
||||
ADDRMD: 32
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
- TOOLSET: msvc-14.0
|
||||
- TOOLSET: msvc-12.0,msvc-14.0
|
||||
ADDRMD: 32,64
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
- TOOLSET: msvc-14.1
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[/
|
||||
/ Copyright (c) 2008 Howard Hinnant
|
||||
/ Copyright (c) 2009-20012 Vicente J. Botet Escriba
|
||||
/ Copyright (c) 2009-2012 Vicente J. Botet Escriba
|
||||
/
|
||||
/ 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)
|
||||
|
@@ -100,7 +100,7 @@ struct call_traits<T&>
|
||||
typedef T& param_type; // hh removed const
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND( __BORLANDC__, < 0x5A0 )
|
||||
#if BOOST_WORKAROUND( BOOST_BORLANDC, < 0x5A0 )
|
||||
// these are illegal specialisations; cv-qualifies applied to
|
||||
// references have no effect according to [8.3.2p1],
|
||||
// C++ Builder requires them though as it treats cv-qualified
|
||||
|
@@ -100,6 +100,11 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#if defined(__cpp_impl_three_way_comparison)
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/declval.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__)
|
||||
# pragma set woff 1234
|
||||
@@ -109,6 +114,13 @@
|
||||
# pragma warning( disable : 4284 ) // complaint about return type of
|
||||
#endif // operator-> not begin a UDT
|
||||
|
||||
// Define BOOST_OPERATORS_CONSTEXPR to be like BOOST_CONSTEXPR but empty under MSVC < v19.22
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1922)
|
||||
#define BOOST_OPERATORS_CONSTEXPR
|
||||
#else
|
||||
#define BOOST_OPERATORS_CONSTEXPR BOOST_CONSTEXPR
|
||||
#endif
|
||||
|
||||
// In this section we supply the xxxx1 and xxxx2 forms of the operator
|
||||
// templates, which are explicitly targeted at the 1-type-argument and
|
||||
// 2-type-argument operator forms, respectively.
|
||||
@@ -132,34 +144,46 @@ template <typename T> class empty_base {};
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct less_than_comparable2 : B
|
||||
{
|
||||
friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
|
||||
friend bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); }
|
||||
friend bool operator>(const U& x, const T& y) { return y < x; }
|
||||
friend bool operator<(const U& x, const T& y) { return y > x; }
|
||||
friend bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); }
|
||||
friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); }
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator>(const U& x, const T& y) { return y < x; }
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator<(const U& x, const T& y) { return y > x; }
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); }
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
|
||||
};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct less_than_comparable1 : B
|
||||
{
|
||||
friend bool operator>(const T& x, const T& y) { return y < x; }
|
||||
friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
|
||||
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator>(const T& x, const T& y) { return y < x; }
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
|
||||
};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct equality_comparable2 : B
|
||||
{
|
||||
friend bool operator==(const U& y, const T& x) { return x == y; }
|
||||
friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
|
||||
friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
|
||||
#if defined(__cpp_impl_three_way_comparison)
|
||||
template< typename R = decltype(boost::declval< T const& >() == boost::declval< U const& >()) >
|
||||
friend BOOST_OPERATORS_CONSTEXPR
|
||||
typename boost::enable_if_c< !boost::is_same< R, bool >::value, bool >::type
|
||||
operator==(const U& y, const T& x) { return x == y; }
|
||||
|
||||
template< typename R = decltype(boost::declval< T const& >() == boost::declval< U const& >()) >
|
||||
friend BOOST_OPERATORS_CONSTEXPR
|
||||
typename boost::enable_if_c< !boost::is_same< R, bool >::value, bool >::type
|
||||
operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
|
||||
#else
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator==(const U& y, const T& x) { return x == y; }
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
|
||||
#endif
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator!=(const T& x, const U& y) { return !static_cast<bool>(x == y); }
|
||||
};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct equality_comparable1 : B
|
||||
{
|
||||
friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
|
||||
};
|
||||
|
||||
// A macro which produces "name_2left" from "name".
|
||||
@@ -362,7 +386,7 @@ BOOST_BINARY_OPERATOR( right_shiftable, >> )
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct equivalent2 : B
|
||||
{
|
||||
friend bool operator==(const T& x, const U& y)
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator==(const T& x, const U& y)
|
||||
{
|
||||
return !static_cast<bool>(x < y) && !static_cast<bool>(x > y);
|
||||
}
|
||||
@@ -371,7 +395,7 @@ struct equivalent2 : B
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct equivalent1 : B
|
||||
{
|
||||
friend bool operator==(const T&x, const T&y)
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator==(const T&x, const T&y)
|
||||
{
|
||||
return !static_cast<bool>(x < y) && !static_cast<bool>(y < x);
|
||||
}
|
||||
@@ -380,28 +404,28 @@ struct equivalent1 : B
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct partially_ordered2 : B
|
||||
{
|
||||
friend bool operator<=(const T& x, const U& y)
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const T& x, const U& y)
|
||||
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
|
||||
friend bool operator>=(const T& x, const U& y)
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const T& x, const U& y)
|
||||
{ return static_cast<bool>(x > y) || static_cast<bool>(x == y); }
|
||||
friend bool operator>(const U& x, const T& y)
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator>(const U& x, const T& y)
|
||||
{ return y < x; }
|
||||
friend bool operator<(const U& x, const T& y)
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator<(const U& x, const T& y)
|
||||
{ return y > x; }
|
||||
friend bool operator<=(const U& x, const T& y)
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const U& x, const T& y)
|
||||
{ return static_cast<bool>(y > x) || static_cast<bool>(y == x); }
|
||||
friend bool operator>=(const U& x, const T& y)
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const U& x, const T& y)
|
||||
{ return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
|
||||
};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct partially_ordered1 : B
|
||||
{
|
||||
friend bool operator>(const T& x, const T& y)
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator>(const T& x, const T& y)
|
||||
{ return y < x; }
|
||||
friend bool operator<=(const T& x, const T& y)
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator<=(const T& x, const T& y)
|
||||
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
|
||||
friend bool operator>=(const T& x, const T& y)
|
||||
friend BOOST_OPERATORS_CONSTEXPR bool operator>=(const T& x, const T& y)
|
||||
{ return static_cast<bool>(y < x) || static_cast<bool>(x == y); }
|
||||
};
|
||||
|
||||
|
@@ -144,9 +144,11 @@ struct less_than_comparable1 : B
|
||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||
struct equality_comparable2 : B
|
||||
{
|
||||
#if !defined(__cpp_impl_three_way_comparison)
|
||||
friend bool operator==(const U& y, const T& x) { return x == y; }
|
||||
friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
|
||||
friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
|
||||
#endif
|
||||
friend bool operator!=(const T& x, const U& y) { return !static_cast<bool>(x == y); }
|
||||
};
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||
|
@@ -22,7 +22,7 @@
|
||||
# define BOOST_RESULT_OF_ARGS BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)
|
||||
#endif
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
|
||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||
: conditional<
|
||||
@@ -151,7 +151,7 @@ struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)),
|
||||
|
||||
#else // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
|
||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||
: tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { };
|
||||
@@ -177,7 +177,7 @@ struct tr1_result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), F
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
|
||||
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of_impl<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)),
|
||||
|
@@ -1,4 +1,5 @@
|
||||
// (C) Copyright 2002-2008, Fernando Luis Cacciola Carballal.
|
||||
// Copyright 2020 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -21,15 +22,10 @@
|
||||
// issues, by clearing the bytes of T, before constructing the T object it
|
||||
// contains. More details on these issues are at libs/utility/value_init.htm
|
||||
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#include <boost/config.hpp> // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/swap.hpp>
|
||||
#include <cstring>
|
||||
#include <new>
|
||||
#include <cstddef>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
@@ -60,92 +56,58 @@
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct zero_init
|
||||
{
|
||||
zero_init()
|
||||
{
|
||||
}
|
||||
|
||||
zero_init( void * p, std::size_t n )
|
||||
{
|
||||
std::memset( p, 0, n );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
class initialized
|
||||
#if BOOST_DETAIL_VALUE_INIT_WORKAROUND
|
||||
: detail::zero_init
|
||||
#endif
|
||||
{
|
||||
private :
|
||||
struct wrapper
|
||||
{
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
|
||||
typename
|
||||
#endif
|
||||
remove_const<T>::type data;
|
||||
private:
|
||||
|
||||
BOOST_GPU_ENABLED
|
||||
wrapper()
|
||||
:
|
||||
data()
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_GPU_ENABLED
|
||||
wrapper(T const & arg)
|
||||
:
|
||||
data(arg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
mutable
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
|
||||
typename
|
||||
#endif
|
||||
aligned_storage<sizeof(wrapper), alignment_of<wrapper>::value>::type x;
|
||||
|
||||
BOOST_GPU_ENABLED
|
||||
wrapper * wrapper_address() const
|
||||
{
|
||||
return static_cast<wrapper *>( static_cast<void*>(&x));
|
||||
}
|
||||
T data_;
|
||||
|
||||
public :
|
||||
|
||||
BOOST_GPU_ENABLED
|
||||
initialized()
|
||||
{
|
||||
initialized():
|
||||
#if BOOST_DETAIL_VALUE_INIT_WORKAROUND
|
||||
std::memset(&x, 0, sizeof(x));
|
||||
zero_init( &const_cast< char& >( reinterpret_cast<char const volatile&>( data_ ) ), sizeof( data_ ) ),
|
||||
#endif
|
||||
new (wrapper_address()) wrapper();
|
||||
data_()
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_GPU_ENABLED
|
||||
initialized(initialized const & arg)
|
||||
explicit initialized(T const & arg): data_( arg )
|
||||
{
|
||||
new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address())));
|
||||
}
|
||||
|
||||
BOOST_GPU_ENABLED
|
||||
explicit initialized(T const & arg)
|
||||
{
|
||||
new (wrapper_address()) wrapper(arg);
|
||||
}
|
||||
|
||||
BOOST_GPU_ENABLED
|
||||
initialized & operator=(initialized const & arg)
|
||||
{
|
||||
// Assignment is only allowed when T is non-const.
|
||||
BOOST_STATIC_ASSERT( ! is_const<T>::value );
|
||||
*wrapper_address() = static_cast<wrapper const &>(*(arg.wrapper_address()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
BOOST_GPU_ENABLED
|
||||
~initialized()
|
||||
{
|
||||
wrapper_address()->wrapper::~wrapper();
|
||||
}
|
||||
|
||||
BOOST_GPU_ENABLED
|
||||
T const & data() const
|
||||
{
|
||||
return wrapper_address()->data;
|
||||
return data_;
|
||||
}
|
||||
|
||||
BOOST_GPU_ENABLED
|
||||
T& data()
|
||||
{
|
||||
return wrapper_address()->data;
|
||||
return data_;
|
||||
}
|
||||
|
||||
BOOST_GPU_ENABLED
|
||||
@@ -157,13 +119,13 @@ class initialized
|
||||
BOOST_GPU_ENABLED
|
||||
operator T const &() const
|
||||
{
|
||||
return wrapper_address()->data;
|
||||
return data_;
|
||||
}
|
||||
|
||||
BOOST_GPU_ENABLED
|
||||
operator T&()
|
||||
{
|
||||
return wrapper_address()->data;
|
||||
return data_;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
@@ -454,7 +454,7 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
</caption>
|
||||
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<td colspan="4">
|
||||
<table align="center" border="1">
|
||||
<caption>
|
||||
<em>Key</em>
|
||||
@@ -482,6 +482,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<th>Supplied Operations</th>
|
||||
|
||||
<th>Requirements</th>
|
||||
|
||||
<th>Propagates <code>constexpr</code>?</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -496,6 +498,9 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>t < t1</code>.<br>
|
||||
Return convertible to <code>bool</code>. See the <a href=
|
||||
"#ordering">Ordering Note</a>.</td>
|
||||
|
||||
<td>Since <code>C++11</code><br>
|
||||
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC < v19.22</a>)</span></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -513,6 +518,9 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>t < u</code>. <code>t > u</code>.<br>
|
||||
Returns convertible to <code>bool</code>. See the <a href=
|
||||
"#ordering">Ordering Note</a>.</td>
|
||||
|
||||
<td>Since <code>C++11</code><br>
|
||||
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC < v19.22</a>)</span></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -524,6 +532,9 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
|
||||
<td><code>t == t1</code>.<br>
|
||||
Return convertible to <code>bool</code>.</td>
|
||||
|
||||
<td>Since <code>C++11</code><br>
|
||||
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC < v19.22</a>)</span></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -537,6 +548,9 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
|
||||
<td><code>t == u</code>.<br>
|
||||
Return convertible to <code>bool</code>.</td>
|
||||
|
||||
<td>Since <code>C++11</code><br>
|
||||
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC < v19.22</a>)</span></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -548,6 +562,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp += t1</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -560,6 +576,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp += u</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -572,6 +590,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp -= t1</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -584,6 +604,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp -= u</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -594,6 +616,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
|
||||
<td><code>T temp(u); temp -= t</code>.<br>
|
||||
Return convertible to <code>T</code>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -606,6 +630,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp *= t1</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -619,6 +645,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp *= u</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -630,6 +658,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp /= t1</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -641,6 +671,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp /= u</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -651,6 +683,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
|
||||
<td><code>T temp(u); temp /= t</code>.<br>
|
||||
Return convertible to <code>T</code>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -662,6 +696,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp %= t1</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -673,6 +709,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp %= u</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -683,6 +721,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
|
||||
<td><code>T temp(u); temp %= t</code>.<br>
|
||||
Return convertible to <code>T</code>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -694,6 +734,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp |= t1</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -706,6 +748,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp |= u</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -717,6 +761,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp &= t1</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -729,6 +775,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp &= u</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -740,6 +788,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp ^= t1</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -752,6 +802,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp ^= u</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -762,6 +814,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
|
||||
<td><code>T temp(t); ++t</code><br>
|
||||
Return convertible to <code>T</code>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -772,6 +826,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
|
||||
<td><code>T temp(t); --t;</code><br>
|
||||
Return convertible to <code>T</code>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -784,6 +840,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp <<= t1</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -796,6 +854,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp <<= u</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -808,6 +868,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp >>= t1</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -820,6 +882,8 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>T temp(t); temp >>= u</code>.<br>
|
||||
Return convertible to <code>T</code>. See the <a href=
|
||||
"#symmetry">Symmetry Note</a>.</td>
|
||||
|
||||
<td>No</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -831,6 +895,9 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>t < t1</code>.<br>
|
||||
Return convertible to <code>bool</code>. See the <a href=
|
||||
"#ordering">Ordering Note</a>.</td>
|
||||
|
||||
<td>Since <code>C++11</code><br>
|
||||
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC < v19.22</a>)</span></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -842,6 +909,9 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>t < u</code>. <code>t > u</code>.<br>
|
||||
Returns convertible to <code>bool</code>. See the <a href=
|
||||
"#ordering">Ordering Note</a>.</td>
|
||||
|
||||
<td>Since <code>C++11</code><br>
|
||||
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC < v19.22</a>)</span></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -856,6 +926,9 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
<td><code>t < t1</code>. <code>t == t1</code>.<br>
|
||||
Returns convertible to <code>bool</code>. See the <a href=
|
||||
"#ordering">Ordering Note</a>.</td>
|
||||
|
||||
<td>Since <code>C++11</code><br>
|
||||
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC < v19.22</a>)</span></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -874,6 +947,9 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
u</code>.<br>
|
||||
Returns convertible to <code>bool</code>. See the <a href=
|
||||
"#ordering">Ordering Note</a>.</td>
|
||||
|
||||
<td>Since <code>C++11</code><br>
|
||||
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC < v19.22</a>)</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
@@ -21,6 +21,7 @@ run compressed_pair_final_test.cpp ;
|
||||
run iterators_test.cpp ;
|
||||
|
||||
run operators_test.cpp ;
|
||||
compile operators_constexpr_test.cpp ;
|
||||
|
||||
compile result_of_test.cpp ;
|
||||
|
||||
@@ -35,6 +36,8 @@ run string_view_test2.cpp ;
|
||||
run string_view_test_io.cpp ;
|
||||
|
||||
run value_init_test.cpp ;
|
||||
run value_init_test2.cpp ;
|
||||
run value_init_test3.cpp ;
|
||||
run value_init_workaround_test.cpp ;
|
||||
run initialized_test.cpp ;
|
||||
compile-fail value_init_test_fail1.cpp ;
|
||||
|
@@ -376,7 +376,7 @@ void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>:
|
||||
reference r = t;
|
||||
const_reference cr = t;
|
||||
reference r2 = r;
|
||||
#ifndef __BORLANDC__
|
||||
#ifndef BOOST_BORLANDC
|
||||
// C++ Builder buglet:
|
||||
const_reference cr2 = r;
|
||||
#endif
|
||||
@@ -393,7 +393,7 @@ void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>:
|
||||
unused_variable(v3);
|
||||
unused_variable(v4);
|
||||
unused_variable(v5);
|
||||
#ifndef __BORLANDC__
|
||||
#ifndef BOOST_BORLANDC
|
||||
unused_variable(r2);
|
||||
unused_variable(cr2);
|
||||
#endif
|
||||
|
59
test/operators_constexpr_test.cpp
Normal file
59
test/operators_constexpr_test.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright 2020 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_CONSTEXPR) && \
|
||||
(!defined(BOOST_MSVC) || (BOOST_MSVC >= 1922))
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
class Value
|
||||
: boost::operators<Value> {
|
||||
public:
|
||||
BOOST_OPERATORS_CONSTEXPR explicit Value(int v)
|
||||
: v_(v) { }
|
||||
|
||||
BOOST_OPERATORS_CONSTEXPR bool
|
||||
operator<(const Value& x) const {
|
||||
return v_ < x.v_;
|
||||
}
|
||||
|
||||
BOOST_OPERATORS_CONSTEXPR bool
|
||||
operator==(const Value& x) const {
|
||||
return v_ == x.v_;
|
||||
}
|
||||
|
||||
private:
|
||||
int v_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) == Value(2)));
|
||||
BOOST_STATIC_ASSERT(Value(1) != Value(2));
|
||||
BOOST_STATIC_ASSERT(Value(1) < Value(2));
|
||||
BOOST_STATIC_ASSERT(Value(1) <= Value(2));
|
||||
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) > Value(2)));
|
||||
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) >= Value(2)));
|
||||
|
||||
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(2) == Value(1)));
|
||||
BOOST_STATIC_ASSERT(Value(2) != Value(1));
|
||||
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(2) < Value(1)));
|
||||
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(2) <= Value(1)));
|
||||
BOOST_STATIC_ASSERT(Value(2) > Value(1));
|
||||
BOOST_STATIC_ASSERT(Value(2) >= Value(1));
|
||||
|
||||
BOOST_STATIC_ASSERT(Value(1) == Value(1));
|
||||
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) != Value(1)));
|
||||
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) < Value(1)));
|
||||
BOOST_STATIC_ASSERT(Value(1) <= Value(1));
|
||||
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) > Value(1)));
|
||||
BOOST_STATIC_ASSERT(Value(1) >= Value(1));
|
||||
#endif
|
@@ -50,9 +50,9 @@ namespace
|
||||
void operator!() const;
|
||||
|
||||
public:
|
||||
convertible_to_bool( const bool value ) : _value( value ) {}
|
||||
convertible_to_bool( const bool value ) : _value( value ) {}
|
||||
|
||||
operator unspecified_bool_type() const
|
||||
operator unspecified_bool_type() const
|
||||
{ return _value ? &convertible_to_bool::_value : 0; }
|
||||
};
|
||||
|
||||
@@ -64,12 +64,12 @@ namespace
|
||||
, boost::shiftable<Wrapped1<T> >
|
||||
{
|
||||
public:
|
||||
explicit Wrapped1( T v = T() ) : _value(v) {}
|
||||
T value() const { return _value; }
|
||||
explicit Wrapped1( T v = T() ) : _value(v) {}
|
||||
T value() const { return _value; }
|
||||
|
||||
convertible_to_bool operator<(const Wrapped1& x) const
|
||||
convertible_to_bool operator<(const Wrapped1& x) const
|
||||
{ return _value < x._value; }
|
||||
convertible_to_bool operator==(const Wrapped1& x) const
|
||||
convertible_to_bool operator==(const Wrapped1& x) const
|
||||
{ return _value == x._value; }
|
||||
|
||||
Wrapped1& operator+=(const Wrapped1& x)
|
||||
@@ -92,8 +92,8 @@ namespace
|
||||
{ _value <<= x._value; return *this; }
|
||||
Wrapped1& operator>>=(const Wrapped1& x)
|
||||
{ _value >>= x._value; return *this; }
|
||||
Wrapped1& operator++() { ++_value; return *this; }
|
||||
Wrapped1& operator--() { --_value; return *this; }
|
||||
Wrapped1& operator++() { ++_value; return *this; }
|
||||
Wrapped1& operator--() { --_value; return *this; }
|
||||
|
||||
private:
|
||||
T _value;
|
||||
@@ -568,6 +568,25 @@ namespace
|
||||
int v;
|
||||
};
|
||||
|
||||
// Test type designed specifically to test C++20 operator rewriting support
|
||||
struct my_int :
|
||||
public boost::equality_comparable2< my_int, int >
|
||||
{
|
||||
explicit my_int(int n) : m_n(n) {}
|
||||
|
||||
operator int () const
|
||||
{
|
||||
return m_n;
|
||||
}
|
||||
|
||||
bool operator== (my_int that)
|
||||
{
|
||||
return that.m_n == m_n;
|
||||
}
|
||||
|
||||
int m_n;
|
||||
};
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
@@ -932,5 +951,11 @@ main()
|
||||
|
||||
cout << "Performed tests on MyLongInt objects.\n";
|
||||
|
||||
my_int my_n = my_int(10);
|
||||
|
||||
// Test if C++20 operator rewriting causes infinite recursion (https://github.com/boostorg/utility/issues/65)
|
||||
BOOST_TEST(my_n == 10);
|
||||
BOOST_TEST(my_n != 20);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
@@ -17,11 +17,12 @@
|
||||
|
||||
#include "boost/utility/value_init.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#ifdef BOOST_BORLANDC
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
|
||||
//
|
||||
// Sample POD type
|
||||
@@ -217,8 +218,8 @@ void check_initialized_value ( T const& y )
|
||||
BOOST_TEST ( y == initializedValue ) ;
|
||||
}
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#if __BORLANDC__ == 0x582
|
||||
#ifdef BOOST_BORLANDC
|
||||
#if BOOST_BORLANDC == 0x582
|
||||
void check_initialized_value( NonPOD const& )
|
||||
{
|
||||
// The initialized_value check is skipped for Borland 5.82
|
||||
|
169
test/value_init_test2.cpp
Normal file
169
test/value_init_test2.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
// Copyright 2010, Niels Dekker.
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// Test program for the boost::value_initialized<T> workaround.
|
||||
//
|
||||
// 17 June 2010 (Created) Niels Dekker
|
||||
|
||||
#include <boost/utility/value_init.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct empty_struct
|
||||
{
|
||||
};
|
||||
|
||||
// A POD aggregate struct derived from an empty struct.
|
||||
// Similar to struct Foo1 from Microsoft Visual C++ bug report 484295,
|
||||
// "VC++ does not value-initialize members of derived classes without
|
||||
// user-declared constructor", reported in 2009 by Sylvester Hesp:
|
||||
// https://connect.microsoft.com/VisualStudio/feedback/details/484295
|
||||
struct derived_struct: empty_struct
|
||||
{
|
||||
int data;
|
||||
};
|
||||
|
||||
bool is_value_initialized(const derived_struct& arg)
|
||||
{
|
||||
return arg.data == 0;
|
||||
}
|
||||
|
||||
|
||||
class virtual_destructor_holder
|
||||
{
|
||||
public:
|
||||
int i;
|
||||
virtual ~virtual_destructor_holder()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
bool is_value_initialized(const virtual_destructor_holder& arg)
|
||||
{
|
||||
return arg.i == 0;
|
||||
}
|
||||
|
||||
// Equivalent to the Stats class from GCC Bug 33916,
|
||||
// "Default constructor fails to initialize array members", reported in 2007 by
|
||||
// Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
|
||||
// and fixed for GCC 4.2.4.
|
||||
class private_int_array_pair
|
||||
{
|
||||
friend bool is_value_initialized(const private_int_array_pair& arg);
|
||||
private:
|
||||
int first[12];
|
||||
int second[12];
|
||||
};
|
||||
|
||||
bool is_value_initialized(const private_int_array_pair& arg)
|
||||
{
|
||||
for ( unsigned i = 0; i < 12; ++i)
|
||||
{
|
||||
if ( (arg.first[i] != 0) || (arg.second[i] != 0) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct int_pair_struct
|
||||
{
|
||||
int first;
|
||||
int second;
|
||||
};
|
||||
|
||||
typedef int int_pair_struct::*ptr_to_member_type;
|
||||
|
||||
struct ptr_to_member_struct
|
||||
{
|
||||
ptr_to_member_type data;
|
||||
};
|
||||
|
||||
bool is_value_initialized(const ptr_to_member_struct& arg)
|
||||
{
|
||||
return arg.data == 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is_value_initialized(const T(& arg)[2])
|
||||
{
|
||||
return
|
||||
is_value_initialized(arg[0]) &&
|
||||
is_value_initialized(arg[1]);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is_value_initialized(const boost::value_initialized<T>& arg)
|
||||
{
|
||||
return is_value_initialized(arg.data());
|
||||
}
|
||||
|
||||
// Returns zero when the specified object is value-initializated, and one otherwise.
|
||||
// Prints a message to standard output if the value-initialization has failed.
|
||||
template <class T>
|
||||
unsigned failed_to_value_initialized(const T& object, const char *const object_name)
|
||||
{
|
||||
if ( is_value_initialized(object) )
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Note: Failed to value-initialize " << object_name << '.' << std::endl;
|
||||
return 1u;
|
||||
}
|
||||
}
|
||||
|
||||
// A macro that passed both the name and the value of the specified object to
|
||||
// the function above here.
|
||||
#define FAILED_TO_VALUE_INITIALIZE(value) failed_to_value_initialized(value, #value)
|
||||
|
||||
// Equivalent to the dirty_stack() function from GCC Bug 33916,
|
||||
// "Default constructor fails to initialize array members", reported in 2007 by
|
||||
// Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
|
||||
void dirty_stack()
|
||||
{
|
||||
unsigned char array_on_stack[4096];
|
||||
for (unsigned i = 0; i < sizeof(array_on_stack); ++i)
|
||||
{
|
||||
array_on_stack[i] = 0x11;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
|
||||
|
||||
std::cout << "BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED is defined.\n\n";
|
||||
|
||||
#endif
|
||||
|
||||
dirty_stack();
|
||||
|
||||
BOOST_TEST( is_value_initialized( boost::value_initialized<derived_struct>() ) );
|
||||
BOOST_TEST( is_value_initialized( boost::value_initialized<virtual_destructor_holder[2]>() ) );
|
||||
BOOST_TEST( is_value_initialized( boost::value_initialized<private_int_array_pair>() ) );
|
||||
|
||||
#if !BOOST_WORKAROUND( BOOST_MSVC, BOOST_TESTED_AT(1925) )
|
||||
|
||||
// Null pointers to data members are represented as -1 in MSVC, but
|
||||
// value initialization sets them to all zero. The workaround employed
|
||||
// by value_initialized<> is to memset the storage to all zero, which
|
||||
// doesn't help.
|
||||
|
||||
BOOST_TEST( is_value_initialized( boost::value_initialized<ptr_to_member_struct>() ) );
|
||||
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
40
test/value_init_test3.cpp
Normal file
40
test/value_init_test3.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/utility/value_init.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if __cplusplus >= 201103L || ( defined(BOOST_MSVC) && BOOST_MSVC >= 1900 )
|
||||
|
||||
struct X
|
||||
{
|
||||
int a;
|
||||
char b;
|
||||
};
|
||||
|
||||
struct Y: boost::value_initialized<X>
|
||||
{
|
||||
char c = 42;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( y.data().a, 0 );
|
||||
BOOST_TEST_EQ( y.data().b, 0 );
|
||||
BOOST_TEST_EQ( y.c, 42 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Skipping test because compiler doesn't support in-class member initializers" )
|
||||
|
||||
int main() {}
|
||||
|
||||
#endif
|
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "boost/utility/value_init.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#ifdef BOOST_BORLANDC
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "boost/utility/value_init.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#ifdef BOOST_BORLANDC
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "boost/utility/value_init.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#ifdef BOOST_BORLANDC
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user