diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/utility/test | |
parent | Initial commit. (diff) | |
download | ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/utility/test')
28 files changed, 6189 insertions, 0 deletions
diff --git a/src/boost/libs/utility/test/Jamfile.v2 b/src/boost/libs/utility/test/Jamfile.v2 new file mode 100644 index 00000000..d0277ef3 --- /dev/null +++ b/src/boost/libs/utility/test/Jamfile.v2 @@ -0,0 +1,46 @@ +# Copyright David Abrahams 2003. + +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +# For more information, see http://www.boost.org/ + +# bring in rules for testing +import testing ; + +run base_from_member_test.cpp ; +run base_from_member_ref_test.cpp ; + +run binary_test.cpp ; + +run call_traits_test.cpp : -u ; + +run compressed_pair_test.cpp ; +run compressed_pair_final_test.cpp ; + +run iterators_test.cpp ; + +run operators_test.cpp ; + +compile result_of_test.cpp ; + +# compile-fail string_ref_from_rvalue.cpp ; +run string_ref_test1.cpp ; +run string_ref_test2.cpp ; +run string_ref_test_io.cpp ; +# compile-fail string_view_from_rvalue.cpp ; +compile string_view_constexpr_test1.cpp ; +run string_view_test1.cpp ; +run string_view_test2.cpp ; +run string_view_test_io.cpp ; + +run value_init_test.cpp ; +run value_init_workaround_test.cpp ; +run initialized_test.cpp ; +compile-fail value_init_test_fail1.cpp ; +compile-fail value_init_test_fail2.cpp ; +compile-fail value_init_test_fail3.cpp ; +compile-fail initialized_test_fail1.cpp ; +compile-fail initialized_test_fail2.cpp ; + +run ostream_string_test.cpp ; diff --git a/src/boost/libs/utility/test/base_from_member_ref_test.cpp b/src/boost/libs/utility/test/base_from_member_ref_test.cpp new file mode 100644 index 00000000..52f9b870 --- /dev/null +++ b/src/boost/libs/utility/test/base_from_member_ref_test.cpp @@ -0,0 +1,29 @@ +// +// Test that a base_from_member<T&> can be properly constructed +// +// Copyright 2014 Agustin Berge +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include <boost/utility/base_from_member.hpp> + +#include <boost/core/lightweight_test.hpp> + +struct foo : boost::base_from_member<int&> +{ + explicit foo(int& ref) : boost::base_from_member<int&>(ref) + { + BOOST_TEST(&member == &ref); + } +}; + +int main() +{ + int i = 0; + foo f(i); + + return boost::report_errors(); +} diff --git a/src/boost/libs/utility/test/base_from_member_test.cpp b/src/boost/libs/utility/test/base_from_member_test.cpp new file mode 100644 index 00000000..685c6387 --- /dev/null +++ b/src/boost/libs/utility/test/base_from_member_test.cpp @@ -0,0 +1,593 @@ +// Boost test program for base-from-member class templates -----------------// + +// Copyright 2001, 2003 Daryle Walker. Use, modification, and distribution are +// subject to the Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.) + +// See <http://www.boost.org/libs/utility/> for the library's home page. + +// Revision History +// 14 Jun 2003 Adjusted code for Boost.Test changes (Daryle Walker) +// 29 Aug 2001 Initial Version (Daryle Walker) + +#include <boost/core/lightweight_test.hpp> + +#include <boost/config.hpp> // for BOOST_NO_MEMBER_TEMPLATES +#include <boost/noncopyable.hpp> // for boost::noncopyable + +#include <boost/utility/base_from_member.hpp> // for boost::base_from_member + +#include <functional> // for std::less +#include <iostream> // for std::cout (std::ostream, std::endl indirectly) +#include <set> // for std::set +#include <typeinfo> // for std::type_info +#include <utility> // for std::pair, std::make_pair +#include <vector> // for std::vector + + +// Control if extra information is printed +#ifndef CONTROL_EXTRA_PRINTING +#define CONTROL_EXTRA_PRINTING 1 +#endif + + +// A (sub)object can be identified by its memory location and its type. +// Both are needed since an object can start at the same place as its +// first base class subobject and/or contained subobject. +typedef std::pair< void *, std::type_info const * > object_id; + +// Object IDs need to be printed +std::ostream & operator <<( std::ostream &os, object_id const &oi ); + +// A way to generate an object ID +template < typename T > + object_id identify( T &obj ); + +// A custom comparison type is needed +struct object_id_compare +{ + bool operator ()( object_id const &a, object_id const &b ) const; + +}; // object_id_compare + +// A singleton of this type coordinates the acknowledgements +// of objects being created and used. +class object_registrar + : private boost::noncopyable +{ +public: + + #ifndef BOOST_NO_MEMBER_TEMPLATES + template < typename T > + void register_object( T &obj ) + { this->register_object_imp( identify(obj) ); } + template < typename T, typename U > + void register_use( T &owner, U &owned ) + { this->register_use_imp( identify(owner), identify(owned) ); } + template < typename T, typename U > + void unregister_use( T &owner, U &owned ) + { this->unregister_use_imp( identify(owner), identify(owned) ); } + template < typename T > + void unregister_object( T &obj ) + { this->unregister_object_imp( identify(obj) ); } + #endif + + void register_object_imp( object_id obj ); + void register_use_imp( object_id owner, object_id owned ); + void unregister_use_imp( object_id owner, object_id owned ); + void unregister_object_imp( object_id obj ); + + typedef std::set<object_id, object_id_compare> set_type; + + typedef std::vector<object_id> error_record_type; + typedef std::vector< std::pair<object_id, object_id> > error_pair_type; + + set_type db_; + + error_pair_type defrauders_in_, defrauders_out_; + error_record_type overeager_, overkilled_; + +}; // object_registrar + +// A sample type to be used by containing types +class base_or_member +{ +public: + explicit base_or_member( int x = 1, double y = -0.25 ); + ~base_or_member(); + +}; // base_or_member + +// A sample type that uses base_or_member, used +// as a base for the main demonstration classes +class base_class +{ +public: + explicit base_class( base_or_member &x, base_or_member *y = 0, + base_or_member *z = 0 ); + + ~base_class(); + +private: + base_or_member *x_, *y_, *z_; + +}; // base_class + +// This bad class demonstrates the direct method of a base class needing +// to be initialized by a member. This is improper since the member +// isn't initialized until after the base class. +class bad_class + : public base_class +{ +public: + bad_class(); + ~bad_class(); + +private: + base_or_member x_; + +}; // bad_class + +// The first good class demonstrates the correct way to initialize a +// base class with a member. The member is changed to another base +// class, one that is initialized before the base that needs it. +class good_class_1 + : private boost::base_from_member<base_or_member> + , public base_class +{ + typedef boost::base_from_member<base_or_member> pbase_type; + typedef base_class base_type; + +public: + good_class_1(); + ~good_class_1(); + +}; // good_class_1 + +// The second good class also demonstrates the correct way to initialize +// base classes with other subobjects. This class uses the other helpers +// in the library, and shows the technique of using two base subobjects +// of the "same" type. +class good_class_2 + : private boost::base_from_member<base_or_member, 0> + , private boost::base_from_member<base_or_member, 1> + , private boost::base_from_member<base_or_member, 2> + , public base_class +{ + typedef boost::base_from_member<base_or_member, 0> pbase_type0; + typedef boost::base_from_member<base_or_member, 1> pbase_type1; + typedef boost::base_from_member<base_or_member, 2> pbase_type2; + typedef base_class base_type; + +public: + good_class_2(); + ~good_class_2(); + +}; // good_class_2 + +// Declare/define the single object registrar +object_registrar obj_reg; + + +// Main functionality +int +main() +{ + BOOST_TEST( obj_reg.db_.empty() ); + BOOST_TEST( obj_reg.defrauders_in_.empty() ); + BOOST_TEST( obj_reg.defrauders_out_.empty() ); + BOOST_TEST( obj_reg.overeager_.empty() ); + BOOST_TEST( obj_reg.overkilled_.empty() ); + + // Make a separate block to examine pre- and post-effects + { + using std::cout; + using std::endl; + + bad_class bc; + BOOST_TEST( obj_reg.db_.size() == 3 ); + BOOST_TEST( obj_reg.defrauders_in_.size() == 1 ); + + good_class_1 gc1; + BOOST_TEST( obj_reg.db_.size() == 6 ); + BOOST_TEST( obj_reg.defrauders_in_.size() == 1 ); + + good_class_2 gc2; + BOOST_TEST( obj_reg.db_.size() == 11 ); + BOOST_TEST( obj_reg.defrauders_in_.size() == 1 ); + + BOOST_TEST( obj_reg.defrauders_out_.empty() ); + BOOST_TEST( obj_reg.overeager_.empty() ); + BOOST_TEST( obj_reg.overkilled_.empty() ); + + // Getting the addresses of the objects ensure + // that they're used, and not optimized away. + cout << "Object 'bc' is at " << &bc << '.' << endl; + cout << "Object 'gc1' is at " << &gc1 << '.' << endl; + cout << "Object 'gc2' is at " << &gc2 << '.' << endl; + } + + BOOST_TEST( obj_reg.db_.empty() ); + BOOST_TEST( obj_reg.defrauders_in_.size() == 1 ); + BOOST_TEST( obj_reg.defrauders_out_.size() == 1 ); + BOOST_TEST( obj_reg.overeager_.empty() ); + BOOST_TEST( obj_reg.overkilled_.empty() ); + + return boost::report_errors(); +} + + +// Print an object's ID +std::ostream & +operator << +( + std::ostream & os, + object_id const & oi +) +{ + // I had an std::ostringstream to help, but I did not need it since + // the program never screws around with formatting. Worse, using + // std::ostringstream is an issue with some compilers. + + return os << '[' << ( oi.second ? oi.second->name() : "NOTHING" ) + << " at " << oi.first << ']'; +} + +// Get an object ID given an object +template < typename T > +inline +object_id +identify +( + T & obj +) +{ + return std::make_pair( static_cast<void *>(&obj), &(typeid( obj )) ); +} + +// Compare two object IDs +bool +object_id_compare::operator () +( + object_id const & a, + object_id const & b +) const +{ + std::less<void *> vp_cmp; + if ( vp_cmp(a.first, b.first) ) + { + return true; + } + else if ( vp_cmp(b.first, a.first) ) + { + return false; + } + else + { + // object pointers are equal, compare the types + if ( a.second == b.second ) + { + return false; + } + else if ( !a.second ) + { + return true; // NULL preceeds anything else + } + else if ( !b.second ) + { + return false; // NULL preceeds anything else + } + else + { + return a.second->before( *b.second ) != 0; + } + } +} + +// Let an object register its existence +void +object_registrar::register_object_imp +( + object_id obj +) +{ + if ( db_.count(obj) <= 0 ) + { + db_.insert( obj ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "Registered " << obj << '.' << std::endl; + #endif + } + else + { + overeager_.push_back( obj ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "Attempted to register a non-existant " << obj + << '.' << std::endl; + #endif + } +} + +// Let an object register its use of another object +void +object_registrar::register_use_imp +( + object_id owner, + object_id owned +) +{ + if ( db_.count(owned) > 0 ) + { + // We don't care to record usage registrations + } + else + { + defrauders_in_.push_back( std::make_pair(owner, owned) ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "Attempted to own a non-existant " << owned + << " by " << owner << '.' << std::endl; + #endif + } +} + +// Let an object un-register its use of another object +void +object_registrar::unregister_use_imp +( + object_id owner, + object_id owned +) +{ + if ( db_.count(owned) > 0 ) + { + // We don't care to record usage un-registrations + } + else + { + defrauders_out_.push_back( std::make_pair(owner, owned) ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "Attempted to disown a non-existant " << owned + << " by " << owner << '.' << std::endl; + #endif + } +} + +// Let an object un-register its existence +void +object_registrar::unregister_object_imp +( + object_id obj +) +{ + set_type::iterator const i = db_.find( obj ); + + if ( i != db_.end() ) + { + db_.erase( i ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "Unregistered " << obj << '.' << std::endl; + #endif + } + else + { + overkilled_.push_back( obj ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "Attempted to unregister a non-existant " << obj + << '.' << std::endl; + #endif + } +} + +// Macros to abstract the registration of objects +#ifndef BOOST_NO_MEMBER_TEMPLATES +#define PRIVATE_REGISTER_BIRTH(o) obj_reg.register_object( (o) ) +#define PRIVATE_REGISTER_DEATH(o) obj_reg.unregister_object( (o) ) +#define PRIVATE_REGISTER_USE(o, w) obj_reg.register_use( (o), (w) ) +#define PRIVATE_UNREGISTER_USE(o, w) obj_reg.unregister_use( (o), (w) ) +#else +#define PRIVATE_REGISTER_BIRTH(o) obj_reg.register_object_imp( \ + identify((o)) ) +#define PRIVATE_REGISTER_DEATH(o) obj_reg.unregister_object_imp( \ + identify((o)) ) +#define PRIVATE_REGISTER_USE(o, w) obj_reg.register_use_imp( identify((o)), \ + identify((w)) ) +#define PRIVATE_UNREGISTER_USE(o, w) obj_reg.unregister_use_imp( \ + identify((o)), identify((w)) ) +#endif + +// Create a base_or_member, with arguments to simulate member initializations +base_or_member::base_or_member +( + int x, // = 1 + double y // = -0.25 +) +{ + PRIVATE_REGISTER_BIRTH( *this ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "\tMy x-factor is " << x << " and my y-factor is " << y + << '.' << std::endl; + #endif +} + +// Destroy a base_or_member +inline +base_or_member::~base_or_member +( +) +{ + PRIVATE_REGISTER_DEATH( *this ); +} + +// Create a base_class, registering any objects used +base_class::base_class +( + base_or_member & x, + base_or_member * y, // = 0 + base_or_member * z // = 0 +) + : x_( &x ), y_( y ), z_( z ) +{ + PRIVATE_REGISTER_BIRTH( *this ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "\tMy x-factor is " << x_; + #endif + + PRIVATE_REGISTER_USE( *this, *x_ ); + + if ( y_ ) + { + #if CONTROL_EXTRA_PRINTING + std::cout << ", my y-factor is " << y_; + #endif + + PRIVATE_REGISTER_USE( *this, *y_ ); + } + + if ( z_ ) + { + #if CONTROL_EXTRA_PRINTING + std::cout << ", my z-factor is " << z_; + #endif + + PRIVATE_REGISTER_USE( *this, *z_ ); + } + + #if CONTROL_EXTRA_PRINTING + std::cout << '.' << std::endl; + #endif +} + +// Destroy a base_class, unregistering the objects it uses +base_class::~base_class +( +) +{ + PRIVATE_REGISTER_DEATH( *this ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "\tMy x-factor was " << x_; + #endif + + PRIVATE_UNREGISTER_USE( *this, *x_ ); + + if ( y_ ) + { + #if CONTROL_EXTRA_PRINTING + std::cout << ", my y-factor was " << y_; + #endif + + PRIVATE_UNREGISTER_USE( *this, *y_ ); + } + + if ( z_ ) + { + #if CONTROL_EXTRA_PRINTING + std::cout << ", my z-factor was " << z_; + #endif + + PRIVATE_UNREGISTER_USE( *this, *z_ ); + } + + #if CONTROL_EXTRA_PRINTING + std::cout << '.' << std::endl; + #endif +} + +// Create a bad_class, noting the improper construction order +bad_class::bad_class +( +) + : x_( -7, 16.75 ), base_class( x_ ) // this order doesn't matter +{ + PRIVATE_REGISTER_BIRTH( *this ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "\tMy factor is at " << &x_ + << " and my base is at " << static_cast<base_class *>(this) << '.' + << std::endl; + #endif +} + +// Destroy a bad_class, noting the improper destruction order +bad_class::~bad_class +( +) +{ + PRIVATE_REGISTER_DEATH( *this ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "\tMy factor was at " << &x_ + << " and my base was at " << static_cast<base_class *>(this) + << '.' << std::endl; + #endif +} + +// Create a good_class_1, noting the proper construction order +good_class_1::good_class_1 +( +) + : pbase_type( 8 ), base_type( member ) +{ + PRIVATE_REGISTER_BIRTH( *this ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "\tMy factor is at " << &member + << " and my base is at " << static_cast<base_class *>(this) << '.' + << std::endl; + #endif +} + +// Destroy a good_class_1, noting the proper destruction order +good_class_1::~good_class_1 +( +) +{ + PRIVATE_REGISTER_DEATH( *this ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "\tMy factor was at " << &member + << " and my base was at " << static_cast<base_class *>(this) + << '.' << std::endl; + #endif +} + +// Create a good_class_2, noting the proper construction order +good_class_2::good_class_2 +( +) + : pbase_type0(), pbase_type1(-16, 0.125), pbase_type2(2, -3) + , base_type( pbase_type1::member, &this->pbase_type0::member, + &this->pbase_type2::member ) +{ + PRIVATE_REGISTER_BIRTH( *this ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "\tMy factors are at " << &this->pbase_type0::member + << ", " << &this->pbase_type1::member << ", " + << &this->pbase_type2::member << ", and my base is at " + << static_cast<base_class *>(this) << '.' << std::endl; + #endif +} + +// Destroy a good_class_2, noting the proper destruction order +good_class_2::~good_class_2 +( +) +{ + PRIVATE_REGISTER_DEATH( *this ); + + #if CONTROL_EXTRA_PRINTING + std::cout << "\tMy factors were at " << &this->pbase_type0::member + << ", " << &this->pbase_type1::member << ", " + << &this->pbase_type2::member << ", and my base was at " + << static_cast<base_class *>(this) << '.' << std::endl; + #endif +} diff --git a/src/boost/libs/utility/test/binary_test.cpp b/src/boost/libs/utility/test/binary_test.cpp new file mode 100644 index 00000000..f39dc08f --- /dev/null +++ b/src/boost/libs/utility/test/binary_test.cpp @@ -0,0 +1,647 @@ +/*============================================================================= + Copyright (c) 2006, 2007 Matthew Calabrese + + 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) +==============================================================================*/ + +#include <boost/core/lightweight_test.hpp> +#include <boost/utility/binary.hpp> +#include <algorithm> +#include <cstddef> + +#ifdef BOOST_MSVC +#pragma warning(disable:4996) // warning C4996: 'std::equal': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' +#endif + +/* +Note: This file tests every single valid bit-grouping on its own, and some + random combinations of bit-groupings. +*/ + +std::size_t const num_random_test_values = 32; + +// Note: These hex values should all correspond with the binary array below +unsigned int const random_unsigned_ints_hex[num_random_test_values] + = { 0x0103u, 0x77ebu, 0x5f36u, 0x1f18u, 0xc530u, 0xa73au, 0xd6f8u, 0x0919u + , 0xfbb0u, 0x3e7cu, 0xd0e9u, 0x22c8u, 0x724eu, 0x14fau, 0xd98eu, 0x40b5 + , 0xeba0u, 0xfe50u, 0x688au, 0x1b05u, 0x5f9cu, 0xe4fcu, 0xa7b8u, 0xd3acu + , 0x1dddu, 0xbf04u, 0x8352u, 0xe89cu, 0x7506u, 0xe767u, 0xf489u, 0xe167 + }; + +unsigned int const random_unsigned_ints_binary[num_random_test_values] + = { BOOST_BINARY( 0 00010000 0011 ), BOOST_BINARY( 0 11101 1111 101011 ) + , BOOST_BINARY( 010111 1100110 1 1 0 ), BOOST_BINARY( 000 1 11110 00 11000 ) + , BOOST_BINARY( 110 001010 0110 000 ), BOOST_BINARY( 1010 01110011 1010 ) + , BOOST_BINARY( 11 010 1 101111 1000 ), BOOST_BINARY( 0000 100100 0110 01 ) + , BOOST_BINARY( 1111 101110 11 0000 ), BOOST_BINARY( 00111110 01111100 ) + , BOOST_BINARY( 11 010 000111 01001 ), BOOST_BINARY( 00100 010110 01000 ) + , BOOST_BINARY( 01 11001001 001110 ), BOOST_BINARY( 0010 1001111 1010 ) + , BOOST_BINARY( 1101 1 00110 0 01110 ), BOOST_BINARY( 100 000 01011010 1 ) + , BOOST_BINARY( 11 1010 1110 1000 00 ), BOOST_BINARY( 11111 110010 10000 ) + , BOOST_BINARY( 01101 00010 001010 ), BOOST_BINARY( 000 11011 000001 01 ) + , BOOST_BINARY( 01 01111 1100111 00 ), BOOST_BINARY( 1 110010 0111111 00 ) + , BOOST_BINARY( 101 0011 11 01110 00 ), BOOST_BINARY( 110100 1 110101 100 ) + , BOOST_BINARY( 00 1110111 011 101 ), BOOST_BINARY( 1011 1111 00000 100 ) + , BOOST_BINARY( 1000 00110 101 0010 ), BOOST_BINARY( 1110 10001 001110 0 ) + , BOOST_BINARY( 011 1010100 000 110 ), BOOST_BINARY( 1110 0111 01100 111 ) + , BOOST_BINARY( 11110 10010 001001 ), BOOST_BINARY( 11 1000010 1100 111 ) + }; + +unsigned int const unsigned_ints_1_bit[2] = +{ BOOST_BINARY( 0 ) +, BOOST_BINARY( 1 ) +}; + +unsigned int const unsigned_ints_2_bits[4] = +{ BOOST_BINARY( 00 ) +, BOOST_BINARY( 01 ) +, BOOST_BINARY( 10 ) +, BOOST_BINARY( 11 ) +}; + +unsigned int const unsigned_ints_3_bits[8] = +{ BOOST_BINARY( 000 ) +, BOOST_BINARY( 001 ) +, BOOST_BINARY( 010 ) +, BOOST_BINARY( 011 ) +, BOOST_BINARY( 100 ) +, BOOST_BINARY( 101 ) +, BOOST_BINARY( 110 ) +, BOOST_BINARY( 111 ) +}; + +unsigned int const unsigned_ints_4_bits[16] = +{ BOOST_BINARY( 0000 ) +, BOOST_BINARY( 0001 ) +, BOOST_BINARY( 0010 ) +, BOOST_BINARY( 0011 ) +, BOOST_BINARY( 0100 ) +, BOOST_BINARY( 0101 ) +, BOOST_BINARY( 0110 ) +, BOOST_BINARY( 0111 ) +, BOOST_BINARY( 1000 ) +, BOOST_BINARY( 1001 ) +, BOOST_BINARY( 1010 ) +, BOOST_BINARY( 1011 ) +, BOOST_BINARY( 1100 ) +, BOOST_BINARY( 1101 ) +, BOOST_BINARY( 1110 ) +, BOOST_BINARY( 1111 ) +}; + +unsigned int const unsigned_ints_5_bits[32] = +{ BOOST_BINARY( 00000 ) +, BOOST_BINARY( 00001 ) +, BOOST_BINARY( 00010 ) +, BOOST_BINARY( 00011 ) +, BOOST_BINARY( 00100 ) +, BOOST_BINARY( 00101 ) +, BOOST_BINARY( 00110 ) +, BOOST_BINARY( 00111 ) +, BOOST_BINARY( 01000 ) +, BOOST_BINARY( 01001 ) +, BOOST_BINARY( 01010 ) +, BOOST_BINARY( 01011 ) +, BOOST_BINARY( 01100 ) +, BOOST_BINARY( 01101 ) +, BOOST_BINARY( 01110 ) +, BOOST_BINARY( 01111 ) +, BOOST_BINARY( 10000 ) +, BOOST_BINARY( 10001 ) +, BOOST_BINARY( 10010 ) +, BOOST_BINARY( 10011 ) +, BOOST_BINARY( 10100 ) +, BOOST_BINARY( 10101 ) +, BOOST_BINARY( 10110 ) +, BOOST_BINARY( 10111 ) +, BOOST_BINARY( 11000 ) +, BOOST_BINARY( 11001 ) +, BOOST_BINARY( 11010 ) +, BOOST_BINARY( 11011 ) +, BOOST_BINARY( 11100 ) +, BOOST_BINARY( 11101 ) +, BOOST_BINARY( 11110 ) +, BOOST_BINARY( 11111 ) +}; + +unsigned int const unsigned_ints_6_bits[64] = +{ BOOST_BINARY( 000000 ) +, BOOST_BINARY( 000001 ) +, BOOST_BINARY( 000010 ) +, BOOST_BINARY( 000011 ) +, BOOST_BINARY( 000100 ) +, BOOST_BINARY( 000101 ) +, BOOST_BINARY( 000110 ) +, BOOST_BINARY( 000111 ) +, BOOST_BINARY( 001000 ) +, BOOST_BINARY( 001001 ) +, BOOST_BINARY( 001010 ) +, BOOST_BINARY( 001011 ) +, BOOST_BINARY( 001100 ) +, BOOST_BINARY( 001101 ) +, BOOST_BINARY( 001110 ) +, BOOST_BINARY( 001111 ) +, BOOST_BINARY( 010000 ) +, BOOST_BINARY( 010001 ) +, BOOST_BINARY( 010010 ) +, BOOST_BINARY( 010011 ) +, BOOST_BINARY( 010100 ) +, BOOST_BINARY( 010101 ) +, BOOST_BINARY( 010110 ) +, BOOST_BINARY( 010111 ) +, BOOST_BINARY( 011000 ) +, BOOST_BINARY( 011001 ) +, BOOST_BINARY( 011010 ) +, BOOST_BINARY( 011011 ) +, BOOST_BINARY( 011100 ) +, BOOST_BINARY( 011101 ) +, BOOST_BINARY( 011110 ) +, BOOST_BINARY( 011111 ) +, BOOST_BINARY( 100000 ) +, BOOST_BINARY( 100001 ) +, BOOST_BINARY( 100010 ) +, BOOST_BINARY( 100011 ) +, BOOST_BINARY( 100100 ) +, BOOST_BINARY( 100101 ) +, BOOST_BINARY( 100110 ) +, BOOST_BINARY( 100111 ) +, BOOST_BINARY( 101000 ) +, BOOST_BINARY( 101001 ) +, BOOST_BINARY( 101010 ) +, BOOST_BINARY( 101011 ) +, BOOST_BINARY( 101100 ) +, BOOST_BINARY( 101101 ) +, BOOST_BINARY( 101110 ) +, BOOST_BINARY( 101111 ) +, BOOST_BINARY( 110000 ) +, BOOST_BINARY( 110001 ) +, BOOST_BINARY( 110010 ) +, BOOST_BINARY( 110011 ) +, BOOST_BINARY( 110100 ) +, BOOST_BINARY( 110101 ) +, BOOST_BINARY( 110110 ) +, BOOST_BINARY( 110111 ) +, BOOST_BINARY( 111000 ) +, BOOST_BINARY( 111001 ) +, BOOST_BINARY( 111010 ) +, BOOST_BINARY( 111011 ) +, BOOST_BINARY( 111100 ) +, BOOST_BINARY( 111101 ) +, BOOST_BINARY( 111110 ) +, BOOST_BINARY( 111111 ) +}; + +unsigned int const unsigned_ints_7_bits[128] = +{ BOOST_BINARY( 0000000 ) +, BOOST_BINARY( 0000001 ) +, BOOST_BINARY( 0000010 ) +, BOOST_BINARY( 0000011 ) +, BOOST_BINARY( 0000100 ) +, BOOST_BINARY( 0000101 ) +, BOOST_BINARY( 0000110 ) +, BOOST_BINARY( 0000111 ) +, BOOST_BINARY( 0001000 ) +, BOOST_BINARY( 0001001 ) +, BOOST_BINARY( 0001010 ) +, BOOST_BINARY( 0001011 ) +, BOOST_BINARY( 0001100 ) +, BOOST_BINARY( 0001101 ) +, BOOST_BINARY( 0001110 ) +, BOOST_BINARY( 0001111 ) +, BOOST_BINARY( 0010000 ) +, BOOST_BINARY( 0010001 ) +, BOOST_BINARY( 0010010 ) +, BOOST_BINARY( 0010011 ) +, BOOST_BINARY( 0010100 ) +, BOOST_BINARY( 0010101 ) +, BOOST_BINARY( 0010110 ) +, BOOST_BINARY( 0010111 ) +, BOOST_BINARY( 0011000 ) +, BOOST_BINARY( 0011001 ) +, BOOST_BINARY( 0011010 ) +, BOOST_BINARY( 0011011 ) +, BOOST_BINARY( 0011100 ) +, BOOST_BINARY( 0011101 ) +, BOOST_BINARY( 0011110 ) +, BOOST_BINARY( 0011111 ) +, BOOST_BINARY( 0100000 ) +, BOOST_BINARY( 0100001 ) +, BOOST_BINARY( 0100010 ) +, BOOST_BINARY( 0100011 ) +, BOOST_BINARY( 0100100 ) +, BOOST_BINARY( 0100101 ) +, BOOST_BINARY( 0100110 ) +, BOOST_BINARY( 0100111 ) +, BOOST_BINARY( 0101000 ) +, BOOST_BINARY( 0101001 ) +, BOOST_BINARY( 0101010 ) +, BOOST_BINARY( 0101011 ) +, BOOST_BINARY( 0101100 ) +, BOOST_BINARY( 0101101 ) +, BOOST_BINARY( 0101110 ) +, BOOST_BINARY( 0101111 ) +, BOOST_BINARY( 0110000 ) +, BOOST_BINARY( 0110001 ) +, BOOST_BINARY( 0110010 ) +, BOOST_BINARY( 0110011 ) +, BOOST_BINARY( 0110100 ) +, BOOST_BINARY( 0110101 ) +, BOOST_BINARY( 0110110 ) +, BOOST_BINARY( 0110111 ) +, BOOST_BINARY( 0111000 ) +, BOOST_BINARY( 0111001 ) +, BOOST_BINARY( 0111010 ) +, BOOST_BINARY( 0111011 ) +, BOOST_BINARY( 0111100 ) +, BOOST_BINARY( 0111101 ) +, BOOST_BINARY( 0111110 ) +, BOOST_BINARY( 0111111 ) +, BOOST_BINARY( 1000000 ) +, BOOST_BINARY( 1000001 ) +, BOOST_BINARY( 1000010 ) +, BOOST_BINARY( 1000011 ) +, BOOST_BINARY( 1000100 ) +, BOOST_BINARY( 1000101 ) +, BOOST_BINARY( 1000110 ) +, BOOST_BINARY( 1000111 ) +, BOOST_BINARY( 1001000 ) +, BOOST_BINARY( 1001001 ) +, BOOST_BINARY( 1001010 ) +, BOOST_BINARY( 1001011 ) +, BOOST_BINARY( 1001100 ) +, BOOST_BINARY( 1001101 ) +, BOOST_BINARY( 1001110 ) +, BOOST_BINARY( 1001111 ) +, BOOST_BINARY( 1010000 ) +, BOOST_BINARY( 1010001 ) +, BOOST_BINARY( 1010010 ) +, BOOST_BINARY( 1010011 ) +, BOOST_BINARY( 1010100 ) +, BOOST_BINARY( 1010101 ) +, BOOST_BINARY( 1010110 ) +, BOOST_BINARY( 1010111 ) +, BOOST_BINARY( 1011000 ) +, BOOST_BINARY( 1011001 ) +, BOOST_BINARY( 1011010 ) +, BOOST_BINARY( 1011011 ) +, BOOST_BINARY( 1011100 ) +, BOOST_BINARY( 1011101 ) +, BOOST_BINARY( 1011110 ) +, BOOST_BINARY( 1011111 ) +, BOOST_BINARY( 1100000 ) +, BOOST_BINARY( 1100001 ) +, BOOST_BINARY( 1100010 ) +, BOOST_BINARY( 1100011 ) +, BOOST_BINARY( 1100100 ) +, BOOST_BINARY( 1100101 ) +, BOOST_BINARY( 1100110 ) +, BOOST_BINARY( 1100111 ) +, BOOST_BINARY( 1101000 ) +, BOOST_BINARY( 1101001 ) +, BOOST_BINARY( 1101010 ) +, BOOST_BINARY( 1101011 ) +, BOOST_BINARY( 1101100 ) +, BOOST_BINARY( 1101101 ) +, BOOST_BINARY( 1101110 ) +, BOOST_BINARY( 1101111 ) +, BOOST_BINARY( 1110000 ) +, BOOST_BINARY( 1110001 ) +, BOOST_BINARY( 1110010 ) +, BOOST_BINARY( 1110011 ) +, BOOST_BINARY( 1110100 ) +, BOOST_BINARY( 1110101 ) +, BOOST_BINARY( 1110110 ) +, BOOST_BINARY( 1110111 ) +, BOOST_BINARY( 1111000 ) +, BOOST_BINARY( 1111001 ) +, BOOST_BINARY( 1111010 ) +, BOOST_BINARY( 1111011 ) +, BOOST_BINARY( 1111100 ) +, BOOST_BINARY( 1111101 ) +, BOOST_BINARY( 1111110 ) +, BOOST_BINARY( 1111111 ) +}; +unsigned int const unsigned_ints_8_bits[256] = +{ BOOST_BINARY( 00000000 ) +, BOOST_BINARY( 00000001 ) +, BOOST_BINARY( 00000010 ) +, BOOST_BINARY( 00000011 ) +, BOOST_BINARY( 00000100 ) +, BOOST_BINARY( 00000101 ) +, BOOST_BINARY( 00000110 ) +, BOOST_BINARY( 00000111 ) +, BOOST_BINARY( 00001000 ) +, BOOST_BINARY( 00001001 ) +, BOOST_BINARY( 00001010 ) +, BOOST_BINARY( 00001011 ) +, BOOST_BINARY( 00001100 ) +, BOOST_BINARY( 00001101 ) +, BOOST_BINARY( 00001110 ) +, BOOST_BINARY( 00001111 ) +, BOOST_BINARY( 00010000 ) +, BOOST_BINARY( 00010001 ) +, BOOST_BINARY( 00010010 ) +, BOOST_BINARY( 00010011 ) +, BOOST_BINARY( 00010100 ) +, BOOST_BINARY( 00010101 ) +, BOOST_BINARY( 00010110 ) +, BOOST_BINARY( 00010111 ) +, BOOST_BINARY( 00011000 ) +, BOOST_BINARY( 00011001 ) +, BOOST_BINARY( 00011010 ) +, BOOST_BINARY( 00011011 ) +, BOOST_BINARY( 00011100 ) +, BOOST_BINARY( 00011101 ) +, BOOST_BINARY( 00011110 ) +, BOOST_BINARY( 00011111 ) +, BOOST_BINARY( 00100000 ) +, BOOST_BINARY( 00100001 ) +, BOOST_BINARY( 00100010 ) +, BOOST_BINARY( 00100011 ) +, BOOST_BINARY( 00100100 ) +, BOOST_BINARY( 00100101 ) +, BOOST_BINARY( 00100110 ) +, BOOST_BINARY( 00100111 ) +, BOOST_BINARY( 00101000 ) +, BOOST_BINARY( 00101001 ) +, BOOST_BINARY( 00101010 ) +, BOOST_BINARY( 00101011 ) +, BOOST_BINARY( 00101100 ) +, BOOST_BINARY( 00101101 ) +, BOOST_BINARY( 00101110 ) +, BOOST_BINARY( 00101111 ) +, BOOST_BINARY( 00110000 ) +, BOOST_BINARY( 00110001 ) +, BOOST_BINARY( 00110010 ) +, BOOST_BINARY( 00110011 ) +, BOOST_BINARY( 00110100 ) +, BOOST_BINARY( 00110101 ) +, BOOST_BINARY( 00110110 ) +, BOOST_BINARY( 00110111 ) +, BOOST_BINARY( 00111000 ) +, BOOST_BINARY( 00111001 ) +, BOOST_BINARY( 00111010 ) +, BOOST_BINARY( 00111011 ) +, BOOST_BINARY( 00111100 ) +, BOOST_BINARY( 00111101 ) +, BOOST_BINARY( 00111110 ) +, BOOST_BINARY( 00111111 ) +, BOOST_BINARY( 01000000 ) +, BOOST_BINARY( 01000001 ) +, BOOST_BINARY( 01000010 ) +, BOOST_BINARY( 01000011 ) +, BOOST_BINARY( 01000100 ) +, BOOST_BINARY( 01000101 ) +, BOOST_BINARY( 01000110 ) +, BOOST_BINARY( 01000111 ) +, BOOST_BINARY( 01001000 ) +, BOOST_BINARY( 01001001 ) +, BOOST_BINARY( 01001010 ) +, BOOST_BINARY( 01001011 ) +, BOOST_BINARY( 01001100 ) +, BOOST_BINARY( 01001101 ) +, BOOST_BINARY( 01001110 ) +, BOOST_BINARY( 01001111 ) +, BOOST_BINARY( 01010000 ) +, BOOST_BINARY( 01010001 ) +, BOOST_BINARY( 01010010 ) +, BOOST_BINARY( 01010011 ) +, BOOST_BINARY( 01010100 ) +, BOOST_BINARY( 01010101 ) +, BOOST_BINARY( 01010110 ) +, BOOST_BINARY( 01010111 ) +, BOOST_BINARY( 01011000 ) +, BOOST_BINARY( 01011001 ) +, BOOST_BINARY( 01011010 ) +, BOOST_BINARY( 01011011 ) +, BOOST_BINARY( 01011100 ) +, BOOST_BINARY( 01011101 ) +, BOOST_BINARY( 01011110 ) +, BOOST_BINARY( 01011111 ) +, BOOST_BINARY( 01100000 ) +, BOOST_BINARY( 01100001 ) +, BOOST_BINARY( 01100010 ) +, BOOST_BINARY( 01100011 ) +, BOOST_BINARY( 01100100 ) +, BOOST_BINARY( 01100101 ) +, BOOST_BINARY( 01100110 ) +, BOOST_BINARY( 01100111 ) +, BOOST_BINARY( 01101000 ) +, BOOST_BINARY( 01101001 ) +, BOOST_BINARY( 01101010 ) +, BOOST_BINARY( 01101011 ) +, BOOST_BINARY( 01101100 ) +, BOOST_BINARY( 01101101 ) +, BOOST_BINARY( 01101110 ) +, BOOST_BINARY( 01101111 ) +, BOOST_BINARY( 01110000 ) +, BOOST_BINARY( 01110001 ) +, BOOST_BINARY( 01110010 ) +, BOOST_BINARY( 01110011 ) +, BOOST_BINARY( 01110100 ) +, BOOST_BINARY( 01110101 ) +, BOOST_BINARY( 01110110 ) +, BOOST_BINARY( 01110111 ) +, BOOST_BINARY( 01111000 ) +, BOOST_BINARY( 01111001 ) +, BOOST_BINARY( 01111010 ) +, BOOST_BINARY( 01111011 ) +, BOOST_BINARY( 01111100 ) +, BOOST_BINARY( 01111101 ) +, BOOST_BINARY( 01111110 ) +, BOOST_BINARY( 01111111 ) +, BOOST_BINARY( 10000000 ) +, BOOST_BINARY( 10000001 ) +, BOOST_BINARY( 10000010 ) +, BOOST_BINARY( 10000011 ) +, BOOST_BINARY( 10000100 ) +, BOOST_BINARY( 10000101 ) +, BOOST_BINARY( 10000110 ) +, BOOST_BINARY( 10000111 ) +, BOOST_BINARY( 10001000 ) +, BOOST_BINARY( 10001001 ) +, BOOST_BINARY( 10001010 ) +, BOOST_BINARY( 10001011 ) +, BOOST_BINARY( 10001100 ) +, BOOST_BINARY( 10001101 ) +, BOOST_BINARY( 10001110 ) +, BOOST_BINARY( 10001111 ) +, BOOST_BINARY( 10010000 ) +, BOOST_BINARY( 10010001 ) +, BOOST_BINARY( 10010010 ) +, BOOST_BINARY( 10010011 ) +, BOOST_BINARY( 10010100 ) +, BOOST_BINARY( 10010101 ) +, BOOST_BINARY( 10010110 ) +, BOOST_BINARY( 10010111 ) +, BOOST_BINARY( 10011000 ) +, BOOST_BINARY( 10011001 ) +, BOOST_BINARY( 10011010 ) +, BOOST_BINARY( 10011011 ) +, BOOST_BINARY( 10011100 ) +, BOOST_BINARY( 10011101 ) +, BOOST_BINARY( 10011110 ) +, BOOST_BINARY( 10011111 ) +, BOOST_BINARY( 10100000 ) +, BOOST_BINARY( 10100001 ) +, BOOST_BINARY( 10100010 ) +, BOOST_BINARY( 10100011 ) +, BOOST_BINARY( 10100100 ) +, BOOST_BINARY( 10100101 ) +, BOOST_BINARY( 10100110 ) +, BOOST_BINARY( 10100111 ) +, BOOST_BINARY( 10101000 ) +, BOOST_BINARY( 10101001 ) +, BOOST_BINARY( 10101010 ) +, BOOST_BINARY( 10101011 ) +, BOOST_BINARY( 10101100 ) +, BOOST_BINARY( 10101101 ) +, BOOST_BINARY( 10101110 ) +, BOOST_BINARY( 10101111 ) +, BOOST_BINARY( 10110000 ) +, BOOST_BINARY( 10110001 ) +, BOOST_BINARY( 10110010 ) +, BOOST_BINARY( 10110011 ) +, BOOST_BINARY( 10110100 ) +, BOOST_BINARY( 10110101 ) +, BOOST_BINARY( 10110110 ) +, BOOST_BINARY( 10110111 ) +, BOOST_BINARY( 10111000 ) +, BOOST_BINARY( 10111001 ) +, BOOST_BINARY( 10111010 ) +, BOOST_BINARY( 10111011 ) +, BOOST_BINARY( 10111100 ) +, BOOST_BINARY( 10111101 ) +, BOOST_BINARY( 10111110 ) +, BOOST_BINARY( 10111111 ) +, BOOST_BINARY( 11000000 ) +, BOOST_BINARY( 11000001 ) +, BOOST_BINARY( 11000010 ) +, BOOST_BINARY( 11000011 ) +, BOOST_BINARY( 11000100 ) +, BOOST_BINARY( 11000101 ) +, BOOST_BINARY( 11000110 ) +, BOOST_BINARY( 11000111 ) +, BOOST_BINARY( 11001000 ) +, BOOST_BINARY( 11001001 ) +, BOOST_BINARY( 11001010 ) +, BOOST_BINARY( 11001011 ) +, BOOST_BINARY( 11001100 ) +, BOOST_BINARY( 11001101 ) +, BOOST_BINARY( 11001110 ) +, BOOST_BINARY( 11001111 ) +, BOOST_BINARY( 11010000 ) +, BOOST_BINARY( 11010001 ) +, BOOST_BINARY( 11010010 ) +, BOOST_BINARY( 11010011 ) +, BOOST_BINARY( 11010100 ) +, BOOST_BINARY( 11010101 ) +, BOOST_BINARY( 11010110 ) +, BOOST_BINARY( 11010111 ) +, BOOST_BINARY( 11011000 ) +, BOOST_BINARY( 11011001 ) +, BOOST_BINARY( 11011010 ) +, BOOST_BINARY( 11011011 ) +, BOOST_BINARY( 11011100 ) +, BOOST_BINARY( 11011101 ) +, BOOST_BINARY( 11011110 ) +, BOOST_BINARY( 11011111 ) +, BOOST_BINARY( 11100000 ) +, BOOST_BINARY( 11100001 ) +, BOOST_BINARY( 11100010 ) +, BOOST_BINARY( 11100011 ) +, BOOST_BINARY( 11100100 ) +, BOOST_BINARY( 11100101 ) +, BOOST_BINARY( 11100110 ) +, BOOST_BINARY( 11100111 ) +, BOOST_BINARY( 11101000 ) +, BOOST_BINARY( 11101001 ) +, BOOST_BINARY( 11101010 ) +, BOOST_BINARY( 11101011 ) +, BOOST_BINARY( 11101100 ) +, BOOST_BINARY( 11101101 ) +, BOOST_BINARY( 11101110 ) +, BOOST_BINARY( 11101111 ) +, BOOST_BINARY( 11110000 ) +, BOOST_BINARY( 11110001 ) +, BOOST_BINARY( 11110010 ) +, BOOST_BINARY( 11110011 ) +, BOOST_BINARY( 11110100 ) +, BOOST_BINARY( 11110101 ) +, BOOST_BINARY( 11110110 ) +, BOOST_BINARY( 11110111 ) +, BOOST_BINARY( 11111000 ) +, BOOST_BINARY( 11111001 ) +, BOOST_BINARY( 11111010 ) +, BOOST_BINARY( 11111011 ) +, BOOST_BINARY( 11111100 ) +, BOOST_BINARY( 11111101 ) +, BOOST_BINARY( 11111110 ) +, BOOST_BINARY( 11111111 ) +}; + +struct left_is_not_one_less_than_right +{ + bool operator ()( unsigned int left, unsigned int right ) const + { + return right != left + 1; + } +}; + +template< std::size_t Size > +bool is_ascending_from_0_array( unsigned int const (&array)[Size] ) +{ + unsigned int const* const curr = array, + * const end = array + Size; + + return ( *curr == 0 ) + && ( std::adjacent_find( curr, end + , left_is_not_one_less_than_right() + ) + == end + ); +} + +std::size_t const unsigned_int_id = 1, + unsigned_long_int_id = 2; + +typedef char (&unsigned_int_id_type)[unsigned_int_id]; +typedef char (&unsigned_long_int_id_type)[unsigned_long_int_id]; + +// Note: Functions only used for type checking +unsigned_int_id_type binary_type_checker( unsigned int ); +unsigned_long_int_id_type binary_type_checker( unsigned long int ); + +int main() +{ + BOOST_TEST( is_ascending_from_0_array( unsigned_ints_1_bit ) ); + BOOST_TEST( is_ascending_from_0_array( unsigned_ints_2_bits ) ); + BOOST_TEST( is_ascending_from_0_array( unsigned_ints_3_bits ) ); + BOOST_TEST( is_ascending_from_0_array( unsigned_ints_4_bits ) ); + BOOST_TEST( is_ascending_from_0_array( unsigned_ints_5_bits ) ); + BOOST_TEST( is_ascending_from_0_array( unsigned_ints_6_bits ) ); + BOOST_TEST( is_ascending_from_0_array( unsigned_ints_7_bits ) ); + BOOST_TEST( is_ascending_from_0_array( unsigned_ints_8_bits ) ); + + BOOST_TEST( std::equal( &random_unsigned_ints_hex[0] + , random_unsigned_ints_hex + num_random_test_values + , &random_unsigned_ints_binary[0] + ) + ); + + BOOST_TEST( sizeof( binary_type_checker( BOOST_BINARY_U( 110100 1010 ) ) ) + == unsigned_int_id + ); + + BOOST_TEST( sizeof( binary_type_checker( BOOST_BINARY_UL( 11110 ) ) ) + == unsigned_long_int_id + ); + + BOOST_TEST( sizeof( binary_type_checker( BOOST_BINARY_LU( 10 0001 ) ) ) + == unsigned_long_int_id + ); + + return boost::report_errors(); +} diff --git a/src/boost/libs/utility/test/call_traits_test.cpp b/src/boost/libs/utility/test/call_traits_test.cpp new file mode 100644 index 00000000..9e49b68a --- /dev/null +++ b/src/boost/libs/utility/test/call_traits_test.cpp @@ -0,0 +1,418 @@ +// boost::compressed_pair test program + +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). + + +// standalone test program for <boost/call_traits.hpp> +// 18 Mar 2002: +// Changed some names to prevent conflicts with some new type_traits additions. +// 03 Oct 2000: +// Enabled extra tests for VC6. + +#include <iostream> +#include <iomanip> +#include <algorithm> +#include <typeinfo> +#include <boost/call_traits.hpp> + +#include <libs/type_traits/test/test.hpp> +#include <libs/type_traits/test/check_type.hpp> + +#ifdef BOOST_MSVC +#pragma warning(disable:4181) // : warning C4181: qualifier applied to reference type; ignored +#endif + +// a way prevent warnings for unused variables +template<class T> inline void unused_variable(const T&) {} + +// +// struct contained models a type that contains a type (for example std::pair) +// arrays are contained by value, and have to be treated as a special case: +// +template <class T> +struct contained +{ + // define our typedefs first, arrays are stored by value + // so value_type is not the same as result_type: + typedef typename boost::call_traits<T>::param_type param_type; + typedef typename boost::call_traits<T>::reference reference; + typedef typename boost::call_traits<T>::const_reference const_reference; + typedef T value_type; + typedef typename boost::call_traits<T>::value_type result_type; + + // stored value: + value_type v_; + + // constructors: + contained() {} + contained(param_type p) : v_(p){} + // return byval: + result_type value()const { return v_; } + // return by_ref: + reference get() { return v_; } + const_reference const_get()const { return v_; } + // pass value: + void call(param_type){} +private: + contained& operator=(const contained&); +}; + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template <class T, std::size_t N> +struct contained<T[N]> +{ + typedef typename boost::call_traits<T[N]>::param_type param_type; + typedef typename boost::call_traits<T[N]>::reference reference; + typedef typename boost::call_traits<T[N]>::const_reference const_reference; + typedef T value_type[N]; + typedef typename boost::call_traits<T[N]>::value_type result_type; + + value_type v_; + + contained(param_type p) + { + std::copy(p, p+N, v_); + } + // return byval: + result_type value()const { return v_; } + // return by_ref: + reference get() { return v_; } + const_reference const_get()const { return v_; } + void call(param_type){} +private: + contained& operator=(const contained&); +}; +#endif + +template <class T> +contained<typename boost::call_traits<T>::value_type> test_wrap_type(const T& t) +{ + typedef typename boost::call_traits<T>::value_type ct; + return contained<ct>(t); +} + +namespace test{ + +template <class T1, class T2> +std::pair< + typename boost::call_traits<T1>::value_type, + typename boost::call_traits<T2>::value_type> + make_pair(const T1& t1, const T2& t2) +{ + return std::pair< + typename boost::call_traits<T1>::value_type, + typename boost::call_traits<T2>::value_type>(t1, t2); +} + +} // namespace test + +using namespace std; + +// +// struct call_traits_checker: +// verifies behaviour of contained example: +// +template <class T> +struct call_traits_checker +{ + typedef typename boost::call_traits<T>::param_type param_type; + void operator()(param_type); +}; + +template <class T> +void call_traits_checker<T>::operator()(param_type p) +{ + T t(p); + contained<T> c(t); + cout << "checking contained<" << typeid(T).name() << ">..." << endl; + BOOST_CHECK(t == c.value()); + BOOST_CHECK(t == c.get()); + BOOST_CHECK(t == c.const_get()); +#ifndef __ICL + //cout << "typeof contained<" << typeid(T).name() << ">::v_ is: " << typeid(&contained<T>::v_).name() << endl; + cout << "typeof contained<" << typeid(T).name() << ">::value() is: " << typeid(&contained<T>::value).name() << endl; + cout << "typeof contained<" << typeid(T).name() << ">::get() is: " << typeid(&contained<T>::get).name() << endl; + cout << "typeof contained<" << typeid(T).name() << ">::const_get() is: " << typeid(&contained<T>::const_get).name() << endl; + cout << "typeof contained<" << typeid(T).name() << ">::call() is: " << typeid(&contained<T>::call).name() << endl; + cout << endl; +#endif +} + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template <class T, std::size_t N> +struct call_traits_checker<T[N]> +{ + typedef typename boost::call_traits<T[N]>::param_type param_type; + void operator()(param_type t) + { + contained<T[N]> c(t); + cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl; + unsigned int i = 0; + for(i = 0; i < N; ++i) + BOOST_CHECK(t[i] == c.value()[i]); + for(i = 0; i < N; ++i) + BOOST_CHECK(t[i] == c.get()[i]); + for(i = 0; i < N; ++i) + BOOST_CHECK(t[i] == c.const_get()[i]); + + cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is: " << typeid(&contained<T[N]>::v_).name() << endl; + cout << "typeof contained<" << typeid(T[N]).name() << ">::value is: " << typeid(&contained<T[N]>::value).name() << endl; + cout << "typeof contained<" << typeid(T[N]).name() << ">::get is: " << typeid(&contained<T[N]>::get).name() << endl; + cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is: " << typeid(&contained<T[N]>::const_get).name() << endl; + cout << "typeof contained<" << typeid(T[N]).name() << ">::call is: " << typeid(&contained<T[N]>::call).name() << endl; + cout << endl; + } +}; +#endif + +// +// check_wrap: +template <class W, class U> +void check_wrap(const W& w, const U& u) +{ + cout << "checking " << typeid(W).name() << "..." << endl; + BOOST_CHECK(w.value() == u); +} + +// +// check_make_pair: +// verifies behaviour of "make_pair": +// +template <class T, class U, class V> +void check_make_pair(T c, U u, V v) +{ + cout << "checking std::pair<" << typeid(c.first).name() << ", " << typeid(c.second).name() << ">..." << endl; + BOOST_CHECK(c.first == u); + BOOST_CHECK(c.second == v); + cout << endl; +} + + +struct comparible_UDT +{ + int i_; + comparible_UDT() : i_(2){} + comparible_UDT(const comparible_UDT& other) : i_(other.i_){} + comparible_UDT& operator=(const comparible_UDT& other) + { + i_ = other.i_; + return *this; + } + bool operator == (const comparible_UDT& v){ return v.i_ == i_; } +}; + +int main() +{ + call_traits_checker<comparible_UDT> c1; + comparible_UDT u; + c1(u); + call_traits_checker<int> c2; + call_traits_checker<enum_UDT> c2b; + int i = 2; + c2(i); + c2b(one); + int* pi = &i; + int a[2] = {1,2}; +#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL) + call_traits_checker<int*> c3; + c3(pi); + call_traits_checker<int&> c4; + c4(i); + call_traits_checker<const int&> c5; + c5(i); +#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__MWERKS__) && !defined(__SUNPRO_CC) + call_traits_checker<int[2]> c6; + c6(a); +#endif +#endif + + check_wrap(test_wrap_type(2), 2); +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC) + check_wrap(test_wrap_type(a), a); + check_make_pair(test::make_pair(a, a), a, a); +#endif + + // cv-qualifiers applied to reference types should have no effect + // declare these here for later use with is_reference and remove_reference: + typedef int& r_type; + typedef const r_type cr_type; + + BOOST_CHECK_TYPE(comparible_UDT, boost::call_traits<comparible_UDT>::value_type); + BOOST_CHECK_TYPE(comparible_UDT&, boost::call_traits<comparible_UDT>::reference); + BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::const_reference); + BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::param_type); + BOOST_CHECK_TYPE(int, boost::call_traits<int>::value_type); + BOOST_CHECK_TYPE(int&, boost::call_traits<int>::reference); + BOOST_CHECK_TYPE(const int&, boost::call_traits<int>::const_reference); + BOOST_CHECK_TYPE(const int, boost::call_traits<int>::param_type); + BOOST_CHECK_TYPE(int*, boost::call_traits<int*>::value_type); + BOOST_CHECK_TYPE(int*&, boost::call_traits<int*>::reference); + BOOST_CHECK_TYPE(int*const&, boost::call_traits<int*>::const_reference); + BOOST_CHECK_TYPE(int*const, boost::call_traits<int*>::param_type); +#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) + BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::value_type); + BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::reference); + BOOST_CHECK_TYPE(const int&, boost::call_traits<int&>::const_reference); + BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::param_type); +#if !(defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ < 1))) + BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::value_type); + BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::reference); + BOOST_CHECK_TYPE(const int&, boost::call_traits<cr_type>::const_reference); + BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::param_type); +#else + std::cout << "Your compiler cannot instantiate call_traits<int&const>, skipping four tests (4 errors)" << std::endl; +#endif + BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::value_type); + BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::reference); + BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::const_reference); + BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::param_type); +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + BOOST_CHECK_TYPE(const int*, boost::call_traits<int[3]>::value_type); + BOOST_CHECK_TYPE(int(&)[3], boost::call_traits<int[3]>::reference); + BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<int[3]>::const_reference); + BOOST_CHECK_TYPE(const int*const, boost::call_traits<int[3]>::param_type); + BOOST_CHECK_TYPE(const int*, boost::call_traits<const int[3]>::value_type); + BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::reference); + BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::const_reference); + BOOST_CHECK_TYPE(const int*const, boost::call_traits<const int[3]>::param_type); + // test with abstract base class: + BOOST_CHECK_TYPE(test_abc1, boost::call_traits<test_abc1>::value_type); + BOOST_CHECK_TYPE(test_abc1&, boost::call_traits<test_abc1>::reference); + BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::const_reference); + BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::param_type); +#else + std::cout << "You're compiler does not support partial template specialiation, skipping 8 tests (8 errors)" << std::endl; +#endif +#else + std::cout << "You're compiler does not support partial template specialiation, skipping 20 tests (20 errors)" << std::endl; +#endif + // test with an incomplete type: + BOOST_CHECK_TYPE(incomplete_type, boost::call_traits<incomplete_type>::value_type); + BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits<incomplete_type>::reference); + BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::const_reference); + BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::param_type); + // test enum: + BOOST_CHECK_TYPE(enum_UDT, boost::call_traits<enum_UDT>::value_type); + BOOST_CHECK_TYPE(enum_UDT&, boost::call_traits<enum_UDT>::reference); + BOOST_CHECK_TYPE(const enum_UDT&, boost::call_traits<enum_UDT>::const_reference); + BOOST_CHECK_TYPE(const enum_UDT, boost::call_traits<enum_UDT>::param_type); + return 0; +} + +// +// define call_traits tests to check that the assertions in the docs do actually work +// this is an compile-time only set of tests: +// +template <typename T, bool isarray = false> +struct call_traits_test +{ + typedef ::boost::call_traits<T> ct; + typedef typename ct::param_type param_type; + typedef typename ct::reference reference; + typedef typename ct::const_reference const_reference; + typedef typename ct::value_type value_type; + static void assert_construct(param_type val); +}; + +template <typename T, bool isarray> +void call_traits_test<T, isarray>::assert_construct(typename call_traits_test<T, isarray>::param_type val) +{ + // + // this is to check that the call_traits assertions are valid: + T t(val); + value_type v(t); + reference r(t); + const_reference cr(t); + param_type p(t); + value_type v2(v); + value_type v3(r); + value_type v4(p); + reference r2(v); + reference r3(r); + const_reference cr2(v); + const_reference cr3(r); + const_reference cr4(cr); + const_reference cr5(p); + param_type p2(v); + param_type p3(r); + param_type p4(p); + + unused_variable(v2); + unused_variable(v3); + unused_variable(v4); + unused_variable(r2); + unused_variable(r3); + unused_variable(cr2); + unused_variable(cr3); + unused_variable(cr4); + unused_variable(cr5); + unused_variable(p2); + unused_variable(p3); + unused_variable(p4); +} +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template <typename T> +struct call_traits_test<T, true> +{ + typedef ::boost::call_traits<T> ct; + typedef typename ct::param_type param_type; + typedef typename ct::reference reference; + typedef typename ct::const_reference const_reference; + typedef typename ct::value_type value_type; + static void assert_construct(param_type val); +}; + +template <typename T> +void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>::param_type val) +{ + // + // this is to check that the call_traits assertions are valid: + T t; + value_type v(t); + value_type v5(val); + reference r = t; + const_reference cr = t; + reference r2 = r; + #ifndef __BORLANDC__ + // C++ Builder buglet: + const_reference cr2 = r; + #endif + param_type p(t); + value_type v2(v); + const_reference cr3 = cr; + value_type v3(r); + value_type v4(p); + param_type p2(v); + param_type p3(r); + param_type p4(p); + + unused_variable(v2); + unused_variable(v3); + unused_variable(v4); + unused_variable(v5); +#ifndef __BORLANDC__ + unused_variable(r2); + unused_variable(cr2); +#endif + unused_variable(cr3); + unused_variable(p2); + unused_variable(p3); + unused_variable(p4); +} +#endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +// +// now check call_traits assertions by instantiating call_traits_test: +template struct call_traits_test<int>; +template struct call_traits_test<const int>; +template struct call_traits_test<int*>; +#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) +template struct call_traits_test<int&>; +template struct call_traits_test<const int&>; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC) +template struct call_traits_test<int[2], true>; +#endif +#endif + diff --git a/src/boost/libs/utility/test/compressed_pair_final_test.cpp b/src/boost/libs/utility/test/compressed_pair_final_test.cpp new file mode 100644 index 00000000..247f3fce --- /dev/null +++ b/src/boost/libs/utility/test/compressed_pair_final_test.cpp @@ -0,0 +1,55 @@ +/* +Copyright 2018 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_FINAL) +#include <boost/compressed_pair.hpp> +#include <boost/core/lightweight_test.hpp> + +struct type1 { + operator bool() const { + return false; + } +}; + +struct type2 final { + operator bool() const { + return false; + } +}; + +#if !defined(BOOST_IS_FINAL) +namespace boost { + +template<> +struct is_final<type2> + : true_type { }; + +} /* boost*/ +#endif + +template<class T1, class T2> +void test() +{ + boost::compressed_pair<T1, T2> p; + BOOST_TEST(!p.first()); + BOOST_TEST(!p.second()); +} + +int main() +{ + test<type1, type2>(); + test<type2, type1>(); + test<type2, type2>(); + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/src/boost/libs/utility/test/compressed_pair_test.cpp b/src/boost/libs/utility/test/compressed_pair_test.cpp new file mode 100644 index 00000000..ea10b2c0 --- /dev/null +++ b/src/boost/libs/utility/test/compressed_pair_test.cpp @@ -0,0 +1,387 @@ +// boost::compressed_pair test program + +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). + +// standalone test program for <boost/compressed_pair.hpp> +// Revised 03 Oct 2000: +// Enabled tests for VC6. + +#include <iostream> +#include <typeinfo> +#include <cassert> + +#include <boost/compressed_pair.hpp> +#include <boost/core/lightweight_test.hpp> + +using namespace boost; + +struct empty_UDT +{ + ~empty_UDT(){}; + empty_UDT& operator=(const empty_UDT&){ return *this; } + bool operator==(const empty_UDT&)const + { return true; } +}; +struct empty_POD_UDT +{ + empty_POD_UDT& operator=(const empty_POD_UDT&){ return *this; } + bool operator==(const empty_POD_UDT&)const + { return true; } +}; + +struct non_empty1 +{ + int i; + non_empty1() : i(1){} + non_empty1(int v) : i(v){} + friend bool operator==(const non_empty1& a, const non_empty1& b) + { return a.i == b.i; } +}; + +struct non_empty2 +{ + int i; + non_empty2() : i(3){} + non_empty2(int v) : i(v){} + friend bool operator==(const non_empty2& a, const non_empty2& b) + { return a.i == b.i; } +}; + +#ifdef __GNUC__ +using std::swap; +#endif + +template <class T1, class T2> +struct compressed_pair_tester +{ + // define the types we need: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits<first_type>::param_type first_param_type; + typedef typename call_traits<second_type>::param_type second_param_type; + // define our test proc: + static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); +}; + +template <class T1, class T2> +void compressed_pair_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4) +{ +#ifndef __GNUC__ + // gcc 2.90 can't cope with function scope using + // declarations, and generates an internal compiler error... + using std::swap; +#endif + // default construct: + boost::compressed_pair<T1,T2> cp1; + // first param construct: + boost::compressed_pair<T1,T2> cp2(p1); + cp2.second() = p2; + BOOST_TEST(cp2.first() == p1); + BOOST_TEST(cp2.second() == p2); + // second param construct: + boost::compressed_pair<T1,T2> cp3(p2); + cp3.first() = p1; + BOOST_TEST(cp3.second() == p2); + BOOST_TEST(cp3.first() == p1); + // both param construct: + boost::compressed_pair<T1,T2> cp4(p1, p2); + BOOST_TEST(cp4.first() == p1); + BOOST_TEST(cp4.second() == p2); + boost::compressed_pair<T1,T2> cp5(p3, p4); + BOOST_TEST(cp5.first() == p3); + BOOST_TEST(cp5.second() == p4); + // check const members: + const boost::compressed_pair<T1,T2>& cpr1 = cp4; + BOOST_TEST(cpr1.first() == p1); + BOOST_TEST(cpr1.second() == p2); + + // copy construct: + boost::compressed_pair<T1,T2> cp6(cp4); + BOOST_TEST(cp6.first() == p1); + BOOST_TEST(cp6.second() == p2); + // assignment: + cp1 = cp4; + BOOST_TEST(cp1.first() == p1); + BOOST_TEST(cp1.second() == p2); + cp1 = cp5; + BOOST_TEST(cp1.first() == p3); + BOOST_TEST(cp1.second() == p4); + // swap: + cp4.swap(cp5); + BOOST_TEST(cp4.first() == p3); + BOOST_TEST(cp4.second() == p4); + BOOST_TEST(cp5.first() == p1); + BOOST_TEST(cp5.second() == p2); + swap(cp4,cp5); + BOOST_TEST(cp4.first() == p1); + BOOST_TEST(cp4.second() == p2); + BOOST_TEST(cp5.first() == p3); + BOOST_TEST(cp5.second() == p4); +} + +// +// tests for case where one or both +// parameters are reference types: +// +template <class T1, class T2> +struct compressed_pair_reference_tester +{ + // define the types we need: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits<first_type>::param_type first_param_type; + typedef typename call_traits<second_type>::param_type second_param_type; + // define our test proc: + static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); +}; + +template <class T1, class T2> +void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4) +{ +#ifndef __GNUC__ + // gcc 2.90 can't cope with function scope using + // declarations, and generates an internal compiler error... + using std::swap; +#endif + // both param construct: + boost::compressed_pair<T1,T2> cp4(p1, p2); + BOOST_TEST(cp4.first() == p1); + BOOST_TEST(cp4.second() == p2); + boost::compressed_pair<T1,T2> cp5(p3, p4); + BOOST_TEST(cp5.first() == p3); + BOOST_TEST(cp5.second() == p4); + // check const members: + const boost::compressed_pair<T1,T2>& cpr1 = cp4; + BOOST_TEST(cpr1.first() == p1); + BOOST_TEST(cpr1.second() == p2); + + // copy construct: + boost::compressed_pair<T1,T2> cp6(cp4); + BOOST_TEST(cp6.first() == p1); + BOOST_TEST(cp6.second() == p2); + // assignment: + // VC6 bug: + // When second() is an empty class, VC6 performs the + // assignment by doing a memcpy - even though the empty + // class is really a zero sized base class, the result + // is that the memory of first() gets trampled over. + // Similar arguments apply to the case that first() is + // an empty base class. + // Strangely the problem is dependent upon the compiler + // settings - some generate the problem others do not. + cp4.first() = p3; + cp4.second() = p4; + BOOST_TEST(cp4.first() == p3); + BOOST_TEST(cp4.second() == p4); +} +// +// supplimentary tests for case where first arg only is a reference type: +// +template <class T1, class T2> +struct compressed_pair_reference1_tester +{ + // define the types we need: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits<first_type>::param_type first_param_type; + typedef typename call_traits<second_type>::param_type second_param_type; + // define our test proc: + static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); +}; + +template <class T1, class T2> +void compressed_pair_reference1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type) +{ +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // first param construct: + boost::compressed_pair<T1,T2> cp2(p1); + cp2.second() = p2; + BOOST_TEST(cp2.first() == p1); + BOOST_TEST(cp2.second() == p2); +#endif +} +// +// supplimentary tests for case where second arg only is a reference type: +// +template <class T1, class T2> +struct compressed_pair_reference2_tester +{ + // define the types we need: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits<first_type>::param_type first_param_type; + typedef typename call_traits<second_type>::param_type second_param_type; + // define our test proc: + static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); +}; + +template <class T1, class T2> +void compressed_pair_reference2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type) +{ +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // second param construct: + boost::compressed_pair<T1,T2> cp3(p2); + cp3.first() = p1; + BOOST_TEST(cp3.second() == p2); + BOOST_TEST(cp3.first() == p1); +#endif +} + +// +// tests for where one or the other parameter is an array: +// +template <class T1, class T2> +struct compressed_pair_array1_tester +{ + // define the types we need: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits<first_type>::param_type first_param_type; + typedef typename call_traits<second_type>::param_type second_param_type; + // define our test proc: + static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); +}; + +template <class T1, class T2> +void compressed_pair_array1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type) +{ + // default construct: + boost::compressed_pair<T1,T2> cp1; + // second param construct: + boost::compressed_pair<T1,T2> cp3(p2); + cp3.first()[0] = p1[0]; + BOOST_TEST(cp3.second() == p2); + BOOST_TEST(cp3.first()[0] == p1[0]); + // check const members: + const boost::compressed_pair<T1,T2>& cpr1 = cp3; + BOOST_TEST(cpr1.first()[0] == p1[0]); + BOOST_TEST(cpr1.second() == p2); + + BOOST_TEST(sizeof(T1) == sizeof(cp1.first())); +} + +template <class T1, class T2> +struct compressed_pair_array2_tester +{ + // define the types we need: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits<first_type>::param_type first_param_type; + typedef typename call_traits<second_type>::param_type second_param_type; + // define our test proc: + static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); +}; + +template <class T1, class T2> +void compressed_pair_array2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type) +{ + // default construct: + boost::compressed_pair<T1,T2> cp1; + // first param construct: + boost::compressed_pair<T1,T2> cp2(p1); + cp2.second()[0] = p2[0]; + BOOST_TEST(cp2.first() == p1); + BOOST_TEST(cp2.second()[0] == p2[0]); + // check const members: + const boost::compressed_pair<T1,T2>& cpr1 = cp2; + BOOST_TEST(cpr1.first() == p1); + BOOST_TEST(cpr1.second()[0] == p2[0]); + + BOOST_TEST(sizeof(T2) == sizeof(cp1.second())); +} + +template <class T1, class T2> +struct compressed_pair_array_tester +{ + // define the types we need: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits<first_type>::param_type first_param_type; + typedef typename call_traits<second_type>::param_type second_param_type; + // define our test proc: + static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); +}; + +template <class T1, class T2> +void compressed_pair_array_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type) +{ + // default construct: + boost::compressed_pair<T1,T2> cp1; + cp1.first()[0] = p1[0]; + cp1.second()[0] = p2[0]; + BOOST_TEST(cp1.first()[0] == p1[0]); + BOOST_TEST(cp1.second()[0] == p2[0]); + // check const members: + const boost::compressed_pair<T1,T2>& cpr1 = cp1; + BOOST_TEST(cpr1.first()[0] == p1[0]); + BOOST_TEST(cpr1.second()[0] == p2[0]); + + BOOST_TEST(sizeof(T1) == sizeof(cp1.first())); + BOOST_TEST(sizeof(T2) == sizeof(cp1.second())); +} + +int main() +{ + // declare some variables to pass to the tester: + non_empty1 ne1(2); + non_empty1 ne2(3); + non_empty2 ne3(4); + non_empty2 ne4(5); + empty_POD_UDT e1; + empty_UDT e2; + + // T1 != T2, both non-empty + compressed_pair_tester<non_empty1,non_empty2>::test(ne1, ne3, ne2, ne4); + // T1 != T2, T2 empty + compressed_pair_tester<non_empty1,empty_POD_UDT>::test(ne1, e1, ne2, e1); + // T1 != T2, T1 empty + compressed_pair_tester<empty_POD_UDT,non_empty2>::test(e1, ne3, e1, ne4); + // T1 != T2, both empty + compressed_pair_tester<empty_POD_UDT,empty_UDT>::test(e1, e2, e1, e2); + // T1 == T2, both non-empty + compressed_pair_tester<non_empty1,non_empty1>::test(ne1, ne1, ne2, ne2); + // T1 == T2, both empty + compressed_pair_tester<empty_UDT,empty_UDT>::test(e2, e2, e2, e2); + + + // test references: + + // T1 != T2, both non-empty + compressed_pair_reference_tester<non_empty1&,non_empty2>::test(ne1, ne3, ne2, ne4); + compressed_pair_reference_tester<non_empty1,non_empty2&>::test(ne1, ne3, ne2, ne4); + compressed_pair_reference1_tester<non_empty1&,non_empty2>::test(ne1, ne3, ne2, ne4); + compressed_pair_reference2_tester<non_empty1,non_empty2&>::test(ne1, ne3, ne2, ne4); + // T1 != T2, T2 empty + compressed_pair_reference_tester<non_empty1&,empty_POD_UDT>::test(ne1, e1, ne2, e1); + compressed_pair_reference1_tester<non_empty1&,empty_POD_UDT>::test(ne1, e1, ne2, e1); + // T1 != T2, T1 empty + compressed_pair_reference_tester<empty_POD_UDT,non_empty2&>::test(e1, ne3, e1, ne4); + compressed_pair_reference2_tester<empty_POD_UDT,non_empty2&>::test(e1, ne3, e1, ne4); + // T1 == T2, both non-empty + compressed_pair_reference_tester<non_empty1&,non_empty1&>::test(ne1, ne1, ne2, ne2); + + // tests arrays: + non_empty1 nea1[2]; + non_empty1 nea2[2]; + non_empty2 nea3[2]; + non_empty2 nea4[2]; + nea1[0] = non_empty1(5); + nea2[0] = non_empty1(6); + nea3[0] = non_empty2(7); + nea4[0] = non_empty2(8); + + // T1 != T2, both non-empty + compressed_pair_array1_tester<non_empty1[2],non_empty2>::test(nea1, ne3, nea2, ne4); + compressed_pair_array2_tester<non_empty1,non_empty2[2]>::test(ne1, nea3, ne2, nea4); + compressed_pair_array_tester<non_empty1[2],non_empty2[2]>::test(nea1, nea3, nea2, nea4); + // T1 != T2, T2 empty + compressed_pair_array1_tester<non_empty1[2],empty_POD_UDT>::test(nea1, e1, nea2, e1); + // T1 != T2, T1 empty + compressed_pair_array2_tester<empty_POD_UDT,non_empty2[2]>::test(e1, nea3, e1, nea4); + // T1 == T2, both non-empty + compressed_pair_array_tester<non_empty1[2],non_empty1[2]>::test(nea1, nea1, nea2, nea2); + return boost::report_errors(); +} diff --git a/src/boost/libs/utility/test/initialized_test.cpp b/src/boost/libs/utility/test/initialized_test.cpp new file mode 100644 index 00000000..0b8852f1 --- /dev/null +++ b/src/boost/libs/utility/test/initialized_test.cpp @@ -0,0 +1,116 @@ +// Copyright 2010, Niels Dekker. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Test program for boost::initialized<T>. +// +// 2 May 2010 (Created) Niels Dekker + +#include <boost/utility/value_init.hpp> +#include <boost/core/lightweight_test.hpp> + +#include <string> + +namespace +{ + // Typical use case for boost::initialized<T>: A generic class that + // holds a value of type T, which must be initialized by either + // value-initialization or direct-initialization. + template <class T> class key_value_pair + { + std::string m_key; + boost::initialized<T> m_value; + public: + + // Value-initializes the object held by m_value. + key_value_pair() { } + + // Value-initializes the object held by m_value. + explicit key_value_pair(const std::string& key) + : + m_key(key) + { + } + + // Direct-initializes the object held by m_value. + key_value_pair(const std::string& key, const T& value) + : + m_key(key), m_value(value) + { + } + + const T& get_value() const + { + return m_value; + } + }; + + + // Tells whether the argument is value-initialized. + bool is_value_initialized(const int& arg) + { + return arg == 0; + } + + + // Tells whether the argument is value-initialized. + bool is_value_initialized(const std::string& arg) + { + return arg.empty(); + } + + struct foo + { + int data; + }; + + bool operator==(const foo& lhs, const foo& rhs) + { + return lhs.data == rhs.data; + } + + + // Tells whether the argument is value-initialized. + bool is_value_initialized(const foo& arg) + { + return arg.data == 0; + } + + + template <class T> + void test_key_value_pair(const T& magic_value) + { + // The value component of a default key_value_pair must be value-initialized. + key_value_pair<T> default_key_value_pair; + BOOST_TEST( is_value_initialized(default_key_value_pair.get_value() ) ); + + // The value component of a key_value_pair that only has its key explicitly specified + // must also be value-initialized. + BOOST_TEST( is_value_initialized(key_value_pair<T>("key").get_value()) ); + + // However, the value component of the following key_value_pair must be + // "magic_value", as it must be direct-initialized. + BOOST_TEST( key_value_pair<T>("key", magic_value).get_value() == magic_value ); + } +} + + +// Tests boost::initialize for a fundamental type, a type with a +// user-defined constructor, and a user-defined type without +// a user-defined constructor. +int main() +{ + + const int magic_number = 42; + test_key_value_pair(magic_number); + + const std::string magic_string = "magic value"; + test_key_value_pair(magic_string); + + const foo magic_foo = { 42 }; + test_key_value_pair(magic_foo); + + return boost::report_errors(); +} diff --git a/src/boost/libs/utility/test/initialized_test_fail1.cpp b/src/boost/libs/utility/test/initialized_test_fail1.cpp new file mode 100644 index 00000000..ffeecab5 --- /dev/null +++ b/src/boost/libs/utility/test/initialized_test_fail1.cpp @@ -0,0 +1,33 @@ +// Copyright 2010, Niels Dekker. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Test program for boost::initialized<T>. Must fail to compile. +// +// Initial: 2 May 2010 + +#include <boost/utility/value_init.hpp> + +namespace +{ + void direct_initialize_from_int() + { + // Okay: initialized<T> supports direct-initialization from T. + boost::initialized<int> direct_initialized_int(1); + } + + void copy_initialize_from_int() + { + // The following line should not compile, because initialized<T> + // was not intended to supports copy-initialization from T. + boost::initialized<int> copy_initialized_int = 1; + } +} + +int main() +{ + // This should fail to compile, so there is no need to call any function. + return 0; +} diff --git a/src/boost/libs/utility/test/initialized_test_fail2.cpp b/src/boost/libs/utility/test/initialized_test_fail2.cpp new file mode 100644 index 00000000..f3fbf391 --- /dev/null +++ b/src/boost/libs/utility/test/initialized_test_fail2.cpp @@ -0,0 +1,37 @@ +// Copyright 2010, Niels Dekker. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Test program for boost::initialized<T>. Must fail to compile. +// +// Initial: 2 May 2010 + +#include <boost/utility/value_init.hpp> + +namespace +{ + void from_value_initialized_to_initialized() + { + boost::value_initialized<int> value_initialized_int; + + // Okay: initialized<T> can be initialized by value_initialized<T>. + boost::initialized<int> initialized_int(value_initialized_int); + } + + void from_initialized_to_value_initialized() + { + boost::initialized<int> initialized_int(13); + + // The following line should not compile, because initialized<T> + // should not be convertible to value_initialized<T>. + boost::value_initialized<int> value_initialized_int(initialized_int); + } +} + +int main() +{ + // This should fail to compile, so there is no need to call any function. + return 0; +} diff --git a/src/boost/libs/utility/test/iterators_test.cpp b/src/boost/libs/utility/test/iterators_test.cpp new file mode 100644 index 00000000..8f2d04d0 --- /dev/null +++ b/src/boost/libs/utility/test/iterators_test.cpp @@ -0,0 +1,322 @@ +// Demonstrate and test boost/operators.hpp on std::iterators --------------// + +// (C) Copyright Jeremy Siek 1999. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +// Revision History +// 29 May 01 Factored implementation, added comparison tests, use Test Tools +// library (Daryle Walker) +// 12 Dec 99 Initial version with iterator operators (Jeremy Siek) + +#include <boost/core/lightweight_test.hpp> + +#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT +#include <boost/operators.hpp> // for boost::random_access_iterator_helper + +#include <cstddef> // for std::ptrdiff_t, std::size_t +#include <cstring> // for std::strcmp +#include <iostream> // for std::cout (std::endl, ends, and flush indirectly) +#include <string> // for std::string +#include <sstream> // for std::stringstream + +# ifdef BOOST_NO_STDC_NAMESPACE + namespace std { using ::strcmp; } +# endif + + +// Iterator test class +template <class T, class R, class P> +struct test_iter + : public boost::random_access_iterator_helper< + test_iter<T,R,P>, T, std::ptrdiff_t, P, R> +{ + typedef test_iter self; + typedef R Reference; + typedef std::ptrdiff_t Distance; + +public: + explicit test_iter(T* i =0) : _i(i) { } + test_iter(const self& x) : _i(x._i) { } + self& operator=(const self& x) { _i = x._i; return *this; } + Reference operator*() const { return *_i; } + self& operator++() { ++_i; return *this; } + self& operator--() { --_i; return *this; } + self& operator+=(Distance n) { _i += n; return *this; } + self& operator-=(Distance n) { _i -= n; return *this; } + bool operator==(const self& x) const { return _i == x._i; } + bool operator<(const self& x) const { return _i < x._i; } + friend Distance operator-(const self& x, const self& y) { + return x._i - y._i; + } +protected: + P _i; +}; + +// Iterator operator testing classes +class test_opr_base +{ +protected: + // Test data and types + BOOST_STATIC_CONSTANT( std::size_t, fruit_length = 6u ); + + typedef std::string fruit_array_type[ fruit_length ]; + + static fruit_array_type fruit; + +}; // test_opr_base + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +// A definition is required even for integral static constants +const std::size_t test_opr_base::fruit_length; +#endif + +template <typename T, typename R = T&, typename P = T*> +class test_opr + : public test_opr_base +{ + typedef test_opr<T, R, P> self_type; + +public: + // Types + typedef T value_type; + typedef R reference; + typedef P pointer; + + typedef test_iter<T, R, P> iter_type; + + // Test controller + static void master_test( char const name[] ); + +private: + // Test data + static iter_type const fruit_begin; + static iter_type const fruit_end; + + // Test parts + static void post_increment_test(); + static void post_decrement_test(); + static void indirect_referral_test(); + static void offset_addition_test(); + static void reverse_offset_addition_test(); + static void offset_subtraction_test(); + static void comparison_test(); + static void indexing_test(); + +}; // test_opr + + +// Class-static data definitions +test_opr_base::fruit_array_type + test_opr_base::fruit = { "apple", "orange", "pear", "peach", "grape", "plum" }; + +template <typename T, typename R, typename P> + typename test_opr<T, R, P>::iter_type const + test_opr<T, R, P>::fruit_begin = test_iter<T,R,P>( fruit ); + +template <typename T, typename R, typename P> +typename test_opr<T, R, P>::iter_type const + test_opr<T, R, P>::fruit_end = test_iter<T,R,P>( fruit + fruit_length ); + + +// Main testing function +int +main() +{ + using std::string; + + typedef test_opr<string, string &, string *> test1_type; + typedef test_opr<string, string const &, string const *> test2_type; + + test1_type::master_test( "non-const string" ); + test2_type::master_test( "const string" ); + + return boost::report_errors(); +} + +// Tests for all of the operators added by random_access_iterator_helper +template <typename T, typename R, typename P> +void +test_opr<T, R, P>::master_test +( + char const name[] +) +{ + std::cout << "Doing test run for " << name << '.' << std::endl; + + post_increment_test(); + post_decrement_test(); + indirect_referral_test(); + offset_addition_test(); + reverse_offset_addition_test(); + offset_subtraction_test(); + comparison_test(); + indexing_test(); +} + +// Test post-increment +template <typename T, typename R, typename P> +void +test_opr<T, R, P>::post_increment_test +( +) +{ + std::cout << "\tDoing post-increment test." << std::endl; + + std::stringstream oss; + for ( iter_type i = fruit_begin ; i != fruit_end ; ) + { + oss << *i++ << ' '; + } + + BOOST_TEST( oss.str() == "apple orange pear peach grape plum "); +} + +// Test post-decrement +template <typename T, typename R, typename P> +void +test_opr<T, R, P>::post_decrement_test +( +) +{ + std::cout << "\tDoing post-decrement test." << std::endl; + + std::stringstream oss; + for ( iter_type i = fruit_end ; i != fruit_begin ; ) + { + i--; + oss << *i << ' '; + } + + BOOST_TEST( oss.str() == "plum grape peach pear orange apple "); +} + +// Test indirect structure referral +template <typename T, typename R, typename P> +void +test_opr<T, R, P>::indirect_referral_test +( +) +{ + std::cout << "\tDoing indirect reference test." << std::endl; + + std::stringstream oss; + for ( iter_type i = fruit_begin ; i != fruit_end ; ++i ) + { + oss << i->size() << ' '; + } + + BOOST_TEST( oss.str() == "5 6 4 5 5 4 "); +} + +// Test offset addition +template <typename T, typename R, typename P> +void +test_opr<T, R, P>::offset_addition_test +( +) +{ + std::cout << "\tDoing offset addition test." << std::endl; + + std::ptrdiff_t const two = 2; + std::stringstream oss; + for ( iter_type i = fruit_begin ; i != fruit_end ; i = i + two ) + { + oss << *i << ' '; + } + + BOOST_TEST( oss.str() == "apple pear grape "); +} + +// Test offset addition, in reverse order +template <typename T, typename R, typename P> +void +test_opr<T, R, P>::reverse_offset_addition_test +( +) +{ + std::cout << "\tDoing reverse offset addition test." << std::endl; + + std::ptrdiff_t const two = 2; + std::stringstream oss; + for ( iter_type i = fruit_begin ; i != fruit_end ; i = two + i ) + { + oss << *i << ' '; + } + + BOOST_TEST( oss.str() == "apple pear grape "); +} + +// Test offset subtraction +template <typename T, typename R, typename P> +void +test_opr<T, R, P>::offset_subtraction_test +( +) +{ + std::cout << "\tDoing offset subtraction test." << std::endl; + + std::ptrdiff_t const two = 2; + std::stringstream oss; + for ( iter_type i = fruit_end ; fruit_begin < i ; ) + { + i = i - two; + if ( (fruit_begin < i) || (fruit_begin == i) ) + { + oss << *i << ' '; + } + } + + BOOST_TEST( oss.str() == "grape pear apple "); +} + +// Test comparisons +template <typename T, typename R, typename P> +void +test_opr<T, R, P>::comparison_test +( +) +{ + using std::cout; + using std::ptrdiff_t; + + cout << "\tDoing comparison tests.\n\t\tPass:"; + + for ( iter_type i = fruit_begin ; i != fruit_end ; ++i ) + { + ptrdiff_t const i_offset = i - fruit_begin; + + cout << ' ' << *i << std::flush; + for ( iter_type j = fruit_begin ; j != fruit_end ; ++j ) + { + ptrdiff_t const j_offset = j - fruit_begin; + + BOOST_TEST( (i != j) == (i_offset != j_offset) ); + BOOST_TEST( (i > j) == (i_offset > j_offset) ); + BOOST_TEST( (i <= j) == (i_offset <= j_offset) ); + BOOST_TEST( (i >= j) == (i_offset >= j_offset) ); + } + } + cout << std::endl; +} + +// Test indexing +template <typename T, typename R, typename P> +void +test_opr<T, R, P>::indexing_test +( +) +{ + std::cout << "\tDoing indexing test." << std::endl; + + std::stringstream oss; + for ( std::size_t k = 0u ; k < fruit_length ; ++k ) + { + oss << fruit_begin[ k ] << ' '; + } + + BOOST_TEST( oss.str() == "apple orange pear peach grape plum "); +} diff --git a/src/boost/libs/utility/test/operators_test.cpp b/src/boost/libs/utility/test/operators_test.cpp new file mode 100644 index 00000000..6cf7a76c --- /dev/null +++ b/src/boost/libs/utility/test/operators_test.cpp @@ -0,0 +1,936 @@ +// Demonstrate and test boost/operators.hpp -------------------------------// + +// Copyright Beman Dawes 1999. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/utility for documentation. + +// Revision History +// 03 Apr 08 Added convertible_to_bool (Daniel Frey) +// 01 Oct 01 Added tests for "left" operators +// and new grouped operators. (Helmut Zeisel) +// 20 May 01 Output progress messages. Added tests for new operator +// templates. Updated random number generator. Changed tests to +// use Boost Test Tools library. (Daryle Walker) +// 04 Jun 00 Added regression test for a bug I found (David Abrahams) +// 17 Jun 00 Fix for broken compilers (Aleksey Gurtovoy) +// ?? ??? 00 Major update to randomly test all one- and two- argument forms by +// wrapping integral types and comparing the results of operations +// to the results for the raw types (David Abrahams) +// 12 Dec 99 Minor update, output confirmation message. +// 15 Nov 99 Initial version + +#include <boost/config.hpp> // for BOOST_MSVC +#include <boost/operators.hpp> // for the tested items +#include <boost/utility/detail/minstd_rand.hpp> // for boost::detail::minstd_rand +#include <boost/core/lightweight_test.hpp> + +#include <iostream> // for std::cout (std::endl indirectly) + + +namespace +{ + // avoiding a template version of true_value so as to not confuse VC++ + int true_value(int x) { return x; } + long true_value(long x) { return x; } + signed char true_value(signed char x) { return x; } + unsigned int true_value(unsigned int x) { return x; } + unsigned long true_value(unsigned long x) { return x; } + unsigned char true_value(unsigned char x) { return x; } + + // verify the minimum requirements for some operators + class convertible_to_bool + { + private: + bool _value; + + typedef bool convertible_to_bool::*unspecified_bool_type; + + void operator!() const; + + public: + convertible_to_bool( const bool value ) : _value( value ) {} + + operator unspecified_bool_type() const + { return _value ? &convertible_to_bool::_value : 0; } + }; + + // The use of operators<> here tended to obscure + // interactions with certain compiler bugs + template <class T> + class Wrapped1 + : boost::operators<Wrapped1<T> > + , boost::shiftable<Wrapped1<T> > + { + public: + explicit Wrapped1( T v = T() ) : _value(v) {} + T value() const { return _value; } + + convertible_to_bool operator<(const Wrapped1& x) const + { return _value < x._value; } + convertible_to_bool operator==(const Wrapped1& x) const + { return _value == x._value; } + + Wrapped1& operator+=(const Wrapped1& x) + { _value += x._value; return *this; } + Wrapped1& operator-=(const Wrapped1& x) + { _value -= x._value; return *this; } + Wrapped1& operator*=(const Wrapped1& x) + { _value *= x._value; return *this; } + Wrapped1& operator/=(const Wrapped1& x) + { _value /= x._value; return *this; } + Wrapped1& operator%=(const Wrapped1& x) + { _value %= x._value; return *this; } + Wrapped1& operator|=(const Wrapped1& x) + { _value |= x._value; return *this; } + Wrapped1& operator&=(const Wrapped1& x) + { _value &= x._value; return *this; } + Wrapped1& operator^=(const Wrapped1& x) + { _value ^= x._value; return *this; } + Wrapped1& operator<<=(const Wrapped1& x) + { _value <<= x._value; return *this; } + Wrapped1& operator>>=(const Wrapped1& x) + { _value >>= x._value; return *this; } + Wrapped1& operator++() { ++_value; return *this; } + Wrapped1& operator--() { --_value; return *this; } + + private: + T _value; + }; + template <class T> + T true_value(Wrapped1<T> x) { return x.value(); } + + template <class T, class U> + class Wrapped2 + : boost::operators<Wrapped2<T, U> > + , boost::operators2<Wrapped2<T, U>, U> + , boost::shiftable1<Wrapped2<T, U> + , boost::shiftable2<Wrapped2<T, U>, U > > + { + public: + explicit Wrapped2( T v = T() ) : _value(v) {} + T value() const { return _value; } + + convertible_to_bool operator<(const Wrapped2& x) const + { return _value < x._value; } + convertible_to_bool operator==(const Wrapped2& x) const + { return _value == x._value; } + + Wrapped2& operator+=(const Wrapped2& x) + { _value += x._value; return *this; } + Wrapped2& operator-=(const Wrapped2& x) + { _value -= x._value; return *this; } + Wrapped2& operator*=(const Wrapped2& x) + { _value *= x._value; return *this; } + Wrapped2& operator/=(const Wrapped2& x) + { _value /= x._value; return *this; } + Wrapped2& operator%=(const Wrapped2& x) + { _value %= x._value; return *this; } + Wrapped2& operator|=(const Wrapped2& x) + { _value |= x._value; return *this; } + Wrapped2& operator&=(const Wrapped2& x) + { _value &= x._value; return *this; } + Wrapped2& operator^=(const Wrapped2& x) + { _value ^= x._value; return *this; } + Wrapped2& operator<<=(const Wrapped2& x) + { _value <<= x._value; return *this; } + Wrapped2& operator>>=(const Wrapped2& x) + { _value >>= x._value; return *this; } + Wrapped2& operator++() { ++_value; return *this; } + Wrapped2& operator--() { --_value; return *this; } + + convertible_to_bool operator<(U u) const + { return _value < u; } + convertible_to_bool operator>(U u) const + { return _value > u; } + convertible_to_bool operator==(U u) const + { return _value == u; } + + Wrapped2& operator+=(U u) { _value += u; return *this; } + Wrapped2& operator-=(U u) { _value -= u; return *this; } + Wrapped2& operator*=(U u) { _value *= u; return *this; } + Wrapped2& operator/=(U u) { _value /= u; return *this; } + Wrapped2& operator%=(U u) { _value %= u; return *this; } + Wrapped2& operator|=(U u) { _value |= u; return *this; } + Wrapped2& operator&=(U u) { _value &= u; return *this; } + Wrapped2& operator^=(U u) { _value ^= u; return *this; } + Wrapped2& operator<<=(U u) { _value <<= u; return *this; } + Wrapped2& operator>>=(U u) { _value >>= u; return *this; } + + private: + T _value; + }; + template <class T, class U> + T true_value(Wrapped2<T,U> x) { return x.value(); } + + template <class T> + class Wrapped3 + : boost::equivalent<Wrapped3<T> > + , boost::partially_ordered<Wrapped3<T> > + , boost::equality_comparable<Wrapped3<T> > + { + public: + explicit Wrapped3( T v = T() ) : _value(v) {} + T value() const { return _value; } + + convertible_to_bool operator<(const Wrapped3& x) const + { return _value < x._value; } + + private: + T _value; + }; + template <class T> + T true_value(Wrapped3<T> x) { return x.value(); } + + template <class T, class U> + class Wrapped4 + : boost::equality_comparable1<Wrapped4<T, U> + , boost::equivalent1<Wrapped4<T, U> + , boost::partially_ordered1<Wrapped4<T, U> > > > + , boost::partially_ordered2<Wrapped4<T, U>, U + , boost::equivalent2<Wrapped4<T, U>, U + , boost::equality_comparable2<Wrapped4<T, U>, U> > > + { + public: + explicit Wrapped4( T v = T() ) : _value(v) {} + T value() const { return _value; } + + convertible_to_bool operator<(const Wrapped4& x) const + { return _value < x._value; } + + convertible_to_bool operator<(U u) const + { return _value < u; } + convertible_to_bool operator>(U u) const + { return _value > u; } + + private: + T _value; + }; + template <class T, class U> + T true_value(Wrapped4<T,U> x) { return x.value(); } + + // U must be convertible to T + template <class T, class U> + class Wrapped5 + : boost::ordered_field_operators2<Wrapped5<T, U>, U> + , boost::ordered_field_operators1<Wrapped5<T, U> > + { + public: + explicit Wrapped5( T v = T() ) : _value(v) {} + + // Conversion from U to Wrapped5<T,U> + Wrapped5(U u) : _value(u) {} + + T value() const { return _value; } + + convertible_to_bool operator<(const Wrapped5& x) const + { return _value < x._value; } + convertible_to_bool operator<(U u) const + { return _value < u; } + convertible_to_bool operator>(U u) const + { return _value > u; } + convertible_to_bool operator==(const Wrapped5& u) const + { return _value == u._value; } + convertible_to_bool operator==(U u) const + { return _value == u; } + + Wrapped5& operator/=(const Wrapped5& u) { _value /= u._value; return *this;} + Wrapped5& operator/=(U u) { _value /= u; return *this;} + Wrapped5& operator*=(const Wrapped5& u) { _value *= u._value; return *this;} + Wrapped5& operator*=(U u) { _value *= u; return *this;} + Wrapped5& operator-=(const Wrapped5& u) { _value -= u._value; return *this;} + Wrapped5& operator-=(U u) { _value -= u; return *this;} + Wrapped5& operator+=(const Wrapped5& u) { _value += u._value; return *this;} + Wrapped5& operator+=(U u) { _value += u; return *this;} + + private: + T _value; + }; + template <class T, class U> + T true_value(Wrapped5<T,U> x) { return x.value(); } + + // U must be convertible to T + template <class T, class U> + class Wrapped6 + : boost::ordered_euclidean_ring_operators2<Wrapped6<T, U>, U> + , boost::ordered_euclidean_ring_operators1<Wrapped6<T, U> > + { + public: + explicit Wrapped6( T v = T() ) : _value(v) {} + + // Conversion from U to Wrapped6<T,U> + Wrapped6(U u) : _value(u) {} + + T value() const { return _value; } + + convertible_to_bool operator<(const Wrapped6& x) const + { return _value < x._value; } + convertible_to_bool operator<(U u) const + { return _value < u; } + convertible_to_bool operator>(U u) const + { return _value > u; } + convertible_to_bool operator==(const Wrapped6& u) const + { return _value == u._value; } + convertible_to_bool operator==(U u) const + { return _value == u; } + + Wrapped6& operator%=(const Wrapped6& u) { _value %= u._value; return *this;} + Wrapped6& operator%=(U u) { _value %= u; return *this;} + Wrapped6& operator/=(const Wrapped6& u) { _value /= u._value; return *this;} + Wrapped6& operator/=(U u) { _value /= u; return *this;} + Wrapped6& operator*=(const Wrapped6& u) { _value *= u._value; return *this;} + Wrapped6& operator*=(U u) { _value *= u; return *this;} + Wrapped6& operator-=(const Wrapped6& u) { _value -= u._value; return *this;} + Wrapped6& operator-=(U u) { _value -= u; return *this;} + Wrapped6& operator+=(const Wrapped6& u) { _value += u._value; return *this;} + Wrapped6& operator+=(U u) { _value += u; return *this;} + + private: + T _value; + }; + template <class T, class U> + T true_value(Wrapped6<T,U> x) { return x.value(); } + + // MyInt uses only the single template-argument form of all_operators<> + typedef Wrapped1<int> MyInt; + + typedef Wrapped2<long, long> MyLong; + + typedef Wrapped3<signed char> MyChar; + + typedef Wrapped4<short, short> MyShort; + + typedef Wrapped5<double, int> MyDoubleInt; + + typedef Wrapped6<long, int> MyLongInt; + + template <class X1, class Y1, class X2, class Y2> + void sanity_check(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + BOOST_TEST( true_value(y1) == true_value(y2) ); + BOOST_TEST( true_value(x1) == true_value(x2) ); + } + + template <class X1, class Y1, class X2, class Y2> + void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + BOOST_TEST( static_cast<bool>(x1 < y1) == static_cast<bool>(x2 < y2) ); + BOOST_TEST( static_cast<bool>(x1 <= y1) == static_cast<bool>(x2 <= y2) ); + BOOST_TEST( static_cast<bool>(x1 >= y1) == static_cast<bool>(x2 >= y2) ); + BOOST_TEST( static_cast<bool>(x1 > y1) == static_cast<bool>(x2 > y2) ); + } + + template <class X1, class Y1, class X2, class Y2> + void test_less_than_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + test_less_than_comparable_aux( x1, y1, x2, y2 ); + test_less_than_comparable_aux( y1, x1, y2, x2 ); + } + + template <class X1, class Y1, class X2, class Y2> + void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + BOOST_TEST( static_cast<bool>(x1 == y1) == static_cast<bool>(x2 == y2) ); + BOOST_TEST( static_cast<bool>(x1 != y1) == static_cast<bool>(x2 != y2) ); + } + + template <class X1, class Y1, class X2, class Y2> + void test_equality_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + test_equality_comparable_aux( x1, y1, x2, y2 ); + test_equality_comparable_aux( y1, x1, y2, x2 ); + } + + template <class X1, class Y1, class X2, class Y2> + void test_multipliable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + BOOST_TEST( (x1 * y1).value() == (x2 * y2) ); + } + + template <class X1, class Y1, class X2, class Y2> + void test_multipliable(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + test_multipliable_aux( x1, y1, x2, y2 ); + test_multipliable_aux( y1, x1, y2, x2 ); + } + + template <class A, class B> + void test_value_equality(A a, B b) + { + BOOST_TEST(a.value() == b); + } + +#define TEST_OP_R(op) test_value_equality(x1 op y1, x2 op y2) +#define TEST_OP_L(op) test_value_equality(y1 op x1, y2 op x2) + + template <class X1, class Y1, class X2, class Y2> + void test_addable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + TEST_OP_R(+); + } + + template <class X1, class Y1, class X2, class Y2> + void test_addable(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + test_addable_aux( x1, y1, x2, y2 ); + test_addable_aux( y1, x1, y2, x2 ); + } + + template <class X1, class Y1, class X2, class Y2> + void test_subtractable(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + TEST_OP_R(-); + } + + template <class X1, class Y1, class X2, class Y2> + void test_subtractable_left(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + TEST_OP_L(-); + } + + template <class X1, class Y1, class X2, class Y2> + void test_dividable(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + if ( y2 != 0 ) + TEST_OP_R(/); + } + + template <class X1, class Y1, class X2, class Y2> + void test_dividable_left(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + if ( x2 != 0 ) + TEST_OP_L(/); + } + + template <class X1, class Y1, class X2, class Y2> + void test_modable(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + if ( y2 != 0 ) + TEST_OP_R(%); + } + + template <class X1, class Y1, class X2, class Y2> + void test_modable_left(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + if ( x2 != 0 ) + TEST_OP_L(%); + } + + template <class X1, class Y1, class X2, class Y2> + void test_xorable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + TEST_OP_R(^); + } + + template <class X1, class Y1, class X2, class Y2> + void test_xorable(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + test_xorable_aux( x1, y1, x2, y2 ); + test_xorable_aux( y1, x1, y2, x2 ); + } + + template <class X1, class Y1, class X2, class Y2> + void test_andable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + TEST_OP_R(&); + } + + template <class X1, class Y1, class X2, class Y2> + void test_andable(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + test_andable_aux( x1, y1, x2, y2 ); + test_andable_aux( y1, x1, y2, x2 ); + } + + template <class X1, class Y1, class X2, class Y2> + void test_orable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + TEST_OP_R(|); + } + + template <class X1, class Y1, class X2, class Y2> + void test_orable(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + test_orable_aux( x1, y1, x2, y2 ); + test_orable_aux( y1, x1, y2, x2 ); + } + + template <class X1, class Y1, class X2, class Y2> + void test_left_shiftable(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + TEST_OP_R(<<); + } + + template <class X1, class Y1, class X2, class Y2> + void test_right_shiftable(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + sanity_check( x1, y1, x2, y2 ); + TEST_OP_R(>>); + } + + template <class X1, class X2> + void test_incrementable(X1 x1, X2 x2) + { + sanity_check( x1, x1, x2, x2 ); + BOOST_TEST( (x1++).value() == x2++ ); + BOOST_TEST( x1.value() == x2 ); + } + + template <class X1, class X2> + void test_decrementable(X1 x1, X2 x2) + { + sanity_check( x1, x1, x2, x2 ); + BOOST_TEST( (x1--).value() == x2-- ); + BOOST_TEST( x1.value() == x2 ); + } + + template <class X1, class Y1, class X2, class Y2> + void test_all(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + test_less_than_comparable( x1, y1, x2, y2 ); + test_equality_comparable( x1, y1, x2, y2 ); + test_multipliable( x1, y1, x2, y2 ); + test_addable( x1, y1, x2, y2 ); + test_subtractable( x1, y1, x2, y2 ); + test_dividable( x1, y1, x2, y2 ); + test_modable( x1, y1, x2, y2 ); + test_xorable( x1, y1, x2, y2 ); + test_andable( x1, y1, x2, y2 ); + test_orable( x1, y1, x2, y2 ); + test_left_shiftable( x1, y1, x2, y2 ); + test_right_shiftable( x1, y1, x2, y2 ); + test_incrementable( x1, x2 ); + test_decrementable( x1, x2 ); + } + + template <class X1, class Y1, class X2, class Y2> + void test_left(X1 x1, Y1 y1, X2 x2, Y2 y2) + { + test_subtractable_left( x1, y1, x2, y2 ); + test_dividable_left( x1, y1, x2, y2 ); + test_modable_left( x1, y1, x2, y2 ); + } + + template <class Big, class Small> + struct tester + { + void operator()(boost::detail::minstd_rand& randomizer) const + { + Big b1 = Big( randomizer() ); + Big b2 = Big( randomizer() ); + Small s = Small( randomizer() ); + + test_all( Wrapped1<Big>(b1), Wrapped1<Big>(b2), b1, b2 ); + test_all( Wrapped2<Big, Small>(b1), s, b1, s ); + } + }; + + template <class Big, class Small> + struct tester_left + { + void operator()(boost::detail::minstd_rand& randomizer) const + { + Big b1 = Big( randomizer() ); + Small s = Small( randomizer() ); + + test_left( Wrapped6<Big, Small>(b1), s, b1, s ); + } + }; + + // added as a regression test. We had a bug which this uncovered. + struct Point + : boost::addable<Point + , boost::subtractable<Point> > + { + Point( int h, int v ) : h(h), v(v) {} + Point() :h(0), v(0) {} + const Point& operator+=( const Point& rhs ) + { h += rhs.h; v += rhs.v; return *this; } + const Point& operator-=( const Point& rhs ) + { h -= rhs.h; v -= rhs.v; return *this; } + + int h; + int v; + }; + +} // unnamed namespace + + +// workaround for MSVC bug; for some reasons the compiler doesn't instantiate +// inherited operator templates at the moment it must, so the following +// explicit instantiations force it to do that. + +#if defined(BOOST_MSVC) && (_MSC_VER < 1300) +template Wrapped1<int>; +template Wrapped1<long>; +template Wrapped1<unsigned int>; +template Wrapped1<unsigned long>; + +template Wrapped2<int, int>; +template Wrapped2<int, signed char>; +template Wrapped2<long, signed char>; +template Wrapped2<long, int>; +template Wrapped2<long, long>; +template Wrapped2<unsigned int, unsigned int>; +template Wrapped2<unsigned int, unsigned char>; +template Wrapped2<unsigned long, unsigned int>; +template Wrapped2<unsigned long, unsigned char>; +template Wrapped2<unsigned long, unsigned long>; + +template Wrapped6<long, int>; +template Wrapped6<long, signed char>; +template Wrapped6<int, signed char>; +template Wrapped6<unsigned long, unsigned int>; +template Wrapped6<unsigned long, unsigned char>; +template Wrapped6<unsigned int, unsigned char>; +#endif + +#define PRIVATE_EXPR_TEST(e, t) BOOST_TEST( ((e), (t)) ) + +int +main() +{ + using std::cout; + using std::endl; + + // Regression test. + Point x; + x = x + Point(3, 4); + x = x - Point(3, 4); + + cout << "Created point, and operated on it." << endl; + + for (int n = 0; n < 1000; ++n) // was 10,000 but took too long (Beman) + { + boost::detail::minstd_rand r; + tester<long, int>()(r); + tester<long, signed char>()(r); + tester<long, long>()(r); + tester<int, int>()(r); + tester<int, signed char>()(r); + + tester<unsigned long, unsigned int>()(r); + tester<unsigned long, unsigned char>()(r); + tester<unsigned long, unsigned long>()(r); + tester<unsigned int, unsigned int>()(r); + tester<unsigned int, unsigned char>()(r); + + tester_left<long, int>()(r); + tester_left<long, signed char>()(r); + tester_left<int, signed char>()(r); + + tester_left<unsigned long, unsigned int>()(r); + tester_left<unsigned long, unsigned char>()(r); + tester_left<unsigned int, unsigned char>()(r); + } + + cout << "Did random tester loop." << endl; + + MyInt i1(1); + MyInt i2(2); + MyInt i; + + BOOST_TEST( i1.value() == 1 ); + BOOST_TEST( i2.value() == 2 ); + BOOST_TEST( i.value() == 0 ); + + cout << "Created MyInt objects.\n"; + + PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) ); + + BOOST_TEST( static_cast<bool>(i2 == i) ); + BOOST_TEST( static_cast<bool>(i1 != i2) ); + BOOST_TEST( static_cast<bool>(i1 < i2) ); + BOOST_TEST( static_cast<bool>(i1 <= i2) ); + BOOST_TEST( static_cast<bool>(i <= i2) ); + BOOST_TEST( static_cast<bool>(i2 > i1) ); + BOOST_TEST( static_cast<bool>(i2 >= i1) ); + BOOST_TEST( static_cast<bool>(i2 >= i) ); + + PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) ); + PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) ); + PRIVATE_EXPR_TEST( (i = i - i1), (i.value() == 4) ); + PRIVATE_EXPR_TEST( (i = i * i2), (i.value() == 8) ); + PRIVATE_EXPR_TEST( (i = i / i2), (i.value() == 4) ); + PRIVATE_EXPR_TEST( (i = i % ( i - i1 )), (i.value() == 1) ); + PRIVATE_EXPR_TEST( (i = i2 + i2), (i.value() == 4) ); + PRIVATE_EXPR_TEST( (i = i1 | i2 | i), (i.value() == 7) ); + PRIVATE_EXPR_TEST( (i = i & i2), (i.value() == 2) ); + PRIVATE_EXPR_TEST( (i = i + i1), (i.value() == 3) ); + PRIVATE_EXPR_TEST( (i = i ^ i1), (i.value() == 2) ); + PRIVATE_EXPR_TEST( (i = ( i + i1 ) * ( i2 | i1 )), (i.value() == 9) ); + + PRIVATE_EXPR_TEST( (i = i1 << i2), (i.value() == 4) ); + PRIVATE_EXPR_TEST( (i = i2 >> i1), (i.value() == 1) ); + + cout << "Performed tests on MyInt objects.\n"; + + MyLong j1(1); + MyLong j2(2); + MyLong j; + + BOOST_TEST( j1.value() == 1 ); + BOOST_TEST( j2.value() == 2 ); + BOOST_TEST( j.value() == 0 ); + + cout << "Created MyLong objects.\n"; + + PRIVATE_EXPR_TEST( (j = j2), (j.value() == 2) ); + + BOOST_TEST( static_cast<bool>(j2 == j) ); + BOOST_TEST( static_cast<bool>(2 == j) ); + BOOST_TEST( static_cast<bool>(j2 == 2) ); + BOOST_TEST( static_cast<bool>(j == j2) ); + BOOST_TEST( static_cast<bool>(j1 != j2) ); + BOOST_TEST( static_cast<bool>(j1 != 2) ); + BOOST_TEST( static_cast<bool>(1 != j2) ); + BOOST_TEST( static_cast<bool>(j1 < j2) ); + BOOST_TEST( static_cast<bool>(1 < j2) ); + BOOST_TEST( static_cast<bool>(j1 < 2) ); + BOOST_TEST( static_cast<bool>(j1 <= j2) ); + BOOST_TEST( static_cast<bool>(1 <= j2) ); + BOOST_TEST( static_cast<bool>(j1 <= j) ); + BOOST_TEST( static_cast<bool>(j <= j2) ); + BOOST_TEST( static_cast<bool>(2 <= j2) ); + BOOST_TEST( static_cast<bool>(j <= 2) ); + BOOST_TEST( static_cast<bool>(j2 > j1) ); + BOOST_TEST( static_cast<bool>(2 > j1) ); + BOOST_TEST( static_cast<bool>(j2 > 1) ); + BOOST_TEST( static_cast<bool>(j2 >= j1) ); + BOOST_TEST( static_cast<bool>(2 >= j1) ); + BOOST_TEST( static_cast<bool>(j2 >= 1) ); + BOOST_TEST( static_cast<bool>(j2 >= j) ); + BOOST_TEST( static_cast<bool>(2 >= j) ); + BOOST_TEST( static_cast<bool>(j2 >= 2) ); + + BOOST_TEST( static_cast<bool>((j1 + 2) == 3) ); + BOOST_TEST( static_cast<bool>((1 + j2) == 3) ); + PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) ); + + BOOST_TEST( static_cast<bool>((j + 2) == 5) ); + BOOST_TEST( static_cast<bool>((3 + j2) == 5) ); + PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) ); + + BOOST_TEST( static_cast<bool>((j - 1) == 4) ); + PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) ); + + BOOST_TEST( static_cast<bool>((j * 2) == 8) ); + BOOST_TEST( static_cast<bool>((4 * j2) == 8) ); + PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) ); + + BOOST_TEST( static_cast<bool>((j / 2) == 4) ); + PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) ); + + BOOST_TEST( static_cast<bool>((j % 3) == 1) ); + PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) ); + + PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) ); + + BOOST_TEST( static_cast<bool>((1 | j2 | j) == 7) ); + BOOST_TEST( static_cast<bool>((j1 | 2 | j) == 7) ); + BOOST_TEST( static_cast<bool>((j1 | j2 | 4) == 7) ); + PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) ); + + BOOST_TEST( static_cast<bool>((7 & j2) == 2) ); + BOOST_TEST( static_cast<bool>((j & 2) == 2) ); + PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) ); + + PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) ); + + BOOST_TEST( static_cast<bool>((3 ^ j1) == 2) ); + BOOST_TEST( static_cast<bool>((j ^ 1) == 2) ); + PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) ); + + PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) ); + + BOOST_TEST( static_cast<bool>((j1 << 2) == 4) ); + BOOST_TEST( static_cast<bool>((j2 << 1) == 4) ); + PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) ); + + BOOST_TEST( static_cast<bool>((j >> 2) == 1) ); + BOOST_TEST( static_cast<bool>((j2 >> 1) == 1) ); + PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) ); + + cout << "Performed tests on MyLong objects.\n"; + + MyChar k1(1); + MyChar k2(2); + MyChar k; + + BOOST_TEST( k1.value() == 1 ); + BOOST_TEST( k2.value() == 2 ); + BOOST_TEST( k.value() == 0 ); + + cout << "Created MyChar objects.\n"; + + PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) ); + + BOOST_TEST( static_cast<bool>(k2 == k) ); + BOOST_TEST( static_cast<bool>(k1 != k2) ); + BOOST_TEST( static_cast<bool>(k1 < k2) ); + BOOST_TEST( static_cast<bool>(k1 <= k2) ); + BOOST_TEST( static_cast<bool>(k <= k2) ); + BOOST_TEST( static_cast<bool>(k2 > k1) ); + BOOST_TEST( static_cast<bool>(k2 >= k1) ); + BOOST_TEST( static_cast<bool>(k2 >= k) ); + + cout << "Performed tests on MyChar objects.\n"; + + MyShort l1(1); + MyShort l2(2); + MyShort l; + + BOOST_TEST( l1.value() == 1 ); + BOOST_TEST( l2.value() == 2 ); + BOOST_TEST( l.value() == 0 ); + + cout << "Created MyShort objects.\n"; + + PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) ); + + BOOST_TEST( static_cast<bool>(l2 == l) ); + BOOST_TEST( static_cast<bool>(2 == l) ); + BOOST_TEST( static_cast<bool>(l2 == 2) ); + BOOST_TEST( static_cast<bool>(l == l2) ); + BOOST_TEST( static_cast<bool>(l1 != l2) ); + BOOST_TEST( static_cast<bool>(l1 != 2) ); + BOOST_TEST( static_cast<bool>(1 != l2) ); + BOOST_TEST( static_cast<bool>(l1 < l2) ); + BOOST_TEST( static_cast<bool>(1 < l2) ); + BOOST_TEST( static_cast<bool>(l1 < 2) ); + BOOST_TEST( static_cast<bool>(l1 <= l2) ); + BOOST_TEST( static_cast<bool>(1 <= l2) ); + BOOST_TEST( static_cast<bool>(l1 <= l) ); + BOOST_TEST( static_cast<bool>(l <= l2) ); + BOOST_TEST( static_cast<bool>(2 <= l2) ); + BOOST_TEST( static_cast<bool>(l <= 2) ); + BOOST_TEST( static_cast<bool>(l2 > l1) ); + BOOST_TEST( static_cast<bool>(2 > l1) ); + BOOST_TEST( static_cast<bool>(l2 > 1) ); + BOOST_TEST( static_cast<bool>(l2 >= l1) ); + BOOST_TEST( static_cast<bool>(2 >= l1) ); + BOOST_TEST( static_cast<bool>(l2 >= 1) ); + BOOST_TEST( static_cast<bool>(l2 >= l) ); + BOOST_TEST( static_cast<bool>(2 >= l) ); + BOOST_TEST( static_cast<bool>(l2 >= 2) ); + + cout << "Performed tests on MyShort objects.\n"; + + MyDoubleInt di1(1); + MyDoubleInt di2(2.); + MyDoubleInt half(0.5); + MyDoubleInt di; + MyDoubleInt tmp; + + BOOST_TEST( di1.value() == 1 ); + BOOST_TEST( di2.value() == 2 ); + BOOST_TEST( di2.value() == 2 ); + BOOST_TEST( di.value() == 0 ); + + cout << "Created MyDoubleInt objects.\n"; + + PRIVATE_EXPR_TEST( (di = di2), (di.value() == 2) ); + + BOOST_TEST( static_cast<bool>(di2 == di) ); + BOOST_TEST( static_cast<bool>(2 == di) ); + BOOST_TEST( static_cast<bool>(di == 2) ); + BOOST_TEST( static_cast<bool>(di1 < di2) ); + BOOST_TEST( static_cast<bool>(1 < di2) ); + BOOST_TEST( static_cast<bool>(di1 <= di2) ); + BOOST_TEST( static_cast<bool>(1 <= di2) ); + BOOST_TEST( static_cast<bool>(di2 > di1) ); + BOOST_TEST( static_cast<bool>(di2 > 1) ); + BOOST_TEST( static_cast<bool>(di2 >= di1) ); + BOOST_TEST( static_cast<bool>(di2 >= 1) ); + BOOST_TEST( static_cast<bool>(di1 / di2 == half) ); + BOOST_TEST( static_cast<bool>(di1 / 2 == half) ); + BOOST_TEST( static_cast<bool>(1 / di2 == half) ); + PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=2) == half) ); + PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=di2) == half) ); + BOOST_TEST( static_cast<bool>(di1 * di2 == di2) ); + BOOST_TEST( static_cast<bool>(di1 * 2 == di2) ); + BOOST_TEST( static_cast<bool>(1 * di2 == di2) ); + PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=2) == di2) ); + PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=di2) == di2) ); + BOOST_TEST( static_cast<bool>(di2 - di1 == di1) ); + BOOST_TEST( static_cast<bool>(di2 - 1 == di1) ); + BOOST_TEST( static_cast<bool>(2 - di1 == di1) ); + PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=1) == di1) ); + PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=di1) == di1) ); + BOOST_TEST( static_cast<bool>(di1 + di1 == di2) ); + BOOST_TEST( static_cast<bool>(di1 + 1 == di2) ); + BOOST_TEST( static_cast<bool>(1 + di1 == di2) ); + PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=1) == di2) ); + PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=di1) == di2) ); + + cout << "Performed tests on MyDoubleInt objects.\n"; + + MyLongInt li1(1); + MyLongInt li2(2); + MyLongInt li; + MyLongInt tmp2; + + BOOST_TEST( li1.value() == 1 ); + BOOST_TEST( li2.value() == 2 ); + BOOST_TEST( li.value() == 0 ); + + cout << "Created MyLongInt objects.\n"; + + PRIVATE_EXPR_TEST( (li = li2), (li.value() == 2) ); + + BOOST_TEST( static_cast<bool>(li2 == li) ); + BOOST_TEST( static_cast<bool>(2 == li) ); + BOOST_TEST( static_cast<bool>(li == 2) ); + BOOST_TEST( static_cast<bool>(li1 < li2) ); + BOOST_TEST( static_cast<bool>(1 < li2) ); + BOOST_TEST( static_cast<bool>(li1 <= li2) ); + BOOST_TEST( static_cast<bool>(1 <= li2) ); + BOOST_TEST( static_cast<bool>(li2 > li1) ); + BOOST_TEST( static_cast<bool>(li2 > 1) ); + BOOST_TEST( static_cast<bool>(li2 >= li1) ); + BOOST_TEST( static_cast<bool>(li2 >= 1) ); + BOOST_TEST( static_cast<bool>(li1 % li2 == li1) ); + BOOST_TEST( static_cast<bool>(li1 % 2 == li1) ); + BOOST_TEST( static_cast<bool>(1 % li2 == li1) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=2) == li1) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=li2) == li1) ); + BOOST_TEST( static_cast<bool>(li1 / li2 == 0) ); + BOOST_TEST( static_cast<bool>(li1 / 2 == 0) ); + BOOST_TEST( static_cast<bool>(1 / li2 == 0) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=2) == 0) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=li2) == 0) ); + BOOST_TEST( static_cast<bool>(li1 * li2 == li2) ); + BOOST_TEST( static_cast<bool>(li1 * 2 == li2) ); + BOOST_TEST( static_cast<bool>(1 * li2 == li2) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=2) == li2) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=li2) == li2) ); + BOOST_TEST( static_cast<bool>(li2 - li1 == li1) ); + BOOST_TEST( static_cast<bool>(li2 - 1 == li1) ); + BOOST_TEST( static_cast<bool>(2 - li1 == li1) ); + PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=1) == li1) ); + PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=li1) == li1) ); + BOOST_TEST( static_cast<bool>(li1 + li1 == li2) ); + BOOST_TEST( static_cast<bool>(li1 + 1 == li2) ); + BOOST_TEST( static_cast<bool>(1 + li1 == li2) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=1) == li2) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=li1) == li2) ); + + cout << "Performed tests on MyLongInt objects.\n"; + + return boost::report_errors(); +} diff --git a/src/boost/libs/utility/test/ostream_string_test.cpp b/src/boost/libs/utility/test/ostream_string_test.cpp new file mode 100644 index 00000000..e6145b3a --- /dev/null +++ b/src/boost/libs/utility/test/ostream_string_test.cpp @@ -0,0 +1,136 @@ +/* +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/core/lightweight_test.hpp> +#include <boost/utility/ostream_string.hpp> +#include <sstream> +#include <string> + +int main() +{ + { + std::ostringstream os; + os.width(1); + os.fill('.'); + os.setf(std::ios_base::left, std::ios_base::adjustfield); + boost::ostream_string(os, "xy", 2); + BOOST_TEST(os.good()); + BOOST_TEST(os.width() == 0); + BOOST_TEST(os.str() == "xy"); + } + { + std::wostringstream os; + os.width(1); + os.fill('.'); + os.setf(std::ios_base::left, std::ios_base::adjustfield); + boost::ostream_string(os, L"xy", 2); + BOOST_TEST(os.good()); + BOOST_TEST(os.width() == 0); + BOOST_TEST(os.str() == L"xy"); + } + { + std::ostringstream os; + os.width(1); + os.fill('.'); + os.setf(std::ios_base::right, std::ios_base::adjustfield); + boost::ostream_string(os, "xy", 2); + BOOST_TEST(os.good()); + BOOST_TEST(os.width() == 0); + BOOST_TEST(os.str() == "xy"); + } + { + std::wostringstream os; + os.width(1); + os.fill('.'); + os.setf(std::ios_base::right, std::ios_base::adjustfield); + boost::ostream_string(os, L"xy", 2); + BOOST_TEST(os.good()); + BOOST_TEST(os.width() == 0); + BOOST_TEST(os.str() == L"xy"); + } + { + std::ostringstream os; + os.width(4); + os.fill('.'); + os.setf(std::ios_base::left, std::ios_base::adjustfield); + boost::ostream_string(os, "xy", 2); + BOOST_TEST(os.good()); + BOOST_TEST(os.width() == 0); + BOOST_TEST(os.str() == "xy.."); + } + { + std::wostringstream os; + os.width(4); + os.fill(L'.'); + os.setf(std::ios_base::left, std::ios_base::adjustfield); + boost::ostream_string(os, L"xy", 2); + BOOST_TEST(os.good()); + BOOST_TEST(os.width() == 0); + BOOST_TEST(os.str() == L"xy.."); + } + { + std::ostringstream os; + os.width(4); + os.fill('.'); + os.setf(std::ios_base::right, std::ios_base::adjustfield); + boost::ostream_string(os, "xy", 2); + BOOST_TEST(os.good()); + BOOST_TEST(os.width() == 0); + BOOST_TEST(os.str() == "..xy"); + } + { + std::wostringstream os; + os.width(4); + os.fill(L'.'); + os.setf(std::ios_base::right, std::ios_base::adjustfield); + boost::ostream_string(os, L"xy", 2); + BOOST_TEST(os.good()); + BOOST_TEST(os.width() == 0); + BOOST_TEST(os.str() == L"..xy"); + } + { + std::ostringstream os; + os.width(12); + os.fill('.'); + os.setf(std::ios_base::left, std::ios_base::adjustfield); + boost::ostream_string(os, "xy", 2); + BOOST_TEST(os.good()); + BOOST_TEST(os.width() == 0); + BOOST_TEST(os.str() == "xy.........."); + } + { + std::wostringstream os; + os.width(12); + os.fill(L'.'); + os.setf(std::ios_base::left, std::ios_base::adjustfield); + boost::ostream_string(os, L"xy", 2); + BOOST_TEST(os.good()); + BOOST_TEST(os.width() == 0); + BOOST_TEST(os.str() == L"xy.........."); + } + { + std::ostringstream os; + os.width(12); + os.fill('.'); + os.setf(std::ios_base::right, std::ios_base::adjustfield); + boost::ostream_string(os, "xy", 2); + BOOST_TEST(os.good()); + BOOST_TEST(os.width() == 0); + BOOST_TEST(os.str() == "..........xy"); + } + { + std::wostringstream os; + os.width(12); + os.fill(L'.'); + os.setf(std::ios_base::right, std::ios_base::adjustfield); + boost::ostream_string(os, L"xy", 2); + BOOST_TEST(os.good()); + BOOST_TEST(os.width() == 0); + BOOST_TEST(os.str() == L"..........xy"); + } + return boost::report_errors(); +} diff --git a/src/boost/libs/utility/test/result_of_test.cpp b/src/boost/libs/utility/test/result_of_test.cpp new file mode 100644 index 00000000..290043b3 --- /dev/null +++ b/src/boost/libs/utility/test/result_of_test.cpp @@ -0,0 +1,322 @@ +// Boost result_of library + +// Copyright Douglas Gregor 2003-2004. 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) + +// Examples: +// To run the default test: +// $ cd libs/utility/test && bjam +// To test decltype on g++ 2.7: +// $ cd libs/utility/test && bjam cxxflags="-std=c++11 -D BOOST_RESULT_OF_USE_DECLTYPE" + +#include <boost/config.hpp> + +// For more information, see http://www.boost.org/libs/utility +#include <boost/utility/result_of.hpp> +#include <utility> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +struct int_result_type +{ + typedef int result_type; + result_type operator()(float); +}; + +struct int_result_of +{ + template<typename F> struct result { typedef int type; }; + result<int_result_of(double)>::type operator()(double); + result<const int_result_of(double)>::type operator()(double) const; + result<int_result_of()>::type operator()(); + result<volatile int_result_of()>::type operator()() volatile; +}; + +struct int_result_type_and_float_result_of_and_char_return +{ + typedef int result_type; + template<typename F> struct result { typedef float type; }; + char operator()(char); +}; + +template<typename T> +struct int_result_type_template +{ + typedef int result_type; + result_type operator()(float); +}; + +template<typename T> +struct int_result_of_template +{ + template<typename F> struct result; + template<typename This, typename That> struct result<This(That)> { typedef int type; }; + typename result<int_result_of_template<T>(double)>::type operator()(double); + typename result<const int_result_of_template<T>(double)>::type operator()(double) const; + typename result<int_result_of_template<T>(double)>::type operator()(); + typename result<volatile int_result_of_template<T>(double)>::type operator()() volatile; +}; + +template<typename T> +struct int_result_type_and_float_result_of_and_char_return_template +{ + typedef int result_type; + template<typename F> struct result; + template<typename This, typename That> struct result<This(That)> { typedef float type; }; + char operator()(char); +}; + +template<typename T> +struct cv_overload_check {}; + +struct result_of_member_function_template +{ + template<typename F> struct result; + + template<typename This, typename That> struct result<This(That)> { typedef That type; }; + template<class T> typename result<result_of_member_function_template(T)>::type operator()(T); + + template<typename This, typename That> struct result<const This(That)> { typedef cv_overload_check<const That> type; }; + template<class T> typename result<const result_of_member_function_template(T)>::type operator()(T) const; + + template<typename This, typename That> struct result<volatile This(That)> { typedef cv_overload_check<volatile That> type; }; + template<class T> typename result<volatile result_of_member_function_template(T)>::type operator()(T) volatile; + + template<typename This, typename That> struct result<const volatile This(That)> { typedef cv_overload_check<const volatile That> type; }; + template<class T> typename result<const volatile result_of_member_function_template(T)>::type operator()(T) const volatile; + + template<typename This, typename That> struct result<This(That &, That)> { typedef That & type; }; + template<class T> typename result<result_of_member_function_template(T &, T)>::type operator()(T &, T); + + template<typename This, typename That> struct result<This(That const &, That)> { typedef That const & type; }; + template<class T> typename result<result_of_member_function_template(T const &, T)>::type operator()(T const &, T); + + template<typename This, typename That> struct result<This(That volatile &, That)> { typedef That volatile & type; }; + template<class T> typename result<result_of_member_function_template(T volatile &, T)>::type operator()(T volatile &, T); + + template<typename This, typename That> struct result<This(That const volatile &, That)> { typedef That const volatile & type; }; + template<class T> typename result<result_of_member_function_template(T const volatile &, T)>::type operator()(T const volatile &, T); +}; + +struct no_result_type_or_result +{ + short operator()(double); + cv_overload_check<const short> operator()(double) const; + cv_overload_check<volatile short> operator()(double) volatile; + cv_overload_check<const volatile short> operator()(double) const volatile; + int operator()(); + cv_overload_check<const int> operator()() const; + cv_overload_check<volatile int> operator()() volatile; + cv_overload_check<const volatile int> operator()() const volatile; +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + short operator()(int&&); + int operator()(int&); + long operator()(int const&); +#endif +}; + +template<typename T> +struct no_result_type_or_result_template +{ + short operator()(double); + cv_overload_check<const short> operator()(double) const; + cv_overload_check<volatile short> operator()(double) volatile; + cv_overload_check<const volatile short> operator()(double) const volatile; + int operator()(); + cv_overload_check<const int> operator()() const; + cv_overload_check<volatile int> operator()() volatile; + cv_overload_check<const volatile int> operator()() const volatile; +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + short operator()(int&&); + int operator()(int&); + long operator()(int const&); +#endif +}; + +// sfinae_tests are derived from example code from Joel de Guzman, +// which demonstrated the interaction between result_of and SFINAE. +template <typename F, typename Arg> +typename boost::result_of<F(Arg const&)>::type +sfinae_test(F f, Arg const& arg) +{ + return f(arg); +} + +template <typename F, typename Arg> +typename boost::result_of<F(Arg&)>::type +sfinae_test(F f, Arg& arg) +{ + return f(arg); +} + +int sfinae_test_f(int& i) +{ + return i; +} + +struct X {}; + +int main() +{ + using namespace boost; + + typedef int (*func_ptr)(float, double); + typedef int (&func_ref)(float, double); + typedef int (*func_ptr_0)(); + typedef int (&func_ref_0)(); + typedef void (*func_ptr_void)(float, double); + typedef void (&func_ref_void)(float, double); + typedef void (*func_ptr_void_0)(); + typedef void (&func_ref_void_0)(); + typedef int (X::*mem_func_ptr)(float); + typedef int (X::*mem_func_ptr_c)(float) const; + typedef int (X::*mem_func_ptr_v)(float) volatile; + typedef int (X::*mem_func_ptr_cv)(float) const volatile; + typedef int (X::*mem_func_ptr_0)(); + + BOOST_STATIC_ASSERT((is_same<result_of<int_result_type(float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_template<void>(float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of_template<void>(double)>::type, int>::value)); + + BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type(float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_template<void>(float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of_template<void>(double)>::type, int>::value)); + + BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(void)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of(void)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(void)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of_template<void>(void)>::type, void>::value)); + + // Prior to decltype, result_of could not deduce the return type + // of nullary function objects unless they exposed a result_type. +#if defined(BOOST_RESULT_OF_USE_DECLTYPE) + BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, int>::value)); +#else + BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, void>::value)); +#endif + + // Prior to decltype, result_of ignored a nested result<> if + // result_type was defined. After decltype, result_of deduces the + // actual return type of the function object, ignoring both + // result<> and result_type. +#if defined(BOOST_RESULT_OF_USE_DECLTYPE) + BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, char>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, char>::value)); +#else + BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value)); +#endif + + BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value)); + + BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(char, float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<func_ref(char, float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_0()>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<func_ref_0()>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_void(char, float)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<func_ref_void(char, float)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_void_0()>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<func_ref_void_0()>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr(X,char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_c(X,char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_v(X,char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_cv(X,char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_0(X)>::type, int>::value)); + + BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(char, float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(char, float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_0()>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_0()>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_void(char, float)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_void(char, float)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_void_0()>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_void_0()>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr(X,char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_c(X,char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_v(X,char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_cv(X,char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_0(X)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(void)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(void)>::type, int>::value)); + + BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(double)>::type, double>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<const result_of_member_function_template(double)>::type, cv_overload_check<const double> >::value)); + BOOST_STATIC_ASSERT((is_same<result_of<volatile result_of_member_function_template(double)>::type, cv_overload_check<volatile double> >::value)); + BOOST_STATIC_ASSERT((is_same<result_of<const volatile result_of_member_function_template(double)>::type, cv_overload_check<const volatile double> >::value)); + BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int &, int)>::type, int &>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value)); + + BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(double)>::type, double>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<const result_of_member_function_template(double)>::type, cv_overload_check<const double> >::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile result_of_member_function_template(double)>::type, cv_overload_check<volatile double> >::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<const volatile result_of_member_function_template(double)>::type, cv_overload_check<const volatile double> >::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int &, int)>::type, int &>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value)); + + typedef int (*pf_t)(int); + BOOST_STATIC_ASSERT((is_same<result_of<pf_t(int)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<pf_t const(int)>::type,int>::value)); + + BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value)); + +#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) + BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(double)>::type, short>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(double)>::type, cv_overload_check<const short> >::value)); + BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(double)>::type, cv_overload_check<volatile short> >::value)); + BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result(double)>::type, cv_overload_check<const volatile short> >::value)); + BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(void)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(void)>::type, cv_overload_check<const int> >::value)); + BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(void)>::type, cv_overload_check<volatile int> >::value)); + BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result(void)>::type, cv_overload_check<const volatile int> >::value)); + + BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(double)>::type, short>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(double)>::type, cv_overload_check<const short> >::value)); + BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(double)>::type, cv_overload_check<volatile short> >::value)); + BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(double)>::type, cv_overload_check<const volatile short> >::value)); + BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(void)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const int> >::value)); + BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<volatile int> >::value)); + BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const volatile int> >::value)); + + BOOST_STATIC_ASSERT((is_same<result_of<func_ptr&(char, float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<func_ptr const&(char, float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<int_result_of&(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<int_result_of const&(double)>::type, int>::value)); + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&&)>::type, short>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int const&)>::type, long>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int&&)>::type, short>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int&)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int const&)>::type, long>::value)); +#endif +#endif + +#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) + int i = 123; + sfinae_test(sfinae_test_f, i); +#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) + + return 0; +} diff --git a/src/boost/libs/utility/test/string_ref_from_rvalue.cpp b/src/boost/libs/utility/test/string_ref_from_rvalue.cpp new file mode 100644 index 00000000..6ec8a5a2 --- /dev/null +++ b/src/boost/libs/utility/test/string_ref_from_rvalue.cpp @@ -0,0 +1,26 @@ +/* + Copyright (c) Marshall Clow 2017. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + For more information, see http://www.boost.org +*/ + +#include <iostream> +#include <algorithm> +#include <string> + +#include <boost/utility/string_ref.hpp> + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +#error "Unsupported test" +#endif + +std::string makeatemp() { return "abc"; } + +int main() +{ + boost::basic_string_ref<char> sv(makeatemp()); + return 0; +} diff --git a/src/boost/libs/utility/test/string_ref_test1.cpp b/src/boost/libs/utility/test/string_ref_test1.cpp new file mode 100644 index 00000000..fc889051 --- /dev/null +++ b/src/boost/libs/utility/test/string_ref_test1.cpp @@ -0,0 +1,110 @@ +/* + Copyright (c) Marshall Clow 2012-2012. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + For more information, see http://www.boost.org +*/ + +#include <iostream> +#include <algorithm> +#include <string> + +#include <boost/utility/string_ref.hpp> + +#include <boost/core/lightweight_test.hpp> + +typedef boost::string_ref string_ref; + +// Should be equal +void interop ( const std::string &str, string_ref ref ) { +// BOOST_TEST ( str == ref ); + BOOST_TEST ( str.size () == ref.size ()); + BOOST_TEST ( std::equal ( str.begin (), str.end (), ref.begin ())); + BOOST_TEST ( std::equal ( str.rbegin (), str.rend (), ref.rbegin ())); + } + +void null_tests ( const char *p ) { +// All zero-length string-refs should be equal + string_ref sr1; // NULL, 0 + string_ref sr2 ( NULL, 0 ); + string_ref sr3 ( p, 0 ); + string_ref sr4 ( p ); + sr4.clear (); + + BOOST_TEST ( sr1 == sr2 ); + BOOST_TEST ( sr1 == sr3 ); + BOOST_TEST ( sr2 == sr3 ); + BOOST_TEST ( sr1 == sr4 ); + } + +// make sure that substrings work just like strings +void test_substr ( const std::string &str ) { + const size_t sz = str.size (); + string_ref ref ( str ); + +// Substrings at the end + for ( size_t i = 0; i <= sz; ++ i ) + interop ( str.substr ( i ), ref.substr ( i )); + +// Substrings at the beginning + for ( size_t i = 0; i <= sz; ++ i ) + interop ( str.substr ( 0, i ), ref.substr ( 0, i )); + +// All possible substrings + for ( size_t i = 0; i < sz; ++i ) + for ( size_t j = i; j < sz; ++j ) + interop ( str.substr ( i, j ), ref.substr ( i, j )); + } + +// make sure that removing prefixes and suffixes work just like strings +void test_remove ( const std::string &str ) { + const size_t sz = str.size (); + std::string work; + string_ref ref; + + for ( size_t i = 1; i <= sz; ++i ) { + work = str; + ref = str; + while ( ref.size () >= i ) { + interop ( work, ref ); + work.erase ( 0, i ); + ref.remove_prefix (i); + } + } + + for ( size_t i = 1; i < sz; ++ i ) { + work = str; + ref = str; + while ( ref.size () >= i ) { + interop ( work, ref ); + work.erase ( work.size () - i, i ); + ref.remove_suffix (i); + } + } + } + +const char *test_strings [] = { + "", + "1", + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", + "0123456789", + NULL + }; + +int main() +{ + const char **p = &test_strings[0]; + + while ( *p != NULL ) { + interop ( *p, *p ); + test_substr ( *p ); + test_remove ( *p ); + null_tests ( *p ); + + p++; + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/utility/test/string_ref_test2.cpp b/src/boost/libs/utility/test/string_ref_test2.cpp new file mode 100644 index 00000000..d7337751 --- /dev/null +++ b/src/boost/libs/utility/test/string_ref_test2.cpp @@ -0,0 +1,323 @@ +/* + Copyright (c) Marshall Clow 2012-2012. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + For more information, see http://www.boost.org +*/ + +#include <iostream> +#include <cstring> // for std::strchr + +#include <boost/utility/string_ref.hpp> + +#include <boost/core/lightweight_test.hpp> + +typedef boost::string_ref string_ref; + +void ends_with ( const char *arg ) { + const size_t sz = std::strlen ( arg ); + string_ref sr ( arg ); + string_ref sr2 ( arg ); + const char *p = arg; + + while ( *p ) { + BOOST_TEST ( sr.ends_with ( p )); + ++p; + } + + while ( !sr2.empty ()) { + BOOST_TEST ( sr.ends_with ( sr2 )); + sr2.remove_prefix (1); + } + + sr2 = arg; + while ( !sr2.empty ()) { + BOOST_TEST ( sr.ends_with ( sr2 )); + sr2.remove_prefix (1); + } + + char ch = sz == 0 ? '\0' : arg [ sz - 1 ]; + sr2 = arg; + if ( sz > 0 ) + BOOST_TEST ( sr2.ends_with ( ch )); + BOOST_TEST ( !sr2.ends_with ( ++ch )); + BOOST_TEST ( sr2.ends_with ( string_ref ())); + } + +void starts_with ( const char *arg ) { + const size_t sz = std::strlen ( arg ); + string_ref sr ( arg ); + string_ref sr2 ( arg ); + const char *p = arg + std::strlen ( arg ) - 1; + while ( p >= arg ) { + std::string foo ( arg, p + 1 ); + BOOST_TEST ( sr.starts_with ( foo )); + --p; + } + + while ( !sr2.empty ()) { + BOOST_TEST ( sr.starts_with ( sr2 )); + sr2.remove_suffix (1); + } + + char ch = *arg; + sr2 = arg; + if ( sz > 0 ) + BOOST_TEST ( sr2.starts_with ( ch )); + BOOST_TEST ( !sr2.starts_with ( ++ch )); + BOOST_TEST ( sr2.starts_with ( string_ref ())); + } + +void reverse ( const char *arg ) { +// Round trip + string_ref sr1 ( arg ); + std::string string1 ( sr1.rbegin (), sr1.rend ()); + string_ref sr2 ( string1 ); + std::string string2 ( sr2.rbegin (), sr2.rend ()); + + BOOST_TEST ( std::equal ( sr2.rbegin (), sr2.rend (), arg )); + BOOST_TEST ( string2 == arg ); + BOOST_TEST ( std::equal ( sr1.begin (), sr1.end (), string2.begin ())); + } + +// This helper function eliminates signed vs. unsigned warnings +string_ref::size_type ptr_diff ( const char *res, const char *base ) { + BOOST_TEST ( res >= base ); + return static_cast<string_ref::size_type> ( res - base ); + } + +void find ( const char *arg ) { + string_ref sr1; + string_ref sr2; + const char *p; + +// When we search for the empty string, we find it at position 0 + BOOST_TEST ( sr1.find (sr2) == 0 ); + BOOST_TEST ( sr1.rfind(sr2) == 0 ); + +// Look for each character in the string(searching from the start) + p = arg; + sr1 = arg; + while ( *p ) { + string_ref::size_type pos = sr1.find(*p); + BOOST_TEST ( pos != string_ref::npos && ( pos <= ptr_diff ( p, arg ))); + ++p; + } + +// Look for each character in the string (searching from the end) + p = arg; + sr1 = arg; + while ( *p ) { + string_ref::size_type pos = sr1.rfind(*p); + BOOST_TEST ( pos != string_ref::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg ))); + ++p; + } + +// Look for pairs on characters (searching from the start) + sr1 = arg; + p = arg; + while ( *p && *(p+1)) { + string_ref sr3 ( p, 2 ); + string_ref::size_type pos = sr1.find ( sr3 ); + BOOST_TEST ( pos != string_ref::npos && pos <= static_cast<string_ref::size_type>( p - arg )); + p++; + } + + sr1 = arg; + p = arg; +// for all possible chars, see if we find them in the right place. +// Note that strchr will/might do the _wrong_ thing if we search for NULL + for ( int ch = 1; ch < 256; ++ch ) { + string_ref::size_type pos = sr1.find(ch); + const char *strp = std::strchr ( arg, ch ); + BOOST_TEST (( strp == NULL ) == ( pos == string_ref::npos )); + if ( strp != NULL ) + BOOST_TEST ( ptr_diff ( strp, arg ) == pos ); + } + + sr1 = arg; + p = arg; +// for all possible chars, see if we find them in the right place. +// Note that strchr will/might do the _wrong_ thing if we search for NULL + for ( int ch = 1; ch < 256; ++ch ) { + string_ref::size_type pos = sr1.rfind(ch); + const char *strp = std::strrchr ( arg, ch ); + BOOST_TEST (( strp == NULL ) == ( pos == string_ref::npos )); + if ( strp != NULL ) + BOOST_TEST ( ptr_diff ( strp, arg ) == pos ); + } + + +// Find everything at the start + p = arg; + sr1 = arg; + while ( !sr1.empty ()) { + string_ref::size_type pos = sr1.find(*p); + BOOST_TEST ( pos == 0 ); + sr1.remove_prefix (1); + ++p; + } + +// Find everything at the end + sr1 = arg; + p = arg + std::strlen ( arg ) - 1; + while ( !sr1.empty ()) { + string_ref::size_type pos = sr1.rfind(*p); + BOOST_TEST ( pos == sr1.size () - 1 ); + sr1.remove_suffix (1); + --p; + } + +// Find everything at the start + sr1 = arg; + p = arg; + while ( !sr1.empty ()) { + string_ref::size_type pos = sr1.find_first_of(*p); + BOOST_TEST ( pos == 0 ); + sr1.remove_prefix (1); + ++p; + } + + +// Find everything at the end + sr1 = arg; + p = arg + std::strlen ( arg ) - 1; + while ( !sr1.empty ()) { + string_ref::size_type pos = sr1.find_last_of(*p); + BOOST_TEST ( pos == sr1.size () - 1 ); + sr1.remove_suffix (1); + --p; + } + +// Basic sanity checking for "find_first_of / find_first_not_of" + sr1 = arg; + sr2 = arg; + while ( !sr1.empty() ) { + BOOST_TEST ( sr1.find_first_of ( sr2 ) == 0 ); + BOOST_TEST ( sr1.find_first_not_of ( sr2 ) == string_ref::npos ); + sr1.remove_prefix ( 1 ); + } + + p = arg; + sr1 = arg; + while ( *p ) { + string_ref::size_type pos1 = sr1.find_first_of(*p); + string_ref::size_type pos2 = sr1.find_first_not_of(*p); + BOOST_TEST ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg )); + if ( pos2 != string_ref::npos ) { + for ( size_t i = 0 ; i < pos2; ++i ) + BOOST_TEST ( sr1[i] == *p ); + BOOST_TEST ( sr1 [ pos2 ] != *p ); + } + + BOOST_TEST ( pos2 != pos1 ); + ++p; + } + +// Basic sanity checking for "find_last_of / find_last_not_of" + sr1 = arg; + sr2 = arg; + while ( !sr1.empty() ) { + BOOST_TEST ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 )); + BOOST_TEST ( sr1.find_last_not_of ( sr2 ) == string_ref::npos ); + sr1.remove_suffix ( 1 ); + } + + p = arg; + sr1 = arg; + while ( *p ) { + string_ref::size_type pos1 = sr1.find_last_of(*p); + string_ref::size_type pos2 = sr1.find_last_not_of(*p); + BOOST_TEST ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg )); + BOOST_TEST ( pos2 == string_ref::npos || pos1 < sr1.size ()); + if ( pos2 != string_ref::npos ) { + for ( size_t i = sr1.size () -1 ; i > pos2; --i ) + BOOST_TEST ( sr1[i] == *p ); + BOOST_TEST ( sr1 [ pos2 ] != *p ); + } + + BOOST_TEST ( pos2 != pos1 ); + ++p; + } + + } + + +void to_string ( const char *arg ) { + string_ref sr1; + std::string str1; + std::string str2; + + str1.assign ( arg ); + sr1 = arg; +// str2 = sr1.to_string<std::allocator<char> > (); + str2 = sr1.to_string (); + BOOST_TEST ( str1 == str2 ); + +#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS + std::string str3 = static_cast<std::string> ( sr1 ); + BOOST_TEST ( str1 == str3 ); +#endif + } + +void compare ( const char *arg ) { + string_ref sr1; + std::string str1; + std::string str2 = str1; + + str1.assign ( arg ); + sr1 = arg; + BOOST_TEST ( sr1 == sr1); // compare string_ref and string_ref + BOOST_TEST ( sr1 == str1); // compare string and string_ref + BOOST_TEST ( str1 == sr1 ); // compare string_ref and string + BOOST_TEST ( sr1 == arg ); // compare string_ref and pointer + BOOST_TEST ( arg == sr1 ); // compare pointer and string_ref + + if ( sr1.size () > 0 ) { + (*str1.rbegin())++; + BOOST_TEST ( sr1 != str1 ); + BOOST_TEST ( str1 != sr1 ); + BOOST_TEST ( sr1 < str1 ); + BOOST_TEST ( sr1 <= str1 ); + BOOST_TEST ( str1 > sr1 ); + BOOST_TEST ( str1 >= sr1 ); + + (*str1.rbegin()) -= 2; + BOOST_TEST ( sr1 != str1 ); + BOOST_TEST ( str1 != sr1 ); + BOOST_TEST ( sr1 > str1 ); + BOOST_TEST ( sr1 >= str1 ); + BOOST_TEST ( str1 < sr1 ); + BOOST_TEST ( str1 <= sr1 ); + } + } + +const char *test_strings [] = { + "", + "0", + "abc", + "AAA", // all the same + "adsfadadiaef;alkdg;aljt;j agl;sjrl;tjs;lga;lretj;srg[w349u5209dsfadfasdfasdfadsf", + "abc\0asdfadsfasf", + NULL + }; + +int main() +{ + const char **p = &test_strings[0]; + + while ( *p != NULL ) { + starts_with ( *p ); + ends_with ( *p ); + reverse ( *p ); + find ( *p ); + to_string ( *p ); + compare ( *p ); + + p++; + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/utility/test/string_ref_test_io.cpp b/src/boost/libs/utility/test/string_ref_test_io.cpp new file mode 100644 index 00000000..3609f915 --- /dev/null +++ b/src/boost/libs/utility/test/string_ref_test_io.cpp @@ -0,0 +1,184 @@ +/* + * Copyright Andrey Semashev 2013. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ +/*! + * \file string_ref_test_io.cpp + * \author Andrey Semashev + * \date 26.05.2013 + * + * \brief This header contains tests for stream operations of \c basic_string_ref. + */ + +#include <boost/utility/string_ref.hpp> + +#include <iomanip> +#include <sstream> +#include <algorithm> +#include <iterator> +#include <string> + +#include <boost/config.hpp> +#include <boost/core/lightweight_test.hpp> + +/* Current implementations seem to be missing codecvt facets to convert chars to char16_t and char32_t even though the types are available. +*/ + +static const char* test_strings[] = +{ + "begin", + "abcd", + "end" +}; + +//! The context with test data for particular character type +template< typename CharT > +struct context +{ + typedef CharT char_type; + typedef std::basic_string< char_type > string_type; + typedef std::basic_ostringstream< char_type > ostream_type; + + string_type begin, abcd, end; + + context() + { + boost::string_ref str = test_strings[0]; + std::copy(str.begin(), str.end(), std::back_inserter(begin)); + + str = test_strings[1]; + std::copy(str.begin(), str.end(), std::back_inserter(abcd)); + + str = test_strings[2]; + std::copy(str.begin(), str.end(), std::back_inserter(end)); + } +}; + +// Test regular output +template<class CharT> +void test_string_ref_output() +{ + typedef CharT char_type; + typedef std::basic_ostringstream< char_type > ostream_type; + typedef boost::basic_string_ref< char_type > string_ref_type; + + context< char_type > ctx; + + ostream_type strm; + strm << string_ref_type(ctx.abcd); + BOOST_TEST(strm.str() == ctx.abcd); +} + +// Test support for padding +template<class CharT> +void test_padding() +{ + typedef CharT char_type; + typedef std::basic_ostringstream< char_type > ostream_type; + typedef boost::basic_string_ref< char_type > string_ref_type; + + context< char_type > ctx; + + // Test for padding + { + ostream_type strm_ref; + strm_ref << ctx.begin << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end; + + ostream_type strm_correct; + strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end; + + BOOST_TEST(strm_ref.str() == strm_correct.str()); + } + + // Test for long padding + { + ostream_type strm_ref; + strm_ref << ctx.begin << std::setw(100) << string_ref_type(ctx.abcd) << ctx.end; + + ostream_type strm_correct; + strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end; + + BOOST_TEST(strm_ref.str() == strm_correct.str()); + } + + // Test that short width does not truncate the string + { + ostream_type strm_ref; + strm_ref << ctx.begin << std::setw(1) << string_ref_type(ctx.abcd) << ctx.end; + + ostream_type strm_correct; + strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end; + + BOOST_TEST(strm_ref.str() == strm_correct.str()); + } +} + +// Test support for padding fill +template<class CharT> +void test_padding_fill() +{ + typedef CharT char_type; + typedef std::basic_ostringstream< char_type > ostream_type; + typedef boost::basic_string_ref< char_type > string_ref_type; + + context< char_type > ctx; + + ostream_type strm_ref; + strm_ref << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end; + + ostream_type strm_correct; + strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end; + + BOOST_TEST(strm_ref.str() == strm_correct.str()); +} + +// Test support for alignment +template<class CharT> +void test_alignment() +{ + typedef CharT char_type; + typedef std::basic_ostringstream< char_type > ostream_type; + typedef boost::basic_string_ref< char_type > string_ref_type; + + context< char_type > ctx; + + // Left alignment + { + ostream_type strm_ref; + strm_ref << ctx.begin << std::left << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end; + + ostream_type strm_correct; + strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end; + + BOOST_TEST(strm_ref.str() == strm_correct.str()); + } + + // Right alignment + { + ostream_type strm_ref; + strm_ref << ctx.begin << std::right << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end; + + ostream_type strm_correct; + strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end; + + BOOST_TEST(strm_ref.str() == strm_correct.str()); + } +} + +template<class CharT> +void test() +{ + test_string_ref_output<CharT>(); + test_padding<CharT>(); + test_padding_fill<CharT>(); + test_alignment<CharT>(); +} + +int main() +{ + test<char>(); + test<wchar_t>(); + return boost::report_errors(); +} diff --git a/src/boost/libs/utility/test/string_view_constexpr_test1.cpp b/src/boost/libs/utility/test/string_view_constexpr_test1.cpp new file mode 100644 index 00000000..615d600c --- /dev/null +++ b/src/boost/libs/utility/test/string_view_constexpr_test1.cpp @@ -0,0 +1,114 @@ +/* + Copyright (c) Marshall Clow 2017-2017. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + For more information, see http://www.boost.org +*/ + +#include <new> // for placement new +#include <iostream> +#include <cstddef> // for NULL, std::size_t, std::ptrdiff_t +#include <cstring> // for std::strchr and std::strcmp +#include <cstdlib> // for std::malloc and std::free + +#include <boost/config.hpp> +#include <boost/utility/string_view.hpp> + +#if __cplusplus >= 201402L +struct constexpr_char_traits +{ + typedef char char_type; + typedef int int_type; + typedef std::streamoff off_type; + typedef std::streampos pos_type; + typedef std::mbstate_t state_type; + + static void assign(char_type& c1, const char_type& c2) noexcept { c1 = c2; } + static constexpr bool eq(char_type c1, char_type c2) noexcept { return c1 == c2; } + static constexpr bool lt(char_type c1, char_type c2) noexcept { return c1 < c2; } + + static constexpr int compare(const char_type* s1, const char_type* s2, size_t n) noexcept; + static constexpr size_t length(const char_type* s) noexcept; + static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a) noexcept; + static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n) noexcept; + static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n) noexcept; + static constexpr char_type* assign(char_type* s, size_t n, char_type a) noexcept; + + static constexpr int_type not_eof(int_type c) noexcept { return eq_int_type(c, eof()) ? ~eof() : c; } + static constexpr char_type to_char_type(int_type c) noexcept { return char_type(c); } + static constexpr int_type to_int_type(char_type c) noexcept { return int_type(c); } + static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept { return c1 == c2; } + static constexpr int_type eof() noexcept { return EOF; } +}; + +// yields: +// 0 if for each i in [0,n), X::eq(s1[i],s2[i]) is true; +// else, a negative value if, for some j in [0,n), X::lt(s1[j],s2[j]) is true and +// for each i in [0,j) X::eq(s2[i],s2[i]) is true; +// else a positive value. +constexpr int constexpr_char_traits::compare(const char_type* s1, const char_type* s2, size_t n) noexcept +{ + for (; n != 0; --n, ++s1, ++s2) + { + if (lt(*s1, *s2)) + return -1; + if (lt(*s2, *s1)) + return 1; + } + return 0; +} + +// yields: the smallest i such that X::eq(s[i],charT()) is true. +constexpr size_t constexpr_char_traits::length(const char_type* s) noexcept +{ + size_t len = 0; + for (; !eq(*s, char_type(0)); ++s) + ++len; + return len; +} + +typedef boost::basic_string_view<char, constexpr_char_traits> string_view; + +int main() +{ + constexpr string_view sv1; + constexpr string_view sv2{"abc", 3}; // ptr, len + constexpr string_view sv3{"def"}; // ptr + + constexpr const char *s1 = ""; + constexpr const char *s2 = "abc"; + + static_assert( (sv1 == sv1), "" ); + + static_assert(!(sv1 == sv2), "" ); + static_assert( (sv1 != sv2), "" ); + static_assert( (sv1 < sv2), "" ); + static_assert( (sv1 <= sv2), "" ); + static_assert(!(sv1 > sv2), "" ); + static_assert(!(sv1 >= sv2), "" ); + + static_assert(!(s1 == sv2), "" ); + static_assert( (s1 != sv2), "" ); + static_assert( (s1 < sv2), "" ); + static_assert( (s1 <= sv2), "" ); + static_assert(!(s1 > sv2), "" ); + static_assert(!(s1 >= sv2), "" ); + + static_assert(!(sv1 == s2), "" ); + static_assert( (sv1 != s2), "" ); + static_assert( (sv1 < s2), "" ); + static_assert( (sv1 <= s2), "" ); + static_assert(!(sv1 > s2), "" ); + static_assert(!(sv1 >= s2), "" ); + + static_assert( sv1.compare(sv2) < 0, "" ); + static_assert( sv1.compare(sv1) == 0, "" ); + static_assert( sv3.compare(sv1) > 0, "" ); + + static_assert( sv1.compare(s2) < 0, "" ); + static_assert( sv1.compare(s1) == 0, "" ); + static_assert( sv3.compare(s1) > 0, "" ); +} +#endif diff --git a/src/boost/libs/utility/test/string_view_from_rvalue.cpp b/src/boost/libs/utility/test/string_view_from_rvalue.cpp new file mode 100644 index 00000000..a7649395 --- /dev/null +++ b/src/boost/libs/utility/test/string_view_from_rvalue.cpp @@ -0,0 +1,26 @@ +/* + Copyright (c) Marshall Clow 2017. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + For more information, see http://www.boost.org +*/ + +#include <iostream> +#include <algorithm> +#include <string> + +#include <boost/utility/string_view.hpp> + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +#error "Unsupported test" +#endif + +std::string makeatemp() { return "abc"; } + +int main() +{ + boost::basic_string_view<char> sv(makeatemp()); + return 0; +} diff --git a/src/boost/libs/utility/test/string_view_test1.cpp b/src/boost/libs/utility/test/string_view_test1.cpp new file mode 100644 index 00000000..c35bbfac --- /dev/null +++ b/src/boost/libs/utility/test/string_view_test1.cpp @@ -0,0 +1,120 @@ +/* + Copyright (c) Marshall Clow 2012-2012. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + For more information, see http://www.boost.org +*/ + +#include <iostream> +#include <algorithm> +#include <string> + +#include <boost/utility/string_view.hpp> +#include <boost/container_hash/hash.hpp> + +#include <boost/core/lightweight_test.hpp> + +typedef boost::string_view string_view; + +// Should be equal +void interop ( const std::string &str, string_view ref ) { +// BOOST_TEST ( str == ref ); + BOOST_TEST ( str.size () == ref.size ()); + BOOST_TEST ( std::equal ( str.begin (), str.end (), ref.begin ())); + BOOST_TEST ( std::equal ( str.rbegin (), str.rend (), ref.rbegin ())); + } + +void null_tests ( const char *p ) { +// All zero-length string-refs should be equal + string_view sr1; // NULL, 0 + string_view sr2 ( NULL, 0 ); + string_view sr3 ( p, 0 ); + string_view sr4 ( p ); + sr4.clear (); + + BOOST_TEST ( sr1 == sr2 ); + BOOST_TEST ( sr1 == sr3 ); + BOOST_TEST ( sr2 == sr3 ); + BOOST_TEST ( sr1 == sr4 ); + } + +// make sure that substrings work just like strings +void test_substr ( const std::string &str ) { + const size_t sz = str.size (); + string_view ref ( str ); + +// Substrings at the end + for ( size_t i = 0; i <= sz; ++ i ) + interop ( str.substr ( i ), ref.substr ( i )); + +// Substrings at the beginning + for ( size_t i = 0; i <= sz; ++ i ) + interop ( str.substr ( 0, i ), ref.substr ( 0, i )); + +// All possible substrings + for ( size_t i = 0; i < sz; ++i ) + for ( size_t j = i; j < sz; ++j ) + interop ( str.substr ( i, j ), ref.substr ( i, j )); + } + +// make sure that removing prefixes and suffixes work just like strings +void test_remove ( const std::string &str ) { + const size_t sz = str.size (); + std::string work; + string_view ref; + + for ( size_t i = 1; i <= sz; ++i ) { + work = str; + ref = str; + while ( ref.size () >= i ) { + interop ( work, ref ); + work.erase ( 0, i ); + ref.remove_prefix (i); + } + } + + for ( size_t i = 1; i < sz; ++ i ) { + work = str; + ref = str; + while ( ref.size () >= i ) { + interop ( work, ref ); + work.erase ( work.size () - i, i ); + ref.remove_suffix (i); + } + } + } + +void test_hash(const std::string& str) { + string_view ref = str; + BOOST_TEST(boost::hash_value(ref) == boost::hash_value(str)); + boost::hash<std::string> hstr; + boost::hash<string_view> hsv; + BOOST_TEST(hsv(ref) == hstr(str)); + } + +const char *test_strings [] = { + "", + "1", + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", + "0123456789", + NULL + }; + +int main() +{ + const char **p = &test_strings[0]; + + while ( *p != NULL ) { + interop ( *p, *p ); + test_substr ( *p ); + test_remove ( *p ); + null_tests ( *p ); + test_hash( *p ); + + p++; + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/utility/test/string_view_test2.cpp b/src/boost/libs/utility/test/string_view_test2.cpp new file mode 100644 index 00000000..135fd1aa --- /dev/null +++ b/src/boost/libs/utility/test/string_view_test2.cpp @@ -0,0 +1,410 @@ +/* + Copyright (c) Marshall Clow 2012-2012. + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + For more information, see http://www.boost.org +*/ + +#include <new> // for placement new +#include <iostream> +#include <cstddef> // for NULL, std::size_t, std::ptrdiff_t +#include <cstring> // for std::strchr and std::strcmp +#include <cstdlib> // for std::malloc and std::free + +#include <boost/utility/string_view.hpp> +#include <boost/config.hpp> + +#include <boost/core/lightweight_test.hpp> + +typedef boost::string_view string_view; + +void ends_with ( const char *arg ) { + const size_t sz = std::strlen ( arg ); + string_view sr ( arg ); + string_view sr2 ( arg ); + const char *p = arg; + + while ( *p ) { + BOOST_TEST ( sr.ends_with ( p )); + ++p; + } + + while ( !sr2.empty ()) { + BOOST_TEST ( sr.ends_with ( sr2 )); + sr2.remove_prefix (1); + } + + sr2 = arg; + while ( !sr2.empty ()) { + BOOST_TEST ( sr.ends_with ( sr2 )); + sr2.remove_prefix (1); + } + + char ch = sz == 0 ? '\0' : arg [ sz - 1 ]; + sr2 = arg; + if ( sz > 0 ) + BOOST_TEST ( sr2.ends_with ( ch )); + BOOST_TEST ( !sr2.ends_with ( ++ch )); + BOOST_TEST ( sr2.ends_with ( string_view())); + } + +void starts_with ( const char *arg ) { + const size_t sz = std::strlen ( arg ); + string_view sr ( arg ); + string_view sr2 ( arg ); + const char *p = arg + std::strlen ( arg ) - 1; + while ( p >= arg ) { + std::string foo ( arg, p + 1 ); + BOOST_TEST ( sr.starts_with ( foo )); + --p; + } + + while ( !sr2.empty ()) { + BOOST_TEST ( sr.starts_with ( sr2 )); + sr2.remove_suffix (1); + } + + char ch = *arg; + sr2 = arg; + if ( sz > 0 ) + BOOST_TEST ( sr2.starts_with ( ch )); + BOOST_TEST ( !sr2.starts_with ( ++ch )); + BOOST_TEST ( sr2.starts_with ( string_view ())); + } + +void reverse ( const char *arg ) { +// Round trip + string_view sr1 ( arg ); + std::string string1 ( sr1.rbegin (), sr1.rend ()); + string_view sr2 ( string1 ); + std::string string2 ( sr2.rbegin (), sr2.rend ()); + + BOOST_TEST ( std::equal ( sr2.rbegin (), sr2.rend (), arg )); + BOOST_TEST ( string2 == arg ); + BOOST_TEST ( std::equal ( sr1.begin (), sr1.end (), string2.begin ())); + } + +// This helper function eliminates signed vs. unsigned warnings +string_view::size_type ptr_diff ( const char *res, const char *base ) { + BOOST_TEST ( res >= base ); + return static_cast<string_view::size_type> ( res - base ); + } + +void find ( const char *arg ) { + string_view sr1; + string_view sr2; + const char *p; + +// When we search for the empty string, we find it at position 0 + BOOST_TEST ( sr1.find (sr2) == 0 ); + BOOST_TEST ( sr1.rfind(sr2) == 0 ); + +// Look for each character in the string(searching from the start) + p = arg; + sr1 = arg; + while ( *p ) { + string_view::size_type pos = sr1.find(*p); + BOOST_TEST ( pos != string_view::npos && ( pos <= ptr_diff ( p, arg ))); + ++p; + } + +// Look for each character in the string (searching from the end) + p = arg; + sr1 = arg; + while ( *p ) { + string_view::size_type pos = sr1.rfind(*p); + BOOST_TEST ( pos != string_view::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg ))); + ++p; + } + +// Look for pairs on characters (searching from the start) + sr1 = arg; + p = arg; + while ( *p && *(p+1)) { + string_view sr3 ( p, 2 ); + string_view::size_type pos = sr1.find ( sr3 ); + BOOST_TEST ( pos != string_view::npos && pos <= static_cast<string_view::size_type>( p - arg )); + p++; + } + + sr1 = arg; + p = arg; +// for all possible chars, see if we find them in the right place. +// Note that strchr will/might do the _wrong_ thing if we search for NULL + for ( int ch = 1; ch < 256; ++ch ) { + string_view::size_type pos = sr1.find(ch); + const char *strp = std::strchr ( arg, ch ); + BOOST_TEST (( strp == NULL ) == ( pos == string_view::npos )); + if ( strp != NULL ) + BOOST_TEST ( ptr_diff ( strp, arg ) == pos ); + } + + sr1 = arg; + p = arg; +// for all possible chars, see if we find them in the right place. +// Note that strchr will/might do the _wrong_ thing if we search for NULL + for ( int ch = 1; ch < 256; ++ch ) { + string_view::size_type pos = sr1.rfind(ch); + const char *strp = std::strrchr ( arg, ch ); + BOOST_TEST (( strp == NULL ) == ( pos == string_view::npos )); + if ( strp != NULL ) + BOOST_TEST ( ptr_diff ( strp, arg ) == pos ); + } + + +// Find everything at the start + p = arg; + sr1 = arg; + while ( !sr1.empty ()) { + string_view::size_type pos = sr1.find(*p); + BOOST_TEST ( pos == 0 ); + sr1.remove_prefix (1); + ++p; + } + +// Find everything at the end + sr1 = arg; + p = arg + std::strlen ( arg ) - 1; + while ( !sr1.empty ()) { + string_view::size_type pos = sr1.rfind(*p); + BOOST_TEST ( pos == sr1.size () - 1 ); + sr1.remove_suffix (1); + --p; + } + +// Find everything at the start + sr1 = arg; + p = arg; + while ( !sr1.empty ()) { + string_view::size_type pos = sr1.find_first_of(*p); + BOOST_TEST ( pos == 0 ); + sr1.remove_prefix (1); + ++p; + } + + +// Find everything at the end + sr1 = arg; + p = arg + std::strlen ( arg ) - 1; + while ( !sr1.empty ()) { + string_view::size_type pos = sr1.find_last_of(*p); + BOOST_TEST ( pos == sr1.size () - 1 ); + sr1.remove_suffix (1); + --p; + } + +// Basic sanity checking for "find_first_of / find_first_not_of" + sr1 = arg; + sr2 = arg; + while ( !sr1.empty() ) { + BOOST_TEST ( sr1.find_first_of ( sr2 ) == 0 ); + BOOST_TEST ( sr1.find_first_not_of ( sr2 ) == string_view::npos ); + sr1.remove_prefix ( 1 ); + } + + p = arg; + sr1 = arg; + while ( *p ) { + string_view::size_type pos1 = sr1.find_first_of(*p); + string_view::size_type pos2 = sr1.find_first_not_of(*p); + BOOST_TEST ( pos1 != string_view::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg )); + if ( pos2 != string_view::npos ) { + for ( size_t i = 0 ; i < pos2; ++i ) + BOOST_TEST ( sr1[i] == *p ); + BOOST_TEST ( sr1 [ pos2 ] != *p ); + } + + BOOST_TEST ( pos2 != pos1 ); + ++p; + } + +// Basic sanity checking for "find_last_of / find_last_not_of" + sr1 = arg; + sr2 = arg; + while ( !sr1.empty() ) { + BOOST_TEST ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 )); + BOOST_TEST ( sr1.find_last_not_of ( sr2 ) == string_view::npos ); + sr1.remove_suffix ( 1 ); + } + + p = arg; + sr1 = arg; + while ( *p ) { + string_view::size_type pos1 = sr1.find_last_of(*p); + string_view::size_type pos2 = sr1.find_last_not_of(*p); + BOOST_TEST ( pos1 != string_view::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg )); + BOOST_TEST ( pos2 == string_view::npos || pos1 < sr1.size ()); + if ( pos2 != string_view::npos ) { + for ( size_t i = sr1.size () -1 ; i > pos2; --i ) + BOOST_TEST ( sr1[i] == *p ); + BOOST_TEST ( sr1 [ pos2 ] != *p ); + } + + BOOST_TEST ( pos2 != pos1 ); + ++p; + } + + } + +template <typename T> +class custom_allocator { +public: + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef void* void_pointer; + typedef const void* const_void_pointer; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef T& reference; + typedef const T& const_reference; + + template<class U> + struct rebind { + typedef custom_allocator<U> other; + }; + + custom_allocator() BOOST_NOEXCEPT {} + template <typename U> + custom_allocator(custom_allocator<U> const&) BOOST_NOEXCEPT {} + + pointer allocate(size_type n) const { + return static_cast<pointer>(std::malloc(sizeof(value_type) * n)); + } + void deallocate(pointer p, size_type) const BOOST_NOEXCEPT { + std::free(p); + } + + pointer address(reference value) const BOOST_NOEXCEPT { + return &value; + } + + const_pointer address(const_reference value) const BOOST_NOEXCEPT { + return &value; + } + + BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT { + return (~(size_type)0u) / sizeof(value_type); + } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template <class U, class... Args> + void construct(U* ptr, Args&&... args) const { + ::new((void*)ptr) U(static_cast<Args&&>(args)...); + } +#else + template <class U, class V> + void construct(U* ptr, V&& value) const { + ::new((void*)ptr) U(static_cast<V&&>(value)); + } +#endif +#else + template <class U, class V> + void construct(U* ptr, const V& value) const { + ::new((void*)ptr) U(value); + } +#endif + + template <class U> + void construct(U* ptr) const { + ::new((void*)ptr) U(); + } + + template <class U> + void destroy(U* ptr) const { + (void)ptr; + ptr->~U(); + } + }; + +template <typename T, typename U> +BOOST_CONSTEXPR bool operator==(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT { + return true; + } +template <typename T, typename U> +BOOST_CONSTEXPR bool operator!=(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT { + return false; + } + +void to_string ( const char *arg ) { + string_view sr1; + std::string str1; + std::string str2; + + str1.assign ( arg ); + sr1 = arg; +// str2 = sr1.to_string<std::allocator<char> > (); + str2 = sr1.to_string (); + BOOST_TEST ( str1 == str2 ); + + std::basic_string<char, std::char_traits<char>, custom_allocator<char> > str3 = sr1.to_string(custom_allocator<char>()); + BOOST_TEST ( std::strcmp(str1.c_str(), str3.c_str()) == 0 ); + +#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS + std::string str4 = static_cast<std::string> ( sr1 ); + BOOST_TEST ( str1 == str4 ); +#endif + } + +void compare ( const char *arg ) { + string_view sr1; + std::string str1; + std::string str2 = str1; + + str1.assign ( arg ); + sr1 = arg; + BOOST_TEST ( sr1 == sr1); // compare string_view and string_view + BOOST_TEST ( sr1 == str1); // compare string and string_view + BOOST_TEST ( str1 == sr1 ); // compare string_view and string + BOOST_TEST ( sr1 == arg ); // compare string_view and pointer + BOOST_TEST ( arg == sr1 ); // compare pointer and string_view + + if ( sr1.size () > 0 ) { + (*str1.rbegin())++; + BOOST_TEST ( sr1 != str1 ); + BOOST_TEST ( str1 != sr1 ); + BOOST_TEST ( sr1 < str1 ); + BOOST_TEST ( sr1 <= str1 ); + BOOST_TEST ( str1 > sr1 ); + BOOST_TEST ( str1 >= sr1 ); + + (*str1.rbegin()) -= 2; + BOOST_TEST ( sr1 != str1 ); + BOOST_TEST ( str1 != sr1 ); + BOOST_TEST ( sr1 > str1 ); + BOOST_TEST ( sr1 >= str1 ); + BOOST_TEST ( str1 < sr1 ); + BOOST_TEST ( str1 <= sr1 ); + } + } + +const char *test_strings [] = { + "", + "0", + "abc", + "AAA", // all the same + "adsfadadiaef;alkdg;aljt;j agl;sjrl;tjs;lga;lretj;srg[w349u5209dsfadfasdfasdfadsf", + "abc\0asdfadsfasf", + NULL + }; + +int main() +{ + const char **p = &test_strings[0]; + + while ( *p != NULL ) { + starts_with ( *p ); + ends_with ( *p ); + reverse ( *p ); + find ( *p ); + to_string ( *p ); + compare ( *p ); + + p++; + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/utility/test/string_view_test_io.cpp b/src/boost/libs/utility/test/string_view_test_io.cpp new file mode 100644 index 00000000..416ff338 --- /dev/null +++ b/src/boost/libs/utility/test/string_view_test_io.cpp @@ -0,0 +1,184 @@ +/* + * Copyright Andrey Semashev 2013. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ +/*! + * \file string_ref_test_io.cpp + * \author Andrey Semashev + * \date 26.05.2013 + * + * \brief This header contains tests for stream operations of \c basic_string_ref. + */ + +#include <boost/utility/string_view.hpp> + +#include <iomanip> +#include <sstream> +#include <algorithm> +#include <iterator> +#include <string> + +#include <boost/config.hpp> +#include <boost/core/lightweight_test.hpp> + +/* Current implementations seem to be missing codecvt facets to convert chars to char16_t and char32_t even though the types are available. +*/ + +static const char* test_strings[] = +{ + "begin", + "abcd", + "end" +}; + +//! The context with test data for particular character type +template< typename CharT > +struct context +{ + typedef CharT char_type; + typedef std::basic_string< char_type > string_type; + typedef std::basic_ostringstream< char_type > ostream_type; + + string_type begin, abcd, end; + + context() + { + boost::string_view str = test_strings[0]; + std::copy(str.begin(), str.end(), std::back_inserter(begin)); + + str = test_strings[1]; + std::copy(str.begin(), str.end(), std::back_inserter(abcd)); + + str = test_strings[2]; + std::copy(str.begin(), str.end(), std::back_inserter(end)); + } +}; + +// Test regular output +template<class CharT> +void test_string_view_output() +{ + typedef CharT char_type; + typedef std::basic_ostringstream< char_type > ostream_type; + typedef boost::basic_string_view< char_type > string_view_type; + + context< char_type > ctx; + + ostream_type strm; + strm << string_view_type(ctx.abcd); + BOOST_TEST(strm.str() == ctx.abcd); +} + +// Test support for padding +template<class CharT> +void test_padding() +{ + typedef CharT char_type; + typedef std::basic_ostringstream< char_type > ostream_type; + typedef boost::basic_string_view< char_type > string_view_type; + + context< char_type > ctx; + + // Test for padding + { + ostream_type strm_ref; + strm_ref << ctx.begin << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; + + ostream_type strm_correct; + strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end; + + BOOST_TEST(strm_ref.str() == strm_correct.str()); + } + + // Test for long padding + { + ostream_type strm_ref; + strm_ref << ctx.begin << std::setw(100) << string_view_type(ctx.abcd) << ctx.end; + + ostream_type strm_correct; + strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end; + + BOOST_TEST(strm_ref.str() == strm_correct.str()); + } + + // Test that short width does not truncate the string + { + ostream_type strm_ref; + strm_ref << ctx.begin << std::setw(1) << string_view_type(ctx.abcd) << ctx.end; + + ostream_type strm_correct; + strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end; + + BOOST_TEST(strm_ref.str() == strm_correct.str()); + } +} + +// Test support for padding fill +template<class CharT> +void test_padding_fill() +{ + typedef CharT char_type; + typedef std::basic_ostringstream< char_type > ostream_type; + typedef boost::basic_string_view< char_type > string_view_type; + + context< char_type > ctx; + + ostream_type strm_ref; + strm_ref << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; + + ostream_type strm_correct; + strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end; + + BOOST_TEST(strm_ref.str() == strm_correct.str()); +} + +// Test support for alignment +template<class CharT> +void test_alignment() +{ + typedef CharT char_type; + typedef std::basic_ostringstream< char_type > ostream_type; + typedef boost::basic_string_view< char_type > string_view_type; + + context< char_type > ctx; + + // Left alignment + { + ostream_type strm_ref; + strm_ref << ctx.begin << std::left << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; + + ostream_type strm_correct; + strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end; + + BOOST_TEST(strm_ref.str() == strm_correct.str()); + } + + // Right alignment + { + ostream_type strm_ref; + strm_ref << ctx.begin << std::right << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; + + ostream_type strm_correct; + strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end; + + BOOST_TEST(strm_ref.str() == strm_correct.str()); + } +} + +template<class CharT> +void test() +{ + test_string_view_output<CharT>(); + test_padding<CharT>(); + test_padding_fill<CharT>(); + test_alignment<CharT>(); +} + +int main() +{ + test<char>(); + test<wchar_t>(); + return boost::report_errors(); +} diff --git a/src/boost/libs/utility/test/value_init_test.cpp b/src/boost/libs/utility/test/value_init_test.cpp new file mode 100644 index 00000000..ed7ec3d5 --- /dev/null +++ b/src/boost/libs/utility/test/value_init_test.cpp @@ -0,0 +1,371 @@ +// Copyright 2002-2008, Fernando Luis Cacciola Carballal. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Test program for "boost/utility/value_init.hpp" +// +// 21 Ago 2002 (Created) Fernando Cacciola +// 15 Jan 2008 (Added tests regarding compiler issues) Fernando Cacciola, Niels Dekker +// 23 May 2008 (Added tests regarding initialized_value) Niels Dekker +// 21 Ago 2008 (Added swap test) Niels Dekker + +#include <cstring> // For memcmp. +#include <iostream> +#include <string> + +#include "boost/utility/value_init.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include <boost/core/lightweight_test.hpp> + +// +// Sample POD type +// +struct POD +{ + POD () : f(0), c(0), i(0){} + + POD ( char c_, int i_, float f_ ) : f(f_), c(c_), i(i_) {} + + friend std::ostream& operator << ( std::ostream& os, POD const& pod ) + { return os << '(' << pod.c << ',' << pod.i << ',' << pod.f << ')' ; } + + friend bool operator == ( POD const& lhs, POD const& rhs ) + { return lhs.f == rhs.f && lhs.c == rhs.c && lhs.i == rhs.i ; } + + float f; + char c; + int i; +} ; + +// +// Sample non POD type +// +struct NonPODBase +{ + virtual ~NonPODBase() {} +} ; +struct NonPOD : NonPODBase +{ + NonPOD () : id() {} + explicit NonPOD ( std::string const& id_) : id(id_) {} + + friend std::ostream& operator << ( std::ostream& os, NonPOD const& npod ) + { return os << '(' << npod.id << ')' ; } + + friend bool operator == ( NonPOD const& lhs, NonPOD const& rhs ) + { return lhs.id == rhs.id ; } + + std::string id ; +} ; + +// +// Sample aggregate POD struct type +// Some compilers do not correctly value-initialize such a struct, for example: +// Borland C++ Report #51854, "Value-initialization: POD struct should be zero-initialized " +// http://qc.codegear.com/wc/qcmain.aspx?d=51854 +// +struct AggregatePODStruct +{ + float f; + char c; + int i; +}; + +bool operator == ( AggregatePODStruct const& lhs, AggregatePODStruct const& rhs ) +{ return lhs.f == rhs.f && lhs.c == rhs.c && lhs.i == rhs.i ; } + +// +// An aggregate struct that contains an std::string and an int. +// Pavel Kuznetsov (MetaCommunications Engineering) used a struct like +// this to reproduce the Microsoft Visual C++ compiler bug, reported as +// Feedback ID 100744, "Value-initialization in new-expression" +// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744 +// +struct StringAndInt +{ + std::string s; + int i; +}; + +bool operator == ( StringAndInt const& lhs, StringAndInt const& rhs ) +{ return lhs.s == rhs.s && lhs.i == rhs.i ; } + + +// +// A struct that has an explicit (user defined) destructor. +// Some compilers do not correctly value-initialize such a struct, for example: +// Microsoft Visual C++, Feedback ID 100744, "Value-initialization in new-expression" +// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744 +// +struct StructWithDestructor +{ + int i; + ~StructWithDestructor() {} +}; + +bool operator == ( StructWithDestructor const& lhs, StructWithDestructor const& rhs ) +{ return lhs.i == rhs.i ; } + + +// +// A struct that has a virtual function. +// Some compilers do not correctly value-initialize such a struct either, for example: +// Microsoft Visual C++, Feedback ID 100744, "Value-initialization in new-expression" +// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744 +// +struct StructWithVirtualFunction +{ + int i; + virtual void VirtualFunction(); +}; + +void StructWithVirtualFunction::VirtualFunction() +{ +} + +bool operator == ( StructWithVirtualFunction const& lhs, StructWithVirtualFunction const& rhs ) +{ return lhs.i == rhs.i ; } + + +// +// A struct that is derived from an aggregate POD struct. +// Some compilers do not correctly value-initialize such a struct, for example: +// GCC Bugzilla Bug 30111, "Value-initialization of POD base class doesn't initialize members", +// reported by Jonathan Wakely, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 +// +struct DerivedFromAggregatePODStruct : AggregatePODStruct +{ + DerivedFromAggregatePODStruct() : AggregatePODStruct() {} +}; + +// +// A struct that wraps an aggregate POD struct as data member. +// +struct AggregatePODStructWrapper +{ + AggregatePODStructWrapper() : dataMember() {} + AggregatePODStruct dataMember; +}; + +bool operator == ( AggregatePODStructWrapper const& lhs, AggregatePODStructWrapper const& rhs ) +{ return lhs.dataMember == rhs.dataMember ; } + +typedef unsigned char ArrayOfBytes[256]; + + +// +// A struct that allows testing whether the appropriate copy functions are called. +// +struct CopyFunctionCallTester +{ + bool is_copy_constructed; + bool is_assignment_called; + + CopyFunctionCallTester() + : is_copy_constructed(false), is_assignment_called(false) {} + + CopyFunctionCallTester(const CopyFunctionCallTester & ) + : is_copy_constructed(true), is_assignment_called(false) {} + + CopyFunctionCallTester & operator=(const CopyFunctionCallTester & ) + { + is_assignment_called = true ; + return *this ; + } +}; + + +// +// A struct that allows testing whether its customized swap function is called. +// +struct SwapFunctionCallTester +{ + bool is_custom_swap_called; + int data; + + SwapFunctionCallTester() + : is_custom_swap_called(false), data(0) {} + + SwapFunctionCallTester(const SwapFunctionCallTester & arg) + : is_custom_swap_called(false), data(arg.data) {} + + void swap(SwapFunctionCallTester & arg) + { + std::swap(data, arg.data); + is_custom_swap_called = true; + arg.is_custom_swap_called = true; + } +}; + +void swap(SwapFunctionCallTester & lhs, SwapFunctionCallTester & rhs) +{ + lhs.swap(rhs); +} + + + +template<class T> +void check_initialized_value ( T const& y ) +{ + T initializedValue = boost::initialized_value ; + BOOST_TEST ( y == initializedValue ) ; +} + +#ifdef __BORLANDC__ +#if __BORLANDC__ == 0x582 +void check_initialized_value( NonPOD const& ) +{ + // The initialized_value check is skipped for Borland 5.82 + // and this type (NonPOD), because the following statement + // won't compile on this particular compiler version: + // NonPOD initializedValue = boost::initialized_value() ; + // + // This is caused by a compiler bug, that is fixed with a newer version + // of the Borland compiler. The Release Notes for Delphi(R) 2007 for + // Win32(R) and C++Builder(R) 2007 (http://dn.codegear.com/article/36575) + // say about similar statements: + // both of these statements now compile but under 5.82 got the error: + // Error E2015: Ambiguity between 'V::V(const A &)' and 'V::V(const V &)' +} +#endif +#endif + +// +// This test function tests boost::value_initialized<T> for a specific type T. +// The first argument (y) is assumed have the value of a value-initialized object. +// Returns true on success. +// +template<class T> +bool test ( T const& y, T const& z ) +{ + const int errors_before_test = boost::detail::test_errors(); + + check_initialized_value(y); + + boost::value_initialized<T> x ; + BOOST_TEST ( y == x ) ; + BOOST_TEST ( y == boost::get(x) ) ; + + static_cast<T&>(x) = z ; + boost::get(x) = z ; + BOOST_TEST ( x == z ) ; + + boost::value_initialized<T> const x_c ; + BOOST_TEST ( y == x_c ) ; + BOOST_TEST ( y == boost::get(x_c) ) ; + T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ; + x_c_ref = z ; + BOOST_TEST ( x_c == z ) ; + + boost::value_initialized<T> const copy1 = x; + BOOST_TEST ( boost::get(copy1) == boost::get(x) ) ; + + boost::value_initialized<T> copy2; + copy2 = x; + BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ; + + { + boost::value_initialized<T> * ptr = new boost::value_initialized<T>; + BOOST_TEST ( y == *ptr ) ; + delete ptr; + } + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + boost::value_initialized<T const> cx ; + BOOST_TEST ( y == cx ) ; + BOOST_TEST ( y == boost::get(cx) ) ; + + boost::value_initialized<T const> const cx_c ; + BOOST_TEST ( y == cx_c ) ; + BOOST_TEST ( y == boost::get(cx_c) ) ; +#endif + + return boost::detail::test_errors() == errors_before_test ; +} + +int main() +{ + BOOST_TEST ( test( 0,1234 ) ) ; + BOOST_TEST ( test( 0.0,12.34 ) ) ; + BOOST_TEST ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ; + BOOST_TEST ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ; + + NonPOD NonPOD_object( std::string("NonPOD_object") ); + BOOST_TEST ( test<NonPOD *>( 0, &NonPOD_object ) ) ; + + AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 }; + AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 }; + BOOST_TEST ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) ); + + StringAndInt stringAndInt0; + StringAndInt stringAndInt1; + stringAndInt0.i = 0; + stringAndInt1.i = 1; + stringAndInt1.s = std::string("1"); + BOOST_TEST ( test(stringAndInt0, stringAndInt1) ); + + StructWithDestructor structWithDestructor0; + StructWithDestructor structWithDestructor1; + structWithDestructor0.i = 0; + structWithDestructor1.i = 1; + BOOST_TEST ( test(structWithDestructor0, structWithDestructor1) ); + + StructWithVirtualFunction structWithVirtualFunction0; + StructWithVirtualFunction structWithVirtualFunction1; + structWithVirtualFunction0.i = 0; + structWithVirtualFunction1.i = 1; + BOOST_TEST ( test(structWithVirtualFunction0, structWithVirtualFunction1) ); + + DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0; + DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1; + static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct; + static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct; + BOOST_TEST ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) ); + + AggregatePODStructWrapper aggregatePODStructWrapper0; + AggregatePODStructWrapper aggregatePODStructWrapper1; + aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct; + aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct; + BOOST_TEST ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) ); + + ArrayOfBytes zeroInitializedArrayOfBytes = { 0 }; + boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes; + BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0); + + boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2; + valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes; + BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0); + + boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1; + BOOST_TEST ( ! get(copyFunctionCallTester1).is_copy_constructed); + BOOST_TEST ( ! get(copyFunctionCallTester1).is_assignment_called); + + boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1); + BOOST_TEST ( get(copyFunctionCallTester2).is_copy_constructed); + BOOST_TEST ( ! get(copyFunctionCallTester2).is_assignment_called); + + boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3; + copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1); + BOOST_TEST ( ! get(copyFunctionCallTester3).is_copy_constructed); + BOOST_TEST ( get(copyFunctionCallTester3).is_assignment_called); + + boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1; + boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2; + get(swapFunctionCallTester1).data = 1; + get(swapFunctionCallTester2).data = 2; + boost::swap(swapFunctionCallTester1, swapFunctionCallTester2); + BOOST_TEST( get(swapFunctionCallTester1).data == 2 ); + BOOST_TEST( get(swapFunctionCallTester2).data == 1 ); + BOOST_TEST( get(swapFunctionCallTester1).is_custom_swap_called ); + BOOST_TEST( get(swapFunctionCallTester2).is_custom_swap_called ); + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/utility/test/value_init_test_fail1.cpp b/src/boost/libs/utility/test/value_init_test_fail1.cpp new file mode 100644 index 00000000..789e6b33 --- /dev/null +++ b/src/boost/libs/utility/test/value_init_test_fail1.cpp @@ -0,0 +1,27 @@ +// Copyright 2002, Fernando Luis Cacciola Carballal. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Test program for "boost/utility/value_init.hpp" +// +// Initial: 21 Agu 2002 + +#include <iostream> +#include <string> + +#include "boost/utility/value_init.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +int main() +{ + boost::value_initialized<int> const x_c ; + + get(x_c) = 1234 ; // this should produce an ERROR + + return 0; +} diff --git a/src/boost/libs/utility/test/value_init_test_fail2.cpp b/src/boost/libs/utility/test/value_init_test_fail2.cpp new file mode 100644 index 00000000..052a2bdf --- /dev/null +++ b/src/boost/libs/utility/test/value_init_test_fail2.cpp @@ -0,0 +1,27 @@ +// Copyright 2002, Fernando Luis Cacciola Carballal. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Test program for "boost/utility/value_init.hpp" +// +// Initial: 21 Agu 2002 + +#include <iostream> +#include <string> + +#include "boost/utility/value_init.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +int main() +{ + boost::value_initialized<int const> cx ; + + get(cx) = 1234 ; // this should produce an ERROR + + return 0; +} diff --git a/src/boost/libs/utility/test/value_init_test_fail3.cpp b/src/boost/libs/utility/test/value_init_test_fail3.cpp new file mode 100644 index 00000000..1801f827 --- /dev/null +++ b/src/boost/libs/utility/test/value_init_test_fail3.cpp @@ -0,0 +1,27 @@ +// Copyright 2002, Fernando Luis Cacciola Carballal. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Test program for "boost/utility/value_init.hpp" +// +// Initial: 21 Agu 2002 + +#include <iostream> +#include <string> + +#include "boost/utility/value_init.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +int main() +{ + boost::value_initialized<int const> const cx_c ; + + get(cx_c) = 1234 ; // this should produce an ERROR + + return 0; +} diff --git a/src/boost/libs/utility/test/value_init_workaround_test.cpp b/src/boost/libs/utility/test/value_init_workaround_test.cpp new file mode 100644 index 00000000..9ffdffc5 --- /dev/null +++ b/src/boost/libs/utility/test/value_init_workaround_test.cpp @@ -0,0 +1,163 @@ +// Copyright 2010, Niels Dekker. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Test program for the boost::value_initialized<T> workaround. +// +// 17 June 2010 (Created) Niels Dekker + +// Switch the workaround off, before inluding "value_init.hpp". +#define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0 +#include <boost/utility/value_init.hpp> + +#include <iostream> // For cout. +#include <cstdlib> // For EXIT_SUCCESS and EXIT_FAILURE. + +namespace +{ + struct empty_struct + { + }; + + // A POD aggregate struct derived from an empty struct. + // Similar to struct Foo1 from Microsoft Visual C++ bug report 484295, + // "VC++ does not value-initialize members of derived classes without + // user-declared constructor", reported in 2009 by Sylvester Hesp: + // https://connect.microsoft.com/VisualStudio/feedback/details/484295 + struct derived_struct: empty_struct + { + int data; + }; + + bool is_value_initialized(const derived_struct& arg) + { + return arg.data == 0; + } + + + class virtual_destructor_holder + { + public: + int i; + virtual ~virtual_destructor_holder() + { + } + }; + + bool is_value_initialized(const virtual_destructor_holder& arg) + { + return arg.i == 0; + } + + // Equivalent to the Stats class from GCC Bug 33916, + // "Default constructor fails to initialize array members", reported in 2007 by + // Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 + // and fixed for GCC 4.2.4. + class private_int_array_pair + { + friend bool is_value_initialized(const private_int_array_pair& arg); + private: + int first[12]; + int second[12]; + }; + + bool is_value_initialized(const private_int_array_pair& arg) + { + for ( unsigned i = 0; i < 12; ++i) + { + if ( (arg.first[i] != 0) || (arg.second[i] != 0) ) + { + return false; + } + } + return true; + } + + struct int_pair_struct + { + int first; + int second; + }; + + typedef int int_pair_struct::*ptr_to_member_type; + + struct ptr_to_member_struct + { + ptr_to_member_type data; + }; + + bool is_value_initialized(const ptr_to_member_struct& arg) + { + return arg.data == 0; + } + + template <typename T> + bool is_value_initialized(const T(& arg)[2]) + { + return + is_value_initialized(arg[0]) && + is_value_initialized(arg[1]); + } + + template <typename T> + bool is_value_initialized(const boost::value_initialized<T>& arg) + { + return is_value_initialized(arg.data()); + } + + // Returns zero when the specified object is value-initializated, and one otherwise. + // Prints a message to standard output if the value-initialization has failed. + template <class T> + unsigned failed_to_value_initialized(const T& object, const char *const object_name) + { + if ( is_value_initialized(object) ) + { + return 0u; + } + else + { + std::cout << "Note: Failed to value-initialize " << object_name << '.' << std::endl; + return 1u; + } + } + +// A macro that passed both the name and the value of the specified object to +// the function above here. +#define FAILED_TO_VALUE_INITIALIZE(value) failed_to_value_initialized(value, #value) + + // Equivalent to the dirty_stack() function from GCC Bug 33916, + // "Default constructor fails to initialize array members", reported in 2007 by + // Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 + void dirty_stack() + { + unsigned char array_on_stack[4096]; + for (unsigned i = 0; i < sizeof(array_on_stack); ++i) + { + array_on_stack[i] = 0x11; + } + } + +} + + +int main() +{ + dirty_stack(); + + // TODO More types may be added later. + const unsigned num_failures = + FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<derived_struct>()) + + FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<virtual_destructor_holder[2]>()) + + FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<private_int_array_pair>()) + + FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<ptr_to_member_struct>()); + +#ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED + // One or more failures are expected. + return num_failures > 0 ? EXIT_SUCCESS : EXIT_FAILURE; +#else + // No failures are expected. + return num_failures == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +#endif +} |