1
0
forked from boostorg/core

Compare commits

...

35 Commits

Author SHA1 Message Date
Peter Dimov
cf66842419 MinGW doesn't have _exit either 2018-09-05 08:39:35 +03:00
Peter Dimov
861eb5cf4c Merge branch 'develop' into feature/Exit 2018-09-05 07:24:23 +03:00
Peter Dimov
205b319b57 Use _exit instead of _Exit on MinGW 2018-09-05 07:17:58 +03:00
Glen Fernandes
6f1d88d153 Provide detail::test_errors() as others are using it 2018-09-05 00:16:17 -04:00
Peter Dimov
7f7c4c5b83 Call _set_abort_behavior on all compilers impersonating MSVC 2018-09-05 07:01:29 +03:00
Peter Dimov
dfd5a0b8db Remove dead #else branch 2018-09-05 06:56:59 +03:00
Peter Dimov
d8c0768788 Use _Exit(3) instead of abort() to avoid core dump 2018-09-05 06:26:40 +03:00
Peter Dimov
d0a9206d6a Call _set_abort_behavior on clang-win too 2018-09-05 06:04:53 +03:00
Glen Fernandes
76c3538315 Suppress MSVC error dialogs and add test for report_errors() 2018-09-04 21:16:36 -04:00
Glen Fernandes
f2638b6d64 Merge pull request #40 from glenfe/develop
Abort instead of assert if report_errors() not called
2018-09-04 20:25:11 -04:00
Glen Fernandes
30c006ac82 Call test_results() in BOOST_TEST() 2018-09-04 20:22:56 -04:00
Glen Fernandes
c71eb0e479 Abort instead of assert if report_errors() not called 2018-09-04 17:00:50 -04:00
Glen Fernandes
3f7d36445d Reduce statics in Lightweight_test 2018-09-04 16:53:25 -04:00
Peter Dimov
a08dda22b2 Remove clang-3.7 from Travis, as it's not in trusty-updates and the -precise sources no longer work 2018-08-31 01:52:04 +03:00
Glen Fernandes
2d99acd7ec Name the empty_value template parameters 2018-08-27 22:48:06 -04:00
Glen Fernandes
65b98db868 Update formatting in documentation 2018-08-27 00:57:45 -04:00
Glen Fernandes
edcd9e2cf5 Add documentation for empty_value 2018-08-26 20:16:26 -04:00
Glen Fernandes
2eaba7d6d1 Make empty_value<T> trivial if T is trivial 2018-08-26 02:10:02 -04:00
Peter Dimov
a05906fd44 Add comment describing noncopyable_::base_token 2018-08-25 15:15:53 +03:00
Peter Dimov
f3782a946f Derive noncopyable from a base_token class to allow it to be detected by Type Traits without an #include 2018-08-25 01:47:47 +03:00
Glen Fernandes
f504872d89 Implement empty_value 2018-08-24 16:24:34 -04:00
Glen Fernandes
e1f070b7b4 Remove anti_op and change the error output
The new output is no less useful, and not potentially misleading (for example in the case of BOOST_TEST_LT(1, nan) failing, it was not right to say that 1 >= nan).
2018-08-09 08:04:09 -04:00
Hans Dembinski
740f2142c5 new test backend based on predicates (#39)
* Work in progress, some tests fail

* adding tests

* missing header

* moved close_to to detail, added constness, replaced predicates from <functional> with custom ones, new code does not rely on partial template specialization

* renamed predicates and removed close_to predicate

* removing now superfluous headers

* unpatching the fix to put in a separate PR

* move predicate to first argument

* call op and anti_op as normal methods
2018-08-08 15:37:51 +03:00
Peter Dimov
5c10ee4517 explicit_operator_bool: fix g++ 4.6 workaround 2018-08-08 00:27:59 +03:00
Peter Dimov
b7ad896707 explicit_operator_bool: under g++ 4.6 the operator can't be constexpr 2018-08-07 22:59:25 +03:00
Peter Dimov
70413b0568 Add more Travis configurations 2018-08-07 18:50:14 +03:00
Peter Dimov
b8a9b2c234 Add lightweight_test_test3 2018-08-07 17:58:23 +03:00
Peter Dimov
e11fa9ac03 In lightweight_test_eq_nullptr, test with nullptr as first argument as well 2018-08-07 17:43:38 +03:00
Peter Dimov
e1d50a1de2 Fix typo in lightweight_test.hpp 2018-08-07 17:40:47 +03:00
Glen Fernandes
e128f4e1b8 Add documentation for exchange 2018-07-20 08:25:48 -04:00
Glen Fernandes
cc119253b4 Simplify test case; type does not need to be noncopyable 2018-07-12 21:48:05 -04:00
Glen Fernandes
19ec659a91 Simplify exchange implementation for pre-C++11 2018-07-09 08:48:50 -04:00
Glen Fernandes
75ae238d0c Use #else instead of #elif BOOST_WORKAROUND 2018-07-08 12:04:09 -04:00
Glen Fernandes
630ab2aae4 Workaround MSVC10 and MSVC11 for exchange 2018-07-08 11:18:17 -04:00
Glen Fernandes
2cd4753a02 Implement boost::exchange 2018-07-08 09:25:07 -04:00
20 changed files with 1052 additions and 158 deletions

View File

@@ -28,6 +28,26 @@ matrix:
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
- os: linux
compiler: g++-4.4
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
addons:
apt:
packages:
- g++-4.4
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.6
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
addons:
apt:
packages:
- g++-4.6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.7
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
@@ -89,6 +109,16 @@ matrix:
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
@@ -103,7 +133,6 @@ matrix:
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
- os: linux
compiler: clang++-3.6
@@ -112,20 +141,9 @@ matrix:
apt:
packages:
- clang-3.6
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
- os: linux
compiler: clang++-3.7
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
- os: linux
compiler: clang++-3.8
@@ -137,7 +155,6 @@ matrix:
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
- os: linux
compiler: clang++-3.9
@@ -149,7 +166,6 @@ matrix:
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.9
- os: linux
compiler: clang++-4.0
@@ -173,6 +189,25 @@ matrix:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
- os: linux
compiler: clang++-6.0
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17
addons:
apt:
packages:
- clang-6.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-6.0
- os: linux
compiler: clang++-libc++
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
addons:
apt:
packages:
- libc++-dev
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z

View File

@@ -41,7 +41,9 @@ criteria for inclusion is that the utility component be:
[include addressof.qbk]
[include checked_delete.qbk]
[include demangle.qbk]
[include empty_value.qbk]
[include enable_if.qbk]
[include exchange.qbk]
[include explicit_operator_bool.qbk]
[include ignore_unused.qbk]
[include is_same.qbk]

129
doc/empty_value.qbk Normal file
View File

@@ -0,0 +1,129 @@
[/
Copyright 2018 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]
[section:empty_value empty_value]
[simplesect Authors]
* Glen Fernandes
[endsimplesect]
[section Overview]
The header <boost/core/empty_value.hpp> provides the class template
`boost::empty_value` for library authors to conveniently leverage the Empty
Base Optimization to store objects of potentially empty types.
[endsect]
[section Examples]
The following example shows `boost::empty_value` used to create a type that
stores a pointer, comparer, and allocator, where the comparer and allocator
could be empty types.
```
template<class Ptr, class Compare, class Allocator>
class storage
: empty_value<Compare, 0>
, empty_value<Allocator, 1> {
public:
storage()
: empty_value<Compare, 0>(empty_init_t())
, empty_value<Allocator, 1>(empty_init_t())
, ptr_() { }
storage(const Compare& c, const Allocator& a)
: empty_value<Compare, 0>(empty_init_t(), c)
, empty_value<Allocator, 1>(empty_init_t(), a)
, ptr_() { }
const Ptr& pointer() const {
return ptr_;
}
Ptr& pointer() {
return ptr_;
}
const Compare& compare() const {
return empty_value<Compare, 0>::get();
}
Compare& compare() {
return empty_value<Compare, 0>::get();
}
const Allocator& allocator() const {
return empty_value<Allocator, 1>::get();
}
Allocator& allocator() {
return empty_value<Allocator, 1>::get();
}
private:
Ptr ptr_;
};
```
[endsect]
[section Reference]
```
namespace boost {
struct empty_init_t { };
template<class T, unsigned Index = 0, bool Empty = ``/see below/``>
class empty_value {
public:
empty_value() = default;
template<class... Args>
explicit empty_value(empty_init_t, Args&&... args);
const T& get() const;
T& get();
};
} /* boost */
```
[section Template parameters]
[variablelist
[[`T`][The type of value to store]]
[[`Index`][Optional: Specify to create a distinct base type]]
[[`Empty`][Optional: Specify to force inheritance from type]]]
[endsect]
[section Constructors]
[variablelist
[[`empty_value() = default;`][Default initialize the value]]
[[`template<class... Args> empty_value(empty_init_t, Args&&... args);`]
[Initialize the value with `std::forward<Args>(args)...`]]]
[endsect]
[section Member functions]
[variablelist
[[`const T& get() const;`][Returns the value]]
[[`T& get();`][Returns the value]]]
[endsect]
[endsect]
[endsect]

62
doc/exchange.qbk Normal file
View File

@@ -0,0 +1,62 @@
[/
Copyright 2018 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]
[section:exchange exchange]
[simplesect Authors]
* Glen Fernandes
[endsimplesect]
[section Overview]
The header <boost/core/exchange.hpp> provides the function template
`boost::exchange` which is an implementation of the `std::exchange`
function introduced in C++14.
[endsect]
[section Examples]
The following example shows `boost::exchange` used to simplify the
implementation of a move constructor.
```
Node(Node&& other)
: head_(boost::exchange(other.head_, nullptr))
, tail_(boost::exchange(other.tail_, nullptr)) { }
```
[endsect]
[section Reference]
```
namespace boost {
template<class T, class U = T>
constexpr T exchange(T& t, U&& u);
}
```
[section Functions]
[*`template<class T, class U = T> constexpr T exchange(T& t, U&& u);`]
Equivalent to:
```
T v = std::move(t);
t = std::forward<U>(u);
return v;
```
[endsect]
[endsect]
[endsect]

View File

@@ -0,0 +1,125 @@
/*
Copyright 2018 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CORE_EMPTY_VALUE_HPP
#define BOOST_CORE_EMPTY_VALUE_HPP
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#include <utility>
#endif
#if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40700)
#define BOOST_DETAIL_EMPTY_VALUE_BASE
#elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1800)
#define BOOST_DETAIL_EMPTY_VALUE_BASE
#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1800)
#define BOOST_DETAIL_EMPTY_VALUE_BASE
#elif defined(BOOST_CLANG) && !defined(__CUDACC__)
#if __has_feature(is_empty) && __has_feature(is_final)
#define BOOST_DETAIL_EMPTY_VALUE_BASE
#endif
#endif
namespace boost {
template<class T>
struct use_empty_value_base {
enum {
#if defined(BOOST_DETAIL_EMPTY_VALUE_BASE)
value = __is_empty(T) && !__is_final(T)
#else
value = false
#endif
};
};
struct empty_init_t { };
template<class T, unsigned N = 0, bool E = use_empty_value_base<T>::value>
class empty_value {
public:
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
empty_value() = default;
#else
empty_value() { }
#endif
empty_value(empty_init_t)
: value_() { }
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class... Args>
explicit empty_value(empty_init_t, Args&&... args)
: value_(std::forward<Args>(args)...) { }
#else
template<class U>
empty_value(empty_init_t, U&& value)
: value_(std::forward<U>(value)) { }
#endif
#else
template<class U>
empty_value(empty_init_t, const U& value)
: value_(value) { }
#endif
const T& get() const BOOST_NOEXCEPT {
return value_;
}
T& get() BOOST_NOEXCEPT {
return value_;
}
private:
T value_;
};
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template<class T, unsigned N>
class empty_value<T, N, true>
: T {
public:
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
empty_value() = default;
#else
empty_value() { }
#endif
empty_value(empty_init_t)
: T() { }
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class... Args>
explicit empty_value(empty_init_t, Args&&... args)
: T(std::forward<Args>(args)...) { }
#else
template<class U>
empty_value(empty_init_t, U&& value)
: T(std::forward<U>(value)) { }
#endif
#else
template<class U>
empty_value(empty_init_t, const U& value)
: T(value) { }
#endif
const T& get() const BOOST_NOEXCEPT {
return *this;
}
T& get() BOOST_NOEXCEPT {
return *this;
}
};
#endif
} /* boost */
#endif

View File

@@ -0,0 +1,49 @@
/*
Copyright 2018 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CORE_EXCHANGE_HPP
#define BOOST_CORE_EXCHANGE_HPP
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#include <boost/config/workaround.hpp>
#include <utility>
#endif
namespace boost {
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<class T, class U>
inline T exchange(T& t, const U& u)
{
T v = t;
t = u;
return v;
}
#else
#if BOOST_WORKAROUND(BOOST_MSVC, < 1800)
template<class T, class U>
inline T exchange(T& t, U&& u)
{
T v = std::move(t);
t = std::forward<U>(u);
return v;
}
#else
template<class T, class U = T>
BOOST_CXX14_CONSTEXPR inline T exchange(T& t, U&& u)
{
T v = std::move(t);
t = std::forward<U>(u);
return v;
}
#endif
#endif
} /* boost */
#endif

View File

@@ -19,6 +19,7 @@
#define BOOST_CORE_EXPLICIT_OPERATOR_BOOL_HPP
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
@@ -52,6 +53,8 @@
return !this->operator! ();\
}
#if !BOOST_WORKAROUND(BOOST_GCC, < 40700)
/*!
* \brief The macro defines a constexpr explicit operator of conversion to \c bool
*
@@ -65,6 +68,12 @@
return !this->operator! ();\
}
#else
#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL() BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
#endif
#else // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
#if (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG)

View File

@@ -14,16 +14,19 @@
// Copyright (2) Beman Dawes 2010, 2011
// Copyright (3) Ion Gaztanaga 2013
//
// Copyright 2018 Glen Joseph Fernandes
// (glenjofe@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
//
#include <boost/core/no_exceptions_support.hpp>
#include <boost/assert.hpp>
#include <boost/current_function.hpp>
#include <iostream>
#include <iterator>
#include <cstdlib>
#include <cstring>
#include <cstddef>
@@ -39,29 +42,52 @@ namespace boost
namespace detail
{
struct report_errors_reminder
{
bool called_report_errors_function;
report_errors_reminder() : called_report_errors_function(false) {}
~report_errors_reminder()
{
BOOST_ASSERT(called_report_errors_function); // verify report_errors() was called
class test_result {
public:
test_result()
: report_(false)
, errors_(0) {
#if defined(_MSC_VER)
::_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
#endif
}
~test_result() {
if (!report_) {
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "main() should return report_errors()" << std::endl;
#if defined(_MSC_VER)
::_exit( 3 );
#elif defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
std::abort();
#else
::_Exit( 3 );
#endif
}
}
int& errors() {
return errors_;
}
void done() {
report_ = true;
}
private:
bool report_;
int errors_;
};
inline report_errors_reminder& report_errors_remind()
inline test_result& test_results()
{
static report_errors_reminder r;
return r;
static test_result instance;
return instance;
}
inline int & test_errors()
inline int& test_errors()
{
static int x = 0;
report_errors_remind();
return x;
return test_results().errors();
}
inline void test_failed_impl(char const * expr, char const * file, int line, char const * function)
@@ -69,7 +95,7 @@ inline void test_failed_impl(char const * expr, char const * file, int line, cha
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): test '" << expr << "' failed in function '"
<< function << "'" << std::endl;
++test_errors();
++test_results().errors();
}
inline void error_impl(char const * msg, char const * file, int line, char const * function)
@@ -77,7 +103,7 @@ inline void error_impl(char const * msg, char const * file, int line, char const
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): " << msg << " in function '"
<< function << "'" << std::endl;
++test_errors();
++test_results().errors();
}
inline void throw_failed_impl(char const * excep, char const * file, int line, char const * function)
@@ -85,7 +111,7 @@ inline void throw_failed_impl(char const * excep, char const * file, int line, c
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): Exception '" << excep << "' not thrown in function '"
<< function << "'" << std::endl;
++test_errors();
++test_results().errors();
}
// In the comparisons below, it is possible that T and U are signed and unsigned integer types, which generates warnings in some compilers.
@@ -118,105 +144,58 @@ template<class T> inline const void* test_output_impl(T volatile* v) { return co
inline const void* test_output_impl(std::nullptr_t) { return nullptr; }
#endif
template<class T, class U> inline void test_eq_impl( char const * expr1, char const * expr2,
char const * file, int line, char const * function, T const & t, U const & u )
{
if( t == u )
{
report_errors_remind();
}
else
{
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): test '" << expr1 << " == " << expr2
<< "' failed in function '" << function << "': "
<< "'" << test_output_impl(t) << "' != '" << test_output_impl(u) << "'" << std::endl;
++test_errors();
}
}
struct lw_test_eq {
template <typename T, typename U>
bool operator()(const T& t, const U& u) const { return t == u; }
static const char* op() { return "=="; }
};
template<class T, class U> inline void test_ne_impl( char const * expr1, char const * expr2,
char const * file, int line, char const * function, T const & t, U const & u )
{
if( t != u )
{
report_errors_remind();
}
else
{
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): test '" << expr1 << " != " << expr2
<< "' failed in function '" << function << "': "
<< "'" << test_output_impl(t) << "' == '" << test_output_impl(u) << "'" << std::endl;
++test_errors();
}
}
struct lw_test_ne {
template <typename T, typename U>
bool operator()(const T& t, const U& u) const { return t != u; }
static const char* op() { return "!="; }
};
template<class T, class U> inline void test_lt_impl( char const * expr1, char const * expr2,
char const * file, int line, char const * function, T const & t, U const & u )
{
if( t < u )
{
report_errors_remind();
}
else
{
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): test '" << expr1 << " < " << expr2
<< "' failed in function '" << function << "': "
<< "'" << test_output_impl(t) << "' >= '" << test_output_impl(u) << "'" << std::endl;
++test_errors();
}
}
struct lw_test_lt {
template <typename T, typename U>
bool operator()(const T& t, const U& u) const { return t < u; }
static const char* op() { return "<"; }
};
template<class T, class U> inline void test_le_impl( char const * expr1, char const * expr2,
char const * file, int line, char const * function, T const & t, U const & u )
{
if( t <= u )
{
report_errors_remind();
}
else
{
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): test '" << expr1 << " <= " << expr2
<< "' failed in function '" << function << "': "
<< "'" << test_output_impl(t) << "' > '" << test_output_impl(u) << "'" << std::endl;
++test_errors();
}
}
struct lw_test_le {
template <typename T, typename U>
bool operator()(const T& t, const U& u) const { return t <= u; }
static const char* op() { return "<="; }
};
template<class T, class U> inline void test_gt_impl( char const * expr1, char const * expr2,
char const * file, int line, char const * function, T const & t, U const & u )
{
if( t > u )
{
report_errors_remind();
}
else
{
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): test '" << expr1 << " > " << expr2
<< "' failed in function '" << function << "': "
<< "'" << test_output_impl(t) << "' <= '" << test_output_impl(u) << "'" << std::endl;
++test_errors();
}
}
struct lw_test_gt {
template <typename T, typename U>
bool operator()(const T& t, const U& u) const { return t > u; }
static const char* op() { return ">"; }
};
template<class T, class U> inline void test_ge_impl( char const * expr1, char const * expr2,
char const * file, int line, char const * function, T const & t, U const & u )
struct lw_test_ge {
template <typename T, typename U>
bool operator()(const T& t, const U& u) const { return t >= u; }
static const char* op() { return ">="; }
};
template<class BinaryPredicate, class T, class U>
inline void test_with_impl(BinaryPredicate pred, char const * expr1, char const * expr2,
char const * file, int line, char const * function,
T const & t, U const & u)
{
if( t >= u )
if( pred(t, u) )
{
report_errors_remind();
test_results();
}
else
{
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): test '" << expr1 << " >= " << expr2
<< "' failed in function '" << function << "': "
<< "'" << test_output_impl(t) << "' < '" << test_output_impl(u) << "'" << std::endl;
++test_errors();
<< file << "(" << line << "): test '" << expr1 << " " << pred.op() << " " << expr2
<< "' ('" << test_output_impl(t) << "' " << pred.op() << " '" << test_output_impl(u)
<< "') failed in function '" << function << "'" << std::endl;
++test_results().errors();
}
}
@@ -225,15 +204,14 @@ inline void test_cstr_eq_impl( char const * expr1, char const * expr2,
{
if( std::strcmp(t, u) == 0 )
{
report_errors_remind();
test_results();
}
else
{
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): test '" << expr1 << " == " << expr2
<< "' failed in function '" << function << "': "
<< "'" << t << "' != '" << u << "'" << std::endl;
++test_errors();
<< file << "(" << line << "): test '" << expr1 << " == " << expr2 << "' ('" << t
<< "' == '" << u << "') failed in function '" << function << "'" << std::endl;
++test_results().errors();
}
}
@@ -242,15 +220,14 @@ inline void test_cstr_ne_impl( char const * expr1, char const * expr2,
{
if( std::strcmp(t, u) != 0 )
{
report_errors_remind();
test_results();
}
else
{
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): test '" << expr1 << " == " << expr2
<< "' failed in function '" << function << "': "
<< "'" << t << "' == '" << u << "'" << std::endl;
++test_errors();
<< file << "(" << line << "): test '" << expr1 << " != " << expr2 << "' ('" << t
<< "' != '" << u << "') failed in function '" << function << "'" << std::endl;
++test_results().errors();
}
}
@@ -313,12 +290,12 @@ void test_all_eq_impl(FormattedOutputFunction& output,
if (error_count == 0)
{
boost::detail::report_errors_remind();
test_results();
}
else
{
output << std::endl;
++boost::detail::test_errors();
++test_results().errors();
}
}
@@ -382,12 +359,12 @@ void test_all_with_impl(FormattedOutputFunction& output,
if (error_count == 0)
{
report_errors_remind();
test_results();
}
else
{
output << std::endl;
++test_errors();
++test_results().errors();
}
}
@@ -405,10 +382,10 @@ void test_all_with_impl(FormattedOutputFunction& output,
inline int report_errors()
{
boost::detail::report_errors_remind().called_report_errors_function = true;
int errors = boost::detail::test_errors();
boost::detail::test_result& result = boost::detail::test_results();
result.done();
int errors = result.errors();
if( errors == 0 )
{
BOOST_LIGHTWEIGHT_TEST_OSTREAM
@@ -425,18 +402,18 @@ inline int report_errors()
} // namespace boost
#define BOOST_TEST(expr) ((expr)? (void)0: ::boost::detail::test_failed_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION))
#define BOOST_TEST(expr) ((expr)? (void)::boost::detail::test_results(): ::boost::detail::test_failed_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION))
#define BOOST_TEST_NOT(expr) BOOST_TEST(!(expr))
#define BOOST_ERROR(msg) ( ::boost::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
#define BOOST_TEST_EQ(expr1,expr2) ( ::boost::detail::test_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_NE(expr1,expr2) ( ::boost::detail::test_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_EQ(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_eq(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_NE(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_ne(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_LT(expr1,expr2) ( ::boost::detail::test_lt_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_LE(expr1,expr2) ( ::boost::detail::test_le_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_GT(expr1,expr2) ( ::boost::detail::test_gt_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_GE(expr1,expr2) ( ::boost::detail::test_ge_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_LT(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_lt(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_LE(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_le(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_GT(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_gt(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_GE(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_ge(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_CSTR_EQ(expr1,expr2) ( ::boost::detail::test_cstr_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_CSTR_NE(expr1,expr2) ( ::boost::detail::test_cstr_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )

View File

@@ -31,7 +31,7 @@ template< class T > inline void test_trait_impl( char const * trait, void (*)( T
{
if( T::value == expected )
{
report_errors_remind();
test_results();
}
else
{
@@ -42,7 +42,7 @@ template< class T > inline void test_trait_impl( char const * trait, void (*)( T
<< "' (should have been " << ( expected? "true": "false" ) << ")"
<< std::endl;
++test_errors();
++test_results().errors();
}
}

View File

@@ -20,7 +20,22 @@ namespace boost {
namespace noncopyable_ // protection from unintended ADL
{
class noncopyable
#ifndef BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED
#define BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED
// noncopyable derives from base_token to enable Type Traits to detect
// whether a type derives from noncopyable without needing the definition
// of noncopyable itself.
//
// The definition of base_token is macro-guarded so that Type Trais can
// define it locally without including this header, to avoid a dependency
// on Core.
struct base_token {};
#endif // #ifndef BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED
class noncopyable: base_token
{
protected:
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)

View File

@@ -68,15 +68,14 @@ run get_pointer_test.cpp ;
run lightweight_test_test.cpp ;
run lightweight_test_test.cpp : : : <exception-handling>off : lightweight_test_test_no_except ;
run lightweight_test_test2.cpp ;
run lightweight_test_all_eq_test.cpp ;
run lightweight_test_all_with_test.cpp ;
run lightweight_test_all_with_fail.cpp ;
run lightweight_test_lt_le_test.cpp ;
run lightweight_test_gt_ge_test.cpp ;
run lightweight_test_eq_nullptr.cpp ;
run lightweight_test_test3.cpp ;
run-fail lightweight_test_fail.cpp ;
run-fail lightweight_test_fail2.cpp ;
@@ -90,6 +89,7 @@ run-fail lightweight_test_fail8.cpp ;
run-fail lightweight_test_fail8.cpp : : : <rtti>off : lightweight_test_fail8_no_rtti ;
run-fail lightweight_test_fail9.cpp ;
run-fail lightweight_test_fail10.cpp ;
run-fail lightweight_test_fail11.cpp ;
run-fail lightweight_test_lt_fail.cpp ;
run-fail lightweight_test_le_fail.cpp ;
run-fail lightweight_test_gt_fail.cpp ;
@@ -121,5 +121,11 @@ run pointer_traits_rebind_test.cpp ;
run pointer_traits_pointer_to_test.cpp ;
run to_address_test.cpp ;
run exchange_test.cpp ;
run exchange_move_test.cpp ;
run empty_value_test.cpp ;
run empty_value_size_test.cpp ;
use-project /boost/core/swap : ./swap ;
build-project ./swap ;

View File

@@ -0,0 +1,60 @@
/*
Copyright 2018 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_TEMPLATE_PARTIAL_SPECIALIZATION)
#include <boost/core/empty_value.hpp>
#include <boost/core/lightweight_test.hpp>
struct T1 { };
struct S1
: boost::empty_value<T1, 0, true> { };
struct T2 {
int value;
};
struct S2
: boost::empty_value<T1, 0, true>
, boost::empty_value<T2, 1, true> { };
struct S3
: boost::empty_value<T1, 0, false>
, boost::empty_value<T2, 1, true> { };
struct T3 { };
struct S4
: boost::empty_value<T1, 0, true>
, boost::empty_value<T3, 1, true> { };
struct S5
: boost::empty_value<T1, 0, false>
, boost::empty_value<T3, 1, false> { };
struct S6
: boost::empty_value<T1, 0, true>
, boost::empty_value<T2, 1, true>
, boost::empty_value<T3, 2, true> { };
int main()
{
BOOST_TEST(sizeof(S1) == sizeof(T1));
BOOST_TEST(sizeof(S2) == sizeof(T2));
BOOST_TEST(sizeof(S3) > sizeof(T2));
BOOST_TEST(sizeof(S4) == sizeof(T1));
BOOST_TEST(sizeof(S5) > sizeof(T1));
BOOST_TEST(sizeof(S6) == sizeof(T2));
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

76
test/empty_value_test.cpp Normal file
View File

@@ -0,0 +1,76 @@
/*
Copyright 2018 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/core/empty_value.hpp>
#include <boost/core/lightweight_test.hpp>
struct empty {
operator bool() const {
return false;
}
operator bool() {
return true;
}
};
class type {
public:
type()
: value_(false) { }
explicit type(bool value)
: value_(value) { }
operator bool() const {
return value_;
}
private:
bool value_;
};
void test_bool()
{
const boost::empty_value<bool> v1(boost::empty_init_t(), true);
BOOST_TEST(v1.get());
boost::empty_value<bool> v2 = boost::empty_init_t();
BOOST_TEST(!v2.get());
v2 = v1;
BOOST_TEST(v2.get());
v2.get() = false;
BOOST_TEST(!v2.get());
}
void test_empty()
{
empty e;
const boost::empty_value<empty> v1(boost::empty_init_t(), e);
BOOST_TEST(!v1.get());
boost::empty_value<empty> v2;
BOOST_TEST(v2.get());
v2 = v1;
BOOST_TEST(v2.get());
v2.get() = empty();
BOOST_TEST(v2.get());
}
void test_type()
{
const boost::empty_value<type> v1(boost::empty_init_t(), true);
BOOST_TEST(v1.get());
boost::empty_value<type> v2;
BOOST_TEST(!v2.get());
v2 = v1;
BOOST_TEST(v2.get());
v2.get() = type();
BOOST_TEST(!v2.get());
}
int main()
{
test_bool();
test_empty();
test_type();
return boost::report_errors();
}

100
test/exchange_move_test.cpp Normal file
View File

@@ -0,0 +1,100 @@
/*
Copyright 2018 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_RVALUE_REFERENCES)
#include <boost/core/exchange.hpp>
#include <boost/core/lightweight_test.hpp>
class C1 {
public:
explicit C1(int i)
: i_(i) { }
C1(C1&& c)
: i_(c.i_) { }
C1& operator=(C1&& c) {
i_ = c.i_;
return *this;
}
int i() const {
return i_;
}
private:
C1(const C1&);
C1& operator=(const C1&);
int i_;
};
void test1()
{
C1 x(1);
BOOST_TEST(boost::exchange(x, C1(2)).i() == 1);
BOOST_TEST(x.i() == 2);
}
class C2 {
public:
explicit C2(int i)
: i_(i) { }
operator C1() const {
return C1(i_);
}
int i() const {
return i_;
}
private:
C2(const C2&);
C2& operator=(const C2&);
int i_;
};
void test2()
{
C1 x(1);
BOOST_TEST(boost::exchange(x, C2(2)).i() == 1);
BOOST_TEST(x.i() == 2);
}
class C3 {
public:
explicit C3(int i)
: i_(i) { }
C3(C3&& c)
: i_(c.i_) { }
C3& operator=(C1&& c) {
i_ = c.i();
return *this;
}
int i() const {
return i_;
}
private:
C3(const C3&);
C3& operator=(const C3&);
int i_;
};
void test3()
{
C3 x(1);
BOOST_TEST(boost::exchange(x, C1(2)).i() == 1);
BOOST_TEST(x.i() == 2);
}
int main()
{
test1();
test2();
test3();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

89
test/exchange_test.cpp Normal file
View File

@@ -0,0 +1,89 @@
/*
Copyright 2018 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/core/exchange.hpp>
#include <boost/core/lightweight_test.hpp>
void test1()
{
int i = 1;
BOOST_TEST(boost::exchange(i, 2) == 1);
BOOST_TEST(i == 2);
}
class C1 {
public:
explicit C1(int i)
: i_(i) { }
int i() const {
return i_;
}
private:
int i_;
};
void test2()
{
C1 x(1);
BOOST_TEST(boost::exchange(x, C1(2)).i() == 1);
BOOST_TEST(x.i() == 2);
}
class C2 {
public:
explicit C2(int i)
: i_(i) { }
operator C1() const {
return C1(i_);
}
int i() const {
return i_;
}
private:
int i_;
};
void test3()
{
C1 x(1);
BOOST_TEST(boost::exchange(x, C2(2)).i() == 1);
BOOST_TEST(x.i() == 2);
}
class C3 {
public:
explicit C3(int i)
: i_(i) { }
C3(const C3& c)
: i_(c.i_) { }
C3& operator=(const C1& c) {
i_ = c.i();
return *this;
}
int i() const {
return i_;
}
private:
C3& operator=(const C3&);
int i_;
};
void test4()
{
C3 x(1);
BOOST_TEST(boost::exchange(x, C1(2)).i() == 1);
BOOST_TEST(x.i() == 2);
}
int main()
{
test1();
test2();
test3();
test4();
return boost::report_errors();
}

View File

@@ -120,7 +120,5 @@ int main()
++test_cases;
}
boost::report_errors();
return boost::detail::test_errors() != test_cases;
return !boost::report_errors();
}

View File

@@ -101,7 +101,5 @@ int main()
test_cases += fail_vector();
test_cases += fail_tolerance_predicate();
boost::report_errors();
return boost::detail::test_errors() != test_cases;
return !boost::report_errors();
}

View File

@@ -22,6 +22,9 @@ int main()
BOOST_TEST_EQ( p1, nullptr );
BOOST_TEST_NE( p2, nullptr );
BOOST_TEST_EQ( nullptr, p1 );
BOOST_TEST_NE( nullptr, p2 );
#endif
return boost::report_errors();

View File

@@ -0,0 +1,14 @@
/*
Copyright 2018 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/core/lightweight_test.hpp>
int main()
{
BOOST_TEST(true);
return 0;
}

View File

@@ -0,0 +1,147 @@
//
// Test for lightweight_test.hpp
//
// Copyright (c) 2014, 2018 Peter Dimov
//
// 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
//
#include <boost/core/lightweight_test.hpp>
#include <boost/core/noncopyable.hpp>
#include <ostream>
// EQ
struct eq1: private boost::noncopyable {};
struct eq2: private boost::noncopyable {};
std::ostream& operator<<( std::ostream& os, eq1 const& )
{
return os << "eq1()";
}
std::ostream& operator<<( std::ostream& os, eq2 const& )
{
return os << "eq2()";
}
bool operator==( eq1 const&, eq2 const& )
{
return true;
}
// NE
struct ne1: private boost::noncopyable {};
struct ne2: private boost::noncopyable {};
std::ostream& operator<<( std::ostream& os, ne1 const& )
{
return os << "ne1()";
}
std::ostream& operator<<( std::ostream& os, ne2 const& )
{
return os << "ne2()";
}
bool operator!=( ne1 const&, ne2 const& )
{
return true;
}
// LT
struct lt1: private boost::noncopyable {};
struct lt2: private boost::noncopyable {};
std::ostream& operator<<( std::ostream& os, lt1 const& )
{
return os << "lt1()";
}
std::ostream& operator<<( std::ostream& os, lt2 const& )
{
return os << "lt2()";
}
bool operator<( lt1 const&, lt2 const& )
{
return true;
}
// LE
struct le1: private boost::noncopyable {};
struct le2: private boost::noncopyable {};
std::ostream& operator<<( std::ostream& os, le1 const& )
{
return os << "le1()";
}
std::ostream& operator<<( std::ostream& os, le2 const& )
{
return os << "le2()";
}
bool operator<=( le1 const&, le2 const& )
{
return true;
}
// GT
struct gt1: private boost::noncopyable {};
struct gt2: private boost::noncopyable {};
std::ostream& operator<<( std::ostream& os, gt1 const& )
{
return os << "gt1()";
}
std::ostream& operator<<( std::ostream& os, gt2 const& )
{
return os << "gt2()";
}
bool operator>( gt1 const&, gt2 const& )
{
return true;
}
// GE
struct ge1: private boost::noncopyable {};
struct ge2: private boost::noncopyable {};
std::ostream& operator<<( std::ostream& os, ge1 const& )
{
return os << "ge1()";
}
std::ostream& operator<<( std::ostream& os, ge2 const& )
{
return os << "ge2()";
}
bool operator>=( ge1 const&, ge2 const& )
{
return true;
}
//
int main()
{
BOOST_TEST_EQ( eq1(), eq2() );
BOOST_TEST_NE( ne1(), ne2() );
BOOST_TEST_LT( lt1(), lt2() );
BOOST_TEST_LE( le1(), le2() );
BOOST_TEST_GT( gt1(), gt2() );
BOOST_TEST_GE( ge1(), ge2() );
return boost::report_errors();
}