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,89 @@
# Boost.Optional Library test Jamfile
#
# Copyright (C) 2003, Fernando Luis Cacciola Carballal.
# Copyright (C) 2014 - 2017 Andrzej Krzemienski
#
# Use, modification, and distribution is 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)
#
# See http://www.boost.org/libs/optional for documentation.
#
# You are welcome to contact the author at:
# akrzemi1@gmail.com
#
import testing ;
{
test-suite optional :
[ run optional_test.cpp ]
[ run optional_test_assign.cpp ]
[ run optional_test_swap.cpp ]
[ run optional_test_conversions_from_U.cpp ]
[ run optional_test_convert_from_T.cpp ]
[ run optional_test_empty_braces.cpp ]
[ run optional_test_make_optional.cpp ]
[ run optional_test_flat_map.cpp ]
[ run optional_test_map.cpp ]
[ run optional_test_tie.cpp ]
[ run optional_test_ref_assign_portable_minimum.cpp ]
[ run optional_test_ref_assign_mutable_int.cpp ]
[ run optional_test_ref_assign_const_int.cpp ]
[ run optional_test_ref_converting_ctor.cpp ]
[ run optional_test_ref_convert_assign_non_int.cpp ]
[ run optional_test_ref_convert_assign_mutable_int.cpp ]
[ run optional_test_ref_convert_assign_const_int.cpp ]
[ run optional_test_ref_portable_minimum.cpp ]
[ run optional_test_ref_move.cpp ]
[ run optional_test_ref_to_val.cpp ]
[ run optional_test_inplace_factory.cpp ]
[ run optional_test_io.cpp ]
[ run optional_test_move.cpp ]
[ run optional_test_noexcept_move.cpp ]
[ run optional_test_old_impl.cpp ]
[ run optional_test_equals_none.cpp ]
[ run optional_test_value_access.cpp ]
[ run optional_test_emplace.cpp ]
[ run optional_test_minimum_requirements.cpp ]
[ run optional_test_msvc_bug_workaround.cpp ]
[ run optional_test_member_T.cpp ]
[ run optional_test_tc_base.cpp ]
[ compile optional_test_sfinae_friendly_ctor.cpp ]
[ compile optional_test_path_assignment.cpp ]
[ compile-fail optional_test_fail_const_swap.cpp ]
[ compile-fail optional_test_ref_convert_assign_const_int_prevented.cpp ]
[ compile-fail optional_test_fail1.cpp ]
[ compile-fail optional_test_fail3a.cpp ]
[ compile-fail optional_test_fail3b.cpp ]
[ compile-fail optional_test_ref_fail1.cpp ]
[ compile-fail optional_test_ref_fail3.cpp ]
[ compile-fail optional_test_ref_fail4.cpp ]
[ compile-fail optional_test_inplace_fail.cpp ]
[ compile-fail optional_test_inplace_fail2.cpp ]
[ compile-fail optional_test_fail_implicit_bool_convert.cpp ]
[ compile-fail optional_test_fail_copying_a_moveable_type.cpp ]
[ compile-fail optional_test_fail_optional_rvalue_ref.cpp ]
[ compile-fail optional_test_ref_fail_init_from_Trefref.cpp ]
[ compile-fail optional_test_ref_fail_init_from_Urefref.cpp ]
[ compile-fail optional_test_ref_fail_assign_from_Trefref.cpp ]
[ compile-fail optional_test_ref_fail_assign_from_Urefref.cpp ]
[ compile-fail optional_test_fail_convert_from_null.cpp ]
[ compile-fail optional_test_fail_explicit_convert_in_value_or.cpp ]
[ compile-fail optional_test_fail_explicit_convert_in_value_or_call.cpp ]
[ compile-fail optional_test_fail_io_without_io.cpp ]
[ compile-fail optional_test_fail_none_io_without_io.cpp ]
[ compile-fail optional_test_fail_convert_assign_of_enums.cpp ]
[ run optional_test_static_properties.cpp ]
[ compile optional_test_maybe_uninitialized_warning.cpp ]
[ compile optional_test_deleted_default_ctor.cpp ]
[ compile optional_test_constructible_from_other.cpp ]
#[ run optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp ]
[ run optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_pass.cpp ]
[ run-fail optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_fail.cpp ]
[ run optional_xconfig_NO_PROPER_CONVERT_FROM_CONST_INT_pass.cpp ]
[ run-fail optional_xconfig_NO_PROPER_CONVERT_FROM_CONST_INT_fail.cpp ]
[ run optional_xconfig_NO_LEGAL_CONVERT_FROM_REF_pass.cpp ]
[ compile-fail optional_xconfig_NO_LEGAL_CONVERT_FROM_REF_fail.cpp ]
;
}

View File

@@ -0,0 +1,181 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at: akrzemi1@gmail.com
#ifndef BOOST_OPTIONAL_TEST_OPTIONAL_REF_ASSIGN_TEST_DEFS_AK_07JAN2015_HPP
#define BOOST_OPTIONAL_TEST_OPTIONAL_REF_ASSIGN_TEST_DEFS_AK_07JAN2015_HPP
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/addressof.hpp"
#include "testable_classes.hpp"
using boost::optional;
using boost::none;
using boost::addressof;
template <typename T>
void test_copy_assignment_for_const()
{
const typename concrete_type_of<T>::type v(2);
optional<const T&> o;
o = optional<const T&>(v);
BOOST_TEST(o);
BOOST_TEST(o != none);
BOOST_TEST(addressof(*o) == addressof(v));
BOOST_TEST(val(*o) == val(v));
BOOST_TEST(val(*o) == 2);
}
template <typename T>
void test_copy_assignment_for_noconst_const()
{
typename concrete_type_of<T>::type v(2);
optional<const T&> o;
o = optional<const T&>(v);
BOOST_TEST(o);
BOOST_TEST(o != none);
BOOST_TEST(addressof(*o) == addressof(v));
BOOST_TEST(val(*o) == val(v));
BOOST_TEST(val(*o) == 2);
val(v) = 9;
BOOST_TEST(addressof(*o) == addressof(v));
BOOST_TEST_EQ(val(*o), val(v));
BOOST_TEST_EQ(val(*o), 9);
BOOST_TEST_EQ(val(v), 9);
}
template <typename T>
void test_copy_assignment_for()
{
typename concrete_type_of<T>::type v(2);
optional<T&> o;
o = optional<T&>(v);
BOOST_TEST(o);
BOOST_TEST(o != none);
BOOST_TEST(addressof(*o) == addressof(v));
BOOST_TEST(val(*o) == val(v));
BOOST_TEST(val(*o) == 2);
val(v) = 9;
BOOST_TEST(addressof(*o) == addressof(v));
BOOST_TEST_EQ(val(*o), val(v));
BOOST_TEST_EQ(val(*o), 9);
BOOST_TEST_EQ(val(v), 9);
val(*o) = 7;
BOOST_TEST(addressof(*o) == addressof(v));
BOOST_TEST_EQ(val(*o), val(v));
BOOST_TEST_EQ(val(*o), 7);
BOOST_TEST_EQ(val(v), 7);
}
template <typename T>
void test_rebinding_assignment_semantics_const()
{
const typename concrete_type_of<T>::type v(2), w(7);
optional<const T&> o(v);
BOOST_TEST(o);
BOOST_TEST(addressof(*o) == addressof(v));
BOOST_TEST_EQ(val(*o), val(v));
BOOST_TEST_EQ(val(*o), 2);
o = optional<const T&>(w);
BOOST_TEST_EQ(val(v), 2);
BOOST_TEST(o);
BOOST_TEST(addressof(*o) != addressof(v));
BOOST_TEST_NE(val(*o), val(v));
BOOST_TEST_NE(val(*o), 2);
BOOST_TEST(addressof(*o) == addressof(w));
BOOST_TEST_EQ(val(*o), val(w));
BOOST_TEST_EQ(val(*o), 7);
}
template <typename T>
void test_rebinding_assignment_semantics_noconst_const()
{
typename concrete_type_of<T>::type v(2), w(7);
optional<const T&> o(v);
BOOST_TEST(o);
BOOST_TEST(addressof(*o) == addressof(v));
BOOST_TEST_EQ(val(*o), val(v));
BOOST_TEST_EQ(val(*o), 2);
o = optional<const T&>(w);
BOOST_TEST_EQ(val(v), 2);
BOOST_TEST(o);
BOOST_TEST(addressof(*o) != addressof(v));
BOOST_TEST_NE(val(*o), val(v));
BOOST_TEST_NE(val(*o), 2);
BOOST_TEST(addressof(*o) == addressof(w));
BOOST_TEST_EQ(val(*o), val(w));
BOOST_TEST_EQ(val(*o), 7);
}
template <typename T>
void test_rebinding_assignment_semantics()
{
typename concrete_type_of<T>::type v(2), w(7);
optional<T&> o(v);
BOOST_TEST(o);
BOOST_TEST(addressof(*o) == addressof(v));
BOOST_TEST_EQ(val(*o), val(v));
BOOST_TEST_EQ(val(*o), 2);
o = optional<T&>(w);
BOOST_TEST_EQ(val(v), 2);
BOOST_TEST(o);
BOOST_TEST(addressof(*o) != addressof(v));
BOOST_TEST_NE(val(*o), val(v));
BOOST_TEST_NE(val(*o), 2);
BOOST_TEST(addressof(*o) == addressof(w));
BOOST_TEST_EQ(val(*o), val(w));
BOOST_TEST_EQ(val(*o), 7);
val(*o) = 8;
BOOST_TEST(addressof(*o) == addressof(w));
BOOST_TEST_EQ(val(*o), val(w));
BOOST_TEST_EQ(val(*o), 8);
BOOST_TEST_EQ(val(w), 8);
BOOST_TEST_EQ(val(v), 2);
}
template <typename T, typename U>
void test_converting_assignment()
{
typename concrete_type_of<T>::type v1(1), v2(2), v3(3);
optional<U&> oA(v1), oB(none);
oA = v2;
BOOST_TEST(oA);
BOOST_TEST(addressof(*oA) == addressof(v2));
oB = v3;
BOOST_TEST(oB);
BOOST_TEST(addressof(*oB) == addressof(v3));
}
#endif //BOOST_OPTIONAL_TEST_OPTIONAL_REF_ASSIGN_TEST_DEFS_AK_07JAN2015_HPP

View File

@@ -0,0 +1,954 @@
// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
// Revisions:
// 12 May 2008 (added more swap tests)
//
#include<iostream>
#include<stdexcept>
#include<string>
#define BOOST_ENABLE_ASSERT_HANDLER
#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
#include "boost/mpl/bool.hpp"
#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/none.hpp"
#include "boost/core/lightweight_test.hpp"
#include "optional_test_common.hpp"
void test_implicit_construction ( optional<double> opt, double v, double z )
{
check_value(opt,v,z);
}
void test_implicit_construction ( optional<X> opt, X const& v, X const& z )
{
check_value(opt,v,z);
}
void test_default_implicit_construction ( double, optional<double> opt )
{
BOOST_TEST(!opt);
}
void test_default_implicit_construction ( X const&, optional<X> opt )
{
BOOST_TEST(!opt);
}
//
// Basic test.
// Check ordinary functionality:
// Initialization, assignment, comparison and value-accessing.
//
template<class T>
void test_basics( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T z(0);
T a(1);
// Default construction.
// 'def' state is Uninitialized.
// T::T() is not called (and it is not even defined)
optional<T> def ;
check_uninitialized(def);
// Implicit construction
// The first parameter is implicitely converted to optional<T>(a);
test_implicit_construction(a,a,z);
// Direct initialization.
// 'oa' state is Initialized with 'a'
// T::T( T const& x ) is used.
set_pending_copy( ARG(T) ) ;
optional<T> oa ( a ) ;
check_is_not_pending_copy( ARG(T) );
check_initialized(oa);
check_value(oa,a,z);
T b(2);
optional<T> ob ;
// Value-Assignment upon Uninitialized optional.
// T::T( T const& x ) is used.
set_pending_copy( ARG(T) ) ;
ob = a ;
check_is_not_pending_copy( ARG(T) ) ;
check_initialized(ob);
check_value(ob,a,z);
// Value-Assignment upon Initialized optional.
// T::operator=( T const& x ) is used
set_pending_assign( ARG(T) ) ;
set_pending_copy ( ARG(T) ) ;
set_pending_dtor ( ARG(T) ) ;
ob = b ;
check_is_not_pending_assign( ARG(T) ) ;
check_is_pending_copy ( ARG(T) ) ;
check_is_pending_dtor ( ARG(T) ) ;
check_initialized(ob);
check_value(ob,b,z);
// Assignment initialization.
// T::T ( T const& x ) is used to copy new value.
set_pending_copy( ARG(T) ) ;
optional<T> const oa2 ( oa ) ;
check_is_not_pending_copy( ARG(T) ) ;
check_initialized_const(oa2);
check_value_const(oa2,a,z);
// Assignment
// T::operator= ( T const& x ) is used to copy new value.
set_pending_assign( ARG(T) ) ;
oa = ob ;
check_is_not_pending_assign( ARG(T) ) ;
check_initialized(oa);
check_value(oa,b,z);
// Uninitializing Assignment upon Initialized Optional
// T::~T() is used to destroy previous value in oa.
set_pending_dtor( ARG(T) ) ;
set_pending_copy( ARG(T) ) ;
oa = def ;
check_is_not_pending_dtor( ARG(T) ) ;
check_is_pending_copy ( ARG(T) ) ;
check_uninitialized(oa);
// Uninitializing Assignment upon Uninitialized Optional
// (Dtor is not called this time)
set_pending_dtor( ARG(T) ) ;
set_pending_copy( ARG(T) ) ;
oa = def ;
check_is_pending_dtor( ARG(T) ) ;
check_is_pending_copy( ARG(T) ) ;
check_uninitialized(oa);
// Deinitialization of Initialized Optional
// T::~T() is used to destroy previous value in ob.
set_pending_dtor( ARG(T) ) ;
ob.reset();
check_is_not_pending_dtor( ARG(T) ) ;
check_uninitialized(ob);
// Deinitialization of Uninitialized Optional
// (Dtor is not called this time)
set_pending_dtor( ARG(T) ) ;
ob.reset();
check_is_pending_dtor( ARG(T) ) ;
check_uninitialized(ob);
}
template<class T>
void test_conditional_ctor_and_get_valur_or ( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T a(321);
T z(123);
optional<T> const cdef0(false,a);
optional<T> def0(false,a);
optional<T> def1 = boost::make_optional(false,a); // T is not within boost so ADL won't find make_optional unqualified
check_uninitialized(def0);
check_uninitialized(def1);
optional<T> const co0(true,a);
optional<T> o0(true,a);
optional<T> o1 = boost::make_optional(true,a); // T is not within boost so ADL won't find make_optional unqualified
check_initialized(o0);
check_initialized(o1);
check_value(o0,a,z);
check_value(o1,a,z);
T b = def0.get_value_or(z);
BOOST_TEST( b == z ) ;
b = get_optional_value_or(def0,z);
BOOST_TEST( b == z ) ;
b = o0.get_value_or(z);
BOOST_TEST( b == a ) ;
b = get_optional_value_or(o0,z);
BOOST_TEST( b == a ) ;
T const& crz = z ;
T& rz = z ;
T const& crzz = def0.get_value_or(crz);
BOOST_TEST( crzz == crz ) ;
T& rzz = def0.get_value_or(rz);
BOOST_TEST( rzz == rz ) ;
T const& crzzz = get_optional_value_or(cdef0,crz);
BOOST_TEST( crzzz == crz ) ;
T& rzzz = get_optional_value_or(def0,rz);
BOOST_TEST( rzzz == rz ) ;
T const& crb = o0.get_value_or(crz);
BOOST_TEST( crb == a ) ;
T& rb = o0.get_value_or(rz);
BOOST_TEST( rb == b ) ;
T const& crbb = get_optional_value_or(co0,crz);
BOOST_TEST( crbb == b ) ;
T const& crbbb = get_optional_value_or(o0,crz);
BOOST_TEST( crbbb == b ) ;
T& rbb = get_optional_value_or(o0,rz);
BOOST_TEST( rbb == b ) ;
T& ra = a ;
optional<T&> defref(false,ra);
BOOST_TEST(!defref);
optional<T&> ref(true,ra);
BOOST_TEST(!!ref);
a = T(432);
BOOST_TEST( *ref == a ) ;
T& r1 = defref.get_value_or(z);
BOOST_TEST( r1 == z ) ;
T& r2 = ref.get_value_or(z);
BOOST_TEST( r2 == a ) ;
}
//
// Test Direct Value Manipulation
//
template<class T>
void test_direct_value_manip( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T x(3);
optional<T> const c_opt0(x) ;
optional<T> opt0(x);
BOOST_TEST( c_opt0.get().V() == x.V() ) ;
BOOST_TEST( opt0.get().V() == x.V() ) ;
BOOST_TEST( c_opt0->V() == x.V() ) ;
BOOST_TEST( opt0->V() == x.V() ) ;
BOOST_TEST( (*c_opt0).V() == x.V() ) ;
BOOST_TEST( (* opt0).V() == x.V() ) ;
T y(4);
opt0 = y ;
BOOST_TEST( get(opt0).V() == y.V() ) ;
}
//
// Test Uninitialized access assert
//
template<class T>
void test_uninitialized_access( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
optional<T> def ;
bool passed = false ;
try
{
// This should throw because 'def' is uninitialized
T const& n = def.get() ;
boost::ignore_unused(n);
passed = true ;
}
catch (...) {}
BOOST_TEST(!passed);
passed = false ;
try
{
// This should throw because 'def' is uninitialized
T const& n = *def ;
boost::ignore_unused(n);
passed = true ;
}
catch (...) {}
BOOST_TEST(!passed);
passed = false ;
try
{
T v(5) ;
boost::ignore_unused(v);
// This should throw because 'def' is uninitialized
*def = v ;
passed = true ;
}
catch (...) {}
BOOST_TEST(!passed);
passed = false ;
try
{
// This should throw because 'def' is uninitialized
T v = *(def.operator->()) ;
boost::ignore_unused(v);
passed = true ;
}
catch (...) {}
BOOST_TEST(!passed);
}
#if BOOST_WORKAROUND( BOOST_INTEL_CXX_VERSION, <= 700) // Intel C++ 7.0
void prevent_buggy_optimization( bool v ) {}
#endif
//
// Test Direct Initialization of optional for a T with throwing copy-ctor.
//
template<class T>
void test_throwing_direct_init( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T a(6);
int count = get_instance_count( ARG(T) ) ;
set_throw_on_copy( ARG(T) ) ;
bool passed = false ;
try
{
// This should:
// Attempt to copy construct 'a' and throw.
// 'opt' won't be constructed.
set_pending_copy( ARG(T) ) ;
#if BOOST_WORKAROUND( BOOST_INTEL_CXX_VERSION, <= 700) // Intel C++ 7.0
// Intel C++ 7.0 specific:
// For some reason, when "check_is_not_pending_copy",
// after the exception block is reached,
// X::pending_copy==true even though X's copy ctor set it to false.
// I guessed there is some sort of optimization bug,
// and it seems to be the since the following additional line just
// solves the problem (!?)
prevent_buggy_optimization(X::pending_copy);
#endif
optional<T> opt(a) ;
passed = true ;
}
catch ( ... ){}
BOOST_TEST(!passed);
check_is_not_pending_copy( ARG(T) );
check_instance_count(count, ARG(T) );
reset_throw_on_copy( ARG(T) ) ;
}
//
// Test Value Assignment to an Uninitialized optional for a T with a throwing copy-ctor
//
template<class T>
void test_throwing_val_assign_on_uninitialized( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T a(7);
int count = get_instance_count( ARG(T) ) ;
set_throw_on_copy( ARG(T) ) ;
optional<T> opt ;
bool passed = false ;
try
{
// This should:
// Attempt to copy construct 'a' and throw.
// opt should be left uninitialized.
set_pending_copy( ARG(T) ) ;
opt.reset( a );
passed = true ;
}
catch ( ... ) {}
BOOST_TEST(!passed);
check_is_not_pending_copy( ARG(T) );
check_instance_count(count, ARG(T) );
check_uninitialized(opt);
reset_throw_on_copy( ARG(T) ) ;
}
//
// Test Value Reset on an Initialized optional for a T with a throwing copy-ctor
//
template<class T>
void test_throwing_val_assign_on_initialized( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T z(0);
T a(8);
T b(9);
T x(-1);
int count = get_instance_count( ARG(T) ) ;
optional<T> opt ( b ) ;
++ count ;
check_instance_count(count, ARG(T) );
check_value(opt,b,z);
set_throw_on_assign( ARG(T) ) ;
bool passed = false ;
try
{
// This should:
// Attempt to assign 'a' and throw.
// opt is kept initialized but its value not neccesarily fully assigned
// (in this test, incompletely assigned is flaged with the value -1 being set)
set_pending_assign( ARG(T) ) ;
opt.reset ( a ) ;
passed = true ;
}
catch ( ... ) {}
BOOST_TEST(!passed);
check_is_not_pending_assign( ARG(T) );
check_instance_count(count, ARG(T) );
check_initialized(opt);
check_value(opt,x,z);
reset_throw_on_assign ( ARG(T) ) ;
}
//
// Test Copy Initialization from an Initialized optional for a T with a throwing copy-ctor
//
template<class T>
void test_throwing_copy_initialization( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T z(0);
T a(10);
optional<T> opt (a);
int count = get_instance_count( ARG(T) ) ;
set_throw_on_copy( ARG(T) ) ;
bool passed = false ;
try
{
// This should:
// Attempt to copy construct 'opt' and throw.
// opt1 won't be constructed.
set_pending_copy( ARG(T) ) ;
optional<T> opt1 = opt ;
passed = true ;
}
catch ( ... ) {}
BOOST_TEST(!passed);
check_is_not_pending_copy( ARG(T) );
check_instance_count(count, ARG(T) );
// Nothing should have happened to the source optional.
check_initialized(opt);
check_value(opt,a,z);
reset_throw_on_copy( ARG(T) ) ;
}
//
// Test Assignment to an Uninitialized optional from an Initialized optional
// for a T with a throwing copy-ctor
//
template<class T>
void test_throwing_assign_to_uninitialized( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T z(0);
T a(11);
optional<T> opt0 ;
optional<T> opt1(a) ;
int count = get_instance_count( ARG(T) ) ;
set_throw_on_copy( ARG(T) ) ;
bool passed = false ;
try
{
// This should:
// Attempt to copy construct 'opt1.value()' into opt0 and throw.
// opt0 should be left uninitialized.
set_pending_copy( ARG(T) ) ;
opt0 = opt1 ;
passed = true ;
}
catch ( ... ) {}
BOOST_TEST(!passed);
check_is_not_pending_copy( ARG(T) );
check_instance_count(count, ARG(T) );
check_uninitialized(opt0);
reset_throw_on_copy( ARG(T) ) ;
}
//
// Test Assignment to an Initialized optional from an Initialized optional
// for a T with a throwing copy-ctor
//
template<class T>
void test_throwing_assign_to_initialized( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T z(0);
T a(12);
T b(13);
T x(-1);
optional<T> opt0(a) ;
optional<T> opt1(b) ;
int count = get_instance_count( ARG(T) ) ;
set_throw_on_assign( ARG(T) ) ;
bool passed = false ;
try
{
// This should:
// Attempt to copy construct 'opt1.value()' into opt0 and throw.
// opt0 is kept initialized but its value not neccesarily fully assigned
// (in this test, incompletely assigned is flaged with the value -1 being set)
set_pending_assign( ARG(T) ) ;
opt0 = opt1 ;
passed = true ;
}
catch ( ... ) {}
BOOST_TEST(!passed);
// opt0 was left uninitialized
check_is_not_pending_assign( ARG(T) );
check_instance_count(count, ARG(T) );
check_initialized(opt0);
check_value(opt0,x,z);
reset_throw_on_assign( ARG(T) ) ;
}
//
// Test swap in a no-throwing case
//
template<class T>
void test_no_throwing_swap( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T z(0);
T a(14);
T b(15);
optional<T> def0 ;
optional<T> def1 ;
optional<T> opt0(a) ;
optional<T> opt1(b) ;
int count = get_instance_count( ARG(T) ) ;
swap(def0,def1);
check_uninitialized(def0);
check_uninitialized(def1);
swap(def0,opt0);
check_uninitialized(opt0);
check_initialized(def0);
check_value(def0,a,z);
// restore def0 and opt0
swap(def0,opt0);
swap(opt0,opt1);
check_instance_count(count, ARG(T) );
check_initialized(opt0);
check_initialized(opt1);
check_value(opt0,b,z);
check_value(opt1,a,z);
}
//
// Test swap in a throwing case
//
template<class T>
void test_throwing_swap( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T a(16);
T b(17);
T x(-1);
optional<T> opt0(a) ;
optional<T> opt1(b) ;
set_throw_on_assign( ARG(T) ) ;
//
// Case 1: Both Initialized.
//
bool passed = false ;
try
{
// This should attempt to swap optionals and fail at swap(X&,X&).
swap(opt0,opt1);
passed = true ;
}
catch ( ... ) {}
BOOST_TEST(!passed);
// optional's swap doesn't affect the initialized states of the arguments. Therefore,
// the following must hold:
check_initialized(opt0);
check_initialized(opt1);
check_value(opt0,x,a);
check_value(opt1,b,x);
//
// Case 2: Only one Initialized.
//
reset_throw_on_assign( ARG(T) ) ;
opt0.reset();
opt1.reset(a);
set_throw_on_copy( ARG(T) ) ;
passed = false ;
try
{
// This should attempt to swap optionals and fail at opt0.reset(*opt1)
// Both opt0 and op1 are left unchanged (unswaped)
swap(opt0,opt1);
passed = true ;
}
catch ( ... ) {}
BOOST_TEST(!passed);
check_uninitialized(opt0);
check_initialized(opt1);
check_value(opt1,a,x);
reset_throw_on_copy( ARG(T) ) ;
}
//
// This verifies relational operators.
//
template<class T>
void test_relops( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T v0(0);
T v1(1);
T v2(1);
optional<T> def0 ;
optional<T> def1 ;
optional<T> opt0(v0);
optional<T> opt1(v1);
optional<T> opt2(v2);
// Check identity
BOOST_TEST ( def0 == def0 ) ;
BOOST_TEST ( opt0 == opt0 ) ;
BOOST_TEST ( !(def0 != def0) ) ;
BOOST_TEST ( !(opt0 != opt0) ) ;
// Check when both are uininitalized.
BOOST_TEST ( def0 == def1 ) ; // both uninitialized compare equal
BOOST_TEST ( !(def0 < def1) ) ; // uninitialized is never less than uninitialized
BOOST_TEST ( !(def0 > def1) ) ; // uninitialized is never greater than uninitialized
BOOST_TEST ( !(def0 != def1) ) ;
BOOST_TEST ( def0 <= def1 ) ;
BOOST_TEST ( def0 >= def1 ) ;
// Check when only lhs is uninitialized.
BOOST_TEST ( def0 != opt0 ) ; // uninitialized is never equal to initialized
BOOST_TEST ( !(def0 == opt0) ) ;
BOOST_TEST ( def0 < opt0 ) ; // uninitialized is always less than initialized
BOOST_TEST ( !(def0 > opt0) ) ;
BOOST_TEST ( def0 <= opt0 ) ;
BOOST_TEST ( !(def0 >= opt0) ) ;
// Check when only rhs is uninitialized.
BOOST_TEST ( opt0 != def0 ) ; // initialized is never equal to uninitialized
BOOST_TEST ( !(opt0 == def0) ) ;
BOOST_TEST ( !(opt0 < def0) ) ; // initialized is never less than uninitialized
BOOST_TEST ( opt0 > def0 ) ;
BOOST_TEST ( !(opt0 <= def0) ) ;
BOOST_TEST ( opt0 >= opt0 ) ;
// If both are initialized, values are compared
BOOST_TEST ( opt0 != opt1 ) ;
BOOST_TEST ( opt1 == opt2 ) ;
BOOST_TEST ( opt0 < opt1 ) ;
BOOST_TEST ( opt1 > opt0 ) ;
BOOST_TEST ( opt1 <= opt2 ) ;
BOOST_TEST ( opt1 >= opt0 ) ;
// Compare against a value directly
BOOST_TEST ( opt0 == v0 ) ;
BOOST_TEST ( opt0 != v1 ) ;
BOOST_TEST ( opt1 == v2 ) ;
BOOST_TEST ( opt0 < v1 ) ;
BOOST_TEST ( opt1 > v0 ) ;
BOOST_TEST ( opt1 <= v2 ) ;
BOOST_TEST ( opt1 >= v0 ) ;
BOOST_TEST ( v0 != opt1 ) ;
BOOST_TEST ( v1 == opt2 ) ;
BOOST_TEST ( v0 < opt1 ) ;
BOOST_TEST ( v1 > opt0 ) ;
BOOST_TEST ( v1 <= opt2 ) ;
BOOST_TEST ( v1 >= opt0 ) ;
BOOST_TEST ( def0 != v0 ) ;
BOOST_TEST ( !(def0 == v0) ) ;
BOOST_TEST ( def0 < v0 ) ;
BOOST_TEST ( !(def0 > v0) ) ;
BOOST_TEST ( def0 <= v0 ) ;
BOOST_TEST ( !(def0 >= v0) ) ;
BOOST_TEST ( v0 != def0 ) ;
BOOST_TEST ( !(v0 == def0) ) ;
BOOST_TEST ( !(v0 < def0) ) ;
BOOST_TEST ( v0 > def0 ) ;
BOOST_TEST ( !(v0 <= def0) ) ;
BOOST_TEST ( v0 >= opt0 ) ;
}
template<class T>
void test_none( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
using boost::none ;
optional<T> def0 ;
optional<T> def1(none) ;
optional<T> non_def( T(1234) ) ;
BOOST_TEST ( def0 == none ) ;
BOOST_TEST ( non_def != none ) ;
BOOST_TEST ( !def1 ) ;
BOOST_TEST ( !(non_def < none) ) ;
BOOST_TEST ( non_def > none ) ;
BOOST_TEST ( !(non_def <= none) ) ;
BOOST_TEST ( non_def >= none ) ;
non_def = none ;
BOOST_TEST ( !non_def ) ;
test_default_implicit_construction(T(1),none);
}
template<class T>
void test_arrow( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T a(1234);
optional<T> oa(a) ;
optional<T> const coa(a) ;
BOOST_TEST ( coa->V() == 1234 ) ;
oa->V() = 4321 ;
BOOST_TEST ( a.V() = 1234 ) ;
BOOST_TEST ( (*oa).V() = 4321 ) ;
}
void test_with_builtin_types()
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
test_basics( ARG(double) );
test_conditional_ctor_and_get_valur_or( ARG(double) );
test_uninitialized_access( ARG(double) );
test_no_throwing_swap( ARG(double) );
test_relops( ARG(double) ) ;
test_none( ARG(double) ) ;
}
// MSVC < 11.0 doesn't destroy X when we call ptr->VBase::VBase.
// Make sure that we work around this bug.
struct VBase : virtual X
{
VBase(int v) : X(v) {}
// MSVC 8.0 doesn't generate this correctly...
VBase(const VBase& other) : X(static_cast<const X&>(other)) {}
};
void test_with_class_type()
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
test_basics( ARG(X) );
test_basics( ARG(VBase) );
test_conditional_ctor_and_get_valur_or( ARG(X) );
test_direct_value_manip( ARG(X) );
test_uninitialized_access( ARG(X) );
test_throwing_direct_init( ARG(X) );
test_throwing_val_assign_on_uninitialized( ARG(X) );
test_throwing_val_assign_on_initialized( ARG(X) );
test_throwing_copy_initialization( ARG(X) );
test_throwing_assign_to_uninitialized( ARG(X) );
test_throwing_assign_to_initialized( ARG(X) );
test_no_throwing_swap( ARG(X) );
test_throwing_swap( ARG(X) );
test_relops( ARG(X) ) ;
test_none( ARG(X) ) ;
test_arrow( ARG(X) ) ;
BOOST_TEST ( X::count == 0 ) ;
}
int eat ( bool ) { return 1 ; }
int eat ( char ) { return 1 ; }
int eat ( int ) { return 1 ; }
int eat ( void const* ) { return 1 ; }
template<class T> int eat ( T ) { return 0 ; }
//
// This verifies that operator safe_bool() behaves properly.
//
template<class T>
void test_no_implicit_conversions_impl( T const& )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
optional<T> def ;
BOOST_TEST ( eat(def) == 0 ) ;
}
void test_no_implicit_conversions()
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
bool b = false ;
char c = 0 ;
int i = 0 ;
void const* p = 0 ;
test_no_implicit_conversions_impl(b);
test_no_implicit_conversions_impl(c);
test_no_implicit_conversions_impl(i);
test_no_implicit_conversions_impl(p);
}
// Test for support for classes with overridden operator&
class CustomAddressOfClass
{
int n;
public:
CustomAddressOfClass() : n(0) {}
CustomAddressOfClass(CustomAddressOfClass const& that) : n(that.n) {}
explicit CustomAddressOfClass(int m) : n(m) {}
int* operator& () { return &n; }
bool operator== (CustomAddressOfClass const& that) const { return n == that.n; }
};
void test_custom_addressof_operator()
{
boost::optional< CustomAddressOfClass > o1(CustomAddressOfClass(10));
BOOST_TEST(!!o1);
BOOST_TEST(o1.get() == CustomAddressOfClass(10));
o1 = CustomAddressOfClass(20);
BOOST_TEST(!!o1);
BOOST_TEST(o1.get() == CustomAddressOfClass(20));
o1 = boost::none;
BOOST_TEST(!o1);
}
int main()
{
try
{
test_with_class_type();
test_with_builtin_types();
test_no_implicit_conversions();
test_custom_addressof_operator();
}
catch ( ... )
{
BOOST_ERROR("Unexpected Exception caught!");
}
return boost::report_errors();
}

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2018 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/core/lightweight_test.hpp"
#include "boost/optional/optional.hpp"
void test_assignment_to_empty()
{
// this test used to fail on GCC 8.1.0/8.2.0/9.0.0 with -std=c++98
boost::optional<int> oa, ob(1);
BOOST_TEST(!oa);
BOOST_TEST(ob);
oa = ob;
BOOST_TEST(oa);
}
int main()
{
test_assignment_to_empty();
return boost::report_errors();
}

View File

@@ -0,0 +1,283 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2014, Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#include <boost/core/ignore_unused.hpp>
#ifdef ENABLE_TRACE
#define TRACE(msg) std::cout << msg << std::endl ;
#else
#define TRACE(msg)
#endif
namespace boost {
void assertion_failed (char const * expr, char const * func, char const * file, long )
{
using std::string ;
string msg = string("Boost assertion failure for \"")
+ string(expr)
+ string("\" at file \"")
+ string(file)
+ string("\" function \"")
+ string(func)
+ string("\"") ;
TRACE(msg);
throw std::logic_error(msg);
}
}
using boost::optional ;
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
using boost::swap ;
using boost::get ;
using boost::get_pointer ;
#endif
// MSVC6.0 does not support comparisons of optional against a literal null pointer value (0)
// via the safe_bool operator.
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1300) ) // 1300 == VC++ 7.1
#define BOOST_OPTIONAL_NO_NULL_COMPARE
#else
#define BOOST_OPTIONAL_NO_NULL_COMPARE // Andrzej: I also disable 0 comparison everywhere
#endif
#define ARG(T) (static_cast< T const* >(0))
//
// Helper class used to verify the lifetime managment of the values held by optional
//
class X
{
public :
X ( int av ) : v(av)
{
++ count ;
TRACE ( "X::X(" << av << "). this=" << this ) ;
}
X ( X const& rhs ) : v(rhs.v)
{
pending_copy = false ;
TRACE ( "X::X( X const& rhs). this=" << this << " rhs.v=" << rhs.v ) ;
if ( throw_on_copy )
{
TRACE ( "throwing exception in X's copy ctor" ) ;
throw 0 ;
}
++ count ;
}
~X()
{
pending_dtor = false ;
-- count ;
TRACE ( "X::~X(). v=" << v << " this=" << this );
}
X& operator= ( X const& rhs )
{
pending_assign = false ;
if ( throw_on_assign )
{
TRACE ( "throwing exception in X's assignment" ) ;
v = -1 ;
throw 0 ;
}
else
{
v = rhs.v ;
TRACE ( "X::operator =( X const& rhs). this=" << this << " rhs.v=" << rhs.v ) ;
}
return *this ;
}
friend bool operator == ( X const& a, X const& b )
{ return a.v == b.v ; }
friend bool operator != ( X const& a, X const& b )
{ return a.v != b.v ; }
friend bool operator < ( X const& a, X const& b )
{ return a.v < b.v ; }
int V() const { return v ; }
int& V() { return v ; }
static int count ;
static bool pending_copy ;
static bool pending_dtor ;
static bool pending_assign ;
static bool throw_on_copy ;
static bool throw_on_assign ;
private :
int v ;
private :
X() ;
} ;
int X::count = 0 ;
bool X::pending_copy = false ;
bool X::pending_dtor = false ;
bool X::pending_assign = false ;
bool X::throw_on_copy = false ;
bool X::throw_on_assign = false ;
inline void set_pending_copy ( X const* ) { X::pending_copy = true ; }
inline void set_pending_dtor ( X const* ) { X::pending_dtor = true ; }
inline void set_pending_assign ( X const* ) { X::pending_assign = true ; }
inline void set_throw_on_copy ( X const* ) { X::throw_on_copy = true ; }
inline void set_throw_on_assign ( X const* ) { X::throw_on_assign = true ; }
inline void reset_throw_on_copy ( X const* ) { X::throw_on_copy = false ; }
inline void reset_throw_on_assign ( X const* ) { X::throw_on_assign = false ; }
inline void check_is_pending_copy ( X const* ) { BOOST_TEST( X::pending_copy ) ; }
inline void check_is_pending_dtor ( X const* ) { BOOST_TEST( X::pending_dtor ) ; }
inline void check_is_pending_assign ( X const* ) { BOOST_TEST( X::pending_assign ) ; }
inline void check_is_not_pending_copy ( X const* ) { BOOST_TEST( !X::pending_copy ) ; }
inline void check_is_not_pending_dtor ( X const* ) { BOOST_TEST( !X::pending_dtor ) ; }
inline void check_is_not_pending_assign( X const* ) { BOOST_TEST( !X::pending_assign ) ; }
inline void check_instance_count ( int c, X const* ) { BOOST_TEST( X::count == c ) ; }
inline int get_instance_count ( X const* ) { return X::count ; }
inline void set_pending_copy (...) {}
inline void set_pending_dtor (...) {}
inline void set_pending_assign (...) {}
inline void set_throw_on_copy (...) {}
inline void set_throw_on_assign (...) {}
inline void reset_throw_on_copy (...) {}
inline void reset_throw_on_assign (...) {}
inline void check_is_pending_copy (...) {}
inline void check_is_pending_dtor (...) {}
inline void check_is_pending_assign (...) {}
inline void check_is_not_pending_copy (...) {}
inline void check_is_not_pending_dtor (...) {}
inline void check_is_not_pending_assign(...) {}
inline void check_instance_count (...) {}
inline int get_instance_count (...) { return 0 ; }
template<class T>
inline void check_uninitialized_const ( optional<T> const& opt )
{
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
BOOST_TEST( opt == 0 ) ;
#endif
BOOST_TEST( !opt ) ;
BOOST_TEST( !get_pointer(opt) ) ;
BOOST_TEST( !opt.get_ptr() ) ;
BOOST_TEST( !opt.has_value() ) ;
BOOST_TEST( !opt.is_initialized() ) ;
BOOST_TEST( opt == boost::none ) ;
}
template<class T>
inline void check_uninitialized ( optional<T>& opt )
{
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
BOOST_TEST( opt == 0 ) ;
#endif
BOOST_TEST( !opt ) ;
BOOST_TEST( !get_pointer(opt) ) ;
BOOST_TEST( !opt.get_ptr() ) ;
BOOST_TEST( !opt.has_value() ) ;
BOOST_TEST( !opt.is_initialized() ) ;
BOOST_TEST( opt == boost::none ) ;
check_uninitialized_const(opt);
}
template<class T>
inline void check_initialized_const ( optional<T> const& opt )
{
BOOST_TEST( opt ) ;
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
BOOST_TEST( opt != 0 ) ;
#endif
BOOST_TEST ( !!opt ) ;
BOOST_TEST ( get_pointer(opt) ) ;
BOOST_TEST ( opt.get_ptr() ) ;
BOOST_TEST ( opt.has_value() ) ;
BOOST_TEST ( opt.is_initialized() ) ;
BOOST_TEST ( opt != boost::none ) ;
}
template<class T>
inline void check_initialized ( optional<T>& opt )
{
BOOST_TEST( opt ) ;
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
BOOST_TEST( opt != 0 ) ;
#endif
BOOST_TEST ( !!opt ) ;
BOOST_TEST ( get_pointer(opt) ) ;
BOOST_TEST ( opt.get_ptr() ) ;
BOOST_TEST ( opt.has_value() ) ;
BOOST_TEST ( opt.is_initialized() ) ;
BOOST_TEST ( opt != boost::none ) ;
check_initialized_const(opt);
}
template<class T>
inline void check_value_const ( optional<T> const& opt, T const& v, T const& z )
{
BOOST_TEST( *opt == v ) ;
BOOST_TEST( *opt != z ) ;
BOOST_TEST( opt.get() == v ) ;
BOOST_TEST( opt.get() != z ) ;
BOOST_TEST( (*(opt.operator->()) == v) ) ;
BOOST_TEST( *get_pointer(opt) == v ) ;
}
template<class T>
inline void check_value ( optional<T>& opt, T const& v, T const& z )
{
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // 1200 == VC++ 6.0
// For some reason, VC6.0 is creating a temporary while evaluating (*opt == v),
// so we need to turn throw on copy off first.
reset_throw_on_copy( ARG(T) ) ;
#endif
BOOST_TEST( *opt == v ) ;
BOOST_TEST( *opt != z ) ;
BOOST_TEST( opt.get() == v ) ;
BOOST_TEST( opt.get() != z ) ;
BOOST_TEST( (*(opt.operator->()) == v) ) ;
BOOST_TEST( *get_pointer(opt) == v ) ;
check_value_const(opt,v,z);
}

View File

@@ -0,0 +1,59 @@
// Copyright (c) 2018 Andrey Semashev
//
// Use, modification, and distribution is 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)
// The test verifies that Boost.Optional copy constructors do not attempt to invoke
// the element type initializing constructors from templated arguments
#include <boost/optional/optional.hpp>
#include <boost/core/enable_if.hpp>
struct no_type
{
char data;
};
struct yes_type
{
char data[2];
};
template< unsigned int Size >
struct size_tag {};
template< typename T, typename U >
struct is_constructible
{
static U& get();
template< typename T1 >
static yes_type check_helper(size_tag< sizeof(static_cast< T1 >(get())) >*);
template< typename T1 >
static no_type check_helper(...);
static const bool value = sizeof(check_helper< T >(0)) == sizeof(yes_type);
};
template< typename T >
class wrapper
{
public:
wrapper() {}
wrapper(wrapper const&) {}
template< typename U >
wrapper(U const&, typename boost::enable_if_c< is_constructible< T, U >::value, int >::type = 0) {}
};
inline boost::optional< wrapper< int > > foo()
{
return boost::optional< wrapper< int > >();
}
int main()
{
// Invokes boost::optional copy constructor. Should not invoke wrapper constructor from U.
boost::optional< wrapper< int > > res = foo();
return 0;
}

View File

@@ -0,0 +1,111 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at: akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
using boost::optional;
// testing types:
// X is convertible to Y
// ADeriv is convertible to ABase
struct X
{
int val;
explicit X(int v) : val(v) {}
};
struct Y
{
int yval;
Y(X const& x) : yval(x.val) {}
friend bool operator==(Y const& l, Y const& r) { return l.yval == r.yval; }
};
struct ABase
{
int val;
explicit ABase(int v) : val(v) {}
friend bool operator==(ABase const& l, ABase const& r) { return l.val == r.val; }
};
struct ADeriv : ABase
{
explicit ADeriv(int v) : ABase(v) {}
};
template <typename T, typename U>
void test_convert_optional_U_to_optional_T_for()
{
#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
{
optional<U> ou(U(8));
optional<T> ot1(ou);
BOOST_TEST(ot1);
BOOST_TEST(*ot1 == T(*ou));
}
#endif
#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
{
optional<U> ou(U(8));
optional<T> ot2;
ot2 = ou;
BOOST_TEST(ot2);
BOOST_TEST(*ot2 == T(*ou));
}
#endif
}
void test_convert_optional_U_to_optional_T()
{
test_convert_optional_U_to_optional_T_for<Y, X>();
test_convert_optional_U_to_optional_T_for<ABase, ADeriv>();
test_convert_optional_U_to_optional_T_for<long, short>();
test_convert_optional_U_to_optional_T_for<double, float>();
}
template <typename T, typename U>
void test_convert_U_to_optional_T_for()
{
U u(8);
optional<T> ot1(u);
BOOST_TEST(ot1);
BOOST_TEST(*ot1 == T(u));
optional<T> ot2;
ot2 = u;
BOOST_TEST(ot2);
BOOST_TEST(*ot2 == T(u));
}
void test_convert_U_to_optional_T()
{
test_convert_U_to_optional_T_for<Y, X>();
test_convert_U_to_optional_T_for<ABase, ADeriv>();
test_convert_U_to_optional_T_for<long, short>();
test_convert_U_to_optional_T_for<double, float>();
}
int main()
{
test_convert_optional_U_to_optional_T();
test_convert_U_to_optional_T();
return boost::report_errors();
}

View File

@@ -0,0 +1,70 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
#include "boost/none.hpp"
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
using boost::optional;
using boost::none;
template <typename U>
struct superconv
{
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
template <typename T>
superconv(T&&) { BOOST_STATIC_ASSERT(sizeof(T) == 0); }
#else
template <typename T>
superconv(const T&) { BOOST_STATIC_ASSERT(sizeof(T) == 0); }
template <typename T>
superconv( T&) { BOOST_STATIC_ASSERT(sizeof(T) == 0); }
#endif
superconv() {}
};
void test_optional_of_superconverting_T() // compile-time test
{
#ifndef BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT
superconv<optional<int> > s;
superconv<optional<int> > & rs = s;
optional<superconv<optional<int> > > os = rs;
#endif
}
void test_optional_optional_T()
{
optional<int> oi1 (1), oiN;
optional< optional<int> > ooi1 (oi1), ooiN(oiN);
BOOST_TEST(ooi1);
BOOST_TEST(*ooi1);
BOOST_TEST_EQ(**ooi1, 1);
BOOST_TEST(ooiN);
BOOST_TEST(!*ooiN);
}
int main()
{
test_optional_optional_T();
test_optional_of_superconverting_T();
return boost::report_errors();
}

View File

@@ -0,0 +1,66 @@
// Copyright 2017 Peter Dimov
// Copyright 2017 Vinnie Falco
// Copyright 2018 Andrzej Krzemienski
//
// 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_DELETED_FUNCTIONS)
int main()
{
}
#else
#include <boost/optional.hpp>
#include <utility>
class basic_multi_buffer;
class const_buffers_type // a similar declaration in boost.beast had problem
{ // with boost opitonal
basic_multi_buffer const* b_;
friend class basic_multi_buffer;
explicit
const_buffers_type(basic_multi_buffer const& b);
public:
const_buffers_type() = delete;
const_buffers_type(const_buffers_type const&) = default;
const_buffers_type& operator=(const_buffers_type const&) = default;
};
void test_beast_example()
{
// test if it even compiles
boost::optional< std::pair<const_buffers_type, int> > opt, opt2;
opt = opt2;
(void)opt;
}
struct NotDefaultConstructible // minimal class exposing the problem
{
NotDefaultConstructible() = delete;
};
void test_assign_for_non_default_constructible()
{
// test if it even compiles
boost::optional<NotDefaultConstructible> opt, opt2;
opt = opt2;
(void)opt;
}
int main()
{
test_beast_example();
test_assign_for_non_default_constructible();
}
#endif

View File

@@ -0,0 +1,390 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include <string>
#include "boost/core/lightweight_test.hpp"
#include "boost/none.hpp"
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
using boost::optional;
using boost::none;
using boost::in_place_init;
using boost::in_place_init_if;
#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
class Guard
{
public:
int which_ctor;
Guard () : which_ctor(0) { }
Guard (int&, double&&) : which_ctor(1) { }
Guard (int&&, double&) : which_ctor(2) { }
Guard (int&&, double&&) : which_ctor(3) { }
Guard (int&, double&) : which_ctor(4) { }
Guard (std::string const&) : which_ctor(5) { }
Guard (std::string &) : which_ctor(6) { }
Guard (std::string &&) : which_ctor(7) { }
private:
Guard(Guard&&);
Guard(Guard const&);
void operator=(Guard &&);
void operator=(Guard const&);
};
void test_emplace()
{
int i = 0;
double d = 0.0;
const std::string cs;
std::string ms;
optional<Guard> o;
o.emplace();
BOOST_TEST(o);
BOOST_TEST(0 == o->which_ctor);
o.emplace(i, 2.0);
BOOST_TEST(o);
BOOST_TEST(1 == o->which_ctor);
o.emplace(1, d);
BOOST_TEST(o);
BOOST_TEST(2 == o->which_ctor);
o.emplace(1, 2.0);
BOOST_TEST(o);
BOOST_TEST(3 == o->which_ctor);
o.emplace(i, d);
BOOST_TEST(o);
BOOST_TEST(4 == o->which_ctor);
o.emplace(cs);
BOOST_TEST(o);
BOOST_TEST(5 == o->which_ctor);
o.emplace(ms);
BOOST_TEST(o);
BOOST_TEST(6 == o->which_ctor);
o.emplace(std::string());
BOOST_TEST(o);
BOOST_TEST(7 == o->which_ctor);
}
void test_in_place_ctor()
{
int i = 0;
double d = 0.0;
const std::string cs;
std::string ms;
{
optional<Guard> o (in_place_init);
BOOST_TEST(o);
BOOST_TEST(0 == o->which_ctor);
}
{
optional<Guard> o (in_place_init, i, 2.0);
BOOST_TEST(o);
BOOST_TEST(1 == o->which_ctor);
}
{
optional<Guard> o (in_place_init, 1, d);
BOOST_TEST(o);
BOOST_TEST(2 == o->which_ctor);
}
{
optional<Guard> o (in_place_init, 1, 2.0);
BOOST_TEST(o);
BOOST_TEST(3 == o->which_ctor);
}
{
optional<Guard> o (in_place_init, i, d);
BOOST_TEST(o);
BOOST_TEST(4 == o->which_ctor);
}
{
optional<Guard> o (in_place_init, cs);
BOOST_TEST(o);
BOOST_TEST(5 == o->which_ctor);
}
{
optional<Guard> o (in_place_init, ms);
BOOST_TEST(o);
BOOST_TEST(6 == o->which_ctor);
}
{
optional<Guard> o (in_place_init, std::string());
BOOST_TEST(o);
BOOST_TEST(7 == o->which_ctor);
}
}
void test_in_place_if_ctor()
{
int i = 0;
double d = 0.0;
const std::string cs;
std::string ms;
{
optional<Guard> o (in_place_init_if, true);
BOOST_TEST(o);
BOOST_TEST(0 == o->which_ctor);
}
{
optional<Guard> o (in_place_init_if, true, i, 2.0);
BOOST_TEST(o);
BOOST_TEST(1 == o->which_ctor);
}
{
optional<Guard> o (in_place_init_if, true, 1, d);
BOOST_TEST(o);
BOOST_TEST(2 == o->which_ctor);
}
{
optional<Guard> o (in_place_init_if, true, 1, 2.0);
BOOST_TEST(o);
BOOST_TEST(3 == o->which_ctor);
}
{
optional<Guard> o (in_place_init_if, true, i, d);
BOOST_TEST(o);
BOOST_TEST(4 == o->which_ctor);
}
{
optional<Guard> o (in_place_init_if, true, cs);
BOOST_TEST(o);
BOOST_TEST(5 == o->which_ctor);
}
{
optional<Guard> o (in_place_init_if, true, ms);
BOOST_TEST(o);
BOOST_TEST(6 == o->which_ctor);
}
{
optional<Guard> o (in_place_init_if, true, std::string());
BOOST_TEST(o);
BOOST_TEST(7 == o->which_ctor);
}
{
optional<Guard> o (in_place_init_if, false, 1, 2.0);
BOOST_TEST(!o);
}
}
#endif
#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
struct ThrowOnMove
{
ThrowOnMove(ThrowOnMove&&) { throw int(); }
ThrowOnMove(ThrowOnMove const&) { throw int(); }
ThrowOnMove(int){}
};
void test_no_moves_on_emplacement()
{
try {
optional<ThrowOnMove> o;
o.emplace(1);
BOOST_TEST(o);
}
catch (...) {
BOOST_TEST(false);
}
}
void test_no_moves_on_in_place_ctor()
{
try {
optional<ThrowOnMove> o (in_place_init, 1);
BOOST_TEST(o);
optional<ThrowOnMove> p (in_place_init_if, true, 1);
BOOST_TEST(p);
optional<ThrowOnMove> q (in_place_init_if, false, 1);
BOOST_TEST(!q);
}
catch (...) {
BOOST_TEST(false);
}
}
#endif
struct Thrower
{
Thrower(bool throw_) { if (throw_) throw int(); }
private:
Thrower(Thrower const&);
#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
Thrower(Thrower&&);
#endif
};
void test_clear_on_throw()
{
optional<Thrower> ot;
try {
ot.emplace(false);
BOOST_TEST(ot);
} catch(...) {
BOOST_TEST(false);
}
try {
ot.emplace(true);
BOOST_TEST(false);
} catch(...) {
BOOST_TEST(!ot);
}
}
void test_no_assignment_on_emplacement()
{
optional<const std::string> os, ot;
BOOST_TEST(!os);
os.emplace("wow");
BOOST_TEST(os);
BOOST_TEST_EQ(*os, "wow");
BOOST_TEST(!ot);
ot.emplace();
BOOST_TEST(ot);
BOOST_TEST_EQ(*ot, "");
}
namespace no_rvalue_refs {
class Guard
{
public:
int which_ctor;
Guard () : which_ctor(0) { }
Guard (std::string const&) : which_ctor(5) { }
Guard (std::string &) : which_ctor(6) { }
private:
Guard(Guard const&);
void operator=(Guard const&);
};
void test_emplace()
{
const std::string cs;
std::string ms;
optional<Guard> o;
o.emplace();
BOOST_TEST(o);
BOOST_TEST(0 == o->which_ctor);
o.emplace(cs);
BOOST_TEST(o);
BOOST_TEST(5 == o->which_ctor);
o.emplace(ms);
BOOST_TEST(o);
BOOST_TEST(6 == o->which_ctor);
}
void test_in_place_ctor()
{
const std::string cs;
std::string ms;
{
optional<Guard> o (in_place_init);
BOOST_TEST(o);
BOOST_TEST(0 == o->which_ctor);
}
{
optional<Guard> o (in_place_init, cs);
BOOST_TEST(o);
BOOST_TEST(5 == o->which_ctor);
}
{
optional<Guard> o (in_place_init, ms);
BOOST_TEST(o);
BOOST_TEST(6 == o->which_ctor);
}
}
void test_in_place_if_ctor()
{
const std::string cs;
std::string ms;
{
optional<Guard> n (in_place_init_if, false);
BOOST_TEST(!n);
optional<Guard> o (in_place_init_if, true);
BOOST_TEST(o);
BOOST_TEST(0 == o->which_ctor);
}
{
optional<Guard> n (in_place_init_if, false, cs);
BOOST_TEST(!n);
optional<Guard> o (in_place_init_if, true, cs);
BOOST_TEST(o);
BOOST_TEST(5 == o->which_ctor);
}
{
optional<Guard> n (in_place_init_if, false, ms);
BOOST_TEST(!n);
optional<Guard> o (in_place_init_if, true, ms);
BOOST_TEST(o);
BOOST_TEST(6 == o->which_ctor);
}
}
} // namespace no_rvalue_ref
int main()
{
#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
test_emplace();
test_in_place_ctor();
test_in_place_if_ctor();
#endif
#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
test_no_moves_on_emplacement();
test_no_moves_on_in_place_ctor();
#endif
test_clear_on_throw();
test_no_assignment_on_emplacement();
no_rvalue_refs::test_emplace();
no_rvalue_refs::test_in_place_ctor();
no_rvalue_refs::test_in_place_if_ctor();
return boost::report_errors();
}

View File

@@ -0,0 +1,57 @@
// Copyright (C) 2016 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
using boost::optional;
struct Value
{
explicit Value(int) {}
};
#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
template <typename T>
void test_brace_init()
{
optional<T> o = {};
BOOST_TEST(!o);
}
template <typename T>
void test_brace_assign()
{
optional<T> o;
o = {};
BOOST_TEST(!o);
}
#endif
int main()
{
#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
test_brace_init<int>();
test_brace_init<Value>();
test_brace_assign<int>();
test_brace_assign<Value>();
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,43 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
#include "boost/none.hpp"
struct SemiRegular // no operator==
{
private: void operator==(SemiRegular const&) const {}
private: void operator!=(SemiRegular const&) const {}
};
void test_equal_to_none_of_noncomparable_T()
{
boost::optional<SemiRegular> i = SemiRegular();
boost::optional<SemiRegular> o;
BOOST_TEST(i != boost::none);
BOOST_TEST(boost::none != i);
BOOST_TEST(o == boost::none);
BOOST_TEST(boost::none == o);
}
int main()
{
test_equal_to_none_of_noncomparable_T();
return boost::report_errors();
}

View File

@@ -0,0 +1,152 @@
// Copyright (C) 2017 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
#include "boost/core/lightweight_test_trait.hpp"
#include "boost/type_traits/is_base_of.hpp"
#include "boost/optional/detail/experimental_traits.hpp"
#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
struct PrivDefault
{
private: PrivDefault() {}
};
struct CustDefault
{
CustDefault() {}
};
struct CustomizedTrivial
{
CustomizedTrivial() {}
};
struct DeletedDefault
{
BOOST_DELETED_FUNCTION(DeletedDefault())
};
namespace boost { namespace optional_config {
template <> struct optional_uses_direct_storage_for<CustomizedTrivial> : boost::true_type {};
}}
struct CustDtor
{
~CustDtor() {}
};
struct NoDefault
{
explicit NoDefault(int) {}
};
struct Empty {};
template <typename T, typename U>
struct Aggregate { T t; U u; };
struct CustAssign
{
CustAssign& operator=(CustAssign const&) { return *this; }
};
struct CustMove
{
CustMove(CustMove &&) {}
};
void test_type_traits()
{
// this only tests if type traits are implemented correctly
BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for<int> ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for<double> ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for<CustomizedTrivial> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<PrivDefault> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<NoDefault> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<CustDefault> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<Aggregate<int, CustDefault> > ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<CustDtor> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<CustAssign> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<CustMove> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<Aggregate<int, CustMove> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<int> ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<double> ));
#ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for<Empty> ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for<Aggregate<int, double> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for<Aggregate<Aggregate<Empty, int>, double> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<Empty> ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<Aggregate<int, double> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<Aggregate<Aggregate<Empty, int>, double> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<PrivDefault> ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<NoDefault> ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<CustDefault> ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<Aggregate<int, CustDefault> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<DeletedDefault> ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<Aggregate<int, DeletedDefault> > ));
#endif
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<DeletedDefault> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<Aggregate<int, DeletedDefault> > ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable<CustDtor> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable<CustAssign> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable<CustMove> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable<Aggregate<int, CustMove> > ));
}
void test_trivial_copyability()
{
BOOST_TEST_TRAIT_TRUE((boost::is_base_of<boost::optional_detail::tc_optional_base<int>, boost::optional<int> > ));
BOOST_TEST_TRAIT_TRUE((boost::is_base_of<boost::optional_detail::tc_optional_base<double>, boost::optional<double> > ));
BOOST_TEST_TRAIT_TRUE((boost::is_base_of<boost::optional_detail::tc_optional_base<CustomizedTrivial>, boost::optional<CustomizedTrivial> > ));
BOOST_TEST_TRAIT_FALSE((boost::is_base_of<boost::optional_detail::tc_optional_base<DeletedDefault>, boost::optional<DeletedDefault> > ));
#ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<int> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<double> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<CustomizedTrivial> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<Empty> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<Aggregate<int, double> > > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<Aggregate<Aggregate<Empty, int>, double> > > ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<DeletedDefault> > ));
#endif
}
#endif
int main()
{
#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
test_type_traits();
test_trivial_copyability();
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,25 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void test_deep_constantness()
{
boost::optional<int> opt ;
boost::optional<int> const copt ;
*copt = opt ; // Cannot assign to "int const&"
}

View File

@@ -0,0 +1,26 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void test_no_implicit_conversion()
{
boost::optional<int> opt(1) ;
// You can compare against 0 or against another optional<>,
// but not against another value
if ( opt == 1 ) ;
}

View File

@@ -0,0 +1,33 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
#if BOOST_WORKAROUND( BOOST_INTEL_CXX_VERSION, <= 700) // Intel C++ 7.0
// Interl C++ 7.0 incorrectly accepts the initialization "boost::optional<int> opt = 3"
// even though the ctor is explicit (c.f. 12.3.1.2), so the test uses another form of
// copy-initialization: argument-passing (8.5.12)
void helper ( boost::optional<int> ) ;
void test_explicit_constructor()
{
helper(3) ; // ERROR: Ctor is explicit.
}
#else
void test_explicit_constructor()
{
boost::optional<int> opt = 3 ; // ERROR: Ctor is explicit.
}
#endif

View File

@@ -0,0 +1,25 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#include<string>
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void test_no_unsupported_conversion()
{
boost::optional<int> opt1(1) ;
boost::optional< std::string > opt2( opt1 ) ; // Cannot convert from "int" to "std::string"
}

View File

@@ -0,0 +1,28 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#include<string>
#include "boost/optional.hpp"
struct A {} ;
struct B {} ;
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void test_no_unsupported_conversion()
{
boost::optional<A> opt1;
boost::optional<B> opt2;
opt2 = opt1 ; // Cannot convert from "A" to "B"
}

View File

@@ -0,0 +1,26 @@
// Copyright (C) 2018, Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional.hpp"
// THIS TEST SHOULD FAIL TO COMPILE
void test_converitng_assignment_of_different_enums()
{
const boost::optional<int> o1(1);
const boost::optional<int> o2(2);
swap(o1, o2); // no swap on const objects should compile
}
int main()
{
test_converitng_assignment_of_different_enums();
}

View File

@@ -0,0 +1,26 @@
// Copyright (C) 2015, Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional.hpp"
// THIS TEST SHOULD FAIL TO COMPILE
enum E1 {e1};
enum E2 {e2};
void test_converitng_assignment_of_different_enums()
{
boost::optional<E2> o2(e2);
boost::optional<E1> o1;
o1 = o2;
}
int main() {}

View File

@@ -0,0 +1,25 @@
// Copyright (C) 2014, Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
struct NoInitFromNull{};
void test_conversion_from_null()
{
boost::optional<NoInitFromNull> opt = 0;
}

View File

@@ -0,0 +1,36 @@
// Copyright (C) 2014, Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
class MoveOnly
{
public:
int val;
MoveOnly(int v) : val(v) {}
MoveOnly(MoveOnly&& rhs) : val(rhs.val) { rhs.val = 0; }
void operator=(MoveOnly&& rhs) {val = rhs.val; rhs.val = 0; }
private:
MoveOnly(MoveOnly const&);
void operator=(MoveOnly const&);
};
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void test_copying_optional_with_noncopyable_T()
{
boost::optional<MoveOnly> opt1 ;
boost::optional<MoveOnly> opt2(opt1) ;
}

View File

@@ -0,0 +1,32 @@
// Copyright (C) 2014, Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
struct U
{};
struct T
{
explicit T(U const&) {}
};
void test_implicit_conversion_to_bool()
{
boost::optional<T> opt;
opt.value_or(U());
}

View File

@@ -0,0 +1,34 @@
// Copyright (C) 2014, Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
struct U
{};
struct T
{
explicit T(U const&) {}
};
U get_U() { return U(); }
void test_verifying_the_implicit_conversion_to_bool()
{
boost::optional<T> opt;
opt.value_or_eval(get_U);
}

View File

@@ -0,0 +1,28 @@
// Copyright (C) 2014, Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
bool test_implicit_conversion_to_bool()
{
boost::optional<int> opt;
return opt;
}
#else
# error "Test skipped: this compiler does not support explicit conversion operators."
#endif

View File

@@ -0,0 +1,24 @@
// Copyright (C) 2015, Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include <iostream>
#include "boost/optional.hpp"
// but no boost/optional/optional_io.hpp
// THIS TEST SHOULD FAIL TO COMPILE
// Unless one includes header boost/optional/optional_io.hpp, it should not be possible
// to stream out an optional object.
void test_streaming_out_optional()
{
boost::optional<int> opt;
std::cout << opt;
}

View File

@@ -0,0 +1,23 @@
// Copyright (C) 2015, Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include <iostream>
#include "boost/none.hpp"
// but no boost/optional/optional_io.hpp
// THIS TEST SHOULD FAIL TO COMPILE
// Unless one includes header boost/optional/optional_io.hpp, it should not be possible
// to stream out boost::none.
void test_streaming_out_none()
{
std::cout << boost::none;
}

View File

@@ -0,0 +1,19 @@
// Copyright (C) 2014, Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
boost::optional<int&&> oi;

View File

@@ -0,0 +1,275 @@
// Copyright (C) 2018 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/ignore_unused.hpp"
#include "boost/core/is_same.hpp"
#include "boost/core/lightweight_test.hpp"
#include "boost/core/lightweight_test_trait.hpp"
using boost::optional;
using boost::make_optional;
using boost::core::is_same;
template <typename Expected, typename Deduced>
void verify_type(Deduced)
{
BOOST_TEST_TRAIT_TRUE(( is_same<Expected, Deduced> ));
}
struct Int
{
int i;
explicit Int(int i_) : i(i_) {}
};
struct convert_t
{
typedef optional<Int> result_type;
optional<Int> operator()(int i) { if (i != 0) return Int(i); else return boost::none; }
};
void test_flat_map_on_mutable_optional_with_function_object()
{
{
optional<int> oi (1);
verify_type< optional<Int> >(oi.flat_map(convert_t()));
optional<Int> oI = oi.flat_map(convert_t());
BOOST_TEST(bool(oI));
BOOST_TEST_EQ(1, oI->i);
}
{
optional<int> oi (0);
optional<Int> oI = oi.flat_map(convert_t());
BOOST_TEST(!oI);
}
{
optional<int> oi;
optional<Int> oI = oi.flat_map(convert_t());
BOOST_TEST(!oI);
}
}
void test_flat_map_on_const_optional_with_function_object()
{
{
const optional<int> oi (1);
verify_type< optional<Int> >(oi.flat_map(convert_t()));
optional<Int> oI = oi.flat_map(convert_t());
BOOST_TEST(bool(oI));
BOOST_TEST_EQ(1, oI->i);
}
{
const optional<int> oi (0);
optional<Int> oI = oi.flat_map(convert_t());
BOOST_TEST(!oI);
}
{
const optional<int> oi;
optional<Int> oI = oi.flat_map(convert_t());
BOOST_TEST(!oI);
}
}
void test_flat_map_with_lambda()
{
#if !defined BOOST_NO_CXX11_LAMBDAS && !defined BOOST_NO_CXX11_DECLTYPE_N3276
{
optional<int> oi (1);
verify_type< optional<Int> >(oi.flat_map([](int i){ return optional<Int>(i == 0, Int(i)); }));
optional<Int> oI = oi.flat_map([](int i){ return optional<Int>(i != 0, Int(i)); });
BOOST_TEST(bool(oI));
BOOST_TEST_EQ(1, oI->i);
}
{
optional<int> oi (0);
optional<Int> oI = oi.flat_map([](int i){ return optional<Int>(i != 0, Int(i)); });
BOOST_TEST(!oI);
}
{
optional<int> oi;
optional<Int> oI = oi.flat_map([](int i){ return optional<Int>(i != 0, Int(i)); });
BOOST_TEST(!oI);
}
#endif // lambdas
}
struct get_opt_ref
{
typedef optional<int&> result_type;
optional<int&> operator()(int& i) { return i != 0 ? optional<int&>(i) : optional<int&>(); }
};
void test_flat_map_obj_to_ref()
{
{
optional<int> oi (2);
verify_type< optional<int&> >(oi.flat_map(get_opt_ref()));
optional<int&> ori = oi.flat_map(get_opt_ref());
BOOST_TEST(bool(ori));
BOOST_TEST_EQ(2, *ori);
*ori = 3;
BOOST_TEST(bool(oi));
BOOST_TEST_EQ(3, *oi);
BOOST_TEST_EQ(3, *ori);
}
{
optional<int> oi (0);
optional<int&> ori = oi.flat_map(get_opt_ref());
BOOST_TEST(!ori);
}
{
optional<int> oi;
optional<int&> ori = oi.flat_map(get_opt_ref());
BOOST_TEST(!ori);
}
}
optional<int&> get_opt_int_ref(Int& i)
{
return i.i ? optional<int&>(i.i) : optional<int&>();
}
void test_flat_map_ref_to_ref()
{
{
Int I (5);
optional<Int&> orI (I);
verify_type< optional<int&> >(orI.flat_map(get_opt_int_ref));
optional<int&> ori = orI.flat_map(get_opt_int_ref);
BOOST_TEST(bool(ori));
BOOST_TEST_EQ(5, *ori);
*ori = 6;
BOOST_TEST_EQ(6, *ori);
BOOST_TEST_EQ(6, I.i);
}
{
Int I (0);
optional<Int&> orI (I);
optional<int&> ori = orI.flat_map(get_opt_int_ref);
BOOST_TEST(!ori);
}
{
optional<Int&> orI;
optional<int&> ori = orI.flat_map(get_opt_int_ref);
BOOST_TEST(!ori);
}
}
optional< optional<Int> > make_opt_int(int i)
{
if (i == 0)
return boost::none;
else if (i == 1)
return boost::make_optional(optional<Int>());
else
return boost::make_optional(boost::make_optional(Int(i)));
}
void test_flat_map_opt_opt()
{
{
optional<int> oi (9);
verify_type<optional<optional<Int> > >(oi.flat_map(make_opt_int));
optional<optional<Int> > ooI = oi.flat_map(make_opt_int);
BOOST_TEST(bool(ooI));
BOOST_TEST(bool(*ooI));
BOOST_TEST_EQ(9, (**ooI).i);
}
{
optional<int> oi (1);
optional<optional<Int> > ooI = oi.flat_map(make_opt_int);
BOOST_TEST(bool(ooI));
BOOST_TEST(!*ooI);
}
{
optional<int> oi (0);
optional<optional<Int> > ooI = oi.flat_map(make_opt_int);
BOOST_TEST(!ooI);
}
{
optional<int> oi;
optional<optional<Int> > ooI = oi.flat_map(make_opt_int);
BOOST_TEST(!ooI);
}
}
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
struct MoveOnly
{
int value;
explicit MoveOnly(int i) : value(i) {}
MoveOnly(MoveOnly && r) : value(r.value) { r.value = 0; }
MoveOnly& operator=(MoveOnly && r) { value = r.value; r.value = 0; return *this; }
private:
MoveOnly(MoveOnly const&);
void operator=(MoveOnly const&);
};
MoveOnly makeMoveOnly(int i)
{
return MoveOnly(i);
}
optional<MoveOnly> makeOptMoveOnly(int i)
{
return optional<MoveOnly>(MoveOnly(i));
}
optional<int> get_val(MoveOnly m)
{
return optional<int>(m.value != 0, m.value);
}
void test_flat_map_move_only()
{
{
optional<MoveOnly> om (makeMoveOnly(1)), om2 (makeMoveOnly(2));
verify_type<optional<int> >(boost::move(om).flat_map(get_val));
optional<int> oi = boost::move(om2).flat_map(get_val);
BOOST_TEST(bool(oi));
BOOST_TEST_EQ(2, *oi);
}
{
optional<int> oj = makeOptMoveOnly(4).flat_map(get_val);
BOOST_TEST(bool(oj));
BOOST_TEST_EQ(4, *oj);
}
{
optional<int> oj = optional<MoveOnly>().flat_map(get_val);
BOOST_TEST(!oj);
}
}
#endif // no rvalue refs
int main()
{
test_flat_map_on_mutable_optional_with_function_object();
test_flat_map_on_const_optional_with_function_object();
test_flat_map_with_lambda();
test_flat_map_obj_to_ref();
test_flat_map_ref_to_ref();
test_flat_map_opt_opt();
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
test_flat_map_move_only();
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,113 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
#include<string>
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
#include "boost/utility/in_place_factory.hpp"
#include "boost/utility/typed_in_place_factory.hpp"
#endif
#include "boost/core/lightweight_test.hpp"
#include "boost/none.hpp"
struct Guard
{
double num;
std::string str;
Guard() : num() {}
Guard(double num_, std::string str_) : num(num_), str(str_) {}
friend bool operator==(const Guard& lhs, const Guard& rhs) { return lhs.num == rhs.num && lhs.str == rhs.str; }
friend bool operator!=(const Guard& lhs, const Guard& rhs) { return !(lhs == rhs); }
private:
Guard(const Guard&);
Guard& operator=(const Guard&);
};
void test_ctor()
{
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
Guard g0, g1(1.0, "one"), g2(2.0, "two");
boost::optional<Guard> og0 ( boost::in_place() );
boost::optional<Guard> og1 ( boost::in_place(1.0, "one") );
boost::optional<Guard> og1_( boost::in_place(1.0, "one") );
boost::optional<Guard> og2 ( boost::in_place<Guard>(2.0, "two") );
BOOST_TEST(og0);
BOOST_TEST(og1);
BOOST_TEST(og1_);
BOOST_TEST(og2);
BOOST_TEST(*og0 == g0);
BOOST_TEST(*og1 == g1);
BOOST_TEST(*og1_ == g1);
BOOST_TEST(*og2 == g2);
BOOST_TEST(og1_ == og1);
BOOST_TEST(og1_ != og2);
BOOST_TEST(og1_ != og0);
boost::optional<unsigned int> o( boost::in_place(5) );
BOOST_TEST(o);
BOOST_TEST(*o == 5);
#endif
}
void test_assign()
{
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
#ifndef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
Guard g0, g1(1.0, "one"), g2(2.0, "two");
boost::optional<Guard> og0, og1, og1_, og2;
og0 = boost::in_place();
og1 = boost::in_place(1.0, "one");
og1_ = boost::in_place(1.0, "one");
og2 = boost::in_place<Guard>(2.0, "two");
BOOST_TEST(og0);
BOOST_TEST(og1);
BOOST_TEST(og1_);
BOOST_TEST(og2);
BOOST_TEST(*og0 == g0);
BOOST_TEST(*og1 == g1);
BOOST_TEST(*og1_ == g1);
BOOST_TEST(*og2 == g2);
BOOST_TEST(og1_ == og1);
BOOST_TEST(og1_ != og2);
BOOST_TEST(og1_ != og0);
boost::optional<unsigned int> o;
o = boost::in_place(5);
BOOST_TEST(o);
BOOST_TEST(*o == 5);
#endif
#endif
}
int main()
{
test_ctor();
test_assign();
return boost::report_errors();
}

View File

@@ -0,0 +1,53 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
#include<string>
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
#include "boost/utility/in_place_factory.hpp"
#include "boost/utility/typed_in_place_factory.hpp"
#endif
#include "boost/core/lightweight_test.hpp"
#include "boost/none.hpp"
struct Guard
{
double num;
std::string str;
Guard() : num() {}
Guard(double num_, std::string str_) : num(num_), str(str_) {}
friend bool operator==(const Guard& lhs, const Guard& rhs) { return lhs.num == rhs.num && lhs.str == rhs.str; }
friend bool operator!=(const Guard& lhs, const Guard& rhs) { return !(lhs == rhs); }
private:
Guard(const Guard&);
Guard& operator=(const Guard&);
};
int main()
{
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
int excessive_param = 2;
boost::optional<Guard> og1 ( boost::in_place(1.0, "one", excessive_param) );
#else
NOTHING_TO_TEST_SO_JUST_FAIL
#endif
return 0;
}

View File

@@ -0,0 +1,53 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
#include<string>
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
#include "boost/utility/in_place_factory.hpp"
#include "boost/utility/typed_in_place_factory.hpp"
#endif
#include "boost/core/lightweight_test.hpp"
#include "boost/none.hpp"
struct Guard
{
double num;
std::string str;
Guard() : num() {}
Guard(double num_, std::string str_) : num(num_), str(str_) {}
friend bool operator==(const Guard& lhs, const Guard& rhs) { return lhs.num == rhs.num && lhs.str == rhs.str; }
friend bool operator!=(const Guard& lhs, const Guard& rhs) { return !(lhs == rhs); }
private:
Guard(const Guard&);
Guard& operator=(const Guard&);
};
int main()
{
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
typedef int BAD_TARGET_TYPE;
boost::optional<Guard> og1 ( boost::in_place<BAD_TARGET_TYPE>(1.0, "one") );
#else
NOTHING_TO_TEST_SO_JUST_FAIL
#endif
return 0;
}

View File

@@ -0,0 +1,87 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
#include <sstream>
#include "boost/optional/optional.hpp"
#include "boost/optional/optional_io.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
using boost::optional;
template<class Opt>
void test2( Opt o, Opt buff )
{
std::stringstream s ;
const int markv = 123 ;
int mark = 0 ;
s << o << " " << markv ;
s >> buff >> mark ;
BOOST_TEST( buff == o ) ;
BOOST_TEST( mark == markv ) ;
}
template<class T>
void test( T v, T w )
{
test2( boost::make_optional(v), optional<T> ());
test2( boost::make_optional(v), boost::make_optional(w));
test2( optional<T> () , optional<T> ());
test2( optional<T> () , boost::make_optional(w));
}
template <class T>
void subtest_tag_none_reversibility_with_optional(optional<T> ov)
{
std::stringstream s;
s << boost::none;
s >> ov;
BOOST_TEST(!ov);
}
template <class T>
void subtest_tag_none_equivalence_with_optional()
{
std::stringstream s, r;
optional<T> ov;
s << boost::none;
r << ov;
BOOST_TEST_EQ(s.str(), r.str());
}
template <class T>
void test_tag_none(T v)
{
subtest_tag_none_reversibility_with_optional(optional<T>(v));
subtest_tag_none_reversibility_with_optional(optional<T>());
subtest_tag_none_equivalence_with_optional<T>();
}
int main()
{
test(1,2);
test(std::string("hello"), std::string("buffer"));
test_tag_none(10);
test_tag_none(std::string("text"));
return boost::report_errors();
}

View File

@@ -0,0 +1,121 @@
// Copyright (C) 2017 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/ignore_unused.hpp"
#include "boost/core/is_same.hpp"
#include "boost/core/lightweight_test.hpp"
#include "boost/core/lightweight_test_trait.hpp"
using boost::optional;
using boost::make_optional;
using boost::core::is_same;
template <typename Expected, typename Deduced>
void verify_type(Deduced)
{
BOOST_TEST_TRAIT_TRUE(( is_same<Expected, Deduced> ));
}
#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
struct MoveOnly
{
int value;
explicit MoveOnly(int i) : value(i) {}
MoveOnly(MoveOnly && r) : value(r.value) { r.value = 0; }
MoveOnly& operator=(MoveOnly && r) { value = r.value; r.value = 0; return *this; }
private:
MoveOnly(MoveOnly const&);
void operator=(MoveOnly const&);
};
MoveOnly makeMoveOnly(int i)
{
return MoveOnly(i);
}
void test_make_optional_for_move_only_type()
{
verify_type< optional<MoveOnly> >(make_optional(makeMoveOnly(2)));
verify_type< optional<MoveOnly> >(make_optional(true, makeMoveOnly(2)));
optional<MoveOnly> o1 = make_optional(makeMoveOnly(1));
BOOST_TEST (o1);
BOOST_TEST_EQ (1, o1->value);
optional<MoveOnly> o2 = make_optional(true, makeMoveOnly(2));
BOOST_TEST (o2);
BOOST_TEST_EQ (2, o2->value);
optional<MoveOnly> oN = make_optional(false, makeMoveOnly(2));
BOOST_TEST (!oN);
}
#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
void test_make_optional_for_optional()
{
optional<int> oi;
verify_type< optional< optional<int> > >(make_optional(oi));
verify_type< optional< optional<int> > >(make_optional(true, oi));
optional< optional<int> > ooi = make_optional(oi);
BOOST_TEST (ooi);
BOOST_TEST (!*ooi);
optional< optional<int> > ooT = make_optional(true, oi);
BOOST_TEST (ooT);
BOOST_TEST (!*ooT);
optional< optional<int> > ooF = make_optional(false, oi);
BOOST_TEST (!ooF);
}
void test_nested_make_optional()
{
verify_type< optional< optional<int> > >(make_optional(make_optional(1)));
verify_type< optional< optional<int> > >(make_optional(true, make_optional(true, 2)));
optional< optional<int> > oo1 = make_optional(make_optional(1));
BOOST_TEST (oo1);
BOOST_TEST (*oo1);
BOOST_TEST_EQ (1, **oo1);
optional< optional<int> > oo2 = make_optional(true, make_optional(true, 2));
BOOST_TEST (oo2);
BOOST_TEST (*oo2);
BOOST_TEST_EQ (2, **oo2);
optional< optional<int> > oo3 = make_optional(true, make_optional(false, 3));
BOOST_TEST (oo3);
BOOST_TEST (!*oo3);
optional< optional<int> > oo4 = make_optional(false, make_optional(true, 4));
BOOST_TEST (!oo4);
}
int main()
{
#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
test_make_optional_for_move_only_type();
#endif
test_make_optional_for_optional();
test_nested_make_optional();
return boost::report_errors();
}

View File

@@ -0,0 +1,192 @@
// Copyright (C) 2018 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/ignore_unused.hpp"
#include "boost/core/is_same.hpp"
#include "boost/core/lightweight_test.hpp"
#include "boost/core/lightweight_test_trait.hpp"
using boost::optional;
using boost::make_optional;
using boost::core::is_same;
template <typename Expected, typename Deduced>
void verify_type(Deduced)
{
BOOST_TEST_TRAIT_TRUE(( is_same<Expected, Deduced> ));
}
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
struct MoveOnly
{
int value;
explicit MoveOnly(int i) : value(i) {}
MoveOnly(MoveOnly && r) : value(r.value) { r.value = 0; }
MoveOnly& operator=(MoveOnly && r) { value = r.value; r.value = 0; return *this; }
private:
MoveOnly(MoveOnly const&);
void operator=(MoveOnly const&);
};
MoveOnly makeMoveOnly(int i)
{
return MoveOnly(i);
}
optional<MoveOnly> makeOptMoveOnly(int i)
{
return optional<MoveOnly>(MoveOnly(i));
}
int get_val(MoveOnly m)
{
return m.value;
}
void test_map_move_only()
{
optional<MoveOnly> om (makeMoveOnly(7)), om2 (makeMoveOnly(8));
verify_type<optional<int> >(boost::move(om).map(get_val));
optional<int> oi = boost::move(om2).map(get_val);
BOOST_TEST(bool(oi));
BOOST_TEST_EQ(8, *oi);
optional<int> oj = makeOptMoveOnly(4).map(get_val);
BOOST_TEST(bool(oj));
BOOST_TEST_EQ(4, *oj);
optional<MoveOnly> o_;
optional<int> oi_ = boost::move(o_).map(get_val);
BOOST_TEST(!oi_);
}
#endif // no rvalue refs
struct Int
{
int i;
explicit Int(int i_) : i(i_) {}
};
struct convert_t
{
typedef Int result_type;
Int operator()(int i) { return Int(i); }
};
int& get_int_ref(Int& i)
{
return i.i;
}
struct get_ref
{
typedef int& result_type;
int& operator()(int& i) { return i; }
};
void test_map()
{
optional<int> oi (1);
verify_type<optional<Int> >(oi.map(convert_t()));
optional<Int> oI = oi.map(convert_t());
BOOST_TEST(bool(oI));
BOOST_TEST_EQ(1, oI->i);
optional<Int> o_ = optional<int>().map(convert_t());
BOOST_TEST(!o_);
}
optional<Int> make_opt_int(int i)
{
if (i != 0)
return Int(i);
else
return boost::none;
}
void test_map_optional()
{
optional<int> o9 (9), o0 (0), o_;
verify_type<optional<optional<Int> > >(o9.map(make_opt_int));
optional<optional<Int> > oo9 = o9.map(make_opt_int);
BOOST_TEST(bool(oo9));
BOOST_TEST(bool(*oo9));
BOOST_TEST_EQ(9, (**oo9).i);
optional<optional<Int> > oo0 = o0.map(make_opt_int);
BOOST_TEST(bool(oo0));
BOOST_TEST(!*oo0);
optional<optional<Int> > oo_ = o_.map(make_opt_int);
BOOST_TEST(!oo_);
}
void test_map_with_lambda()
{
#if !defined BOOST_NO_CXX11_LAMBDAS && !defined BOOST_NO_CXX11_DECLTYPE_N3276
optional<int> oi (1), oj(2);
verify_type<optional<bool> >(oi.map([](int i){ return i == 1; }));
optional<bool> ob = oi.map([](int i){ return i == 1; });
optional<bool> oc = oj.map([](int i){ return i == 1; });
BOOST_TEST(bool(ob));
BOOST_TEST_EQ(true, *ob);
BOOST_TEST(bool(oc));
BOOST_TEST_EQ(false, *oc);
#endif // lambdas
}
void test_map_to_ref()
{
optional<int> oi (2);
verify_type<optional<int&> >(oi.map(get_ref()));
optional<int&> ori = oi.map(get_ref());
BOOST_TEST(bool(ori));
*ori = 3;
BOOST_TEST(bool(oi));
BOOST_TEST_EQ(3, *oi);
BOOST_TEST_EQ(3, *ori);
}
void test_map_optional_ref()
{
Int I (5);
optional<Int&> ori (I);
verify_type<optional<int&> >(ori.map(get_int_ref));
optional<int&> orii = ori.map(get_int_ref);
BOOST_TEST(bool(orii));
BOOST_TEST_EQ(5, *orii);
*orii = 6;
BOOST_TEST_EQ(6, I.i);
}
int main()
{
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
test_map_move_only();
#endif
test_map_with_lambda();
test_map();
test_map_optional();
test_map_to_ref();
test_map_optional();
test_map_optional_ref();
return boost::report_errors();
}

View File

@@ -0,0 +1,32 @@
// Copyright (C) 2017 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
boost::optional<int> getitem();
int main(int argc, const char *[])
{
boost::optional<int> a = getitem();
boost::optional<int> b;
if (argc > 0)
b = argc;
if (a == b)
return 1;
return 0;
}

View File

@@ -0,0 +1,44 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
struct Status
{
enum T
{
DISCONNECTED,
CONNECTING,
CONNECTED,
};
T mValue;
};
void test_member_T()
{
boost::optional<Status> x = Status();
x->mValue = Status::CONNECTED;
BOOST_TEST(x->mValue == Status::CONNECTED);
}
int main()
{
test_member_T();
return boost::report_errors();
}

View File

@@ -0,0 +1,76 @@
// Copyright (C) 2014-2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include <string>
#include "boost/core/lightweight_test.hpp"
#include "boost/none.hpp"
class NonConstructible
{
private:
NonConstructible();
NonConstructible(NonConstructible const&);
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
NonConstructible(NonConstructible &&);
#endif
};
void test_non_constructible()
{
boost::optional<NonConstructible> o;
BOOST_TEST(!o);
BOOST_TEST(o == boost::none);
BOOST_TEST_THROWS(o.value(), boost::bad_optional_access);
}
class Guard
{
public:
explicit Guard(int) {}
private:
Guard();
Guard(Guard const&);
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
Guard(Guard &&);
#endif
};
void test_guard()
{
boost::optional<Guard> o;
o.emplace(1);
BOOST_TEST(o);
BOOST_TEST(o != boost::none);
}
void test_non_assignable()
{
boost::optional<const std::string> o;
o.emplace("cat");
BOOST_TEST(o);
BOOST_TEST(o != boost::none);
BOOST_TEST_EQ(*o, std::string("cat"));
}
int main()
{
test_non_constructible();
test_guard();
test_non_assignable();
return boost::report_errors();
}

View File

@@ -0,0 +1,352 @@
// Copyright (C) 2014 - 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
using boost::optional;
using boost::none;
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
enum State
{
sDefaultConstructed,
sValueCopyConstructed,
sValueMoveConstructed,
sCopyConstructed,
sMoveConstructed,
sMoveAssigned,
sCopyAssigned,
sValueCopyAssigned,
sValueMoveAssigned,
sMovedFrom,
sIntConstructed
};
struct OracleVal
{
State s;
int i;
OracleVal(int i = 0) : s(sIntConstructed), i(i) {}
};
struct Oracle
{
State s;
OracleVal val;
Oracle() : s(sDefaultConstructed) {}
Oracle(const OracleVal& v) : s(sValueCopyConstructed), val(v) {}
Oracle(OracleVal&& v) : s(sValueMoveConstructed), val(std::move(v)) {v.s = sMovedFrom;}
Oracle(const Oracle& o) : s(sCopyConstructed), val(o.val) {}
Oracle(Oracle&& o) : s(sMoveConstructed), val(std::move(o.val)) {o.s = sMovedFrom;}
Oracle& operator=(const OracleVal& v) { s = sValueCopyAssigned; val = v; return *this; }
Oracle& operator=(OracleVal&& v) { s = sValueMoveAssigned; val = std::move(v); v.s = sMovedFrom; return *this; }
Oracle& operator=(const Oracle& o) { s = sCopyAssigned; val = o.val; return *this; }
Oracle& operator=(Oracle&& o) { s = sMoveAssigned; val = std::move(o.val); o.s = sMovedFrom; return *this; }
};
bool operator==( Oracle const& a, Oracle const& b ) { return a.val.i == b.val.i; }
bool operator!=( Oracle const& a, Oracle const& b ) { return a.val.i != b.val.i; }
void test_move_ctor_from_U()
{
optional<Oracle> o1 ((OracleVal()));
BOOST_TEST(o1);
BOOST_TEST(o1->s == sValueMoveConstructed || o1->s == sMoveConstructed);
OracleVal v1;
optional<Oracle> o2 (v1);
BOOST_TEST(o2);
BOOST_TEST(o2->s == sValueCopyConstructed || o2->s == sCopyConstructed || o2->s == sMoveConstructed );
BOOST_TEST(v1.s == sIntConstructed);
optional<Oracle> o3 (boost::move(v1));
BOOST_TEST(o3);
BOOST_TEST(o3->s == sValueMoveConstructed || o3->s == sMoveConstructed);
BOOST_TEST(v1.s == sMovedFrom);
}
void test_move_ctor_form_T()
{
optional<Oracle> o1 ((Oracle()));
BOOST_TEST(o1);
BOOST_TEST(o1->s == sMoveConstructed);
Oracle v1;
optional<Oracle> o2 (v1);
BOOST_TEST(o2);
BOOST_TEST(o2->s == sCopyConstructed);
BOOST_TEST(v1.s == sDefaultConstructed);
optional<Oracle> o3 (boost::move(v1));
BOOST_TEST(o3);
BOOST_TEST(o3->s == sMoveConstructed);
BOOST_TEST(v1.s == sMovedFrom);
}
void test_move_ctor_from_optional_T()
{
optional<Oracle> o1;
optional<Oracle> o2(boost::move(o1));
BOOST_TEST(!o1);
BOOST_TEST(!o2);
optional<Oracle> o3((Oracle()));
optional<Oracle> o4(boost::move(o3));
BOOST_TEST(o3);
BOOST_TEST(o4);
BOOST_TEST(o3->s == sMovedFrom);
BOOST_TEST(o4->s == sMoveConstructed);
optional<Oracle> o5((optional<Oracle>()));
BOOST_TEST(!o5);
optional<Oracle> o6((optional<Oracle>(Oracle())));
BOOST_TEST(o6);
BOOST_TEST(o6->s == sMoveConstructed);
optional<Oracle> o7(o6); // does copy ctor from non-const lvalue compile?
}
void test_move_assign_from_U()
{
optional<Oracle> o1 = boost::none; // test if additional ctors didn't break it
o1 = boost::none; // test if additional assignments didn't break it
o1 = OracleVal();
BOOST_TEST(o1);
BOOST_TEST(o1->s == sValueMoveConstructed);
o1 = OracleVal();
BOOST_TEST(o1);
BOOST_TEST(o1->s == sMoveAssigned);
OracleVal v1;
optional<Oracle> o2;
o2 = v1;
BOOST_TEST(o2);
BOOST_TEST(o2->s == sValueCopyConstructed);
BOOST_TEST(v1.s == sIntConstructed);
o2 = v1;
BOOST_TEST(o2);
BOOST_TEST(o2->s == sCopyAssigned || o2->s == sMoveAssigned);
BOOST_TEST(v1.s == sIntConstructed);
optional<Oracle> o3;
o3 = boost::move(v1);
BOOST_TEST(o3);
BOOST_TEST(o3->s == sValueMoveConstructed);
BOOST_TEST(v1.s == sMovedFrom);
}
void test_move_assign_from_T()
{
optional<Oracle> o1;
o1 = Oracle();
BOOST_TEST(o1);
BOOST_TEST(o1->s == sMoveConstructed);
o1 = Oracle();
BOOST_TEST(o1);
BOOST_TEST(o1->s == sMoveAssigned);
Oracle v1;
optional<Oracle> o2;
o2 = v1;
BOOST_TEST(o2);
BOOST_TEST(o2->s == sCopyConstructed);
BOOST_TEST(v1.s == sDefaultConstructed);
o2 = v1;
BOOST_TEST(o2);
BOOST_TEST(o2->s == sCopyAssigned);
BOOST_TEST(v1.s == sDefaultConstructed);
optional<Oracle> o3;
o3 = boost::move(v1);
BOOST_TEST(o3);
BOOST_TEST(o3->s == sMoveConstructed);
BOOST_TEST(v1.s == sMovedFrom);
}
void test_move_assign_from_optional_T()
{
optional<Oracle> o1;
optional<Oracle> o2;
o1 = optional<Oracle>();
BOOST_TEST(!o1);
optional<Oracle> o3((Oracle()));
o1 = o3;
BOOST_TEST(o3);
BOOST_TEST(o3->s == sMoveConstructed);
BOOST_TEST(o1);
BOOST_TEST(o1->s == sCopyConstructed);
o2 = boost::move(o3);
BOOST_TEST(o3);
BOOST_TEST(o3->s == sMovedFrom);
BOOST_TEST(o2);
BOOST_TEST(o2->s == sMoveConstructed);
o2 = optional<Oracle>((Oracle()));
BOOST_TEST(o2);
BOOST_TEST(o2->s == sMoveAssigned);
}
class MoveOnly
{
public:
int val;
MoveOnly(int v) : val(v) {}
MoveOnly(MoveOnly&& rhs) : val(rhs.val) { rhs.val = 0; }
void operator=(MoveOnly&& rhs) {val = rhs.val; rhs.val = 0; }
private:
MoveOnly(MoveOnly const&);
void operator=(MoveOnly const&);
friend class MoveOnlyB;
};
void test_with_move_only()
{
optional<MoveOnly> o1;
optional<MoveOnly> o2((MoveOnly(1)));
BOOST_TEST(o2);
BOOST_TEST(o2->val == 1);
optional<MoveOnly> o3 (boost::move(o1));
BOOST_TEST(!o3);
optional<MoveOnly> o4 (boost::move(o2));
BOOST_TEST(o4);
BOOST_TEST(o4->val == 1);
BOOST_TEST(o2);
BOOST_TEST(o2->val == 0);
o3 = boost::move(o4);
BOOST_TEST(o3);
BOOST_TEST(o3->val == 1);
BOOST_TEST(o4);
BOOST_TEST(o4->val == 0);
}
class MoveOnlyB
{
public:
int val;
MoveOnlyB(int v) : val(v) {}
MoveOnlyB(MoveOnlyB&& rhs) : val(rhs.val) { rhs.val = 0; }
void operator=(MoveOnlyB&& rhs) {val = rhs.val; rhs.val = 0; }
MoveOnlyB(MoveOnly&& rhs) : val(rhs.val) { rhs.val = 0; }
void operator=(MoveOnly&& rhs) {val = rhs.val; rhs.val = 0; }
private:
MoveOnlyB(MoveOnlyB const&);
void operator=(MoveOnlyB const&);
MoveOnlyB(MoveOnly const&);
void operator=(MoveOnly const&);
};
void test_move_assign_from_optional_U()
{
optional<MoveOnly> a((MoveOnly(2)));
optional<MoveOnlyB> b1;
b1 = boost::move(a);
BOOST_TEST(b1);
BOOST_TEST(b1->val == 2);
BOOST_TEST(a);
BOOST_TEST(a->val == 0);
b1 = MoveOnly(4);
BOOST_TEST(b1);
BOOST_TEST(b1->val == 4);
}
void test_move_ctor_from_optional_U()
{
optional<MoveOnly> a((MoveOnly(2)));
optional<MoveOnlyB> b1(boost::move(a));
BOOST_TEST(b1);
BOOST_TEST(b1->val == 2);
BOOST_TEST(a);
BOOST_TEST(a->val == 0);
optional<MoveOnlyB> b2(( optional<MoveOnly>(( MoveOnly(4) )) ));
BOOST_TEST(b2);
BOOST_TEST(b2->val == 4);
}
void test_swap()
{
optional<MoveOnly> a((MoveOnly(2)));
optional<MoveOnly> b((MoveOnly(3)));
swap(a, b);
BOOST_TEST(a->val == 3);
BOOST_TEST(b->val == 2);
}
void test_optional_ref_to_movables()
{
MoveOnly m(3);
optional<MoveOnly&> orm = m;
orm->val = 2;
BOOST_TEST(m.val == 2);
optional<MoveOnly&> orm2 = orm;
orm2->val = 1;
BOOST_TEST(m.val == 1);
BOOST_TEST(orm->val == 1);
optional<MoveOnly&> orm3 = boost::move(orm);
orm3->val = 4;
BOOST_TEST(m.val == 4);
BOOST_TEST(orm->val == 4);
BOOST_TEST(orm2->val == 4);
}
#endif
int main()
{
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
test_move_ctor_from_U();
test_move_ctor_form_T();
test_move_ctor_from_optional_T();
test_move_ctor_from_optional_U();
test_move_assign_from_U();
test_move_assign_from_T();
test_move_assign_from_optional_T();
test_move_assign_from_optional_U();
test_with_move_only();
test_optional_ref_to_movables();
test_swap();
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,41 @@
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#define BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
struct Wrapper
{
operator int () { return 9; }
operator boost::optional<int> () { return 7; }
};
void test()
{
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
boost::optional<int> v = Wrapper();
BOOST_TEST(v);
BOOST_TEST_EQ(*v, 7);
#endif
}
int main()
{
test();
return boost::report_errors();
}

View File

@@ -0,0 +1,116 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/static_assert.hpp"
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
using boost::optional;
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
#ifndef BOOST_NO_CXX11_NOEXCEPT
// these 4 classes have different noexcept signatures in move operations
struct NothrowBoth {
NothrowBoth(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {};
void operator=(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {};
};
struct NothrowCtor {
NothrowCtor(NothrowCtor&&) BOOST_NOEXCEPT_IF(true) {};
void operator=(NothrowCtor&&) BOOST_NOEXCEPT_IF(false) {};
};
struct NothrowAssign {
NothrowAssign(NothrowAssign&&) BOOST_NOEXCEPT_IF(false) {};
void operator=(NothrowAssign&&) BOOST_NOEXCEPT_IF(true) {};
};
struct NothrowNone {
NothrowNone(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {};
void operator=(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {};
};
#if 0 // these also test type_traits, which are wrong
void test_noexcept_as_defined() // this is a compile-time test
{
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<NothrowBoth>::value);
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable<NothrowBoth>::value);
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<NothrowCtor>::value);
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<NothrowCtor>::value);
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<NothrowAssign>::value);
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable<NothrowAssign>::value);
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<NothrowNone>::value);
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<NothrowNone>::value);
}
void test_noexcept_on_optional_with_type_traits() // this is a compile-time test
{
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowBoth> >::value);
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable<optional<NothrowBoth> >::value);
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowBoth>()));
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowCtor> >::value);
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowCtor> >::value);
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowCtor>()));
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowAssign> >::value);
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowAssign> >::value);
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowAssign>()));
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowNone> >::value);
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowNone> >::value);
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowNone>()));
}
#endif
void test_noexcept_optional_with_operator() // compile-time test
{
typedef optional<NothrowBoth> ONx2;
typedef optional<NothrowCtor> ONxC;
typedef optional<NothrowAssign> ONxA;
typedef optional<NothrowNone> ONx0;
ONx2 onx2;
ONxC onxC;
ONxA onxA;
ONx0 onx0;
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONx2() ));
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONx2(boost::move(onx2)) ));
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( onx2 = ONx2() ));
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONxC() ));
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONxC(boost::move(onxC)) ));
BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( onxC = ONxC() ));
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONxA() ));
BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( ONxA(boost::move(onxA)) ));
BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( onxA = ONxA() ));
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONx0() ));
BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( ONx0(boost::move(onx0)) ));
BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( onx0 = ONx0() ));
}
#endif // !defned BOOST_NO_CXX11_NOEXCEPT
#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
int main()
{
return 0;
}

View File

@@ -0,0 +1,223 @@
// Copyright (C) 2014 - 2018 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#define BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL // does old implementation still work for basic usage?
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/ignore_unused.hpp"
#include "boost/core/lightweight_test.hpp"
using boost::optional;
struct IntWrapper
{
int _i;
IntWrapper(int i) : _i(i) {}
bool operator==(IntWrapper const& rhs) const { return _i == rhs._i; }
};
template <typename T>
void test_function_value_or_for()
{
optional<T> oM0;
const optional<T> oC0;
optional<T> oM1(1);
const optional<T> oC2(2);
BOOST_TEST(oM0.value_or(5) == 5);
BOOST_TEST(oC0.value_or(5) == 5);
BOOST_TEST(oM1.value_or(5) == 1);
BOOST_TEST(oC2.value_or(5) == 2);
}
template <typename T>
void test_function_value_for()
{
optional<T> o0;
optional<T> o1(1);
const optional<T> oC(2);
try
{
T& v = o1.value();
BOOST_TEST(v == 1);
}
catch(...)
{
BOOST_TEST(false);
}
try
{
T const& v = oC.value();
BOOST_TEST(v == 2);
}
catch(...)
{
BOOST_TEST(false);
}
BOOST_TEST_THROWS(o0.value(), boost::bad_optional_access);
}
void test_function_value()
{
test_function_value_for<int>();
test_function_value_for<double>();
test_function_value_for<IntWrapper>();
}
struct FatToIntConverter
{
static int conversions;
int _val;
FatToIntConverter(int val) : _val(val) {}
operator int() const { conversions += 1; return _val; }
};
int FatToIntConverter::conversions = 0;
void test_function_value_or()
{
test_function_value_or_for<int>();
test_function_value_or_for<double>();
test_function_value_or_for<IntWrapper>();
optional<int> oi(1);
BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 1);
BOOST_TEST(FatToIntConverter::conversions == 0);
oi = boost::none;
BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 2);
BOOST_TEST(FatToIntConverter::conversions == 1);
}
struct FunM
{
int operator()() { return 5; }
};
struct FunC
{
int operator()() const { return 6; }
};
int funP ()
{
return 7;
}
int throw_()
{
throw int();
}
void test_function_value_or_eval()
{
optional<int> o1 = 1;
optional<int> oN;
FunM funM;
FunC funC;
BOOST_TEST_EQ(o1.value_or_eval(funM), 1);
BOOST_TEST_EQ(oN.value_or_eval(funM), 5);
BOOST_TEST_EQ(o1.value_or_eval(FunM()), 1);
BOOST_TEST_EQ(oN.value_or_eval(FunM()), 5);
BOOST_TEST_EQ(o1.value_or_eval(funC), 1);
BOOST_TEST_EQ(oN.value_or_eval(funC), 6);
BOOST_TEST_EQ(o1.value_or_eval(FunC()), 1);
BOOST_TEST_EQ(oN.value_or_eval(FunC()), 6);
BOOST_TEST_EQ(o1.value_or_eval(funP), 1);
BOOST_TEST_EQ(oN.value_or_eval(funP), 7);
#ifndef BOOST_NO_CXX11_LAMBDAS
BOOST_TEST_EQ(o1.value_or_eval([](){return 8;}), 1);
BOOST_TEST_EQ(oN.value_or_eval([](){return 8;}), 8);
#endif
try
{
BOOST_TEST_EQ(o1.value_or_eval(throw_), 1);
}
catch(...)
{
BOOST_TEST(false);
}
BOOST_TEST_THROWS(oN.value_or_eval(throw_), int);
}
const optional<std::string> makeConstOptVal()
{
return std::string("something");
}
void test_const_move()
{
std::string s5 = *makeConstOptVal();
std::string s6 = makeConstOptVal().value();
boost::ignore_unused(s5);
boost::ignore_unused(s6);
}
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
struct MoveOnly
{
explicit MoveOnly(int){}
MoveOnly(MoveOnly &&){}
void operator=(MoveOnly &&);
private:
MoveOnly(MoveOnly const&);
void operator=(MoveOnly const&);
};
optional<MoveOnly> makeMoveOnly()
{
return MoveOnly(1);
}
MoveOnly moveOnlyDefault()
{
return MoveOnly(1);
}
// compile-time test
void test_move_only_getters()
{
MoveOnly m1 = *makeMoveOnly();
MoveOnly m2 = makeMoveOnly().value();
MoveOnly m3 = makeMoveOnly().value_or(MoveOnly(1));
MoveOnly m4 = makeMoveOnly().value_or_eval(moveOnlyDefault);
boost::ignore_unused(m1);
boost::ignore_unused(m2);
boost::ignore_unused(m3);
boost::ignore_unused(m4);
}
#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
int main()
{
test_function_value();
test_function_value_or();
test_function_value_or_eval();
test_const_move();
return boost::report_errors();
}

View File

@@ -0,0 +1,73 @@
// Copyright (C) 2019 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#ifndef BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT
#ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS
template <typename, typename>
struct void_t
{
typedef void type;
};
template <typename T, typename = void>
struct trait
{
};
// the following trait emulates properties std::iterator_traits
template <typename T>
struct trait<T, BOOST_DEDUCED_TYPENAME void_t<BOOST_DEDUCED_TYPENAME T::value_type,
BOOST_DEDUCED_TYPENAME boost::enable_if<boost::is_constructible<T, T&> >::type
>::type>
{
typedef BOOST_DEDUCED_TYPENAME T::value_type value_type;
};
// This class emulates the properties of std::filesystem::path
struct Path
{
#if __cplusplus >= 201103
template <typename T, typename = BOOST_DEDUCED_TYPENAME trait<T>::value_type>
Path(T const&);
#else
template <typename T>
Path(T const&, BOOST_DEDUCED_TYPENAME trait<T>::value_type* = 0);
#endif
};
#endif
#endif
int main()
{
#ifndef BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT
#ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS
boost::optional<Path> optFs1;
boost::optional<Path> optFs2;
optFs1 = optFs2;
// the following still fails although it shouldn't
//BOOST_STATIC_ASSERT((std::is_copy_constructible<boost::optional<Path>>::value));
#endif
#endif
}

View File

@@ -0,0 +1,34 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at: akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
#include "testable_classes.hpp"
#include "optional_ref_assign_test_defs.hpp"
using boost::optional;
using boost::none;
int main()
{
test_copy_assignment_for_const<int>();
test_copy_assignment_for_noconst_const<int>();
test_rebinding_assignment_semantics_const<int>();
test_rebinding_assignment_semantics_noconst_const<int>();
return boost::report_errors();
}

View File

@@ -0,0 +1,31 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at: akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
#include "testable_classes.hpp"
#include "optional_ref_assign_test_defs.hpp"
using boost::optional;
using boost::none;
int main()
{
test_copy_assignment_for<int>();
test_rebinding_assignment_semantics<int>();
return boost::report_errors();
}

View File

@@ -0,0 +1,45 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at: akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
#include "testable_classes.hpp"
#include "optional_ref_assign_test_defs.hpp"
using boost::optional;
using boost::none;
template <typename T>
void test_optional_ref_assignment()
{
test_copy_assignment_for<T>();
test_rebinding_assignment_semantics<T>();
test_copy_assignment_for_const<T>();
test_copy_assignment_for_noconst_const<T>();
test_rebinding_assignment_semantics_const<T>();
test_rebinding_assignment_semantics_noconst_const<T>();
}
int main()
{
test_optional_ref_assignment<ScopeGuard>();
test_optional_ref_assignment<Abstract>();
test_optional_ref_assignment< optional<int> >();
return boost::report_errors();
}

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at: akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/addressof.hpp"
#include "boost/core/enable_if.hpp"
#include "boost/core/lightweight_test.hpp"
#include "testable_classes.hpp"
#include "optional_ref_assign_test_defs.hpp"
int main()
{
#ifndef BOOST_OPTIONAL_CONFIG_NO_PROPER_ASSIGN_FROM_CONST_INT
test_converting_assignment<const int, const int>();
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,32 @@
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at: akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/addressof.hpp"
#include "boost/core/enable_if.hpp"
#include "boost/core/lightweight_test.hpp"
#include "testable_classes.hpp"
#include "optional_ref_assign_test_defs.hpp"
int main()
{
#ifdef BOOST_OPTIONAL_CONFIG_NO_PROPER_ASSIGN_FROM_CONST_INT
test_converting_assignment<const int, const int>();
#else
BOOST_STATIC_ASSERT_MSG(false, "EXPECTED TEST COMPILE-TIME FAILURE");
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at: akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/addressof.hpp"
#include "boost/core/enable_if.hpp"
#include "boost/core/lightweight_test.hpp"
#include "testable_classes.hpp"
#include "optional_ref_assign_test_defs.hpp"
int main()
{
test_converting_assignment<int, int>();
test_converting_assignment<int, const int>();
return boost::report_errors();
}

View File

@@ -0,0 +1,39 @@
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at: akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/addressof.hpp"
#include "boost/core/enable_if.hpp"
#include "boost/core/lightweight_test.hpp"
#include "testable_classes.hpp"
#include "optional_ref_assign_test_defs.hpp"
template <typename T>
void test_all_const_cases()
{
test_converting_assignment<T, T>();
test_converting_assignment<const T, const T>();
test_converting_assignment<T, const T>();
}
int main()
{
test_all_const_cases<ScopeGuard>();
test_all_const_cases<Abstract>();
return boost::report_errors();
}

View File

@@ -0,0 +1,110 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at: akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/addressof.hpp"
#include "boost/core/enable_if.hpp"
#include "boost/core/lightweight_test.hpp"
#include "testable_classes.hpp"
using boost::optional;
using boost::none;
template <typename T>
void test_converting_ctor()
{
typename concrete_type_of<T>::type v1(1), v2(2);
{
optional<T&> o1 = v1, o1_ = v1, o2 = v2;
BOOST_TEST(o1);
BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1));
BOOST_TEST(o1_);
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(v1));
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(*o1));
BOOST_TEST(o2);
BOOST_TEST(boost::addressof(*o2) == boost::addressof(v2));
BOOST_TEST(boost::addressof(*o2) != boost::addressof(*o1));
}
{
const optional<T&> o1 = v1, o1_ = v1, o2 = v2;
BOOST_TEST(o1);
BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1));
BOOST_TEST(o1_);
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(v1));
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(*o1));
BOOST_TEST(o2);
BOOST_TEST(boost::addressof(*o2) == boost::addressof(v2));
BOOST_TEST(boost::addressof(*o2) != boost::addressof(*o1));
}
}
template <typename T>
void test_converting_ctor_for_noconst_const()
{
typename concrete_type_of<T>::type v1(1), v2(2);
{
optional<const T&> o1 = v1, o1_ = v1, o2 = v2;
BOOST_TEST(o1);
BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1));
BOOST_TEST(o1_);
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(v1));
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(*o1));
BOOST_TEST(o2);
BOOST_TEST(boost::addressof(*o2) == boost::addressof(v2));
BOOST_TEST(boost::addressof(*o2) != boost::addressof(*o1));
}
{
const optional<const T&> o1 = v1, o1_ = v1, o2 = v2;
BOOST_TEST(o1);
BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1));
BOOST_TEST(o1_);
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(v1));
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(*o1));
BOOST_TEST(o2);
BOOST_TEST(boost::addressof(*o2) == boost::addressof(v2));
BOOST_TEST(boost::addressof(*o2) != boost::addressof(*o1));
}
}
template <typename T>
void test_all_const_cases()
{
test_converting_ctor<T>();
#ifndef BOOST_OPTIONAL_CONFIG_NO_PROPER_CONVERT_FROM_CONST_INT
test_converting_ctor<const T>();
#endif
test_converting_ctor_for_noconst_const<T>();
}
int main()
{
test_all_const_cases<int>();
test_all_const_cases<ScopeGuard>();
test_all_const_cases<Abstract>();
test_all_const_cases< optional<int> >();
return boost::report_errors();
}

View File

@@ -0,0 +1,25 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_converting_assignment()
{
boost::optional<int&> opt ;
double v = 1 ;
double& r = v ;
opt = r ;
}

View File

@@ -0,0 +1,23 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_converting_ctor()
{
boost::optional<short&> opt1 ;
boost::optional<int&> opt2 = opt1 ;
}

View File

@@ -0,0 +1,24 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_converting_initialization()
{
short v = 1 ;
short& r = v;
boost::optional<int&> opt(r) ;
}

View File

@@ -0,0 +1,26 @@
// Copyright (C) 2014, andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_assign_from_Trefref()
{
boost::optional<const int&> opt;
opt = int(3);
}
#else
# error "Test skipped. This cannot be implemented w/o rvalue references."
#endif

View File

@@ -0,0 +1,26 @@
// Copyright (C) 2014, andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_assign_from_Urefref()
{
boost::optional<const int&> opt;
opt = long(3);
}
#else
# error "Test skipped. This cannot be implemented w/o rvalue references."
#endif

View File

@@ -0,0 +1,27 @@
// Copyright (C) 2014, andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
#include "boost/core/ignore_unused.hpp"
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_init_from_Trefref()
{
boost::optional<const int&> opt = int(3);
boost::ignore_unused(opt);
}
#else
# error "Test skipped. This cannot be implemented w/o rvalue references."
#endif

View File

@@ -0,0 +1,27 @@
// Copyright (C) 2014, 2016 andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
#include "boost/core/ignore_unused.hpp"
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_init_from_Urefref()
{
boost::optional<const int&> opt = long(3);
boost::ignore_unused(opt);
}
#else
# error "Test skipped. This cannot be implemented w/o rvalue references."
#endif

View File

@@ -0,0 +1,69 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at: akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include <string>
#include "boost/core/addressof.hpp"
#include "boost/core/lightweight_test.hpp"
using boost::optional;
std::string global("text");
optional<std::string&> make_optional_string_ref()
{
return optional<std::string&>(global);
}
std::string& return_global()
{
return global;
}
int main()
{
optional<std::string&> opt;
opt = make_optional_string_ref();
BOOST_TEST(bool(opt));
BOOST_TEST(*opt == global);
BOOST_TEST(boost::addressof(*opt) == boost::addressof(global));
{
std::string& str = *make_optional_string_ref();
BOOST_TEST(str == global);
BOOST_TEST(boost::addressof(str) == boost::addressof(global));
}
{
std::string& str = make_optional_string_ref().value();
BOOST_TEST(str == global);
BOOST_TEST(boost::addressof(str) == boost::addressof(global));
}
{
std::string& str = make_optional_string_ref().value_or(global);
BOOST_TEST(str == global);
BOOST_TEST(boost::addressof(str) == boost::addressof(global));
}
{
std::string& str = make_optional_string_ref().value_or_eval(&return_global);
BOOST_TEST(str == global);
BOOST_TEST(boost::addressof(str) == boost::addressof(global));
}
return boost::report_errors();
}

View File

@@ -0,0 +1,499 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at: akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/addressof.hpp"
#include "boost/core/enable_if.hpp"
#include "boost/core/lightweight_test.hpp"
#include "testable_classes.hpp"
using boost::optional;
using boost::none;
struct CountingClass
{
static int count;
static int assign_count;
CountingClass() { ++count; }
CountingClass(const CountingClass&) { ++count; }
CountingClass& operator=(const CountingClass&) { ++assign_count; return *this; }
~CountingClass() { ++count; }
};
int CountingClass::count = 0;
int CountingClass::assign_count = 0;
void test_no_object_creation()
{
BOOST_TEST_EQ(0, CountingClass::count);
BOOST_TEST_EQ(0, CountingClass::assign_count);
{
CountingClass v1, v2;
optional<CountingClass&> oA(v1);
optional<CountingClass&> oB;
optional<CountingClass&> oC = oA;
oB = oA;
*oB = v2;
oC = none;
oC = optional<CountingClass&>(v2);
oB = none;
oA = oB;
}
BOOST_TEST_EQ(4, CountingClass::count);
BOOST_TEST_EQ(1, CountingClass::assign_count);
}
template <typename T>
typename boost::enable_if< has_arrow<T> >::type
test_arrow_const()
{
const typename concrete_type_of<T>::type v(2);
optional<const T&> o(v);
BOOST_TEST(o);
BOOST_TEST_EQ(o->val(), 2);
BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val()));
}
template <typename T>
typename boost::disable_if< has_arrow<T> >::type
test_arrow_const()
{
}
template <typename T>
typename boost::enable_if< has_arrow<T> >::type
test_arrow_noconst_const()
{
typename concrete_type_of<T>::type v(2);
optional<const T&> o(v);
BOOST_TEST(o);
BOOST_TEST_EQ(o->val(), 2);
BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val()));
v.val() = 1;
BOOST_TEST(o);
BOOST_TEST_EQ(o->val(), 1);
BOOST_TEST_EQ(v.val(), 1);
BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val()));
}
template <typename T>
typename boost::disable_if< has_arrow<T> >::type
test_arrow_noconst_const()
{
}
template <typename T>
typename boost::enable_if< has_arrow<T> >::type
test_arrow()
{
typename concrete_type_of<T>::type v(2);
optional<T&> o(v);
BOOST_TEST(o);
BOOST_TEST_EQ(o->val(), 2);
BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val()));
v.val() = 1;
BOOST_TEST(o);
BOOST_TEST_EQ(o->val(), 1);
BOOST_TEST_EQ(v.val(), 1);
BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val()));
o->val() = 3;
BOOST_TEST(o);
BOOST_TEST_EQ(o->val(), 3);
BOOST_TEST_EQ(v.val(), 3);
BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val()));
}
template <typename T>
typename boost::disable_if< has_arrow<T> >::type
test_arrow()
{
}
template <typename T>
void test_not_containing_value_for()
{
optional<T&> o1;
optional<T&> o2 = none;
optional<T&> o3 = o1;
BOOST_TEST(!o1);
BOOST_TEST(!o2);
BOOST_TEST(!o3);
BOOST_TEST(o1 == none);
BOOST_TEST(o2 == none);
BOOST_TEST(o3 == none);
}
template <typename T>
void test_direct_init_for_const()
{
const typename concrete_type_of<T>::type v(2);
optional<const T&> o(v);
BOOST_TEST(o);
BOOST_TEST(o != none);
BOOST_TEST(boost::addressof(*o) == boost::addressof(v));
BOOST_TEST_EQ(val(*o), val(v));
BOOST_TEST_EQ(val(*o), 2);
}
template <typename T>
void test_direct_init_for_noconst_const()
{
typename concrete_type_of<T>::type v(2);
optional<const T&> o(v);
BOOST_TEST(o);
BOOST_TEST(o != none);
BOOST_TEST(boost::addressof(*o) == boost::addressof(v));
BOOST_TEST_EQ(val(*o), val(v));
BOOST_TEST_EQ(val(*o), 2);
val(v) = 9;
BOOST_TEST(boost::addressof(*o) == boost::addressof(v));
BOOST_TEST_EQ(val(*o), val(v));
BOOST_TEST_EQ(val(*o), 9);
BOOST_TEST_EQ(val(v), 9);
}
template <typename T>
void test_direct_init_for()
{
typename concrete_type_of<T>::type v(2);
optional<T&> o(v);
BOOST_TEST(o);
BOOST_TEST(o != none);
BOOST_TEST(boost::addressof(*o) == boost::addressof(v));
BOOST_TEST_EQ(val(*o), val(v));
BOOST_TEST_EQ(val(*o), 2);
val(v) = 9;
BOOST_TEST(boost::addressof(*o) == boost::addressof(v));
BOOST_TEST_EQ(val(*o), val(v));
BOOST_TEST_EQ(val(*o), 9);
BOOST_TEST_EQ(val(v), 9);
val(*o) = 7;
BOOST_TEST(boost::addressof(*o) == boost::addressof(v));
BOOST_TEST_EQ(val(*o), val(v));
BOOST_TEST_EQ(val(*o), 7);
BOOST_TEST_EQ(val(v), 7);
}
template <typename T, typename U>
void test_clearing_the_value()
{
typename concrete_type_of<T>::type v(2);
optional<U&> o1(v), o2(v);
BOOST_TEST(o1);
BOOST_TEST(o1 != none);
BOOST_TEST(o2);
BOOST_TEST(o2 != none);
o1 = none;
BOOST_TEST(!o1);
BOOST_TEST(o1 == none);
BOOST_TEST(o2);
BOOST_TEST(o2 != none);
BOOST_TEST_EQ(val(*o2), 2);
BOOST_TEST(boost::addressof(*o2) == boost::addressof(v));
BOOST_TEST_EQ(val(v), 2);
}
template <typename T, typename U>
void test_equality()
{
typename concrete_type_of<T>::type v1(1), v2(2), v2_(2), v3(3);
optional<U&> o1(v1), o2(v2), o2_(v2_), o3(v3), o3_(v3), oN, oN_;
// o2 and o2_ point to different objects; o3 and o3_ point to the same object
BOOST_TEST(oN == oN);
BOOST_TEST(oN == oN_);
BOOST_TEST(oN_ == oN);
BOOST_TEST(o1 == o1);
BOOST_TEST(o2 == o2);
BOOST_TEST(o2 == o2_);
BOOST_TEST(o2_ == o2);
BOOST_TEST(o3 == o3);
BOOST_TEST(o3 == o3_);
BOOST_TEST(!(oN == o1));
BOOST_TEST(!(o1 == oN));
BOOST_TEST(!(o2 == o1));
BOOST_TEST(!(o2 == oN));
BOOST_TEST(!(oN != oN));
BOOST_TEST(!(oN != oN_));
BOOST_TEST(!(oN_ != oN));
BOOST_TEST(!(o1 != o1));
BOOST_TEST(!(o2 != o2));
BOOST_TEST(!(o2 != o2_));
BOOST_TEST(!(o2_ != o2));
BOOST_TEST(!(o3 != o3));
BOOST_TEST(!(o3 != o3_));
BOOST_TEST( (oN != o1));
BOOST_TEST( (o1 != oN));
BOOST_TEST( (o2 != o1));
BOOST_TEST( (o2 != oN));
}
template <typename T, typename U>
void test_order()
{
typename concrete_type_of<T>::type v1(1), v2(2), v2_(2), v3(3);
optional<U&> o1(v1), o2(v2), o2_(v2_), o3(v3), o3_(v3), oN, oN_;
// o2 and o2_ point to different objects; o3 and o3_ point to the same object
BOOST_TEST(!(oN < oN));
BOOST_TEST(!(oN < oN_));
BOOST_TEST(!(oN_ < oN));
BOOST_TEST(!(o1 < o1));
BOOST_TEST(!(o2 < o2));
BOOST_TEST(!(o2 < o2_));
BOOST_TEST(!(o2_ < o2));
BOOST_TEST(!(o3 < o3));
BOOST_TEST(!(o3 < o3_));
BOOST_TEST( (oN <= oN));
BOOST_TEST( (oN <= oN_));
BOOST_TEST( (oN_ <= oN));
BOOST_TEST( (o1 <= o1));
BOOST_TEST( (o2 <= o2));
BOOST_TEST( (o2 <= o2_));
BOOST_TEST( (o2_ <= o2));
BOOST_TEST( (o3 <= o3));
BOOST_TEST( (o3 <= o3_));
BOOST_TEST(!(oN > oN));
BOOST_TEST(!(oN > oN_));
BOOST_TEST(!(oN_ > oN));
BOOST_TEST(!(o1 > o1));
BOOST_TEST(!(o2 > o2));
BOOST_TEST(!(o2 > o2_));
BOOST_TEST(!(o2_ > o2));
BOOST_TEST(!(o3 > o3));
BOOST_TEST(!(o3 > o3_));
BOOST_TEST( (oN >= oN));
BOOST_TEST( (oN >= oN_));
BOOST_TEST( (oN_ >= oN));
BOOST_TEST( (o1 >= o1));
BOOST_TEST( (o2 >= o2));
BOOST_TEST( (o2 >= o2_));
BOOST_TEST( (o2_ >= o2));
BOOST_TEST( (o3 >= o3));
BOOST_TEST( (o3 >= o3_));
BOOST_TEST( (oN < o1));
BOOST_TEST( (oN_ < o1));
BOOST_TEST( (oN < o2));
BOOST_TEST( (oN_ < o2));
BOOST_TEST( (oN < o2_));
BOOST_TEST( (oN_ < o2_));
BOOST_TEST( (oN < o3));
BOOST_TEST( (oN_ < o3));
BOOST_TEST( (oN < o3_));
BOOST_TEST( (oN_ < o3_));
BOOST_TEST( (o1 < o2));
BOOST_TEST( (o1 < o2_));
BOOST_TEST( (o1 < o3));
BOOST_TEST( (o1 < o3_));
BOOST_TEST( (o2 < o3));
BOOST_TEST( (o2_ < o3));
BOOST_TEST( (o2 < o3_));
BOOST_TEST( (o2_ < o3_));
BOOST_TEST( (oN <= o1));
BOOST_TEST( (oN_ <= o1));
BOOST_TEST( (oN <= o2));
BOOST_TEST( (oN_ <= o2));
BOOST_TEST( (oN <= o2_));
BOOST_TEST( (oN_ <= o2_));
BOOST_TEST( (oN <= o3));
BOOST_TEST( (oN_ <= o3));
BOOST_TEST( (oN <= o3_));
BOOST_TEST( (oN_ <= o3_));
BOOST_TEST( (o1 <= o2));
BOOST_TEST( (o1 <= o2_));
BOOST_TEST( (o1 <= o3));
BOOST_TEST( (o1 <= o3_));
BOOST_TEST( (o2 <= o3));
BOOST_TEST( (o2_ <= o3));
BOOST_TEST( (o2 <= o3_));
BOOST_TEST( (o2_ <= o3_));
BOOST_TEST(!(oN > o1));
BOOST_TEST(!(oN_ > o1));
BOOST_TEST(!(oN > o2));
BOOST_TEST(!(oN_ > o2));
BOOST_TEST(!(oN > o2_));
BOOST_TEST(!(oN_ > o2_));
BOOST_TEST(!(oN > o3));
BOOST_TEST(!(oN_ > o3));
BOOST_TEST(!(oN > o3_));
BOOST_TEST(!(oN_ > o3_));
BOOST_TEST(!(o1 > o2));
BOOST_TEST(!(o1 > o2_));
BOOST_TEST(!(o1 > o3));
BOOST_TEST(!(o1 > o3_));
BOOST_TEST(!(o2 > o3));
BOOST_TEST(!(o2_ > o3));
BOOST_TEST(!(o2 > o3_));
BOOST_TEST(!(o2_ > o3_));
BOOST_TEST(!(oN >= o1));
BOOST_TEST(!(oN_ >= o1));
BOOST_TEST(!(oN >= o2));
BOOST_TEST(!(oN_ >= o2));
BOOST_TEST(!(oN >= o2_));
BOOST_TEST(!(oN_ >= o2_));
BOOST_TEST(!(oN >= o3));
BOOST_TEST(!(oN_ >= o3));
BOOST_TEST(!(oN >= o3_));
BOOST_TEST(!(oN_ >= o3_));
BOOST_TEST(!(o1 >= o2));
BOOST_TEST(!(o1 >= o2_));
BOOST_TEST(!(o1 >= o3));
BOOST_TEST(!(o1 >= o3_));
BOOST_TEST(!(o2 >= o3));
BOOST_TEST(!(o2_ >= o3));
BOOST_TEST(!(o2 >= o3_));
BOOST_TEST(!(o2_ >= o3_));
BOOST_TEST(!(o1 < oN));
BOOST_TEST(!(o1 < oN_));
BOOST_TEST(!(o2 < oN));
BOOST_TEST(!(o2 < oN_));
BOOST_TEST(!(o2_ < oN));
BOOST_TEST(!(o2_ < oN_));
BOOST_TEST(!(o3 < oN));
BOOST_TEST(!(o3 < oN_));
BOOST_TEST(!(o3_ < oN));
BOOST_TEST(!(o3_ < oN_));
BOOST_TEST(!(o2 < oN));
BOOST_TEST(!(o2_ < oN_));
BOOST_TEST(!(o3 < oN));
BOOST_TEST(!(o3_ < oN_));
BOOST_TEST(!(o3 < oN));
BOOST_TEST(!(o3 < oN_));
BOOST_TEST(!(o3_ < oN));
BOOST_TEST(!(o3_ < oN_));
}
template <typename T, typename U>
void test_swap()
{
typename concrete_type_of<T>::type v1(1), v2(2);
optional<U&> o1(v1), o1_(v1), o2(v2), o2_(v2), oN, oN_;
swap(o1, o1);
BOOST_TEST(o1);
BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1));
swap(oN, oN_);
BOOST_TEST(!oN);
BOOST_TEST(!oN_);
swap(o1, oN);
BOOST_TEST(!o1);
BOOST_TEST(oN);
BOOST_TEST(boost::addressof(*oN) == boost::addressof(v1));
swap(oN, o1);
BOOST_TEST(!oN);
BOOST_TEST(o1);
BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1));
swap(o1_, o2_);
BOOST_TEST(o1_);
BOOST_TEST(o2_);
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(v2));
BOOST_TEST(boost::addressof(*o2_) == boost::addressof(v1));
}
template <typename T, typename U>
void test_convertability_of_compatible_reference_types()
{
typename concrete_type_of<T>::type v1(1);
optional<T&> oN, o1(v1);
optional<U&> uN(oN), u1(o1);
BOOST_TEST(!uN);
BOOST_TEST(u1);
BOOST_TEST(boost::addressof(*u1) == boost::addressof(*o1));
uN = o1;
u1 = oN;
BOOST_TEST(!u1);
BOOST_TEST(uN);
BOOST_TEST(boost::addressof(*uN) == boost::addressof(*o1));
}
template <typename T>
void test_optional_ref()
{
test_not_containing_value_for<T>();
test_direct_init_for<T>();
test_clearing_the_value<T, T>();
test_arrow<T>();
test_equality<T, T>();
test_order<T, T>();
test_swap<T, T>();
}
template <typename T>
void test_optional_const_ref()
{
test_not_containing_value_for<const T>();
test_direct_init_for_const<T>();
test_direct_init_for_noconst_const<T>();
test_clearing_the_value<const T, const T>();
test_clearing_the_value<T, const T>();
test_arrow_const<T>();
test_arrow_noconst_const<T>();
test_equality<const T, const T>();
test_equality<T, const T>();
test_order<const T, const T>();
test_order<T, const T>();
test_swap<const T, const T>();
test_swap<T, const T>();
}
int main()
{
test_optional_ref<int>();
test_optional_ref<ScopeGuard>();
test_optional_ref<Abstract>();
test_optional_ref< optional<int> >();
test_optional_const_ref<int>();
test_optional_const_ref<ScopeGuard>();
test_optional_const_ref<Abstract>();
test_optional_const_ref< optional<int> >();
test_convertability_of_compatible_reference_types<int, const int>();
test_convertability_of_compatible_reference_types<Impl, Abstract>();
test_convertability_of_compatible_reference_types<Impl, const Abstract>();
test_convertability_of_compatible_reference_types<const Impl, const Abstract>();
test_convertability_of_compatible_reference_types<optional<int>, const optional<int> >();
return boost::report_errors();
}

View File

@@ -0,0 +1,116 @@
// Copyright (C) 2016 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
using boost::optional;
using boost::none;
struct Value
{
int val;
explicit Value(int v) : val(v) {}
};
int val(int const& i)
{
return i;
}
int val(Value const& v)
{
return v.val;
}
template <typename Tref>
optional<Tref&> make_opt_ref(Tref& v)
{
return optional<Tref&>(v);
}
template <typename Tval, typename Tref>
void test_construct_from_optional_ref()
{
Tref v1 (1), v2 (2);
optional<Tref&> opt_ref0;
optional<Tref&> opt_ref1 (v1);
optional<Tval> opt_val0 (opt_ref0);
optional<Tval> opt_val1 (opt_ref1);
optional<Tval> opt_val2 (make_opt_ref(v2));
BOOST_TEST (!opt_val0);
BOOST_TEST (opt_val1);
BOOST_TEST (opt_val2);
BOOST_TEST_EQ (1, val(*opt_val1));
BOOST_TEST_EQ (2, val(*opt_val2));
BOOST_TEST (boost::addressof(*opt_val1) != boost::addressof(v1));
BOOST_TEST (boost::addressof(*opt_val2) != boost::addressof(v2));
}
template <typename Tval, typename Tref>
void test_assign_from_optional_ref()
{
Tref v1 (1), v2 (2);
optional<Tref&> opt_ref0;
optional<Tref&> opt_ref1 (v1);
optional<Tval> opt_val0;
optional<Tval> opt_val1;
optional<Tval> opt_val2;
opt_val0 = opt_ref0;
opt_val1 = opt_ref1;
opt_val2 = make_opt_ref(v2);
BOOST_TEST (!opt_val0);
BOOST_TEST (opt_val1);
BOOST_TEST (opt_val2);
BOOST_TEST_EQ (1, val(*opt_val1));
BOOST_TEST_EQ (2, val(*opt_val2));
BOOST_TEST (boost::addressof(*opt_val1) != boost::addressof(v1));
BOOST_TEST (boost::addressof(*opt_val2) != boost::addressof(v2));
}
int main()
{
test_construct_from_optional_ref<int, int>();
test_construct_from_optional_ref<int, int const>();
test_construct_from_optional_ref<int const, int const>();
test_construct_from_optional_ref<int const, int>();
test_construct_from_optional_ref<Value, Value>();
test_construct_from_optional_ref<Value, Value const>();
test_construct_from_optional_ref<Value const, Value const>();
test_construct_from_optional_ref<Value const, Value>();
test_assign_from_optional_ref<int, int>();
test_assign_from_optional_ref<int, int const>();
test_assign_from_optional_ref<Value, Value>();
test_assign_from_optional_ref<Value, Value const>();
return boost::report_errors();
}

View File

@@ -0,0 +1,49 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
using boost::optional;
#if (!defined BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT)
struct X {};
struct Y {};
struct Resource
{
explicit Resource(const X&) {}
};
BOOST_STATIC_ASSERT(( boost::is_constructible<Resource, const X&>::value ));
BOOST_STATIC_ASSERT(( !boost::is_constructible<Resource, const Y&>::value ));
BOOST_STATIC_ASSERT(( boost::is_constructible<optional<Resource>, const X&>::value ));
BOOST_STATIC_ASSERT(( !boost::is_constructible<optional<Resource>, const Y&>::value ));
#ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS
BOOST_STATIC_ASSERT(( boost::is_constructible< optional< optional<int> >, optional<int> >::value ));
BOOST_STATIC_ASSERT(( !boost::is_constructible< optional<int>, optional< optional<int> > >::value ));
BOOST_STATIC_ASSERT(( boost::is_constructible< optional< optional<int> >, const optional<int>& >::value ));
BOOST_STATIC_ASSERT(( !boost::is_constructible< optional<int>, const optional< optional<int> >& >::value ));
BOOST_STATIC_ASSERT(( boost::is_constructible<optional<Resource>, const optional<X>&>::value ));
BOOST_STATIC_ASSERT(( !boost::is_constructible<optional<Resource>, const optional<Y>&>::value ));
#endif
#endif
int main() { }

View File

@@ -0,0 +1,146 @@
// Copyright (C) 2017 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
#include "boost/core/lightweight_test_trait.hpp"
#include "boost/type_traits/is_base_of.hpp"
#include "boost/optional/detail/experimental_traits.hpp"
#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
struct PrivDefault
{
private: PrivDefault() {}
};
struct CustDefault
{
CustDefault() {}
};
struct CustomizedTrivial
{
CustomizedTrivial() {}
};
struct DeletedDefault
{
BOOST_DELETED_FUNCTION(DeletedDefault())
};
namespace boost { namespace optional_config {
template <> struct optional_uses_direct_storage_for<CustomizedTrivial> : boost::true_type {};
}}
struct CustDtor
{
~CustDtor() {}
};
struct NoDefault
{
explicit NoDefault(int) {}
};
struct Empty {};
template <typename T, typename U>
struct Aggregate { T t; U u; };
struct CustAssign
{
CustAssign& operator=(CustAssign const&) { return *this; }
};
struct CustMove
{
CustMove(CustMove &&) {}
};
void test_type_traits()
{
// this only tests if type traits are implemented correctly
BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for<int> ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for<double> ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for<CustomizedTrivial> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<PrivDefault> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<NoDefault> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<CustDefault> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<Aggregate<int, CustDefault> > ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<CustDtor> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<CustAssign> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<CustMove> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<Aggregate<int, CustMove> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<int> ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<double> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<Empty> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<Aggregate<int, double> > ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<Aggregate<Aggregate<Empty, int>, double> > ));
#ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<Empty> ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<Aggregate<int, double> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<Aggregate<Aggregate<Empty, int>, double> > ));
#endif
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<DeletedDefault> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for<Aggregate<int, DeletedDefault> > ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable<CustDtor> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable<CustAssign> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable<CustMove> ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable<Aggregate<int, CustMove> > ));
}
void test_trivial_copyability()
{
BOOST_TEST_TRAIT_TRUE((boost::is_base_of<boost::optional_detail::tc_optional_base<int>, boost::optional<int> > ));
BOOST_TEST_TRAIT_TRUE((boost::is_base_of<boost::optional_detail::tc_optional_base<double>, boost::optional<double> > ));
BOOST_TEST_TRAIT_TRUE((boost::is_base_of<boost::optional_detail::tc_optional_base<CustomizedTrivial>, boost::optional<CustomizedTrivial> > ));
BOOST_TEST_TRAIT_FALSE((boost::is_base_of<boost::optional_detail::tc_optional_base<DeletedDefault>, boost::optional<DeletedDefault> > ));
#ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<int> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<double> > ));
BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<CustomizedTrivial> > ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<DeletedDefault> > ));
#endif
BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<Empty> > ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<Aggregate<int, double> > > ));
BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable<boost::optional<Aggregate<Aggregate<Empty, int>, double> > > ));
}
#endif
int main()
{
#ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
test_type_traits();
test_trivial_copyability();
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,366 @@
// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
// Revisions:
// 12 May 2008 (added more swap tests)
//
#include "boost/optional/optional.hpp"
#include "boost/utility/in_place_factory.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
#if __cplusplus < 201103L
#include <algorithm>
#else
#include <utility>
#endif
using boost::optional;
using boost::none;
#define ARG(T) (static_cast< T const* >(0))
namespace optional_swap_test
{
class default_ctor_exception : public std::exception {} ;
class copy_ctor_exception : public std::exception {} ;
class assignment_exception : public std::exception {} ;
//
// Base class for swap test classes. Its assignment should not be called, when swapping
// optional<T> objects. (The default std::swap would do so.)
//
class base_class_with_forbidden_assignment
{
public:
base_class_with_forbidden_assignment & operator=(const base_class_with_forbidden_assignment &)
{
BOOST_TEST(!"The assignment should not be used while swapping!");
throw assignment_exception();
}
virtual ~base_class_with_forbidden_assignment() {}
};
//
// Class without default constructor
//
class class_without_default_ctor : public base_class_with_forbidden_assignment
{
public:
char data;
explicit class_without_default_ctor(char arg) : data(arg) {}
};
//
// Class whose default constructor should not be used by optional::swap!
//
class class_whose_default_ctor_should_not_be_used : public base_class_with_forbidden_assignment
{
public:
char data;
explicit class_whose_default_ctor_should_not_be_used(char arg) : data(arg) {}
class_whose_default_ctor_should_not_be_used()
{
BOOST_TEST(!"This default constructor should not be used while swapping!");
throw default_ctor_exception();
}
};
//
// Class whose default constructor should be used by optional::swap.
// Its copy constructor should be avoided!
//
class class_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment
{
public:
char data;
explicit class_whose_default_ctor_should_be_used(char arg) : data(arg) { }
class_whose_default_ctor_should_be_used() : data('\0') { }
class_whose_default_ctor_should_be_used(const class_whose_default_ctor_should_be_used &)
{
BOOST_TEST(!"This copy constructor should not be used while swapping!");
throw copy_ctor_exception();
}
};
//
// Class template whose default constructor should be used by optional::swap.
// Its copy constructor should be avoided!
//
template <class T>
class template_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment
{
public:
T data;
explicit template_whose_default_ctor_should_be_used(T arg) : data(arg) { }
template_whose_default_ctor_should_be_used() : data('\0') { }
template_whose_default_ctor_should_be_used(const template_whose_default_ctor_should_be_used &)
{
BOOST_TEST(!"This copy constructor should not be used while swapping!");
throw copy_ctor_exception();
}
};
//
// Class whose explicit constructor should be used by optional::swap.
// Its other constructors should be avoided!
//
class class_whose_explicit_ctor_should_be_used : public base_class_with_forbidden_assignment
{
public:
char data;
explicit class_whose_explicit_ctor_should_be_used(char arg) : data(arg) { }
class_whose_explicit_ctor_should_be_used()
{
BOOST_TEST(!"This default constructor should not be used while swapping!");
throw default_ctor_exception();
}
class_whose_explicit_ctor_should_be_used(const class_whose_explicit_ctor_should_be_used &)
{
BOOST_TEST(!"This copy constructor should not be used while swapping!");
throw copy_ctor_exception();
}
};
void swap(class_whose_default_ctor_should_not_be_used & lhs, class_whose_default_ctor_should_not_be_used & rhs)
{
std::swap(lhs.data, rhs.data);
}
void swap(class_whose_default_ctor_should_be_used & lhs, class_whose_default_ctor_should_be_used & rhs)
{
std::swap(lhs.data, rhs.data);
}
void swap(class_without_default_ctor & lhs, class_without_default_ctor & rhs)
{
std::swap(lhs.data, rhs.data);
}
void swap(class_whose_explicit_ctor_should_be_used & lhs, class_whose_explicit_ctor_should_be_used & rhs)
{
std::swap(lhs.data, rhs.data);
}
template <class T>
void swap(template_whose_default_ctor_should_be_used<T> & lhs, template_whose_default_ctor_should_be_used<T> & rhs)
{
std::swap(lhs.data, rhs.data);
}
//
// optional<T>::swap should be customized when neither the copy constructor
// nor the default constructor of T are supposed to be used when swapping, e.g.,
// for the following type T = class_whose_explicit_ctor_should_be_used.
//
void swap(boost::optional<class_whose_explicit_ctor_should_be_used> & x, boost::optional<class_whose_explicit_ctor_should_be_used> & y)
{
bool hasX(x);
bool hasY(y);
if ( !hasX && !hasY )
return;
if( !hasX )
x = boost::in_place('\0');
else if ( !hasY )
y = boost::in_place('\0');
optional_swap_test::swap(*x,*y);
if( !hasX )
y = boost::none ;
else if( !hasY )
x = boost::none ;
}
} // End of namespace optional_swap_test.
namespace boost {
//
// Compile time tweaking on whether or not swap should use the default constructor:
//
template <> struct optional_swap_should_use_default_constructor<
optional_swap_test::class_whose_default_ctor_should_be_used> : true_type {} ;
template <> struct optional_swap_should_use_default_constructor<
optional_swap_test::class_whose_default_ctor_should_not_be_used> : false_type {} ;
template <class T> struct optional_swap_should_use_default_constructor<
optional_swap_test::template_whose_default_ctor_should_be_used<T> > : true_type {} ;
//
// Specialization of boost::swap:
//
template <>
void swap(optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & x, optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & y)
{
optional_swap_test::swap(x, y);
}
} // namespace boost
namespace std {
//
// Specializations of std::swap:
//
template <>
void swap(optional_swap_test::class_whose_default_ctor_should_be_used & x, optional_swap_test::class_whose_default_ctor_should_be_used & y)
{
optional_swap_test::swap(x, y);
}
template <>
void swap(optional_swap_test::class_whose_default_ctor_should_not_be_used & x, optional_swap_test::class_whose_default_ctor_should_not_be_used & y)
{
optional_swap_test::swap(x, y);
}
template <>
void swap(optional_swap_test::class_without_default_ctor & x, optional_swap_test::class_without_default_ctor & y)
{
optional_swap_test::swap(x, y);
}
template <>
void swap(optional_swap_test::class_whose_explicit_ctor_should_be_used & x, optional_swap_test::class_whose_explicit_ctor_should_be_used & y)
{
optional_swap_test::swap(x, y);
}
} // namespace std
//
// Tests whether the swap function works properly for optional<T>.
// Assumes that T has one data member, of type char.
// Returns true iff the test is passed.
//
template <class T>
void test_swap_function( T const* )
{
try
{
optional<T> obj1;
optional<T> obj2('a');
// Self-swap should not have any effect.
swap(obj1, obj1);
swap(obj2, obj2);
BOOST_TEST(!obj1);
BOOST_TEST(!!obj2 && obj2->data == 'a');
// Call non-member swap.
swap(obj1, obj2);
// Test if obj1 and obj2 are really swapped.
BOOST_TEST(!!obj1 && obj1->data == 'a');
BOOST_TEST(!obj2);
// Call non-member swap one more time.
swap(obj1, obj2);
// Test if obj1 and obj2 are swapped back.
BOOST_TEST(!obj1);
BOOST_TEST(!!obj2 && obj2->data == 'a');
}
catch(const std::exception &)
{
// The swap function should not throw, for our test cases.
BOOST_TEST(!"throw in swap");
}
}
//
// Tests whether the optional<T>::swap member function works properly.
// Assumes that T has one data member, of type char.
// Returns true iff the test is passed.
//
template <class T>
void test_swap_member_function( T const* )
{
try
{
optional<T> obj1;
optional<T> obj2('a');
// Self-swap should not have any effect.
obj1.swap(obj1);
obj2.swap(obj2);
BOOST_TEST(!obj1);
BOOST_TEST(!!obj2 && obj2->data == 'a');
// Call member swap.
obj1.swap(obj2);
// Test if obj1 and obj2 are really swapped.
BOOST_TEST(!!obj1 && obj1->data == 'a');
BOOST_TEST(!obj2);
// Call member swap one more time.
obj1.swap(obj2);
// Test if obj1 and obj2 are swapped back.
BOOST_TEST(!obj1);
BOOST_TEST(!!obj2 && obj2->data == 'a');
}
catch(const std::exception &)
{
BOOST_TEST(!"throw in swap");
}
}
//
// Tests compile time tweaking of swap, by means of
// optional_swap_should_use_default_constructor.
//
void test_swap_tweaking()
{
( test_swap_function( ARG(optional_swap_test::class_without_default_ctor) ) );
( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
( test_swap_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) );
( test_swap_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) );
( test_swap_member_function( ARG(optional_swap_test::class_without_default_ctor) ) );
( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
( test_swap_member_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) );
( test_swap_member_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) );
}
int main()
{
test_swap_tweaking();
return boost::report_errors();
}

View File

@@ -0,0 +1,87 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
int main()
{
}
#else
#include <utility>
struct NotDefaultConstructible
{
NotDefaultConstructible() = delete;
};
void test_tc_base()
{
boost::optional<NotDefaultConstructible> o;
BOOST_TEST(boost::none == o);
}
struct S
{
};
template<class T>
struct W
{
T& t_;
template<class... Args>
W(Args&&... args)
: t_(std::forward<Args>(args)...)
{
}
};
void test_value_init()
{
#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
{
S s;
W<S> w{s};
}
#endif
{
S s;
W<S> w(s);
}
}
void test_optoinal_reference_wrapper()
{
boost::optional<W<S&> > o;
BOOST_TEST(boost::none == o);
}
int main()
{
test_tc_base();
test_value_init();
test_optoinal_reference_wrapper();
return boost::report_errors();
}
#endif

View File

@@ -0,0 +1,74 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
#include "boost/none.hpp"
#include "boost/tuple/tuple.hpp"
struct counting_oracle
{
int val;
counting_oracle() : val() { ++default_ctor_count; }
counting_oracle(int v) : val(v) { ++val_ctor_count; }
counting_oracle(const counting_oracle& rhs) : val(rhs.val) { ++copy_ctor_count; }
counting_oracle& operator=(const counting_oracle& rhs) { val = rhs.val; ++copy_assign_count; return *this; }
~counting_oracle() { ++dtor_count; }
static int dtor_count;
static int default_ctor_count;
static int val_ctor_count;
static int copy_ctor_count;
static int copy_assign_count;
static int equals_count;
friend bool operator==(const counting_oracle& lhs, const counting_oracle& rhs) { ++equals_count; return lhs.val == rhs.val; }
static void clear_count()
{
dtor_count = default_ctor_count = val_ctor_count = copy_ctor_count = copy_assign_count = equals_count = 0;
}
};
int counting_oracle::dtor_count = 0;
int counting_oracle::default_ctor_count = 0;
int counting_oracle::val_ctor_count = 0;
int counting_oracle::copy_ctor_count = 0;
int counting_oracle::copy_assign_count = 0;
int counting_oracle::equals_count = 0;
// Test boost::tie() interoperability.
int main()
{
const std::pair<counting_oracle, counting_oracle> pair(1, 2);
counting_oracle::clear_count();
boost::optional<counting_oracle> o1, o2;
boost::tie(o1, o2) = pair;
BOOST_TEST(o1);
BOOST_TEST(o2);
BOOST_TEST(*o1 == counting_oracle(1));
BOOST_TEST(*o2 == counting_oracle(2));
BOOST_TEST_EQ(2, counting_oracle::copy_ctor_count);
BOOST_TEST_EQ(0, counting_oracle::copy_assign_count);
BOOST_TEST_EQ(0, counting_oracle::default_ctor_count);
return boost::report_errors();
}

View File

@@ -0,0 +1,222 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/optional/optional.hpp"
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/core/ignore_unused.hpp"
#include "boost/core/lightweight_test.hpp"
using boost::optional;
struct IntWrapper
{
int _i;
IntWrapper(int i) : _i(i) {}
bool operator==(IntWrapper const& rhs) const { return _i == rhs._i; }
};
template <typename T>
void test_function_value_or_for()
{
optional<T> oM0;
const optional<T> oC0;
optional<T> oM1(1);
const optional<T> oC2(2);
BOOST_TEST(oM0.value_or(5) == 5);
BOOST_TEST(oC0.value_or(5) == 5);
BOOST_TEST(oM1.value_or(5) == 1);
BOOST_TEST(oC2.value_or(5) == 2);
}
template <typename T>
void test_function_value_for()
{
optional<T> o0;
optional<T> o1(1);
const optional<T> oC(2);
try
{
T& v = o1.value();
BOOST_TEST(v == 1);
}
catch(...)
{
BOOST_TEST(false);
}
try
{
T const& v = oC.value();
BOOST_TEST(v == 2);
}
catch(...)
{
BOOST_TEST(false);
}
BOOST_TEST_THROWS(o0.value(), boost::bad_optional_access);
}
void test_function_value()
{
test_function_value_for<int>();
test_function_value_for<double>();
test_function_value_for<IntWrapper>();
}
struct FatToIntConverter
{
static int conversions;
int _val;
FatToIntConverter(int val) : _val(val) {}
operator int() const { conversions += 1; return _val; }
};
int FatToIntConverter::conversions = 0;
void test_function_value_or()
{
test_function_value_or_for<int>();
test_function_value_or_for<double>();
test_function_value_or_for<IntWrapper>();
optional<int> oi(1);
BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 1);
BOOST_TEST(FatToIntConverter::conversions == 0);
oi = boost::none;
BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 2);
BOOST_TEST(FatToIntConverter::conversions == 1);
}
struct FunM
{
int operator()() { return 5; }
};
struct FunC
{
int operator()() const { return 6; }
};
int funP ()
{
return 7;
}
int throw_()
{
throw int();
}
void test_function_value_or_eval()
{
optional<int> o1 = 1;
optional<int> oN;
FunM funM;
FunC funC;
BOOST_TEST_EQ(o1.value_or_eval(funM), 1);
BOOST_TEST_EQ(oN.value_or_eval(funM), 5);
BOOST_TEST_EQ(o1.value_or_eval(FunM()), 1);
BOOST_TEST_EQ(oN.value_or_eval(FunM()), 5);
BOOST_TEST_EQ(o1.value_or_eval(funC), 1);
BOOST_TEST_EQ(oN.value_or_eval(funC), 6);
BOOST_TEST_EQ(o1.value_or_eval(FunC()), 1);
BOOST_TEST_EQ(oN.value_or_eval(FunC()), 6);
BOOST_TEST_EQ(o1.value_or_eval(funP), 1);
BOOST_TEST_EQ(oN.value_or_eval(funP), 7);
#ifndef BOOST_NO_CXX11_LAMBDAS
BOOST_TEST_EQ(o1.value_or_eval([](){return 8;}), 1);
BOOST_TEST_EQ(oN.value_or_eval([](){return 8;}), 8);
#endif
try
{
BOOST_TEST_EQ(o1.value_or_eval(throw_), 1);
}
catch(...)
{
BOOST_TEST(false);
}
BOOST_TEST_THROWS(oN.value_or_eval(throw_), int);
}
const optional<std::string> makeConstOptVal()
{
return std::string("something");
}
void test_const_move()
{
std::string s5 = *makeConstOptVal();
std::string s6 = makeConstOptVal().value();
boost::ignore_unused(s5);
boost::ignore_unused(s6);
}
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
struct MoveOnly
{
explicit MoveOnly(int){}
MoveOnly(MoveOnly &&){}
void operator=(MoveOnly &&);
private:
MoveOnly(MoveOnly const&);
void operator=(MoveOnly const&);
};
optional<MoveOnly> makeMoveOnly()
{
return MoveOnly(1);
}
MoveOnly moveOnlyDefault()
{
return MoveOnly(1);
}
// compile-time test
void test_move_only_getters()
{
MoveOnly m1 = *makeMoveOnly();
MoveOnly m2 = makeMoveOnly().value();
MoveOnly m3 = makeMoveOnly().value_or(MoveOnly(1));
MoveOnly m4 = makeMoveOnly().value_or_eval(moveOnlyDefault);
boost::ignore_unused(m1);
boost::ignore_unused(m2);
boost::ignore_unused(m3);
boost::ignore_unused(m4);
}
#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
int main()
{
test_function_value();
test_function_value_or();
test_function_value_or_eval();
test_const_move();
return boost::report_errors();
}

View File

@@ -0,0 +1,50 @@
// Copyright (C) 2015 - 2018 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/core/lightweight_test.hpp"
#include "boost/optional/detail/optional_config.hpp"
#include "boost/predef.h"
#include <string>
int main()
{
#if defined(__GNUC__)
std::string emptys;
#ifdef BOOST_INTEL_CXX_VERSION
BOOST_TEST_EQ(emptys, "HAS INTEL INSIDE");
#else
BOOST_TEST_EQ(emptys, "NO INTEL INSIDE");
#endif
#if !defined BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_TEST_EQ(emptys, "HAS RVALUE REFS");
#else
BOOST_TEST_EQ(emptys, "NO RVALUE REFS");
#endif
int empty = -1;
BOOST_TEST_EQ(empty, __GNUC__);
BOOST_TEST_EQ(empty, __GNUC_MINOR__);
BOOST_TEST_EQ(empty, __GNUC_PATCHLEVEL__);
BOOST_TEST_EQ(empty, __cplusplus);
#endif
BOOST_TEST_EQ(empty, BOOST_COMP_GNUC);
BOOST_TEST_EQ(empty, BOOST_COMP_CLANG);
BOOST_TEST_EQ(empty, BOOST_LANG_STDCPP);
BOOST_TEST_EQ(empty, BOOST_LIB_C_GNU);
BOOST_TEST_EQ(empty, BOOST_LIB_STD_GNU);
BOOST_TEST_EQ(empty, BOOST_LIB_STD_CXX);
return boost::report_errors();
}

View File

@@ -0,0 +1,37 @@
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/core/ignore_unused.hpp"
#include "boost/core/lightweight_test.hpp"
#include "boost/optional/detail/optional_config.hpp"
#if (defined BOOST_NO_CXX11_RVALUE_REFERENCES) || (!defined BOOST_OPTIONAL_CONFIG_NO_LEGAL_CONVERT_FROM_REF)
# error "failed as requested"
#else
struct S {};
struct Binder
{
S& ref_;
template <typename R> Binder (R&&r) : ref_(r) {}
};
int main()
{
S s ;
Binder b = s;
boost::ignore_unused(b);
}
#endif

View File

@@ -0,0 +1,38 @@
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/core/ignore_unused.hpp"
#include "boost/core/lightweight_test.hpp"
#include "boost/optional/detail/optional_config.hpp"
#if (defined BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined BOOST_OPTIONAL_CONFIG_NO_LEGAL_CONVERT_FROM_REF)
int main() { return 0; }
#else
struct S {};
struct Binder
{
S& ref_;
template <typename R> Binder (R&&r) : ref_(r) {}
};
int main()
{
S s ;
Binder b = s;
boost::ignore_unused(b);
return 0;
}
#endif

View File

@@ -0,0 +1,42 @@
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/core/lightweight_test.hpp"
#include "boost/optional/detail/optional_config.hpp"
#ifndef BOOST_OPTIONAL_CONFIG_NO_PROPER_ASSIGN_FROM_CONST_INT
int main()
{
BOOST_ERROR("failed as requested");
return boost::report_errors();
}
#else
const int global_i = 0;
struct Binder
{
void operator=(const int& i)
{
BOOST_TEST(&i == &global_i);
}
};
int main()
{
Binder s;
s = global_i;
return boost::report_errors();
}
#endif

View File

@@ -0,0 +1,41 @@
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/core/lightweight_test.hpp"
#include "boost/optional/detail/optional_config.hpp"
#ifndef BOOST_OPTIONAL_CONFIG_NO_PROPER_ASSIGN_FROM_CONST_INT
const int global_i = 0;
struct Binder
{
void operator=(const int& i)
{
BOOST_TEST(&i == &global_i);
}
};
int main()
{
Binder s;
s = global_i;
return boost::report_errors();
}
#else
int main()
{
return boost::report_errors();
}
#endif

View File

@@ -0,0 +1,43 @@
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/core/ignore_unused.hpp"
#include "boost/core/lightweight_test.hpp"
#include "boost/optional/detail/optional_config.hpp"
#ifndef BOOST_OPTIONAL_CONFIG_NO_PROPER_CONVERT_FROM_CONST_INT
int main()
{
BOOST_ERROR("failed as requested");
return boost::report_errors();
}
#else
const int global_i = 0;
struct Binder
{
Binder(const int& i)
{
BOOST_TEST(&i == &global_i);
}
};
int main()
{
Binder b = global_i;
boost::ignore_unused(b);
return boost::report_errors();
}
#endif

View File

@@ -0,0 +1,42 @@
// Copyright (C) 2015 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#include "boost/core/ignore_unused.hpp"
#include "boost/core/lightweight_test.hpp"
#include "boost/optional/detail/optional_config.hpp"
#ifndef BOOST_OPTIONAL_CONFIG_NO_PROPER_CONVERT_FROM_CONST_INT
const int global_i = 0;
struct Binder
{
Binder(const int& i)
{
BOOST_TEST(&i == &global_i);
}
};
int main()
{
Binder b = global_i;
boost::ignore_unused(b);
return boost::report_errors();
}
#else
int main()
{
return boost::report_errors();
}
#endif

View File

@@ -0,0 +1,103 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is 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)
//
// See http://www.boost.org/libs/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
#ifndef BOOST_OPTIONAL_TEST_TESTABKE_CLASSES_AK_07JAN2015_HPP
#define BOOST_OPTIONAL_TEST_TESTABKE_CLASSES_AK_07JAN2015_HPP
#include "boost/optional/optional.hpp"
struct ScopeGuard // no copy/move ctor/assign
{
int val_;
explicit ScopeGuard(int v) : val_(v) {}
int& val() { return val_; }
const int& val() const { return val_; }
private:
ScopeGuard(ScopeGuard const&);
void operator=(ScopeGuard const&);
};
struct Abstract
{
virtual int& val() = 0;
virtual const int& val() const = 0;
virtual ~Abstract() {}
Abstract(){}
private:
Abstract(Abstract const&);
void operator=(Abstract const&);
};
struct Impl : Abstract
{
int val_;
Impl(int v) : val_(v) {}
int& val() { return val_; }
const int& val() const { return val_; }
};
template <typename T>
struct concrete_type_of
{
typedef T type;
};
template <>
struct concrete_type_of<Abstract>
{
typedef Impl type;
};
template <>
struct concrete_type_of<const Abstract>
{
typedef const Impl type;
};
template <typename T>
struct has_arrow
{
static const bool value = true;
};
template <>
struct has_arrow<int>
{
static const bool value = false;
};
template <>
struct has_arrow< boost::optional<int> >
{
static const bool value = false;
};
int& val(int& i) { return i; }
int& val(Abstract& a) { return a.val(); }
int& val(Impl& a) { return a.val(); }
int& val(ScopeGuard& g) { return g.val(); }
template <typename T> int& val(T& o) { return *o; }
const int& val(const int& i) { return i; }
const int& val(const Abstract& a) { return a.val(); }
const int& val(const Impl& a) { return a.val(); }
const int& val(const ScopeGuard& g) { return g.val(); }
template <typename T> const int& val(const T& o) { return *o; }
bool operator==(const Abstract& l, const Abstract& r) { return l.val() == r.val(); }
bool operator==(const ScopeGuard& l, const ScopeGuard& r) { return l.val() == r.val(); }
bool operator<(const Abstract& l, const Abstract& r) { return l.val() < r.val(); }
bool operator<(const ScopeGuard& l, const ScopeGuard& r) { return l.val() < r.val(); }
#endif //BOOST_OPTIONAL_TEST_TESTABKE_CLASSES_AK_07JAN2015_HPP