From d809d4e832c4b0971a0ce3d3d35df6da445093fe Mon Sep 17 00:00:00 2001 From: nobody Date: Tue, 21 Mar 2006 02:26:31 +0000 Subject: [PATCH 001/126] This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'. [SVN r33417] From d968b5f5b9b733a7c3b3d765604c8888732e6ea5 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Thu, 27 Jul 2006 11:48:49 +0000 Subject: [PATCH 002/126] boost guidelines (mainly from inspect tool: tabs, license reference text, etc.); more to do... [SVN r34753] --- include/boost/utility/value_init.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/utility/value_init.hpp b/include/boost/utility/value_init.hpp index d991486..3d44491 100644 --- a/include/boost/utility/value_init.hpp +++ b/include/boost/utility/value_init.hpp @@ -1,4 +1,4 @@ -// (C) 2002, Fernando Luis Cacciola Carballal. +// 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 From 505d419a1b9daef0221bcd987261ba1ade342912 Mon Sep 17 00:00:00 2001 From: Hartmut Kaiser Date: Fri, 8 Sep 2006 00:16:31 +0000 Subject: [PATCH 003/126] Resolved an ambiguity. [SVN r35039] --- include/boost/utility/value_init.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/utility/value_init.hpp b/include/boost/utility/value_init.hpp index 3d44491..d24908c 100644 --- a/include/boost/utility/value_init.hpp +++ b/include/boost/utility/value_init.hpp @@ -40,7 +40,7 @@ template struct select_base { typedef typename - detail::if_true< ::boost::is_const::value > + boost::detail::if_true< ::boost::is_const::value > ::template then< const_T_base, non_const_T_base >::type type ; } ; From 6dd93ab91631827b98ad746be5478d026c6cec8c Mon Sep 17 00:00:00 2001 From: John Maddock Date: Mon, 16 Oct 2006 18:01:40 +0000 Subject: [PATCH 004/126] Removed unneeded semicolon. [SVN r35636] --- call_traits.htm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/call_traits.htm b/call_traits.htm index 53f093e..6d9bddf 100644 --- a/call_traits.htm +++ b/call_traits.htm @@ -606,7 +606,7 @@ template <bool opt> struct filler { template <typename I, typename T> - static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val); + static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val) { while(first != last) { @@ -762,3 +762,4 @@ href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost.

 

+ From 95da2e90de755facd0046990a7c24ef131a4183f Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Mon, 6 Nov 2006 17:10:46 +0000 Subject: [PATCH 005/126] Remove obsolete Boost.Build v1 files. [SVN r35880] --- enable_if/test/Jamfile | 33 -------------------------------- test/Jamfile | 43 ------------------------------------------ 2 files changed, 76 deletions(-) delete mode 100644 enable_if/test/Jamfile delete mode 100755 test/Jamfile diff --git a/enable_if/test/Jamfile b/enable_if/test/Jamfile deleted file mode 100644 index f2e5ee3..0000000 --- a/enable_if/test/Jamfile +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright David Abrahams 2003. -# 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/ - -subproject libs/utility/enable_if/test ; - -# bring in rules for testing -import testing ; - -# Make tests run by default. -DEPENDS all : test ; - -{ - local test_monitor = @boost/libs/test/build/boost_test_exec_monitor ; - - # look in BOOST_ROOT for sources first, just in this Jamfile - local SEARCH_SOURCE = $(BOOST_ROOT) $(SEARCH_SOURCE) ; - - test-suite utility/enable_if - : - [ run libs/utility/enable_if/test/constructors.cpp $(test_monitor) ] - [ run libs/utility/enable_if/test/dummy_arg_disambiguation.cpp $(test_monitor) ] - [ run libs/utility/enable_if/test/lazy.cpp $(test_monitor) ] - [ run libs/utility/enable_if/test/lazy_test.cpp $(test_monitor) ] - [ run libs/utility/enable_if/test/member_templates.cpp $(test_monitor) ] - [ run libs/utility/enable_if/test/namespace_disambiguation.cpp $(test_monitor) ] - [ run libs/utility/enable_if/test/no_disambiguation.cpp $(test_monitor) ] - [ run libs/utility/enable_if/test/partial_specializations.cpp $(test_monitor) ] - ; -} diff --git a/test/Jamfile b/test/Jamfile deleted file mode 100755 index 89d77d0..0000000 --- a/test/Jamfile +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright David Abrahams 2003. Permission to copy, use, -# modify, sell and distribute this software is granted provided this -# copyright notice appears in all copies. This software is provided -# "as is" without express or implied warranty, and with no claim as -# to its suitability for any purpose. - -# For more information, see http://www.boost.org/ - -subproject libs/utility/test ; - -# bring in rules for testing -import testing ; - -# Make tests run by default. -DEPENDS all : test ; - -local test_monitor = @boost/libs/test/build/boost_test_exec_monitor ; - -# Please keep the tests ordered by filename -test-suite utility - : - [ run ../addressof_test.cpp ] - [ run ../assert_test.cpp ] - [ run ../base_from_member_test.cpp ] - [ run ../binary_search_test.cpp ] - [ run ../call_traits_test.cpp : -u ] - [ compile-fail ../checked_delete_test.cpp ] - [ run ../compressed_pair_test.cpp $(test_monitor) : -u ] - [ run ../current_function_test.cpp : : : always_show_run_output ] - [ run ../iterators_test.cpp $(test_monitor) ] - [ run next_prior_test.cpp $(test_monitor) ] - [ compile-fail ../noncopyable_test.cpp ] - [ run ../numeric_traits_test.cpp ] - [ run ../operators_test.cpp $(test_monitor) ] - [ compile ../ref_ct_test.cpp ] - [ run ../ref_test.cpp $(test_monitor) ] - [ compile result_of_test.cpp ] - [ run ../shared_iterator_test.cpp ] - [ run ../value_init_test.cpp ] - [ compile-fail ../value_init_test_fail1.cpp ] - [ compile-fail ../value_init_test_fail2.cpp ] - [ compile-fail ../value_init_test_fail3.cpp ] - ; From ee3551e8dc1b4ba92d6af74fae49ba01dc8b1b58 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Tue, 7 Nov 2006 19:27:00 +0000 Subject: [PATCH 006/126] Merged copyright and license addition [SVN r35907] --- index.html | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 677539c..daf785e 100644 --- a/index.html +++ b/index.html @@ -27,8 +27,13 @@ value_init


+

© Copyright Beman Dawes, 2001

+

Distributed under the Boost Software License, Version 1.0. (See + accompanying file + LICENSE_1_0.txt or copy at + + www.boost.org/LICENSE_1_0.txt)

Revised - 01 September, 2003

-

 

- - + 07 November, 2006

+ + \ No newline at end of file From 3c7b4094602c652d22393747947a796c49aaa02f Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 9 Nov 2006 20:34:33 +0000 Subject: [PATCH 007/126] License/copyright edits [SVN r35958] --- assert.html | 7 +++---- checked_delete.html | 7 +++---- current_function.html | 7 +++---- throw_exception.html | 7 +++---- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/assert.html b/assert.html index a3dec66..4381ae1 100644 --- a/assert.html +++ b/assert.html @@ -48,9 +48,8 @@ void assertion_failed(char const * expr, char const * function, char const * fil can be included multiple times in a single translation unit. BOOST_ASSERT will be redefined each time as specified above.


- Copyright © 2002 by Peter Dimov. Permission to copy, use, modify, sell and - distribute this document is granted provided this copyright notice appears in - all copies. This document is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose.

+ Copyright © 2002 by Peter Dimov. Distributed under the Boost Software License, Version + 1.0. See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt.

diff --git a/checked_delete.html b/checked_delete.html index c123fd5..33b5bcb 100644 --- a/checked_delete.html +++ b/checked_delete.html @@ -115,9 +115,8 @@ template<class T> struct checked_array_deleter


- Copyright © 2002 by Peter Dimov. Permission to copy, use, modify, sell and - distribute this document is granted provided this copyright notice appears in - all copies. This document is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose.

+ Copyright © 2002 by Peter Dimov. Distributed under the Boost Software License, Version + 1.0. See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt.

diff --git a/current_function.html b/current_function.html index f383e3a..373eb22 100644 --- a/current_function.html +++ b/current_function.html @@ -29,9 +29,8 @@ function. On such compilers, the string literal has an unspecified value.


- Copyright © 2002 by Peter Dimov. Permission to copy, use, modify, sell and - distribute this document is granted provided this copyright notice appears in - all copies. This document is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose.

+ Copyright © 2002 by Peter Dimov. Distributed under the Boost Software License, Version + 1.0. See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt.

diff --git a/throw_exception.html b/throw_exception.html index 89466fb..66a63f3 100644 --- a/throw_exception.html +++ b/throw_exception.html @@ -51,9 +51,8 @@ template<class E> void throw_exception(E const & e) }


- Copyright © 2002 by Peter Dimov. Permission to copy, use, modify, sell and - distribute this document is granted provided this copyright notice appears in - all copies. This document is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose.

+ Copyright © 2002 by Peter Dimov. Distributed under the Boost Software License, Version + 1.0. See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt.

From d9f8bae673d56ee7425f32657ac9e19310c6f14f Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Fri, 10 Nov 2006 19:59:52 +0000 Subject: [PATCH 008/126] Merge from HEAD. Allow building of shared versions of some Boost.Test libraries. Adjust tests to use always use static linking to Boost.Test, since linking to the shared version requires test changes. Patch from Juergen Hunold. [SVN r35990] --- test/Jamfile.v2 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 493011d..d5ecaa0 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -18,15 +18,15 @@ test-suite utility [ run ../binary_search_test.cpp ] [ run ../call_traits_test.cpp : -u ] [ compile-fail ../checked_delete_test.cpp ] - [ run ../compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor : -u ] + [ run ../compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor/static : -u ] [ run ../current_function_test.cpp : : : always_show_run_output ] - [ run ../iterators_test.cpp ../../test/build//boost_test_exec_monitor ] - [ run next_prior_test.cpp ../../test/build//boost_test_exec_monitor ] + [ run ../iterators_test.cpp ../../test/build//boost_test_exec_monitor/static ] + [ run next_prior_test.cpp ../../test/build//boost_test_exec_monitor/static ] [ compile-fail ../noncopyable_test.cpp ] [ run ../numeric_traits_test.cpp ] - [ run ../operators_test.cpp ../../test/build//boost_test_exec_monitor ] + [ run ../operators_test.cpp ../../test/build//boost_test_exec_monitor/static ] [ compile ../ref_ct_test.cpp ] - [ run ../ref_test.cpp ../../test/build//boost_test_exec_monitor ] + [ run ../ref_test.cpp ../../test/build//boost_test_exec_monitor/static ] [ compile result_of_test.cpp ] [ run ../shared_iterator_test.cpp ] [ run ../value_init_test.cpp ] From 30a40f9f76111c31928165f132bb60aa6d151e8b Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 4 Dec 2006 20:31:38 +0000 Subject: [PATCH 009/126] Linked to current_function.html [SVN r36268] --- index.html | 1 + utility.htm | 1 + 2 files changed, 2 insertions(+) diff --git a/index.html b/index.html index daf785e..1d2bffb 100644 --- a/index.html +++ b/index.html @@ -19,6 +19,7 @@ call_traits
checked_delete
compressed_pair
+ current_function
enable_if
iterator_adaptors
operators
diff --git a/utility.htm b/utility.htm index 16616ad..8d8d80f 100644 --- a/utility.htm +++ b/utility.htm @@ -23,6 +23,7 @@
  • Function template addressof()
  • Class template result_of
  • +
  • Other utilities not part of utility.hpp
  • Function templates checked_delete() and From 09f7aab52dbeff7507e07ed11ac302d1c79916b5 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Tue, 5 Dec 2006 22:33:21 +0000 Subject: [PATCH 010/126] Merged L & C issue fixes & HTML conversions from trunk to branch. [SVN r36281] --- Assignable.html | 199 ++++--- Collection.html | 1036 ++++++++++++++++------------------- CopyConstructible.html | 303 +++++----- LessThanComparable.html | 394 +++++++------ MultiPassInputIterator.html | 157 +++--- generator_iterator.htm | 173 +++--- 6 files changed, 1065 insertions(+), 1197 deletions(-) diff --git a/Assignable.html b/Assignable.html index 557f4e7..54934f1 100644 --- a/Assignable.html +++ b/Assignable.html @@ -1,116 +1,109 @@ - - - -Assignable - - -C++ Boost - -
    -

    Assignable

    + -

    Description

    -A type is Assignable if it is possible to assign one object of the type -to another object of that type. + + + + + Assignable + -

    Notation

    - - - - - + + C++ Boost
    - - - - +

    Assignable

    - - - - +

    Description

    -
    -T - -is type that is a model of Assignable -
    -t - -is an object of type T -
    -u - -is an object of type T or possibly const T -
    -

    Definitions

    -

    Valid expressions

    - - - - - - - - - - - - - +

    A type is Assignable if it is possible to assign one object of the type + to another object of that type.

    -
    -Name - -Expression - -Return type - -Semantics -
    -Assignment - -t = u - -T& - -t is equivalent to u -
    +

    Notation

    + + + -
    T
    -

    Models

    + is type that is a model of Assignable + -
      -
    • int -
    • std::pair -
    + + t -

    See also

    -DefaultConstructible -and -CopyConstructible + is an object of type T + -
    -
    - - -
    Copyright © 2000 -Jeremy Siek, Univ.of Notre Dame (jsiek@lsc.nd.edu) -
    + + u - - + is an object of type T or possibly const + T + + + +

    Definitions

    + +

    Valid expressions

    + + + + + + + + + + + + + + + + + + + + + +
    NameExpressionReturn typeSemantics
    Assignmentt = uT&t is equivalent to u
    + +

    Models

    + +
      +
    • int
    • + +
    • std::pair
    • +
    + +

    See also

    + +

    DefaultConstructible + and CopyConstructible

    +
    + +

    Valid HTML 4.01 Transitional

    + +

    Revised + 05 December, 2006

    + + + + + + + +
    Copyright © 2000Jeremy Siek, Univ.of + Notre Dame (jsiek@lsc.nd.edu)
    + +

    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)

    + + diff --git a/Collection.html b/Collection.html index 9069e28..c811e7e 100644 --- a/Collection.html +++ b/Collection.html @@ -1,244 +1,190 @@ - - - -Collection - + - -

    - boost logo -
    Collection -

    + + + + -

    Description

    + Collection + -A Collection is a concept similar to the STL Container -concept. A Collection provides iterators for accessing a range of -elements and provides information about the number of elements in the -Collection. However, a Collection has fewer requirements than a -Container. The motivation for the Collection concept is that there are -many useful Container-like types that do not meet the full -requirements of Container, and many algorithms that can be written -with this reduced set of requirements. To summarize the reduction -in requirements: + +

    boost logo
    + Collection

    -
      -
    • It is not required to "own" its elements: the lifetime -of an element in a Collection does not have to match the lifetime of -the Collection object, though the lifetime of the element should cover -the lifetime of the Collection object. -
    • The semantics of copying a Collection object is not defined (it -could be a deep or shallow copy or not even support copying). -
    • The associated reference type of a Collection does -not have to be a real C++ reference. -
    +

    Description

    +

    A Collection is a concept similar to the STL Container concept. A + Collection provides iterators for accessing a range of elements and + provides information about the number of elements in the Collection. + However, a Collection has fewer requirements than a Container. The + motivation for the Collection concept is that there are many useful + Container-like types that do not meet the full requirements of Container, + and many algorithms that can be written with this reduced set of + requirements. To summarize the reduction in requirements:

    -Because of the reduced requirements, some care must be taken when -writing code that is meant to be generic for all Collection types. -In particular, a Collection object should be passed by-reference -since assumptions can not be made about the behaviour of the -copy constructor. +
      +
    • It is not required to "own" its elements: the lifetime of an element + in a Collection does not have to match the lifetime of the Collection + object, though the lifetime of the element should cover the lifetime of + the Collection object.
    • -

      +

    • The semantics of copying a Collection object is not defined (it could + be a deep or shallow copy or not even support copying).
    • -

      Associated types

      +
    • The associated reference type of a Collection does not have to be a + real C++ reference.
    • +
    Because of the reduced requirements, some care must be taken when + writing code that is meant to be generic for all Collection types. In + particular, a Collection object should be passed by-reference since + assumptions can not be made about the behaviour of the copy constructor. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -Value type - -X::value_type - -The type of the object stored in a Collection. -If the Collection is mutable then -the value type must be Assignable. -Otherwise the value type must be CopyConstructible. -
    -Iterator type - -X::iterator - -The type of iterator used to iterate through a Collection's - elements. The iterator's value type is expected to be the - Collection's value type. A conversion - from the iterator type to the const iterator type must exist. - The iterator type must be an InputIterator. -
    -Const iterator type - -X::const_iterator - -A type of iterator that may be used to examine, but not to modify, - a Collection's elements. -
    -Reference type - -X::reference - -A type that behaves like a reference to the Collection's value type. -[1] -
    -Const reference type - -X::const_reference - -A type that behaves like a const reference to the Collection's value type. -
    -Pointer type - -X::pointer - -A type that behaves as a pointer to the Collection's value type. -
    -Distance type - -X::difference_type - -A signed integral type used to represent the distance between two - of the Collection's iterators. This type must be the same as - the iterator's distance type. -
    -Size type - -X::size_type - -An unsigned integral type that can represent any nonnegative value - of the Collection's distance type. -
    -

    Notation

    - - - - - - - - - - - - - -
    -X - -A type that is a model of Collection. -
    -a, b - -Object of type X. -
    -T - -The value type of X. -
    +

    Associated types

    -

    Valid expressions

    + + + -The following expressions must be valid. -

    +

    -
    Value typeX::value_type
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -Name - -Expression - -Return type -
    -Beginning of range - -a.begin() - -iterator if a is mutable, const_iterator otherwise -
    -End of range - -a.end() - -iterator if a is mutable, const_iterator otherwise -
    -Size - -a.size() - -size_type -
    -Empty Collection - -a.empty() - -Convertible to bool -
    -Swap - -a.swap(b) - -void -
    -

    Expression semantics

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -Name - -Expression - -Semantics - -Postcondition -
    -
    -Beginning of range - -a.begin() - -Returns an iterator pointing to the first element in the Collection. - -a.begin() is either dereferenceable or past-the-end. It is - past-the-end if and only if a.size() == 0. -
    -End of range - -a.end() - -Returns an iterator pointing one past the last element in the - Collection. - -a.end() is past-the-end. -
    -Size - -a.size() - -Returns the size of the Collection, that is, its number of elements. - -a.size() >= 0 -
    -Empty Collection - -a.empty() - -Equivalent to a.size() == 0. (But possibly faster.) - -  -
    -Swap - -a.swap(b) - -Equivalent to swap(a,b) - -  -
    -

    Complexity guarantees

    -begin() and end() are amortized constant time. -

    -size() is at most linear in the Collection's -size. empty() is amortized constant time. -

    -swap() is at most linear in the size of the two collections. -

    Invariants

    - - - - - - - - - - - - - -
    -Valid range - -For any Collection a, [a.begin(), a.end()) is a valid - range. -
    -Range size - -a.size() is equal to the distance from a.begin() to a.end(). -
    -Completeness - -An algorithm that iterates through the range [a.begin(), a.end()) - will pass through every element of a. -
    + + Empty Collection + a.empty() -

    Models

    -
      -
    • array -
    • array_ptr -
    • vector<bool> -
    + Equivalent to a.size() == 0. (But possibly + faster.) +   + -

    Collection Refinements

    + + Swap -There are quite a few concepts that refine the Collection concept, -similar to the concepts that refine the Container concept. Here -is a brief overview of the refining concepts. + a.swap(b) -

    ForwardCollection

    -The elements are arranged in some order that -does not change spontaneously from one iteration to the next. As -a result, a ForwardCollection is -EqualityComparable -and -LessThanComparable. -In addition, the iterator type of a ForwardCollection is a -MultiPassInputIterator which is just an InputIterator with the added -requirements that the iterator can be used to make multiple passes -through a range, and that if it1 == it2 and it1 is -dereferenceable then ++it1 == ++it2. The ForwardCollection -also has a front() method. + Equivalent to swap(a,b) -

    - - - - - - - + + +
    -Name - -Expression - -Return type - -Semantics -
     
    - - -Front - - -a.front() - - -reference if a is mutable,
    const_reference -otherwise. - - -Equivalent to *(a.begin()). - - +

    Complexity guarantees

    - +

    begin() and end() are amortized constant time.

    +

    size() is at most linear in the Collection's size. + empty() is amortized constant time.

    -

    ReversibleCollection

    +

    swap() is at most linear in the size of the two + collections.

    -The container provides access to iterators that traverse in both -directions (forward and reverse). The iterator type must meet all of -the requirements of -BidirectionalIterator -except that the reference type does not have to be a real C++ -reference. The ReversibleCollection adds the following requirements -to those of ForwardCollection. -

    +

    Invariants

    - - - - - - - - - - - - - - - - - - - +
    -Name - -Expression - -Return type - -Semantics -
    -Beginning of range - -a.rbegin() - -reverse_iterator if a is mutable, -const_reverse_iterator otherwise. - -Equivalent to X::reverse_iterator(a.end()). -
    -End of range - -a.rend() - -reverse_iterator if a is mutable, -const_reverse_iterator otherwise. - -Equivalent to X::reverse_iterator(a.begin()). -
    + + - - - - - - + + -
    Valid range
    -Back - -a.back() - -reference if a is mutable,
    const_reference -otherwise. -
    -Equivalent to *(--a.end()). -
    For any Collection a, [a.begin(), + a.end()) is a valid range.
    + + Range size -

    SequentialCollection

    + a.size() is equal to the distance from + a.begin() to a.end(). + -The elements are arranged in a strict linear order. No extra methods -are required. + + Completeness -

    RandomAccessCollection

    + An algorithm that iterates through the range + [a.begin(), a.end()) will pass through every element of + a. + + -The iterators of a RandomAccessCollection satisfy all of the -requirements of RandomAccessIterator -except that the reference type does not have to be a real C++ -reference. In addition, a RandomAccessCollection provides -an element access operator. +

    Models

    -

    +

      +
    • array
    • - - - - - - - - - - - - - +
    • array_ptr
    • -
      -Name - -Expression - -Return type - -Semantics -
      -Element Access - -a[n] - -reference if a is mutable, -const_reference otherwise. - -Returns the nth element of the Collection. -n must be convertible to size_type. -Precondition: 0 <= n < a.size(). -
      +
    • vector<bool>
    • +
    -

    Notes

    +

    Collection Refinements

    -

    [1] +

    There are quite a few concepts that refine the Collection concept, + similar to the concepts that refine the Container concept. Here is a brief + overview of the refining concepts.

    -The reference type does not have to be a real C++ reference. The -requirements of the reference type depend on the context within which -the Collection is being used. Specifically it depends on the -requirements the context places on the value type of the Collection. -The reference type of the Collection must meet the same requirements -as the value type. In addition, the reference objects must be -equivalent to the value type objects in the collection (which is -trivially true if they are the same object). Also, in a mutable -Collection, an assignment to the reference object must result in an -assignment to the object in the Collection (again, which is trivially -true if they are the same object, but non-trivial if the reference -type is a proxy class). +

    ForwardCollection

    -

    See also

    -Container +

    The elements are arranged in some order that does not change + spontaneously from one iteration to the next. As a result, a + ForwardCollection is EqualityComparable + and LessThanComparable. + In addition, the iterator type of a ForwardCollection is a + MultiPassInputIterator which is just an InputIterator with the added + requirements that the iterator can be used to make multiple passes through + a range, and that if it1 == it2 and it1 is + dereferenceable then ++it1 == ++it2. The ForwardCollection also + has a front() method.

    + + + -
    -
    -
    Name
    - -
    Copyright © 2000 -Jeremy Siek, Univ.of Notre Dame and C++ Library & Compiler Group/SGI (jsiek@engr.sgi.com) -
    + Expression - - + Return type + + Semantics + + + + Front + + a.front() + + reference if a is mutable,
    + const_reference otherwise. + + Equivalent to *(a.begin()). + + + +

    ReversibleCollection

    + +

    The container provides access to iterators that traverse in both + directions (forward and reverse). The iterator type must meet all of the + requirements of BidirectionalIterator + except that the reference type does not have to be a real C++ reference. + The ReversibleCollection adds the following requirements to those of + ForwardCollection.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameExpressionReturn typeSemantics
    Beginning of rangea.rbegin()reverse_iterator if a is mutable, + const_reverse_iterator otherwise.Equivalent to + X::reverse_iterator(a.end()).
    End of rangea.rend()reverse_iterator if a is mutable, + const_reverse_iterator otherwise.Equivalent to + X::reverse_iterator(a.begin()).
    Backa.back()reference if a is mutable,
    + const_reference otherwise.
    Equivalent to *(--a.end()).
    + +

    SequentialCollection

    + +

    The elements are arranged in a strict linear order. No extra methods are + required.

    + +

    RandomAccessCollection

    + +

    The iterators of a RandomAccessCollection satisfy all of the + requirements of RandomAccessIterator + except that the reference type does not have to be a real C++ reference. In + addition, a RandomAccessCollection provides an element access operator.

    + + + + + + + + + + + + + + + + + + + + + +
    NameExpressionReturn typeSemantics
    Element Accessa[n]reference if a is mutable, + const_reference otherwise.Returns the nth element of the Collection. n + must be convertible to size_type. Precondition: 0 <= n + < a.size().
    + +

    Notes

    + +

    [1] The reference type does not have to be a + real C++ reference. The requirements of the reference type depend on the + context within which the Collection is being used. Specifically it depends + on the requirements the context places on the value type of the Collection. + The reference type of the Collection must meet the same requirements as the + value type. In addition, the reference objects must be equivalent to the + value type objects in the collection (which is trivially true if they are + the same object). Also, in a mutable Collection, an assignment to the + reference object must result in an assignment to the object in the + Collection (again, which is trivially true if they are the same object, but + non-trivial if the reference type is a proxy class).

    + +

    See also

    + +

    Container

    +
    + +

    Valid HTML 4.01 Transitional

    + +

    Revised + 05 + December, 2006

    + + + + + + + +
    Copyright © 2000Jeremy + Siek, Univ.of Notre Dame and C++ Library & Compiler Group/SGI + (jsiek@engr.sgi.com)
    + +

    Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt)

    + + diff --git a/CopyConstructible.html b/CopyConstructible.html index f2d6308..40ff7a7 100644 --- a/CopyConstructible.html +++ b/CopyConstructible.html @@ -1,178 +1,139 @@ - - - -Copy Constructible - - -C++ Boost - -
    -

    Copy Constructible

    + -

    Description

    -A type is Copy Constructible if it is possible to copy objects of that -type. + + + + -

    Notation

    - - - - - + Copy Constructible + - - - - + + C++ Boost
    - - - - +

    Copy Constructible

    -
    -T - -is type that is a model of Copy Constructible -
    -t - -is an object of type T -
    -u - -is an object of type const T -
    -

    Definitions

    -

    Valid expressions

    - - - - - - - - - - - - - +

    Description

    +

    A type is Copy Constructible if it is possible to copy objects of that + type.

    - - -
    -Name - -Expression - -Return type - -Semantics -
    -Copy constructor - -T(t) - -T - -t is equivalent to T(t) -
    -Copy constructor - -
    +  

    Notation

    + + + + + + + + + + + + + + + + + + + +
    Tis type that is a model of Copy Constructible
    tis an object of type T
    uis an object of type const T
    + +

    Definitions

    + +

    Valid expressions

    + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - - + + + + + + - - - + - - - + + + + + + + + - - - + - - - + + + + + + + + - - - + + + + +
    NameExpressionReturn typeSemantics
    Copy constructorT(t)Tt is equivalent to T(t)
    Copy constructor +
     T(u)
     
    -
    -T - -u is equivalent to T(u) -
    T
    -Destructor - -
    +      
    u is equivalent to T(u)
    Destructor +
     t.~T()
     
    -
    -T - -  -
    -Address Operator - -
    +      
    T 
    Address Operator +
     &t
     
    -
    -T* - -denotes the address of t -
    -Address Operator - -
    +      
    T*denotes the address of t
    Address Operator +
     &u
     
    -
    -T* - -denotes the address of u -
    T*denotes the address of u
    -
    +

    Models

    +
      +
    • int
    • - -

      Models

      +
    • std::pair
    • +
    -
      -
    • int -
    • std::pair -
    - -

    Concept Checking Class

    - -
    +  

    Concept Checking Class

    +
       template <class T>
       struct CopyConstructibleConcept
       {
    @@ -192,19 +153,33 @@ denotes the address of u
       };
     
    -

    See also

    -Default Constructible -and -Assignable +

    See also

    -
    -
    - - -
    Copyright © 2000 -Jeremy Siek, Univ.of Notre Dame (jsiek@lsc.nd.edu) -
    +

    Default + Constructible and Assignable

    +
    - - +

    Valid HTML 4.01 Transitional

    + +

    Revised + 05 + December, 2006

    + + + + + + + +
    Copyright © 2000Jeremy Siek, Univ.of + Notre Dame (jsiek@lsc.nd.edu)
    + +

    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)

    + + diff --git a/LessThanComparable.html b/LessThanComparable.html index 8913b38..a723377 100644 --- a/LessThanComparable.html +++ b/LessThanComparable.html @@ -1,212 +1,210 @@ - + + + - - -LessThanComparable - - -C++ Boost - -
    -

    LessThanComparable

    -

    Description

    -A type is LessThanComparable if it is ordered: it must -be possible to compare two objects of that type using operator<, and -operator< must be a strict weak ordering relation. + + + + LessThanComparable + -

    Refinement of

    -

    Associated types

    -

    Notation

    - - - - - - - - - -
    -X - -A type that is a model of LessThanComparable -
    -x, y, z - -Object of type X -
    -

    Definitions

    -Consider the relation !(x < y) && !(y < x). If this relation is -transitive (that is, if !(x < y) && !(y < x) && !(y < z) && !(z < y) -implies !(x < z) && !(z < x)), then it satisfies the mathematical -definition of an equivalence relation. In this case, operator< -is a strict weak ordering. -

    -If operator< is a strict weak ordering, and if each equivalence class -has only a single element, then operator< is a total ordering. -

    Valid expressions

    - - - - - - - - - - - - - -
    -Name - -Expression - -Type requirements - -Return type -
    -Less - -x < y - -  - -Convertible to bool -
    + + C++ Boost
    +

    LessThanComparable

    +

    Description

    -

    Expression semantics

    - - - - - - - - - - - - - -
    -Name - -Expression - -Precondition - -Semantics - -Postcondition -
    -Less - -x < y - -x and y are in the domain of < - -  -
    +

    A type is LessThanComparable if it is ordered: it must be possible to + compare two objects of that type using operator<, and + operator< must be a strict weak ordering relation.

    +

    Refinement of

    -

    Complexity guarantees

    -

    Invariants

    - - - - - - - - - - - - - -
    -Irreflexivity - -x < x must be false. -
    -Antisymmetry - -x < y implies !(y < x) [2] -
    -Transitivity - -x < y and y < z implies x < z [3] -
    -

    Models

    -
      -
    • -int -
    -

    Notes

    -

    [1] -Only operator< is fundamental; the other inequality operators -are essentially syntactic sugar. -

    [2] -Antisymmetry is a theorem, not an axiom: it follows from -irreflexivity and transitivity. -

    [3] -Because of irreflexivity and transitivity, operator< always -satisfies the definition of a partial ordering. The definition of -a strict weak ordering is stricter, and the definition of a -total ordering is stricter still. -

    See also

    -EqualityComparable, StrictWeakOrdering +

    Associated types

    +

    Notation

    + + + -
    -
    -
    X
    - -
    Copyright © 2000 -Jeremy Siek, Univ.of Notre Dame (jsiek@lsc.nd.edu) -
    + A type that is a model of LessThanComparable + - - + + x, y, z + + Object of type X + + + +

    Definitions

    + +

    Consider the relation !(x < y) && !(y < x). If + this relation is transitive (that is, if !(x < y) && !(y + < x) && !(y < z) && !(z < y) implies !(x + < z) && !(z < x)), then it satisfies the mathematical + definition of an equivalence relation. In this case, operator< + is a strict weak ordering.

    + +

    If operator< is a strict weak ordering, and if each + equivalence class has only a single element, then operator< is + a total ordering.

    + +

    Valid expressions

    + + + + + + + + + + + + + + + + + + + + + +
    NameExpressionType requirementsReturn type
    Lessx < y Convertible to bool
    + +

    Expression semantics

    + + + + + + + + + + + + + + + + + + + + + + + +
    NameExpressionPreconditionSemanticsPostcondition
    Lessx < yx and y are in the domain of + < 
    + +

    Complexity guarantees

    + +

    Invariants

    + + + + + + + + + + + + + + + + + + + +
    Irreflexivityx < x must be false.
    Antisymmetryx < y implies !(y < x) [2]
    Transitivityx < y and y < z implies x + < z [3]
    + +

    Models

    + +
      +
    • int
    • +
    + +

    Notes

    + +

    [1] Only operator< is fundamental; + the other inequality operators are essentially syntactic sugar.

    + +

    [2] Antisymmetry is a theorem, not an axiom: it + follows from irreflexivity and transitivity.

    + +

    [3] Because of irreflexivity and transitivity, + operator< always satisfies the definition of a partial + ordering. The definition of a strict weak ordering is stricter, + and the definition of a total ordering is stricter still.

    + +

    See also

    + +

    EqualityComparable, + StrictWeakOrdering
    +

    +
    + +

    Valid HTML 4.01 Transitional

    + +

    Revised + 05 + December, 2006

    + + + + + + + +
    Copyright © 2000Jeremy Siek, Univ.of + Notre Dame (jsiek@lsc.nd.edu)
    + +

    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)

    + + diff --git a/MultiPassInputIterator.html b/MultiPassInputIterator.html index dec6e31..fa7517c 100644 --- a/MultiPassInputIterator.html +++ b/MultiPassInputIterator.html @@ -1,92 +1,95 @@ - - - -MultiPassInputIterator - -C++ Boost + -
    + + + + -

    - -Multi-Pass Input Iterator -

    + MultiPassInputIterator + -This concept is a refinement of Input Iterator, -adding the requirements that the iterator can be used to make multiple -passes through a range, and that if it1 == it2 and -it1 is dereferenceable then ++it1 == ++it2. The -Multi-Pass Input Iterator is very similar to the Forward Iterator. The -only difference is that a Forward Iterator -requires the reference type to be value_type&, whereas -MultiPassInputIterator is like Input Iterator -in that the reference type merely has to be convertible to -value_type. + + C++ Boost
    +

    Multi-Pass Input Iterator

    -

    Design Notes

    +

    This concept is a refinement of Input Iterator, adding + the requirements that the iterator can be used to make multiple passes + through a range, and that if it1 == it2 and it1 is + dereferenceable then ++it1 == ++it2. The Multi-Pass Input Iterator + is very similar to the Forward Iterator. + The only difference is that a Forward Iterator + requires the reference type to be value_type&, + whereas MultiPassInputIterator is like Input Iterator in that + the reference type merely has to be convertible to + value_type.

    -comments by Valentin Bonnard: +

    Design Notes

    -

    I think that introducing Multi-Pass Input Iterator isn't the right -solution. Do you also want to define Multi-Pass Bidirectionnal Iterator -and Multi-Pass Random Access Iterator ? I don't, definitly. It only -confuses the issue. The problem lies into the existing hierarchy of -iterators, which mixes movabillity, modifiabillity and lvalue-ness, -and these are clearly independant. +

    comments by Valentin Bonnard:

    -

    The terms Forward, Bidirectionnal and Random Access are about -movabillity and shouldn't be used to mean anything else. In a -completly orthogonal way, iterators can be immutable, mutable, or -neither. Lvalueness of iterators is also orthogonal with -immutabillity. With these clean concepts, your Multi-Pass Input Iterator -is just called a Forward Iterator. +

    I think that introducing Multi-Pass Input Iterator isn't the right + solution. Do you also want to define Multi-Pass Bidirectionnal Iterator and + Multi-Pass Random Access Iterator ? I don't, definitly. It only confuses + the issue. The problem lies into the existing hierarchy of iterators, which + mixes movabillity, modifiabillity and lvalue-ness, and these are clearly + independant.

    -

    -Other translations are:
    -std::Forward Iterator -> ForwardIterator & Lvalue Iterator
    -std::Bidirectionnal Iterator -> Bidirectionnal Iterator & Lvalue Iterator
    -std::Random Access Iterator -> Random Access Iterator & Lvalue Iterator
    +

    The terms Forward, Bidirectionnal and Random Access are about + movabillity and shouldn't be used to mean anything else. In a completly + orthogonal way, iterators can be immutable, mutable, or neither. Lvalueness + of iterators is also orthogonal with immutabillity. With these clean + concepts, your Multi-Pass Input Iterator is just called a Forward + Iterator.

    -

    -Note that in practice the only operation not allowed on my -Forward Iterator which is allowed on std::Forward Iterator is -&*it. I think that &* is rarely needed in generic code. +

    Other translations are:
    + std::Forward Iterator -> ForwardIterator & Lvalue Iterator
    + std::Bidirectionnal Iterator -> Bidirectionnal Iterator & Lvalue + Iterator
    + std::Random Access Iterator -> Random Access Iterator & Lvalue + Iterator

    -

    -reply by Jeremy Siek: +

    Note that in practice the only operation not allowed on my Forward + Iterator which is allowed on std::Forward Iterator is &*it. I + think that &* is rarely needed in generic code.

    -

    -The above analysis by Valentin is right on. Of course, there is -the problem with backward compatibility. The current STL implementations -are based on the old definition of Forward Iterator. The right course -of action is to get Forward Iterator, etc. changed in the C++ standard. -Once that is done we can drop Multi-Pass Input Iterator. +

    reply by Jeremy Siek:

    +

    The above analysis by Valentin is right on. Of course, there is the + problem with backward compatibility. The current STL implementations are + based on the old definition of Forward Iterator. The right course of action + is to get Forward Iterator, etc. changed in the C++ standard. Once that is + done we can drop Multi-Pass Input Iterator.

    +
    -
    -
    - - -
    Copyright © 2000 -Jeremy Siek, Univ.of Notre Dame (jsiek@lsc.nd.edu) -
    +

    Valid HTML 4.01 Transitional

    - - +

    Revised + 05 + December, 2006

    + + + + + + + +
    Copyright © 2000Jeremy Siek, Univ.of + Notre Dame (jsiek@lsc.nd.edu)
    + +

    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)

    + + diff --git a/generator_iterator.htm b/generator_iterator.htm index fd3e3fc..c81d3d1 100644 --- a/generator_iterator.htm +++ b/generator_iterator.htm @@ -1,33 +1,37 @@ - + -Generator Iterator Adaptor Documentation + + + + Generator Iterator Adaptor Documentation - -boost.png (6897 bytes) + boost.png (6897 bytes) -

    Generator Iterator Adaptor

    -Defined in header boost/generator_iterator.hpp -

    -The generator iterator adaptor makes it easier to create custom input -iterators from 0-ary functions and function objects. The adaptor -takes a -Generator -and creates a model of -Input Iterator. -Each increment retrieves an item from the generator and makes it -available to be retrieved by dereferencing. The motivation for this -iterator is that some concepts can be more naturally expressed as a -generator, while most STL algorithms expect an iterator. An example -is the Random Number library. +

    Generator Iterator Adaptor

    -

    Synopsis

    +

    Defined in header boost/generator_iterator.hpp

    -
    -
    +  

    The generator iterator adaptor makes it easier to create custom input + iterators from 0-ary functions and function objects. The adaptor takes a + Generator and + creates a model of Input Iterator. Each + increment retrieves an item from the generator and makes it available to be + retrieved by dereferencing. The motivation for this iterator is that some + concepts can be more naturally expressed as a generator, while most STL + algorithms expect an iterator. An example is the Random Number library.

    + +

    Synopsis

    + +
    +
     namespace boost {
       template <class Generator>
       class generator_iterator_policies;
    @@ -40,21 +44,19 @@ namespace boost {
       make_generator_iterator(Generator & gen);
     }
     
    -
    +
    +
    -
    +

    The Generator Iterator Generator Class

    -

    The Generator Iterator Generator Class

    - -The class generator_iterator_generator is a helper class whose purpose -is to construct a generator iterator type. The template parameter for -this class is the Generator function object type that is being -wrapped. The generator iterator adaptor only holds a reference (or -pointer) to the function object, therefore the function object must -outlive the generator iterator adaptor constructed from it. - -
    -template <class Generator>
    +  

    The class generator_iterator_generator is a helper class whose purpose + is to construct a generator iterator type. The template parameter for this + class is the Generator function object type that is being wrapped. The + generator iterator adaptor only holds a reference (or pointer) to the + function object, therefore the function object must outlive the generator + iterator adaptor constructed from it.

    +
    +template <class Generator>
     class generator_iterator_generator
     {
     public:
    @@ -62,65 +64,65 @@ public:
     }
     
    +

    Template Parameters

    -

    Template Parameters

    + + + -
    Parameter
    - - - - + + - - -
    ParameterDescription
    Description
    Generator -The generator (0-ary function object) type being -wrapped. The return type of the function must be defined as -Generator::result_type. The function object must be a model -of -Generator. -
    + + Generator -

    Concept Model

    -The generator iterator class is a model of -Input Iterator. + The generator (0-ary function object) type being wrapped. The + return type of the function must be defined as + Generator::result_type. The function object must be a model of + Generator. + + -

    Members

    -The generator iterator implements the member functions -and operators required of the -Input Iterator -concept. +

    Concept Model

    -
    +

    The generator iterator class is a model of Input Iterator.

    -
    -

    The Generator Iterator Object Generator

    +

    Members

    -The make_generator_iterator() function provides a -convenient way to create generator iterator objects. The function -saves the user the trouble of explicitly writing out the iterator -types. +

    The generator iterator implements the member functions and operators + required of the Input Iterator + concept.

    +
    -
    -
    +  

    The + Generator Iterator Object Generator

    + +

    The make_generator_iterator() function provides a convenient + way to create generator iterator objects. The function saves the user the + trouble of explicitly writing out the iterator types.

    + +
    +
     template <class Generator>
     typename generator_iterator_generator<Generator>::type
     make_generator_iterator(Generator & gen);
     
    -
    +
    +
    -
    +

    Example

    +

    The following program shows how generator_iterator + transforms a generator into an input iterator.

    -

    Example

    - -The following program shows how generator_iterator -transforms a generator into an input iterator. - -
    -
    -#include <iostream>
    -#include <boost/generator_iterator.hpp>
    +  
    +
    +#include <iostream>
    +#include <boost/generator_iterator.hpp>
     
     class my_generator
     {
    @@ -140,11 +142,22 @@ int main()
         std::cout << *it << std::endl;
     }
     
    -
    +
    +
    -
    +

    Valid HTML 4.01 Transitional

    -Written by Jens Maurer. +

    Revised + 05 December, 2006

    +

    Copyright © 2001 Jens Maurer

    + +

    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)

    From 005c2f3cc8b3cbef266c0d30f8512f338a662ef5 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 7 Jan 2007 22:58:41 +0000 Subject: [PATCH 011/126] Fix a couple of links. [SVN r36656] --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 1d2bffb..b08822b 100644 --- a/index.html +++ b/index.html @@ -30,11 +30,11 @@

    © Copyright Beman Dawes, 2001

    Distributed under the Boost Software License, Version 1.0. (See - accompanying file + accompanying file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt)

    Revised 07 November, 2006

    - \ No newline at end of file + From aa0096bf42209c92261d0ae11d1460c7ced06c4a Mon Sep 17 00:00:00 2001 From: Fernando Cacciola Date: Thu, 12 Apr 2007 14:32:38 +0000 Subject: [PATCH 012/126] Testsuite for none_t added. [SVN r37421] --- test/Jamfile.v2 | 1 + test/none_test.cpp | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 test/none_test.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index d5ecaa0..330c08c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -33,4 +33,5 @@ test-suite utility [ compile-fail ../value_init_test_fail1.cpp ] [ compile-fail ../value_init_test_fail2.cpp ] [ compile-fail ../value_init_test_fail3.cpp ] + [ run none_test.cpp ] ; diff --git a/test/none_test.cpp b/test/none_test.cpp new file mode 100644 index 0000000..00a6fc9 --- /dev/null +++ b/test/none_test.cpp @@ -0,0 +1,22 @@ +// Copyright 2007 Fernando Luis Cacciola Carballal. 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 documentation. + +// Boost test program for noost::none_t and boost::none + +// Test strategy contributed by Richard Smith + +#include // Test none.hpp is included with + +// Left undefined to cause a linker error if this overload is incorrectly selected. +void verify_no_implicit_conversion_to_int ( int i ) ; + +void verify_no_implicit_conversion_to_int ( boost::optional const& ) {} + +int main() +{ + verify_no_implicit_conversion_to_int( boost::none ); +} From d5ea07c737bf0c1a33325f71bca0534470558553 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Wed, 6 Jun 2007 20:57:40 +0000 Subject: [PATCH 013/126] Merged changes for ticket #979 from HEAD [SVN r37920] --- include/boost/operators.hpp | 204 ++++++++++++++++++------------------ 1 file changed, 103 insertions(+), 101 deletions(-) diff --git a/include/boost/operators.hpp b/include/boost/operators.hpp index fbba602..b3b1bd7 100644 --- a/include/boost/operators.hpp +++ b/include/boost/operators.hpp @@ -8,6 +8,8 @@ // See http://www.boost.org/libs/utility/operators.htm for documentation. // Revision History +// 24 May 07 Changed empty_base to depend on T, see +// http://svn.boost.org/trac/boost/ticket/979 // 21 Oct 02 Modified implementation of operators to allow compilers with a // correct named return value optimization (NRVO) to produce optimal // code. (Daniel Frey) @@ -90,15 +92,15 @@ namespace boost { namespace detail { +template class empty_base { + // Helmut Zeisel, empty base class optimization bug with GCC 3.0.0 #if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0 -class empty_base { bool dummy; -}; -#else -class empty_base {}; #endif +}; + } // namespace detail } // namespace boost @@ -119,7 +121,7 @@ namespace boost // Note that friend functions defined in a class are implicitly inline. // See the C++ std, 11.4 [class.friend] paragraph 5 -template +template > struct less_than_comparable2 : B { friend bool operator<=(const T& x, const U& y) { return !(x > y); } @@ -130,7 +132,7 @@ struct less_than_comparable2 : B friend bool operator>=(const U& x, const T& y) { return !(y > x); } }; -template +template > struct less_than_comparable1 : B { friend bool operator>(const T& x, const T& y) { return y < x; } @@ -138,7 +140,7 @@ struct less_than_comparable1 : B friend bool operator>=(const T& x, const T& y) { return !(x < y); } }; -template +template > struct equality_comparable2 : B { friend bool operator==(const U& y, const T& x) { return x == y; } @@ -146,7 +148,7 @@ struct equality_comparable2 : B friend bool operator!=(const T& y, const U& x) { return !(y == x); } }; -template +template > struct equality_comparable1 : B { friend bool operator!=(const T& x, const T& y) { return !(x == y); } @@ -165,7 +167,7 @@ struct equality_comparable1 : B // implementation available. #define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \ -template \ +template > \ struct NAME##2 : B \ { \ friend T operator OP( const T& lhs, const U& rhs ) \ @@ -174,33 +176,33 @@ struct NAME##2 : B \ { T nrv( rhs ); nrv OP##= lhs; return nrv; } \ }; \ \ -template \ +template > \ struct NAME##1 : B \ { \ friend T operator OP( const T& lhs, const T& rhs ) \ { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ }; -#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \ -template \ -struct NAME##2 : B \ -{ \ - friend T operator OP( const T& lhs, const U& rhs ) \ - { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ -}; \ - \ -template \ -struct BOOST_OPERATOR2_LEFT(NAME) : B \ -{ \ - friend T operator OP( const U& lhs, const T& rhs ) \ - { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ -}; \ - \ -template \ -struct NAME##1 : B \ -{ \ - friend T operator OP( const T& lhs, const T& rhs ) \ - { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ +#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \ +template > \ +struct NAME##2 : B \ +{ \ + friend T operator OP( const T& lhs, const U& rhs ) \ + { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ +}; \ + \ +template > \ +struct BOOST_OPERATOR2_LEFT(NAME) : B \ +{ \ + friend T operator OP( const U& lhs, const T& rhs ) \ + { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ +}; \ + \ +template > \ +struct NAME##1 : B \ +{ \ + friend T operator OP( const T& lhs, const T& rhs ) \ + { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ }; #else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) @@ -210,35 +212,35 @@ struct NAME##1 : B \ // BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide // optimization opportunities to the compiler :) -#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \ -template \ -struct NAME##2 : B \ -{ \ - friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ - friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \ -}; \ - \ -template \ -struct NAME##1 : B \ -{ \ - friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ +#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \ +template > \ +struct NAME##2 : B \ +{ \ + friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ + friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \ +}; \ + \ +template > \ +struct NAME##1 : B \ +{ \ + friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ }; #define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \ -template \ +template > \ struct NAME##2 : B \ { \ friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ }; \ \ -template \ +template > \ struct BOOST_OPERATOR2_LEFT(NAME) : B \ { \ friend T operator OP( const U& lhs, const T& rhs ) \ { return T( lhs ) OP##= rhs; } \ }; \ \ -template \ +template > \ struct NAME##1 : B \ { \ friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ @@ -261,7 +263,7 @@ BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | ) // incrementable and decrementable contributed by Jeremy Siek -template +template > struct incrementable : B { friend T operator++(T& x, int) @@ -274,7 +276,7 @@ private: // The use of this typedef works around a Borland bug typedef T incrementable_type; }; -template +template > struct decrementable : B { friend T operator--(T& x, int) @@ -289,7 +291,7 @@ private: // The use of this typedef works around a Borland bug // Iterator operator classes (contributed by Jeremy Siek) ------------------// -template +template > struct dereferenceable : B { P operator->() const @@ -298,7 +300,7 @@ struct dereferenceable : B } }; -template +template > struct indexable : B { R operator[](I n) const @@ -313,14 +315,14 @@ struct indexable : B #if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) #define BOOST_BINARY_OPERATOR( NAME, OP ) \ -template \ +template > \ struct NAME##2 : B \ { \ friend T operator OP( const T& lhs, const U& rhs ) \ { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ }; \ \ -template \ +template > \ struct NAME##1 : B \ { \ friend T operator OP( const T& lhs, const T& rhs ) \ @@ -330,13 +332,13 @@ struct NAME##1 : B \ #else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) #define BOOST_BINARY_OPERATOR( NAME, OP ) \ -template \ +template > \ struct NAME##2 : B \ { \ friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ }; \ \ -template \ +template > \ struct NAME##1 : B \ { \ friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ @@ -349,7 +351,7 @@ BOOST_BINARY_OPERATOR( right_shiftable, >> ) #undef BOOST_BINARY_OPERATOR -template +template > struct equivalent2 : B { friend bool operator==(const T& x, const U& y) @@ -358,7 +360,7 @@ struct equivalent2 : B } }; -template +template > struct equivalent1 : B { friend bool operator==(const T&x, const T&y) @@ -367,7 +369,7 @@ struct equivalent1 : B } }; -template +template > struct partially_ordered2 : B { friend bool operator<=(const T& x, const U& y) @@ -384,7 +386,7 @@ struct partially_ordered2 : B { return (y < x) || (y == x); } }; -template +template > struct partially_ordered1 : B { friend bool operator>(const T& x, const T& y) @@ -397,161 +399,161 @@ struct partially_ordered1 : B // Combined operator classes (contributed by Daryle Walker) ----------------// -template +template > struct totally_ordered2 : less_than_comparable2 > {}; -template +template > struct totally_ordered1 : less_than_comparable1 > {}; -template +template > struct additive2 : addable2 > {}; -template +template > struct additive1 : addable1 > {}; -template +template > struct multiplicative2 : multipliable2 > {}; -template +template > struct multiplicative1 : multipliable1 > {}; -template +template > struct integer_multiplicative2 : multiplicative2 > {}; -template +template > struct integer_multiplicative1 : multiplicative1 > {}; -template +template > struct arithmetic2 : additive2 > {}; -template +template > struct arithmetic1 : additive1 > {}; -template +template > struct integer_arithmetic2 : additive2 > {}; -template +template > struct integer_arithmetic1 : additive1 > {}; -template +template > struct bitwise2 : xorable2 > > {}; -template +template > struct bitwise1 : xorable1 > > {}; -template +template > struct unit_steppable : incrementable > {}; -template +template > struct shiftable2 : left_shiftable2 > {}; -template +template > struct shiftable1 : left_shiftable1 > {}; -template +template > struct ring_operators2 : additive2 > > {}; -template +template > struct ring_operators1 : additive1 > {}; -template +template > struct ordered_ring_operators2 : ring_operators2 > {}; -template +template > struct ordered_ring_operators1 : ring_operators1 > {}; -template +template > struct field_operators2 : ring_operators2 > > {}; -template +template > struct field_operators1 : ring_operators1 > {}; -template +template > struct ordered_field_operators2 : field_operators2 > {}; -template +template > struct ordered_field_operators1 : field_operators1 > {}; -template +template > struct euclidian_ring_operators2 : ring_operators2 > > > > {}; -template +template > struct euclidian_ring_operators1 : ring_operators1 > > {}; -template +template > struct ordered_euclidian_ring_operators2 : totally_ordered2 > {}; -template +template > struct ordered_euclidian_ring_operators1 : totally_ordered1 > {}; -template +template > struct input_iteratable : equality_comparable1 > > {}; -template +template > struct output_iteratable : incrementable {}; -template +template > struct forward_iteratable : input_iteratable {}; -template +template > struct bidirectional_iteratable : forward_iteratable +template > struct random_access_iteratable : bidirectional_iteratable \ +# define BOOST_IMPORT_TEMPLATE4(template_name) \ + template > \ struct template_name : ::template_name {}; -# define BOOST_IMPORT_TEMPLATE3(template_name) \ - template \ +# define BOOST_IMPORT_TEMPLATE3(template_name) \ + template > \ struct template_name : ::template_name {}; -# define BOOST_IMPORT_TEMPLATE2(template_name) \ - template \ +# define BOOST_IMPORT_TEMPLATE2(template_name) \ + template > \ struct template_name : ::template_name {}; -# define BOOST_IMPORT_TEMPLATE1(template_name) \ - template \ +# define BOOST_IMPORT_TEMPLATE1(template_name) \ + template > \ struct template_name : ::template_name {}; # endif // BOOST_NO_USING_TEMPLATE @@ -752,7 +754,7 @@ template struct is_chained_base { # define BOOST_OPERATOR_TEMPLATE(template_name) \ template \ ,class O = typename is_chained_base::value \ > \ struct template_name : template_name##2 {}; \ @@ -788,7 +790,7 @@ BOOST_OPERATOR_TEMPLATE1(template_name##1) // In this case we can only assume that template_name<> is equivalent to the // more commonly needed template_name1<> form. # define BOOST_OPERATOR_TEMPLATE(template_name) \ - template \ + template > \ struct template_name : template_name##1 {}; #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION From 9ff18c2c96cf2d14ff5bb5723413e5121e3d6dd7 Mon Sep 17 00:00:00 2001 From: nobody Date: Tue, 24 Jul 2007 19:28:14 +0000 Subject: [PATCH 014/126] This commit was manufactured by cvs2svn to create tag 'Version_1_34_1'. [SVN r38286] From 6aa648d3157c6d274509ea90a4562d72fa4e81e8 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Fri, 5 Oct 2007 14:25:06 +0000 Subject: [PATCH 015/126] Starting point for releases [SVN r39706] From 74462349c284e9a5785c3594f6509ada480e3b5b Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Sun, 25 Nov 2007 18:07:19 +0000 Subject: [PATCH 016/126] Full merge from trunk at revision 41356 of entire boost-root tree. [SVN r41369] --- include/boost/assert.hpp | 13 +++ include/boost/current_function.hpp | 4 + .../detail/in_place_factory_prefix.hpp | 19 +-- .../detail/in_place_factory_suffix.hpp | 8 +- .../utility/detail/result_of_iterate.hpp | 31 ++--- include/boost/utility/in_place_factory.hpp | 96 ++++++++++------ include/boost/utility/result_of.hpp | 52 ++++++--- .../boost/utility/typed_in_place_factory.hpp | 84 ++++++++------ include/boost/utility/value_init.hpp | 108 +++++++++++++----- 9 files changed, 278 insertions(+), 137 deletions(-) diff --git a/include/boost/assert.hpp b/include/boost/assert.hpp index 5619f29..c227f17 100644 --- a/include/boost/assert.hpp +++ b/include/boost/assert.hpp @@ -2,6 +2,7 @@ // boost/assert.hpp - BOOST_ASSERT(expr) // // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2007 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -35,3 +36,15 @@ void assertion_failed(char const * expr, char const * function, char const * fil # include // .h to support old libraries w/o - effect is the same # define BOOST_ASSERT(expr) assert(expr) #endif + +#undef BOOST_VERIFY + +#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) ) + +# define BOOST_VERIFY(expr) ((void)(expr)) + +#else + +# define BOOST_VERIFY(expr) BOOST_ASSERT(expr) + +#endif diff --git a/include/boost/current_function.hpp b/include/boost/current_function.hpp index 40e3abd..aa5756e 100644 --- a/include/boost/current_function.hpp +++ b/include/boost/current_function.hpp @@ -32,6 +32,10 @@ inline void current_function_helper() # define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ +#elif defined(__DMC__) && (__DMC__ >= 0x810) + +# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ + #elif defined(__FUNCSIG__) # define BOOST_CURRENT_FUNCTION __FUNCSIG__ diff --git a/include/boost/utility/detail/in_place_factory_prefix.hpp b/include/boost/utility/detail/in_place_factory_prefix.hpp index 092083e..6ce7247 100644 --- a/include/boost/utility/detail/in_place_factory_prefix.hpp +++ b/include/boost/utility/detail/in_place_factory_prefix.hpp @@ -1,4 +1,5 @@ // Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// Copyright (C) 2007, Tobias Schwinger. // // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -9,25 +10,27 @@ // You are welcome to contact the author at: // fernando_cacciola@hotmail.com // -#ifndef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_25AGO2003_HPP -#define BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_25AGO2003_HPP +#ifndef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_04APR2007_HPP +#define BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_04APR2007_HPP +#include +#include #include +#include +#include +#include +#include #include #include #include -#include -#include -#include -#include +#include #define BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT(z,n,_) BOOST_PP_CAT(m_a,n) BOOST_PP_LPAREN() BOOST_PP_CAT(a,n) BOOST_PP_RPAREN() #define BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL(z,n,_) BOOST_PP_CAT(A,n) const& BOOST_PP_CAT(m_a,n); -#define BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_ARG(z,n,_) BOOST_PP_CAT(m_a,n) #define BOOST_MAX_INPLACE_FACTORY_ARITY 10 -#undef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_25AGO2003_HPP +#undef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_04APR2007_HPP #endif diff --git a/include/boost/utility/detail/in_place_factory_suffix.hpp b/include/boost/utility/detail/in_place_factory_suffix.hpp index 3efe221..b1fc4d3 100644 --- a/include/boost/utility/detail/in_place_factory_suffix.hpp +++ b/include/boost/utility/detail/in_place_factory_suffix.hpp @@ -1,4 +1,5 @@ // Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// Copyright (C) 2007, Tobias Schwinger. // // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -9,15 +10,14 @@ // You are welcome to contact the author at: // fernando_cacciola@hotmail.com // -#ifndef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_25AGO2003_HPP -#define BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_25AGO2003_HPP +#ifndef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_04APR2007_HPP +#define BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_04APR2007_HPP #undef BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT #undef BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL -#undef BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_ARG #undef BOOST_MAX_INPLACE_FACTORY_ARITY -#undef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_25AGO2003_HPP +#undef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_04APR2007_HPP #endif diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp index 5aa3a5c..41616c3 100644 --- a/include/boost/utility/detail/result_of_iterate.hpp +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -21,66 +21,69 @@ template struct result_of - : detail::result_of {}; + : boost::detail::result_of_impl::value)> {}; #endif +#undef BOOST_RESULT_OF_ARGS + +#if BOOST_PP_ITERATION() >= 1 + namespace detail { template -struct result_of +struct result_of_impl { typedef R type; }; template -struct result_of +struct result_of_impl { typedef R type; }; -#undef BOOST_RESULT_OF_ARGS - -#if BOOST_PP_ITERATION() > 1 && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) template -struct result_of + FArgs, false> { typedef R type; }; template -struct result_of + FArgs, false> { typedef R type; }; template -struct result_of + FArgs, false> { typedef R type; }; template -struct result_of + FArgs, false> { typedef R type; }; #endif } +#endif diff --git a/include/boost/utility/in_place_factory.hpp b/include/boost/utility/in_place_factory.hpp index 612c9a3..16eaacf 100644 --- a/include/boost/utility/in_place_factory.hpp +++ b/include/boost/utility/in_place_factory.hpp @@ -1,4 +1,5 @@ // Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// Copyright (C) 2007, Tobias Schwinger. // // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -9,50 +10,79 @@ // You are welcome to contact the author at: // fernando_cacciola@hotmail.com // -#ifndef BOOST_UTILITY_INPLACE_FACTORY_25AGO2003_HPP -#define BOOST_UTILITY_INPLACE_FACTORY_25AGO2003_HPP +#ifndef BOOST_UTILITY_INPLACE_FACTORY_04APR2007_HPP +#ifndef BOOST_PP_IS_ITERATING #include -#include - namespace boost { class in_place_factory_base {} ; -#define BOOST_DEFINE_INPLACE_FACTORY_CLASS(z,n,_) \ -template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),class A) > \ -class BOOST_PP_CAT(in_place_factory, BOOST_PP_INC(n) ) : public in_place_factory_base \ -{ \ -public: \ -\ - BOOST_PP_CAT(in_place_factory, BOOST_PP_INC(n) ) ( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n),A,const& a) ) \ - : \ - BOOST_PP_ENUM( BOOST_PP_INC(n), BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT, _ ) \ - {} \ -\ - template \ - void apply ( void* address BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T) ) const \ - { \ - new ( address ) T ( BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), m_a ) ) ; \ - } \ -\ - BOOST_PP_REPEAT( BOOST_PP_INC(n), BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL, _) \ -} ; \ -\ -template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),class A) > \ -BOOST_PP_CAT(in_place_factory, BOOST_PP_INC(n) ) < BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), A ) > \ -in_place ( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n),A, const& a) ) \ -{ \ - return BOOST_PP_CAT(in_place_factory, BOOST_PP_INC(n) ) < BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), A ) > \ - ( BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), a ) ) ; \ -} ; \ - -BOOST_PP_REPEAT( BOOST_MAX_INPLACE_FACTORY_ARITY, BOOST_DEFINE_INPLACE_FACTORY_CLASS, BOOST_PP_EMPTY() ) +#define BOOST_PP_ITERATION_LIMITS (0, BOOST_MAX_INPLACE_FACTORY_ARITY) +#define BOOST_PP_FILENAME_1 +#include BOOST_PP_ITERATE() } // namespace boost #include +#define BOOST_UTILITY_INPLACE_FACTORY_04APR2007_HPP +#else +#define N BOOST_PP_ITERATION() + +#if N +template< BOOST_PP_ENUM_PARAMS(N, class A) > +#endif +class BOOST_PP_CAT(in_place_factory,N) + : + public in_place_factory_base +{ +public: + + explicit BOOST_PP_CAT(in_place_factory,N) + ( BOOST_PP_ENUM_BINARY_PARAMS(N,A,const& a) ) +#if N > 0 + : BOOST_PP_ENUM(N, BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT, _) +#endif + {} + + template + void* apply(void* address + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) const + { + return new(address) T( BOOST_PP_ENUM_PARAMS(N, m_a) ); + } + + template + void* apply(void* address, std::size_t n + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) const + { + for(char* next = address = this->BOOST_NESTED_TEMPLATE apply(address); + !! --n;) + this->BOOST_NESTED_TEMPLATE apply(next = next+sizeof(T)); + return address; + } + + BOOST_PP_REPEAT(N, BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL, _) +}; + +#if N > 0 +template< BOOST_PP_ENUM_PARAMS(N, class A) > +inline BOOST_PP_CAT(in_place_factory,N)< BOOST_PP_ENUM_PARAMS(N, A) > +in_place( BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a) ) +{ + return BOOST_PP_CAT(in_place_factory,N)< BOOST_PP_ENUM_PARAMS(N, A) > + ( BOOST_PP_ENUM_PARAMS(N, a) ); +} +#else +inline in_place_factory0 in_place() +{ + return in_place_factory0(); +} +#endif + +#undef N +#endif #endif diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp index 668cb69..cdcac34 100644 --- a/include/boost/utility/result_of.hpp +++ b/include/boost/utility/result_of.hpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #ifndef BOOST_RESULT_OF_NUM_ARGS # define BOOST_RESULT_OF_NUM_ARGS 10 @@ -29,28 +31,48 @@ namespace detail { BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) -template struct get_result_of; - -template -struct get_result_of -{ - typedef typename F::result_type type; -}; - -template -struct get_result_of -{ - typedef typename F::template result::type type; -}; +template struct result_of_impl; template -struct get_result_of +struct result_of_void_impl { typedef void type; }; +template +struct result_of_void_impl +{ + typedef R type; +}; + +template +struct result_of_void_impl +{ + typedef R type; +}; + template -struct result_of : get_result_of::value)> {}; +struct result_of_impl +{ + typedef typename F::result_type type; +}; + +template +struct is_function_with_no_args : mpl::false_ {}; + +template +struct is_function_with_no_args : mpl::true_ {}; + +template +struct result_of_nested_result : F::template result +{}; + +template +struct result_of_impl + : mpl::if_, + result_of_void_impl, + result_of_nested_result >::type +{}; } // end namespace detail diff --git a/include/boost/utility/typed_in_place_factory.hpp b/include/boost/utility/typed_in_place_factory.hpp index e19fb75..347b7f4 100644 --- a/include/boost/utility/typed_in_place_factory.hpp +++ b/include/boost/utility/typed_in_place_factory.hpp @@ -1,4 +1,5 @@ // Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// Copyright (C) 2007, Tobias Schwinger. // // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -9,8 +10,8 @@ // You are welcome to contact the author at: // fernando_cacciola@hotmail.com // -#ifndef BOOST_UTILITY_TYPED_INPLACE_FACTORY_25AGO2003_HPP -#define BOOST_UTILITY_TYPED_INPLACE_FACTORY_25AGO2003_HPP +#ifndef BOOST_UTILITY_TYPED_INPLACE_FACTORY_04APR2007_HPP +#ifndef BOOST_PP_IS_ITERATING #include @@ -18,40 +19,59 @@ namespace boost { class typed_in_place_factory_base {} ; -#define BOOST_DEFINE_TYPED_INPLACE_FACTORY_CLASS(z,n,_) \ -template< class T, BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),class A) > \ -class BOOST_PP_CAT(typed_in_place_factory, BOOST_PP_INC(n) ) : public typed_in_place_factory_base \ -{ \ -public: \ -\ - typedef T value_type ; \ -\ - BOOST_PP_CAT(typed_in_place_factory, BOOST_PP_INC(n) ) ( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n),A,const& a) ) \ - : \ - BOOST_PP_ENUM( BOOST_PP_INC(n), BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT, _ ) \ - {} \ -\ - void apply ( void* address ) const \ - { \ - new ( address ) T ( BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), m_a ) ) ; \ - } \ -\ - BOOST_PP_REPEAT( BOOST_PP_INC(n), BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL, _) \ -} ; \ -\ -template< class T, BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),class A) > \ -BOOST_PP_CAT(typed_in_place_factory, BOOST_PP_INC(n) ) < T , BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), A ) > \ -in_place ( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n),A, const& a) ) \ -{ \ - return BOOST_PP_CAT(typed_in_place_factory, BOOST_PP_INC(n) ) < T, BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), A ) > \ - ( BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), a ) ) ; \ -} ; \ - -BOOST_PP_REPEAT( BOOST_MAX_INPLACE_FACTORY_ARITY, BOOST_DEFINE_TYPED_INPLACE_FACTORY_CLASS, BOOST_PP_EMPTY() ) +#define BOOST_PP_ITERATION_LIMITS (0, BOOST_MAX_INPLACE_FACTORY_ARITY) +#define BOOST_PP_FILENAME_1 +#include BOOST_PP_ITERATE() } // namespace boost #include +#define BOOST_UTILITY_TYPED_INPLACE_FACTORY_04APR2007_HPP +#else +#define N BOOST_PP_ITERATION() + +template< class T BOOST_PP_ENUM_TRAILING_PARAMS(N,class A) > +class BOOST_PP_CAT(typed_in_place_factory,N) + : + public typed_in_place_factory_base +{ +public: + + typedef T value_type; + + explicit BOOST_PP_CAT(typed_in_place_factory,N) + ( BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a) ) +#if N > 0 + : BOOST_PP_ENUM(N, BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT, _) +#endif + {} + + void* apply (void* address) const + { + return new(address) T( BOOST_PP_ENUM_PARAMS(N, m_a) ); + } + + void* apply (void* address, std::size_t n) const + { + for(void* next = address = this->apply(address); !! --n;) + this->apply(next = static_cast(next) + sizeof(T)); + return address; + } + + BOOST_PP_REPEAT(N, BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL, _) +}; + +template< class T BOOST_PP_ENUM_TRAILING_PARAMS(N, class A) > +inline BOOST_PP_CAT(typed_in_place_factory,N)< + T BOOST_PP_ENUM_TRAILING_PARAMS(N, A) > +in_place( BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a) ) +{ + return BOOST_PP_CAT(typed_in_place_factory,N)< + T BOOST_PP_ENUM_TRAILING_PARAMS(N, A) >( BOOST_PP_ENUM_PARAMS(N, a) ); +} + +#undef N +#endif #endif diff --git a/include/boost/utility/value_init.hpp b/include/boost/utility/value_init.hpp index d24908c..c4cd3e1 100644 --- a/include/boost/utility/value_init.hpp +++ b/include/boost/utility/value_init.hpp @@ -1,63 +1,110 @@ -// Copyright 2002, Fernando Luis Cacciola Carballal. +// (C) Copyright 2002-2007, 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) // // 21 Ago 2002 (Created) Fernando Cacciola +// 07 Set 2007 (Worked around MSVC++ bug) Fernando Cacciola, Niels Dekker +// 16 Nov 2007 (Refactoring: removed private base classes) Fernando Cacciola, Niels Dekker // #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP -#include "boost/detail/select_type.hpp" -#include "boost/type_traits/cv_traits.hpp" +#include +#include +#include + +// Microsoft Visual C++ does not correctly support value initialization, as reported by +// Pavel Kuznetsov (MetaCommunications Engineering), 7/28/2005, Feedback ID 100744, +// Feedback Title: Value-initialization in new-expression +// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744 +// The report was closed at 11/14/2006, and its status was set to "Closed (Won't Fix)". +// Luckily, even in the presence of this compiler bug, boost::value_initialized will still +// do its job correctly, when using the following workaround: +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) +# define BOOST_UTILITY_VALUE_INIT_WORKAROUND +#endif + +#ifdef BOOST_UTILITY_VALUE_INIT_WORKAROUND + +#include +#include +#include +#include + +#ifdef BOOST_MSVC +#pragma warning(push) +#if _MSC_VER >= 1310 +// When using MSVC 7.1 or higher, placement new, "new (&x) T()", may trigger warning C4345: +// "behavior change: an object of POD type constructed with an initializer of the form () +// will be default-initialized". There is no need to worry about this, though. +#pragma warning(disable: 4345) +#endif +#endif namespace boost { -namespace vinit_detail { - template -class const_T_base +class value_initialized { - protected : + private : + mutable typename ::boost::aligned_storage::value>::type x; - const_T_base() : x() {} + public : + + value_initialized() + { + std::memset(&x, 0, sizeof(x)); + new (&x) T(); + } + + ~value_initialized() + { + void * ptr = &x; + static_cast(ptr)->T::~T(); + } + + T& data() const + { + void * ptr = &x; + return *static_cast(ptr); + } + + operator T&() const { return this->data(); } - T x ; } ; -template -struct non_const_T_base -{ - protected : +#ifdef BOOST_MSVC +// Restores the state of warning C4345. +#pragma warning(pop) +#endif - non_const_T_base() : x() {} +#else - mutable T x ; -} ; +namespace boost { template -struct select_base -{ - typedef typename - boost::detail::if_true< ::boost::is_const::value > - ::template then< const_T_base, non_const_T_base >::type type ; -} ; - -} // namespace vinit_detail - -template -class value_initialized : private vinit_detail::select_base::type +class value_initialized { public : - value_initialized() {} + value_initialized() : x() {} - operator T&() const { return this->x ; } + T& data() const { return x; } - T& data() const { return this->x ; } + operator T&() const { return this->data(); } + + mutable +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + typename +#endif + ::boost::remove_const::type x ; } ; +#endif + + template T const& get ( value_initialized const& x ) @@ -74,4 +121,3 @@ T& get ( value_initialized& x ) #endif - From 13bdfb8bbdd4ad60da171050bf83e4c9eec7d57d Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Sun, 25 Nov 2007 18:38:02 +0000 Subject: [PATCH 017/126] Full merge from trunk at revision 41356 of entire boost-root tree. [SVN r41370] --- OptionalPointee.html | 10 ++++++++-- assert.html | 12 ++++++++--- compressed_pair.htm | 19 +++++++++--------- in_place_factories.html | 9 ++++----- test/Jamfile.v2 | 12 +++++------ test/none_test.cpp | 22 -------------------- test/result_of_test.cpp | 32 +++++++++++++++++++++++++++++ utility.htm | 18 ++++++++--------- value_init.htm | 20 +++++++++---------- value_init_test.cpp | 42 ++++++++++++++++++++++++++++++++------- value_init_test_fail1.cpp | 2 +- value_init_test_fail2.cpp | 2 +- value_init_test_fail3.cpp | 2 +- 13 files changed, 126 insertions(+), 76 deletions(-) delete mode 100644 test/none_test.cpp diff --git a/OptionalPointee.html b/OptionalPointee.html index a6d6d97..462d6f3 100644 --- a/OptionalPointee.html +++ b/OptionalPointee.html @@ -145,14 +145,20 @@ objects are is implemented in +

    Acknowledgements

    +

    Based on the original concept developed by Augustus Saunders. +
    +


    Copyright © 2003 -Fernando Cacciola, -based on the original concept developed by Augustus Saunders. +Fernando Cacciola
    +

    Distributed under the Boost Software License, Version 1.0. See +www.boost.org/LICENSE_1_0.txt

    + \ No newline at end of file diff --git a/assert.html b/assert.html index 4381ae1..a970cef 100644 --- a/assert.html +++ b/assert.html @@ -47,9 +47,15 @@ void assertion_failed(char const * expr, char const * function, char const * fil

    As is the case with <cassert>, <boost/assert.hpp> can be included multiple times in a single translation unit. BOOST_ASSERT will be redefined each time as specified above.

    +

    <boost/assert.hpp> also defines the macro BOOST_VERIFY. + It has exactly the same behavior as BOOST_ASSERT, except that + the expression that is passed to BOOST_VERIFY is always + evaluated. This is useful when the asserted expression has desirable side + effects; it can also help suppress warnings about unused variables when the + only use of the variable is inside an assertion.


    - Copyright © 2002 by Peter Dimov. Distributed under the Boost Software License, Version - 1.0. See accompanying file LICENSE_1_0.txt or - copy at http://www.boost.org/LICENSE_1_0.txt.

    + Copyright © 2002, 2007 by Peter Dimov. Distributed under the Boost Software + License, Version 1.0. See accompanying file LICENSE_1_0.txt + or copy at http://www.boost.org/LICENSE_1_0.txt.

    diff --git a/compressed_pair.htm b/compressed_pair.htm index 4662fc5..f054d08 100644 --- a/compressed_pair.htm +++ b/compressed_pair.htm @@ -3,7 +3,7 @@ Header - + @@ -59,17 +59,18 @@ public: empty type, then assigning to that member will produce memory corruption, unless the empty type has a "do nothing" assignment operator defined. This is due to a bug in the way VC6 generates implicit assignment operators.

    -
    -

    Revised 08 May 2001

    -

    © Copyright boost.org 2000. Permission to copy, use, modify, sell and - distribute this document is granted provided this copyright notice appears in - all copies. This document is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose.

    +

    Acknowledgements

    Based on contributions by Steve Cleary, Beman Dawes, Howard Hinnant and John Maddock.

    Maintained by John Maddock, the latest version of this file can be found at www.boost.org, and the boost discussion list at www.yahoogroups.com/list/boost.

    -

     

    +
    +

    Revised + 07 November 2007

    +

    © Copyright Beman Dawes, 2000.

    +

    Distributed under the Boost Software License, Version 1.0. See +www.boost.org/LICENSE_1_0.txt

    + - + \ No newline at end of file diff --git a/in_place_factories.html b/in_place_factories.html index 9b71559..b36387d 100644 --- a/in_place_factories.html +++ b/in_place_factories.html @@ -3,9 +3,8 @@ - - -Header + +In_place_factory Documentation @@ -77,7 +76,7 @@ object is likely to be temporary and serve no purpose besides being the source

    A solution to this problem is to support direct construction of the contained object right in the container's storage.
    -In this shceme, the user supplies the arguments for the X constructor +In this scheme, the user supplies the arguments for the X constructor directly to the container:

    struct C
     {
    @@ -138,7 +137,7 @@ The following simplified example shows the basic idea. A complete example follow
     
     void foo()
     {
    -  C c( in_place(123,"hello" ) ;
    +  C c( in_place(123,"hello") ) ;
     }
     
    diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 330c08c..56c84a4 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -1,8 +1,7 @@ -# Copyright David Abrahams 2003. Permission to copy, use, -# modify, sell and distribute this software is granted provided this -# copyright notice appears in all copies. This software is provided -# "as is" without express or implied warranty, and with no claim as -# to its suitability for any purpose. +# 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/ @@ -33,5 +32,6 @@ test-suite utility [ compile-fail ../value_init_test_fail1.cpp ] [ compile-fail ../value_init_test_fail2.cpp ] [ compile-fail ../value_init_test_fail3.cpp ] - [ run none_test.cpp ] + [ run ../verify_test.cpp ] ; + diff --git a/test/none_test.cpp b/test/none_test.cpp deleted file mode 100644 index 00a6fc9..0000000 --- a/test/none_test.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2007 Fernando Luis Cacciola Carballal. 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 documentation. - -// Boost test program for noost::none_t and boost::none - -// Test strategy contributed by Richard Smith - -#include // Test none.hpp is included with - -// Left undefined to cause a linker error if this overload is incorrectly selected. -void verify_no_implicit_conversion_to_int ( int i ) ; - -void verify_no_implicit_conversion_to_int ( boost::optional const& ) {} - -int main() -{ - verify_no_implicit_conversion_to_int( boost::none ); -} diff --git a/test/result_of_test.cpp b/test/result_of_test.cpp index af7aba2..10f3410 100644 --- a/test/result_of_test.cpp +++ b/test/result_of_test.cpp @@ -24,6 +24,24 @@ struct int_result_type_and_float_result_of template struct result { typedef float type; }; }; +template +struct int_result_type_template { typedef int result_type; }; + +template +struct int_result_of_template +{ + template struct result; + template struct result { typedef int type; }; +}; + +template +struct int_result_type_and_float_result_of_template +{ + typedef int result_type; + template struct result; + template struct result { typedef float type; }; +}; + struct X {}; int main() @@ -32,10 +50,13 @@ int main() typedef int (*func_ptr)(float, double); typedef int (&func_ref)(float, double); + typedef int (*func_ptr_0)(); + typedef int (&func_ref_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::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); @@ -43,11 +64,22 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, void>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same(char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + return 0; } diff --git a/utility.htm b/utility.htm index 8d8d80f..937a8a3 100644 --- a/utility.htm +++ b/utility.htm @@ -163,9 +163,9 @@ void f() { N > 0 or void when N = 0. For additional information about result_of, see the - current draft of the C++ Library TR, N1647, - or the result_of N1836, + or, for motivation and design rationale, the result_of proposal.

    Class template result_of resides in @@ -183,12 +183,12 @@ void f() {

    See separate documentation.


    Revised  02 May, 200407 November, 2007

    -

    © Copyright boost.org 1999-2003. Permission to copy, use, modify, sell and distribute - this document is granted provided this copyright notice appears in all copies. - This document is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose.

    +

    © Copyright Beman Dawes 1999-2003.

    +

    Distributed under the Boost Software License, Version 1.0. See +www.boost.org/LICENSE_1_0.txt

    + - + \ No newline at end of file diff --git a/value_init.htm b/value_init.htm index d8c28e3..8ceba8b 100644 --- a/value_init.htm +++ b/value_init.htm @@ -197,23 +197,23 @@ the wrapped object is always performed with the get() idiom:

    value_initialized was developed by Fernando Cacciola, with help and suggestions from David Abrahams and Darin Adler.
    Special thanks to Björn Karlsson who carefully edited and completed this documentation. -
     
    - -
    -

    Revised 19 September 2002

    - -

    © Copyright boost.org 2002. Permission to copy, use, modify, sell -and distribute this document is granted provided this copyright notice appears -in all copies. This document is provided "as is" without express or implied -warranty, and with no claim as to its suitability for any purpose.

    Developed by Fernando Cacciola, the latest version of this file can be found at www.boost.org, and the boost discussion list at www.yahoogroups.com/list/boost.

    + +
    +

    Revised 19 September 2002

    + +

    © Copyright Fernando Cacciola, 2002.

    + +

    Distributed under the Boost Software License, Version 1.0. See +www.boost.org/LICENSE_1_0.txt

    +

    - + \ No newline at end of file diff --git a/value_init_test.cpp b/value_init_test.cpp index fe73cc1..4c576a6 100644 --- a/value_init_test.cpp +++ b/value_init_test.cpp @@ -1,4 +1,4 @@ -// (C) 2002, Fernando Luis Cacciola Carballal. +// 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 @@ -60,9 +60,29 @@ struct NonPOD : NonPODBase std::string id ; } ; -template -void test ( T const& y, T const& z ) +// +// Sample aggregate POD struct type +// +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 ; } + + +// +// This test function tests boost::value_initialized for a specific type T. +// The first argument (y) is assumed have the value of a value-initialized object. +// Returns true on success. +// +template +bool test ( T const& y, T const& z ) +{ + const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter(); boost::value_initialized x ; BOOST_CHECK ( y == x ) ; BOOST_CHECK ( y == boost::get(x) ) ; @@ -86,14 +106,22 @@ void test ( T const& y, T const& z ) BOOST_CHECK ( y == cx_c ) ; BOOST_CHECK ( y == boost::get(cx_c) ) ; #endif + return boost::minimal_test::errors_counter() == counter_before_test ; } int test_main(int, char **) { - test( 0,1234 ) ; - test( 0.0,12.34 ) ; - test( POD(0,0,0.0), POD('a',1234,56.78) ) ; - test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ; + BOOST_CHECK ( test( 0,1234 ) ) ; + BOOST_CHECK ( test( 0.0,12.34 ) ) ; + BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78) ) ) ; + BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ; + + NonPOD NonPOD_object( std::string("NonPOD_object") ); + BOOST_CHECK ( test( 0, &NonPOD_object ) ) ; + + AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 }; + AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 }; + BOOST_CHECK ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) ); return 0; } diff --git a/value_init_test_fail1.cpp b/value_init_test_fail1.cpp index 8904732..e3f6f1a 100644 --- a/value_init_test_fail1.cpp +++ b/value_init_test_fail1.cpp @@ -1,4 +1,4 @@ -// (C) 2002, Fernando Luis Cacciola Carballal. +// 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 diff --git a/value_init_test_fail2.cpp b/value_init_test_fail2.cpp index 1f40061..bbc7c90 100644 --- a/value_init_test_fail2.cpp +++ b/value_init_test_fail2.cpp @@ -1,4 +1,4 @@ -// (C) 2002, Fernando Luis Cacciola Carballal. +// 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 diff --git a/value_init_test_fail3.cpp b/value_init_test_fail3.cpp index 72fd761..9bea5ba 100644 --- a/value_init_test_fail3.cpp +++ b/value_init_test_fail3.cpp @@ -1,4 +1,4 @@ -// (C) 2002, Fernando Luis Cacciola Carballal. +// 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 From d5554eb6d74232368c0815888e38c67f16ce936b Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Sun, 25 Nov 2007 22:34:55 +0000 Subject: [PATCH 018/126] Pick up missing smart_ptr, utility, and type_traits files from full merge from trunk at revision 41356 of entire boost-root tree. [SVN r41386] --- verify_test.cpp | 126 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 verify_test.cpp diff --git a/verify_test.cpp b/verify_test.cpp new file mode 100644 index 0000000..3481636 --- /dev/null +++ b/verify_test.cpp @@ -0,0 +1,126 @@ +// +// verify_test.cpp - a test for BOOST_VERIFY +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2007 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#include + +int f( int & x ) +{ + return ++x; +} + +void test_default() +{ + int x = 1; + + BOOST_VERIFY( 1 ); + BOOST_VERIFY( x == 1 ); + BOOST_VERIFY( ++x ); + BOOST_VERIFY( f(x) ); + BOOST_VERIFY( &x ); + + BOOST_TEST( x == 3 ); +} + +#define BOOST_DISABLE_ASSERTS +#include + +void test_disabled() +{ + int x = 1; + + BOOST_VERIFY( 1 ); + BOOST_VERIFY( x == 1 ); + BOOST_VERIFY( ++x ); + BOOST_VERIFY( f(x) ); + BOOST_VERIFY( &x ); + + BOOST_TEST( x == 3 ); + + BOOST_VERIFY( 0 ); + BOOST_VERIFY( !x ); + BOOST_VERIFY( x == 0 ); + BOOST_VERIFY( !++x ); + BOOST_VERIFY( !f(x) ); + + BOOST_TEST( x == 5 ); + + void * p = 0; + BOOST_VERIFY( p ); +} + +#undef BOOST_DISABLE_ASSERTS + +#define BOOST_ENABLE_ASSERT_HANDLER +#include +#include +#include + +int handler_invoked = 0; + +void boost::assertion_failed(char const * expr, char const * function, char const * file, long line) +{ +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::printf; +#endif + + printf("Expression: %s\nFunction: %s\nFile: %s\nLine: %ld\n\n", expr, function, file, line); + ++handler_invoked; +} + +struct X +{ + static bool f() + { + BOOST_VERIFY( 0 ); + return false; + } +}; + +void test_handler() +{ + int x = 1; + + BOOST_VERIFY( 1 ); + BOOST_VERIFY( x == 1 ); + BOOST_VERIFY( ++x ); + BOOST_VERIFY( f(x) ); + BOOST_VERIFY( &x ); + + BOOST_TEST( x == 3 ); + + BOOST_VERIFY( 0 ); + BOOST_VERIFY( !x ); + BOOST_VERIFY( x == 0 ); + BOOST_VERIFY( !++x ); + BOOST_VERIFY( !f(x) ); + + BOOST_TEST( x == 5 ); + + void * p = 0; + BOOST_VERIFY( p ); + + BOOST_VERIFY( X::f() ); + + BOOST_TEST( handler_invoked == 8 ); +} + +#undef BOOST_ENABLE_ASSERT_HANDLER + +int main() +{ + test_default(); + test_disabled(); + test_handler(); + + return boost::report_errors(); +} From 88099a882f805dd4294d963fd995b6d158dfe7df Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Sat, 5 Jan 2008 22:38:50 +0000 Subject: [PATCH 019/126] Merged value_init.hpp from trunk [42277] to release branch, thereby resolving ticket #1459 and #1491. Fernando Cacciola (owner of value_init) encouraged me to do the commit. [SVN r42501] --- include/boost/utility/value_init.hpp | 119 +++++++++++++-------------- 1 file changed, 56 insertions(+), 63 deletions(-) diff --git a/include/boost/utility/value_init.hpp b/include/boost/utility/value_init.hpp index c4cd3e1..097f21a 100644 --- a/include/boost/utility/value_init.hpp +++ b/include/boost/utility/value_init.hpp @@ -5,105 +5,98 @@ // http://www.boost.org/LICENSE_1_0.txt) // // 21 Ago 2002 (Created) Fernando Cacciola -// 07 Set 2007 (Worked around MSVC++ bug) Fernando Cacciola, Niels Dekker -// 16 Nov 2007 (Refactoring: removed private base classes) Fernando Cacciola, Niels Dekker +// 24 Dec 2007 (Refactored and worked around various compiler bugs) Fernando Cacciola, Niels Dekker // #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP -#include -#include -#include - -// Microsoft Visual C++ does not correctly support value initialization, as reported by -// Pavel Kuznetsov (MetaCommunications Engineering), 7/28/2005, Feedback ID 100744, -// Feedback Title: Value-initialization in new-expression +// Note: The implementation of boost::value_initialized had to deal with the +// fact that various compilers haven't fully implemented value-initialization: +// Microsoft Feedback ID 100744 - Value-initialization in new-expression +// Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005-07-28 // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744 -// The report was closed at 11/14/2006, and its status was set to "Closed (Won't Fix)". -// Luckily, even in the presence of this compiler bug, boost::value_initialized will still -// do its job correctly, when using the following workaround: -#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) -# define BOOST_UTILITY_VALUE_INIT_WORKAROUND -#endif - -#ifdef BOOST_UTILITY_VALUE_INIT_WORKAROUND +// GCC Bug 30111 - Value-initialization of POD base class doesn't initialize members +// Reported by Jonathan Wakely, 2006-12-07 +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 +// GCC Bug 33916 - Default constructor fails to initialize array members +// Reported by Michael Elizabeth Chastain, 2007-10-26 +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 +// Borland Report 51854 - Value-initialization: POD struct should be zero-initialized +// Reported by Niels Dekker (LKEB, Leiden University Medical Center), 2007-11-09 +// http://qc.codegear.com/wc/qcmain.aspx?d=51854 +// The constructor of boost::value_initialized works around these issues, by +// clearing the bytes of T, before constructing the T object it contains. #include +#include +#include #include #include #include -#ifdef BOOST_MSVC -#pragma warning(push) -#if _MSC_VER >= 1310 -// When using MSVC 7.1 or higher, placement new, "new (&x) T()", may trigger warning C4345: -// "behavior change: an object of POD type constructed with an initializer of the form () -// will be default-initialized". There is no need to worry about this, though. -#pragma warning(disable: 4345) -#endif -#endif - namespace boost { template class value_initialized { private : - mutable typename ::boost::aligned_storage::value>::type x; + struct wrapper + { +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) + typename +#endif + remove_const::type data; + }; + + mutable aligned_storage::value> x; public : value_initialized() { - std::memset(&x, 0, sizeof(x)); - new (&x) T(); + std::memset(x.address(), 0, sizeof(x)); +#ifdef BOOST_MSVC +#pragma warning(push) +#if _MSC_VER >= 1310 +// When using MSVC 7.1 or higher, the following placement new expression may trigger warning C4345: +// "behavior change: an object of POD type constructed with an initializer of the form () +// will be default-initialized". There is no need to worry about this, though. +#pragma warning(disable: 4345) +#endif +#endif + new (x.address()) wrapper(); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + } + + value_initialized(value_initialized const & arg) + { + new (x.address()) wrapper( *static_cast(arg.x.address()) ); + } + + value_initialized & operator=(value_initialized const & arg) + { + T & this_data = this->data(); + T const & arg_data = arg.data(); + this_data = arg_data; + return *this; } ~value_initialized() { - void * ptr = &x; - static_cast(ptr)->T::~T(); + static_cast(x.address())->wrapper::~wrapper(); } T& data() const { - void * ptr = &x; - return *static_cast(ptr); + return static_cast(x.address())->data; } operator T&() const { return this->data(); } } ; -#ifdef BOOST_MSVC -// Restores the state of warning C4345. -#pragma warning(pop) -#endif - -#else - -namespace boost { - -template -class value_initialized -{ - public : - - value_initialized() : x() {} - - T& data() const { return x; } - - operator T&() const { return this->data(); } - - mutable -#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) - typename -#endif - ::boost::remove_const::type x ; - -} ; -#endif - template From 97b8966337057eb02b8a8da355b6082a5f760d51 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Tue, 15 Jan 2008 19:55:28 +0000 Subject: [PATCH 020/126] value_init doc + test: Merged from trunk changeset [42798] to release. [SVN r42799] --- value_init.htm | 165 ++++++++++++++++++++++++++++++++++++------ value_init_test.cpp | 173 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 310 insertions(+), 28 deletions(-) diff --git a/value_init.htm b/value_init.htm index 8ceba8b..405f0b6 100644 --- a/value_init.htm +++ b/value_init.htm @@ -17,11 +17,13 @@
    Rationale
    Introduction
    +
    Details
    @@ -30,7 +32,7 @@ Acknowledgements
    @@ -44,24 +46,91 @@ for initialization. Depending on the type, the value of a newly constructed object can be zero-initialized (logically 0), default-constructed (using the default constructor), or indeterminate. When writing generic code, -this problem must be addressed. value_initialized provides +this problem must be addressed. The template value_initialized provides a solution with consistent syntax for value initialization of scalar, -union and class types.
    +union and class types. +Moreover, value_initialized offers a workaround to various +compiler issues regarding value-initialization. + +

    Introduction

    -

    The C++ standard [1] contains the definitions +

    +There are various ways to initialize a variable, in C++. The following +declarations all may have a local variable initialized to its default +value: +

    +  T1 var1;
    +  T2 var2 = 0;
    +  T3 var3 = {};
    +  T4 var4 = T4();
    +
    +Unfortunately, whether or not any of those declarations correctly +initialize the variable very much depends on its type. The first +declaration is valid for any +DefaultConstructible type (by definition). +However, it does not always do an initialization! +It correctly initializes the variable when it's an instance of a +class, and the author of the class has provided a proper default +constructor. On the other hand, the value of var1 is indeterminate when +its type is an arithmetic type, like int, float, or char. +An arithmetic variable +is of course initialized properly by the second declaration, T2 +var2 = 0. But this initialization form usually won't work for a +class type (unless the class was especially written to support being +initialized that way). The third form, T3 var3 = {} +initializes an aggregate, typically a "C-style" struct or a "C-style" array. +However, the syntax is not allowed for a class that has an explicitly declared +constructor. (But watch out for an upcoming C++ language change, +by Bjarne Stroustrup et al [1]!) +The fourth form is the most generic form of them, as it +can be used to initialize arithmetic types, class types, aggregates, pointers, and +other types. The declaration, T4 var4 = T4(), should be read +as follows: First a temporary object is created, by T4(). +This object is value-initialized. Next the temporary +object is copied to the named variable, var4. Afterwards, the temporary +is destroyed. While the copying and the destruction are likely to +be optimized away, C++ still requires the type T4 to be +CopyConstructible. +(So T4 needs to be both DefaultConstructible and CopyConstructible.) +A class may not be CopyConstructible, for example because it may have a +private and undefined copy constructor, +or because it may be derived from boost::noncopyable. +Scott Meyers [2] explains why a class would be defined like that. +

    +

    +There is another, less obvious disadvantage to the fourth form, T4 var4 = T4(): +It suffers from various compiler issues, causing +a variable to be left uninitialized in some compiler specific cases. +

    +

    +The template value_initialized +offers a generic way to initialize +an object, like T4 var4 = T4(), but without requiring its type +to be CopyConstructible. And it offers a workaround to those compiler issues +regarding value-initialization as well! It allows getting an initialized +variable of any type; it only requires the type to be DefaultConstructible. +A properly value-initialized object of type T is +constructed by the following declaration: +

    +  value_initialized<T> var;
    +
    +

    + +

    Details

    +

    The C++ standard [3] contains the definitions of zero-initialization and default-initialization. Informally, zero-initialization means that the object is given the initial value 0 (converted to the type) and default-initialization means that - POD [2] types are zero-initialized, while class + POD [4] types are zero-initialized, while non-POD class types are initialized with their corresponding default constructors. A declaration can contain an initializer, which specifies the object's initial value. The initializer can be just '()', which states that -the object shall be default-initialized (but see below). However, if a declaration +the object shall be value-initialized (but see below). However, if a declaration has no initializer and it is of a non-const, non-static - POD type, the initial value is indeterminate:(see §8.5 for the + POD type, the initial value is indeterminate: (see §8.5, [dcl.init], for the accurate definitions).

    int x ; // no initializer. x value is indeterminate.
    std::string s ; // no initializer, s is default-constructed.

    int y = int() ;
    // y is initialized using copy-initialization
    // but the temporary uses an empty set of parentheses as the initializer,
    // so it is default-constructed.
    // A default constructed POD type is zero-initialized,
    // therefore, y == 0.

    void foo ( std::string ) ;
    foo ( std::string() ) ;
    // the temporary string is default constructed
    // as indicated by the initializer ()
    @@ -87,14 +156,11 @@ the object shall be default-initialized (but see below). However, if a decla

    In order to specify value-initialization of an object we need to use the empty-set initializer: ().

    -

    (but recall that the current C++ Standard states that '()' invokes default-initialization, -not value-initialization)

    -

    As before, a declaration with no intializer specifies default-initialization, and a declaration with a non-empty initializer specifies copy (=xxx) or direct (xxx) initialization.

    -
    template<class T> void eat(T);
    int x ; // indeterminate initial value.
    std::string s; // default-initialized.
    eat ( int() ) ; // value-initialized
    eat ( std::string() ) ; // value-initialied
    +
    template<class T> void eat(T);
    int x ; // indeterminate initial value.
    std::string s; // default-initialized.
    eat ( int() ) ; // value-initialized
    eat ( std::string() ) ; // value-initialized

    value-initialization syntax

    @@ -102,7 +168,7 @@ not value-initialization)

    parentheses is not permitted by the syntax of initializers because it is parsed as the declaration of a function taking no arguments:

    -
    int x() ; // declares function int(*)()
    int y ( int() ) ; // decalares function int(*)( int(*)() )
    +
    int x() ; // declares function int(*)()

    Thus, the empty () must be put in some other initialization context.

    @@ -124,8 +190,50 @@ data member:

    template<class T> 
    struct W
    {
    // value-initialization of 'data' here.
    W() : data() {}
    T data ;
    } ;
    W<int> w ;
    // w.data is value-initialized for any type.
    -

    This is the solution supplied by the value_initialized<> template - class.

    +

    This is the solution as it was supplied by earlier versions of the +value_initialized<T> template + class. Unfortunately this approach suffered from various compiler issues.

    + +

    compiler issues

    + +Various compilers haven't yet fully implemented value-initialization. +So when an object should be value-initialized (according to the C++ Standard), +it may in practice still be left uninitialized, because of those +compiler issues! It's hard to make a general statement on what those issues +are like, because they depend on the compiler you are using, its version number, +and the type of object you would like to have value-initialized. +Compilers usually support value-initialization for built-in types properly. +But objects of user-defined types that involve aggregates may in some cases +be partially, or even entirely left uninitialized, when they should be value-initialized. +

    +

    +We have encountered issues regarding value-initialization on compilers by +Microsoft, Sun, Borland, and GNU. Here is a list of bug reports on those issues: + +
    + +Microsoft Feedback ID 100744 - Value-initialization in new-expression +
    Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005-07-28 +
    + +GCC Bug 30111 - Value-initialization of POD base class doesn't initialize members +
    Reported by Jonathan Wakely, 2006-12-07 +
    + +GCC Bug 33916 - Default constructor fails to initialize array members +
    Reported by Michael Elizabeth Chastain, 2007-10-26 +
    + +Borland Report 51854 - Value-initialization: POD struct should be zero-initialized +
    Reported by Niels Dekker (LKEB, Leiden University Medical Center), 2007-09-11 +
    +
    +

    +New versions of value_initialized +(Boost release version 1.35 or higher) +offer a workaround to these issues: value_initialized will now clear +its internal data, prior to constructing the object that it contains. +

    Types

    @@ -191,23 +299,36 @@ the wrapped object is always performed with the get() idiom:

    value_initialized<int> x ;
    get(x) = 1 ; // OK

    value_initialized<int const> cx ;
    get(x) = 1 ; // ERROR: Cannot modify a const object

    value_initialized<int> const x_c ;
    get(x_c) = 1 ; // ERROR: Cannot modify a const object

    value_initialized<int const> const cx_c ;
    get(cx_c) = 1 ; // ERROR: Cannot modify a const object

    References

    - [1] The C++ Standard, ISO/IEC 14882:98
    - [2] Plain Old Data + [1] Bjarne Stroustrup, Gabriel Dos Reis, and J. Stephen Adamczyk wrote + various papers, proposing to extend the support for brace-enclosed initializer lists + in the next version of C++. + This would allow a variable var of any DefaultConstructible type + T to be value-initialized by doing T var = {}. + The papers are listed at Bjarne's web page, + My C++ Standards committee papers
    + [2] Scott Meyers, Effective C++, Third Edition, item 6, + Explicitly disallow the use of compiler-generated functions you do not want, + Scott Meyers: Books and CDs
    + [3] The C++ Standard, Second edition (2003), ISO/IEC 14882:2003
    + [4] POD stands for "Plain Old Data" +

    Acknowledgements

    value_initialized was developed by Fernando Cacciola, with help and suggestions from David Abrahams and Darin Adler.
    -Special thanks to Björn Karlsson who carefully edited and completed this documentation. - +Special thanks to Björn Karlsson who carefully edited and completed this documentation. + +

    value_initialized was reimplemented by Fernando Cacciola and Niels Dekker +for Boost release version 1.35 (2008), offering a workaround to various compiler issues. +

    Developed by Fernando Cacciola, the latest version of this file can be found at www.boost.org, and the boost discussion list -at www.yahoogroups.com/list/boost. + href="http://www.boost.org">www.boost.org.


    -

    Revised 19 September 2002

    +

    Revised 15 January 2008

    -

    © Copyright Fernando Cacciola, 2002.

    +

    © Copyright Fernando Cacciola, 2002, 2008.

    Distributed under the Boost Software License, Version 1.0. See www.boost.org/LICENSE_1_0.txt

    diff --git a/value_init_test.cpp b/value_init_test.cpp index 4c576a6..7b332d7 100644 --- a/value_init_test.cpp +++ b/value_init_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2002, Fernando Luis Cacciola Carballal. +// 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 @@ -6,12 +6,15 @@ // // Test program for "boost/utility/value_init.hpp" // -// Initial: 21 Agu 2002 +// 21 Agu 2002 (Created) Fernando Cacciola +// 15 Jan 2008 (Added tests regarding compiler issues) Fernando Cacciola, Niels Dekker +#include // For memcmp. #include #include #include "boost/utility/value_init.hpp" +#include #ifdef __BORLANDC__ #pragma hdrstop @@ -62,6 +65,9 @@ struct NonPOD : NonPODBase // // 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 { @@ -73,6 +79,106 @@ struct AggregatePODStruct 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 ; + } +}; + // // This test function tests boost::value_initialized for a specific type T. @@ -97,6 +203,16 @@ bool test ( T const& y, T const& z ) x_c_ref = z ; BOOST_CHECK ( x_c == z ) ; + boost::value_initialized const copy1 = x; + BOOST_CHECK ( boost::get(copy1) == boost::get(x) ) ; + + boost::value_initialized copy2; + copy2 = x; + BOOST_CHECK ( boost::get(copy2) == boost::get(x) ) ; + + boost::shared_ptr > ptr( new boost::value_initialized ); + BOOST_CHECK ( y == *ptr ) ; + #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) boost::value_initialized cx ; BOOST_CHECK ( y == cx ) ; @@ -106,6 +222,7 @@ bool test ( T const& y, T const& z ) BOOST_CHECK ( y == cx_c ) ; BOOST_CHECK ( y == boost::get(cx_c) ) ; #endif + return boost::minimal_test::errors_counter() == counter_before_test ; } @@ -123,13 +240,57 @@ int test_main(int, char **) AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 }; BOOST_CHECK ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) ); + StringAndInt stringAndInt0; + StringAndInt stringAndInt1; + stringAndInt0.i = 0; + stringAndInt1.i = 1; + stringAndInt1.s = std::string("1"); + BOOST_CHECK ( test(stringAndInt0, stringAndInt1) ); + + StructWithDestructor structWithDestructor0; + StructWithDestructor structWithDestructor1; + structWithDestructor0.i = 0; + structWithDestructor1.i = 1; + BOOST_CHECK ( test(structWithDestructor0, structWithDestructor1) ); + + StructWithVirtualFunction structWithVirtualFunction0; + StructWithVirtualFunction structWithVirtualFunction1; + structWithVirtualFunction0.i = 0; + structWithVirtualFunction1.i = 1; + BOOST_CHECK ( test(structWithVirtualFunction0, structWithVirtualFunction1) ); + + DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0; + DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1; + static_cast(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct; + static_cast(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct; + BOOST_CHECK ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) ); + + AggregatePODStructWrapper aggregatePODStructWrapper0; + AggregatePODStructWrapper aggregatePODStructWrapper1; + aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct; + aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct; + BOOST_CHECK ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) ); + + ArrayOfBytes zeroInitializedArrayOfBytes = { 0 }; + boost::value_initialized valueInitializedArrayOfBytes; + BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0); + + boost::value_initialized copyFunctionCallTester1; + BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed); + BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called); + + boost::value_initialized copyFunctionCallTester2 = boost::value_initialized(copyFunctionCallTester1); + BOOST_CHECK ( get(copyFunctionCallTester2).is_copy_constructed); + BOOST_CHECK ( ! get(copyFunctionCallTester2).is_assignment_called); + + boost::value_initialized copyFunctionCallTester3; + copyFunctionCallTester3 = boost::value_initialized(copyFunctionCallTester1); + BOOST_CHECK ( ! get(copyFunctionCallTester3).is_copy_constructed); + BOOST_CHECK ( get(copyFunctionCallTester3).is_assignment_called); + return 0; } unsigned int expected_failures = 0; - - - - From ab479794f3307b0e8911dbefc69babf6f52e63e6 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 10 Feb 2008 16:39:38 +0000 Subject: [PATCH 021/126] Merged revisions 43206,43208-43213 via svnmerge from https://svn.boost.org/svn/boost/trunk ........ r43206 | danieljames | 2008-02-10 09:55:03 +0000 (Sun, 10 Feb 2008) | 1 line Fix some broken links. ........ r43209 | danieljames | 2008-02-10 14:56:22 +0000 (Sun, 10 Feb 2008) | 1 line Link to people pages on the website, as they've been removed from the download. ........ r43210 | danieljames | 2008-02-10 15:02:17 +0000 (Sun, 10 Feb 2008) | 1 line Point links to the pages that used to be in 'more' to the site. ........ r43212 | danieljames | 2008-02-10 16:10:16 +0000 (Sun, 10 Feb 2008) | 1 line Fix links on the home page as well. ........ r43213 | danieljames | 2008-02-10 16:21:22 +0000 (Sun, 10 Feb 2008) | 1 line Generated documentation which is no longer generated. ........ [SVN r43214] --- base_from_member.html | 6 +++--- generator_iterator.htm | 2 +- operators.htm | 10 +++++----- utility.htm | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/base_from_member.html b/base_from_member.html index 4dd70f4..21ee6d2 100644 --- a/base_from_member.html +++ b/base_from_member.html @@ -334,7 +334,7 @@ with the exact pointer type used in switcher's constructor.

    Contributors

    -
    Ed Brey +
    Ed Brey
    Suggested some interface changes.
    R. Samuel Klatchko (switcher's constructor.

    Invented the idiom of how to use a class member for initializing a base class. -
    Dietmar Kuehl +
    Dietmar Kuehl
    Popularized the base-from-member idiom in his IOStream example classes. @@ -353,7 +353,7 @@ with the exact pointer type used in switcher's constructor.

    can be controlled and automated with macros. The implementation uses the Preprocessor library. -
    Daryle Walker +
    Daryle Walker
    Started the library. Contributed the test file base_from_member_test.cpp.
    diff --git a/generator_iterator.htm b/generator_iterator.htm index c81d3d1..6070522 100644 --- a/generator_iterator.htm +++ b/generator_iterator.htm @@ -153,7 +153,7 @@ int main() 05 December, 2006

    Copyright © 2001 Jens Maurer

    + "http://www.boost.org/people/jens_maurer.htm">Jens Maurer

    Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or diff --git a/operators.htm b/operators.htm index fca90e5..13d0d0b 100644 --- a/operators.htm +++ b/operators.htm @@ -2029,13 +2029,13 @@ public:

    Contributors

    -
    Dave Abrahams
    +
    Dave Abrahams
    Started the library and contributed the arithmetic operators in boost/operators.hpp.
    -
    Jeremy Siek
    +
    Jeremy Siek
    Contributed the dereference operators and iterator helpers in iterators_test.cpp.
    -
    Aleksey +
    Aleksey Gurtovoy
    Contributed the code to support base class chaining while remaining backward-compatible with old versions of the library.
    -
    Beman Dawes
    +
    Beman Dawes
    Contributed operators_test.cpp.
    -
    Daryle Walker
    +
    Daryle Walker
    Contributed classes for the shift operators, equivalence, partial ordering, and arithmetic conversions. Added the grouped operator diff --git a/utility.htm b/utility.htm index 937a8a3..9514188 100644 --- a/utility.htm +++ b/utility.htm @@ -68,7 +68,7 @@ const std::list<T>::iterator next = boost::next(prev, 2);

    The distance from the given iterator should be supplied as an absolute value. For example, the iterator four iterators prior to the given iterator p may be obtained by prior(p, 4).

    -

    Contributed by Dave Abrahams. Two-argument versions by Daniel Walker.

    +

    Contributed by Dave Abrahams. Two-argument versions by Daniel Walker.

    Class noncopyable

    Class noncopyable is a base class.  Derive your own class from noncopyable when you want to prohibit copy construction @@ -89,7 +89,7 @@ const std::list<T>::iterator next = boost::next(prev, 2);

    to verify class noncopyable works as expected. It has have been run successfully under GCC 2.95, Metrowerks CodeWarrior 5.0, and Microsoft Visual C++ 6.0 sp 3.

    -

    Contributed by Dave Abrahams.

    +

    Contributed by Dave Abrahams.

    Example

    // inside one of your own headers ...
    
    From 9b52e49fda68c1ce95b7d899ff98f03841edd8dc Mon Sep 17 00:00:00 2001
    From: John Maddock 
    Date: Sat, 15 Mar 2008 18:45:28 +0000
    Subject: [PATCH 022/126] Merge inspection failure fixes from Trunk.
    
    [SVN r43634]
    ---
     call_traits.htm | 30 ++++++++++--------------------
     enable_if.html  | 19 ++++++++++---------
     index.html      |  5 +++--
     3 files changed, 23 insertions(+), 31 deletions(-)
    
    diff --git a/call_traits.htm b/call_traits.htm
    index 6d9bddf..a69c1de 100644
    --- a/call_traits.htm
    +++ b/call_traits.htm
    @@ -740,26 +740,16 @@ specialisation).

    Revised 01 September 2000

    -

    © Copyright boost.org 2000. Permission to copy, use, modify, -sell and distribute this document is granted provided this -copyright notice appears in all copies. This document is provided -"as is" without express or implied warranty, and with -no claim as to its suitability for any purpose.

    - -

    Based on contributions by Steve Cleary, Beman Dawes, Howard -Hinnant and John Maddock.

    - -

    Maintained by John -Maddock, the latest version of this file can be found at www.boost.org, and the boost -discussion list at www.yahoogroups.com/list/boost.

    - -

    .

    - -

     

    - -

     

    +

    + Copyright 2000 Steve Cleary, Beman Dawes, Howard + Hinnant and John Maddock.
    + 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 + ). +

    diff --git a/enable_if.html b/enable_if.html index 2b6ac0a..a17a290 100644 --- a/enable_if.html +++ b/enable_if.html @@ -366,17 +366,18 @@ David Vandevoorde and Nicolai M. Josuttis. C++ Templates: The Complete Guide. Addison-Wesley, 2002. - - - - -
    - -Contributed by:
    -Jaakko Järvi, Jeremiah Willcock and Andrew Lumsdaine
    +
    +

    Copyright Jaakko Järvi, Jeremiah Willcock and Andrew Lumsdaine
    {jajarvi|jewillco|lums}@osl.iu.edu
    Indiana University
    -Open Systems Lab +Open Systems Lab
    +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 +). +

    diff --git a/index.html b/index.html index b08822b..7605aef 100644 --- a/index.html +++ b/index.html @@ -21,14 +21,15 @@ compressed_pair
    current_function
    enable_if
    - iterator_adaptors
    + iterator_adaptors
    + generator iterator adaptors
    operators
    throw_exception
    utility
    value_init


    -

    © Copyright Beman Dawes, 2001

    +

    © Copyright Beman Dawes, 2001

    Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at From 50bc75a8021c413efd0c04b536742d71653d4cfb Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 21 May 2008 20:57:05 +0000 Subject: [PATCH 023/126] Add minor documentation fixes to the release branch. (I left out the changes to the hash library). Merged via svnmerge from https://svn.boost.org/svn/boost/trunk ................ r44807 | danieljames | 2008-04-27 08:39:49 +0100 (Sun, 27 Apr 2008) | 78 lines Merge in documentation fixes. Apart from the change to optional's documenation Jamfile, which I included by mistake. I wrote about this at: http://lists.boost.org/Archives/boost/2008/04/136405.php Merged revisions 44585-44806 via svnmerge from https://svn.boost.org/svn/boost/branches/doc ........ r44585 | danieljames | 2008-04-19 16:25:27 +0100 (Sat, 19 Apr 2008) | 2 lines Fix broken link to vacpp in bjam docs. ........ r44586 | danieljames | 2008-04-19 16:27:36 +0100 (Sat, 19 Apr 2008) | 2 lines Fix broken link to bcpp in bjam docs. ........ r44587 | danieljames | 2008-04-19 16:33:58 +0100 (Sat, 19 Apr 2008) | 2 lines DateTime documentation - Fix a link to the serialization library. ........ r44588 | danieljames | 2008-04-19 16:35:36 +0100 (Sat, 19 Apr 2008) | 2 lines Fix some links in interprocess & intrusive. ........ r44589 | danieljames | 2008-04-19 16:37:39 +0100 (Sat, 19 Apr 2008) | 2 lines Fix some links in the python docs. ........ r44590 | danieljames | 2008-04-19 16:38:29 +0100 (Sat, 19 Apr 2008) | 2 lines Work around a quickbook bug which is affecting the python docs. ........ r44591 | danieljames | 2008-04-19 16:39:34 +0100 (Sat, 19 Apr 2008) | 2 lines Fix a broken link in the numeric conversion docs. ........ r44592 | danieljames | 2008-04-19 16:40:45 +0100 (Sat, 19 Apr 2008) | 2 lines Fix some links in the optional docs. ........ r44593 | danieljames | 2008-04-19 16:42:09 +0100 (Sat, 19 Apr 2008) | 2 lines Fix link to the hash documentation from bimap. ........ r44599 | danieljames | 2008-04-19 18:07:33 +0100 (Sat, 19 Apr 2008) | 2 lines Fix a typo in the format library. ........ r44600 | danieljames | 2008-04-19 19:20:59 +0100 (Sat, 19 Apr 2008) | 1 line Initialise svnmerge. ........ r44641 | danieljames | 2008-04-20 18:59:47 +0100 (Sun, 20 Apr 2008) | 2 lines Fix the lincense url in shared container iterator documentation. ........ r44642 | danieljames | 2008-04-20 19:00:00 +0100 (Sun, 20 Apr 2008) | 2 lines Fix image link in the mpi documentation. ........ r44643 | danieljames | 2008-04-20 19:00:11 +0100 (Sun, 20 Apr 2008) | 2 lines Fix a typo in the spirit docs. ........ r44644 | danieljames | 2008-04-20 19:00:23 +0100 (Sun, 20 Apr 2008) | 2 lines Escape the slash so that quickbook doesn't think it the start of an italic section, and mess up the link. Refs #1844 ........ r44647 | danieljames | 2008-04-20 19:39:47 +0100 (Sun, 20 Apr 2008) | 2 lines Fix another typo in spirit docs. ........ ................ r45232 | danieljames | 2008-05-08 22:50:19 +0100 (Thu, 08 May 2008) | 1 line Fix some invalid xml by replacing ampersands with character entities. ................ r45576 | danieljames | 2008-05-20 16:39:25 +0100 (Tue, 20 May 2008) | 20 lines Merge some small documentation fixes from the doc branch, and mark some previously merged changes as merged. Merged revisions 44811,45129,45142,45154,45281-45282,45365 via svnmerge from https://svn.boost.org/svn/boost/branches/doc ........ r45129 | danieljames | 2008-05-05 12:36:50 +0100 (Mon, 05 May 2008) | 2 lines Update navbar links in boostbook. ........ r45282 | danieljames | 2008-05-11 14:15:31 +0100 (Sun, 11 May 2008) | 2 lines Group functions in the hash header - requires Frank's free-function-group fix. (not included in release branch). ........ r45365 | danieljames | 2008-05-14 21:39:00 +0100 (Wed, 14 May 2008) | 2 lines Add boost.root to standalone hash documentation. (not included in release branch). ........ ................ [SVN r45622] --- shared_container_iterator.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared_container_iterator.html b/shared_container_iterator.html index dfef648..ed149b5 100644 --- a/shared_container_iterator.html +++ b/shared_container_iterator.html @@ -315,7 +315,7 @@ Last modified: Mon Aug 11 11:27:03 EST 2003

    © Copyright 2003 The Trustees of Indiana University. 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)

    + http://www.boost.org/LICENSE_1_0.txt)

    From 8849fbc52d5769d9bfc3b1723aaaa79e95c01f00 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Tue, 17 Jun 2008 22:14:09 +0000 Subject: [PATCH 024/126] Merged value_init.hpp from trunk, including new boost::initialized_value object. (Was discussed beforehand with Fernando Cacciola.) [SVN r46464] --- include/boost/utility/value_init.hpp | 66 +++++++++++++++++----------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/include/boost/utility/value_init.hpp b/include/boost/utility/value_init.hpp index 097f21a..67127c0 100644 --- a/include/boost/utility/value_init.hpp +++ b/include/boost/utility/value_init.hpp @@ -1,4 +1,4 @@ -// (C) Copyright 2002-2007, Fernando Luis Cacciola Carballal. +// (C) 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 @@ -6,29 +6,20 @@ // // 21 Ago 2002 (Created) Fernando Cacciola // 24 Dec 2007 (Refactored and worked around various compiler bugs) Fernando Cacciola, Niels Dekker +// 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola // #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP // Note: The implementation of boost::value_initialized had to deal with the -// fact that various compilers haven't fully implemented value-initialization: -// Microsoft Feedback ID 100744 - Value-initialization in new-expression -// Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005-07-28 -// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744 -// GCC Bug 30111 - Value-initialization of POD base class doesn't initialize members -// Reported by Jonathan Wakely, 2006-12-07 -// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 -// GCC Bug 33916 - Default constructor fails to initialize array members -// Reported by Michael Elizabeth Chastain, 2007-10-26 -// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 -// Borland Report 51854 - Value-initialization: POD struct should be zero-initialized -// Reported by Niels Dekker (LKEB, Leiden University Medical Center), 2007-11-09 -// http://qc.codegear.com/wc/qcmain.aspx?d=51854 -// The constructor of boost::value_initialized works around these issues, by -// clearing the bytes of T, before constructing the T object it contains. +// fact that various compilers haven't fully implemented value-initialization. +// The constructor of boost::value_initialized works around these compiler +// issues, by clearing the bytes of T, before constructing the T object it +// contains. More details on these issues are at libs/utility/value_init.htm #include #include +#include #include #include #include @@ -48,23 +39,32 @@ class value_initialized remove_const::type data; }; - mutable aligned_storage::value> x; + mutable +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) + typename +#endif + aligned_storage::value>::type x; + + wrapper * wrapper_address() const + { + return static_cast( static_cast(&x)); + } public : value_initialized() { - std::memset(x.address(), 0, sizeof(x)); + std::memset(&x, 0, sizeof(x)); #ifdef BOOST_MSVC #pragma warning(push) #if _MSC_VER >= 1310 // When using MSVC 7.1 or higher, the following placement new expression may trigger warning C4345: // "behavior change: an object of POD type constructed with an initializer of the form () -// will be default-initialized". There is no need to worry about this, though. +// will be default-initialized". It is safe to ignore this warning when using value_initialized. #pragma warning(disable: 4345) #endif #endif - new (x.address()) wrapper(); + new (wrapper_address()) wrapper(); #ifdef BOOST_MSVC #pragma warning(pop) #endif @@ -72,25 +72,25 @@ class value_initialized value_initialized(value_initialized const & arg) { - new (x.address()) wrapper( *static_cast(arg.x.address()) ); + new (wrapper_address()) wrapper( static_cast(*(arg.wrapper_address()))); } value_initialized & operator=(value_initialized const & arg) { - T & this_data = this->data(); - T const & arg_data = arg.data(); - this_data = arg_data; + // Assignment is only allowed when T is non-const. + BOOST_STATIC_ASSERT( ! is_const::value ); + *wrapper_address() = static_cast(*(arg.wrapper_address())); return *this; } ~value_initialized() { - static_cast(x.address())->wrapper::~wrapper(); + wrapper_address()->wrapper::~wrapper(); } T& data() const { - return static_cast(x.address())->data; + return wrapper_address()->data; } operator T&() const { return this->data(); } @@ -110,6 +110,20 @@ T& get ( value_initialized& x ) return x.data() ; } + +class initialized_value_t +{ + public : + + template operator T() const + { + return get( value_initialized() ); + } +}; + +initialized_value_t const initialized_value = {} ; + + } // namespace boost From 8827b8ed8b79a1ae9f93b1fcd745ae4b57349184 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Tue, 17 Jun 2008 22:17:14 +0000 Subject: [PATCH 025/126] Merged value_init doc + test from trunk, including doc and test for boost::initialized_value, that was added with changeset [46464] [SVN r46465] --- value_init.htm | 63 +++++++++++++++++++++++++++++++++++++++++---- value_init_test.cpp | 39 ++++++++++++++++++++++++++-- 2 files changed, 95 insertions(+), 7 deletions(-) diff --git a/value_init.htm b/value_init.htm index 405f0b6..531814e 100644 --- a/value_init.htm +++ b/value_init.htm @@ -28,11 +28,12 @@
    -
    Types
    +
    Types and objects
    Acknowledgements
    @@ -52,6 +53,9 @@ union and class types. Moreover, value_initialized offers a workaround to various compiler issues regarding value-initialization. +Furthermore, a const object, initialized_value is provided, +to avoid repeating the type name when retrieving the value from a +value_initialized<T> object.

    @@ -117,6 +121,16 @@ constructed by the following declaration:
       value_initialized<T> var;
     
    +

    +

    +The const object initialized_value +allows value-initializing a variable as follows: +

    +  T var = initialized_value ;
    +
    +This form of initialization is semantically equivalent to T4 var4 = T4(), +but robust against the aforementioned compiler issues. +

    Details

    @@ -235,7 +249,7 @@ offer a workaround to these issues: value_initialized will now clea its internal data, prior to constructing the object that it contains.

    -

    Types

    +

    Types and objects

    template class value_initialized<T>

    @@ -298,6 +312,43 @@ the wrapped object is always performed with the get() idiom:

    value_initialized<int> x ;
    get(x) = 1 ; // OK

    value_initialized<int const> cx ;
    get(x) = 1 ; // ERROR: Cannot modify a const object

    value_initialized<int> const x_c ;
    get(x_c) = 1 ; // ERROR: Cannot modify a const object

    value_initialized<int const> const cx_c ;
    get(cx_c) = 1 ; // ERROR: Cannot modify a const object
    +

    initialized_value

    + +
    +namespace boost {
    +class initialized_value_t
    +{
    +  public :
    +    template <class T> operator T() const ;
    +};
    +
    +initialized_value_t const initialized_value = {} ;
    +
    +} // namespace boost
    +
    + +initialized_value provides a convenient way to get +an initialized value: its conversion operator provides an appropriate +value-initialized object for any CopyConstructible type. + +Suppose you need to have an initialized variable of type T. +You could do it as follows: +
    +  T var = T();
    +
    +But as mentioned before, this form suffers from various compiler issues. +The template value_initialized offers a workaround: +
    +  T var = get( value_initialized<T>() );
    +
    +Unfortunately both forms repeat the type name, which +is rather short now (T), but could of course be +more like Namespace::Template<Arg>::Type. +Instead, one could use initialized_value as follows: +
    +  T var = initialized_value ;
    +
    +

    References

    [1] Bjarne Stroustrup, Gabriel Dos Reis, and J. Stephen Adamczyk wrote various papers, proposing to extend the support for brace-enclosed initializer lists @@ -320,13 +371,15 @@ Special thanks to Björn Karlsson who carefully edited and completed this do

    value_initialized was reimplemented by Fernando Cacciola and Niels Dekker for Boost release version 1.35 (2008), offering a workaround to various compiler issues.

    +

    initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008). +

    Developed by Fernando Cacciola, the latest version of this file can be found at www.boost.org.


    -

    Revised 15 January 2008

    +

    Revised 23 May 2008

    © Copyright Fernando Cacciola, 2002, 2008.

    @@ -337,4 +390,4 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
    - \ No newline at end of file + diff --git a/value_init_test.cpp b/value_init_test.cpp index 7b332d7..7191156 100644 --- a/value_init_test.cpp +++ b/value_init_test.cpp @@ -6,8 +6,9 @@ // // Test program for "boost/utility/value_init.hpp" // -// 21 Agu 2002 (Created) Fernando Cacciola +// 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 #include // For memcmp. #include @@ -52,7 +53,7 @@ struct NonPODBase struct NonPOD : NonPODBase { NonPOD () : id() {} - NonPOD ( std::string const& id_) : id(id_) {} + explicit NonPOD ( std::string const& id_) : id(id_) {} friend std::ostream& operator << ( std::ostream& os, NonPOD const& npod ) { return os << '(' << npod.id << ')' ; } @@ -180,6 +181,32 @@ struct CopyFunctionCallTester }; +template +void check_initialized_value ( T const& y ) +{ + T initializedValue = boost::initialized_value ; + BOOST_CHECK ( 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 for a specific type T. // The first argument (y) is assumed have the value of a value-initialized object. @@ -189,9 +216,13 @@ template bool test ( T const& y, T const& z ) { const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter(); + + check_initialized_value(y); + boost::value_initialized x ; BOOST_CHECK ( y == x ) ; BOOST_CHECK ( y == boost::get(x) ) ; + static_cast(x) = z ; boost::get(x) = z ; BOOST_CHECK ( x == z ) ; @@ -275,6 +306,10 @@ int test_main(int, char **) boost::value_initialized valueInitializedArrayOfBytes; BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0); + boost::value_initialized valueInitializedArrayOfBytes2; + valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes; + BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0); + boost::value_initialized copyFunctionCallTester1; BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed); BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called); From 492a8ad213f4a7dcc2e52ce4beb345b3070fcab8 Mon Sep 17 00:00:00 2001 From: Anthony Williams Date: Wed, 18 Jun 2008 13:01:08 +0000 Subject: [PATCH 026/126] Merge of new boost.thread code along with required changes from boost.bind [SVN r46474] --- include/boost/utility/addressof.hpp | 43 ++++++++++++++++------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/include/boost/utility/addressof.hpp b/include/boost/utility/addressof.hpp index 7629488..8e0a586 100644 --- a/include/boost/utility/addressof.hpp +++ b/include/boost/utility/addressof.hpp @@ -1,6 +1,7 @@ // Copyright (C) 2002 Brad King (brad.king@kitware.com) // Douglas Gregor (gregod@cs.rpi.edu) -// Peter Dimov +// +// Copyright (C) 2002, 2008 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -14,27 +15,31 @@ # include # include -namespace boost { - -// Do not make addressof() inline. Breaks MSVC 7. (Peter Dimov) - -// VC7 strips const from nested classes unless we add indirection here -# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) - -template struct _addp +namespace boost { - typedef T * type; + +namespace detail +{ + +template struct addressof_impl +{ + static inline T * f( T & v, long ) + { + return reinterpret_cast( + &const_cast(reinterpret_cast(v))); + } + + static inline T * f( T * v, int ) + { + return v; + } }; - -template typename _addp::type -# else -template T* -# endif -addressof(T& v) +} // namespace detail + +template T * addressof( T & v ) { - return reinterpret_cast( - &const_cast(reinterpret_cast(v))); + return boost::detail::addressof_impl::f( v, 0 ); } // Borland doesn't like casting an array reference to a char reference @@ -53,6 +58,6 @@ const T (*addressof(const T (&t)[N]))[N] } # endif -} +} // namespace boost #endif // BOOST_UTILITY_ADDRESSOF_HPP From 17bee9d43fd2b8db688e6f20e6b4bf4bbb11aa85 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Sat, 28 Jun 2008 13:57:20 +0000 Subject: [PATCH 027/126] =?UTF-8?q?With=20his=20kind=20permission,=20chang?= =?UTF-8?q?e=20Jaakko=20"J=C3=A4rvi"=20to=20"Jarvi"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [SVN r46809] --- enable_if/test/constructors.cpp | 2 +- enable_if/test/dummy_arg_disambiguation.cpp | 2 +- enable_if/test/lazy.cpp | 2 +- enable_if/test/lazy_test.cpp | 2 +- enable_if/test/member_templates.cpp | 2 +- enable_if/test/namespace_disambiguation.cpp | 2 +- enable_if/test/no_disambiguation.cpp | 2 +- enable_if/test/partial_specializations.cpp | 2 +- include/boost/ref.hpp | 2 +- include/boost/utility/enable_if.hpp | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/enable_if/test/constructors.cpp b/enable_if/test/constructors.cpp index 557b2f0..515d9b4 100644 --- a/enable_if/test/constructors.cpp +++ b/enable_if/test/constructors.cpp @@ -6,7 +6,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Authors: Jaakko Järvi (jajarvi at osl.iu.edu) +// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) // Jeremiah Willcock (jewillco at osl.iu.edu) // Andrew Lumsdaine (lums at osl.iu.edu) diff --git a/enable_if/test/dummy_arg_disambiguation.cpp b/enable_if/test/dummy_arg_disambiguation.cpp index bb9f733..2c9afaf 100644 --- a/enable_if/test/dummy_arg_disambiguation.cpp +++ b/enable_if/test/dummy_arg_disambiguation.cpp @@ -6,7 +6,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Authors: Jaakko Järvi (jajarvi at osl.iu.edu) +// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) // Jeremiah Willcock (jewillco at osl.iu.edu) // Andrew Lumsdaine (lums at osl.iu.edu) diff --git a/enable_if/test/lazy.cpp b/enable_if/test/lazy.cpp index d766fc9..d41bcd4 100644 --- a/enable_if/test/lazy.cpp +++ b/enable_if/test/lazy.cpp @@ -6,7 +6,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Authors: Jaakko Järvi (jajarvi at osl.iu.edu) +// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) // Jeremiah Willcock (jewillco at osl.iu.edu) // Andrew Lumsdaine (lums at osl.iu.edu) diff --git a/enable_if/test/lazy_test.cpp b/enable_if/test/lazy_test.cpp index d52d01e..87a595e 100644 --- a/enable_if/test/lazy_test.cpp +++ b/enable_if/test/lazy_test.cpp @@ -6,7 +6,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Authors: Jaakko Järvi (jajarvi at osl.iu.edu) +// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) // Jeremiah Willcock (jewillco at osl.iu.edu) // Andrew Lumsdaine (lums at osl.iu.edu) diff --git a/enable_if/test/member_templates.cpp b/enable_if/test/member_templates.cpp index 23dd173..62a8e22 100644 --- a/enable_if/test/member_templates.cpp +++ b/enable_if/test/member_templates.cpp @@ -6,7 +6,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Authors: Jaakko Järvi (jajarvi at osl.iu.edu) +// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) // Jeremiah Willcock (jewillco at osl.iu.edu) // Andrew Lumsdaine (lums at osl.iu.edu) diff --git a/enable_if/test/namespace_disambiguation.cpp b/enable_if/test/namespace_disambiguation.cpp index 90a98a1..15430b1 100644 --- a/enable_if/test/namespace_disambiguation.cpp +++ b/enable_if/test/namespace_disambiguation.cpp @@ -6,7 +6,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Authors: Jaakko Järvi (jajarvi at osl.iu.edu) +// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) // Jeremiah Willcock (jewillco at osl.iu.edu) // Andrew Lumsdaine (lums at osl.iu.edu) diff --git a/enable_if/test/no_disambiguation.cpp b/enable_if/test/no_disambiguation.cpp index f4936e8..e2488b0 100644 --- a/enable_if/test/no_disambiguation.cpp +++ b/enable_if/test/no_disambiguation.cpp @@ -6,7 +6,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Authors: Jaakko Järvi (jajarvi at osl.iu.edu) +// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) // Jeremiah Willcock (jewillco at osl.iu.edu) // Andrew Lumsdaine (lums at osl.iu.edu) diff --git a/enable_if/test/partial_specializations.cpp b/enable_if/test/partial_specializations.cpp index 3dce799..172346e 100644 --- a/enable_if/test/partial_specializations.cpp +++ b/enable_if/test/partial_specializations.cpp @@ -6,7 +6,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Authors: Jaakko Järvi (jajarvi at osl.iu.edu) +// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) // Jeremiah Willcock (jewillco at osl.iu.edu) // Andrew Lumsdaine (lums at osl.iu.edu) diff --git a/include/boost/ref.hpp b/include/boost/ref.hpp index ab09ae7..330ca65 100644 --- a/include/boost/ref.hpp +++ b/include/boost/ref.hpp @@ -15,7 +15,7 @@ // // ref.hpp - ref/cref, useful helper functions // -// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi) +// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) // Copyright (C) 2001, 2002 Peter Dimov // Copyright (C) 2002 David Abrahams // diff --git a/include/boost/utility/enable_if.hpp b/include/boost/utility/enable_if.hpp index c8b54c4..e076e7b 100644 --- a/include/boost/utility/enable_if.hpp +++ b/include/boost/utility/enable_if.hpp @@ -6,7 +6,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Authors: Jaakko Järvi (jajarvi at osl.iu.edu) +// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) // Jeremiah Willcock (jewillco at osl.iu.edu) // Andrew Lumsdaine (lums at osl.iu.edu) From e632b0fb1f56e0f3a17349bb8938bf94c0a1a19b Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sat, 28 Jun 2008 18:29:40 +0000 Subject: [PATCH 028/126] Boost Exception In other libraries, watch for compile error referring to throw_exception_assert_compatibility in boost::throw_exception. Resolve by throwing an exception that derives from std::exception. This is not a new requirement but it is being enforced now. [SVN r46818] --- include/boost/exception.hpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 include/boost/exception.hpp diff --git a/include/boost/exception.hpp b/include/boost/exception.hpp new file mode 100644 index 0000000..d805002 --- /dev/null +++ b/include/boost/exception.hpp @@ -0,0 +1,19 @@ +//Copyright (c) 2006-2008 Emil Dotchevski and Reverge Studios, Inc. + +//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) + +#ifndef UUID_1D94A7C6054E11DB9804B622A1EF5492 +#define UUID_1D94A7C6054E11DB9804B622A1EF5492 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif From 7a036f6f3a0dfec1b1ee40bc381d9b477b779d7f Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 4 Jul 2008 17:04:47 +0000 Subject: [PATCH 029/126] Merge some small fixes from trunk. Merged revisions 46740,46742,47002,47040 via svnmerge from https://svn.boost.org/svn/boost/trunk ........ r46740 | danieljames | 2008-06-26 20:20:56 +0100 (Thu, 26 Jun 2008) | 1 line Fix a character encoding error. ........ r46742 | danieljames | 2008-06-26 20:25:38 +0100 (Thu, 26 Jun 2008) | 6 lines Give the asio documentation its own target. The asio documentation is built with the rest of the combined documentation but is really separate. So give it its own target so that separate parts can be built separately. ........ r47040 | danieljames | 2008-07-03 15:34:56 +0100 (Thu, 03 Jul 2008) | 1 line Workaround for some template syntax not supported in old versions of Visual C++ 6.5 ........ [SVN r47078] --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 7605aef..ff22fb4 100644 --- a/index.html +++ b/index.html @@ -29,7 +29,7 @@ value_init


    -

    © Copyright Beman Dawes, 2001

    +

    © Copyright Beman Dawes, 2001

    Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at From 4b24dba257ee35e9e6cc3b8e18c2e449d60d096d Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Thu, 18 Sep 2008 02:54:03 +0000 Subject: [PATCH 030/126] Replaced copyright symbols with (c) to match trunk [SVN r48842] --- enable_if/test/constructors.cpp | 2 +- enable_if/test/dummy_arg_disambiguation.cpp | 2 +- enable_if/test/lazy.cpp | 2 +- enable_if/test/lazy_test.cpp | 2 +- enable_if/test/member_templates.cpp | 2 +- enable_if/test/namespace_disambiguation.cpp | 2 +- enable_if/test/no_disambiguation.cpp | 2 +- enable_if/test/partial_specializations.cpp | 2 +- include/boost/utility/enable_if.hpp | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/enable_if/test/constructors.cpp b/enable_if/test/constructors.cpp index 515d9b4..0d465de 100644 --- a/enable_if/test/constructors.cpp +++ b/enable_if/test/constructors.cpp @@ -1,6 +1,6 @@ // Boost enable_if library -// Copyright 2003 © The Trustees of Indiana University. +// Copyright 2003 (c) The Trustees of Indiana University. // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/enable_if/test/dummy_arg_disambiguation.cpp b/enable_if/test/dummy_arg_disambiguation.cpp index 2c9afaf..60dfdfd 100644 --- a/enable_if/test/dummy_arg_disambiguation.cpp +++ b/enable_if/test/dummy_arg_disambiguation.cpp @@ -1,6 +1,6 @@ // Boost enable_if library -// Copyright 2003 © The Trustees of Indiana University. +// Copyright 2003 (c) The Trustees of Indiana University. // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/enable_if/test/lazy.cpp b/enable_if/test/lazy.cpp index d41bcd4..f04111e 100644 --- a/enable_if/test/lazy.cpp +++ b/enable_if/test/lazy.cpp @@ -1,6 +1,6 @@ // Boost enable_if library -// Copyright 2003 © The Trustees of Indiana University. +// Copyright 2003 (c) The Trustees of Indiana University. // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/enable_if/test/lazy_test.cpp b/enable_if/test/lazy_test.cpp index 87a595e..9ec5324 100644 --- a/enable_if/test/lazy_test.cpp +++ b/enable_if/test/lazy_test.cpp @@ -1,6 +1,6 @@ // Boost enable_if library -// Copyright 2003 © The Trustees of Indiana University. +// Copyright 2003 (c) The Trustees of Indiana University. // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/enable_if/test/member_templates.cpp b/enable_if/test/member_templates.cpp index 62a8e22..55e2d80 100644 --- a/enable_if/test/member_templates.cpp +++ b/enable_if/test/member_templates.cpp @@ -1,6 +1,6 @@ // Boost enable_if library -// Copyright 2003 © The Trustees of Indiana University. +// Copyright 2003 (c) The Trustees of Indiana University. // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/enable_if/test/namespace_disambiguation.cpp b/enable_if/test/namespace_disambiguation.cpp index 15430b1..45d4f0a 100644 --- a/enable_if/test/namespace_disambiguation.cpp +++ b/enable_if/test/namespace_disambiguation.cpp @@ -1,6 +1,6 @@ // Boost enable_if library -// Copyright 2003 © The Trustees of Indiana University. +// Copyright 2003 (c) The Trustees of Indiana University. // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/enable_if/test/no_disambiguation.cpp b/enable_if/test/no_disambiguation.cpp index e2488b0..e2416ed 100644 --- a/enable_if/test/no_disambiguation.cpp +++ b/enable_if/test/no_disambiguation.cpp @@ -1,6 +1,6 @@ // Boost enable_if library -// Copyright 2003 © The Trustees of Indiana University. +// Copyright 2003 (c) The Trustees of Indiana University. // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/enable_if/test/partial_specializations.cpp b/enable_if/test/partial_specializations.cpp index 172346e..1d4db99 100644 --- a/enable_if/test/partial_specializations.cpp +++ b/enable_if/test/partial_specializations.cpp @@ -1,6 +1,6 @@ // Boost enable_if library -// Copyright 2003 © The Trustees of Indiana University. +// Copyright 2003 (c) The Trustees of Indiana University. // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/include/boost/utility/enable_if.hpp b/include/boost/utility/enable_if.hpp index e076e7b..d292c6a 100644 --- a/include/boost/utility/enable_if.hpp +++ b/include/boost/utility/enable_if.hpp @@ -1,6 +1,6 @@ // Boost enable_if library -// Copyright 2003 © The Trustees of Indiana University. +// Copyright 2003 (c) The Trustees of Indiana University. // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at From 10e83b490b95eca97e962ead70731f2a571e7fef Mon Sep 17 00:00:00 2001 From: Matthew Calabrese Date: Fri, 19 Sep 2008 08:19:02 +0000 Subject: [PATCH 031/126] Merged BOOST_BINARY utility macro. [SVN r48879] --- binary_test.cpp | 643 ++++++++++++++++++++++++++++ include/boost/utility.hpp | 3 +- include/boost/utility/binary.hpp | 708 +++++++++++++++++++++++++++++++ test/Jamfile.v2 | 1 + utility.htm | 60 ++- 5 files changed, 1412 insertions(+), 3 deletions(-) create mode 100644 binary_test.cpp create mode 100644 include/boost/utility/binary.hpp diff --git a/binary_test.cpp b/binary_test.cpp new file mode 100644 index 0000000..b4041b3 --- /dev/null +++ b/binary_test.cpp @@ -0,0 +1,643 @@ +/*============================================================================= + 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 +#include +#include +#include + +/* +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 test_main( int, char *[] ) +{ + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_1_bit ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_2_bits ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_3_bits ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_4_bits ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_5_bits ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_6_bits ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_7_bits ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_8_bits ) ); + + BOOST_CHECK( std::equal( &random_unsigned_ints_hex[0] + , random_unsigned_ints_hex + num_random_test_values + , &random_unsigned_ints_binary[0] + ) + ); + + BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_U( 110100 1010 ) ) ) + == unsigned_int_id + ); + + BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_UL( 11110 ) ) ) + == unsigned_long_int_id + ); + + BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_LU( 10 0001 ) ) ) + == unsigned_long_int_id + ); + + return 0; +} diff --git a/include/boost/utility.hpp b/include/boost/utility.hpp index 211d89d..b909f29 100644 --- a/include/boost/utility.hpp +++ b/include/boost/utility.hpp @@ -10,7 +10,8 @@ #define BOOST_UTILITY_HPP #include -#include +#include +#include #include #include #include diff --git a/include/boost/utility/binary.hpp b/include/boost/utility/binary.hpp new file mode 100644 index 0000000..8cef146 --- /dev/null +++ b/include/boost/utility/binary.hpp @@ -0,0 +1,708 @@ +/*============================================================================= + Copyright (c) 2005 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) +==============================================================================*/ + +#ifndef BOOST_UTILITY_BINARY_HPP +#define BOOST_UTILITY_BINARY_HPP + +/*============================================================================= + + Binary Literal Utility + ______________________ + + + The following code works by converting the input bit pattern into a + Boost.Preprocessor sequence, then converting groupings of 3 bits each into + the corresponding octal digit, and finally concatenating all of the digits + together along with a leading zero. This yields a standard octal literal + with the desired value as specified in bits. + +==============================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BOOST_BINARY( bit_groupings ) \ + BOOST_BINARY_LITERAL_D( BOOST_PP_DEDUCE_D(), bit_groupings ) + +#define BOOST_BINARY_U( bit_groupings ) \ + BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, U ) + +#define BOOST_BINARY_L( bit_groupings ) \ + BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, L ) + +#define BOOST_BINARY_UL( bit_groupings ) \ + BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, UL ) + +#define BOOST_BINARY_LU( bit_groupings ) \ + BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, LU ) + +#define BOOST_BINARY_LL( bit_groupings ) \ + BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, LL ) + +#define BOOST_BINARY_ULL( bit_groupings ) \ + BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, ULL ) + +#define BOOST_BINARY_LLU( bit_groupings ) \ + BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, LLU ) + +#define BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, suffix ) \ + BOOST_SUFFIXED_BINARY_LITERAL_D( BOOST_PP_DEDUCE_D(), bit_groupings, suffix ) + +#define BOOST_SUFFIXED_BINARY_LITERAL_D( d, bit_groupings, suffix ) \ + BOOST_PP_CAT( BOOST_BINARY_LITERAL_D( d, bit_groupings ), suffix ) + +#define BOOST_BINARY_LITERAL_D( d, bit_groupings ) \ + BOOST_PP_SEQ_CAT \ + ( (0) BOOST_DETAIL_CREATE_BINARY_LITERAL_OCTAL_SEQUENCE( d, bit_groupings ) \ + ) + +#define BOOST_DETAIL_CREATE_BINARY_LITERAL_OCTAL_SEQUENCE( d, bit_groupings ) \ + BOOST_PP_SEQ_TRANSFORM \ + ( BOOST_DETAIL_TRIPLE_TO_OCTAL_OPERATION \ + , BOOST_PP_NIL \ + , BOOST_PP_IDENTITY( BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_TRIPLE_SEQUENCE )()\ + ( BOOST_DETAIL_COMPLETE_TRIPLE_SEQUENCE \ + ( \ + d \ + , BOOST_DETAIL_CREATE_BINARY_LITERAL_BIT_SEQUENCE( d, bit_groupings ) \ + ) \ + ) \ + ) + +#define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_TRIPLE_SEQUENCE( bit_sequence ) \ + BOOST_PP_CAT \ + ( BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1 bit_sequence \ + , END_BIT \ + ) + +#define BOOST_DETAIL_BITS_PER_OCTIT 3 + +#define BOOST_DETAIL_COMPLETE_TRIPLE_SEQUENCE( d, incomplete_nibble_sequence ) \ + BOOST_PP_CAT \ + ( BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_ \ + , BOOST_PP_MOD_D( d \ + , BOOST_PP_SEQ_SIZE( incomplete_nibble_sequence ) \ + , BOOST_DETAIL_BITS_PER_OCTIT \ + ) \ + ) \ + incomplete_nibble_sequence + +#define BOOST_DETAIL_FIXED_COMPL( bit ) \ + BOOST_PP_CAT( BOOST_DETAIL_FIXED_COMPL_, bit ) + +#define BOOST_DETAIL_FIXED_COMPL_0 1 + +#define BOOST_DETAIL_FIXED_COMPL_1 0 + +#define BOOST_DETAIL_CREATE_BINARY_LITERAL_BIT_SEQUENCE( d, bit_groupings ) \ + BOOST_PP_EMPTY \ + BOOST_PP_CAT( BOOST_PP_WHILE_, d ) \ + ( BOOST_DETAIL_BINARY_LITERAL_PREDICATE \ + , BOOST_DETAIL_BINARY_LITERAL_OPERATION \ + , bit_groupings () \ + ) + +#define BOOST_DETAIL_BINARY_LITERAL_PREDICATE( d, state ) \ + BOOST_DETAIL_FIXED_COMPL( BOOST_DETAIL_IS_NULLARY_ARGS( state ) ) + +#define BOOST_DETAIL_BINARY_LITERAL_OPERATION( d, state ) \ + BOOST_DETAIL_SPLIT_AND_SWAP \ + ( BOOST_PP_CAT( BOOST_DETAIL_BINARY_LITERAL_ELEMENT_, state ) ) + +#define BOOST_DETAIL_TRIPLE_TO_OCTAL_OPERATION( s, dummy_param, tuple ) \ + BOOST_DETAIL_TERNARY_TRIPLE_TO_OCTAL tuple + +#define BOOST_DETAIL_TERNARY_TRIPLE_TO_OCTAL( bit2, bit1, bit0 ) \ + BOOST_DETAIL_TRIPLE_TO_OCTAL_ ## bit2 ## bit1 ## bit0 + +#define BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_1 (0)(0) +#define BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_2 (0) +#define BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_0 + +#define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1END_BIT + +#define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1( bit ) \ + ( ( bit, BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_2 + +#define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_2( bit ) \ + bit, BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_3 + +#define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_3( bit ) \ + bit ) ) BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1 + +#define BOOST_DETAIL_SPLIT_AND_SWAP( params ) \ + BOOST_PP_IDENTITY( BOOST_DETAIL_SPLIT_AND_SWAP_PARAMS )()( params ) + +#define BOOST_DETAIL_SPLIT_AND_SWAP_PARAMS( first_param, second_param ) \ + second_param first_param + +#define BOOST_DETAIL_LEFT_OF_COMMA( params ) \ + BOOST_PP_IDENTITY( BOOST_DETAIL_FIRST_MACRO_PARAM )()( params ) + +#define BOOST_DETAIL_FIRST_MACRO_PARAM( first_param, second_param ) \ + first_param + +/* Begin derived concepts from Chaos by Paul Mensonides */ + +#define BOOST_DETAIL_IS_NULLARY_ARGS( param ) \ + BOOST_DETAIL_LEFT_OF_COMMA \ + ( BOOST_PP_CAT( BOOST_DETAIL_IS_NULLARY_ARGS_R_ \ + , BOOST_DETAIL_IS_NULLARY_ARGS_C param \ + ) \ + ) + +#define BOOST_DETAIL_IS_NULLARY_ARGS_C() \ + 1 + +#define BOOST_DETAIL_IS_NULLARY_ARGS_R_1 \ + 1, BOOST_PP_NIL + +#define BOOST_DETAIL_IS_NULLARY_ARGS_R_BOOST_DETAIL_IS_NULLARY_ARGS_C \ + 0, BOOST_PP_NIL + +/* End derived concepts from Chaos by Paul Mensonides */ + +#define BOOST_DETAIL_TRIPLE_TO_OCTAL_000 0 +#define BOOST_DETAIL_TRIPLE_TO_OCTAL_001 1 +#define BOOST_DETAIL_TRIPLE_TO_OCTAL_010 2 +#define BOOST_DETAIL_TRIPLE_TO_OCTAL_011 3 +#define BOOST_DETAIL_TRIPLE_TO_OCTAL_100 4 +#define BOOST_DETAIL_TRIPLE_TO_OCTAL_101 5 +#define BOOST_DETAIL_TRIPLE_TO_OCTAL_110 6 +#define BOOST_DETAIL_TRIPLE_TO_OCTAL_111 7 + +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0 (0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1 (1), + +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00 (0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01 (0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10 (1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11 (1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00 (0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01 (0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10 (1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11 (1)(1), + +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000 (0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001 (0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010 (0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011 (0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100 (1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101 (1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110 (1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111 (1)(1)(1), + +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000 (0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001 (0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010 (0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011 (0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100 (0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101 (0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110 (0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111 (0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000 (1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001 (1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010 (1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011 (1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100 (1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101 (1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110 (1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111 (1)(1)(1)(1), + +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000 (0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001 (0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010 (0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011 (0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100 (0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101 (0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110 (0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111 (0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000 (0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001 (0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010 (0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011 (0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100 (0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101 (0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110 (0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111 (0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000 (1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001 (1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010 (1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011 (1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100 (1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101 (1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110 (1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111 (1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000 (1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001 (1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010 (1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011 (1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100 (1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101 (1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110 (1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111 (1)(1)(1)(1)(1), + +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000000 (0)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000001 (0)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000010 (0)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000011 (0)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000100 (0)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000101 (0)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000110 (0)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000111 (0)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001000 (0)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001001 (0)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001010 (0)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001011 (0)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001100 (0)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001101 (0)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001110 (0)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001111 (0)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010000 (0)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010001 (0)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010010 (0)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010011 (0)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010100 (0)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010101 (0)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010110 (0)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010111 (0)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011000 (0)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011001 (0)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011010 (0)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011011 (0)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011100 (0)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011101 (0)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011110 (0)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011111 (0)(1)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100000 (1)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100001 (1)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100010 (1)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100011 (1)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100100 (1)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100101 (1)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100110 (1)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100111 (1)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101000 (1)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101001 (1)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101010 (1)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101011 (1)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101100 (1)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101101 (1)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101110 (1)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101111 (1)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110000 (1)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110001 (1)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110010 (1)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110011 (1)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110100 (1)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110101 (1)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110110 (1)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110111 (1)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111000 (1)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111001 (1)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111010 (1)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111011 (1)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111100 (1)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111101 (1)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111110 (1)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111111 (1)(1)(1)(1)(1)(1), + +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000000 (0)(0)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000001 (0)(0)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000010 (0)(0)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000011 (0)(0)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000100 (0)(0)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000101 (0)(0)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000110 (0)(0)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000111 (0)(0)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001000 (0)(0)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001001 (0)(0)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001010 (0)(0)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001011 (0)(0)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001100 (0)(0)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001101 (0)(0)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001110 (0)(0)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001111 (0)(0)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010000 (0)(0)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010001 (0)(0)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010010 (0)(0)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010011 (0)(0)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010100 (0)(0)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010101 (0)(0)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010110 (0)(0)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010111 (0)(0)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011000 (0)(0)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011001 (0)(0)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011010 (0)(0)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011011 (0)(0)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011100 (0)(0)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011101 (0)(0)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011110 (0)(0)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011111 (0)(0)(1)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100000 (0)(1)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100001 (0)(1)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100010 (0)(1)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100011 (0)(1)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100100 (0)(1)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100101 (0)(1)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100110 (0)(1)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100111 (0)(1)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101000 (0)(1)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101001 (0)(1)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101010 (0)(1)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101011 (0)(1)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101100 (0)(1)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101101 (0)(1)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101110 (0)(1)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101111 (0)(1)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110000 (0)(1)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110001 (0)(1)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110010 (0)(1)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110011 (0)(1)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110100 (0)(1)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110101 (0)(1)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110110 (0)(1)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110111 (0)(1)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111000 (0)(1)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111001 (0)(1)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111010 (0)(1)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111011 (0)(1)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111100 (0)(1)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111101 (0)(1)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111110 (0)(1)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111111 (0)(1)(1)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000000 (1)(0)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000001 (1)(0)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000010 (1)(0)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000011 (1)(0)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000100 (1)(0)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000101 (1)(0)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000110 (1)(0)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000111 (1)(0)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001000 (1)(0)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001001 (1)(0)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001010 (1)(0)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001011 (1)(0)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001100 (1)(0)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001101 (1)(0)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001110 (1)(0)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001111 (1)(0)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010000 (1)(0)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010001 (1)(0)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010010 (1)(0)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010011 (1)(0)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010100 (1)(0)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010101 (1)(0)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010110 (1)(0)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010111 (1)(0)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011000 (1)(0)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011001 (1)(0)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011010 (1)(0)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011011 (1)(0)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011100 (1)(0)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011101 (1)(0)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011110 (1)(0)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011111 (1)(0)(1)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100000 (1)(1)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100001 (1)(1)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100010 (1)(1)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100011 (1)(1)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100100 (1)(1)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100101 (1)(1)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100110 (1)(1)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100111 (1)(1)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101000 (1)(1)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101001 (1)(1)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101010 (1)(1)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101011 (1)(1)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101100 (1)(1)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101101 (1)(1)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101110 (1)(1)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101111 (1)(1)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110000 (1)(1)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110001 (1)(1)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110010 (1)(1)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110011 (1)(1)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110100 (1)(1)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110101 (1)(1)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110110 (1)(1)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110111 (1)(1)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111000 (1)(1)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111001 (1)(1)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111010 (1)(1)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111011 (1)(1)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111100 (1)(1)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111101 (1)(1)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111110 (1)(1)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111111 (1)(1)(1)(1)(1)(1)(1), + +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000000 (0)(0)(0)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000001 (0)(0)(0)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000010 (0)(0)(0)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000011 (0)(0)(0)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000100 (0)(0)(0)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000101 (0)(0)(0)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000110 (0)(0)(0)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000111 (0)(0)(0)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001000 (0)(0)(0)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001001 (0)(0)(0)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001010 (0)(0)(0)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001011 (0)(0)(0)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001100 (0)(0)(0)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001101 (0)(0)(0)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001110 (0)(0)(0)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001111 (0)(0)(0)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010000 (0)(0)(0)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010001 (0)(0)(0)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010010 (0)(0)(0)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010011 (0)(0)(0)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010100 (0)(0)(0)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010101 (0)(0)(0)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010110 (0)(0)(0)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010111 (0)(0)(0)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011000 (0)(0)(0)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011001 (0)(0)(0)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011010 (0)(0)(0)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011011 (0)(0)(0)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011100 (0)(0)(0)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011101 (0)(0)(0)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011110 (0)(0)(0)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011111 (0)(0)(0)(1)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100000 (0)(0)(1)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100001 (0)(0)(1)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100010 (0)(0)(1)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100011 (0)(0)(1)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100100 (0)(0)(1)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100101 (0)(0)(1)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100110 (0)(0)(1)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100111 (0)(0)(1)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101000 (0)(0)(1)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101001 (0)(0)(1)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101010 (0)(0)(1)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101011 (0)(0)(1)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101100 (0)(0)(1)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101101 (0)(0)(1)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101110 (0)(0)(1)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101111 (0)(0)(1)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110000 (0)(0)(1)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110001 (0)(0)(1)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110010 (0)(0)(1)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110011 (0)(0)(1)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110100 (0)(0)(1)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110101 (0)(0)(1)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110110 (0)(0)(1)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110111 (0)(0)(1)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111000 (0)(0)(1)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111001 (0)(0)(1)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111010 (0)(0)(1)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111011 (0)(0)(1)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111100 (0)(0)(1)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111101 (0)(0)(1)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111110 (0)(0)(1)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111111 (0)(0)(1)(1)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000000 (0)(1)(0)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000001 (0)(1)(0)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000010 (0)(1)(0)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000011 (0)(1)(0)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000100 (0)(1)(0)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000101 (0)(1)(0)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000110 (0)(1)(0)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000111 (0)(1)(0)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001000 (0)(1)(0)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001001 (0)(1)(0)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001010 (0)(1)(0)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001011 (0)(1)(0)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001100 (0)(1)(0)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001101 (0)(1)(0)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001110 (0)(1)(0)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001111 (0)(1)(0)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010000 (0)(1)(0)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010001 (0)(1)(0)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010010 (0)(1)(0)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010011 (0)(1)(0)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010100 (0)(1)(0)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010101 (0)(1)(0)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010110 (0)(1)(0)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010111 (0)(1)(0)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011000 (0)(1)(0)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011001 (0)(1)(0)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011010 (0)(1)(0)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011011 (0)(1)(0)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011100 (0)(1)(0)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011101 (0)(1)(0)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011110 (0)(1)(0)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011111 (0)(1)(0)(1)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100000 (0)(1)(1)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100001 (0)(1)(1)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100010 (0)(1)(1)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100011 (0)(1)(1)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100100 (0)(1)(1)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100101 (0)(1)(1)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100110 (0)(1)(1)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100111 (0)(1)(1)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101000 (0)(1)(1)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101001 (0)(1)(1)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101010 (0)(1)(1)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101011 (0)(1)(1)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101100 (0)(1)(1)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101101 (0)(1)(1)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101110 (0)(1)(1)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101111 (0)(1)(1)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110000 (0)(1)(1)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110001 (0)(1)(1)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110010 (0)(1)(1)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110011 (0)(1)(1)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110100 (0)(1)(1)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110101 (0)(1)(1)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110110 (0)(1)(1)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110111 (0)(1)(1)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111000 (0)(1)(1)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111001 (0)(1)(1)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111010 (0)(1)(1)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111011 (0)(1)(1)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111100 (0)(1)(1)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111101 (0)(1)(1)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111110 (0)(1)(1)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111111 (0)(1)(1)(1)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000000 (1)(0)(0)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000001 (1)(0)(0)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000010 (1)(0)(0)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000011 (1)(0)(0)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000100 (1)(0)(0)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000101 (1)(0)(0)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000110 (1)(0)(0)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000111 (1)(0)(0)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001000 (1)(0)(0)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001001 (1)(0)(0)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001010 (1)(0)(0)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001011 (1)(0)(0)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001100 (1)(0)(0)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001101 (1)(0)(0)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001110 (1)(0)(0)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001111 (1)(0)(0)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010000 (1)(0)(0)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010001 (1)(0)(0)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010010 (1)(0)(0)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010011 (1)(0)(0)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010100 (1)(0)(0)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010101 (1)(0)(0)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010110 (1)(0)(0)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010111 (1)(0)(0)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011000 (1)(0)(0)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011001 (1)(0)(0)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011010 (1)(0)(0)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011011 (1)(0)(0)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011100 (1)(0)(0)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011101 (1)(0)(0)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011110 (1)(0)(0)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011111 (1)(0)(0)(1)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100000 (1)(0)(1)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100001 (1)(0)(1)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100010 (1)(0)(1)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100011 (1)(0)(1)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100100 (1)(0)(1)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100101 (1)(0)(1)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100110 (1)(0)(1)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100111 (1)(0)(1)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101000 (1)(0)(1)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101001 (1)(0)(1)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101010 (1)(0)(1)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101011 (1)(0)(1)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101100 (1)(0)(1)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101101 (1)(0)(1)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101110 (1)(0)(1)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101111 (1)(0)(1)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110000 (1)(0)(1)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110001 (1)(0)(1)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110010 (1)(0)(1)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110011 (1)(0)(1)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110100 (1)(0)(1)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110101 (1)(0)(1)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110110 (1)(0)(1)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110111 (1)(0)(1)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111000 (1)(0)(1)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111001 (1)(0)(1)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111010 (1)(0)(1)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111011 (1)(0)(1)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111100 (1)(0)(1)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111101 (1)(0)(1)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111110 (1)(0)(1)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111111 (1)(0)(1)(1)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000000 (1)(1)(0)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000001 (1)(1)(0)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000010 (1)(1)(0)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000011 (1)(1)(0)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000100 (1)(1)(0)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000101 (1)(1)(0)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000110 (1)(1)(0)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000111 (1)(1)(0)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001000 (1)(1)(0)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001001 (1)(1)(0)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001010 (1)(1)(0)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001011 (1)(1)(0)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001100 (1)(1)(0)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001101 (1)(1)(0)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001110 (1)(1)(0)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001111 (1)(1)(0)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010000 (1)(1)(0)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010001 (1)(1)(0)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010010 (1)(1)(0)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010011 (1)(1)(0)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010100 (1)(1)(0)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010101 (1)(1)(0)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010110 (1)(1)(0)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010111 (1)(1)(0)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011000 (1)(1)(0)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011001 (1)(1)(0)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011010 (1)(1)(0)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011011 (1)(1)(0)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011100 (1)(1)(0)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011101 (1)(1)(0)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011110 (1)(1)(0)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011111 (1)(1)(0)(1)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100000 (1)(1)(1)(0)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100001 (1)(1)(1)(0)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100010 (1)(1)(1)(0)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100011 (1)(1)(1)(0)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100100 (1)(1)(1)(0)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100101 (1)(1)(1)(0)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100110 (1)(1)(1)(0)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100111 (1)(1)(1)(0)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101000 (1)(1)(1)(0)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101001 (1)(1)(1)(0)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101010 (1)(1)(1)(0)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101011 (1)(1)(1)(0)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101100 (1)(1)(1)(0)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101101 (1)(1)(1)(0)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101110 (1)(1)(1)(0)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101111 (1)(1)(1)(0)(1)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110000 (1)(1)(1)(1)(0)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110001 (1)(1)(1)(1)(0)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110010 (1)(1)(1)(1)(0)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110011 (1)(1)(1)(1)(0)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110100 (1)(1)(1)(1)(0)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110101 (1)(1)(1)(1)(0)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110110 (1)(1)(1)(1)(0)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110111 (1)(1)(1)(1)(0)(1)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111000 (1)(1)(1)(1)(1)(0)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111001 (1)(1)(1)(1)(1)(0)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111010 (1)(1)(1)(1)(1)(0)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111011 (1)(1)(1)(1)(1)(0)(1)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111100 (1)(1)(1)(1)(1)(1)(0)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111101 (1)(1)(1)(1)(1)(1)(0)(1), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111110 (1)(1)(1)(1)(1)(1)(1)(0), +#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111111 (1)(1)(1)(1)(1)(1)(1)(1), + +#endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 56c84a4..321060c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -15,6 +15,7 @@ test-suite utility [ run ../assert_test.cpp ] [ run ../base_from_member_test.cpp ] [ run ../binary_search_test.cpp ] + [ run ../binary_test.cpp ] [ run ../call_traits_test.cpp : -u ] [ compile-fail ../checked_delete_test.cpp ] [ run ../compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor/static : -u ] diff --git a/utility.htm b/utility.htm index 9514188..eff847d 100644 --- a/utility.htm +++ b/utility.htm @@ -23,6 +23,8 @@

  • Function template addressof()
  • Class template result_of
  • +
  • + Macro BOOST_BINARY
  • Other utilities not part of utility.hpp
  • @@ -181,9 +183,63 @@ void f() {

    Class templates for the Base-from-Member Idiom

    See separate documentation.

    +

    Macro BOOST_BINARY

    + +

    The macro BOOST_BINARY is used for the + representation of binary literals. It takes as an argument + a binary number arranged as an arbitrary amount of 1s and 0s in + groupings of length 1 to 8, with groups separated + by spaces. The type of the literal yielded is determined by + the same rules as those of hex and octal + literals (2.13.1p1). By implementation, this macro + expands directly to an octal literal during preprocessing, so + there is no overhead at runtime and the result is useable in + any place that an octal literal would be.

    + +

    In order to directly support binary literals with suffixes, + additional macros of the form BOOST_BINARY_XXX are also + provided, where XXX is a standard integer suffix in all capital + letters. In addition, LL and ULL suffixes may be used for representing + long long and unsigned long long types in compilers which provide + them as an extension.

    + + +

    The BOOST_BINARY family of macros resides in the header + <boost/utility/binary.hpp> + which is automatically included by + <boost/utility.hpp>. + +

    Contributed by Matt Calabrese.

    +

    Example

    +
    +
    +void foo( int );
    +
    +void foo( unsigned long );
    +
    +void bar()
    +{
    +  int value1 = BOOST_BINARY( 100 111000 01 1 110 );
    +
    +  unsigned long value2 = BOOST_BINARY_UL( 100 001 ); // unsigned long
    +
    +  long long value3 = BOOST_BINARY_LL( 11 000 ); // long long if supported
    +
    +  assert(    BOOST_BINARY( 10010 )
    +          &  BOOST_BINARY( 11000 )
    +          == BOOST_BINARY( 10000 )
    +        );
    +
    +  foo( BOOST_BINARY( 1010 ) ); // calls the first foo
    +
    +  foo( BOOST_BINARY_LU( 1010 ) ); // calls the second foo
    +}
    +

    Revised  07 November, 200704 September, 2008

    © Copyright Beman Dawes 1999-2003.

    @@ -191,4 +247,4 @@ void f() { www.boost.org/LICENSE_1_0.txt

    - \ No newline at end of file + From d0ee9a7c28ae8a33701d89d67b84c47e19fb9ea9 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Fri, 19 Sep 2008 20:29:26 +0000 Subject: [PATCH 032/126] Boost Exception major refactoring: works with or without RTTI, vastly improved boost::throw_exception integration. [SVN r48905] --- include/boost/exception.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/boost/exception.hpp b/include/boost/exception.hpp index d805002..c77f215 100644 --- a/include/boost/exception.hpp +++ b/include/boost/exception.hpp @@ -7,13 +7,11 @@ #define UUID_1D94A7C6054E11DB9804B622A1EF5492 #include -#include -#include #include #include +#include #include #include #include -#include #endif From e1991374ae1af1b4b3f7e5218305f8c9d8f46b8f Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 10 Oct 2008 09:29:21 +0000 Subject: [PATCH 033/126] Merge quickbook workaround and fix some links. Merged revisions 48987,49230-49231 via svnmerge from https://svn.boost.org/svn/boost/trunk ........ r48987 | danieljames | 2008-09-28 13:21:39 +0100 (Sun, 28 Sep 2008) | 1 line Clean up some link errors. ........ r49230 | danieljames | 2008-10-09 23:13:48 +0100 (Thu, 09 Oct 2008) | 1 line position_iterator is meant to be a forward iterator, so avoid using operator+ with it. ........ r49231 | danieljames | 2008-10-09 23:14:14 +0100 (Thu, 09 Oct 2008) | 4 lines Work around the problems with window newlines in position_iterator. (I'm about to fix them, but this will get quickbook working immediately). Fixes #2155 ........ [SVN r49242] --- operators.htm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operators.htm b/operators.htm index 13d0d0b..cfe77da 100644 --- a/operators.htm +++ b/operators.htm @@ -2022,7 +2022,7 @@ public: -

    Check the compiler status +

    Check the compiler status report for the test results with selected platforms.


    From 9168cb9c617bb9e274590a2022630778ee65584c Mon Sep 17 00:00:00 2001 From: Nicola Musatti Date: Mon, 13 Oct 2008 19:21:03 +0000 Subject: [PATCH 034/126] CodeGear patch. Fixes #2341 [SVN r49319] --- include/boost/detail/call_traits.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/detail/call_traits.hpp b/include/boost/detail/call_traits.hpp index 54d441c..6ad646e 100644 --- a/include/boost/detail/call_traits.hpp +++ b/include/boost/detail/call_traits.hpp @@ -92,7 +92,7 @@ struct call_traits typedef T& param_type; // hh removed const }; -#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x581 ) ) +#if BOOST_WORKAROUND( __BORLANDC__, < 0x5A0 ) // these are illegal specialisations; cv-qualifies applied to // references have no effect according to [8.3.2p1], // C++ Builder requires them though as it treats cv-qualified From 8652bf51ec528c53cf3dfcf8a48995798a0a78e8 Mon Sep 17 00:00:00 2001 From: Joseph Gauterin Date: Sat, 15 Nov 2008 01:11:24 +0000 Subject: [PATCH 035/126] Merged utility/swap to release branch. [SVN r49761] --- include/boost/swap.hpp | 12 ++++++++ include/boost/utility/swap.hpp | 55 ++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 include/boost/swap.hpp create mode 100644 include/boost/utility/swap.hpp diff --git a/include/boost/swap.hpp b/include/boost/swap.hpp new file mode 100644 index 0000000..dfc11f0 --- /dev/null +++ b/include/boost/swap.hpp @@ -0,0 +1,12 @@ +// Copyright (C) 2007 Joseph Gauterin +// +// 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) + +#ifndef BOOST_SWAP_HPP +#define BOOST_SWAP_HPP + +#include "boost/utility/swap.hpp" + +#endif diff --git a/include/boost/utility/swap.hpp b/include/boost/utility/swap.hpp new file mode 100644 index 0000000..6845e79 --- /dev/null +++ b/include/boost/utility/swap.hpp @@ -0,0 +1,55 @@ +// Copyright (C) 2007, 2008 Steven Watanabe, Joseph Gauterin, 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) +// For more information, see http://www.boost.org + + +#ifndef BOOST_UTILITY_SWAP_HPP +#define BOOST_UTILITY_SWAP_HPP + +// Note: the implementation of this utility contains various workarounds: +// - swap_impl is put outside the boost namespace, to avoid infinite +// recursion (causing stack overflow) when swapping objects of a primitive +// type. +// - swap_impl has a using-directive, rather than a using-declaration, +// because some compilers (including MSVC 7.1, Borland 5.9.3, and +// Intel 8.1) don't do argument-dependent lookup when it has a +// using-declaration instead. +// - boost::swap has two template arguments, instead of one, to +// avoid ambiguity when swapping objects of a Boost type that does +// not have its own boost::swap overload. + +#include //for std::swap +#include //for std::size_t + +namespace boost_swap_impl +{ + template + void swap_impl(T& left, T& right) + { + using namespace std;//use std::swap if argument dependent lookup fails + swap(left,right); + } + + template + void swap_impl(T (& left)[N], T (& right)[N]) + { + for (std::size_t i = 0; i < N; ++i) + { + ::boost_swap_impl::swap_impl(left[i], right[i]); + } + } +} + +namespace boost +{ + template + void swap(T1& left, T2& right) + { + ::boost_swap_impl::swap_impl(left, right); + } +} + +#endif From 3d96ab26d41a6e91261dd5d6f3d050da1b27adf8 Mon Sep 17 00:00:00 2001 From: Joseph Gauterin Date: Sat, 15 Nov 2008 01:13:01 +0000 Subject: [PATCH 036/126] Merged utility/swap tests to release branch. [SVN r49762] --- swap/test/Jamfile.v2 | 33 ++++++ swap/test/lib_header_1.cpp | 10 ++ swap/test/lib_header_2.cpp | 11 ++ swap/test/mixed_headers_1.cpp | 11 ++ swap/test/mixed_headers_2.cpp | 12 ++ swap/test/no_ambiguity_in_boost.cpp | 44 +++++++ swap/test/primitive.cpp | 23 ++++ swap/test/root_header_1.cpp | 10 ++ swap/test/root_header_2.cpp | 11 ++ swap/test/specialized_in_boost.cpp | 45 ++++++++ swap/test/specialized_in_boost_and_other.cpp | 64 +++++++++++ swap/test/specialized_in_global.cpp | 39 +++++++ swap/test/specialized_in_other.cpp | 45 ++++++++ swap/test/specialized_in_std.cpp | 44 +++++++ swap/test/std_bitset.cpp | 33 ++++++ swap/test/std_dateorder.cpp | 32 ++++++ swap/test/std_string.cpp | 31 +++++ swap/test/std_typeinfo_ptr.cpp | 32 ++++++ swap/test/std_vector_of_boost.cpp | 60 ++++++++++ swap/test/std_vector_of_global.cpp | 53 +++++++++ swap/test/std_vector_of_other.cpp | 60 ++++++++++ swap/test/swap_arrays.cpp | 100 ++++++++++++++++ swap/test/swap_test_class.hpp | 114 +++++++++++++++++++ 23 files changed, 917 insertions(+) create mode 100644 swap/test/Jamfile.v2 create mode 100644 swap/test/lib_header_1.cpp create mode 100644 swap/test/lib_header_2.cpp create mode 100644 swap/test/mixed_headers_1.cpp create mode 100644 swap/test/mixed_headers_2.cpp create mode 100644 swap/test/no_ambiguity_in_boost.cpp create mode 100644 swap/test/primitive.cpp create mode 100644 swap/test/root_header_1.cpp create mode 100644 swap/test/root_header_2.cpp create mode 100644 swap/test/specialized_in_boost.cpp create mode 100644 swap/test/specialized_in_boost_and_other.cpp create mode 100644 swap/test/specialized_in_global.cpp create mode 100644 swap/test/specialized_in_other.cpp create mode 100644 swap/test/specialized_in_std.cpp create mode 100644 swap/test/std_bitset.cpp create mode 100644 swap/test/std_dateorder.cpp create mode 100644 swap/test/std_string.cpp create mode 100644 swap/test/std_typeinfo_ptr.cpp create mode 100644 swap/test/std_vector_of_boost.cpp create mode 100644 swap/test/std_vector_of_global.cpp create mode 100644 swap/test/std_vector_of_other.cpp create mode 100644 swap/test/swap_arrays.cpp create mode 100644 swap/test/swap_test_class.hpp diff --git a/swap/test/Jamfile.v2 b/swap/test/Jamfile.v2 new file mode 100644 index 0000000..7071837 --- /dev/null +++ b/swap/test/Jamfile.v2 @@ -0,0 +1,33 @@ +# Copyright (c) 2007, 2008 Joseph Gauterin +# +# 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) + +# bring in rules for testing +import testing ; + +test-suite utility/swap + : + [ compile root_header_1.cpp ] + [ compile root_header_2.cpp ] + [ compile lib_header_1.cpp ] + [ compile lib_header_2.cpp ] + [ compile mixed_headers_1.cpp ] + [ compile mixed_headers_2.cpp ] + [ run primitive.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run specialized_in_boost.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run specialized_in_global.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run specialized_in_other.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run specialized_in_std.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run specialized_in_boost_and_other.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run std_bitset.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run std_dateorder.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run std_string.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run std_typeinfo_ptr.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run std_vector_of_boost.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run std_vector_of_global.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run std_vector_of_other.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run no_ambiguity_in_boost.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run swap_arrays.cpp ../../../test/build//boost_test_exec_monitor/static ] + ; diff --git a/swap/test/lib_header_1.cpp b/swap/test/lib_header_1.cpp new file mode 100644 index 0000000..923dea6 --- /dev/null +++ b/swap/test/lib_header_1.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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) + +// Tests that the swap header compiles as a standalone translation unit + +#include + diff --git a/swap/test/lib_header_2.cpp b/swap/test/lib_header_2.cpp new file mode 100644 index 0000000..e88909d --- /dev/null +++ b/swap/test/lib_header_2.cpp @@ -0,0 +1,11 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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) + +// Tests that the swap header include guards work correctly + +#include +#include + diff --git a/swap/test/mixed_headers_1.cpp b/swap/test/mixed_headers_1.cpp new file mode 100644 index 0000000..cdb9fe5 --- /dev/null +++ b/swap/test/mixed_headers_1.cpp @@ -0,0 +1,11 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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) + +// Tests that the swap headers work when both are included + +#include +#include + diff --git a/swap/test/mixed_headers_2.cpp b/swap/test/mixed_headers_2.cpp new file mode 100644 index 0000000..94e9d87 --- /dev/null +++ b/swap/test/mixed_headers_2.cpp @@ -0,0 +1,12 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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) + +// Tests that the swap headers work when both are included + +#include +#include + + diff --git a/swap/test/no_ambiguity_in_boost.cpp b/swap/test/no_ambiguity_in_boost.cpp new file mode 100644 index 0000000..e269252 --- /dev/null +++ b/swap/test/no_ambiguity_in_boost.cpp @@ -0,0 +1,44 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +// boost::swap internally does an unqualified function call to swap. +// This could have led to ambiguity or infinite recursion, when the +// objects to be swapped would themselves be from the boost namespace. +// If so, boost::swap itself might be found by argument dependent lookup. +// The implementation of boost::swap resolves this issue by giving +// boost::swap two template argumetns, thereby making it less specialized +// than std::swap. + +#include +#define BOOST_INCLUDE_MAIN +#include + +//Put test class in namespace boost +namespace boost +{ + #include "./swap_test_class.hpp" +} + + +int test_main(int, char*[]) +{ + const boost::swap_test_class initial_value1(1); + const boost::swap_test_class initial_value2(2); + + boost::swap_test_class object1 = initial_value1; + boost::swap_test_class object2 = initial_value2; + + boost::swap_test_class::reset(); + boost::swap(object1,object2); + + BOOST_CHECK(object1 == initial_value2); + BOOST_CHECK(object2 == initial_value1); + BOOST_CHECK_EQUAL(boost::swap_test_class::swap_count(),0); + BOOST_CHECK_EQUAL(boost::swap_test_class::copy_count(),3); + + return 0; +} + diff --git a/swap/test/primitive.cpp b/swap/test/primitive.cpp new file mode 100644 index 0000000..380edb3 --- /dev/null +++ b/swap/test/primitive.cpp @@ -0,0 +1,23 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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 +#define BOOST_INCLUDE_MAIN +#include + +int test_main(int, char*[]) +{ + int object1 = 1; + int object2 = 2; + + boost::swap(object1,object2); + + BOOST_CHECK_EQUAL(object1,2); + BOOST_CHECK_EQUAL(object2,1); + + return 0; +} + diff --git a/swap/test/root_header_1.cpp b/swap/test/root_header_1.cpp new file mode 100644 index 0000000..575d2cb --- /dev/null +++ b/swap/test/root_header_1.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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) + +// Tests that the swap header compiles as a standalone translation unit + +#include + diff --git a/swap/test/root_header_2.cpp b/swap/test/root_header_2.cpp new file mode 100644 index 0000000..d26b3a6 --- /dev/null +++ b/swap/test/root_header_2.cpp @@ -0,0 +1,11 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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) + +// Tests that the swap header include guards work correctly + +#include +#include + diff --git a/swap/test/specialized_in_boost.cpp b/swap/test/specialized_in_boost.cpp new file mode 100644 index 0000000..7b3e12e --- /dev/null +++ b/swap/test/specialized_in_boost.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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 +#define BOOST_INCLUDE_MAIN +#include + +//Put test class in namespace boost +namespace boost +{ + #include "./swap_test_class.hpp" +} + +//Provide swap function in namespace boost +namespace boost +{ + void swap(swap_test_class& left, swap_test_class& right) + { + left.swap(right); + } +} + +int test_main(int, char*[]) +{ + const boost::swap_test_class initial_value1(1); + const boost::swap_test_class initial_value2(2); + + boost::swap_test_class object1 = initial_value1; + boost::swap_test_class object2 = initial_value2; + + boost::swap_test_class::reset(); + boost::swap(object1,object2); + + BOOST_CHECK(object1 == initial_value2); + BOOST_CHECK(object2 == initial_value1); + + BOOST_CHECK_EQUAL(boost::swap_test_class::swap_count(),1); + BOOST_CHECK_EQUAL(boost::swap_test_class::copy_count(),0); + + return 0; +} + diff --git a/swap/test/specialized_in_boost_and_other.cpp b/swap/test/specialized_in_boost_and_other.cpp new file mode 100644 index 0000000..ba6247f --- /dev/null +++ b/swap/test/specialized_in_boost_and_other.cpp @@ -0,0 +1,64 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +// Tests whether instances of a class from a namespace other than boost are +// properly swapped, when both boost and the other namespace have a custom +// swap function for that class. Note that it shouldn't be necessary for a class +// in an other namespace to have a custom swap function in boost, because the +// boost::swap utility should find the swap function in the other namespace, by +// argument dependent lookup (ADL). Unfortunately ADL isn't fully implemented +// by some specific compiler versions, including Intel C++ 8.1, MSVC 7.1, and +// Borland 5.9.3. Users of those compilers might consider adding a swap overload +// to the boost namespace. + +#include +#define BOOST_INCLUDE_MAIN +#include + +//Put test class in namespace other +namespace other +{ + #include "./swap_test_class.hpp" +} + +//Provide swap function in namespace boost +namespace boost +{ + void swap(::other::swap_test_class& left, ::other::swap_test_class& right) + { + left.swap(right); + } +} + +//Provide swap function in namespace other +namespace other +{ + void swap(swap_test_class& left, swap_test_class& right) + { + left.swap(right); + } +} + +int test_main(int, char*[]) +{ + const other::swap_test_class initial_value1(1); + const other::swap_test_class initial_value2(2); + + other::swap_test_class object1 = initial_value1; + other::swap_test_class object2 = initial_value2; + + other::swap_test_class::reset(); + boost::swap(object1,object2); + + BOOST_CHECK(object1 == initial_value2); + BOOST_CHECK(object2 == initial_value1); + + BOOST_CHECK_EQUAL(other::swap_test_class::swap_count(),1); + BOOST_CHECK_EQUAL(other::swap_test_class::copy_count(),0); + + return 0; +} + diff --git a/swap/test/specialized_in_global.cpp b/swap/test/specialized_in_global.cpp new file mode 100644 index 0000000..0a0a029 --- /dev/null +++ b/swap/test/specialized_in_global.cpp @@ -0,0 +1,39 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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 +#define BOOST_INCLUDE_MAIN +#include + +//Put test class in the global namespace +#include "./swap_test_class.hpp" + +//Provide swap function in gloabl namespace +void swap(swap_test_class& left, swap_test_class& right) +{ + left.swap(right); +} + +int test_main(int, char*[]) +{ + const swap_test_class initial_value1(1); + const swap_test_class initial_value2(2); + + swap_test_class object1 = initial_value1; + swap_test_class object2 = initial_value2; + + swap_test_class::reset(); + boost::swap(object1,object2); + + BOOST_CHECK(object1 == initial_value2); + BOOST_CHECK(object2 == initial_value1); + + BOOST_CHECK_EQUAL(swap_test_class::swap_count(),1); + BOOST_CHECK_EQUAL(swap_test_class::copy_count(),0); + + return 0; +} + diff --git a/swap/test/specialized_in_other.cpp b/swap/test/specialized_in_other.cpp new file mode 100644 index 0000000..a39896f --- /dev/null +++ b/swap/test/specialized_in_other.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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 +#define BOOST_INCLUDE_MAIN +#include + +//Put test class in namespace other +namespace other +{ + #include "./swap_test_class.hpp" +} + +//Provide swap function in namespace other +namespace other +{ + void swap(swap_test_class& left, swap_test_class& right) + { + left.swap(right); + } +} + +int test_main(int, char*[]) +{ + const other::swap_test_class initial_value1(1); + const other::swap_test_class initial_value2(2); + + other::swap_test_class object1 = initial_value1; + other::swap_test_class object2 = initial_value2; + + other::swap_test_class::reset(); + boost::swap(object1,object2); + + BOOST_CHECK(object1 == initial_value2); + BOOST_CHECK(object2 == initial_value1); + + BOOST_CHECK_EQUAL(other::swap_test_class::swap_count(),1); + BOOST_CHECK_EQUAL(other::swap_test_class::copy_count(),0); + + return 0; +} + diff --git a/swap/test/specialized_in_std.cpp b/swap/test/specialized_in_std.cpp new file mode 100644 index 0000000..e31e850 --- /dev/null +++ b/swap/test/specialized_in_std.cpp @@ -0,0 +1,44 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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 +#define BOOST_INCLUDE_MAIN +#include + +//Put test class in the global namespace +#include "./swap_test_class.hpp" + + +//Provide swap function in namespace std +namespace std +{ + template <> + void swap(swap_test_class& left, swap_test_class& right) + { + left.swap(right); + } +} + +int test_main(int, char*[]) +{ + const swap_test_class initial_value1(1); + const swap_test_class initial_value2(2); + + swap_test_class object1 = initial_value1; + swap_test_class object2 = initial_value2; + + swap_test_class::reset(); + boost::swap(object1,object2); + + BOOST_CHECK(object1 == initial_value2); + BOOST_CHECK(object2 == initial_value1); + + BOOST_CHECK_EQUAL(swap_test_class::swap_count(),1); + BOOST_CHECK_EQUAL(swap_test_class::copy_count(),0); + + return 0; +} + diff --git a/swap/test/std_bitset.cpp b/swap/test/std_bitset.cpp new file mode 100644 index 0000000..4b9fbae --- /dev/null +++ b/swap/test/std_bitset.cpp @@ -0,0 +1,33 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +// Tests swapping std::bitset objects by means of boost::swap. +// Unlike most other Standard C++ Library template classes, +// std::bitset does not have its own std::swap overload. + +#include +#define BOOST_INCLUDE_MAIN +#include + +#include + +int test_main(int, char*[]) +{ + typedef std::bitset<8> bitset_type; + const bitset_type initial_value1 = 1ul; + const bitset_type initial_value2 = 2ul; + + bitset_type object1 = initial_value1; + bitset_type object2 = initial_value2; + + boost::swap(object1,object2); + + BOOST_CHECK_EQUAL(object1,initial_value2); + BOOST_CHECK_EQUAL(object2,initial_value1); + + return 0; +} + diff --git a/swap/test/std_dateorder.cpp b/swap/test/std_dateorder.cpp new file mode 100644 index 0000000..b593f6f --- /dev/null +++ b/swap/test/std_dateorder.cpp @@ -0,0 +1,32 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +// Tests swapping std::time_base::dateorder objects by means of boost::swap. +// std::time_base::dateorder is an enumerated type. It does not have an +// std::swap overload or template specialization. + +#include +#define BOOST_INCLUDE_MAIN +#include + +#include + +int test_main(int, char*[]) +{ + const std::time_base::dateorder initial_value1 = std::time_base::dmy; + const std::time_base::dateorder initial_value2 = std::time_base::mdy; + + std::time_base::dateorder object1 = initial_value1; + std::time_base::dateorder object2 = initial_value2; + + boost::swap(object1,object2); + + BOOST_CHECK_EQUAL(object1,initial_value2); + BOOST_CHECK_EQUAL(object2,initial_value1); + + return 0; +} + diff --git a/swap/test/std_string.cpp b/swap/test/std_string.cpp new file mode 100644 index 0000000..b7d3d4d --- /dev/null +++ b/swap/test/std_string.cpp @@ -0,0 +1,31 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +// Tests swapping std::string objects by means of boost::swap. +// std::string has its own std::swap overload. + +#include +#define BOOST_INCLUDE_MAIN +#include + +#include + +int test_main(int, char*[]) +{ + const std::string initial_value1 = "one"; + const std::string initial_value2 = "two"; + + std::string object1 = initial_value1; + std::string object2 = initial_value2; + + boost::swap(object1,object2); + + BOOST_CHECK_EQUAL(object1,initial_value2); + BOOST_CHECK_EQUAL(object2,initial_value1); + + return 0; +} + diff --git a/swap/test/std_typeinfo_ptr.cpp b/swap/test/std_typeinfo_ptr.cpp new file mode 100644 index 0000000..38e293a --- /dev/null +++ b/swap/test/std_typeinfo_ptr.cpp @@ -0,0 +1,32 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +// Tests swapping std::type_info pointers by means of boost::swap. +// There is no std::swap overload or template specialization +// for std::type_info pointers. + +#include +#define BOOST_INCLUDE_MAIN +#include + +#include + +int test_main(int, char*[]) +{ + const std::type_info * const initial_value1 = 0; + const std::type_info * const initial_value2 = &typeid(double); + + const std::type_info * ptr1 = initial_value1; + const std::type_info * ptr2 = initial_value2; + + boost::swap(ptr1,ptr2); + + BOOST_CHECK_EQUAL(ptr1,initial_value2); + BOOST_CHECK_EQUAL(ptr2,initial_value1); + + return 0; +} + diff --git a/swap/test/std_vector_of_boost.cpp b/swap/test/std_vector_of_boost.cpp new file mode 100644 index 0000000..b0c6355 --- /dev/null +++ b/swap/test/std_vector_of_boost.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +// Tests swapping std::vector objects by means of boost::swap, +// having boost::swap_test_class as vector element type. + +#include +#define BOOST_INCLUDE_MAIN +#include + +#include + +//Put test class in namespace boost +namespace boost +{ + #include "./swap_test_class.hpp" +} + +//Provide swap function in namespace boost +namespace boost +{ + void swap(swap_test_class& left, swap_test_class& right) + { + left.swap(right); + } +} + +int test_main(int, char*[]) +{ + typedef boost::swap_test_class swap_test_class_type; + typedef std::vector vector_type; + + const vector_type::size_type initial_size1 = 1; + const vector_type::size_type initial_size2 = 2; + + const vector_type initial_value1(initial_size1, swap_test_class_type(1)); + const vector_type initial_value2(initial_size2, swap_test_class_type(2)); + + vector_type object1 = initial_value1; + vector_type object2 = initial_value2; + + swap_test_class_type::reset(); + + boost::swap(object1,object2); + + BOOST_CHECK_EQUAL(object1.size(),initial_size2); + BOOST_CHECK_EQUAL(object2.size(),initial_size1); + + BOOST_CHECK(object1 == initial_value2); + BOOST_CHECK(object2 == initial_value1); + + BOOST_CHECK_EQUAL(swap_test_class_type::swap_count(),0); + BOOST_CHECK_EQUAL(swap_test_class_type::copy_count(),0); + + return 0; +} + diff --git a/swap/test/std_vector_of_global.cpp b/swap/test/std_vector_of_global.cpp new file mode 100644 index 0000000..96a9b6a --- /dev/null +++ b/swap/test/std_vector_of_global.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +// Tests swapping std::vector objects by means of boost::swap, +// having ::swap_test_class as vector element type. + +#include +#define BOOST_INCLUDE_MAIN +#include + +#include + +//Put test class in the global namespace +#include "./swap_test_class.hpp" + +//Provide swap function in the global namespace +void swap(swap_test_class& left, swap_test_class& right) +{ + left.swap(right); +} + +int test_main(int, char*[]) +{ + typedef std::vector vector_type; + + const vector_type::size_type initial_size1 = 1; + const vector_type::size_type initial_size2 = 2; + + const vector_type initial_value1(initial_size1, swap_test_class(1)); + const vector_type initial_value2(initial_size2, swap_test_class(2)); + + vector_type object1 = initial_value1; + vector_type object2 = initial_value2; + + swap_test_class::reset(); + + boost::swap(object1,object2); + + BOOST_CHECK_EQUAL(object1.size(),initial_size2); + BOOST_CHECK_EQUAL(object2.size(),initial_size1); + + BOOST_CHECK(object1 == initial_value2); + BOOST_CHECK(object2 == initial_value1); + + BOOST_CHECK_EQUAL(swap_test_class::swap_count(),0); + BOOST_CHECK_EQUAL(swap_test_class::copy_count(),0); + + return 0; +} + diff --git a/swap/test/std_vector_of_other.cpp b/swap/test/std_vector_of_other.cpp new file mode 100644 index 0000000..2176f6e --- /dev/null +++ b/swap/test/std_vector_of_other.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +// Tests swapping std::vector objects by means of boost::swap, +// having other::swap_test_class as vector element type. + +#include +#define BOOST_INCLUDE_MAIN +#include + +#include + +//Put test class in namespace other +namespace other +{ + #include "./swap_test_class.hpp" +} + +//Provide swap function in namespace other +namespace other +{ + void swap(swap_test_class& left, swap_test_class& right) + { + left.swap(right); + } +} + +int test_main(int, char*[]) +{ + typedef other::swap_test_class swap_test_class_type; + typedef std::vector vector_type; + + const vector_type::size_type initial_size1 = 1; + const vector_type::size_type initial_size2 = 2; + + const vector_type initial_value1(initial_size1, swap_test_class_type(1)); + const vector_type initial_value2(initial_size2, swap_test_class_type(2)); + + vector_type object1 = initial_value1; + vector_type object2 = initial_value2; + + swap_test_class_type::reset(); + + boost::swap(object1,object2); + + BOOST_CHECK_EQUAL(object1.size(),initial_size2); + BOOST_CHECK_EQUAL(object2.size(),initial_size1); + + BOOST_CHECK(object1 == initial_value2); + BOOST_CHECK(object2 == initial_value1); + + BOOST_CHECK_EQUAL(swap_test_class_type::swap_count(),0); + BOOST_CHECK_EQUAL(swap_test_class_type::copy_count(),0); + + return 0; +} + diff --git a/swap/test/swap_arrays.cpp b/swap/test/swap_arrays.cpp new file mode 100644 index 0000000..eeb64bc --- /dev/null +++ b/swap/test/swap_arrays.cpp @@ -0,0 +1,100 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +#include +#define BOOST_INCLUDE_MAIN +#include + +//Put test class in the global namespace +#include "./swap_test_class.hpp" + +#include //for std::copy and std::equal +#include //for std::size_t + +//Provide swap function in both the namespace of swap_test_class +//(which is the global namespace), and the std namespace. +//It's common to provide a swap function for a class in both +//namespaces. Scott Meyers recommends doing so: Effective C++, +//Third Edition, item 25, "Consider support for a non-throwing swap". +void swap(swap_test_class& left, swap_test_class& right) +{ + left.swap(right); +} + +namespace std +{ + template <> + void swap(swap_test_class& left, swap_test_class& right) + { + left.swap(right); + } +} + +// Tests swapping 1-dimensional arrays. +void test_swapping_1D_arrays() +{ + const std::size_t dimension = 2; + const swap_test_class initial_array1[dimension] = { swap_test_class(1), swap_test_class(2) }; + const swap_test_class initial_array2[dimension] = { swap_test_class(3), swap_test_class(4) }; + + swap_test_class array1[dimension]; + swap_test_class array2[dimension]; + + std::copy(initial_array1, initial_array1 + dimension, array1); + std::copy(initial_array2, initial_array2 + dimension, array2); + + swap_test_class::reset(); + boost::swap(array1, array2); + + BOOST_CHECK(std::equal(array1, array1 + dimension, initial_array2)); + BOOST_CHECK(std::equal(array2, array2 + dimension, initial_array1)); + + BOOST_CHECK_EQUAL(swap_test_class::swap_count(), dimension); + BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0); +} + + +// Tests swapping 2-dimensional arrays. +void test_swapping_2D_arrays() +{ + const std::size_t first_dimension = 3; + const std::size_t second_dimension = 4; + const std::size_t number_of_elements = first_dimension * second_dimension; + + swap_test_class array1[first_dimension][second_dimension]; + swap_test_class array2[first_dimension][second_dimension]; + + swap_test_class* const ptr1 = array1[0]; + swap_test_class* const ptr2 = array2[0]; + + for (std::size_t i = 0; i < number_of_elements; ++i) + { + ptr1[i].set_data( static_cast(i) ); + ptr2[i].set_data( static_cast(i + number_of_elements) ); + } + + swap_test_class::reset(); + boost::swap(array1, array2); + + for (std::size_t i = 0; i < number_of_elements; ++i) + { + BOOST_CHECK_EQUAL(ptr1[i].get_data(), static_cast(i + number_of_elements) ); + BOOST_CHECK_EQUAL(ptr2[i].get_data(), static_cast(i) ); + } + + BOOST_CHECK_EQUAL(swap_test_class::swap_count(), number_of_elements); + BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0); +} + + +int test_main(int, char*[]) +{ + test_swapping_1D_arrays(); + test_swapping_2D_arrays(); + + return 0; +} + diff --git a/swap/test/swap_test_class.hpp b/swap/test/swap_test_class.hpp new file mode 100644 index 0000000..8cf1fe9 --- /dev/null +++ b/swap/test/swap_test_class.hpp @@ -0,0 +1,114 @@ +// Copyright (c) 2007-2008 Joseph Gauterin +// +// 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) + +// Tests class used by the Boost.Swap tests + +#ifndef BOOST_UTILITY_SWAP_TEST_CLASS_HPP +#define BOOST_UTILITY_SWAP_TEST_CLASS_HPP + + +class swap_test_class +{ + int m_data; +public: + explicit swap_test_class(int arg = 0) + : + m_data(arg) + { + ++constructCount(); + } + + ~swap_test_class() + { + ++destructCount(); + } + + swap_test_class(const swap_test_class& arg) + : + m_data(arg.m_data) + { + ++copyCount(); + ++destructCount(); + } + + swap_test_class& operator=(const swap_test_class& arg) + { + m_data = arg.m_data; + ++copyCount(); + return *this; + } + + void swap(swap_test_class& other) + { + const int temp = m_data; + m_data = other.m_data; + other.m_data = temp; + + ++swapCount(); + } + + int get_data() const + { + return m_data; + } + + void set_data(int arg) + { + m_data = arg; + } + + static unsigned int swap_count(){ return swapCount(); } + static unsigned int copy_count(){ return copyCount(); } + static unsigned int construct_count(){ return constructCount(); } + static unsigned int destruct_count(){ return destructCount(); } + + static void reset() + { + swapCount() = 0; + copyCount() = 0; + constructCount() = 0; + destructCount() = 0; + } + +private: + static unsigned int& swapCount() + { + static unsigned int value = 0; + return value; + } + + static unsigned int& copyCount() + { + static unsigned int value = 0; + return value; + } + + static unsigned int& constructCount() + { + static unsigned int value = 0; + return value; + } + + static unsigned int& destructCount() + { + static unsigned int value = 0; + return value; + } + +}; + + +inline bool operator==(const swap_test_class & lhs, const swap_test_class & rhs) +{ + return lhs.get_data() == rhs.get_data(); +} + +inline bool operator!=(const swap_test_class & lhs, const swap_test_class & rhs) +{ + return !(lhs == rhs); +} + +#endif From b012f16ee5ac34154d938174dba1ac74c9c6aa31 Mon Sep 17 00:00:00 2001 From: Joseph Gauterin Date: Sat, 15 Nov 2008 01:15:54 +0000 Subject: [PATCH 037/126] Merged utility/swap documentation to release branch. [SVN r49763] --- swap.html | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 swap.html diff --git a/swap.html b/swap.html new file mode 100644 index 0000000..01afd7c --- /dev/null +++ b/swap.html @@ -0,0 +1,94 @@ + + + + + + Boost: Swap Documentation + + + + C++ Boost +

    Swap

    + +

    + template<class T> void swap(T& left, T& right); +

    + + +

    + The template function boost::swap allows the values of two variables to be swapped, using argument dependent lookup to select a specialized swap function if available. If no specialized swap function is available, std::swap is used. +

    + + +

    Rationale

    +

    + The generic std::swap function requires that the elements to be swapped are assignable and copy constructible. It is usually implemented using one copy construction and two assignments - this is often both unnecessarily restrictive and unnecessarily slow. In addition, where the generic swap implementation provides only the basic guarantee, specialized swap functions are often able to provide the no-throw exception guarantee (and it is considered best practice to do so where possible1).

    +

    + The alternative to using argument dependent lookup in this situation is to provide a template specialization of std::swap for every type that requires a specialized swap. Although this is legal C++, no Boost libraries use this method, whereas many Boost libraries provide specialized swap functions in their own namespaces. +

    +

    + boost::swap also supports swapping built-in arrays. Note that std::swap doesn't yet do so, but a request to add an overload of std::swap for built-in arrays has been well-received by the Library Working Group of the C++ Standards Committee2. +

    + + +

    Exception Safety

    +

    + boost::swap provides the same exception guarantee as the underlying swap function used, with one exception; for an array of type T[n], where n > 1 and the underlying swap function for T provides the strong exception guarantee, boost::swap provides only the basic exception guarantee. +

    + + +

    Requirements

    +

    Either:

    +
      +
    • T must be assignable
    • +
    • T must be copy constructible
    • +
    +

    Or:

    +
      +
    • A function with the signature swap(T&,T&) is available via argument dependent lookup
    • +
    +

    Or:

    +
      +
    • A template specialization of std::swap exists for T
    • +
    +

    Or:

    +
      +
    • T is a built-in array of swappable elements
    • +
    + + + +

    Portability

    +

    + Several older compilers do not support argument dependent lookup ‒ on these compilers boost::swap will call std::swap, ignoring any specialized swap functions that could be found as a result of argument dependent lookup. +

    + + +

    Credits

    +
      +
    • + Niels Dekker - for implementing and documenting support for built-in arrays +
    • +
    • + Joseph Gauterin - for the initial idea, implementation, tests, and documentation +
    • +
    • + Steven Watanabe - for the idea to make boost::swap less specialized than std::swap, thereby allowing the function to have the name 'swap' without introducing ambiguity +
    • +
    + + +
    +

    [1]Scott Meyers, Effective C++ Third Edition, Item 25: "Consider support for a non-throwing swap"

    +

    [2]LWG issue 809 (std::swap should be overloaded for array types)

    + + +
    +

    Revised: 21 October 2008

    +

    + Copyright 2007, 2008 Joseph Gauterin. 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>.) +

    + + + From 862cb2a4e0d1c2e5f0fb5fa10fbec786627b35f3 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Thu, 20 Nov 2008 22:53:20 +0000 Subject: [PATCH 038/126] Merged revisions 49661-49662,49666,49669,49735,49756,49770,49811 via svnmerge from https://svn.boost.org/svn/boost/trunk ........ r49661 | danieljames | 2008-11-09 12:03:45 +0000 (Sun, 09 Nov 2008) | 1 line Move hash detail headers out of boost/functional/detail. ........ r49662 | danieljames | 2008-11-09 12:11:50 +0000 (Sun, 09 Nov 2008) | 1 line Add a forwarding header for container_fwd.hpp ........ r49666 | danieljames | 2008-11-09 19:12:05 +0000 (Sun, 09 Nov 2008) | 1 line Avoid comparing default initialised iterators in position_iterator. ........ r49669 | danieljames | 2008-11-09 21:57:38 +0000 (Sun, 09 Nov 2008) | 2 lines Add link to the header to the synopsis in reference documentation. Refs #2214 ........ r49735 | danieljames | 2008-11-14 12:51:00 +0000 (Fri, 14 Nov 2008) | 1 line Explicitly specify the template parameters in the unordered container friend, in order to avoid some warnings. ........ r49756 | danieljames | 2008-11-14 16:11:16 +0000 (Fri, 14 Nov 2008) | 1 line Use pragmas to suppress a Visual C++ warning. ........ r49770 | danieljames | 2008-11-15 13:07:29 +0000 (Sat, 15 Nov 2008) | 1 line Use the new swap library. ........ r49811 | danieljames | 2008-11-16 23:10:00 +0000 (Sun, 16 Nov 2008) | 1 line Fix a typo. ........ [SVN r49855] --- in_place_factories.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/in_place_factories.html b/in_place_factories.html index b36387d..d3791f8 100644 --- a/in_place_factories.html +++ b/in_place_factories.html @@ -99,7 +99,7 @@ directly to the container:

    Framework

    This library proposes a framework to allow some containers to directly contruct contained objects in-place without requiring -the entire set of constructor overloads ftom the contained type. It also allows the container to remove the CopyConstuctible +the entire set of constructor overloads from the contained type. It also allows the container to remove the CopyConstuctible requirement from the contained type since objects can be directly constructed in-place without need of a copy.
    The only requirement on the container is that it must provide proper storage (that is, correctly aligned and sized). Naturally, the container will typically support uninitialized storage to avoid the in-place construction to override @@ -293,4 +293,4 @@ the latest version of this file can be found at www.boost.org, and the boost discussion lists

    - \ No newline at end of file + From 633832e872a05b02e018f598f5d42bffe7941139 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Mon, 24 Nov 2008 16:50:22 +0000 Subject: [PATCH 039/126] Merged libs/utility/swap.html from trunk to release (r47094 through r49914) [SVN r49915] --- swap.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/swap.html b/swap.html index 01afd7c..4022e0b 100644 --- a/swap.html +++ b/swap.html @@ -14,7 +14,7 @@ template<class T> void swap(T& left, T& right);

    - +

    The template function boost::swap allows the values of two variables to be swapped, using argument dependent lookup to select a specialized swap function if available. If no specialized swap function is available, std::swap is used.

    @@ -24,10 +24,10 @@

    The generic std::swap function requires that the elements to be swapped are assignable and copy constructible. It is usually implemented using one copy construction and two assignments - this is often both unnecessarily restrictive and unnecessarily slow. In addition, where the generic swap implementation provides only the basic guarantee, specialized swap functions are often able to provide the no-throw exception guarantee (and it is considered best practice to do so where possible1).

    - The alternative to using argument dependent lookup in this situation is to provide a template specialization of std::swap for every type that requires a specialized swap. Although this is legal C++, no Boost libraries use this method, whereas many Boost libraries provide specialized swap functions in their own namespaces. + The alternative to using argument dependent lookup in this situation is to provide a template specialization of std::swap for every type that requires a specialized swap. Although this is legal C++, no Boost libraries use this method, whereas many Boost libraries provide specialized swap functions in their own namespaces.

    - boost::swap also supports swapping built-in arrays. Note that std::swap doesn't yet do so, but a request to add an overload of std::swap for built-in arrays has been well-received by the Library Working Group of the C++ Standards Committee2. + boost::swap also supports swapping built-in arrays. Note that std::swap originally did not do so, but a request to add an overload of std::swap for built-in arrays has been accepted by the C++ Standards Committee2.

    @@ -45,11 +45,11 @@

    Or:

      -
    • A function with the signature swap(T&,T&) is available via argument dependent lookup
    • +
    • A function with the signature swap(T&,T&) is available via argument dependent lookup

    Or:

      -
    • A template specialization of std::swap exists for T
    • +
    • A template specialization of std::swap exists for T

    Or:

      @@ -73,18 +73,18 @@ Joseph Gauterin - for the initial idea, implementation, tests, and documentation
    • - Steven Watanabe - for the idea to make boost::swap less specialized than std::swap, thereby allowing the function to have the name 'swap' without introducing ambiguity + Steven Watanabe - for the idea to make boost::swap less specialized than std::swap, thereby allowing the function to have the name 'swap' without introducing ambiguity

    [1]Scott Meyers, Effective C++ Third Edition, Item 25: "Consider support for a non-throwing swap"

    -

    [2]LWG issue 809 (std::swap should be overloaded for array types)

    +

    [2]LWG Defect Report 809 (std::swap should be overloaded for array types)


    -

    Revised: 21 October 2008

    +

    Revised: 15 November 2008

    Copyright 2007, 2008 Joseph Gauterin. 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>.) From 9e73b2c6aebf08fd6b61c39236813ab60ad1cc51 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Thu, 27 Nov 2008 19:37:39 +0000 Subject: [PATCH 040/126] Merged value_initialized::swap from trunk [48424] and [48425], according to ticket #2243, as was agreed with Fernando Cacciola. [SVN r49967] --- include/boost/utility/value_init.hpp | 13 +++++++++ value_init.htm | 12 +++++--- value_init_test.cpp | 43 +++++++++++++++++++++++++++- 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/include/boost/utility/value_init.hpp b/include/boost/utility/value_init.hpp index 67127c0..aa7ecb4 100644 --- a/include/boost/utility/value_init.hpp +++ b/include/boost/utility/value_init.hpp @@ -7,6 +7,7 @@ // 21 Ago 2002 (Created) Fernando Cacciola // 24 Dec 2007 (Refactored and worked around various compiler bugs) Fernando Cacciola, Niels Dekker // 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola +// 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola // #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP @@ -22,6 +23,7 @@ #include #include #include +#include #include #include @@ -93,6 +95,11 @@ class value_initialized return wrapper_address()->data; } + void swap(value_initialized & arg) + { + ::boost::swap( this->data(), arg.data() ); + } + operator T&() const { return this->data(); } } ; @@ -110,6 +117,12 @@ T& get ( value_initialized& x ) return x.data() ; } +template +void swap ( value_initialized & lhs, value_initialized & rhs ) +{ + lhs.swap(rhs) ; +} + class initialized_value_t { diff --git a/value_init.htm b/value_init.htm index 531814e..5c1b20e 100644 --- a/value_init.htm +++ b/value_init.htm @@ -253,7 +253,7 @@ its internal data, prior to constructing the object that it contains.

    template class value_initialized<T>

    -
    namespace boost {

    template<class T>
    class value_initialized
    {
    public :
    value_initialized() : x() {}
    operator T&() const { return x ; }
    T& data() const { return x ; }

    private :
    unspecified x ;
    } ;

    template<class T>
    T const& get ( value_initialized<T> const& x )
    {
    return x.data() ;
    }

    template<class T>
    T& get ( value_initialized<T>& x )
    {
    return x.data() ;
    }

    } // namespace boost
    +
    namespace boost {

    template<class T>
    class value_initialized
    {
    public :
    value_initialized() : x() {}
    operator T&() const { return x ; }
    T& data() const { return x ; }
    void swap( value_initialized<T>& );

    private :
    unspecified x ;
    } ;

    template<class T>
    T const& get ( value_initialized<T> const& x )
    {
    return x.data() ;
    }

    template<class T>
    T& get ( value_initialized<T>& x )
    {
    return x.data() ;
    }

    } // namespace boost

    An object of this template class is a T-wrapper convertible to 'T&' whose wrapped object (data member of type T) @@ -276,6 +276,10 @@ non-member function get():

    Both const and non-const objects can be wrapped. Mutable objects can be modified directly from within the wrapper but constant objects cannot:

    + +

    When T is a Swappable type, value_initialized<T> + is swappable as well, by calling its swap member function + as well as by calling boost::swap.

    value_initialized<int> x ; 
    static_cast<int&>(x) = 1 ; // OK
    get(x) = 1 ; // OK

    value_initialized<int const> y ;
    static_cast<int&>(y) = 1 ; // ERROR: cannot cast to int&
    static_cast<int const&>(y) = 1 ; // ERROR: cannot modify a const value
    get(y) = 1 ; // ERROR: cannot modify a const value
    @@ -311,7 +315,7 @@ wrapped object from within a constant wrapper can be avoided if access to the wrapped object is always performed with the get() idiom:

    value_initialized<int> x ;
    get(x) = 1 ; // OK

    value_initialized<int const> cx ;
    get(x) = 1 ; // ERROR: Cannot modify a const object

    value_initialized<int> const x_c ;
    get(x_c) = 1 ; // ERROR: Cannot modify a const object

    value_initialized<int const> const cx_c ;
    get(cx_c) = 1 ; // ERROR: Cannot modify a const object
    - +

    initialized_value

    @@ -379,7 +383,7 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
          


    -

    Revised 23 May 2008

    +

    Revised 28 August 2008

    © Copyright Fernando Cacciola, 2002, 2008.

    @@ -390,4 +394,4 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
    - + \ No newline at end of file diff --git a/value_init_test.cpp b/value_init_test.cpp index 7191156..63f324d 100644 --- a/value_init_test.cpp +++ b/value_init_test.cpp @@ -9,6 +9,7 @@ // 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 // For memcmp. #include @@ -181,6 +182,35 @@ struct CopyFunctionCallTester }; +// +// 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 void check_initialized_value ( T const& y ) { @@ -196,7 +226,7 @@ void check_initialized_value( NonPOD const& ) // 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) @@ -323,9 +353,20 @@ int test_main(int, char **) BOOST_CHECK ( ! get(copyFunctionCallTester3).is_copy_constructed); BOOST_CHECK ( get(copyFunctionCallTester3).is_assignment_called); + boost::value_initialized swapFunctionCallTester1; + boost::value_initialized swapFunctionCallTester2; + get(swapFunctionCallTester1).data = 1; + get(swapFunctionCallTester2).data = 2; + boost::swap(swapFunctionCallTester1, swapFunctionCallTester2); + BOOST_CHECK( get(swapFunctionCallTester1).data == 2 ); + BOOST_CHECK( get(swapFunctionCallTester2).data == 1 ); + BOOST_CHECK( get(swapFunctionCallTester1).is_custom_swap_called ); + BOOST_CHECK( get(swapFunctionCallTester2).is_custom_swap_called ); + return 0; } unsigned int expected_failures = 0; + From ffbbf38e12feceeb2d2dc1e7d5d9ed2c8cecee6a Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Tue, 9 Dec 2008 18:21:25 +0000 Subject: [PATCH 041/126] Merged new array-of-array tests of swap utility from trunk to release branch, following changeset [49954]. [SVN r50227] --- swap/test/Jamfile.v2 | 6 +- ...arrays.cpp => array_of_array_of_class.cpp} | 37 +--------- swap/test/array_of_array_of_int.cpp | 42 +++++++++++ swap/test/array_of_class.cpp | 61 ++++++++++++++++ swap/test/array_of_int.cpp | 35 +++++++++ swap/test/array_of_template.cpp | 71 +++++++++++++++++++ 6 files changed, 217 insertions(+), 35 deletions(-) rename swap/test/{swap_arrays.cpp => array_of_array_of_class.cpp} (66%) create mode 100644 swap/test/array_of_array_of_int.cpp create mode 100644 swap/test/array_of_class.cpp create mode 100644 swap/test/array_of_int.cpp create mode 100644 swap/test/array_of_template.cpp diff --git a/swap/test/Jamfile.v2 b/swap/test/Jamfile.v2 index 7071837..f5b0d46 100644 --- a/swap/test/Jamfile.v2 +++ b/swap/test/Jamfile.v2 @@ -29,5 +29,9 @@ test-suite utility/swap [ run std_vector_of_global.cpp ../../../test/build//boost_test_exec_monitor/static ] [ run std_vector_of_other.cpp ../../../test/build//boost_test_exec_monitor/static ] [ run no_ambiguity_in_boost.cpp ../../../test/build//boost_test_exec_monitor/static ] - [ run swap_arrays.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run array_of_array_of_class.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run array_of_array_of_int.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run array_of_class.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run array_of_int.cpp ../../../test/build//boost_test_exec_monitor/static ] + [ run array_of_template.cpp ../../../test/build//boost_test_exec_monitor/static ] ; diff --git a/swap/test/swap_arrays.cpp b/swap/test/array_of_array_of_class.cpp similarity index 66% rename from swap/test/swap_arrays.cpp rename to swap/test/array_of_array_of_class.cpp index eeb64bc..4f02578 100644 --- a/swap/test/swap_arrays.cpp +++ b/swap/test/array_of_array_of_class.cpp @@ -4,6 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +// Tests swapping an array of arrays of swap_test_class objects by means of boost::swap. + #include #define BOOST_INCLUDE_MAIN #include @@ -33,32 +35,8 @@ namespace std } } -// Tests swapping 1-dimensional arrays. -void test_swapping_1D_arrays() -{ - const std::size_t dimension = 2; - const swap_test_class initial_array1[dimension] = { swap_test_class(1), swap_test_class(2) }; - const swap_test_class initial_array2[dimension] = { swap_test_class(3), swap_test_class(4) }; - - swap_test_class array1[dimension]; - swap_test_class array2[dimension]; - std::copy(initial_array1, initial_array1 + dimension, array1); - std::copy(initial_array2, initial_array2 + dimension, array2); - - swap_test_class::reset(); - boost::swap(array1, array2); - - BOOST_CHECK(std::equal(array1, array1 + dimension, initial_array2)); - BOOST_CHECK(std::equal(array2, array2 + dimension, initial_array1)); - - BOOST_CHECK_EQUAL(swap_test_class::swap_count(), dimension); - BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0); -} - - -// Tests swapping 2-dimensional arrays. -void test_swapping_2D_arrays() +int test_main(int, char*[]) { const std::size_t first_dimension = 3; const std::size_t second_dimension = 4; @@ -76,7 +54,6 @@ void test_swapping_2D_arrays() ptr2[i].set_data( static_cast(i + number_of_elements) ); } - swap_test_class::reset(); boost::swap(array1, array2); for (std::size_t i = 0; i < number_of_elements; ++i) @@ -87,14 +64,6 @@ void test_swapping_2D_arrays() BOOST_CHECK_EQUAL(swap_test_class::swap_count(), number_of_elements); BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0); -} - - -int test_main(int, char*[]) -{ - test_swapping_1D_arrays(); - test_swapping_2D_arrays(); return 0; } - diff --git a/swap/test/array_of_array_of_int.cpp b/swap/test/array_of_array_of_int.cpp new file mode 100644 index 0000000..c1778ec --- /dev/null +++ b/swap/test/array_of_array_of_int.cpp @@ -0,0 +1,42 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +// Tests swapping an array of arrays of integers by means of boost::swap. + +#include +#define BOOST_INCLUDE_MAIN +#include + +#include //for std::copy and std::equal +#include //for std::size_t + +int test_main(int, char*[]) +{ + const std::size_t first_dimension = 3; + const std::size_t second_dimension = 4; + const std::size_t number_of_elements = first_dimension * second_dimension; + + int array1[first_dimension][second_dimension]; + int array2[first_dimension][second_dimension]; + + int* const ptr1 = array1[0]; + int* const ptr2 = array2[0]; + + for (std::size_t i = 0; i < number_of_elements; ++i) + { + ptr1[i] = static_cast(i); + ptr2[i] = static_cast(i + number_of_elements); + } + + boost::swap(array1, array2); + + for (std::size_t i = 0; i < number_of_elements; ++i) + { + BOOST_CHECK_EQUAL(ptr1[i], static_cast(i + number_of_elements) ); + BOOST_CHECK_EQUAL(ptr2[i], static_cast(i) ); + } + return 0; +} diff --git a/swap/test/array_of_class.cpp b/swap/test/array_of_class.cpp new file mode 100644 index 0000000..356762d --- /dev/null +++ b/swap/test/array_of_class.cpp @@ -0,0 +1,61 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +// Tests swapping an array of arrays of swap_test_class objects by means of boost::swap. + +#include +#define BOOST_INCLUDE_MAIN +#include + +//Put test class in the global namespace +#include "./swap_test_class.hpp" + +#include //for std::copy and std::equal +#include //for std::size_t + +//Provide swap function in both the namespace of swap_test_class +//(which is the global namespace), and the std namespace. +//It's common to provide a swap function for a class in both +//namespaces. Scott Meyers recommends doing so: Effective C++, +//Third Edition, item 25, "Consider support for a non-throwing swap". +void swap(swap_test_class& left, swap_test_class& right) +{ + left.swap(right); +} + +namespace std +{ + template <> + void swap(swap_test_class& left, swap_test_class& right) + { + left.swap(right); + } +} + + +int test_main(int, char*[]) +{ + const std::size_t array_size = 2; + const swap_test_class initial_array1[array_size] = { swap_test_class(1), swap_test_class(2) }; + const swap_test_class initial_array2[array_size] = { swap_test_class(3), swap_test_class(4) }; + + swap_test_class array1[array_size]; + swap_test_class array2[array_size]; + + std::copy(initial_array1, initial_array1 + array_size, array1); + std::copy(initial_array2, initial_array2 + array_size, array2); + + swap_test_class::reset(); + boost::swap(array1, array2); + + BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2)); + BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1)); + + BOOST_CHECK_EQUAL(swap_test_class::swap_count(), array_size); + BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0); + + return 0; +} diff --git a/swap/test/array_of_int.cpp b/swap/test/array_of_int.cpp new file mode 100644 index 0000000..22a7dde --- /dev/null +++ b/swap/test/array_of_int.cpp @@ -0,0 +1,35 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +// Tests swapping an array of integers by means of boost::swap. + +#include +#define BOOST_INCLUDE_MAIN +#include + +#include //for std::copy and std::equal +#include //for std::size_t + + +int test_main(int, char*[]) +{ + const std::size_t array_size = 3; + const int initial_array1[array_size] = { 1, 2, 3 }; + const int initial_array2[array_size] = { 4, 5, 6 }; + + int array1[array_size]; + int array2[array_size]; + + std::copy(initial_array1, initial_array1 + array_size, array1); + std::copy(initial_array2, initial_array2 + array_size, array2); + + boost::swap(array1, array2); + + BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2)); + BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1)); + + return 0; +} diff --git a/swap/test/array_of_template.cpp b/swap/test/array_of_template.cpp new file mode 100644 index 0000000..8f350ad --- /dev/null +++ b/swap/test/array_of_template.cpp @@ -0,0 +1,71 @@ +// Copyright (c) 2008 Joseph Gauterin, 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) + +// Tests swapping an array of swap_test_template objects by means of boost::swap. + +#include +#define BOOST_INCLUDE_MAIN +#include + +//Put test class in the global namespace +#include "./swap_test_class.hpp" + +#include //for std::copy and std::equal +#include //for std::size_t + +template +class swap_test_template +{ +public: + typedef T template_argument; + swap_test_class swap_test_object; +}; + +template +inline bool operator==(const swap_test_template & lhs, const swap_test_template & rhs) +{ + return lhs.swap_test_object == rhs.swap_test_object; +} + +template +inline bool operator!=(const swap_test_template & lhs, const swap_test_template & rhs) +{ + return !(lhs == rhs); +} + +//Provide swap function in the namespace of swap_test_template +//(which is the global namespace). Note that it isn't allowed to put +//an overload of this function within the std namespace. +template +void swap(swap_test_template& left, swap_test_template& right) +{ + left.swap_test_object.swap(right.swap_test_object); +} + + +int test_main(int, char*[]) +{ + const std::size_t array_size = 2; + const swap_test_template initial_array1[array_size] = { swap_test_class(1), swap_test_class(2) }; + const swap_test_template initial_array2[array_size] = { swap_test_class(3), swap_test_class(4) }; + + swap_test_template array1[array_size]; + swap_test_template array2[array_size]; + + std::copy(initial_array1, initial_array1 + array_size, array1); + std::copy(initial_array2, initial_array2 + array_size, array2); + + swap_test_class::reset(); + boost::swap(array1, array2); + + BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2)); + BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1)); + + BOOST_CHECK_EQUAL(swap_test_class::swap_count(), array_size); + BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0); + + return 0; +} From 390372294a130aa96ea026747abf6f357fb2c1ef Mon Sep 17 00:00:00 2001 From: "Troy D. Straszheim" Date: Sat, 24 Jan 2009 18:57:20 +0000 Subject: [PATCH 042/126] merge of cmake build files from trunk per beman [SVN r50756] --- CMakeLists.txt | 31 +++++++++++++++++++++++++++++++ module.cmake | 1 + test/CMakeLists.txt | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 module.cmake create mode 100644 test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6df7714 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,31 @@ +#---------------------------------------------------------------------------- +# This file was automatically generated from the original CMakeLists.txt file +# Add a variable to hold the headers for the library +set (lib_headers + assert.hpp + call_traits.hpp + checked_delete.hpp + compressed_pair.hpp + current_function.hpp + operators.hpp + throw_exception.hpp + utility.hpp + utility +) + +# Add a library target to the build system +boost_library_project( + utility + # SRCDIRS + TESTDIRS test + HEADERS ${lib_headers} + # DOCDIRS + DESCRIPTION "Various small utilities for C++ programming." + MODULARIZED + AUTHORS "David Abrahams " + "Brad King" + "Douglas Gregor " + # MAINTAINERS +) + + diff --git a/module.cmake b/module.cmake new file mode 100644 index 0000000..4d78340 --- /dev/null +++ b/module.cmake @@ -0,0 +1 @@ +boost_module(utility DEPENDS iterator exception detail ) \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..fee1ccb --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,38 @@ +boost_additional_test_dependencies(utility BOOST_DEPENDS test) + +boost_test_run(addressof_test ../addressof_test.cpp) +boost_test_run(assert_test ../assert_test.cpp) +boost_test_run(base_from_member_test ../base_from_member_test.cpp) +boost_test_run(binary_search_test ../binary_search_test.cpp) +boost_test_run(call_traits_test ../call_traits_test.cpp ARGS -u) +boost_test_compile_fail(checked_delete_test ../checked_delete_test.cpp) +boost_test_run(compressed_pair_test + ../compressed_pair_test + DEPENDS boost_test_exec_monitor) +boost_test_run(current_function_test ../current_function_test.cpp) +boost_test_run(iterators_test + ../iterators_test.cpp + DEPENDS boost_test_exec_monitor) +boost_test_run(next_prior_test DEPENDS boost_test_exec_monitor) +boost_test_compile_fail(noncopyable_test ../noncopyable_test.cpp) +boost_test_run(numeric_traits_test ../numeric_traits_test.cpp) +if (${CMAKE_SYSTEM} MATCHES "FreeBSD-.*") +boost_test_compile_fail("operators_test_compilerbug") +elseif(${CMAKE_SYSTEM} MATCHES "FreeBSD-.*") +boost_test_run(operators_test + ../operators_test.cpp + DEPENDS boost_test_exec_monitor) +endif(${CMAKE_SYSTEM} MATCHES "FreeBSD-.*") +boost_test_compile(ref_ct_test ../ref_ct_test.cpp) +boost_test_run(ref_test + ../ref_test.cpp + DEPENDS boost_test_exec_monitor) +boost_test_compile(result_of_test) +boost_test_run(shared_iterator_test ../shared_iterator_test.cpp) +boost_test_run(value_init_test ../value_init_test.cpp) +boost_test_compile_fail(value_init_test_fail1 + ../value_init_test_fail1.cpp) +boost_test_compile_fail(value_init_test_fail2 + ../value_init_test_fail2.cpp) +boost_test_compile_fail(value_init_test_fail3 + ../value_init_test_fail3.cpp) From b2e6a82adbde078a5a38170db7775a325bfd7743 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Thu, 29 Jan 2009 19:14:05 +0000 Subject: [PATCH 043/126] This html was outdated; changed to forward to throw_exception.html documentation from Boost Exception [SVN r50880] --- throw_exception.html | 69 +++++++++----------------------------------- 1 file changed, 13 insertions(+), 56 deletions(-) diff --git a/throw_exception.html b/throw_exception.html index 66a63f3..141f487 100644 --- a/throw_exception.html +++ b/throw_exception.html @@ -1,58 +1,15 @@ - + - - Boost: throw_exception.hpp documentation - - - - - - - - - - - -
    boost.png (6897 bytes) - -

    throw_exception.hpp

    -
     
    -

    - The header <boost/throw_exception.hpp> defines the - helper function boost::throw_exception. It is intended to be - used in Boost libraries that need to throw exceptions, but support - configurations and platforms where exceptions aren't available, as indicated by - the presence of the BOOST_NO_EXCEPTIONS - configuration macro. -

    -

    When BOOST_NO_EXCEPTIONS is not defined, boost::throw_exception(e) - is equivalent to throw e. Otherwise, the function is left undefined, - and the user is expected to supply an appropriate definition. Callers of throw_exception - are allowed to assume that the function never returns; therefore, if the - user-defined throw_exception returns, the behavior is undefined.

    -

    Synopsis

    -
    -namespace boost
    -{
    -
    -#ifdef BOOST_NO_EXCEPTIONS
    -
    -void throw_exception(std::exception const & e); // user defined
    -
    -#else
    -
    -template<class E> void throw_exception(E const & e)
    -{
    -    throw e;
    -}
    -
    -#endif
    -
    -}
    -
    -


    - Copyright © 2002 by Peter Dimov. Distributed under the Boost Software License, Version - 1.0. See accompanying file LICENSE_1_0.txt or - copy at http://www.boost.org/LICENSE_1_0.txt.

    - + + +Automatic redirection + + +Automatic redirection failed, please go to +throw_exception.html
    +

    © Copyright Beman Dawes, 2001

    +

    Distributed under the Boost Software License, Version 1.0. (See accompanying +file LICENSE_1_0.txt or copy +at www.boost.org/LICENSE_1_0.txt)

    + From b7cd171b2bbd8f423080be04c09dab2914fed576 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 2 Mar 2009 16:32:03 +0000 Subject: [PATCH 044/126] Merge [51512] to release. Closes #2128. [SVN r51534] --- include/boost/ref.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/boost/ref.hpp b/include/boost/ref.hpp index 330ca65..0d747bd 100644 --- a/include/boost/ref.hpp +++ b/include/boost/ref.hpp @@ -173,6 +173,11 @@ class unwrap_reference # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template inline T* get_pointer( reference_wrapper const & r ) +{ + return r.get_pointer(); +} + } // namespace boost #endif // #ifndef BOOST_REF_HPP_INCLUDED From e3640e45c2b76910d59da2ef024660fb02fedfdb Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 22 Mar 2009 20:05:02 +0000 Subject: [PATCH 045/126] Merge [51872], [51891] to release. Closes #2878. [SVN r51907] --- addressof_fn_test.cpp | 76 +++++++++++++++++++++++ addressof_test2.cpp | 95 +++++++++++++++++++++++++++++ include/boost/utility/addressof.hpp | 16 +++++ test/Jamfile.v2 | 2 + 4 files changed, 189 insertions(+) create mode 100644 addressof_fn_test.cpp create mode 100644 addressof_test2.cpp diff --git a/addressof_fn_test.cpp b/addressof_fn_test.cpp new file mode 100644 index 0000000..0d043bf --- /dev/null +++ b/addressof_fn_test.cpp @@ -0,0 +1,76 @@ +#include + +#if defined(BOOST_MSVC) +#pragma warning(disable: 4786) // identifier truncated in debug info +#pragma warning(disable: 4710) // function not inlined +#pragma warning(disable: 4711) // function selected for automatic inline expansion +#pragma warning(disable: 4514) // unreferenced inline removed +#endif + +// addressof_fn_test.cpp: addressof( f ) +// +// Copyright (c) 2008, 2009 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include + + +void f0() +{ +} + +void f1(int) +{ +} + +void f2(int, int) +{ +} + +void f3(int, int, int) +{ +} + +void f4(int, int, int, int) +{ +} + +void f5(int, int, int, int, int) +{ +} + +void f6(int, int, int, int, int, int) +{ +} + +void f7(int, int, int, int, int, int, int) +{ +} + +void f8(int, int, int, int, int, int, int, int) +{ +} + +void f9(int, int, int, int, int, int, int, int, int) +{ +} + +int main() +{ + BOOST_TEST( boost::addressof( f0 ) == &f0 ); + BOOST_TEST( boost::addressof( f1 ) == &f1 ); + BOOST_TEST( boost::addressof( f2 ) == &f2 ); + BOOST_TEST( boost::addressof( f3 ) == &f3 ); + BOOST_TEST( boost::addressof( f4 ) == &f4 ); + BOOST_TEST( boost::addressof( f5 ) == &f5 ); + BOOST_TEST( boost::addressof( f6 ) == &f6 ); + BOOST_TEST( boost::addressof( f7 ) == &f7 ); + BOOST_TEST( boost::addressof( f8 ) == &f8 ); + BOOST_TEST( boost::addressof( f9 ) == &f9 ); + + return boost::report_errors(); +} diff --git a/addressof_test2.cpp b/addressof_test2.cpp new file mode 100644 index 0000000..b1c36f8 --- /dev/null +++ b/addressof_test2.cpp @@ -0,0 +1,95 @@ +// Copyright (C) 2002 Brad King (brad.king@kitware.com) +// Douglas Gregor (gregod@cs.rpi.edu) +// +// Copyright 2009 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + + +#include + +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) +#pragma warning(push, 3) +#endif + +#include + +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) +#pragma warning(pop) +#endif + +#include + +template void scalar_test( T * = 0 ) +{ + T* px = new T(); + + T& x = *px; + BOOST_TEST( boost::addressof(x) == px ); + + const T& cx = *px; + const T* pcx = boost::addressof(cx); + BOOST_TEST( pcx == px ); + + volatile T& vx = *px; + volatile T* pvx = boost::addressof(vx); + BOOST_TEST( pvx == px ); + + const volatile T& cvx = *px; + const volatile T* pcvx = boost::addressof(cvx); + BOOST_TEST( pcvx == px ); + + delete px; +} + +template void array_test( T * = 0 ) +{ + T nrg[3] = {1,2,3}; + T (*pnrg)[3] = &nrg; + BOOST_TEST( boost::addressof(nrg) == pnrg ); + + T const cnrg[3] = {1,2,3}; + T const (*pcnrg)[3] = &cnrg; + BOOST_TEST( boost::addressof(cnrg) == pcnrg ); +} + +class convertible { +public: + + convertible( int = 0 ) + { + } + + template operator U () const + { + return U(); + } +}; + +class convertible2 { +public: + + convertible2( int = 0 ) + { + } + + operator convertible2* () const + { + return 0; + } +}; + +int main() +{ + scalar_test(); + scalar_test(); + + array_test(); + array_test(); + + return boost::report_errors(); +} diff --git a/include/boost/utility/addressof.hpp b/include/boost/utility/addressof.hpp index 8e0a586..48602be 100644 --- a/include/boost/utility/addressof.hpp +++ b/include/boost/utility/addressof.hpp @@ -21,6 +21,14 @@ namespace boost namespace detail { +template struct addr_impl_ref +{ + T & v_; + + inline addr_impl_ref( T & v ): v_( v ) {} + inline operator T& () const { return v_; } +}; + template struct addressof_impl { static inline T * f( T & v, long ) @@ -39,7 +47,15 @@ template struct addressof_impl template T * addressof( T & v ) { +#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) ) + return boost::detail::addressof_impl::f( v, 0 ); + +#else + + return boost::detail::addressof_impl::f( boost::detail::addr_impl_ref( v ), 0 ); + +#endif } // Borland doesn't like casting an array reference to a char reference diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 321060c..3111cad 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -11,7 +11,9 @@ import testing ; # Please keep the tests ordered by filename test-suite utility : + [ run ../addressof_fn_test.cpp ] [ run ../addressof_test.cpp ] + [ run ../addressof_test2.cpp ] [ run ../assert_test.cpp ] [ run ../base_from_member_test.cpp ] [ run ../binary_search_test.cpp ] From a69e872a91f18cd8a000eda61ded54b5c46c1f03 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 28 Mar 2009 20:53:26 +0000 Subject: [PATCH 046/126] Merge [51977], [51986], [52010] to release. [SVN r52040] --- include/boost/utility/addressof.hpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/include/boost/utility/addressof.hpp b/include/boost/utility/addressof.hpp index 48602be..ac42a51 100644 --- a/include/boost/utility/addressof.hpp +++ b/include/boost/utility/addressof.hpp @@ -47,7 +47,7 @@ template struct addressof_impl template T * addressof( T & v ) { -#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) ) +#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) ) return boost::detail::addressof_impl::f( v, 0 ); @@ -58,9 +58,29 @@ template T * addressof( T & v ) #endif } +#if defined( __SUNPRO_CC ) && BOOST_WORKAROUND( __SUNPRO_CC, BOOST_TESTED_AT( 0x590 ) ) + +namespace detail +{ + +template struct addressof_addp +{ + typedef T * type; +}; + +} // namespace detail + +template< class T, std::size_t N > +typename detail::addressof_addp< T[N] >::type addressof( T (&t)[N] ) +{ + return &t; +} + +#endif + // Borland doesn't like casting an array reference to a char reference // but these overloads work around the problem. -# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +#if defined( __BORLANDC__ ) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) template T (*addressof(T (&t)[N]))[N] { @@ -72,7 +92,7 @@ const T (*addressof(const T (&t)[N]))[N] { return reinterpret_cast(&t); } -# endif +#endif } // namespace boost From ce67dde4f058a379ac7fd6520aea3cf1a3b11a6d Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Tue, 31 Mar 2009 22:16:49 +0000 Subject: [PATCH 047/126] Documentation update [SVN r52091] --- include/boost/exception.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/boost/exception.hpp b/include/boost/exception.hpp index c77f215..b4716a0 100644 --- a/include/boost/exception.hpp +++ b/include/boost/exception.hpp @@ -12,6 +12,8 @@ #include #include #include +#ifndef BOOST_NO_EXCEPTIONS #include +#endif #endif From 76aa5d2f271b491d033a007fa8d9a2716fe81af9 Mon Sep 17 00:00:00 2001 From: "Troy D. Straszheim" Date: Thu, 14 May 2009 19:58:42 +0000 Subject: [PATCH 048/126] more cmakefile tweaks [SVN r52999] --- test/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fee1ccb..4236efd 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,8 @@ boost_additional_test_dependencies(utility BOOST_DEPENDS test) +boost_test_run(addressof_fn_test ../addressof_fn_test.cpp) boost_test_run(addressof_test ../addressof_test.cpp) +boost_test_run(addressof_test2 ../addressof_test2.cpp) boost_test_run(assert_test ../assert_test.cpp) boost_test_run(base_from_member_test ../base_from_member_test.cpp) boost_test_run(binary_search_test ../binary_search_test.cpp) @@ -36,3 +38,4 @@ boost_test_compile_fail(value_init_test_fail2 ../value_init_test_fail2.cpp) boost_test_compile_fail(value_init_test_fail3 ../value_init_test_fail3.cpp) +boost_test_run(verify_test ../verify_test.cpp) \ No newline at end of file From 48cfd421232f542ee70734c1d8e3139a193b6164 Mon Sep 17 00:00:00 2001 From: "Troy D. Straszheim" Date: Thu, 14 May 2009 23:56:22 +0000 Subject: [PATCH 049/126] tune up ptr_container, utility tests in cmakeland [SVN r53007] --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6df7714..df4998a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ set (lib_headers boost_library_project( utility # SRCDIRS - TESTDIRS test + TESTDIRS test swap/test HEADERS ${lib_headers} # DOCDIRS DESCRIPTION "Various small utilities for C++ programming." From eaaf17a88fd26ba8f3b4486cf0008f99975d90b6 Mon Sep 17 00:00:00 2001 From: "Troy D. Straszheim" Date: Fri, 15 May 2009 00:21:14 +0000 Subject: [PATCH 050/126] tuning up cmakefiles for unordered, utility [SVN r53008] --- CMakeLists.txt | 2 +- enable_if/test/CMakeLists.txt | 14 ++++++++++++++ swap/test/CMakeLists.txt | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 enable_if/test/CMakeLists.txt create mode 100644 swap/test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index df4998a..ea7c9d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ set (lib_headers boost_library_project( utility # SRCDIRS - TESTDIRS test swap/test + TESTDIRS test swap/test enable_if/test HEADERS ${lib_headers} # DOCDIRS DESCRIPTION "Various small utilities for C++ programming." diff --git a/enable_if/test/CMakeLists.txt b/enable_if/test/CMakeLists.txt new file mode 100644 index 0000000..a6e1a4f --- /dev/null +++ b/enable_if/test/CMakeLists.txt @@ -0,0 +1,14 @@ +foreach(T + constructors + dummy_arg_disambiguation + lazy + lazy_test + member_templates + namespace_disambiguation + no_disambiguation + partial_specializations + ) + boost_test_run(${T} DEPENDS boost_test_exec_monitor) +endforeach() + + diff --git a/swap/test/CMakeLists.txt b/swap/test/CMakeLists.txt new file mode 100644 index 0000000..1570d83 --- /dev/null +++ b/swap/test/CMakeLists.txt @@ -0,0 +1,35 @@ + +foreach(T + root_header_1 root_header_2 + lib_header_1 lib_header_2 + mixed_headers_1 mixed_headers_2) + boost_test_compile(${T}) +endforeach() + + +# [ run primitive.cpp ../../../test/build//boost_test_exec_monitor/static ] + + +foreach(T + primitive + specialized_in_boost + specialized_in_global + specialized_in_other + specialized_in_std + specialized_in_boost_and_other + std_bitset + std_dateorder + std_string + std_typeinfo_ptr + std_vector_of_boost + std_vector_of_global + std_vector_of_other + no_ambiguity_in_boost + array_of_array_of_class + array_of_array_of_int + array_of_class + array_of_int + array_of_template) + boost_test_run(${T} DEPENDS boost_test_exec_monitor) +endforeach() + From 51f9adbfa1f4863caea798e19049b2cb4ab773d9 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Sat, 16 May 2009 18:15:17 +0000 Subject: [PATCH 051/126] Merged revisions 52837 via svnmerge from https://svn.boost.org/svn/boost/trunk ........ r52837 | eric_niebler | 2009-05-07 10:47:08 -0700 (Thu, 07 May 2009) | 1 line eliminate noisy warning on msvc ........ [SVN r53054] --- include/boost/utility/addressof.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/boost/utility/addressof.hpp b/include/boost/utility/addressof.hpp index ac42a51..95cd92f 100644 --- a/include/boost/utility/addressof.hpp +++ b/include/boost/utility/addressof.hpp @@ -27,6 +27,9 @@ template struct addr_impl_ref inline addr_impl_ref( T & v ): v_( v ) {} inline operator T& () const { return v_; } + +private: + addr_impl_ref & operator=(const addr_impl_ref &); }; template struct addressof_impl From e57213b29868c83e02e8756fd09ab121c386754a Mon Sep 17 00:00:00 2001 From: Jeremiah Willcock Date: Wed, 20 May 2009 19:41:20 +0000 Subject: [PATCH 052/126] Fixed almost all tab and min/max issues found by inspect tool [SVN r53142] --- include/boost/utility/result_of.hpp | 4 ++-- swap/test/std_bitset.cpp | 2 +- swap/test/swap_test_class.hpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp index cdcac34..e35e098 100644 --- a/include/boost/utility/result_of.hpp +++ b/include/boost/utility/result_of.hpp @@ -70,8 +70,8 @@ struct result_of_nested_result : F::template result template struct result_of_impl : mpl::if_, - result_of_void_impl, - result_of_nested_result >::type + result_of_void_impl, + result_of_nested_result >::type {}; } // end namespace detail diff --git a/swap/test/std_bitset.cpp b/swap/test/std_bitset.cpp index 4b9fbae..d8d69e7 100644 --- a/swap/test/std_bitset.cpp +++ b/swap/test/std_bitset.cpp @@ -19,7 +19,7 @@ int test_main(int, char*[]) typedef std::bitset<8> bitset_type; const bitset_type initial_value1 = 1ul; const bitset_type initial_value2 = 2ul; - + bitset_type object1 = initial_value1; bitset_type object2 = initial_value2; diff --git a/swap/test/swap_test_class.hpp b/swap/test/swap_test_class.hpp index 8cf1fe9..a25dbbd 100644 --- a/swap/test/swap_test_class.hpp +++ b/swap/test/swap_test_class.hpp @@ -12,7 +12,7 @@ class swap_test_class { - int m_data; + int m_data; public: explicit swap_test_class(int arg = 0) : From 211eb04f3376d7d0b62ac6560acb976a569d2b68 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Fri, 22 May 2009 09:00:11 +0000 Subject: [PATCH 053/126] Merge [44151], [48025] to release. Closes #3064. [SVN r53172] --- include/boost/operators.hpp | 69 ++++-- operators.htm | 38 ++-- operators_test.cpp | 408 ++++++++++++++++++++---------------- 3 files changed, 300 insertions(+), 215 deletions(-) diff --git a/include/boost/operators.hpp b/include/boost/operators.hpp index b3b1bd7..4b47ba4 100644 --- a/include/boost/operators.hpp +++ b/include/boost/operators.hpp @@ -8,6 +8,9 @@ // See http://www.boost.org/libs/utility/operators.htm for documentation. // Revision History +// 07 Aug 08 Added "euclidean" spelling. (Daniel Frey) +// 03 Apr 08 Make sure "convertible to bool" is sufficient +// for T::operator<, etc. (Daniel Frey) // 24 May 07 Changed empty_base to depend on T, see // http://svn.boost.org/trac/boost/ticket/979 // 21 Oct 02 Modified implementation of operators to allow compilers with a @@ -124,34 +127,34 @@ namespace boost template > struct less_than_comparable2 : B { - friend bool operator<=(const T& x, const U& y) { return !(x > y); } - friend bool operator>=(const T& x, const U& y) { return !(x < y); } + friend bool operator<=(const T& x, const U& y) { return !static_cast(x > y); } + friend bool operator>=(const T& x, const U& y) { return !static_cast(x < y); } friend bool operator>(const U& x, const T& y) { return y < x; } friend bool operator<(const U& x, const T& y) { return y > x; } - friend bool operator<=(const U& x, const T& y) { return !(y < x); } - friend bool operator>=(const U& x, const T& y) { return !(y > x); } + friend bool operator<=(const U& x, const T& y) { return !static_cast(y < x); } + friend bool operator>=(const U& x, const T& y) { return !static_cast(y > x); } }; template > struct less_than_comparable1 : B { friend bool operator>(const T& x, const T& y) { return y < x; } - friend bool operator<=(const T& x, const T& y) { return !(y < x); } - friend bool operator>=(const T& x, const T& y) { return !(x < y); } + friend bool operator<=(const T& x, const T& y) { return !static_cast(y < x); } + friend bool operator>=(const T& x, const T& y) { return !static_cast(x < y); } }; template > struct equality_comparable2 : B { friend bool operator==(const U& y, const T& x) { return x == y; } - friend bool operator!=(const U& y, const T& x) { return !(x == y); } - friend bool operator!=(const T& y, const U& x) { return !(y == x); } + friend bool operator!=(const U& y, const T& x) { return !static_cast(x == y); } + friend bool operator!=(const T& y, const U& x) { return !static_cast(y == x); } }; template > struct equality_comparable1 : B { - friend bool operator!=(const T& x, const T& y) { return !(x == y); } + friend bool operator!=(const T& x, const T& y) { return !static_cast(x == y); } }; // A macro which produces "name_2left" from "name". @@ -356,7 +359,7 @@ struct equivalent2 : B { friend bool operator==(const T& x, const U& y) { - return !(x < y) && !(x > y); + return !static_cast(x < y) && !static_cast(x > y); } }; @@ -365,7 +368,7 @@ struct equivalent1 : B { friend bool operator==(const T&x, const T&y) { - return !(x < y) && !(y < x); + return !static_cast(x < y) && !static_cast(y < x); } }; @@ -373,17 +376,17 @@ template > struct partially_ordered2 : B { friend bool operator<=(const T& x, const U& y) - { return (x < y) || (x == y); } + { return static_cast(x < y) || static_cast(x == y); } friend bool operator>=(const T& x, const U& y) - { return (x > y) || (x == y); } + { return static_cast(x > y) || static_cast(x == y); } friend bool operator>(const U& x, const T& y) { return y < x; } friend bool operator<(const U& x, const T& y) { return y > x; } friend bool operator<=(const U& x, const T& y) - { return (y > x) || (y == x); } + { return static_cast(y > x) || static_cast(y == x); } friend bool operator>=(const U& x, const T& y) - { return (y < x) || (y == x); } + { return static_cast(y < x) || static_cast(y == x); } }; template > @@ -392,9 +395,9 @@ struct partially_ordered1 : B friend bool operator>(const T& x, const T& y) { return y < x; } friend bool operator<=(const T& x, const T& y) - { return (x < y) || (x == y); } + { return static_cast(x < y) || static_cast(x == y); } friend bool operator>=(const T& x, const T& y) - { return (y < x) || (x == y); } + { return static_cast(y < x) || static_cast(x == y); } }; // Combined operator classes (contributed by Daryle Walker) ----------------// @@ -580,7 +583,35 @@ struct ordered_euclidian_ring_operators1 : totally_ordered1 > {}; - + +template > +struct euclidean_ring_operators2 + : ring_operators2 > > > > {}; + +template > +struct euclidean_ring_operators1 + : ring_operators1 > > {}; + +template > +struct ordered_euclidean_ring_operators2 + : totally_ordered2 > {}; + +template > +struct ordered_euclidean_ring_operators1 + : totally_ordered1 > {}; + template > struct input_iteratable : equality_comparable1 euclidian_ring_operators<T>
    + "euclidean_ring_operators1">euclidean_ring_operators<T>
    - euclidian_ring_operators1<T> + euclidean_ring_operators1<T>
      @@ -1439,9 +1439,9 @@ T operator+( T lhs, const T& rhs ) euclidian_ring_operators<T, + "euclidean_ring_operators2">euclidean_ring_operators<T, U>
      - euclidian_ring_operators2<T, U> + euclidean_ring_operators2<T, U>
        @@ -1464,14 +1464,14 @@ T operator+( T lhs, const T& rhs ) ordered_euclidian_ring_operators<T>
        + "ordered_euclidean_ring_operators1">ordered_euclidean_ring_operators<T>
        - ordered_euclidian_ring_operators1<T> + ordered_euclidean_ring_operators1<T>
        • euclidian_ring_operators<T>
        • + "#euclidean_ring_operators1">euclidean_ring_operators<T>
        • totally_ordered<T>
        • @@ -1481,14 +1481,14 @@ T operator+( T lhs, const T& rhs ) ordered_euclidian_ring_operators<T, + "ordered_euclidean_ring_operators2">ordered_euclidean_ring_operators<T, U>
          - ordered_euclidian_ring_operators2<T, U> + ordered_euclidean_ring_operators2<T, U>
          • euclidian_ring_operators<T, + "#euclidean_ring_operators2">euclidean_ring_operators<T, U>
          • totally_ordered<T, @@ -1498,6 +1498,15 @@ T operator+( T lhs, const T& rhs ) +

            Spelling: euclidean vs. euclidian

            + +

            Older versions of the Boost.Operators library used + "euclidian", but it was pointed out that + "euclidean" is the more common spelling. + To be compatible with older version, the library now supports + both spellings. +

            +

            Example Templates

            The arithmetic operator class templates The operators_test.cpp program demonstrates the use of the arithmetic operator templates, and - can also be used to verify correct operation. Check the compiler status report for the - test results with selected platforms.

            + can also be used to verify correct operation. Check the compiler status + report for the test results with selected platforms.

            Dereference Operators and Iterator Helpers

            @@ -2119,10 +2127,10 @@ public: backward-compatible.


            -

            Revised: 29 Oct 2004

            +

            Revised: 7 Aug 2008

            Copyright © Beman Dawes, David Abrahams, 1999-2001.

            -

            Copyright © Daniel Frey, 2002-2004.

            +

            Copyright © Daniel Frey, 2002-2008.

            Use, modification, and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/operators_test.cpp b/operators_test.cpp index d42cb6a..5b71f3a 100644 --- a/operators_test.cpp +++ b/operators_test.cpp @@ -7,6 +7,7 @@ // 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 @@ -43,6 +44,23 @@ namespace unsigned char true_value(unsigned char x) { return x; } unsigned short true_value(unsigned short 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 @@ -54,8 +72,10 @@ namespace explicit Wrapped1( T v = T() ) : _value(v) {} T value() const { return _value; } - bool operator<(const Wrapped1& x) const { return _value < x._value; } - bool operator==(const Wrapped1& x) const { return _value == x._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; } @@ -97,8 +117,10 @@ namespace explicit Wrapped2( T v = T() ) : _value(v) {} T value() const { return _value; } - bool operator<(const Wrapped2& x) const { return _value < x._value; } - bool operator==(const Wrapped2& x) const { return _value == x._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; } @@ -123,9 +145,13 @@ namespace Wrapped2& operator++() { ++_value; return *this; } Wrapped2& operator--() { --_value; return *this; } - bool operator<(U u) const { return _value < u; } - bool operator>(U u) const { return _value > u; } - 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; } + 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; } @@ -153,7 +179,8 @@ namespace explicit Wrapped3( T v = T() ) : _value(v) {} T value() const { return _value; } - bool operator<(const Wrapped3& x) const { return _value < x._value; } + convertible_to_bool operator<(const Wrapped3& x) const + { return _value < x._value; } private: T _value; @@ -174,10 +201,13 @@ namespace explicit Wrapped4( T v = T() ) : _value(v) {} T value() const { return _value; } - bool operator<(const Wrapped4& x) const { return _value < x._value; } + convertible_to_bool operator<(const Wrapped4& x) const + { return _value < x._value; } - bool operator<(U u) const { return _value < u; } - 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; } private: T _value; @@ -198,11 +228,18 @@ namespace Wrapped5(U u) : _value(u) {} T value() const { return _value; } - bool operator<(const Wrapped5& x) const { return _value < x._value; } - bool operator<(U u) const { return _value < u; } - bool operator>(U u) const { return _value > u; } - bool operator==(const Wrapped5& u) const { return _value == u._value; } - bool operator==(U u) const { return _value == u; } + + 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;} @@ -221,8 +258,8 @@ namespace // U must be convertible to T template class Wrapped6 - : boost::ordered_euclidian_ring_operators2, U> - , boost::ordered_euclidian_ring_operators1 > + : boost::ordered_euclidean_ring_operators2, U> + , boost::ordered_euclidean_ring_operators1 > { public: explicit Wrapped6( T v = T() ) : _value(v) {} @@ -231,11 +268,18 @@ namespace Wrapped6(U u) : _value(u) {} T value() const { return _value; } - bool operator<(const Wrapped6& x) const { return _value < x._value; } - bool operator<(U u) const { return _value < u; } - bool operator>(U u) const { return _value > u; } - bool operator==(const Wrapped6& u) const { return _value == u._value; } - bool operator==(U u) const { return _value == u; } + + 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;} @@ -276,10 +320,10 @@ namespace template void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) { - BOOST_CHECK( (x1 < y1) == (x2 < y2) ); - BOOST_CHECK( (x1 <= y1) == (x2 <= y2) ); - BOOST_CHECK( (x1 >= y1) == (x2 >= y2) ); - BOOST_CHECK( (x1 > y1) == (x2 > y2) ); + BOOST_CHECK( static_cast(x1 < y1) == static_cast(x2 < y2) ); + BOOST_CHECK( static_cast(x1 <= y1) == static_cast(x2 <= y2) ); + BOOST_CHECK( static_cast(x1 >= y1) == static_cast(x2 >= y2) ); + BOOST_CHECK( static_cast(x1 > y1) == static_cast(x2 > y2) ); } template @@ -293,8 +337,8 @@ namespace template void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) { - BOOST_CHECK( (x1 == y1) == (x2 == y2) ); - BOOST_CHECK( (x1 != y1) == (x2 != y2) ); + BOOST_CHECK( static_cast(x1 == y1) == static_cast(x2 == y2) ); + BOOST_CHECK( static_cast(x1 != y1) == static_cast(x2 != y2) ); } template @@ -614,14 +658,14 @@ test_main( int , char * [] ) PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) ); - BOOST_CHECK( i2 == i ); - BOOST_CHECK( i1 != i2 ); - BOOST_CHECK( i1 < i2 ); - BOOST_CHECK( i1 <= i2 ); - BOOST_CHECK( i <= i2 ); - BOOST_CHECK( i2 > i1 ); - BOOST_CHECK( i2 >= i1 ); - BOOST_CHECK( i2 >= i ); + BOOST_CHECK( static_cast(i2 == i) ); + BOOST_CHECK( static_cast(i1 != i2) ); + BOOST_CHECK( static_cast(i1 < i2) ); + BOOST_CHECK( static_cast(i1 <= i2) ); + BOOST_CHECK( static_cast(i <= i2) ); + BOOST_CHECK( static_cast(i2 > i1) ); + BOOST_CHECK( static_cast(i2 >= i1) ); + BOOST_CHECK( static_cast(i2 >= i) ); PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) ); PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) ); @@ -653,78 +697,78 @@ test_main( int , char * [] ) PRIVATE_EXPR_TEST( (j = j2), (j.value() == 2) ); - BOOST_CHECK( j2 == j ); - BOOST_CHECK( 2 == j ); - BOOST_CHECK( j2 == 2 ); - BOOST_CHECK( j == j2 ); - BOOST_CHECK( j1 != j2 ); - BOOST_CHECK( j1 != 2 ); - BOOST_CHECK( 1 != j2 ); - BOOST_CHECK( j1 < j2 ); - BOOST_CHECK( 1 < j2 ); - BOOST_CHECK( j1 < 2 ); - BOOST_CHECK( j1 <= j2 ); - BOOST_CHECK( 1 <= j2 ); - BOOST_CHECK( j1 <= j ); - BOOST_CHECK( j <= j2 ); - BOOST_CHECK( 2 <= j2 ); - BOOST_CHECK( j <= 2 ); - BOOST_CHECK( j2 > j1 ); - BOOST_CHECK( 2 > j1 ); - BOOST_CHECK( j2 > 1 ); - BOOST_CHECK( j2 >= j1 ); - BOOST_CHECK( 2 >= j1 ); - BOOST_CHECK( j2 >= 1 ); - BOOST_CHECK( j2 >= j ); - BOOST_CHECK( 2 >= j ); - BOOST_CHECK( j2 >= 2 ); + BOOST_CHECK( static_cast(j2 == j) ); + BOOST_CHECK( static_cast(2 == j) ); + BOOST_CHECK( static_cast(j2 == 2) ); + BOOST_CHECK( static_cast(j == j2) ); + BOOST_CHECK( static_cast(j1 != j2) ); + BOOST_CHECK( static_cast(j1 != 2) ); + BOOST_CHECK( static_cast(1 != j2) ); + BOOST_CHECK( static_cast(j1 < j2) ); + BOOST_CHECK( static_cast(1 < j2) ); + BOOST_CHECK( static_cast(j1 < 2) ); + BOOST_CHECK( static_cast(j1 <= j2) ); + BOOST_CHECK( static_cast(1 <= j2) ); + BOOST_CHECK( static_cast(j1 <= j) ); + BOOST_CHECK( static_cast(j <= j2) ); + BOOST_CHECK( static_cast(2 <= j2) ); + BOOST_CHECK( static_cast(j <= 2) ); + BOOST_CHECK( static_cast(j2 > j1) ); + BOOST_CHECK( static_cast(2 > j1) ); + BOOST_CHECK( static_cast(j2 > 1) ); + BOOST_CHECK( static_cast(j2 >= j1) ); + BOOST_CHECK( static_cast(2 >= j1) ); + BOOST_CHECK( static_cast(j2 >= 1) ); + BOOST_CHECK( static_cast(j2 >= j) ); + BOOST_CHECK( static_cast(2 >= j) ); + BOOST_CHECK( static_cast(j2 >= 2) ); - BOOST_CHECK( (j1 + 2) == 3 ); - BOOST_CHECK( (1 + j2) == 3 ); + BOOST_CHECK( static_cast((j1 + 2) == 3) ); + BOOST_CHECK( static_cast((1 + j2) == 3) ); PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) ); - BOOST_CHECK( (j + 2) == 5 ); - BOOST_CHECK( (3 + j2) == 5 ); + BOOST_CHECK( static_cast((j + 2) == 5) ); + BOOST_CHECK( static_cast((3 + j2) == 5) ); PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) ); - BOOST_CHECK( (j - 1) == 4 ); + BOOST_CHECK( static_cast((j - 1) == 4) ); PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) ); - BOOST_CHECK( (j * 2) == 8 ); - BOOST_CHECK( (4 * j2) == 8 ); + BOOST_CHECK( static_cast((j * 2) == 8) ); + BOOST_CHECK( static_cast((4 * j2) == 8) ); PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) ); - BOOST_CHECK( (j / 2) == 4 ); + BOOST_CHECK( static_cast((j / 2) == 4) ); PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) ); - BOOST_CHECK( (j % 3) == 1 ); + BOOST_CHECK( static_cast((j % 3) == 1) ); PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) ); PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) ); - BOOST_CHECK( (1 | j2 | j) == 7 ); - BOOST_CHECK( (j1 | 2 | j) == 7 ); - BOOST_CHECK( (j1 | j2 | 4) == 7 ); + BOOST_CHECK( static_cast((1 | j2 | j) == 7) ); + BOOST_CHECK( static_cast((j1 | 2 | j) == 7) ); + BOOST_CHECK( static_cast((j1 | j2 | 4) == 7) ); PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) ); - BOOST_CHECK( (7 & j2) == 2 ); - BOOST_CHECK( (j & 2) == 2 ); + BOOST_CHECK( static_cast((7 & j2) == 2) ); + BOOST_CHECK( static_cast((j & 2) == 2) ); PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) ); PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) ); - BOOST_CHECK( (3 ^ j1) == 2 ); - BOOST_CHECK( (j ^ 1) == 2 ); + BOOST_CHECK( static_cast((3 ^ j1) == 2) ); + BOOST_CHECK( static_cast((j ^ 1) == 2) ); PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) ); PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) ); - BOOST_CHECK( (j1 << 2) == 4 ); - BOOST_CHECK( (j2 << 1) == 4 ); + BOOST_CHECK( static_cast((j1 << 2) == 4) ); + BOOST_CHECK( static_cast((j2 << 1) == 4) ); PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) ); - BOOST_CHECK( (j >> 2) == 1 ); - BOOST_CHECK( (j2 >> 1) == 1 ); + BOOST_CHECK( static_cast((j >> 2) == 1) ); + BOOST_CHECK( static_cast((j2 >> 1) == 1) ); PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) ); cout << "Performed tests on MyLong objects.\n"; @@ -741,14 +785,14 @@ test_main( int , char * [] ) PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) ); - BOOST_CHECK( k2 == k ); - BOOST_CHECK( k1 != k2 ); - BOOST_CHECK( k1 < k2 ); - BOOST_CHECK( k1 <= k2 ); - BOOST_CHECK( k <= k2 ); - BOOST_CHECK( k2 > k1 ); - BOOST_CHECK( k2 >= k1 ); - BOOST_CHECK( k2 >= k ); + BOOST_CHECK( static_cast(k2 == k) ); + BOOST_CHECK( static_cast(k1 != k2) ); + BOOST_CHECK( static_cast(k1 < k2) ); + BOOST_CHECK( static_cast(k1 <= k2) ); + BOOST_CHECK( static_cast(k <= k2) ); + BOOST_CHECK( static_cast(k2 > k1) ); + BOOST_CHECK( static_cast(k2 >= k1) ); + BOOST_CHECK( static_cast(k2 >= k) ); cout << "Performed tests on MyChar objects.\n"; @@ -764,31 +808,31 @@ test_main( int , char * [] ) PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) ); - BOOST_CHECK( l2 == l ); - BOOST_CHECK( 2 == l ); - BOOST_CHECK( l2 == 2 ); - BOOST_CHECK( l == l2 ); - BOOST_CHECK( l1 != l2 ); - BOOST_CHECK( l1 != 2 ); - BOOST_CHECK( 1 != l2 ); - BOOST_CHECK( l1 < l2 ); - BOOST_CHECK( 1 < l2 ); - BOOST_CHECK( l1 < 2 ); - BOOST_CHECK( l1 <= l2 ); - BOOST_CHECK( 1 <= l2 ); - BOOST_CHECK( l1 <= l ); - BOOST_CHECK( l <= l2 ); - BOOST_CHECK( 2 <= l2 ); - BOOST_CHECK( l <= 2 ); - BOOST_CHECK( l2 > l1 ); - BOOST_CHECK( 2 > l1 ); - BOOST_CHECK( l2 > 1 ); - BOOST_CHECK( l2 >= l1 ); - BOOST_CHECK( 2 >= l1 ); - BOOST_CHECK( l2 >= 1 ); - BOOST_CHECK( l2 >= l ); - BOOST_CHECK( 2 >= l ); - BOOST_CHECK( l2 >= 2 ); + BOOST_CHECK( static_cast(l2 == l) ); + BOOST_CHECK( static_cast(2 == l) ); + BOOST_CHECK( static_cast(l2 == 2) ); + BOOST_CHECK( static_cast(l == l2) ); + BOOST_CHECK( static_cast(l1 != l2) ); + BOOST_CHECK( static_cast(l1 != 2) ); + BOOST_CHECK( static_cast(1 != l2) ); + BOOST_CHECK( static_cast(l1 < l2) ); + BOOST_CHECK( static_cast(1 < l2) ); + BOOST_CHECK( static_cast(l1 < 2) ); + BOOST_CHECK( static_cast(l1 <= l2) ); + BOOST_CHECK( static_cast(1 <= l2) ); + BOOST_CHECK( static_cast(l1 <= l) ); + BOOST_CHECK( static_cast(l <= l2) ); + BOOST_CHECK( static_cast(2 <= l2) ); + BOOST_CHECK( static_cast(l <= 2) ); + BOOST_CHECK( static_cast(l2 > l1) ); + BOOST_CHECK( static_cast(2 > l1) ); + BOOST_CHECK( static_cast(l2 > 1) ); + BOOST_CHECK( static_cast(l2 >= l1) ); + BOOST_CHECK( static_cast(2 >= l1) ); + BOOST_CHECK( static_cast(l2 >= 1) ); + BOOST_CHECK( static_cast(l2 >= l) ); + BOOST_CHECK( static_cast(2 >= l) ); + BOOST_CHECK( static_cast(l2 >= 2) ); cout << "Performed tests on MyShort objects.\n"; @@ -807,37 +851,37 @@ test_main( int , char * [] ) PRIVATE_EXPR_TEST( (di = di2), (di.value() == 2) ); - BOOST_CHECK( di2 == di ); - BOOST_CHECK( 2 == di ); - BOOST_CHECK( di == 2 ); - BOOST_CHECK( di1 < di2 ); - BOOST_CHECK( 1 < di2 ); - BOOST_CHECK( di1 <= di2 ); - BOOST_CHECK( 1 <= di2 ); - BOOST_CHECK( di2 > di1 ); - BOOST_CHECK( di2 > 1 ); - BOOST_CHECK( di2 >= di1 ); - BOOST_CHECK( di2 >= 1 ); - BOOST_CHECK( di1 / di2 == half ); - BOOST_CHECK( di1 / 2 == half ); - BOOST_CHECK( 1 / di2 == half ); - PRIVATE_EXPR_TEST( (tmp=di1), ((tmp/=2) == half) ); - PRIVATE_EXPR_TEST( (tmp=di1), ((tmp/=di2) == half) ); - BOOST_CHECK( di1 * di2 == di2 ); - BOOST_CHECK( di1 * 2 == di2 ); - BOOST_CHECK( 1 * di2 == di2 ); - PRIVATE_EXPR_TEST( (tmp=di1), ((tmp*=2) == di2) ); - PRIVATE_EXPR_TEST( (tmp=di1), ((tmp*=di2) == di2) ); - BOOST_CHECK( di2 - di1 == di1 ); - BOOST_CHECK( di2 - 1 == di1 ); - BOOST_CHECK( 2 - di1 == di1 ); - PRIVATE_EXPR_TEST( (tmp=di2), ((tmp-=1) == di1) ); - PRIVATE_EXPR_TEST( (tmp=di2), ((tmp-=di1) == di1) ); - BOOST_CHECK( di1 + di1 == di2 ); - BOOST_CHECK( di1 + 1 == di2 ); - BOOST_CHECK( 1 + di1 == di2 ); - PRIVATE_EXPR_TEST( (tmp=di1), ((tmp+=1) == di2) ); - PRIVATE_EXPR_TEST( (tmp=di1), ((tmp+=di1) == di2) ); + BOOST_CHECK( static_cast(di2 == di) ); + BOOST_CHECK( static_cast(2 == di) ); + BOOST_CHECK( static_cast(di == 2) ); + BOOST_CHECK( static_cast(di1 < di2) ); + BOOST_CHECK( static_cast(1 < di2) ); + BOOST_CHECK( static_cast(di1 <= di2) ); + BOOST_CHECK( static_cast(1 <= di2) ); + BOOST_CHECK( static_cast(di2 > di1) ); + BOOST_CHECK( static_cast(di2 > 1) ); + BOOST_CHECK( static_cast(di2 >= di1) ); + BOOST_CHECK( static_cast(di2 >= 1) ); + BOOST_CHECK( static_cast(di1 / di2 == half) ); + BOOST_CHECK( static_cast(di1 / 2 == half) ); + BOOST_CHECK( static_cast(1 / di2 == half) ); + PRIVATE_EXPR_TEST( (tmp=di1), static_cast((tmp/=2) == half) ); + PRIVATE_EXPR_TEST( (tmp=di1), static_cast((tmp/=di2) == half) ); + BOOST_CHECK( static_cast(di1 * di2 == di2) ); + BOOST_CHECK( static_cast(di1 * 2 == di2) ); + BOOST_CHECK( static_cast(1 * di2 == di2) ); + PRIVATE_EXPR_TEST( (tmp=di1), static_cast((tmp*=2) == di2) ); + PRIVATE_EXPR_TEST( (tmp=di1), static_cast((tmp*=di2) == di2) ); + BOOST_CHECK( static_cast(di2 - di1 == di1) ); + BOOST_CHECK( static_cast(di2 - 1 == di1) ); + BOOST_CHECK( static_cast(2 - di1 == di1) ); + PRIVATE_EXPR_TEST( (tmp=di2), static_cast((tmp-=1) == di1) ); + PRIVATE_EXPR_TEST( (tmp=di2), static_cast((tmp-=di1) == di1) ); + BOOST_CHECK( static_cast(di1 + di1 == di2) ); + BOOST_CHECK( static_cast(di1 + 1 == di2) ); + BOOST_CHECK( static_cast(1 + di1 == di2) ); + PRIVATE_EXPR_TEST( (tmp=di1), static_cast((tmp+=1) == di2) ); + PRIVATE_EXPR_TEST( (tmp=di1), static_cast((tmp+=di1) == di2) ); cout << "Performed tests on MyDoubleInt objects.\n"; @@ -854,42 +898,42 @@ test_main( int , char * [] ) PRIVATE_EXPR_TEST( (li = li2), (li.value() == 2) ); - BOOST_CHECK( li2 == li ); - BOOST_CHECK( 2 == li ); - BOOST_CHECK( li == 2 ); - BOOST_CHECK( li1 < li2 ); - BOOST_CHECK( 1 < li2 ); - BOOST_CHECK( li1 <= li2 ); - BOOST_CHECK( 1 <= li2 ); - BOOST_CHECK( li2 > li1 ); - BOOST_CHECK( li2 > 1 ); - BOOST_CHECK( li2 >= li1 ); - BOOST_CHECK( li2 >= 1 ); - BOOST_CHECK( li1 % li2 == li1 ); - BOOST_CHECK( li1 % 2 == li1 ); - BOOST_CHECK( 1 % li2 == li1 ); - PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2%=2) == li1) ); - PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2%=li2) == li1) ); - BOOST_CHECK( li1 / li2 == 0 ); - BOOST_CHECK( li1 / 2 == 0 ); - BOOST_CHECK( 1 / li2 == 0 ); - PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2/=2) == 0) ); - PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2/=li2) == 0) ); - BOOST_CHECK( li1 * li2 == li2 ); - BOOST_CHECK( li1 * 2 == li2 ); - BOOST_CHECK( 1 * li2 == li2 ); - PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2*=2) == li2) ); - PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2*=li2) == li2) ); - BOOST_CHECK( li2 - li1 == li1 ); - BOOST_CHECK( li2 - 1 == li1 ); - BOOST_CHECK( 2 - li1 == li1 ); - PRIVATE_EXPR_TEST( (tmp2=li2), ((tmp2-=1) == li1) ); - PRIVATE_EXPR_TEST( (tmp2=li2), ((tmp2-=li1) == li1) ); - BOOST_CHECK( li1 + li1 == li2 ); - BOOST_CHECK( li1 + 1 == li2 ); - BOOST_CHECK( 1 + li1 == li2 ); - PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2+=1) == li2) ); - PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2+=li1) == li2) ); + BOOST_CHECK( static_cast(li2 == li) ); + BOOST_CHECK( static_cast(2 == li) ); + BOOST_CHECK( static_cast(li == 2) ); + BOOST_CHECK( static_cast(li1 < li2) ); + BOOST_CHECK( static_cast(1 < li2) ); + BOOST_CHECK( static_cast(li1 <= li2) ); + BOOST_CHECK( static_cast(1 <= li2) ); + BOOST_CHECK( static_cast(li2 > li1) ); + BOOST_CHECK( static_cast(li2 > 1) ); + BOOST_CHECK( static_cast(li2 >= li1) ); + BOOST_CHECK( static_cast(li2 >= 1) ); + BOOST_CHECK( static_cast(li1 % li2 == li1) ); + BOOST_CHECK( static_cast(li1 % 2 == li1) ); + BOOST_CHECK( static_cast(1 % li2 == li1) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast((tmp2%=2) == li1) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast((tmp2%=li2) == li1) ); + BOOST_CHECK( static_cast(li1 / li2 == 0) ); + BOOST_CHECK( static_cast(li1 / 2 == 0) ); + BOOST_CHECK( static_cast(1 / li2 == 0) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast((tmp2/=2) == 0) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast((tmp2/=li2) == 0) ); + BOOST_CHECK( static_cast(li1 * li2 == li2) ); + BOOST_CHECK( static_cast(li1 * 2 == li2) ); + BOOST_CHECK( static_cast(1 * li2 == li2) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast((tmp2*=2) == li2) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast((tmp2*=li2) == li2) ); + BOOST_CHECK( static_cast(li2 - li1 == li1) ); + BOOST_CHECK( static_cast(li2 - 1 == li1) ); + BOOST_CHECK( static_cast(2 - li1 == li1) ); + PRIVATE_EXPR_TEST( (tmp2=li2), static_cast((tmp2-=1) == li1) ); + PRIVATE_EXPR_TEST( (tmp2=li2), static_cast((tmp2-=li1) == li1) ); + BOOST_CHECK( static_cast(li1 + li1 == li2) ); + BOOST_CHECK( static_cast(li1 + 1 == li2) ); + BOOST_CHECK( static_cast(1 + li1 == li2) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast((tmp2+=1) == li2) ); + PRIVATE_EXPR_TEST( (tmp2=li1), static_cast((tmp2+=li1) == li2) ); cout << "Performed tests on MyLongInt objects.\n"; From 4003a9f74a81b763466d3289306dfe0717c1597a Mon Sep 17 00:00:00 2001 From: Steven Watanabe Date: Sat, 23 May 2009 05:36:13 +0000 Subject: [PATCH 054/126] Merge [53060] from the trunk. [SVN r53197] --- in_place_factories.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/in_place_factories.html b/in_place_factories.html index d3791f8..f8a4c7b 100644 --- a/in_place_factories.html +++ b/in_place_factories.html @@ -117,7 +117,7 @@ The following simplified example shows the basic idea. A complete example follow

            struct C
             {
                template<class InPlaceFactory>
            -   C ( InPlaceFactory const& aFactoty )
            +   C ( InPlaceFactory const& aFactory )
                 :
                 contained_ ( uninitialized_storage() )
                {
            
            From ffe151458e6a620973c309762bf47d3fe44cd994 Mon Sep 17 00:00:00 2001
            From: Daniel James 
            Date: Mon, 25 May 2009 20:06:26 +0000
            Subject: [PATCH 055/126] Use local copy of the valid HTML 4.01 icon, and make
             sure all the pages that use it are valid.
            
            Merged revisions 53047-53048 via svnmerge from
            https://svn.boost.org/svn/boost/trunk
            
            ........
              r53047 | danieljames | 2009-05-16 15:17:20 +0100 (Sat, 16 May 2009) | 1 line
            
              Fix some validation errors.
            ........
              r53048 | danieljames | 2009-05-16 15:23:59 +0100 (Sat, 16 May 2009) | 1 line
            
              Use a local copy of the valid HTML 4.01 icon.
            ........
            
            
            [SVN r53258]
            ---
             Assignable.html             | 2 +-
             Collection.html             | 2 +-
             CopyConstructible.html      | 2 +-
             LessThanComparable.html     | 2 +-
             MultiPassInputIterator.html | 2 +-
             generator_iterator.htm      | 2 +-
             6 files changed, 6 insertions(+), 6 deletions(-)
            
            diff --git a/Assignable.html b/Assignable.html
            index 54934f1..d3b3157 100644
            --- a/Assignable.html
            +++ b/Assignable.html
            @@ -85,7 +85,7 @@
               

            Valid HTML 4.01 Transitional

            Revised diff --git a/Collection.html b/Collection.html index c811e7e..b92ddd6 100644 --- a/Collection.html +++ b/Collection.html @@ -509,7 +509,7 @@ Returns the largest size that this Collection can ever have. [8]

            Valid HTML 4.01 Transitional

            Revised diff --git a/CopyConstructible.html b/CopyConstructible.html index 40ff7a7..6a7ce65 100644 --- a/CopyConstructible.html +++ b/CopyConstructible.html @@ -160,7 +160,7 @@ t.~T()


            Valid HTML 4.01 Transitional

            Revised diff --git a/LessThanComparable.html b/LessThanComparable.html index a723377..15b938f 100644 --- a/LessThanComparable.html +++ b/LessThanComparable.html @@ -185,7 +185,7 @@


            Valid HTML 4.01 Transitional

            Revised diff --git a/MultiPassInputIterator.html b/MultiPassInputIterator.html index fa7517c..e331ca3 100644 --- a/MultiPassInputIterator.html +++ b/MultiPassInputIterator.html @@ -70,7 +70,7 @@


            Valid HTML 4.01 Transitional

            Revised diff --git a/generator_iterator.htm b/generator_iterator.htm index 6070522..b0e376e 100644 --- a/generator_iterator.htm +++ b/generator_iterator.htm @@ -146,7 +146,7 @@ int main()


            Valid HTML 4.01 Transitional

            Revised From 8cb975feb772cbd0dbb28fe4d78bee5b57b09b30 Mon Sep 17 00:00:00 2001 From: Ronald Garcia Date: Wed, 3 Jun 2009 14:45:12 +0000 Subject: [PATCH 056/126] Merge [47295] to release. [SVN r53602] --- include/boost/ref.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/boost/ref.hpp b/include/boost/ref.hpp index 0d747bd..6058d69 100644 --- a/include/boost/ref.hpp +++ b/include/boost/ref.hpp @@ -173,6 +173,12 @@ class unwrap_reference # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template inline typename unwrap_reference::type& +unwrap_ref(T& t) +{ + return t; +} + template inline T* get_pointer( reference_wrapper const & r ) { return r.get_pointer(); From cd12e322bdd7fb6f1643f5a147b82063b4bb0587 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Wed, 22 Jul 2009 20:55:50 +0000 Subject: [PATCH 057/126] Merging in changes trunk updates: adding standard error_info typedefs, updating the documentation. [SVN r55094] --- include/boost/exception.hpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/include/boost/exception.hpp b/include/boost/exception.hpp index b4716a0..ff31565 100644 --- a/include/boost/exception.hpp +++ b/include/boost/exception.hpp @@ -6,14 +6,8 @@ #ifndef UUID_1D94A7C6054E11DB9804B622A1EF5492 #define UUID_1D94A7C6054E11DB9804B622A1EF5492 -#include -#include -#include -#include -#include -#include -#ifndef BOOST_NO_EXCEPTIONS -#include -#endif +//The header has been deprecated. +//Please #include instead. +#include #endif From 61755605affa3642b1493aa8fd2d62a7de99739c Mon Sep 17 00:00:00 2001 From: "Troy D. Straszheim" Date: Wed, 22 Jul 2009 21:51:01 +0000 Subject: [PATCH 058/126] Add basic copyright/license to keep cmake out of the inspection report [SVN r55095] --- CMakeLists.txt | 6 ++++++ enable_if/test/CMakeLists.txt | 6 ++++++ swap/test/CMakeLists.txt | 6 ++++++ test/CMakeLists.txt | 6 ++++++ 4 files changed, 24 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ea7c9d4..f6285c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,9 @@ +# +# Copyright Troy D. Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt +# #---------------------------------------------------------------------------- # This file was automatically generated from the original CMakeLists.txt file # Add a variable to hold the headers for the library diff --git a/enable_if/test/CMakeLists.txt b/enable_if/test/CMakeLists.txt index a6e1a4f..be95145 100644 --- a/enable_if/test/CMakeLists.txt +++ b/enable_if/test/CMakeLists.txt @@ -1,3 +1,9 @@ +# +# Copyright Troy D. Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt +# foreach(T constructors dummy_arg_disambiguation diff --git a/swap/test/CMakeLists.txt b/swap/test/CMakeLists.txt index 1570d83..2562313 100644 --- a/swap/test/CMakeLists.txt +++ b/swap/test/CMakeLists.txt @@ -1,3 +1,9 @@ +# +# Copyright Troy D. Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt +# foreach(T root_header_1 root_header_2 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4236efd..4ed28b6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,3 +1,9 @@ +# +# Copyright Troy D. Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt +# boost_additional_test_dependencies(utility BOOST_DEPENDS test) boost_test_run(addressof_fn_test ../addressof_fn_test.cpp) From d5291d08b88f8f024e963378b8a26646b746c340 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Sun, 9 Aug 2009 13:45:03 +0000 Subject: [PATCH 059/126] Merged 52463 [SVN r55485] --- operators.htm | 55 +++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/operators.htm b/operators.htm index a33e814..37820e1 100644 --- a/operators.htm +++ b/operators.htm @@ -132,18 +132,18 @@ class MyInt : boost::operators<MyInt> { - bool operator<(const MyInt& x) const; + bool operator<(const MyInt& x) const; bool operator==(const MyInt& x) const; - MyInt& operator+=(const MyInt& x); - MyInt& operator-=(const MyInt& x); - MyInt& operator*=(const MyInt& x); - MyInt& operator/=(const MyInt& x); - MyInt& operator%=(const MyInt& x); - MyInt& operator|=(const MyInt& x); - MyInt& operator&=(const MyInt& x); - MyInt& operator^=(const MyInt& x); - MyInt& operator++(); - MyInt& operator--(); + MyInt& operator+=(const MyInt& x); + MyInt& operator-=(const MyInt& x); + MyInt& operator*=(const MyInt& x); + MyInt& operator/=(const MyInt& x); + MyInt& operator%=(const MyInt& x); + MyInt& operator|=(const MyInt& x); + MyInt& operator&=(const MyInt& x); + MyInt& operator^=(const MyInt& x); + MyInt& operator++(); + MyInt& operator--(); };

            @@ -345,7 +345,7 @@ class MyInt

          As Daniel Krügler pointed out, this technique violates 14.6.5/2 - and is thus non-portable. The reasoning is, that the operators injected + and is thus non-portable. The reasoning is, that the operators injected by the instantiation of e.g. less_than_comparable<myclass> can not be found by ADL according to the rules given by 3.4.2/2, since myclass is @@ -445,6 +445,9 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4); optional template parameter B, which is not shown, for the base class chaining technique.

          +

          The primary operand type T needs to be of class type, + built-in types are not supported.

          +
          Simple Arithmetic Operator Template Classes @@ -917,7 +920,7 @@ T operator+( const T& lhs, const T& rhs ) created, operator+= is called on it and it is copied to the function return value (which is another unnamed object of type T). The standard doesn't generally allow the intermediate - object to be optimized away: + object to be optimized away:
          3.7.2/2: Automatic storage duration
          @@ -928,7 +931,7 @@ T operator+( const T& lhs, const T& rhs ) unused, except that a class object or its copy may be eliminated as specified in 12.8.
          - The reference to 12.8 is important for us: + The reference to 12.8 is important for us:
          12.8/15: Copying class objects
          @@ -942,7 +945,7 @@ T operator+( const T& lhs, const T& rhs )
          This optimization is known as the named return value optimization (NRVO), which leads us to the following implementation for - operator+: + operator+:
           T operator+( const T& lhs, const T& rhs )
           {
          @@ -956,7 +959,7 @@ T operator+( const T& lhs, const T& rhs )
               even implement it in an incorrect way which makes it useless here.
               Without the NRVO, the NRVO-friendly code is no worse than the original
               code showed above, but there is another possible implementation, which
          -    has some very special properties: 
          +    has some very special properties:
           
           T operator+( T lhs, const T& rhs )
           {
          @@ -982,7 +985,7 @@ T operator+( T lhs, const T& rhs )
               will force the NRVO-friendly implementation to be used even for compilers
               that don't implement the NRVO. 

          - +

          Grouped Arithmetic Operators

          The following templates provide common groups of related operations. @@ -1864,7 +1867,7 @@ T operator+( T lhs, const T& rhs ) V, D, P, R>

          - Supports the operations and has the requirements of + Supports the operations and has the requirements of - Supports the operations and has the requirements of + Supports the operations and has the requirements of
          - Supports the operations and has the requirements of + Supports the operations and has the requirements of - Supports the operations and has the requirements of + Supports the operations and has the requirements of
          - Supports the operations and has the requirements of + Supports the operations and has the requirements of
          • Revised: 7 Aug 2008

            Copyright © Beman Dawes, David Abrahams, 1999-2001.

            -

            Copyright © Daniel Frey, 2002-2008.

            -

            Use, modification, and distribution is subject to the Boost Software +

            Copyright © Daniel Frey, 2002-2009.

            +

            Use, modification, and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at From e54cbf3053c2b07f6ecb5f4f6bee47858d43f2b3 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Sat, 3 Oct 2009 08:15:14 +0000 Subject: [PATCH 060/126] Merged Swap documentation from trunk, including revision [56107] and [56108]. [SVN r56541] --- swap.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/swap.html b/swap.html index 4022e0b..36f8425 100644 --- a/swap.html +++ b/swap.html @@ -7,7 +7,11 @@ +

            C++ Boost + Header <boost/swap.hpp> +

            +

            Swap

            @@ -84,9 +88,9 @@


            -

            Revised: 15 November 2008

            +

            Revised: 08 September 2009

            - Copyright 2007, 2008 Joseph Gauterin. Use, modification, and distribution are subject to the Boost Software License, Version 1.0. + Copyright 2007 - 2009 Joseph Gauterin. 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>.)

            From f8bef7ba9557bba53b5f03e1ab6e72dd82ffa3f8 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Sat, 3 Oct 2009 09:08:10 +0000 Subject: [PATCH 061/126] Merged value_init_test from trunk, inc. [51356], anticipating the fix of ticket #2548, which will remove implicit conversion from const value_initialized to non-const T&. [SVN r56543] --- value_init_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/value_init_test.cpp b/value_init_test.cpp index 63f324d..67ebad8 100644 --- a/value_init_test.cpp +++ b/value_init_test.cpp @@ -260,7 +260,7 @@ bool test ( T const& y, T const& z ) boost::value_initialized const x_c ; BOOST_CHECK ( y == x_c ) ; BOOST_CHECK ( y == boost::get(x_c) ) ; - T& x_c_ref = x_c ; + T& x_c_ref = const_cast( boost::get(x_c) ) ; x_c_ref = z ; BOOST_CHECK ( x_c == z ) ; From c131cbd0b281c9a54243f2c3cd483641f4e68e5c Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Sat, 3 Oct 2009 10:19:09 +0000 Subject: [PATCH 062/126] Merged value_init from the trunk, including fix of #2548, regarding "const value_initialized". [SVN r56547] --- include/boost/utility/value_init.hpp | 14 +++++- value_init.htm | 70 +++++++++++++++++++--------- 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/include/boost/utility/value_init.hpp b/include/boost/utility/value_init.hpp index aa7ecb4..177fe74 100644 --- a/include/boost/utility/value_init.hpp +++ b/include/boost/utility/value_init.hpp @@ -8,6 +8,7 @@ // 24 Dec 2007 (Refactored and worked around various compiler bugs) Fernando Cacciola, Niels Dekker // 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola // 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola +// 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola // #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP @@ -90,7 +91,12 @@ class value_initialized wrapper_address()->wrapper::~wrapper(); } - T& data() const + T const & data() const + { + return wrapper_address()->data; + } + + T& data() { return wrapper_address()->data; } @@ -100,12 +106,16 @@ class value_initialized ::boost::swap( this->data(), arg.data() ); } - operator T&() const { return this->data(); } + operator T const &() const { return this->data(); } + + operator T&() { return this->data(); } } ; + + template T const& get ( value_initialized const& x ) { diff --git a/value_init.htm b/value_init.htm index 5c1b20e..57b2313 100644 --- a/value_init.htm +++ b/value_init.htm @@ -253,7 +253,33 @@ its internal data, prior to constructing the object that it contains.

            template class value_initialized<T>

            -
            namespace boost {

            template<class T>
            class value_initialized
            {
            public :
            value_initialized() : x() {}
            operator T&() const { return x ; }
            T& data() const { return x ; }
            void swap( value_initialized<T>& );

            private :
            unspecified x ;
            } ;

            template<class T>
            T const& get ( value_initialized<T> const& x )
            {
            return x.data() ;
            }

            template<class T>
            T& get ( value_initialized<T>& x )
            {
            return x.data() ;
            }

            } // namespace boost
            +
            namespace boost {

            template<class T>
            class value_initialized
            { +
            public : +
            value_initialized() : x() {} +
            operator T const &() const { return x ; } +
            operator T&() { return x ; } +
            T const &data() const { return x ; } +
            T& data() { return x ; } +
            void swap( value_initialized<T>& ); +
            +
            private : +
            unspecified x ; +
            } ; +
            +
            template<class T> +
            T const& get ( value_initialized<T> const& x ) +
            { +
            return x.data() ; +
            } +
            +
            template<class T> +
            T& get ( value_initialized<T>& x ) +
            { +
            return x.data() ; +
            } +
            +
            } // namespace boost +

            An object of this template class is a T-wrapper convertible to 'T&' whose wrapped object (data member of type T) @@ -271,7 +297,8 @@ its internal data, prior to constructing the object that it contains. T&, the member function data(), or the non-member function get():

            -
            void watch(int);
            value_initialized<int> x;

            watch(x) ; // operator T& used.
            watch(x.data());
            watch( get(x) ) // function get() used
            +
            void watch(int);
            value_initialized<int> x; +

            watch(x) ; // operator T& used.
            watch(x.data());
            watch( get(x) ) // function get() used

            Both const and non-const objects can be wrapped. Mutable objects can be modified directly from within the wrapper but constant @@ -281,37 +308,34 @@ non-member function get():

            is swappable as well, by calling its swap member function as well as by calling boost::swap.

            -
            value_initialized<int> x ; 
            static_cast<int&>(x) = 1 ; // OK
            get(x) = 1 ; // OK

            value_initialized<int const> y ;
            static_cast<int&>(y) = 1 ; // ERROR: cannot cast to int&
            static_cast<int const&>(y) = 1 ; // ERROR: cannot modify a const value
            get(y) = 1 ; // ERROR: cannot modify a const value
            +
            value_initialized<int> x ; 
            static_cast<int&>(x) = 1 ; // OK
            get(x) = 1 ; // OK +

            value_initialized<int const> y ;
            static_cast<int&>(y) = 1 ; // ERROR: cannot cast to int&
            static_cast<int const&>(y) = 1 ; // ERROR: cannot modify a const value
            get(y) = 1 ; // ERROR: cannot modify a const value

            Warning:

            -

            Both the conversion operator and the data() member function - are const in order to allow access to the wrapped object -from a constant wrapper:

            +

            The value_initialized implementation of Boost version 1.40.0 and older +allowed non-const access to the wrapped object, from a constant wrapper, +both by its conversion operator and its data() member function. For example:

            -
            void foo(int);
            value_initialized<int> const x ;
            foo(x);
            +
            value_initialized<int> const x_c ;
            int& xr = x_c ; // OK, conversion to int& available even though x_c is itself const. +
            xr = 2 ;
            -

            But notice that this conversion operator is to T& although - it is itself const. As a consequence, if T is - a non-const type, you can modify the wrapped object even from - within a constant wrapper:

            - -
            value_initialized<int> const x_c ;
            int& xr = x_c ; // OK, conversion to int& available even though x_c is itself const.
            xr = 2 ;
            - -

            The reason for this obscure behavior is that some commonly used compilers - just don't accept the following valid code:

            +

            The reason for this obscure behavior was that some compilers + didn't accept the following valid code:

            struct X
            {
            operator int&() ;
            operator int const&() const ;
            };
            X x ;
            (x == 1 ) ; // ERROR HERE!
            -

            These compilers complain about ambiguity between the conversion operators. - This complaint is incorrect, but the only workaround that I know of is - to provide only one of them, which leads to the obscure behavior just explained.
            +

            The current version of value_initialized no longer has this obscure behavior. +As compilers nowadays widely support overloading the conversion operator by having a const and a non-const version, we have decided to fix the issue accordingly. So the current version supports the idea of logical constness. +

            Recommended practice: The non-member get() idiom

            The obscure behavior of being able to modify a non-const -wrapped object from within a constant wrapper can be avoided if access to +wrapped object from within a constant wrapper (as was supported by previous +versions of value_initialized) +can be avoided if access to the wrapped object is always performed with the get() idiom:

            value_initialized<int> x ;
            get(x) = 1 ; // OK

            value_initialized<int const> cx ;
            get(x) = 1 ; // ERROR: Cannot modify a const object

            value_initialized<int> const x_c ;
            get(x_c) = 1 ; // ERROR: Cannot modify a const object

            value_initialized<int const> const cx_c ;
            get(cx_c) = 1 ; // ERROR: Cannot modify a const object
            @@ -383,9 +407,9 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler


            -

            Revised 28 August 2008

            +

            Revised 03 October 2009

            -

            © Copyright Fernando Cacciola, 2002, 2008.

            +

            © Copyright Fernando Cacciola, 2002, 2009.

            Distributed under the Boost Software License, Version 1.0. See www.boost.org/LICENSE_1_0.txt

            @@ -394,4 +418,4 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
            - \ No newline at end of file + From ee146a02a18673384f98d985ee57e822ac291435 Mon Sep 17 00:00:00 2001 From: "Troy D. Straszheim" Date: Sat, 17 Oct 2009 01:10:45 +0000 Subject: [PATCH 063/126] rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release. [SVN r56941] --- CMakeLists.txt | 37 --------------------------- enable_if/test/CMakeLists.txt | 20 --------------- module.cmake | 1 - swap/test/CMakeLists.txt | 41 ------------------------------ test/CMakeLists.txt | 47 ----------------------------------- 5 files changed, 146 deletions(-) delete mode 100644 CMakeLists.txt delete mode 100644 enable_if/test/CMakeLists.txt delete mode 100644 module.cmake delete mode 100644 swap/test/CMakeLists.txt delete mode 100644 test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index f6285c4..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright Troy D. Straszheim -# -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt -# -#---------------------------------------------------------------------------- -# This file was automatically generated from the original CMakeLists.txt file -# Add a variable to hold the headers for the library -set (lib_headers - assert.hpp - call_traits.hpp - checked_delete.hpp - compressed_pair.hpp - current_function.hpp - operators.hpp - throw_exception.hpp - utility.hpp - utility -) - -# Add a library target to the build system -boost_library_project( - utility - # SRCDIRS - TESTDIRS test swap/test enable_if/test - HEADERS ${lib_headers} - # DOCDIRS - DESCRIPTION "Various small utilities for C++ programming." - MODULARIZED - AUTHORS "David Abrahams " - "Brad King" - "Douglas Gregor " - # MAINTAINERS -) - - diff --git a/enable_if/test/CMakeLists.txt b/enable_if/test/CMakeLists.txt deleted file mode 100644 index be95145..0000000 --- a/enable_if/test/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright Troy D. Straszheim -# -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt -# -foreach(T - constructors - dummy_arg_disambiguation - lazy - lazy_test - member_templates - namespace_disambiguation - no_disambiguation - partial_specializations - ) - boost_test_run(${T} DEPENDS boost_test_exec_monitor) -endforeach() - - diff --git a/module.cmake b/module.cmake deleted file mode 100644 index 4d78340..0000000 --- a/module.cmake +++ /dev/null @@ -1 +0,0 @@ -boost_module(utility DEPENDS iterator exception detail ) \ No newline at end of file diff --git a/swap/test/CMakeLists.txt b/swap/test/CMakeLists.txt deleted file mode 100644 index 2562313..0000000 --- a/swap/test/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -# -# Copyright Troy D. Straszheim -# -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt -# - -foreach(T - root_header_1 root_header_2 - lib_header_1 lib_header_2 - mixed_headers_1 mixed_headers_2) - boost_test_compile(${T}) -endforeach() - - -# [ run primitive.cpp ../../../test/build//boost_test_exec_monitor/static ] - - -foreach(T - primitive - specialized_in_boost - specialized_in_global - specialized_in_other - specialized_in_std - specialized_in_boost_and_other - std_bitset - std_dateorder - std_string - std_typeinfo_ptr - std_vector_of_boost - std_vector_of_global - std_vector_of_other - no_ambiguity_in_boost - array_of_array_of_class - array_of_array_of_int - array_of_class - array_of_int - array_of_template) - boost_test_run(${T} DEPENDS boost_test_exec_monitor) -endforeach() - diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt deleted file mode 100644 index 4ed28b6..0000000 --- a/test/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -# -# Copyright Troy D. Straszheim -# -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt -# -boost_additional_test_dependencies(utility BOOST_DEPENDS test) - -boost_test_run(addressof_fn_test ../addressof_fn_test.cpp) -boost_test_run(addressof_test ../addressof_test.cpp) -boost_test_run(addressof_test2 ../addressof_test2.cpp) -boost_test_run(assert_test ../assert_test.cpp) -boost_test_run(base_from_member_test ../base_from_member_test.cpp) -boost_test_run(binary_search_test ../binary_search_test.cpp) -boost_test_run(call_traits_test ../call_traits_test.cpp ARGS -u) -boost_test_compile_fail(checked_delete_test ../checked_delete_test.cpp) -boost_test_run(compressed_pair_test - ../compressed_pair_test - DEPENDS boost_test_exec_monitor) -boost_test_run(current_function_test ../current_function_test.cpp) -boost_test_run(iterators_test - ../iterators_test.cpp - DEPENDS boost_test_exec_monitor) -boost_test_run(next_prior_test DEPENDS boost_test_exec_monitor) -boost_test_compile_fail(noncopyable_test ../noncopyable_test.cpp) -boost_test_run(numeric_traits_test ../numeric_traits_test.cpp) -if (${CMAKE_SYSTEM} MATCHES "FreeBSD-.*") -boost_test_compile_fail("operators_test_compilerbug") -elseif(${CMAKE_SYSTEM} MATCHES "FreeBSD-.*") -boost_test_run(operators_test - ../operators_test.cpp - DEPENDS boost_test_exec_monitor) -endif(${CMAKE_SYSTEM} MATCHES "FreeBSD-.*") -boost_test_compile(ref_ct_test ../ref_ct_test.cpp) -boost_test_run(ref_test - ../ref_test.cpp - DEPENDS boost_test_exec_monitor) -boost_test_compile(result_of_test) -boost_test_run(shared_iterator_test ../shared_iterator_test.cpp) -boost_test_run(value_init_test ../value_init_test.cpp) -boost_test_compile_fail(value_init_test_fail1 - ../value_init_test_fail1.cpp) -boost_test_compile_fail(value_init_test_fail2 - ../value_init_test_fail2.cpp) -boost_test_compile_fail(value_init_test_fail3 - ../value_init_test_fail3.cpp) -boost_test_run(verify_test ../verify_test.cpp) \ No newline at end of file From 583422cda2047d1be34fa064b0b69c9ddb69112f Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 8 Nov 2009 11:45:20 +0000 Subject: [PATCH 064/126] Add swap to utility index page. Merged revisions 47093 via svnmerge from https://svn.boost.org/svn/boost/trunk [SVN r57482] --- index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/index.html b/index.html index ff22fb4..5af6f75 100644 --- a/index.html +++ b/index.html @@ -24,6 +24,7 @@ iterator_adaptors
            generator iterator adaptors
            operators
            + swap
            throw_exception
            utility
            value_init

            From dab1e8e522f9eac24bdb7db72ce5cd3096dc2f58 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Wed, 16 Dec 2009 22:26:57 +0000 Subject: [PATCH 065/126] Merging changes from trunk. [SVN r58421] --- include/boost/exception.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/boost/exception.hpp b/include/boost/exception.hpp index ff31565..6424159 100644 --- a/include/boost/exception.hpp +++ b/include/boost/exception.hpp @@ -6,8 +6,6 @@ #ifndef UUID_1D94A7C6054E11DB9804B622A1EF5492 #define UUID_1D94A7C6054E11DB9804B622A1EF5492 -//The header has been deprecated. -//Please #include instead. -#include +#error The header has been deprecated. Please #include instead. #endif From a47dce770c984198f44f369b8ecefdada1bc9b03 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 10 Jan 2010 19:17:23 +0000 Subject: [PATCH 066/126] Fix some whitespace differences between trunk and release. [SVN r58878] --- include/boost/utility/value_init.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/boost/utility/value_init.hpp b/include/boost/utility/value_init.hpp index 177fe74..5aefac9 100644 --- a/include/boost/utility/value_init.hpp +++ b/include/boost/utility/value_init.hpp @@ -114,8 +114,6 @@ class value_initialized - - template T const& get ( value_initialized const& x ) { From b4dee80e617283c88c95b7f72cda2aa2807c0100 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 7 Mar 2010 12:08:00 +0000 Subject: [PATCH 067/126] Merge various result_of changes. - [42234] Reduce header dependencies, from Shunsuke Sogame. Fixes #1535 - [45256] result_of implementation that makes use of C++0x decltype, from Daniel Walker. Fixes #862. - [48620] Fix result_of to work with const-qualified function pointers. Fixes #1310 - [60052] Remove use of deprecated config macro in result_of. [SVN r60289] --- .../utility/detail/result_of_iterate.hpp | 54 +++++++- include/boost/utility/result_of.hpp | 17 ++- test/result_of_test.cpp | 131 ++++++++++++++++-- utility.htm | 8 +- 4 files changed, 194 insertions(+), 16 deletions(-) diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp index 41616c3..7b09435 100644 --- a/include/boost/utility/detail/result_of_iterate.hpp +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -10,6 +10,47 @@ # error Boost result_of - do not include this file! #endif +#if !defined(BOOST_NO_DECLTYPE) + +// As of N2588, C++0x result_of only supports function call +// expressions of the form f(x). This precludes support for member +// function pointers, which are invoked with expressions of the form +// o->*f(x). This implementation supports both. +template +struct result_of + : mpl::if_< + mpl::or_< is_pointer, is_member_function_pointer > + , detail::result_of_impl< + typename remove_cv::type, + typename remove_cv::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false + > + , detail::result_of_decltype_impl< + F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)) + > + >::type +{}; + +namespace detail { + +# define BOOST_RESULT_OF_STATIC_MEMBERS(z, n, _) \ + static T ## n t ## n; \ + /**/ + +template +class result_of_decltype_impl +{ + static F f; + BOOST_PP_REPEAT(BOOST_PP_ITERATION(), BOOST_RESULT_OF_STATIC_MEMBERS, _) +public: + typedef decltype(f(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),t))) type; +}; + +} // namespace detail + +#else // defined(BOOST_HAS_DECLTYPE) + // CWPro8 requires an argument in a function type specialization #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 0 # define BOOST_RESULT_OF_ARGS void @@ -21,11 +62,22 @@ template struct result_of - : boost::detail::result_of_impl::value)> {}; + : mpl::if_< + mpl::or_< is_pointer, is_member_function_pointer > + , boost::detail::result_of_impl< + typename remove_cv::type, + typename remove_cv::type(BOOST_RESULT_OF_ARGS), + (boost::detail::has_result_type::value)> + , boost::detail::result_of_impl< + F, + F(BOOST_RESULT_OF_ARGS), + (boost::detail::has_result_type::value)> >::type { }; #endif #undef BOOST_RESULT_OF_ARGS +#endif // defined(BOOST_HAS_DECLTYPE) + #if BOOST_PP_ITERATION() >= 1 namespace detail { diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp index e35e098..78168fa 100644 --- a/include/boost/utility/result_of.hpp +++ b/include/boost/utility/result_of.hpp @@ -10,13 +10,18 @@ #define BOOST_RESULT_OF_HPP #include -#include -#include -#include +#include +#include +#include +#include #include #include #include #include +#include +#include +#include +#include #ifndef BOOST_RESULT_OF_NUM_ARGS # define BOOST_RESULT_OF_NUM_ARGS 10 @@ -32,6 +37,7 @@ namespace detail { BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) template struct result_of_impl; +template struct result_of_decltype_impl; template struct result_of_void_impl @@ -51,6 +57,11 @@ struct result_of_void_impl typedef R type; }; +// Determine the return type of a function pointer or pointer to member. +template +struct result_of_pointer + : result_of_impl::type, FArgs, false> { }; + template struct result_of_impl { diff --git a/test/result_of_test.cpp b/test/result_of_test.cpp index 10f3410..73dc757 100644 --- a/test/result_of_test.cpp +++ b/test/result_of_test.cpp @@ -11,35 +11,101 @@ #include #include -struct int_result_type { typedef int result_type; }; +struct int_result_type +{ + typedef int result_type; + result_type operator()(float); +}; struct int_result_of { template struct result { typedef int type; }; + result::type operator()(double); + result::type operator()(double) const; + result::type operator()(); + result::type operator()() volatile; }; -struct int_result_type_and_float_result_of +struct int_result_type_and_float_result_of_and_char_return { typedef int result_type; template struct result { typedef float type; }; + char operator()(char); }; template -struct int_result_type_template { typedef int result_type; }; +struct int_result_type_template +{ + typedef int result_type; + result_type operator()(float); +}; template struct int_result_of_template { template struct result; template struct result { typedef int type; }; + typename result(double)>::type operator()(double); + typename result(double)>::type operator()(double) const; + typename result(double)>::type operator()(); + typename result(double)>::type operator()() volatile; }; template -struct int_result_type_and_float_result_of_template +struct int_result_type_and_float_result_of_and_char_return_template { typedef int result_type; template struct result; template struct result { typedef float type; }; + char operator()(char); +}; + +struct result_of_member_function_template +{ + template struct result; + + template struct result { typedef That type; }; + template typename result::type operator()(T); + + template struct result { typedef const That type; }; + template typename result::type operator()(T) const; + + template struct result { typedef volatile That type; }; + template typename result::type operator()(T) volatile; + + template struct result { typedef const volatile That type; }; + template typename result::type operator()(T) const volatile; + + template struct result { typedef That & type; }; + template typename result::type operator()(T &, T); + + template struct result { typedef That const & type; }; + template typename result::type operator()(T const &, T); + + template struct result { typedef That volatile & type; }; + template typename result::type operator()(T volatile &, T); + + template struct result { typedef That const volatile & type; }; + template typename result::type operator()(T const volatile &, T); +}; + +struct no_result_type_or_result_of +{ + int operator()(double); + short operator()(double) const; + unsigned int operator()(); + unsigned short operator()() volatile; + const unsigned short operator()() const volatile; +}; + +template +struct no_result_type_or_result_of_template +{ + int operator()(double); + short operator()(double) const; + unsigned int operator()(); + unsigned short operator()() volatile; + const unsigned short operator()() const volatile; }; struct X {}; @@ -60,16 +126,37 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same::type, void>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same::type, void>::value)); - BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same(float)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); - BOOST_STATIC_ASSERT((is_same(void)>::type, void>::value)); BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); + + // Prior to decltype, result_of could not deduce the return type + // nullary function objects unless they exposed a result_type. +#if defined(BOOST_HAS_DECLTYPE) + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, int>::value)); +#else + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, void>::value)); BOOST_STATIC_ASSERT((is_same(void)>::type, void>::value)); - BOOST_STATIC_ASSERT((is_same(char)>::type, int>::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_HAS_DECLTYPE) + BOOST_STATIC_ASSERT((is_same::type, char>::value)); + BOOST_STATIC_ASSERT((is_same(char)>::type, char>::value)); +#else + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(char)>::type, int>::value)); +#endif + BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); @@ -81,5 +168,31 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, double>::value)); + BOOST_STATIC_ASSERT((is_same::type, const double>::value)); + BOOST_STATIC_ASSERT((is_same::type, volatile double>::value)); + BOOST_STATIC_ASSERT((is_same::type, const volatile double>::value)); + BOOST_STATIC_ASSERT((is_same::type, int &>::value)); + BOOST_STATIC_ASSERT((is_same::type, int const &>::value)); + BOOST_STATIC_ASSERT((is_same::type, int volatile &>::value)); + BOOST_STATIC_ASSERT((is_same::type, int const volatile &>::value)); + + typedef int (*pf_t)(int); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type,int>::value)); + +#if defined(BOOST_HAS_DECLTYPE) + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, unsigned int>::value)); + BOOST_STATIC_ASSERT((is_same::type, short>::value)); + BOOST_STATIC_ASSERT((is_same::type, unsigned short>::value)); + BOOST_STATIC_ASSERT((is_same::type, const unsigned short>::value)); + BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, unsigned int>::value)); + BOOST_STATIC_ASSERT((is_same(double)>::type, short>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, unsigned short>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, const unsigned short>::value)); +#endif + return 0; } diff --git a/utility.htm b/utility.htm index eff847d..d4c7205 100644 --- a/utility.htm +++ b/utility.htm @@ -154,11 +154,13 @@ void f() { ...,tN)
            . The implementation permits the type F to be a function pointer, function reference, member function pointer, or class - type. When F is a class type with a - member type result_type, + type.

            If your compiler does not support + decltype, then when F is a + class type with a member type result_type, result_of<F(T1, T2, ..., TN)> is - F::result_type. Otherwise, + F::result_type. When F + does not contain result_type, result_of<F(T1, T2, ..., TN)> is F::result<F(T1, T2, ..., TN)>::type when From e30889304c5550c43d20ce176b8a9d8fb12c92b7 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 7 Mar 2010 12:11:44 +0000 Subject: [PATCH 068/126] Merge some tests for unwrap ([47296], [47297]) [SVN r60290] --- ref_test.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/ref_test.cpp b/ref_test.cpp index 63fc9e5..d4237b4 100644 --- a/ref_test.cpp +++ b/ref_test.cpp @@ -68,11 +68,54 @@ struct ref_wrapper } }; +struct copy_counter { + static int count_; + copy_counter(copy_counter const& other) { + ++count_; + } + copy_counter() {} + static void reset() { count_ = 0; } + static int count() { return copy_counter::count_; } +}; + +int copy_counter::count_ = 0; + } // namespace unnamed +template +void do_unwrap(T t) { + + /* typename unwrap_reference::type& lt = */ + unwrap_ref(t); + +} + +void unwrap_test() { + + int i = 3; + const int ci = 2; + + do_unwrap(i); + do_unwrap(ci); + do_unwrap(ref(i)); + do_unwrap(cref(ci)); + do_unwrap(ref(ci)); + + copy_counter cc; + BOOST_CHECK(cc.count() == 0); + + do_unwrap(cc); + do_unwrap(ref(cc)); + do_unwrap(cref(cc)); + + BOOST_CHECK(cc.count() == 1); + BOOST_CHECK(unwrap_ref(ref(cc)).count() == 1); +} + int test_main(int, char * []) { ref_wrapper::test(1); ref_wrapper::test(1); + unwrap_test(); return 0; } From 8af4250c3ce18aa832d78cdeb5376a985f6da22b Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 7 Mar 2010 12:13:29 +0000 Subject: [PATCH 069/126] Suppress/fix some msvc and gcc compiler warnings ([57494]). [SVN r60291] --- base_from_member_test.cpp | 2 +- binary_test.cpp | 4 ++++ call_traits_test.cpp | 11 +++++++++-- ref_test.cpp | 2 +- value_init_test.cpp | 6 +++--- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/base_from_member_test.cpp b/base_from_member_test.cpp index 89328e4..2598df5 100644 --- a/base_from_member_test.cpp +++ b/base_from_member_test.cpp @@ -281,7 +281,7 @@ object_id_compare::operator () } else { - return a.second->before( *b.second ); + return a.second->before( *b.second ) != 0; } } } diff --git a/binary_test.cpp b/binary_test.cpp index b4041b3..aacfab9 100644 --- a/binary_test.cpp +++ b/binary_test.cpp @@ -11,6 +11,10 @@ #include #include +#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. diff --git a/call_traits_test.cpp b/call_traits_test.cpp index e73ede7..72852c4 100644 --- a/call_traits_test.cpp +++ b/call_traits_test.cpp @@ -21,6 +21,10 @@ #include #include +#ifdef BOOST_MSVC +#pragma warning(disable:4181) // : warning C4181: qualifier applied to reference type; ignored +#endif + // a way prevent warnings for unused variables template inline void unused_variable(const T&) {} @@ -52,7 +56,8 @@ struct contained const_reference const_get()const { return v_; } // pass value: void call(param_type){} - +private: + contained& operator=(const contained&); }; #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION @@ -77,6 +82,8 @@ struct contained reference get() { return v_; } const_reference const_get()const { return v_; } void call(param_type){} +private: + contained& operator=(const contained&); }; #endif @@ -197,7 +204,7 @@ struct comparible_UDT bool operator == (const comparible_UDT& v){ return v.i_ == i_; } }; -int main(int argc, char *argv[ ]) +int main() { call_traits_checker c1; comparible_UDT u; diff --git a/ref_test.cpp b/ref_test.cpp index d4237b4..71481fa 100644 --- a/ref_test.cpp +++ b/ref_test.cpp @@ -70,7 +70,7 @@ struct ref_wrapper struct copy_counter { static int count_; - copy_counter(copy_counter const& other) { + copy_counter(copy_counter const& /*other*/) { ++count_; } copy_counter() {} diff --git a/value_init_test.cpp b/value_init_test.cpp index 67ebad8..98b8860 100644 --- a/value_init_test.cpp +++ b/value_init_test.cpp @@ -29,9 +29,9 @@ // struct POD { - POD () : c(0), i(0), f(0) {} + POD () : f(0), c(0), i(0){} - POD ( char c_, int i_, float f_ ) : c(c_), i(i_), f(f_) {} + 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 << ')' ; } @@ -291,7 +291,7 @@ int test_main(int, char **) { BOOST_CHECK ( test( 0,1234 ) ) ; BOOST_CHECK ( test( 0.0,12.34 ) ) ; - BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78) ) ) ; + BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ; BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ; NonPOD NonPOD_object( std::string("NonPOD_object") ); From e2c98762dbbe40adc60984edc2dbb4a6c11e1963 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 7 Mar 2010 16:22:34 +0000 Subject: [PATCH 070/126] Revert [60052] as it isn't as uncontroversial as I thought. [SVN r60314] --- include/boost/utility/detail/result_of_iterate.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp index 7b09435..8de00b4 100644 --- a/include/boost/utility/detail/result_of_iterate.hpp +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -10,7 +10,7 @@ # error Boost result_of - do not include this file! #endif -#if !defined(BOOST_NO_DECLTYPE) +#if defined(BOOST_HAS_DECLTYPE) // As of N2588, C++0x result_of only supports function call // expressions of the form f(x). This precludes support for member From b3ffef536d449405c644fc1e9a71726771e4625a Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Mon, 5 Apr 2010 19:21:12 +0000 Subject: [PATCH 071/126] Merged std_bitset.cpp (boost::swap test) from trunk r60292 through r60334 and r61065 through r61076, including #3984 fix. [SVN r61077] --- swap/test/std_bitset.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/swap/test/std_bitset.cpp b/swap/test/std_bitset.cpp index d8d69e7..c46b686 100644 --- a/swap/test/std_bitset.cpp +++ b/swap/test/std_bitset.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2008 Joseph Gauterin, Niels Dekker +// Copyright (c) 2008 - 2010 Joseph Gauterin, Niels Dekker // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -17,8 +17,8 @@ int test_main(int, char*[]) { typedef std::bitset<8> bitset_type; - const bitset_type initial_value1 = 1ul; - const bitset_type initial_value2 = 2ul; + const bitset_type initial_value1 = 1; + const bitset_type initial_value2 = 2; bitset_type object1 = initial_value1; bitset_type object2 = initial_value2; From 13da21e7b1a8f13379ec67f70c46acb0eb367d54 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Thu, 8 Apr 2010 21:59:33 +0000 Subject: [PATCH 072/126] Revert changes to result_of. Reopens #862, #1310, #1535. [SVN r61149] --- .../utility/detail/result_of_iterate.hpp | 54 +------- include/boost/utility/result_of.hpp | 17 +-- test/result_of_test.cpp | 131 ++---------------- utility.htm | 8 +- 4 files changed, 16 insertions(+), 194 deletions(-) diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp index 8de00b4..41616c3 100644 --- a/include/boost/utility/detail/result_of_iterate.hpp +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -10,47 +10,6 @@ # error Boost result_of - do not include this file! #endif -#if defined(BOOST_HAS_DECLTYPE) - -// As of N2588, C++0x result_of only supports function call -// expressions of the form f(x). This precludes support for member -// function pointers, which are invoked with expressions of the form -// o->*f(x). This implementation supports both. -template -struct result_of - : mpl::if_< - mpl::or_< is_pointer, is_member_function_pointer > - , detail::result_of_impl< - typename remove_cv::type, - typename remove_cv::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false - > - , detail::result_of_decltype_impl< - F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)) - > - >::type -{}; - -namespace detail { - -# define BOOST_RESULT_OF_STATIC_MEMBERS(z, n, _) \ - static T ## n t ## n; \ - /**/ - -template -class result_of_decltype_impl -{ - static F f; - BOOST_PP_REPEAT(BOOST_PP_ITERATION(), BOOST_RESULT_OF_STATIC_MEMBERS, _) -public: - typedef decltype(f(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),t))) type; -}; - -} // namespace detail - -#else // defined(BOOST_HAS_DECLTYPE) - // CWPro8 requires an argument in a function type specialization #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 0 # define BOOST_RESULT_OF_ARGS void @@ -62,22 +21,11 @@ public: template struct result_of - : mpl::if_< - mpl::or_< is_pointer, is_member_function_pointer > - , boost::detail::result_of_impl< - typename remove_cv::type, - typename remove_cv::type(BOOST_RESULT_OF_ARGS), - (boost::detail::has_result_type::value)> - , boost::detail::result_of_impl< - F, - F(BOOST_RESULT_OF_ARGS), - (boost::detail::has_result_type::value)> >::type { }; + : boost::detail::result_of_impl::value)> {}; #endif #undef BOOST_RESULT_OF_ARGS -#endif // defined(BOOST_HAS_DECLTYPE) - #if BOOST_PP_ITERATION() >= 1 namespace detail { diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp index 78168fa..e35e098 100644 --- a/include/boost/utility/result_of.hpp +++ b/include/boost/utility/result_of.hpp @@ -10,18 +10,13 @@ #define BOOST_RESULT_OF_HPP #include -#include -#include -#include -#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include #ifndef BOOST_RESULT_OF_NUM_ARGS # define BOOST_RESULT_OF_NUM_ARGS 10 @@ -37,7 +32,6 @@ namespace detail { BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) template struct result_of_impl; -template struct result_of_decltype_impl; template struct result_of_void_impl @@ -57,11 +51,6 @@ struct result_of_void_impl typedef R type; }; -// Determine the return type of a function pointer or pointer to member. -template -struct result_of_pointer - : result_of_impl::type, FArgs, false> { }; - template struct result_of_impl { diff --git a/test/result_of_test.cpp b/test/result_of_test.cpp index 73dc757..10f3410 100644 --- a/test/result_of_test.cpp +++ b/test/result_of_test.cpp @@ -11,101 +11,35 @@ #include #include -struct int_result_type -{ - typedef int result_type; - result_type operator()(float); -}; +struct int_result_type { typedef int result_type; }; struct int_result_of { template struct result { typedef int type; }; - result::type operator()(double); - result::type operator()(double) const; - result::type operator()(); - result::type operator()() volatile; }; -struct int_result_type_and_float_result_of_and_char_return +struct int_result_type_and_float_result_of { typedef int result_type; template struct result { typedef float type; }; - char operator()(char); }; template -struct int_result_type_template -{ - typedef int result_type; - result_type operator()(float); -}; +struct int_result_type_template { typedef int result_type; }; template struct int_result_of_template { template struct result; template struct result { typedef int type; }; - typename result(double)>::type operator()(double); - typename result(double)>::type operator()(double) const; - typename result(double)>::type operator()(); - typename result(double)>::type operator()() volatile; }; template -struct int_result_type_and_float_result_of_and_char_return_template +struct int_result_type_and_float_result_of_template { typedef int result_type; template struct result; template struct result { typedef float type; }; - char operator()(char); -}; - -struct result_of_member_function_template -{ - template struct result; - - template struct result { typedef That type; }; - template typename result::type operator()(T); - - template struct result { typedef const That type; }; - template typename result::type operator()(T) const; - - template struct result { typedef volatile That type; }; - template typename result::type operator()(T) volatile; - - template struct result { typedef const volatile That type; }; - template typename result::type operator()(T) const volatile; - - template struct result { typedef That & type; }; - template typename result::type operator()(T &, T); - - template struct result { typedef That const & type; }; - template typename result::type operator()(T const &, T); - - template struct result { typedef That volatile & type; }; - template typename result::type operator()(T volatile &, T); - - template struct result { typedef That const volatile & type; }; - template typename result::type operator()(T const volatile &, T); -}; - -struct no_result_type_or_result_of -{ - int operator()(double); - short operator()(double) const; - unsigned int operator()(); - unsigned short operator()() volatile; - const unsigned short operator()() const volatile; -}; - -template -struct no_result_type_or_result_of_template -{ - int operator()(double); - short operator()(double) const; - unsigned int operator()(); - unsigned short operator()() volatile; - const unsigned short operator()() const volatile; }; struct X {}; @@ -126,37 +60,16 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same(float)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); - BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); - - // Prior to decltype, result_of could not deduce the return type - // nullary function objects unless they exposed a result_type. -#if defined(BOOST_HAS_DECLTYPE) - BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same(void)>::type, int>::value)); - BOOST_STATIC_ASSERT((is_same(void)>::type, int>::value)); -#else - BOOST_STATIC_ASSERT((is_same::type, void>::value)); - BOOST_STATIC_ASSERT((is_same::type, void>::value)); BOOST_STATIC_ASSERT((is_same(void)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same(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_HAS_DECLTYPE) - BOOST_STATIC_ASSERT((is_same::type, char>::value)); - BOOST_STATIC_ASSERT((is_same(char)>::type, char>::value)); -#else - BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same(char)>::type, int>::value)); -#endif - + BOOST_STATIC_ASSERT((is_same(char)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); @@ -168,31 +81,5 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same::type, double>::value)); - BOOST_STATIC_ASSERT((is_same::type, const double>::value)); - BOOST_STATIC_ASSERT((is_same::type, volatile double>::value)); - BOOST_STATIC_ASSERT((is_same::type, const volatile double>::value)); - BOOST_STATIC_ASSERT((is_same::type, int &>::value)); - BOOST_STATIC_ASSERT((is_same::type, int const &>::value)); - BOOST_STATIC_ASSERT((is_same::type, int volatile &>::value)); - BOOST_STATIC_ASSERT((is_same::type, int const volatile &>::value)); - - typedef int (*pf_t)(int); - BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same::type,int>::value)); - -#if defined(BOOST_HAS_DECLTYPE) - BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same::type, unsigned int>::value)); - BOOST_STATIC_ASSERT((is_same::type, short>::value)); - BOOST_STATIC_ASSERT((is_same::type, unsigned short>::value)); - BOOST_STATIC_ASSERT((is_same::type, const unsigned short>::value)); - BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); - BOOST_STATIC_ASSERT((is_same(void)>::type, unsigned int>::value)); - BOOST_STATIC_ASSERT((is_same(double)>::type, short>::value)); - BOOST_STATIC_ASSERT((is_same(void)>::type, unsigned short>::value)); - BOOST_STATIC_ASSERT((is_same(void)>::type, const unsigned short>::value)); -#endif - return 0; } diff --git a/utility.htm b/utility.htm index d4c7205..eff847d 100644 --- a/utility.htm +++ b/utility.htm @@ -154,13 +154,11 @@ void f() { ...,tN). The implementation permits the type F to be a function pointer, function reference, member function pointer, or class - type.

            If your compiler does not support - decltype, then when F is a - class type with a member type result_type, + type. When F is a class type with a + member type result_type, result_of<F(T1, T2, ..., TN)> is - F::result_type. When F - does not contain result_type, + F::result_type. Otherwise, result_of<F(T1, T2, ..., TN)> is F::result<F(T1, T2, ..., TN)>::type when From 2a7e81e07f4a7bc5cf53e44e255cc27f0ed6162b Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Sat, 22 May 2010 05:35:51 +0000 Subject: [PATCH 073/126] Merged revisions 61248 via svnmerge from https://svn.boost.org/svn/boost/trunk ........ r61248 | eric_niebler | 2010-04-13 08:01:11 -0700 (Tue, 13 Apr 2010) | 1 line add tr1_result_of that always behaves as TR1 specifies, fix Boost.TR1's result_of to use tr1_result_of ........ [SVN r62137] --- .../utility/detail/result_of_iterate.hpp | 75 +++++++- include/boost/utility/result_of.hpp | 24 ++- test/result_of_test.cpp | 171 +++++++++++++++++- 3 files changed, 247 insertions(+), 23 deletions(-) diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp index 41616c3..035bf19 100644 --- a/include/boost/utility/detail/result_of_iterate.hpp +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -20,10 +20,69 @@ #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) template -struct result_of - : boost::detail::result_of_impl::value)> {}; +struct tr1_result_of + : mpl::if_< + mpl::or_< is_pointer, is_member_function_pointer > + , boost::detail::tr1_result_of_impl< + typename remove_cv::type, + typename remove_cv::type(BOOST_RESULT_OF_ARGS), + (boost::detail::has_result_type::value)> + , boost::detail::tr1_result_of_impl< + F, + F(BOOST_RESULT_OF_ARGS), + (boost::detail::has_result_type::value)> >::type { }; #endif +#if !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE) + +// As of N2588, C++0x result_of only supports function call +// expressions of the form f(x). This precludes support for member +// function pointers, which are invoked with expressions of the form +// o->*f(x). This implementation supports both. +template +struct result_of + : mpl::if_< + mpl::or_< is_pointer, is_member_function_pointer > + , detail::tr1_result_of_impl< + typename remove_cv::type, + typename remove_cv::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false + > + , detail::cpp0x_result_of_impl< + F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)) + > + >::type +{}; + +namespace detail { + +# define BOOST_RESULT_OF_STATIC_MEMBERS(z, n, _) \ + static T ## n t ## n; \ + /**/ + +template +class cpp0x_result_of_impl +{ + static F f; + BOOST_PP_REPEAT(BOOST_PP_ITERATION(), BOOST_RESULT_OF_STATIC_MEMBERS, _) +public: + typedef decltype(f(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),t))) type; +}; + +} // namespace detail + +#else // defined(BOOST_NO_DECLTYPE) + +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) +template +struct result_of + : tr1_result_of { }; +#endif + +#endif // defined(BOOST_NO_DECLTYPE) + #undef BOOST_RESULT_OF_ARGS #if BOOST_PP_ITERATION() >= 1 @@ -32,14 +91,14 @@ namespace detail { template -struct result_of_impl +struct tr1_result_of_impl { typedef R type; }; template -struct result_of_impl +struct tr1_result_of_impl { typedef R type; }; @@ -47,7 +106,7 @@ struct result_of_impl -struct result_of_impl { @@ -56,7 +115,7 @@ struct result_of_impl -struct result_of_impl @@ -66,7 +125,7 @@ struct result_of_impl -struct result_of_impl @@ -76,7 +135,7 @@ struct result_of_impl -struct result_of_impl diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp index e35e098..9a42fd2 100644 --- a/include/boost/utility/result_of.hpp +++ b/include/boost/utility/result_of.hpp @@ -10,13 +10,18 @@ #define BOOST_RESULT_OF_HPP #include -#include -#include -#include +#include +#include +#include +#include #include #include #include #include +#include +#include +#include +#include #ifndef BOOST_RESULT_OF_NUM_ARGS # define BOOST_RESULT_OF_NUM_ARGS 10 @@ -25,13 +30,15 @@ namespace boost { template struct result_of; +template struct tr1_result_of; // a TR1-style implementation of result_of #if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) namespace detail { BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) -template struct result_of_impl; +template struct tr1_result_of_impl; +template struct cpp0x_result_of_impl; template struct result_of_void_impl @@ -51,8 +58,13 @@ struct result_of_void_impl typedef R type; }; +// Determine the return type of a function pointer or pointer to member. template -struct result_of_impl +struct result_of_pointer + : tr1_result_of_impl::type, FArgs, false> { }; + +template +struct tr1_result_of_impl { typedef typename F::result_type type; }; @@ -68,7 +80,7 @@ struct result_of_nested_result : F::template result {}; template -struct result_of_impl +struct tr1_result_of_impl : mpl::if_, result_of_void_impl, result_of_nested_result >::type diff --git a/test/result_of_test.cpp b/test/result_of_test.cpp index 10f3410..a282a75 100644 --- a/test/result_of_test.cpp +++ b/test/result_of_test.cpp @@ -5,41 +5,109 @@ // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#define BOOST_RESULT_OF_USE_DECLTYPE + // For more information, see http://www.boost.org/libs/utility #include #include #include #include -struct int_result_type { typedef int result_type; }; +struct int_result_type +{ + typedef int result_type; + result_type operator()(float); +}; struct int_result_of { template struct result { typedef int type; }; + result::type operator()(double); + result::type operator()(double) const; + result::type operator()(); + result::type operator()() volatile; }; -struct int_result_type_and_float_result_of +struct int_result_type_and_float_result_of_and_char_return { typedef int result_type; template struct result { typedef float type; }; + char operator()(char); }; template -struct int_result_type_template { typedef int result_type; }; +struct int_result_type_template +{ + typedef int result_type; + result_type operator()(float); +}; template struct int_result_of_template { template struct result; template struct result { typedef int type; }; + typename result(double)>::type operator()(double); + typename result(double)>::type operator()(double) const; + typename result(double)>::type operator()(); + typename result(double)>::type operator()() volatile; }; template -struct int_result_type_and_float_result_of_template +struct int_result_type_and_float_result_of_and_char_return_template { typedef int result_type; template struct result; template struct result { typedef float type; }; + char operator()(char); +}; + +struct result_of_member_function_template +{ + template struct result; + + template struct result { typedef That type; }; + template typename result::type operator()(T); + + template struct result { typedef const That type; }; + template typename result::type operator()(T) const; + + template struct result { typedef volatile That type; }; + template typename result::type operator()(T) volatile; + + template struct result { typedef const volatile That type; }; + template typename result::type operator()(T) const volatile; + + template struct result { typedef That & type; }; + template typename result::type operator()(T &, T); + + template struct result { typedef That const & type; }; + template typename result::type operator()(T const &, T); + + template struct result { typedef That volatile & type; }; + template typename result::type operator()(T volatile &, T); + + template struct result { typedef That const volatile & type; }; + template typename result::type operator()(T const volatile &, T); +}; + +struct no_result_type_or_result_of +{ + int operator()(double); + short operator()(double) const; + unsigned int operator()(); + unsigned short operator()() volatile; + const unsigned short operator()() const volatile; +}; + +template +struct no_result_type_or_result_of_template +{ + int operator()(double); + short operator()(double) const; + unsigned int operator()(); + unsigned short operator()() volatile; + const unsigned short operator()() const volatile; }; struct X {}; @@ -60,16 +128,52 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same::type, void>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same::type, void>::value)); - BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same(float)>::type, int>::value)); BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); - BOOST_STATIC_ASSERT((is_same(void)>::type, void>::value)); BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); + + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); + + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, void>::value)); + + // Prior to decltype, result_of could not deduce the return type + // nullary function objects unless they exposed a result_type. +#if !defined(BOOST_NO_DECLTYPE) + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, int>::value)); +#else + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, void>::value)); BOOST_STATIC_ASSERT((is_same(void)>::type, void>::value)); - BOOST_STATIC_ASSERT((is_same(char)>::type, int>::value)); +#endif + + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(char)>::type, int>::value)); + + // 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_NO_DECLTYPE) + BOOST_STATIC_ASSERT((is_same::type, char>::value)); + BOOST_STATIC_ASSERT((is_same(char)>::type, char>::value)); +#else + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(char)>::type, int>::value)); +#endif + BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); @@ -81,5 +185,54 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + + BOOST_STATIC_ASSERT((is_same::type, double>::value)); + BOOST_STATIC_ASSERT((is_same::type, const double>::value)); + BOOST_STATIC_ASSERT((is_same::type, volatile double>::value)); + BOOST_STATIC_ASSERT((is_same::type, const volatile double>::value)); + BOOST_STATIC_ASSERT((is_same::type, int &>::value)); + BOOST_STATIC_ASSERT((is_same::type, int const &>::value)); + BOOST_STATIC_ASSERT((is_same::type, int volatile &>::value)); + BOOST_STATIC_ASSERT((is_same::type, int const volatile &>::value)); + + BOOST_STATIC_ASSERT((is_same::type, double>::value)); + BOOST_STATIC_ASSERT((is_same::type, const double>::value)); + BOOST_STATIC_ASSERT((is_same::type, volatile double>::value)); + BOOST_STATIC_ASSERT((is_same::type, const volatile double>::value)); + BOOST_STATIC_ASSERT((is_same::type, int &>::value)); + BOOST_STATIC_ASSERT((is_same::type, int const &>::value)); + BOOST_STATIC_ASSERT((is_same::type, int volatile &>::value)); + BOOST_STATIC_ASSERT((is_same::type, int const volatile &>::value)); + + typedef int (*pf_t)(int); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type,int>::value)); + + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type,int>::value)); + +#if !defined(BOOST_NO_DECLTYPE) + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, unsigned int>::value)); + BOOST_STATIC_ASSERT((is_same::type, short>::value)); + BOOST_STATIC_ASSERT((is_same::type, unsigned short>::value)); + BOOST_STATIC_ASSERT((is_same::type, const unsigned short>::value)); + BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, unsigned int>::value)); + BOOST_STATIC_ASSERT((is_same(double)>::type, short>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, unsigned short>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, const unsigned short>::value)); +#endif + return 0; } From ca7db1f3619b0afc9ddeaadbadf42403d6a21361 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Sun, 4 Jul 2010 21:50:38 +0000 Subject: [PATCH 074/126] Merged value_init fixes from trunk, ref #3472, #3869. [SVN r63637] --- include/boost/utility/value_init.hpp | 147 +++++++++++++++++++++++---- 1 file changed, 127 insertions(+), 20 deletions(-) diff --git a/include/boost/utility/value_init.hpp b/include/boost/utility/value_init.hpp index 5aefac9..5de9585 100644 --- a/include/boost/utility/value_init.hpp +++ b/include/boost/utility/value_init.hpp @@ -9,6 +9,8 @@ // 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola // 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola // 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola +// 03 Apr 2010 (Added initialized, suggested by Jeffrey Hellrung, fixing #3472) Niels Dekker +// 30 May 2010 (Made memset call conditional, fixing #3869) Niels Dekker // #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP @@ -20,6 +22,7 @@ // contains. More details on these issues are at libs/utility/value_init.htm #include +#include // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION. #include #include #include @@ -28,10 +31,39 @@ #include #include +#ifdef BOOST_MSVC +#pragma warning(push) +#if _MSC_VER >= 1310 +// It is safe to ignore the following warning from MSVC 7.1 or higher: +// "warning C4351: new behavior: elements of array will be default initialized" +#pragma warning(disable: 4351) +// It is safe to ignore the following MSVC warning, which may pop up when T is +// a const type: "warning C4512: assignment operator could not be generated". +#pragma warning(disable: 4512) +#endif +#endif + +#ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION + // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED + // suggests that a workaround should be applied, because of compiler issues + // regarding value-initialization. + #define BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED +#endif + +// Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND +// switches the value-initialization workaround either on or off. +#ifndef BOOST_DETAIL_VALUE_INIT_WORKAROUND + #ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED + #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 1 + #else + #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0 + #endif +#endif + namespace boost { template -class value_initialized +class initialized { private : struct wrapper @@ -40,6 +72,18 @@ class value_initialized typename #endif remove_const::type data; + + wrapper() + : + data() + { + } + + wrapper(T const & arg) + : + data(arg) + { + } }; mutable @@ -55,30 +99,25 @@ class value_initialized public : - value_initialized() + initialized() { +#if BOOST_DETAIL_VALUE_INIT_WORKAROUND std::memset(&x, 0, sizeof(x)); -#ifdef BOOST_MSVC -#pragma warning(push) -#if _MSC_VER >= 1310 -// When using MSVC 7.1 or higher, the following placement new expression may trigger warning C4345: -// "behavior change: an object of POD type constructed with an initializer of the form () -// will be default-initialized". It is safe to ignore this warning when using value_initialized. -#pragma warning(disable: 4345) -#endif #endif new (wrapper_address()) wrapper(); -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif } - value_initialized(value_initialized const & arg) + initialized(initialized const & arg) { new (wrapper_address()) wrapper( static_cast(*(arg.wrapper_address()))); } - value_initialized & operator=(value_initialized const & arg) + explicit initialized(T const & arg) + { + new (wrapper_address()) wrapper(arg); + } + + initialized & operator=(initialized const & arg) { // Assignment is only allowed when T is non-const. BOOST_STATIC_ASSERT( ! is_const::value ); @@ -86,7 +125,7 @@ class value_initialized return *this; } - ~value_initialized() + ~initialized() { wrapper_address()->wrapper::~wrapper(); } @@ -101,17 +140,81 @@ class value_initialized return wrapper_address()->data; } - void swap(value_initialized & arg) + void swap(initialized & arg) { ::boost::swap( this->data(), arg.data() ); } - operator T const &() const { return this->data(); } + operator T const &() const + { + return wrapper_address()->data; + } - operator T&() { return this->data(); } + operator T&() + { + return wrapper_address()->data; + } } ; +template +T const& get ( initialized const& x ) +{ + return x.data() ; +} + +template +T& get ( initialized& x ) +{ + return x.data() ; +} + +template +void swap ( initialized & lhs, initialized & rhs ) +{ + lhs.swap(rhs) ; +} + +template +class value_initialized +{ + private : + + // initialized does value-initialization by default. + initialized m_data; + + public : + + value_initialized() + : + m_data() + { } + + T const & data() const + { + return m_data.data(); + } + + T& data() + { + return m_data.data(); + } + + void swap(value_initialized & arg) + { + m_data.swap(arg.m_data); + } + + operator T const &() const + { + return m_data; + } + + operator T&() + { + return m_data; + } +} ; template @@ -119,6 +222,7 @@ T const& get ( value_initialized const& x ) { return x.data() ; } + template T& get ( value_initialized& x ) { @@ -138,7 +242,7 @@ class initialized_value_t template operator T() const { - return get( value_initialized() ); + return initialized().data(); } }; @@ -147,5 +251,8 @@ initialized_value_t const initialized_value = {} ; } // namespace boost +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif #endif From b273cd3914ef5ec2775b2b6f90732f2fb659aaec Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Sun, 4 Jul 2010 21:56:44 +0000 Subject: [PATCH 075/126] Merged value_init fixes (extra tests + documentation) from trunk, see #3472, #3869. [SVN r63638] --- initialized_test.cpp | 116 ++++++++++++++++++++++++++ initialized_test_fail1.cpp | 33 ++++++++ initialized_test_fail2.cpp | 37 +++++++++ test/Jamfile.v2 | 4 + value_init.htm | 140 +++++++++++++++++++++++++------- value_init_workaround_test.cpp | 144 +++++++++++++++++++++++++++++++++ 6 files changed, 446 insertions(+), 28 deletions(-) create mode 100644 initialized_test.cpp create mode 100644 initialized_test_fail1.cpp create mode 100644 initialized_test_fail2.cpp create mode 100644 value_init_workaround_test.cpp diff --git a/initialized_test.cpp b/initialized_test.cpp new file mode 100644 index 0000000..9380957 --- /dev/null +++ b/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. +// +// 2 May 2010 (Created) Niels Dekker + +#include +#include + +#include + +namespace +{ + // Typical use case for boost::initialized: A generic class that + // holds a value of type T, which must be initialized by either + // value-initialization or direct-initialization. + template class key_value_pair + { + std::string m_key; + boost::initialized 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 + 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 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("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("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/initialized_test_fail1.cpp b/initialized_test_fail1.cpp new file mode 100644 index 0000000..ffeecab --- /dev/null +++ b/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. Must fail to compile. +// +// Initial: 2 May 2010 + +#include + +namespace +{ + void direct_initialize_from_int() + { + // Okay: initialized supports direct-initialization from T. + boost::initialized direct_initialized_int(1); + } + + void copy_initialize_from_int() + { + // The following line should not compile, because initialized + // was not intended to supports copy-initialization from T. + boost::initialized 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/initialized_test_fail2.cpp b/initialized_test_fail2.cpp new file mode 100644 index 0000000..f3fbf39 --- /dev/null +++ b/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. Must fail to compile. +// +// Initial: 2 May 2010 + +#include + +namespace +{ + void from_value_initialized_to_initialized() + { + boost::value_initialized value_initialized_int; + + // Okay: initialized can be initialized by value_initialized. + boost::initialized initialized_int(value_initialized_int); + } + + void from_initialized_to_value_initialized() + { + boost::initialized initialized_int(13); + + // The following line should not compile, because initialized + // should not be convertible to value_initialized. + boost::value_initialized 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/test/Jamfile.v2 b/test/Jamfile.v2 index 3111cad..d3fc34c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -32,9 +32,13 @@ test-suite utility [ compile result_of_test.cpp ] [ run ../shared_iterator_test.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 ../verify_test.cpp ] ; diff --git a/value_init.htm b/value_init.htm index 57b2313..4ae9177 100644 --- a/value_init.htm +++ b/value_init.htm @@ -33,6 +33,7 @@

            @@ -123,6 +124,12 @@ constructed by the following declaration:

            +The template initialized +offers both value-initialization and direct-initialization. +It is especially useful as a data member type, allowing the very same object +to be either direct-initialized or value-initialized. +

            +

            The const object initialized_value allows value-initializing a variable as follows:

            @@ -216,37 +223,65 @@ it may in practice still be left uninitialized, because of those
             compiler issues! It's hard to make a general statement on what those issues
             are like, because they depend on the compiler you are using, its version number,
             and the type of object you would like to have value-initialized.
            -Compilers usually support value-initialization for built-in types properly.
            -But objects of user-defined types that involve aggregates may in some cases
            -be partially, or even entirely left uninitialized, when they should be value-initialized.
            +All compilers we have tested so far support value-initialization for arithmetic types properly.
            +However, various compilers may leave some types of aggregates uninitialized, when they 
            +should be value-initialized. Value-initialization of objects of a pointer-to-member type may also
            +go wrong on various compilers. 
             

            -We have encountered issues regarding value-initialization on compilers by -Microsoft, Sun, Borland, and GNU. Here is a list of bug reports on those issues: - -
            - -Microsoft Feedback ID 100744 - Value-initialization in new-expression -
            Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005-07-28 -
            - -GCC Bug 30111 - Value-initialization of POD base class doesn't initialize members -
            Reported by Jonathan Wakely, 2006-12-07 -
            - -GCC Bug 33916 - Default constructor fails to initialize array members -
            Reported by Michael Elizabeth Chastain, 2007-10-26 -
            - -Borland Report 51854 - Value-initialization: POD struct should be zero-initialized -
            Reported by Niels Dekker (LKEB, Leiden University Medical Center), 2007-09-11 -
            -
            +At the moment of writing, May 2010, the following reported issues regarding +value-initialization are still there in current compiler releases: +

            +Note that all known GCC issues regarding value-initialization are +fixed with GCC version 4.4, including +GCC Bug 30111. +Clang also has completely implemented value-initialization, as far as we know, +now that Clang Bug 7139 is fixed.

            + New versions of value_initialized (Boost release version 1.35 or higher) -offer a workaround to these issues: value_initialized will now clear -its internal data, prior to constructing the object that it contains. +offer a workaround to these issues: value_initialized may now clear +its internal data, prior to constructing the object that it contains. It will do +so for those compilers that need to have such a workaround, based on the +compiler defect macro BOOST_NO_COMPLETE_VALUE_INITIALIZATION.

            Types and objects

            @@ -340,6 +375,52 @@ the wrapped object is always performed with the get() idiom:

            value_initialized<int> x ;
            get(x) = 1 ; // OK

            value_initialized<int const> cx ;
            get(x) = 1 ; // ERROR: Cannot modify a const object

            value_initialized<int> const x_c ;
            get(x_c) = 1 ; // ERROR: Cannot modify a const object

            value_initialized<int const> const cx_c ;
            get(cx_c) = 1 ; // ERROR: Cannot modify a const object
            +

            template class initialized<T>

            + +
            namespace boost {

            template<class T>
            class initialized
            { +
            public : +
            initialized() : x() {} +
            explicit initialized(T const & arg) : x(arg) {} +
            operator T const &() const; +
            operator T&(); +
            T const &data() const; +
            T& data(); +
            void swap( value_initialized<T>& ); +
            +
            private : +
            unspecified x ; +
            } ; +
            +
            template<class T> +
            T const& get ( initialized<T> const& x ); +
            +
            template<class T> +
            T& get ( initialized<T>& x ); +
            +
            } // namespace boost +
            + +The template class boost::initialized<T> supports both value-initialization +and direct-initialization, so its interface is a superset of the interface +of value_initialized<T>: Its default-constructor +value-initializes the wrapped object just like the default-constructor of +value_initialized<T>, but boost::initialized<T> +also offers an extra explicit +constructor, which direct-initializes the wrapped object by the specified value. +

            + +initialized<T> is especially useful when the wrapped +object must be either value-initialized or direct-initialized, depending on +runtime conditions. For example, initialized<T> could +hold the value of a data member that may be value-initialized by some +constructors, and direct-initialized by others. +On the other hand, if it is known beforehand that the +object must always be value-initialized, value_initialized<T> +may be preferable. And if the object must always be +direct-initialized, none of the two wrappers really needs to be used. +

            + +

            initialized_value

            @@ -399,6 +480,9 @@ Special thanks to Björn Karlsson who carefully edited and completed this do
             

            value_initialized was reimplemented by Fernando Cacciola and Niels Dekker for Boost release version 1.35 (2008), offering a workaround to various compiler issues.

            +

            boost::initialized was very much inspired by feedback from Edward Diener and + Jeffrey Hellrung. +

            initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008).

            Developed by Fernando Cacciola, @@ -407,9 +491,9 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler


            -

            Revised 03 October 2009

            +

            Revised 30 May 2010

            -

            © Copyright Fernando Cacciola, 2002, 2009.

            +

            © Copyright Fernando Cacciola, 2002 - 2010.

            Distributed under the Boost Software License, Version 1.0. See www.boost.org/LICENSE_1_0.txt

            diff --git a/value_init_workaround_test.cpp b/value_init_workaround_test.cpp new file mode 100644 index 0000000..190c267 --- /dev/null +++ b/value_init_workaround_test.cpp @@ -0,0 +1,144 @@ +// 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 workaround. +// +// 17 June 2010 (Created) Niels Dekker + +// Switch the workaround off, before inluding "value_init.hpp". +#define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0 +#include + +#include // For cout. +#include // 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; + } + + template + bool is_value_initialized(const T(& arg)[2]) + { + return + is_value_initialized(arg[0]) && + is_value_initialized(arg[1]); + } + + template + bool is_value_initialized(const boost::value_initialized& 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 + 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()) + + FAILED_TO_VALUE_INITIALIZE(boost::value_initialized()) + + FAILED_TO_VALUE_INITIALIZE(boost::value_initialized()); + +#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 +} From d7cf3628f7d25dde8d03043e7e3be26c7d28de01 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Thu, 15 Jul 2010 21:19:14 +0000 Subject: [PATCH 076/126] Merge some link fixes. [64006] and [64059]. [SVN r64061] --- include/boost/utility/compare_pointees.hpp | 2 +- include/boost/utility/detail/in_place_factory_prefix.hpp | 2 +- include/boost/utility/detail/in_place_factory_suffix.hpp | 2 +- include/boost/utility/in_place_factory.hpp | 2 +- include/boost/utility/typed_in_place_factory.hpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/boost/utility/compare_pointees.hpp b/include/boost/utility/compare_pointees.hpp index e6888a6..7e2515c 100644 --- a/include/boost/utility/compare_pointees.hpp +++ b/include/boost/utility/compare_pointees.hpp @@ -4,7 +4,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// See http://www.boost.org/lib/optional for documentation. +// See http://www.boost.org/libs/optional for documentation. // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com diff --git a/include/boost/utility/detail/in_place_factory_prefix.hpp b/include/boost/utility/detail/in_place_factory_prefix.hpp index 6ce7247..afd76b5 100644 --- a/include/boost/utility/detail/in_place_factory_prefix.hpp +++ b/include/boost/utility/detail/in_place_factory_prefix.hpp @@ -5,7 +5,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// See http://www.boost.org/lib/optional for documentation. +// See http://www.boost.org/libs/optional for documentation. // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com diff --git a/include/boost/utility/detail/in_place_factory_suffix.hpp b/include/boost/utility/detail/in_place_factory_suffix.hpp index b1fc4d3..58f48c7 100644 --- a/include/boost/utility/detail/in_place_factory_suffix.hpp +++ b/include/boost/utility/detail/in_place_factory_suffix.hpp @@ -5,7 +5,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// See http://www.boost.org/lib/optional for documentation. +// See http://www.boost.org/libs/optional for documentation. // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com diff --git a/include/boost/utility/in_place_factory.hpp b/include/boost/utility/in_place_factory.hpp index 16eaacf..f84b003 100644 --- a/include/boost/utility/in_place_factory.hpp +++ b/include/boost/utility/in_place_factory.hpp @@ -5,7 +5,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// See http://www.boost.org/lib/optional for documentation. +// See http://www.boost.org/libs/optional for documentation. // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com diff --git a/include/boost/utility/typed_in_place_factory.hpp b/include/boost/utility/typed_in_place_factory.hpp index 347b7f4..833a346 100644 --- a/include/boost/utility/typed_in_place_factory.hpp +++ b/include/boost/utility/typed_in_place_factory.hpp @@ -5,7 +5,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// See http://www.boost.org/lib/optional for documentation. +// See http://www.boost.org/libs/optional for documentation. // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com From b7d4b6edae7a04e02af3cd7584d3875f17cf8276 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Wed, 11 Aug 2010 18:15:46 +0000 Subject: [PATCH 077/126] merged [64695] and [64696] result_of docs from trunk [SVN r64745] --- utility.htm | 94 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 17 deletions(-) diff --git a/utility.htm b/utility.htm index eff847d..3ac5d42 100644 --- a/utility.htm +++ b/utility.htm @@ -151,35 +151,95 @@ void f() { result_of<F(T1, T2, ..., TN)>::type defines the result type of the expression f(t1, t2, - ...,tN). The implementation permits + ...,tN). This implementation permits the type F to be a function pointer, function reference, member function pointer, or class - type. When F is a class type with a + type. By default, N may be any value between 0 and + 10. To change the upper limit, define the macro + BOOST_RESULT_OF_NUM_ARGS to the maximum + value for N. Class template result_of + resides in the header <boost/utility/result_of.hpp>.

            + +

            If your compiler supports decltype, + then you can enable automatic result type deduction by + defining the macro BOOST_RESULT_OF_USE_DECLTYPE, + as in the following example.

            + +
            +
            #define BOOST_RESULT_OF_USE_DECLTYPE
            +#include <boost/utility/result_of.hpp>
            +
            +struct functor {
            +    template<class T>
            +    T operator()(T x)
            +    {
            +        return x;
            +    }
            +};
            +
            +typedef boost::result_of<
            +    functor(int)
            +>::type type;
            +
            + +

            If decltype is not enabled, + then automatic result type deduction of function + objects is not possible. Instead, result_of + uses the following protocol to allow the programmer to + specify a type. When F is a class type with a member type result_type, result_of<F(T1, T2, ..., TN)> is - F::result_type. Otherwise, + F::result_type. When F does + not contain result_type, result_of<F(T1, T2, ..., TN)> is F::result<F(T1, T2, ..., TN)>::type when N > 0 or void - when N = 0. For additional - information about result_of, see the - C++ Library Technical Report, N1836, - or, for motivation and design rationale, the result_of proposal.

            + when N = 0. Note that it is the + responsibility of the programmer to ensure that + function objects accurately advertise their result + type via this protocol, as in the following + example.

            -

            Class template result_of resides in - the header <boost/utility/result_of.hpp>. By - default, N may be any value between 0 and - 10. To change the upper limit, define the macro - BOOST_RESULT_OF_NUM_ARGS to the maximum - value for N.

            +
            +
            struct functor {
            +    template<class> struct result;
            +
            +    template<class F, class T>
            +    struct result<F(T)> {
            +        typedef T type;
            +    };
            +
            +    template<class T>
            +    T operator()(T x)
            +    {
            +        return x;
            +    }
            +};
            +
            +typedef boost::result_of<
            +    functor(int)
            +>::type type;
            +
            -

            This implementation of result_of requires class template partial specialization, the ability to parse function types properly, and support for SFINAE. If result_of is not supported by your compiler, including the header boost/utility/result_of.hpp will define the macro BOOST_NO_RESULT_OF. Contributed by Doug Gregor.

            +

            This implementation of result_of + requires class template partial specialization, the + ability to parse function types properly, and support + for SFINAE. If result_of is not supported + by your compiler, including the header + boost/utility/result_of.hpp will + define the macro BOOST_NO_RESULT_OF.

            + +

            For additional information + about result_of, see the C++ Library + Technical Report, + N1836, + or, for motivation and design rationale, + the result_of proposal.

            + Contributed by Doug Gregor.

            Class templates for the Base-from-Member Idiom

            See separate documentation.

            From 86791caf0e3a4ba047232ac6098c022de6e281e0 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Tue, 15 Feb 2011 14:54:16 +0000 Subject: [PATCH 078/126] Merge trunk BOOST_ASSERT_MSG additions [SVN r68912] --- assert.html | 74 ++++++++++++++++++++++++++++++++++++++++++------- assert_test.cpp | 44 +++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 10 deletions(-) diff --git a/assert.html b/assert.html index a970cef..5f3f6e7 100644 --- a/assert.html +++ b/assert.html @@ -17,36 +17,89 @@
           
          +

          + BOOST_ASSERT
          + BOOST_ASSERT_MSG
          + BOOST_VERIFY

          + +

          BOOST_ASSERT

          The header <boost/assert.hpp> defines the macro BOOST_ASSERT, which is similar to the standard assert macro defined in <cassert>. - The macro is intended to be used in Boost libraries. + The macro is intended to be used in both Boost libraries and user + code.

          By default, BOOST_ASSERT(expr) is equivalent to assert(expr).

          -

          When the macro BOOST_DISABLE_ASSERTS is defined when <boost/assert.hpp> +

          If the macro BOOST_DISABLE_ASSERTS is defined when <boost/assert.hpp> is included, BOOST_ASSERT(expr) is defined as ((void)0). This allows users to selectively disable BOOST_ASSERT without affecting the definition of the standard assert.

          -

          When the macro BOOST_ENABLE_ASSERT_HANDLER is defined when <boost/assert.hpp> +

          If the macro BOOST_ENABLE_ASSERT_HANDLER is defined when <boost/assert.hpp> is included, BOOST_ASSERT(expr) evaluates expr and, if the result is false, evaluates the expression

          +

          ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)

          +

          assertion_failed is declared in <boost/assert.hpp> as

          -
          -namespace boost
          +		
          +
          namespace boost
           {
          -
          -void assertion_failed(char const * expr, char const * function, char const * file, long line);
          -
          +  void assertion_failed(char const * expr, char const * function, char const * file, long line);
           }
           
          +

          but it is never defined. The user is expected to supply an appropriate definition.

          As is the case with <cassert>, <boost/assert.hpp> can be included multiple times in a single translation unit. BOOST_ASSERT will be redefined each time as specified above.

          + +

          BOOST_ASSERT_MSG

          +

          + The header <boost/assert.hpp> defines the macro BOOST_ASSERT_MSG, + which is similar to the standard assert macro defined in <cassert>, + but with an additional macro parameter supplying an error message. The macro is intended to be used in both Boost libraries + and user code. +

          +

          BOOST_ASSERT_MSG(expr, msg) is equivalent to + ((void)0) if BOOST_DISABLE_ASSERTS or NDEBUG are + defined or expr evaluates to true. If those + macros and BOOST_ENABLE_ASSERT_HANDLER are not + defined, and expr evaluates to false, an error + message that includes #expr, msg, BOOST_CURRENT_FUNCTION, + __FILE__, and __LINE__ is sent to output stream + BOOST_ASSERT_MSG_OSTREAM + and std::abort() is called.

          +

          BOOST_ASSERT_MSG_OSTREAM defines the output stream. It defaults to std::cerr. + Integrated development environments (IDE's) like Microsoft Visual Studio + may produce easier to understand output if messages go to a different + stream, such as std::cout. Users may define BOOST_ASSERT_MSG_OSTREAM before including <boost/assert.hpp> + to specify a different output stream. 

          +

          If the macro BOOST_ENABLE_ASSERT_HANDLER is defined when <boost/assert.hpp> + is included, instead of sending a error message to an output + stream, this expression is evaluated

          +
          +

          ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, + __FILE__, __LINE__)

          +
          +

          assertion_failed_msg is declared in <boost/assert.hpp> + as

          +
          +
          namespace boost
          +{
          +  void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line);
          +}
          +
          +
          +

          but it is never defined. The user is expected to supply an appropriate + definition.

          +

          As is the case with <cassert>, <boost/assert.hpp> + can be included multiple times in a single translation unit. BOOST_ASSERT_MSG + will be redefined each time as specified above.

          + +

          BOOST_VERIFY

          <boost/assert.hpp> also defines the macro BOOST_VERIFY. It has exactly the same behavior as BOOST_ASSERT, except that the expression that is passed to BOOST_VERIFY is always @@ -54,8 +107,9 @@ void assertion_failed(char const * expr, char const * function, char const * fil effects; it can also help suppress warnings about unused variables when the only use of the variable is inside an assertion.


          - Copyright © 2002, 2007 by Peter Dimov. Distributed under the Boost Software + Copyright © 2002, 2007 by Peter Dimov.  Copyright © 2011 + by Beman Dawes. 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.

          - + \ No newline at end of file diff --git a/assert_test.cpp b/assert_test.cpp index 693adc4..26051ac 100644 --- a/assert_test.cpp +++ b/assert_test.cpp @@ -2,6 +2,7 @@ // assert_test.cpp - a test for boost/assert.hpp // // Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// Copyright (2) Beman Dawes 2011 // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -20,6 +21,11 @@ void test_default() BOOST_ASSERT(x); BOOST_ASSERT(x == 1); BOOST_ASSERT(&x); + + BOOST_ASSERT_MSG(1, "msg"); + BOOST_ASSERT_MSG(x, "msg"); + BOOST_ASSERT_MSG(x == 1, "msg"); + BOOST_ASSERT_MSG(&x, "msg"); } #define BOOST_DISABLE_ASSERTS @@ -34,13 +40,23 @@ void test_disabled() BOOST_ASSERT(x == 1); BOOST_ASSERT(&x); + BOOST_ASSERT_MSG(1, "msg"); + BOOST_ASSERT_MSG(x, "msg"); + BOOST_ASSERT_MSG(x == 1, "msg"); + BOOST_ASSERT_MSG(&x, "msg"); + BOOST_ASSERT(0); BOOST_ASSERT(!x); BOOST_ASSERT(x == 0); + BOOST_ASSERT_MSG(0, "msg"); + BOOST_ASSERT_MSG(!x, "msg"); + BOOST_ASSERT_MSG(x == 0, "msg"); + void * p = 0; BOOST_ASSERT(p); + BOOST_ASSERT_MSG(p, "msg"); // supress warnings p = &x; @@ -55,6 +71,7 @@ void test_disabled() #include int handler_invoked = 0; +int msg_handler_invoked = 0; void boost::assertion_failed(char const * expr, char const * function, char const * file, long line) { @@ -66,11 +83,24 @@ void boost::assertion_failed(char const * expr, char const * function, char cons ++handler_invoked; } +void boost::assertion_failed_msg(char const * expr, char const * msg, char const * function, + char const * file, long line) +{ +#if !defined(BOOST_NO_STDC_NAMESPACE) + using std::printf; +#endif + + printf("Expression: %s Message: %s\nFunction: %s\nFile: %s\nLine: %ld\n\n", + expr, msg, function, file, line); + ++msg_handler_invoked; +} + struct X { static void f() { BOOST_ASSERT(0); + BOOST_ASSERT_MSG(0, "msg f()"); } }; @@ -83,21 +113,35 @@ void test_handler() BOOST_ASSERT(x == 1); BOOST_ASSERT(&x); + BOOST_ASSERT_MSG(1, "msg2"); + BOOST_ASSERT_MSG(x, "msg3"); + BOOST_ASSERT_MSG(x == 1, "msg4"); + BOOST_ASSERT_MSG(&x, "msg5"); + BOOST_ASSERT(0); BOOST_ASSERT(!x); BOOST_ASSERT(x == 0); + BOOST_ASSERT_MSG(0,"msg 0"); + BOOST_ASSERT_MSG(!x, "msg !x"); + BOOST_ASSERT_MSG(x == 0, "msg x == 0"); + void * p = 0; BOOST_ASSERT(p); + BOOST_ASSERT_MSG(p, "msg p"); X::f(); BOOST_ASSERT(handler_invoked == 5); BOOST_TEST(handler_invoked == 5); + + BOOST_ASSERT_MSG(msg_handler_invoked == 5, "msg_handler_invoked count is wrong"); + BOOST_TEST(msg_handler_invoked == 5); } #undef BOOST_ENABLE_ASSERT_HANDLER +#undef BOOST_ENABLE_ASSERT_MSG_HANDLER int main() { From d01eb82fb711665d498fd522a6c3b09e871b7782 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Tue, 15 Feb 2011 16:18:51 +0000 Subject: [PATCH 079/126] Repair failed merge [SVN r68914] --- include/boost/assert.hpp | 89 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 4 deletions(-) diff --git a/include/boost/assert.hpp b/include/boost/assert.hpp index c227f17..174f084 100644 --- a/include/boost/assert.hpp +++ b/include/boost/assert.hpp @@ -1,8 +1,11 @@ // // boost/assert.hpp - BOOST_ASSERT(expr) +// BOOST_ASSERT_MSG(expr, msg) +// BOOST_VERIFY(expr) // // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. // Copyright (c) 2007 Peter Dimov +// Copyright (c) Beman Dawes 2011 // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,6 +16,16 @@ // See http://www.boost.org/libs/utility/assert.html for documentation. // +// +// Stop inspect complaining about use of 'assert': +// +// boostinspect:naassert_macro +// + +//--------------------------------------------------------------------------------------// +// BOOST_ASSERT // +//--------------------------------------------------------------------------------------// + #undef BOOST_ASSERT #if defined(BOOST_DISABLE_ASSERTS) @@ -25,18 +38,86 @@ namespace boost { - -void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined - + void assertion_failed(char const * expr, + char const * function, char const * file, long line); // user defined } // namespace boost -#define BOOST_ASSERT(expr) ((expr)? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) +#define BOOST_ASSERT(expr) ((expr) \ + ? ((void)0) \ + : ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) #else # include // .h to support old libraries w/o - effect is the same # define BOOST_ASSERT(expr) assert(expr) #endif +//--------------------------------------------------------------------------------------// +// BOOST_ASSERT_MSG // +//--------------------------------------------------------------------------------------// + +# undef BOOST_ASSERT_MSG + +#if defined(BOOST_DISABLE_ASSERTS) || defined(NDEBUG) + + #define BOOST_ASSERT_MSG(expr, msg) ((void)0) + +#elif defined(BOOST_ENABLE_ASSERT_HANDLER) + + #include + + namespace boost + { + void assertion_failed_msg(char const * expr, char const * msg, + char const * function, char const * file, long line); // user defined + } // namespace boost + + #define BOOST_ASSERT_MSG(expr, msg) ((expr) \ + ? ((void)0) \ + : ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) + +#else + #ifndef BOOST_ASSERT_HPP + #define BOOST_ASSERT_HPP + #include + #include + #include + + // IDE's like Visual Studio perform better if output goes to std::cout or + // some other stream, so allow user to configure output stream: + #ifndef BOOST_ASSERT_MSG_OSTREAM + # define BOOST_ASSERT_MSG_OSTREAM std::cerr + #endif + + namespace boost + { + namespace assertion + { + namespace detail + { + inline void assertion_failed_msg(char const * expr, char const * msg, char const * function, + char const * file, long line) + { + BOOST_ASSERT_MSG_OSTREAM + << "***** Internal Program Error - assertion (" << expr << ") failed in " + << function << ":\n" + << file << '(' << line << "): " << msg << std::endl; + std::abort(); + } + } // detail + } // assertion + } // detail + #endif + + #define BOOST_ASSERT_MSG(expr, msg) ((expr) \ + ? ((void)0) \ + : ::boost::assertion::detail::assertion_failed_msg(#expr, msg, \ + BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) +#endif + +//--------------------------------------------------------------------------------------// +// BOOST_VERIFY // +//--------------------------------------------------------------------------------------// + #undef BOOST_VERIFY #if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) ) From 1aa48ea6981d4c1fc3e46f2e203a04d2549a2f8c Mon Sep 17 00:00:00 2001 From: Daniel James Date: Thu, 24 Mar 2011 21:01:36 +0000 Subject: [PATCH 080/126] Utility/operators: [67268] Limit warning suppression to old versions of VC++, fixes #4432. [SVN r70522] --- include/boost/operators.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/boost/operators.hpp b/include/boost/operators.hpp index 4b47ba4..b524cee 100644 --- a/include/boost/operators.hpp +++ b/include/boost/operators.hpp @@ -8,6 +8,8 @@ // See http://www.boost.org/libs/utility/operators.htm for documentation. // Revision History +// 16 Dec 10 Limit warning suppression for 4284 to older versions of VC++ +// (Matthew Bradbury, fixes #4432) // 07 Aug 08 Added "euclidean" spelling. (Daniel Frey) // 03 Apr 08 Make sure "convertible to bool" is sufficient // for T::operator<, etc. (Daniel Frey) @@ -88,7 +90,7 @@ # pragma set woff 1234 #endif -#if defined(BOOST_MSVC) +#if BOOST_WORKAROUND(BOOST_MSVC, < 1600) # pragma warning( disable : 4284 ) // complaint about return type of #endif // operator-> not begin a UDT From e36315c15188ff2717b8bf9859634860922a453d Mon Sep 17 00:00:00 2001 From: Jeremiah Willcock Date: Tue, 23 Aug 2011 18:26:46 +0000 Subject: [PATCH 081/126] Merged in BGL, enable_if, and related changes from trunk: r67035, r57559, r72837, r73010, r73026, r72960, r73425, r73424, r73009, r73998, r73997, r73006, r73630, r73631, r73999, r73422, r73423, r73996, r71221 [SVN r74023] --- enable_if.html | 111 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 93 insertions(+), 18 deletions(-) diff --git a/enable_if.html b/enable_if.html index a17a290..8ea33bb 100644 --- a/enable_if.html +++ b/enable_if.html @@ -21,6 +21,7 @@

          Copyright 2003 Jaakko Järvi, Jeremiah Willcock, Andrew Lumsdaine.
          +Copyright 2011 Matt Calabrese.

          @@ -81,7 +82,7 @@ definitions to find this out. Instantiating the latter definition with
          int::result_type negate(const int&);
           
           
          -where the return type is invalid. If this was an error, adding an unrelated function template +where the return type is invalid. If this were an error, adding an unrelated function template (that was never called) could break otherwise valid code. Due to the SFINAE principle the above example is not, however, erroneous. The latter definition of negate is simply removed from the overload resolution set.
          @@ -154,6 +155,7 @@ typename enable_if<boost::is_arithmetic<T>, T>::type foo(T t) { return t; }
          +

          3  Using enable_if

          @@ -162,8 +164,19 @@ foo(T t) { return t; } The enable_if templates are defined in boost/utility/enable_if.hpp, which is included by boost/utility.hpp.

          -The enable_if template can be used either as the return type, or as an -extra argument. For example, the foo function in the previous section could also be written +With respect to function templates, enable_if can be used in multiple different ways: + +
            +
          • As the return type of an instantiatied function +
          • As an extra parameter of an instantiated function +
          • As an extra template parameter (useful only in a compiler that supports C++0x default +arguments for function template parameters, see Enabling function +templates in C++0x for details) +
          + +In the previous section, the return type form of enable_if was shown. As an example +of using the form of enable_if that works via an extra function parameter, the +foo function in the previous section could also be written as:
          template <class T>
           T foo(T t, typename enable_if<boost::is_arithmetic<T> >::type* dummy = 0); 
          @@ -173,18 +186,80 @@ a default value to keep the parameter hidden from client code.
           Note that the second template argument was not given to enable_if, as the default 
           void gives the desired behavior.

          -Whether to write the enabler as an argument or within the return type is -largely a matter of taste, but for certain functions, only one -alternative is possible: +Which way to write the enabler is largely a matter of taste, but for certain functions, only a +subset of the options is possible:
          • -Operators have a fixed number of arguments, thus enable_if must be used in the return type. -
          • Constructors and destructors do not have a return type; an extra argument is the only option. -
          • There does not seem to be a way to specify an enabler for a conversion operator. Converting constructors, -however, can have enablers as extra default arguments. +Many operators have a fixed number of arguments, thus enable_if must be used either in the +return type or in an extra template parameter. +
          • Functions that have a variadic parameter list must use either the return type form or an extra +template parameter. +
          • Constructors do not have a return type so you must use either an extra function parameter or an +extra template parameter. +
          • Constructors that have a variadic parameter list must an extra template parameter. +
          • Conversion operators can only be written with an extra template parameter.
          + + + +

          3.1  Enabling function templates in C++0x

          + +In a compiler which supports C++0x default arguments for function template parameters, you can +enable and disable function templates by adding an additional template parameter. This approach +works in all situations where you would use either the return type form of enable_if or +the function parameter form, including operators, constructors, variadic function templates, and +even overloaded conversion operations. + +As an example: + +
          #include <boost/type_traits/is_arithmetic.hpp>
          +#include <boost/type_traits/is_pointer.hpp>
          +#include <boost/utility/enable_if.hpp>
          +
          +class test
          +{
          +public:
          +  // A constructor that works for any argument list of size 10
          +  template< class... T
          +          , typename boost::enable_if_c< sizeof...( T ) == 10, int >::type = 0
          +          >
          +  test( T&&... );
          +
          +  // A conversion operation that can convert to any arithmetic type
          +  template< class T
          +          , typename boost::enable_if< boost::is_arithmetic< T >, int >::type = 0
          +          >
          +  operator T() const;
          +
          +  // A conversion operation that can convert to any pointer type
          +  template< class T
          +          , typename boost::enable_if< boost::is_pointer< T >, int >::type = 0
          +          >
          +  operator T() const;
          +};
          +
          +int main()
          +{
          +  // Works
          +  test test_( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 );
          +
          +  // Fails as expected
          +  test fail_construction( 1, 2, 3, 4, 5 );
          +
          +  // Works by calling the conversion operator enabled for arithmetic types
          +  int arithmetic_object = test_;
          +
          +  // Works by calling the conversion operator enabled for pointer types
          +  int* pointer_object = test_;
          +
          +  // Fails as expected
          +  struct {} fail_conversion = test_;
          +}
          +
          +
          + -

          3.1  Enabling template class specializations

          +

          3.2  Enabling template class specializations

          Class template specializations can be enabled or disabled with enable_if. @@ -210,7 +285,7 @@ is the correct value.

          -

          3.2  Overlapping enabler conditions

          +

          3.3  Overlapping enabler conditions

          Once the compiler has examined the enabling conditions and included the @@ -239,7 +314,7 @@ partial specializations as well.

          -

          3.3  Lazy enable_if

          +

          3.4  Lazy enable_if

          In some cases it is necessary to avoid instantiating part of a @@ -285,7 +360,7 @@ above example, is_multipliable<T, U>::value defines when
          -

          3.4  Compiler workarounds

          +

          3.5  Compiler workarounds

          Some compilers flag functions as ambiguous if the only distinguishing factor is a different @@ -367,9 +442,9 @@ David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2002.
          -

          Copyright Jaakko Järvi, Jeremiah Willcock and Andrew Lumsdaine
          -{jajarvi|jewillco|lums}@osl.iu.edu
          -Indiana University
          +

          Copyright Jaakko Järvi*, Jeremiah Willcock*, Andrew Lumsdaine*, Matt Calabrese
          +{jajarvi|jewillco|lums}@osl.iu.edu, rivorus@gmail.com
          +*Indiana University
          Open Systems Lab
          Use, modification and distribution are subject to the Boost Software License, Version 1.0. @@ -386,4 +461,4 @@ or copy at HEVEA. - \ No newline at end of file + From c9d56eed6e6007722cbd20c3cd3d9f1bdd8d86fc Mon Sep 17 00:00:00 2001 From: John Maddock Date: Mon, 10 Oct 2011 11:50:55 +0000 Subject: [PATCH 082/126] Merge Boost.Config changes from Trunk - numerous small bug fixes plus a new Cray C++ config. Fixes #5607. Fixes #5941. Fixes #5878. [SVN r74889] --- include/boost/current_function.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/current_function.hpp b/include/boost/current_function.hpp index aa5756e..cb36e35 100644 --- a/include/boost/current_function.hpp +++ b/include/boost/current_function.hpp @@ -28,7 +28,7 @@ namespace detail inline void current_function_helper() { -#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) +#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) # define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ @@ -65,3 +65,4 @@ inline void current_function_helper() } // namespace boost #endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED + From 87b3643647f380b8cb8e44c2a8c00eae57062d5c Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Tue, 31 Jan 2012 02:30:03 +0000 Subject: [PATCH 083/126] Merged doc updates and fix for #5098 from trunk [SVN r76804] --- .../utility/detail/result_of_iterate.hpp | 20 +++++++------------ include/boost/utility/result_of.hpp | 3 +++ test/result_of_test.cpp | 18 +++++++++++++++++ utility.htm | 14 +++++++++++++ 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp index 035bf19..1ec857a 100644 --- a/include/boost/utility/detail/result_of_iterate.hpp +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -35,10 +35,7 @@ struct tr1_result_of #if !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE) -// As of N2588, C++0x result_of only supports function call -// expressions of the form f(x). This precludes support for member -// function pointers, which are invoked with expressions of the form -// o->*f(x). This implementation supports both. +// Uses declval following N3225 20.7.7.6 when F is not a pointer. template struct result_of @@ -56,18 +53,15 @@ struct result_of namespace detail { -# define BOOST_RESULT_OF_STATIC_MEMBERS(z, n, _) \ - static T ## n t ## n; \ - /**/ - template -class cpp0x_result_of_impl +struct cpp0x_result_of_impl { - static F f; - BOOST_PP_REPEAT(BOOST_PP_ITERATION(), BOOST_RESULT_OF_STATIC_MEMBERS, _) -public: - typedef decltype(f(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),t))) type; + typedef decltype( + boost::declval()( + BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), declval() BOOST_PP_INTERCEPT) + ) + ) type; }; } // namespace detail diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp index 9a42fd2..41cc176 100644 --- a/include/boost/utility/result_of.hpp +++ b/include/boost/utility/result_of.hpp @@ -13,7 +13,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -22,6 +24,7 @@ #include #include #include +#include #ifndef BOOST_RESULT_OF_NUM_ARGS # define BOOST_RESULT_OF_NUM_ARGS 10 diff --git a/test/result_of_test.cpp b/test/result_of_test.cpp index a282a75..39f6c3b 100644 --- a/test/result_of_test.cpp +++ b/test/result_of_test.cpp @@ -98,6 +98,11 @@ struct no_result_type_or_result_of unsigned int operator()(); unsigned short operator()() volatile; const unsigned short operator()() const volatile; +#if !defined(BOOST_NO_RVALUE_REFERENCES) + short operator()(int&&); + int operator()(int&); + long operator()(int const&); +#endif }; template @@ -108,6 +113,11 @@ struct no_result_type_or_result_of_template unsigned int operator()(); unsigned short operator()() volatile; const unsigned short operator()() const volatile; +#if !defined(BOOST_NO_RVALUE_REFERENCES) + short operator()(int&&); + int operator()(int&); + long operator()(int const&); +#endif }; struct X {}; @@ -232,6 +242,14 @@ int main() BOOST_STATIC_ASSERT((is_same(double)>::type, short>::value)); BOOST_STATIC_ASSERT((is_same(void)>::type, unsigned short>::value)); BOOST_STATIC_ASSERT((is_same(void)>::type, const unsigned short>::value)); +#if !defined(BOOST_NO_RVALUE_REFERENCES) + BOOST_STATIC_ASSERT((is_same::type, short>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, long>::value)); + BOOST_STATIC_ASSERT((is_same(int&&)>::type, short>::value)); + BOOST_STATIC_ASSERT((is_same(int&)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(int const&)>::type, long>::value)); +#endif #endif return 0; diff --git a/utility.htm b/utility.htm index 3ac5d42..e2cbfd7 100644 --- a/utility.htm +++ b/utility.htm @@ -224,6 +224,20 @@ typedef boost::result_of< >::type type;

          +

          In a future + release, BOOST_RESULT_OF_USE_DECLTYPE + may be enabled by default on compilers that + support decltype, so if you use the above + protocol please take care to ensure that + the result_type + and result<> members accurately + represent the result type. If you wish to continue to + use the protocol on compilers that + support decltype, + use boost::tr1_result_of, which is also + defined + in <boost/utility/result_of.hpp>.

          +

          This implementation of result_of requires class template partial specialization, the From 7aa68731b4c4e872eb28b145db6d6b6ccd4bf916 Mon Sep 17 00:00:00 2001 From: "Vicente J. Botet Escriba" Date: Sun, 1 Apr 2012 20:16:57 +0000 Subject: [PATCH 084/126] Utility: Fix #6570 [SVN r77699] --- doc/declval.qbk | 13 +++++++++++- doc/html/declval.html | 35 +++++++++++++++++++++++-------- include/boost/utility/declval.hpp | 9 ++++++-- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/doc/declval.qbk b/doc/declval.qbk index 67e82d2..10080aa 100644 --- a/doc/declval.qbk +++ b/doc/declval.qbk @@ -14,7 +14,7 @@ [authors [Botet Escriba, Vicente J.]] [copyright 2008 Howard Hinnant] [copyright 2008 Beman Dawes] - [copyright 2009-2010 Vicente J. Botet Escriba] + [copyright 2009-2012 Vicente J. Botet Escriba] [license Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -100,5 +100,16 @@ Declares a function template convert which only participats in overloading if th [endsect] +[/===============] +[section History] +[/===============] +[heading boost 1.50] + +Fixes: + +* [@http://svn.boost.org/trac/boost/ticket/6570 #6570] Adding noexcept to boost::declval. + + +[endsect] diff --git a/doc/html/declval.html b/doc/html/declval.html index a2c5a01..dff3a83 100644 --- a/doc/html/declval.html +++ b/doc/html/declval.html @@ -3,7 +3,7 @@ Declval - + @@ -17,7 +17,7 @@


          -
          +

          @@ -35,9 +35,9 @@

          -
          +
          -

          +

          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)

          @@ -49,10 +49,11 @@

          Table of Contents

          Overview
          -
          Reference
          +
          Reference
          +
          History
          -
          +
          @@ -112,9 +113,9 @@ function is expected to be part of the daily tool-box of the C++0x programmer.

          -
          +

          #include <boost/utility/declval.hpp> @@ -152,9 +153,25 @@ if the type From can be explicitly converted to type To.

          +
          + +

          + + boost 1.50 +

          +

          + Fixes: +

          +
          • + #6570 + Adding noexcept to boost::declval. +
          +
          - +

          Last revised: September 16, 2010 at 16:19:10 GMT

          Last revised: April 01, 2012 at 20:13:37 GMT


          diff --git a/include/boost/utility/declval.hpp b/include/boost/utility/declval.hpp index 41ec3dc..d74610c 100644 --- a/include/boost/utility/declval.hpp +++ b/include/boost/utility/declval.hpp @@ -13,6 +13,7 @@ //----------------------------------------------------------------------------// #include +//#include //----------------------------------------------------------------------------// // // @@ -36,9 +37,13 @@ namespace boost { +//#if !defined(BOOST_NO_RVALUE_REFERENCES) template - typename add_rvalue_reference::type declval(); //noexcept; // as unevaluated operand - + typename add_rvalue_reference::type declval() BOOST_NOEXCEPT; // as unevaluated operand +//#else +// template +// typename add_lvalue_reference::type declval() BOOST_NOEXCEPT; // as unevaluated operand +//#endif } // namespace boost #endif // BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP From 88e7d8627096e351c00014353547e0184b01e0da Mon Sep 17 00:00:00 2001 From: Lorenzo Caminiti Date: Sat, 26 May 2012 21:17:03 +0000 Subject: [PATCH 085/126] Marked some expected failures for release regression test compilers. Renamed a local function internal template parameter from Bn to Bindn (because B0 is defined as a macro from a Linux header to represent a baudrate). Added itdentity_type.hpp to utility.hpp. Made reference data members of LocalFunction Addable static (because they are not set in the constructor). [SVN r78659] --- include/boost/utility.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/utility.hpp b/include/boost/utility.hpp index b909f29..82177c8 100644 --- a/include/boost/utility.hpp +++ b/include/boost/utility.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include From 2fc827ad236445aeb68ef7e3960034f8d92be806 Mon Sep 17 00:00:00 2001 From: "Vicente J. Botet Escriba" Date: Mon, 28 May 2012 19:00:53 +0000 Subject: [PATCH 086/126] Utility/declval: update history. [SVN r78730] --- doc/declval.qbk | 16 ++++++++-------- doc/html/declval.html | 22 +++++++++------------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/doc/declval.qbk b/doc/declval.qbk index 10080aa..7bf5cb5 100644 --- a/doc/declval.qbk +++ b/doc/declval.qbk @@ -1,7 +1,6 @@ [/ / Copyright (c) 2008 Howard Hinnant - / Copyright (c) 2008 Beman Dawes - / Copyright (c) 2009-20010 Vicente J. Botet Escriba + / Copyright (c) 2009-20012 Vicente J. Botet Escriba / / Distributed under the Boost Software License, Version 1.0. (See accompanying / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,10 +9,8 @@ [article Declval [quickbook 1.5] [authors [Hinnant, Howard]] - [authors [Dawes, Beman]] [authors [Botet Escriba, Vicente J.]] [copyright 2008 Howard Hinnant] - [copyright 2008 Beman Dawes] [copyright 2009-2012 Vicente J. Botet Escriba] [license Distributed under the Boost Software License, Version 1.0. @@ -59,9 +56,9 @@ T is an lvalue-reference, otherwise an rvalue. To extend the domain of this func typename std::add_rvalue_reference::type declval(); // not used which ensures that we can also use cv void as template parameter. The careful reader might have noticed that `declval()` -already exists under the name create() as part of the definition of the semantics of the type trait is_convertible in the C==0x standard. +already exists under the name create() as part of the definition of the semantics of the type trait is_convertible in the C++0x standard. -The provision of a new library component that allows the production of values in unevaluated expressions is considered as +The provision of a new library component that allows the production of values in unevaluated expressions is considered important to realize constrained templates in C++0x where concepts are not available. This extremely light-weight function is expected to be part of the daily tool-box of the C++0x programmer. @@ -77,7 +74,7 @@ This extremely light-weight function is expected to be part of the daily tool-bo namespace boost { template - typename add_rvalue_reference::type declval(); //noexcept; // as unevaluated operand + typename add_rvalue_reference::type declval() noexcept; // as unevaluated operand } // namespace boost @@ -96,7 +93,7 @@ The library provides the function template declval to simplify the definition of template decltype(static_cast(declval())) convert(From&&); -Declares a function template convert which only participats in overloading if the type From can be explicitly converted to type To. +Declares a function template convert which only participates in overloading if the type From can be explicitly converted to type To. [endsect] @@ -113,3 +110,6 @@ Fixes: [endsect] + + + diff --git a/doc/html/declval.html b/doc/html/declval.html index dff3a83..43dd657 100644 --- a/doc/html/declval.html +++ b/doc/html/declval.html @@ -27,17 +27,13 @@ Howard Hinnant

    -Beman Dawes -

    -

    Vicente J. Botet Escriba

    -
    -

    +

    Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

    @@ -104,13 +100,13 @@ which ensures that we can also use cv void as template parameter. The careful reader might have noticed that declval() already exists under the name create() as part of the definition of the semantics of the type trait is_convertible in - the C==0x standard. + the C++0x standard.

    The provision of a new library component that allows the production of values - in unevaluated expressions is considered as important to realize constrained - templates in C++0x where concepts are not available. This extremely light-weight - function is expected to be part of the daily tool-box of the C++0x programmer. + in unevaluated expressions is considered important to realize constrained templates + in C++0x where concepts are not available. This extremely light-weight function + is expected to be part of the daily tool-box of the C++0x programmer.

    @@ -123,7 +119,7 @@
    namespace boost {
     
         template <typename T>
    -    typename add_rvalue_reference<T>::type declval(); //noexcept; // as unevaluated operand
    +    typename add_rvalue_reference<T>::type declval() noexcept; // as unevaluated operand
     
     }  // namespace boost
     
    @@ -149,7 +145,7 @@ decltype(static_cast<To>(declval<From>())) convert(From&&);

    - Declares a function template convert which only participats in overloading + Declares a function template convert which only participates in overloading if the type From can be explicitly converted to type To.

    @@ -158,7 +154,7 @@ History

    - + boost 1.50

    @@ -171,7 +167,7 @@ - +

    Last revised: April 01, 2012 at 20:13:37 GMT

    Last revised: May 28, 2012 at 18:59:06 GMT


    From ad5cf8cf08df4d79e249c016f3c8d21d8244e535 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Thu, 7 Jun 2012 16:47:33 +0000 Subject: [PATCH 087/126] Update Jamfiles and build scripts for PDF generation. Set local_function image DPI's for better PDF builds. [SVN r78849] --- identity_type/doc/Jamfile.v2 | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/identity_type/doc/Jamfile.v2 b/identity_type/doc/Jamfile.v2 index 1fa4cc7..0e1dd1b 100644 --- a/identity_type/doc/Jamfile.v2 +++ b/identity_type/doc/Jamfile.v2 @@ -29,3 +29,16 @@ boostbook doc : index boost.root=../../../../.. ; +# +# This is very imperfect - it results in both html and pdf docs being built, +# for some reason I can't get the "onehtml" format specified above to play nice +# with the usual incantations for mixed pdf/html builds. JM 06/2012. +# +boostbook pdf_doc : index + : + pdf + html:no + ; + +install pdf_doc_install : pdf_doc : . identity_type.pdf PDF ; + From fb2d391928f8d5500c5a1cf20737d2d29798789b Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 11 Jun 2012 07:23:17 +0000 Subject: [PATCH 088/126] Merge documentation build fix from trunk. [SVN r78888] --- identity_type/doc/Jamfile.v2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/identity_type/doc/Jamfile.v2 b/identity_type/doc/Jamfile.v2 index 0e1dd1b..07ca29e 100644 --- a/identity_type/doc/Jamfile.v2 +++ b/identity_type/doc/Jamfile.v2 @@ -41,4 +41,4 @@ boostbook pdf_doc : index ; install pdf_doc_install : pdf_doc : . identity_type.pdf PDF ; - +explicit pdf_doc_install ; From a89b0101fc2b178f29bf955f97cf5b297324a4b8 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Sat, 1 Sep 2012 23:12:32 +0000 Subject: [PATCH 089/126] boost::result_of uses decltype on compilers that implement N3276, merges [77905], [78195], [80352] from trunk [SVN r80355] --- .../utility/detail/result_of_iterate.hpp | 4 +- include/boost/utility/result_of.hpp | 18 +++ test/result_of_test.cpp | 104 ++++++++++-------- utility.htm | 61 ++++++---- 4 files changed, 117 insertions(+), 70 deletions(-) diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp index 1ec857a..f0b7a16 100644 --- a/include/boost/utility/detail/result_of_iterate.hpp +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -66,7 +66,7 @@ struct cpp0x_result_of_impl } // namespace detail -#else // defined(BOOST_NO_DECLTYPE) +#else // !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE) #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) template : tr1_result_of { }; #endif -#endif // defined(BOOST_NO_DECLTYPE) +#endif // !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE) #undef BOOST_RESULT_OF_ARGS diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp index 41cc176..8a07081 100644 --- a/include/boost/utility/result_of.hpp +++ b/include/boost/utility/result_of.hpp @@ -30,6 +30,24 @@ # define BOOST_RESULT_OF_NUM_ARGS 10 #endif +// Use the decltype-based version of result_of by default if the compiler +// supports N3276 . +// The user can force the choice by defining either BOOST_RESULT_OF_USE_DECLTYPE or +// BOOST_RESULT_OF_USE_TR1, but not both! +#if defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1) +# error Both BOOST_RESULT_OF_USE_DECLTYPE and BOOST_RESULT_OF_USE_TR1 cannot be defined at the same time. +#endif + +#ifndef BOOST_RESULT_OF_USE_TR1 +# ifndef BOOST_RESULT_OF_USE_DECLTYPE +# ifndef BOOST_NO_DECLTYPE_N3276 // this implies !defined(BOOST_NO_DECLTYPE) +# define BOOST_RESULT_OF_USE_DECLTYPE +# else +# define BOOST_RESULT_OF_USE_TR1 +# endif +# endif +#endif + namespace boost { template struct result_of; diff --git a/test/result_of_test.cpp b/test/result_of_test.cpp index 39f6c3b..49ecf33 100644 --- a/test/result_of_test.cpp +++ b/test/result_of_test.cpp @@ -5,7 +5,7 @@ // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#define BOOST_RESULT_OF_USE_DECLTYPE +#include // For more information, see http://www.boost.org/libs/utility #include @@ -62,6 +62,9 @@ struct int_result_type_and_float_result_of_and_char_return_template char operator()(char); }; +template +struct cv_overload_check {}; + struct result_of_member_function_template { template struct result; @@ -69,13 +72,13 @@ struct result_of_member_function_template template struct result { typedef That type; }; template typename result::type operator()(T); - template struct result { typedef const That type; }; + template struct result { typedef cv_overload_check type; }; template typename result::type operator()(T) const; - template struct result { typedef volatile That type; }; + template struct result { typedef cv_overload_check type; }; template typename result::type operator()(T) volatile; - template struct result { typedef const volatile That type; }; + template struct result { typedef cv_overload_check type; }; template typename result::type operator()(T) const volatile; template struct result { typedef That & type; }; @@ -91,13 +94,16 @@ struct result_of_member_function_template template typename result::type operator()(T const volatile &, T); }; -struct no_result_type_or_result_of +struct no_result_type_or_result { - int operator()(double); - short operator()(double) const; - unsigned int operator()(); - unsigned short operator()() volatile; - const unsigned short operator()() const volatile; + short operator()(double); + cv_overload_check operator()(double) const; + cv_overload_check operator()(double) volatile; + cv_overload_check operator()(double) const volatile; + int operator()(); + cv_overload_check operator()() const; + cv_overload_check operator()() volatile; + cv_overload_check operator()() const volatile; #if !defined(BOOST_NO_RVALUE_REFERENCES) short operator()(int&&); int operator()(int&); @@ -106,13 +112,16 @@ struct no_result_type_or_result_of }; template -struct no_result_type_or_result_of_template +struct no_result_type_or_result_template { - int operator()(double); - short operator()(double) const; - unsigned int operator()(); - unsigned short operator()() volatile; - const unsigned short operator()() const volatile; + short operator()(double); + cv_overload_check operator()(double) const; + cv_overload_check operator()(double) volatile; + cv_overload_check operator()(double) const volatile; + int operator()(); + cv_overload_check operator()() const; + cv_overload_check operator()() volatile; + cv_overload_check operator()() const volatile; #if !defined(BOOST_NO_RVALUE_REFERENCES) short operator()(int&&); int operator()(int&); @@ -157,7 +166,7 @@ int main() // Prior to decltype, result_of could not deduce the return type // nullary function objects unless they exposed a result_type. -#if !defined(BOOST_NO_DECLTYPE) +#if defined(BOOST_RESULT_OF_USE_DECLTYPE) BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same(void)>::type, int>::value)); @@ -169,14 +178,11 @@ int main() BOOST_STATIC_ASSERT((is_same(void)>::type, void>::value)); #endif - BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same(char)>::type, int>::value)); - // 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_NO_DECLTYPE) +#if defined(BOOST_RESULT_OF_USE_DECLTYPE) BOOST_STATIC_ASSERT((is_same::type, char>::value)); BOOST_STATIC_ASSERT((is_same(char)>::type, char>::value)); #else @@ -184,6 +190,9 @@ int main() BOOST_STATIC_ASSERT((is_same(char)>::type, int>::value)); #endif + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); @@ -207,18 +216,18 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, double>::value)); - BOOST_STATIC_ASSERT((is_same::type, const double>::value)); - BOOST_STATIC_ASSERT((is_same::type, volatile double>::value)); - BOOST_STATIC_ASSERT((is_same::type, const volatile double>::value)); + BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); BOOST_STATIC_ASSERT((is_same::type, int &>::value)); BOOST_STATIC_ASSERT((is_same::type, int const &>::value)); BOOST_STATIC_ASSERT((is_same::type, int volatile &>::value)); BOOST_STATIC_ASSERT((is_same::type, int const volatile &>::value)); BOOST_STATIC_ASSERT((is_same::type, double>::value)); - BOOST_STATIC_ASSERT((is_same::type, const double>::value)); - BOOST_STATIC_ASSERT((is_same::type, volatile double>::value)); - BOOST_STATIC_ASSERT((is_same::type, const volatile double>::value)); + BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); BOOST_STATIC_ASSERT((is_same::type, int &>::value)); BOOST_STATIC_ASSERT((is_same::type, int const &>::value)); BOOST_STATIC_ASSERT((is_same::type, int volatile &>::value)); @@ -231,24 +240,31 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type,int>::value)); -#if !defined(BOOST_NO_DECLTYPE) - BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same::type, unsigned int>::value)); - BOOST_STATIC_ASSERT((is_same::type, short>::value)); - BOOST_STATIC_ASSERT((is_same::type, unsigned short>::value)); - BOOST_STATIC_ASSERT((is_same::type, const unsigned short>::value)); - BOOST_STATIC_ASSERT((is_same(double)>::type, int>::value)); - BOOST_STATIC_ASSERT((is_same(void)>::type, unsigned int>::value)); - BOOST_STATIC_ASSERT((is_same(double)>::type, short>::value)); - BOOST_STATIC_ASSERT((is_same(void)>::type, unsigned short>::value)); - BOOST_STATIC_ASSERT((is_same(void)>::type, const unsigned short>::value)); +#if defined(BOOST_RESULT_OF_USE_DECLTYPE) + BOOST_STATIC_ASSERT((is_same::type, short>::value)); + BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); + + BOOST_STATIC_ASSERT((is_same(double)>::type, short>::value)); + BOOST_STATIC_ASSERT((is_same(double)>::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same(double)>::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same(double)>::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, cv_overload_check >::value)); + BOOST_STATIC_ASSERT((is_same(void)>::type, cv_overload_check >::value)); #if !defined(BOOST_NO_RVALUE_REFERENCES) - BOOST_STATIC_ASSERT((is_same::type, short>::value)); - BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same::type, long>::value)); - BOOST_STATIC_ASSERT((is_same(int&&)>::type, short>::value)); - BOOST_STATIC_ASSERT((is_same(int&)>::type, int>::value)); - BOOST_STATIC_ASSERT((is_same(int const&)>::type, long>::value)); + BOOST_STATIC_ASSERT((is_same::type, short>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, long>::value)); + BOOST_STATIC_ASSERT((is_same(int&&)>::type, short>::value)); + BOOST_STATIC_ASSERT((is_same(int&)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same(int const&)>::type, long>::value)); #endif #endif diff --git a/utility.htm b/utility.htm index e2cbfd7..e4e79a3 100644 --- a/utility.htm +++ b/utility.htm @@ -161,14 +161,12 @@ void f() { resides in the header <boost/utility/result_of.hpp>.

    -

    If your compiler supports decltype, - then you can enable automatic result type deduction by - defining the macro BOOST_RESULT_OF_USE_DECLTYPE, - as in the following example.

    +

    If your compiler's support for decltype is + adequate, result_of automatically uses it to + deduce the result type of your callable object.

    -
    #define BOOST_RESULT_OF_USE_DECLTYPE
    -#include <boost/utility/result_of.hpp>
    +                
    #include <boost/utility/result_of.hpp>
     
     struct functor {
         template<class T>
    @@ -180,21 +178,29 @@ struct functor {
     
     typedef boost::result_of<
         functor(int)
    ->::type type;
    +>::type type; // type is int
    -

    If decltype is not enabled, +

    You can test whether result_of is using + decltype by checking if the macro + BOOST_RESULT_OF_USE_DECLTYPE is defined after + including result_of.hpp. You can also force + result_of to use decltype by + defining BOOST_RESULT_OF_USE_DECLTYPE prior + to including result_of.hpp.

    + +

    In a future - release, BOOST_RESULT_OF_USE_DECLTYPE - may be enabled by default on compilers that - support decltype, so if you use the above - protocol please take care to ensure that - the result_type - and result<> members accurately - represent the result type. If you wish to continue to +

    Since decltype is a new language + feature recently standardized in C++11, + if you are writing a function object + to be used with result_of, for + maximum portability, you might consider following + the above protocol even if your compiler has + proper decltype support. If you wish to continue to use the protocol on compilers that - support decltype, - use boost::tr1_result_of, which is also - defined - in <boost/utility/result_of.hpp>.

    + support decltype, there are two options: + You can use boost::tr1_result_of, which is also + defined in <boost/utility/result_of.hpp>. + Alternatively, you can define the macro + BOOST_RESULT_OF_USE_TR1, which causes + result_of to use the protocol described + above instead of decltype. If you choose to + follow the protocol, take care to ensure that the + result_type and + result<> members accurately + represent the return type of + operator().

    This implementation of result_of @@ -253,7 +266,7 @@ typedef boost::result_of< N1836, or, for motivation and design rationale, the result_of proposal.

    - Contributed by Doug Gregor.

    +

    Created by Doug Gregor. Contributions from Daniel Walker, Eric Niebler, Michel Morin and others

    Class templates for the Base-from-Member Idiom

    See separate documentation.

    From 1f23425baa65ad86f41d37468636a841212c7eff Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Sun, 2 Sep 2012 03:29:41 +0000 Subject: [PATCH 090/126] result_of limit bumped to 16, merge [71769] from trunk [SVN r80358] --- include/boost/utility/result_of.hpp | 2 +- utility.htm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp index 8a07081..93b7264 100644 --- a/include/boost/utility/result_of.hpp +++ b/include/boost/utility/result_of.hpp @@ -27,7 +27,7 @@ #include #ifndef BOOST_RESULT_OF_NUM_ARGS -# define BOOST_RESULT_OF_NUM_ARGS 10 +# define BOOST_RESULT_OF_NUM_ARGS 16 #endif // Use the decltype-based version of result_of by default if the compiler diff --git a/utility.htm b/utility.htm index e4e79a3..73bd692 100644 --- a/utility.htm +++ b/utility.htm @@ -155,7 +155,7 @@ void f() { the type F to be a function pointer, function reference, member function pointer, or class type. By default, N may be any value between 0 and - 10. To change the upper limit, define the macro + 16. To change the upper limit, define the macro BOOST_RESULT_OF_NUM_ARGS to the maximum value for N. Class template result_of resides in the header < Date: Sun, 2 Sep 2012 03:42:37 +0000 Subject: [PATCH 091/126] merge [77702] to release, fixes #6755 [SVN r80359] --- include/boost/utility/detail/result_of_iterate.hpp | 7 ++++++- test/result_of_test.cpp | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp index f0b7a16..f63faa4 100644 --- a/include/boost/utility/detail/result_of_iterate.hpp +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -5,6 +5,11 @@ // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +// Copyright Daniel Walker, Eric Niebler, Michel Morin 2008-2012. +// 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) + // For more information, see http://www.boost.org/libs/utility #if !defined(BOOST_PP_IS_ITERATING) # error Boost result_of - do not include this file! @@ -40,7 +45,7 @@ template struct result_of : mpl::if_< - mpl::or_< is_pointer, is_member_function_pointer > + is_member_function_pointer , detail::tr1_result_of_impl< typename remove_cv::type, typename remove_cv::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false diff --git a/test/result_of_test.cpp b/test/result_of_test.cpp index 49ecf33..3f6da9e 100644 --- a/test/result_of_test.cpp +++ b/test/result_of_test.cpp @@ -202,7 +202,6 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); - BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); @@ -214,6 +213,7 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, double>::value)); BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); From c0cca9e8cc4f8fcf920d1f83818dc10513562f5f Mon Sep 17 00:00:00 2001 From: John Maddock Date: Fri, 7 Sep 2012 08:49:11 +0000 Subject: [PATCH 092/126] Merge changes from Trunk. Fixes #5790. [SVN r80433] --- include/boost/detail/call_traits.hpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/include/boost/detail/call_traits.hpp b/include/boost/detail/call_traits.hpp index 6ad646e..36dea00 100644 --- a/include/boost/detail/call_traits.hpp +++ b/include/boost/detail/call_traits.hpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -43,20 +44,26 @@ struct ct_imp2 typedef const T param_type; }; -template +template struct ct_imp { typedef const T& param_type; }; -template -struct ct_imp +template +struct ct_imp { typedef typename ct_imp2::param_type param_type; }; -template -struct ct_imp +template +struct ct_imp +{ + typedef typename ct_imp2::param_type param_type; +}; + +template +struct ct_imp { typedef const T param_type; }; @@ -79,7 +86,8 @@ public: typedef typename boost::detail::ct_imp< T, ::boost::is_pointer::value, - ::boost::is_arithmetic::value + ::boost::is_arithmetic::value, + ::boost::is_enum::value >::param_type param_type; }; From 1920623a4f861472f467995a5b65cdfa3d1864e2 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Mon, 17 Sep 2012 00:16:36 +0000 Subject: [PATCH 093/126] merged [80550], allowing users to force result_of to use decltype [SVN r80551] --- include/boost/utility/detail/result_of_iterate.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp index f63faa4..5cf30b6 100644 --- a/include/boost/utility/detail/result_of_iterate.hpp +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -38,7 +38,7 @@ struct tr1_result_of (boost::detail::has_result_type::value)> >::type { }; #endif -#if !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE) +#ifdef BOOST_RESULT_OF_USE_DECLTYPE // Uses declval following N3225 20.7.7.6 when F is not a pointer. template } // namespace detail -#else // !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE) +#else // defined(BOOST_RESULT_OF_USE_DECLTYPE) #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) template : tr1_result_of { }; #endif -#endif // !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE) +#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) #undef BOOST_RESULT_OF_ARGS From 7d8353f46a587e742d689d97747fb033651401bc Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Fri, 21 Sep 2012 18:49:46 +0000 Subject: [PATCH 094/126] result_of: merge [80445], [80452], [80535], [80550], [80605], [80608] from trunk [SVN r80621] --- .../utility/detail/result_of_iterate.hpp | 66 +++- include/boost/utility/result_of.hpp | 18 +- test/result_of_test.cpp | 26 ++ utility.htm | 331 +++++++++++++++++- 4 files changed, 432 insertions(+), 9 deletions(-) diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp index 5cf30b6..4d35fc0 100644 --- a/include/boost/utility/detail/result_of_iterate.hpp +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -58,17 +58,79 @@ struct result_of namespace detail { +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) + template -struct cpp0x_result_of_impl +class is_callable { + typedef char (&pass)[1]; + typedef char (&fail)[2]; + + template + struct sub {}; + template + struct stub {}; + + template + static pass test(sub + , stub< + decltype( + boost::declval()( + BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval() BOOST_PP_INTERCEPT) + ) + ) + >* x = 0); + static fail test(...); + +public: + const static bool value = sizeof(pass) == sizeof(test(sub())); + typedef typename boost::mpl::bool_::type type; +}; + +template +struct cpp0x_result_of_impl + : lazy_enable_if< + is_callable + , cpp0x_result_of_impl + > +{}; + +template +struct cpp0x_result_of_impl { typedef decltype( boost::declval()( - BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), declval() BOOST_PP_INTERCEPT) + BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval() BOOST_PP_INTERCEPT) ) ) type; }; +#else // BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) + +template +struct cpp0x_result_of_impl()( + BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval() BOOST_PP_INTERCEPT) + ) + )>::type> { + typedef decltype( + boost::declval()( + BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval() BOOST_PP_INTERCEPT) + ) + ) type; +}; + +#endif // BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) + } // namespace detail #else // defined(BOOST_RESULT_OF_USE_DECLTYPE) diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp index 93b7264..222c9c9 100644 --- a/include/boost/utility/result_of.hpp +++ b/include/boost/utility/result_of.hpp @@ -25,6 +25,7 @@ #include #include #include +#include #ifndef BOOST_RESULT_OF_NUM_ARGS # define BOOST_RESULT_OF_NUM_ARGS 16 @@ -59,7 +60,22 @@ namespace detail { BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) template struct tr1_result_of_impl; -template struct cpp0x_result_of_impl; + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) + +template class is_callable; +template struct cpp0x_result_of_impl; + +#else // BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) + +template +struct result_of_always_void +{ + typedef void type; +}; +template struct cpp0x_result_of_impl {}; + +#endif // BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) template struct result_of_void_impl diff --git a/test/result_of_test.cpp b/test/result_of_test.cpp index 3f6da9e..0c2834f 100644 --- a/test/result_of_test.cpp +++ b/test/result_of_test.cpp @@ -129,6 +129,27 @@ struct no_result_type_or_result_template #endif }; +// sfinae_tests are derived from example code from Joel de Guzman, +// which demonstrated the interaction between result_of and SFINAE. +template +typename boost::result_of::type +sfinae_test(F f, Arg const& arg) +{ + return f(arg); +} + +template +typename boost::result_of::type +sfinae_test(F f, Arg& arg) +{ + return f(arg); +} + +int sfinae_test_f(int& i) +{ + return i; +} + struct X {}; int main() @@ -268,5 +289,10 @@ int main() #endif #endif +#if defined(BOOST_RESULT_OF_USE_DECLTYPE) + int i = 123; + sfinae_test(sfinae_test_f, i); +#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) + return 0; } diff --git a/utility.htm b/utility.htm index 73bd692..c46c515 100644 --- a/utility.htm +++ b/utility.htm @@ -143,7 +143,7 @@ void f() {

    Class template result_of

    The class template result_of helps determine the type of a - call expression. Given an lvalue f of + call expression. For example, given an lvalue f of type F and lvalues t1, t2, ..., tN of types T1, T2, ..., @@ -163,12 +163,16 @@ void f() {

    If your compiler's support for decltype is adequate, result_of automatically uses it to - deduce the result type of your callable object.

    + deduce the type of the call expression, in which case + result_of<F(T1, T2, ..., + TN)>::type names the type + decltype(boost::declval<F>()(boost::declval<T1>(), + boost::declval<T2>(), ..., + boost::declval<TN>())), as in the + following example.

    -
    #include <boost/utility/result_of.hpp>
    -
    -struct functor {
    +                
    struct functor {
         template<class T>
         T operator()(T x)
         {
    @@ -249,7 +253,7 @@ typedef boost::result_of<
                     result_type and
                     result<> members accurately
                     represent the return type of
    -                operator().

    + operator() given a call expression.

    This implementation of result_of @@ -266,6 +270,321 @@ typedef boost::result_of< N1836, or, for motivation and design rationale, the result_of proposal.

    + + +

    Usage guidelines for boost::result_of

    +
    + +

    The following are general suggestions about when + and how to use boost::result_of.

    + +
      +
    1. If you are targeting C++11 and are not concerned + about portability to non-compliant compilers or + previous versions of the standard, then use + std::result_of. If std::result_of + meets your needs, then there's no reason to stop using + it.
    2. + +
    3. If you are targeting C++11 but may port your code + to legacy compilers at some time in the future, then + use boost::result_of with + decltype. When decltype is + used boost::result_of + and std::result_of are usually + interchangeable. See the documentation on + known differences + between boost::result_of and C++11 result_of.
    4. + +
    5. If compiler portability is required, + use boost::result_of with the TR1 protocol.
    6. +
    + +

    Regardless of how you + configure boost::result_of, it is + important to bear in mind that the return type of a + function may change depending on its arguments, and + additionally, the return type of a member function may + change depending on the cv-qualification of the + object. boost::result_of must be passed + the appropriately cv-qualified types in order to + deduce the corresponding return type. For example: + +

    +
    struct functor {
    +    int& operator()(int);
    +    int const& operator()(int) const;
    +
    +    float& operator()(float&);
    +    float const& operator()(float const&);
    +};
    +
    +typedef boost::result_of<
    +    functor(int)
    +>::type type1; // type1 is int &
    +
    +typedef boost::result_of<
    +    const functor(int)
    +>::type type2; // type2 is int const &
    +
    +typedef boost::result_of<
    +    functor(float&)
    +>::type type3; // type3 is float &
    +
    +typedef boost::result_of<
    +    functor(float const&)
    +>::type type4; // type4 is float const &
    +
    + + +

    Usage guidelines for the TR1 result_of protocol

    +
    + +

    On compliant C++11 + compilers, boost::result_of can + use decltype to deduce the type of any + call expression, including calls to function + objects. However, on pre-C++11 compilers or on + compilers without adequate decltype support, + additional scaffolding is needed from function + objects as described above. The following are + suggestions about how to use the TR1 protocol.

    + +
      +
    • When the return type does not depend on the + argument types or the cv-qualification of the + function object, simply + define result_type. There is no need + to use the result template unless the + return type varies.
    • + +
    • Use the protocol specified type when defining + function prototypes. This can help ensure the + actual return type does not get out of sync with + the protocol specification. For example: + +
      +
      struct functor {
      +    typedef int result_type;
      +    result_type operator()(int);
      +};
      +
    • + +
    • Always specify the result + specialization near the corresponding + operator() overload. This can make it + easier to keep the specializations in sync with the + overloads. For example: + +
      +
      struct functor {
      +    template<class> struct result;
      +
      +    template<class F>
      +    struct result<F(int)> {
      +        typedef int& type;
      +    };
      +    result<functor(int)>::type operator()(int);
      +
      +    template<class F>
      +    struct result<const F(int)> {
      +        typedef int const& type;
      +    };
      +    result<const functor(int)>::type operator()(int) const;
      +};
      +
    • + +
    • Use type transformations to simplify + the result template specialization. For + example, the following uses + Boost.TypeTraits + to specialize the result template for + a single operator() that can be called on + both a const and non-const function object with + either an lvalue or rvalue argument. + +
      +
      struct functor {
      +    template<class> struct result;
      +
      +    template<class F, class T>
      +    struct result<F(T)> 
      +        : boost::remove_cv<
      +              typename boost::remove_reference<T>::type
      +          >
      +    {};
      +
      +    template<class T>
      +    T operator()(T const& x) const;
      +};
      +
    • +
    + + +

    Known differences between boost::result_of and TR1 result_of

    +
    + + When using decltype, boost::result_of + ignores the TR1 protocol and instead deduces the + return type of function objects directly + via decltype. In most situations, users + will not notice a difference, so long as they use the + protocol correctly. The following are situations in + which the type deduced + by boost::result_of is known to differ depending on + whether decltype or the TR1 protocol is + used. + +
      +
    • TR1 protocol misusage + +

      When using the TR1 + protocol, boost::result_of cannot + detect whether the actual type of a call to a + function object is the same as the type specified + by the protocol, which allows for the possibility + of inadvertent mismatches between the specified + type and the actual type. When + using decltype, these subtle bugs + may result in compilation errors. For example:

      + +
      +
      struct functor {
      +   typedef short result_type;
      +   int operator()(short);
      +};
      +
      +#ifdef BOOST_RESULT_OF_USE_DECLTYPE
      +
      +BOOST_STATIC_ASSERT((
      +   boost::is_same<boost::result_of<functor(short)>::type, int>::value
      +)); 
      +
      +#else
      +
      +BOOST_STATIC_ASSERT((
      +   boost::is_same<boost::result_of<functor(short)>::type, short>::value
      +));
      +
      +#endif
      +
      + +

      Note that the user can + force boost::result_of to use the TR1 + protocol even on platforms that + support decltype by + defining BOOST_RESULT_OF_USE_TR1.

    • + +
    • Nullary function objects + +

      When using the TR1 protocol, boost::result_of + cannot always deduce the type of calls to + nullary function objects, in which case the + type defaults to void. When using decltype, + boost::result_of always gives the actual type of the + call expression. For example:

      + +
      +
      struct functor {
      +   template<class> struct result {
      +       typedef int type;
      +   };
      +   int operator()();
      +};
      +
      +#ifdef BOOST_RESULT_OF_USE_DECLTYPE
      +
      +BOOST_STATIC_ASSERT((
      +   boost::is_same<boost::result_of<functor()>::type, int>::value
      +));
      +
      +#else
      +
      +BOOST_STATIC_ASSERT((
      +   boost::is_same<boost::result_of<functor()>::type, void>::value
      +));
      +
      +#endif
      +
      + +

      Note that there are some workarounds for the + nullary function problem. So long as the return + type does not vary, + result_type can always be used to + specify the return type regardless of arity. If the + return type does vary, then the user can + specialize boost::result_of itself for + nullary calls.

    • + +
    • Non-class prvalues and cv-qualification + +

      When using the TR1 + protocol, boost::result_of will + report the cv-qualified type specified + by result_type or + the result template regardless of + the actual cv-qualification of the call + expression. When using + decltype, boost::result_of + will report the actual type of the call expression, + which is not cv-qualified when the expression is a + non-class prvalue. For example:

      + +
      +
      struct functor {
      +   template<class> struct result;
      +   template<class F, class T> struct result<F(const T)> {
      +       typedef const T type;
      +   };
      +
      +   const short operator()(const short);
      +   int const & operator()(int const &);
      +};
      +
      +// Non-prvalue call expressions work the same with or without decltype.
      +
      +BOOST_STATIC_ASSERT((
      +   boost::is_same<
      +       boost::result_of<functor(int const &)>::type,
      +       int const &
      +::value
      +));
      +
      +// Non-class prvalue call expressions are not actually cv-qualified,
      +// but only the decltype-based result_of reports this accurately.
      +
      +#ifdef BOOST_RESULT_OF_USE_DECLTYPE
      +
      +BOOST_STATIC_ASSERT((
      +   boost::is_same<
      +       boost::result_of<functor(const short)>::type,
      +       short
      +::value
      +));
      +
      +#else
      +
      +BOOST_STATIC_ASSERT((
      +   boost::is_same<
      +       boost::result_of<functor(const short)>::type,
      +       const short
      +::value
      +));
      +
      +#endif
      +
    • +
    + + +

    Known differences between boost::result_of and C++11 result_of

    +
    + +

    When using decltype, boost::result_of + implements most of the C++11 result_of + specification. One known exception is that + boost::result_of does not implement the + requirements regarding pointers to member data.

    +

    Created by Doug Gregor. Contributions from Daniel Walker, Eric Niebler, Michel Morin and others

    Class templates for the Base-from-Member Idiom

    From 0f43c44e978041214cc3e6bf20ec427309063f7c Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Wed, 26 Sep 2012 18:52:08 +0000 Subject: [PATCH 095/126] result_of: merge [80636],[80654],[80655],[80656],[80712] from trunk [SVN r80713] --- .../utility/detail/result_of_iterate.hpp | 127 +++++++++--------- include/boost/utility/result_of.hpp | 73 ++++++++-- test/result_of_test.cpp | 12 ++ 3 files changed, 137 insertions(+), 75 deletions(-) diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp index 4d35fc0..17fd4d5 100644 --- a/include/boost/utility/detail/result_of_iterate.hpp +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -23,31 +23,29 @@ #endif #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) -template +template struct tr1_result_of : mpl::if_< mpl::or_< is_pointer, is_member_function_pointer > , boost::detail::tr1_result_of_impl< - typename remove_cv::type, - typename remove_cv::type(BOOST_RESULT_OF_ARGS), + typename remove_cv::type, + typename remove_cv::type(BOOST_RESULT_OF_ARGS), (boost::detail::has_result_type::value)> , boost::detail::tr1_result_of_impl< F, - F(BOOST_RESULT_OF_ARGS), + F(BOOST_RESULT_OF_ARGS), (boost::detail::has_result_type::value)> >::type { }; #endif #ifdef BOOST_RESULT_OF_USE_DECLTYPE // Uses declval following N3225 20.7.7.6 when F is not a pointer. -template +template struct result_of : mpl::if_< is_member_function_pointer , detail::tr1_result_of_impl< - typename remove_cv::type, + typename remove_cv::type, typename remove_cv::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false > , detail::cpp0x_result_of_impl< @@ -58,51 +56,60 @@ struct result_of namespace detail { -#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) +#ifdef BOOST_NO_SFINAE_EXPR -template -class is_callable { - typedef char (&pass)[1]; - typedef char (&fail)[2]; +template +struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION()); - template - struct sub {}; - template - struct stub {}; - - template - static pass test(sub - , stub< - decltype( - boost::declval()( - BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval() BOOST_PP_INTERCEPT) - ) - ) - >* x = 0); - static fail test(...); - -public: - const static bool value = sizeof(pass) == sizeof(test(sub())); - typedef typename boost::mpl::bool_::type type; +template +struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION()) { + R operator()(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) const; + typedef result_of_private_type const &(*pfn_t)(...); + operator pfn_t() const volatile; }; -template +template +struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION()); + +template +struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION()) + : BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION()) +{}; + +template +struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION()) + : BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION()) +{}; + +template +struct BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION()) + : mpl::eval_if< + is_class::type>, + result_of_wrap_callable_class, + mpl::identity::type> > + > +{}; + +template +struct BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION()) { + typedef typename BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION())::type wrapper_t; + static const bool value = ( + sizeof(result_of_no_type) == sizeof(detail::result_of_is_private_type( + (boost::declval()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval() BOOST_PP_INTERCEPT)), result_of_weird_type()) + )) + ); + typedef mpl::bool_ type; +}; + +template struct cpp0x_result_of_impl : lazy_enable_if< - is_callable + BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION()) , cpp0x_result_of_impl > {}; -template +template struct cpp0x_result_of_impl { typedef decltype( @@ -112,11 +119,10 @@ struct cpp0x_result_of_impl -struct cpp0x_result_of_impl +struct cpp0x_result_of_impl()( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval() BOOST_PP_INTERCEPT) @@ -129,15 +135,14 @@ struct cpp0x_result_of_impl +template struct result_of : tr1_result_of { }; #endif @@ -146,27 +151,24 @@ struct result_of #undef BOOST_RESULT_OF_ARGS -#if BOOST_PP_ITERATION() >= 1 +#if BOOST_PP_ITERATION() >= 1 namespace detail { -template +template struct tr1_result_of_impl { typedef R type; }; -template +template struct tr1_result_of_impl { typedef R type; }; #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) -template +template struct tr1_result_of_impl @@ -174,8 +176,7 @@ struct tr1_result_of_impl +template struct tr1_result_of_impl +template struct tr1_result_of_impl +template struct tr1_result_of_impl -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include #include +#include #include +#include #include #include #include +#include #include #include @@ -61,21 +66,67 @@ BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) template struct tr1_result_of_impl; -#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) +#ifdef BOOST_NO_SFINAE_EXPR + +struct result_of_private_type {}; + +struct result_of_weird_type { + template + friend result_of_weird_type operator,(T const &, result_of_weird_type); + friend result_of_private_type operator,(result_of_private_type, result_of_weird_type); +}; + +typedef char result_of_yes_type; // sizeof(result_of_yes_type) == 1 +typedef char (&result_of_no_type)[2]; // sizeof(result_of_no_type) == 2 + +result_of_no_type result_of_is_private_type(result_of_weird_type); +result_of_yes_type result_of_is_private_type(result_of_private_type); + +template +struct result_of_callable_class : C { + result_of_callable_class(); + typedef result_of_private_type const &(*pfn_t)(...); + operator pfn_t() const volatile; +}; + +template +struct result_of_wrap_callable_class { + typedef result_of_callable_class type; +}; + +template +struct result_of_wrap_callable_class { + typedef result_of_callable_class const type; +}; + +template +struct result_of_wrap_callable_class { + typedef result_of_callable_class volatile type; +}; + +template +struct result_of_wrap_callable_class { + typedef result_of_callable_class const volatile type; +}; + +template +struct result_of_wrap_callable_class { + typedef typename result_of_wrap_callable_class::type &type; +}; -template class is_callable; template struct cpp0x_result_of_impl; -#else // BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) +#else // BOOST_NO_SFINAE_EXPR template struct result_of_always_void { - typedef void type; + typedef void type; }; + template struct cpp0x_result_of_impl {}; -#endif // BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) +#endif // BOOST_NO_SFINAE_EXPR template struct result_of_void_impl diff --git a/test/result_of_test.cpp b/test/result_of_test.cpp index 0c2834f..61592f5 100644 --- a/test/result_of_test.cpp +++ b/test/result_of_test.cpp @@ -160,6 +160,10 @@ int main() 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; @@ -218,6 +222,10 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); @@ -228,6 +236,10 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); From 124f4ea8798fb84e7a660618354336835684ba39 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Fri, 28 Sep 2012 22:21:32 +0000 Subject: [PATCH 096/126] result_of: merge [80732] from trunk [SVN r80746] --- include/boost/utility/result_of.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp index 72d9ff2..f0e084a 100644 --- a/include/boost/utility/result_of.hpp +++ b/include/boost/utility/result_of.hpp @@ -71,15 +71,14 @@ template struct tr1_result_of_im struct result_of_private_type {}; struct result_of_weird_type { - template - friend result_of_weird_type operator,(T const &, result_of_weird_type); friend result_of_private_type operator,(result_of_private_type, result_of_weird_type); }; typedef char result_of_yes_type; // sizeof(result_of_yes_type) == 1 typedef char (&result_of_no_type)[2]; // sizeof(result_of_no_type) == 2 -result_of_no_type result_of_is_private_type(result_of_weird_type); +template +result_of_no_type result_of_is_private_type(T const &); result_of_yes_type result_of_is_private_type(result_of_private_type); template From b35ef27b3585795f301eb9fa210eae4f06485050 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Wed, 3 Oct 2012 23:09:58 +0000 Subject: [PATCH 097/126] add missing close tag [SVN r80835] --- utility.htm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utility.htm b/utility.htm index c46c515..94920c3 100644 --- a/utility.htm +++ b/utility.htm @@ -168,7 +168,7 @@ void f() { TN)>::type
    names the type decltype(boost::declval<F>()(boost::declval<T1>(), boost::declval<T2>(), ..., - boost::declval<TN>())), as in the + boost::declval<TN>())), as in the following example.

    From 611395441eb73498cf6c925a03284ae02e9f352c Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Tue, 11 Dec 2012 16:41:54 +0000 Subject: [PATCH 098/126] Merge deprecated macro change for Boost.Utility to release; no functionality change [SVN r81855] --- include/boost/utility/result_of.hpp | 2 +- test/result_of_test.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp index f0e084a..4a20254 100644 --- a/include/boost/utility/result_of.hpp +++ b/include/boost/utility/result_of.hpp @@ -46,7 +46,7 @@ #ifndef BOOST_RESULT_OF_USE_TR1 # ifndef BOOST_RESULT_OF_USE_DECLTYPE -# ifndef BOOST_NO_DECLTYPE_N3276 // this implies !defined(BOOST_NO_DECLTYPE) +# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE) # define BOOST_RESULT_OF_USE_DECLTYPE # else # define BOOST_RESULT_OF_USE_TR1 diff --git a/test/result_of_test.cpp b/test/result_of_test.cpp index 61592f5..d06ec64 100644 --- a/test/result_of_test.cpp +++ b/test/result_of_test.cpp @@ -104,7 +104,7 @@ struct no_result_type_or_result cv_overload_check operator()() const; cv_overload_check operator()() volatile; cv_overload_check operator()() const volatile; -#if !defined(BOOST_NO_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) short operator()(int&&); int operator()(int&); long operator()(int const&); @@ -122,7 +122,7 @@ struct no_result_type_or_result_template cv_overload_check operator()() const; cv_overload_check operator()() volatile; cv_overload_check operator()() const volatile; -#if !defined(BOOST_NO_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) short operator()(int&&); int operator()(int&); long operator()(int const&); @@ -291,7 +291,7 @@ int main() BOOST_STATIC_ASSERT((is_same(void)>::type, cv_overload_check >::value)); BOOST_STATIC_ASSERT((is_same(void)>::type, cv_overload_check >::value)); BOOST_STATIC_ASSERT((is_same(void)>::type, cv_overload_check >::value)); -#if !defined(BOOST_NO_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) BOOST_STATIC_ASSERT((is_same::type, short>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, long>::value)); From 856b01240a9564d545370df48ea9e07e1014c246 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Mon, 17 Dec 2012 14:36:31 +0000 Subject: [PATCH 099/126] Merge string_ref to release [SVN r82047] --- doc/Jamfile.v2 | 23 +- doc/string_ref.qbk | 100 +++++++ include/boost/utility/string_ref.hpp | 386 +++++++++++++++++++++++++++ index.html | 4 +- test/Jamfile.v2 | 2 + test/string_ref_test1.cpp | 111 ++++++++ test/string_ref_test2.cpp | 256 ++++++++++++++++++ 7 files changed, 877 insertions(+), 5 deletions(-) create mode 100644 doc/string_ref.qbk create mode 100644 include/boost/utility/string_ref.hpp create mode 100644 test/string_ref_test1.cpp create mode 100644 test/string_ref_test2.cpp diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index b12d71a..10b7c7e 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -62,7 +62,22 @@ boostbook standalone ; - - - - +xml string_ref : string_ref.qbk ; +boostbook standalone + : + string_ref + : + # File name of HTML output: + root.filename=string_ref + # How far down we chunk nested sections, basically all of them: + chunk.section.depth=0 + # Don't put the first section on the same page as the TOC: + chunk.first.sections=0 + # How far down sections get TOC's + toc.section.depth=1 + # Max depth in each TOC: + toc.max.depth=1 + # How far down we go with TOC's + generate.section.toc.level=1 + + ; diff --git a/doc/string_ref.qbk b/doc/string_ref.qbk new file mode 100644 index 0000000..0242096 --- /dev/null +++ b/doc/string_ref.qbk @@ -0,0 +1,100 @@ +[/ + / Copyright (c) 2012 Marshall Clow + / + / 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) + /] + +[article String_Ref + [quickbook 1.5] + [authors [Clow, Marshall]] + [copyright 2012 Marshall Clow] + [license + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + [@http://www.boost.org/LICENSE_1_0.txt]) + ] +] + +[/===============] +[section Overview] +[/===============] + +Boost.StringRef is an implementation of Jeffrey Yaskin's [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html N3442: +string_ref: a non-owning reference to a string]. + +When you are parsing/processing strings from some external source, frequently you want to pass a piece of text to a procedure for specialized processing. The canonical way to do this is as a `std::string`, but that has certain drawbacks: + +1) If you are processing a buffer of text (say a HTTP response or the contents of a file), then you have to create the string from the text you want to pass, which involves memory allocation and copying of data. + +2) if a routine receives a constant `std::string` and wants to pass a portion of that string to another routine, then it must create a new string of that substring. + +3) A routine receives a constant `std::string` and wants to return a portion of the string, then it must create a new string to return. + +`string_ref` is designed to solve these efficiency problems. A `string_ref` is a read-only reference to a contiguous sequence of characters, and provides much of the functionality of `std::string`. A `string_ref` is cheap to create, copy and pass by value, because it does not actually own the storage that it points to. + +A `string_ref` is implemented as a small struct that contains a pointer to the start of the character data and a count. A `string_ref` is cheap to create and cheap to copy. + +`string_ref` acts as a container; it includes all the methods that you would expect in a container, including iteration support, `operator []`, `at` and `size`. It can be used with any of the iterator-based algorithms in the STL - as long as you don't need to change the underlying data (`sort` and `remove`, for example, will not work) + +Besides generic container functionality, `string_ref` provides a subset of the interface of `std::string`. This makes it easy to replace parameters of type `const std::string &` with `boost::string_ref`. + +Because a `string_ref` does not own the data that it "points to", it introduces lifetime issues into code that uses it. The programmer must ensure that the data that a `string_ref` refers to exists as long as the `string_ref` does. + +[endsect] + + +[/===============] +[section Examples] +[/===============] + +Integrating `string_ref` into your code is fairly simple. Wherever you pass a `const std::string &` or `std::string` as a parameter, that's a candidate for passing a `boost::string_ref`. + + std::string extract_part ( const std::string &bar ) { + return bar.substr ( 2, 3 ); + } + + if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ } + +Let's figure out what happens in this (contrived) example. + +First, a temporary string is created from the string literal `"ABCDEFG"`, and it is passed (by reference) to the routine `extract_part`. Then a second string is created in the call `std::string::substr` and returned to `extract_part` (this copy may be elided by RVO). Then `extract_part` returns that string back to the caller (again this copy may be elided). The first temporary string is deallocated, and `front` is called on the second string, and then it is deallocated as well. + +Two `std::string`s are created, and two copy operations. That's (potentially) four memory allocations and deallocations, and the associated copying of data. + +Now let's look at the same code with `string_ref`: + + boost::string_ref extract_part ( boost::string_ref bar ) { + return bar.substr ( 2, 3 ); + } + + if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ } + +No memory allocations. No copying of character data. No changes to the code other than the types. There are two `string_ref`s created, and two `string_ref`s copied, but those are cheap operations. + +[endsect] + + +[/=================] +[section:reference Reference ] +[/=================] + +The header file "string_ref.hpp" defines a template `boost::basic_string_ref`, and four specializations - for `char` / `wchar_t` / `char16_t` / `char32_t` . + +`#include ` + +[endsect] + +[/===============] +[section History] +[/===============] + +[heading boost 1.53] +* Introduced + + +[endsect] + + + + diff --git a/include/boost/utility/string_ref.hpp b/include/boost/utility/string_ref.hpp new file mode 100644 index 0000000..d333628 --- /dev/null +++ b/include/boost/utility/string_ref.hpp @@ -0,0 +1,386 @@ +/* + 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 + + Based on the StringRef implementation in LLVM (http://llvm.org) and + N3422 by Jeffrey Yasskin + http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html + +*/ + +#ifndef BOOST_STRING_REF_HPP +#define BOOST_STRING_REF_HPP + +#include +#include + +#include +#include +#include +#include + +namespace boost { + + namespace detail { + // A helper functor because sometimes we don't have lambdas + template + class string_ref_traits_eq { + public: + string_ref_traits_eq ( charT ch ) : ch_(ch) {} + bool operator () ( charT val ) const { return traits::eq ( ch_, val ); } + charT ch_; + }; + } + + template class basic_string_ref; + typedef basic_string_ref > string_ref; + typedef basic_string_ref > wstring_ref; + +#ifndef BOOST_NO_CXX11_CHAR16_T + typedef basic_string_ref > u16string_ref; +#endif + +#ifndef BOOST_NO_CXX11_CHAR32_T + typedef basic_string_ref > u32string_ref; +#endif + + template + class basic_string_ref { + public: + // types + typedef charT value_type; + typedef const charT* pointer; + typedef const charT& reference; + typedef const charT& const_reference; + typedef pointer const_iterator; // impl-defined + typedef const_iterator iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef const_reverse_iterator reverse_iterator; + typedef std::size_t size_type; + typedef ptrdiff_t difference_type; + static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1); + + // construct/copy + BOOST_CONSTEXPR basic_string_ref () + : ptr_(NULL), len_(0) {} + + BOOST_CONSTEXPR basic_string_ref (const basic_string_ref &rhs) + : ptr_(rhs.ptr_), len_(rhs.len_) {} + + basic_string_ref& operator=(const basic_string_ref &rhs) { + ptr_ = rhs.ptr_; + len_ = rhs.len_; + return *this; + } + + basic_string_ref(const charT* str) + : ptr_(str), len_(traits::length(str)) {} + + template + basic_string_ref(const std::basic_string& str) + : ptr_(str.data()), len_(str.length()) {} + + BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len) + : ptr_(str), len_(len) {} + +#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS + template + explicit operator std::basic_string() const { + return std::basic_string ( ptr_, len_ ); + } +#endif + + // iterators + BOOST_CONSTEXPR const_iterator begin() const { return ptr_; } + BOOST_CONSTEXPR const_iterator cbegin() const { return ptr_; } + BOOST_CONSTEXPR const_iterator end() const { return ptr_ + len_; } + BOOST_CONSTEXPR const_iterator cend() const { return ptr_ + len_; } + const_reverse_iterator rbegin() const { return const_reverse_iterator (end()); } + const_reverse_iterator crbegin() const { return const_reverse_iterator (end()); } + const_reverse_iterator rend() const { return const_reverse_iterator (begin()); } + const_reverse_iterator crend() const { return const_reverse_iterator (begin()); } + + // capacity + BOOST_CONSTEXPR size_type size() const { return len_; } + BOOST_CONSTEXPR size_type length() const { return len_; } + BOOST_CONSTEXPR size_type max_size() const { return len_; } + BOOST_CONSTEXPR bool empty() const { return len_ == 0; } + + // element access + BOOST_CONSTEXPR const charT& operator[](size_type pos) const { return ptr_[pos]; } + + const charT& at(size_t pos) const { + if ( pos >= len_ ) + throw std::out_of_range ( "boost::string_ref::at" ); + return ptr_[pos]; + } + + BOOST_CONSTEXPR const charT& front() const { return ptr_[0]; } + BOOST_CONSTEXPR const charT& back() const { return ptr_[len_-1]; } + BOOST_CONSTEXPR const charT* data() const { return ptr_; } + + // modifiers + void clear() { len_ = 0; } + void remove_prefix(size_type n) { + if ( n > len_ ) + n = len_; + ptr_ += n; + len_ -= n; + } + + void remove_suffix(size_type n) { + if ( n > len_ ) + n = len_; + len_ -= n; + } + + + // basic_string_ref string operations + BOOST_CONSTEXPR + basic_string_ref substr(size_type pos, size_type n=npos) const { +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1600) + // Looks like msvc 8 and 9 have a codegen bug when one branch of + // a conditional operator is a throw expression. -EAN 2012/12/04 + if ( pos > size()) throw std::out_of_range ( "string_ref::substr" ); + if ( n == npos || pos + n > size()) n = size () - pos; + return basic_string_ref ( data() + pos, n ); +#else + return pos > size() ? throw std::out_of_range ( "string_ref::substr" ) : + basic_string_ref ( data() + pos, n == npos || pos + n > size() ? size() - pos : n ); +#endif + } + + int compare(basic_string_ref x) const { + int cmp = traits::compare ( ptr_, x.ptr_, (std::min)(len_, x.len_)); + return cmp != 0 ? cmp : ( len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1 ); + } + + bool starts_with(charT c) const { return !empty() && traits::eq ( c, front()); } + bool starts_with(basic_string_ref x) const { + return len_ >= x.len_ && traits::compare ( ptr_, x.ptr_, x.len_ ) == 0; + } + + bool ends_with(charT c) const { return !empty() && traits::eq ( c, back()); } + bool ends_with(basic_string_ref x) const { + return len_ >= x.len_ && traits::compare ( ptr_ + len_ - x.len_, x.ptr_, x.len_ ) == 0; + } + + size_type find(basic_string_ref s) const { + const_iterator iter = std::search ( this->cbegin (), this->cend (), + s.cbegin (), s.cend (), traits::eq ); + return iter = this->cend () ? npos : std::distance ( this->cbegin (), iter ); + } + + size_type find(charT c) const { + const_iterator iter = std::find_if ( this->cbegin (), this->cend (), + detail::string_ref_traits_eq ( c )); + return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter ); + } + + size_type rfind(basic_string_ref s) const { + const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (), + s.crbegin (), s.crend (), traits::eq ); + return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); + } + + size_type rfind(charT c) const { + const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (), + detail::string_ref_traits_eq ( c )); + return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); + } + + size_type find_first_of(charT c) const { return find (c); } + size_type find_last_of (charT c) const { return rfind (c); } + + size_type find_first_of(basic_string_ref s) const { + const_iterator iter = std::find_first_of + ( this->cbegin (), this->cend (), s.cbegin (), s.cend (), traits::eq ); + return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter ); + } + + size_type find_last_of(basic_string_ref s) const { + const_reverse_iterator iter = std::find_first_of + ( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq ); + return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter); + } + + size_type find_first_not_of(basic_string_ref s) const { + const_iterator iter = find_not_of ( this->cbegin (), this->cend (), s ); + return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter ); + } + + size_type find_first_not_of(charT c) const { + for ( const_iterator iter = this->cbegin (); iter != this->cend (); ++iter ) + if ( !traits::eq ( c, *iter )) + return std::distance ( this->cbegin (), iter ); + return npos; + } + + size_type find_last_not_of(basic_string_ref s) const { + const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s ); + return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); + } + + size_type find_last_not_of(charT c) const { + for ( const_reverse_iterator iter = this->crbegin (); iter != this->crend (); ++iter ) + if ( !traits::eq ( c, *iter )) + return reverse_distance ( this->crbegin (), iter ); + return npos; + } + + private: + template + size_type reverse_distance ( r_iter first, r_iter last ) const { + return len_ - 1 - std::distance ( first, last ); + } + + template + Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const { + for ( ; first != last ; ++first ) + if ( 0 == traits::find ( s.ptr_, s.len_, *first )) + return first; + return last; + } + + + + const charT *ptr_; + std::size_t len_; + }; + + // Comparison operators + template + bool operator==(basic_string_ref x, basic_string_ref y) { + if ( x.size () != y.size ()) return false; + return x.compare(y) == 0; + } + + template + bool operator!=(basic_string_ref x, basic_string_ref y) { + if ( x.size () != y.size ()) return true; + return x.compare(y) != 0; + } + + template + bool operator<(basic_string_ref x, basic_string_ref y) { + return x.compare(y) < 0; + } + + template + bool operator>(basic_string_ref x, basic_string_ref y) { + return x.compare(y) > 0; + } + + template + bool operator<=(basic_string_ref x, basic_string_ref y) { + return x.compare(y) <= 0; + } + + template + bool operator>=(basic_string_ref x, basic_string_ref y) { + return x.compare(y) >= 0; + } + + + // Inserter + template + std::basic_ostream& + operator<<(std::basic_ostream& os, const basic_string_ref& str) { +#ifdef BOOST_NO_CXX11_RANGE_BASED_FOR + for ( typename basic_string_ref::const_iterator iter = str.begin (); iter != str.end (); ++iter ) + os << *iter; +#else + for ( charT x : str ) + os << x; +#endif + return os; + } + +#if 0 + // numeric conversions + // + // These are short-term implementations. + // In a production environment, I would rather avoid the copying. + // + int stoi (string_ref str, size_t* idx=0, int base=10) { + return std::stoi ( std::string(str), idx, base ); + } + + long stol (string_ref str, size_t* idx=0, int base=10) { + return std::stol ( std::string(str), idx, base ); + } + + unsigned long stoul (string_ref str, size_t* idx=0, int base=10) { + return std::stoul ( std::string(str), idx, base ); + } + + long long stoll (string_ref str, size_t* idx=0, int base=10) { + return std::stoll ( std::string(str), idx, base ); + } + + unsigned long long stoull (string_ref str, size_t* idx=0, int base=10) { + return std::stoull ( std::string(str), idx, base ); + } + + float stof (string_ref str, size_t* idx=0) { + return std::stof ( std::string(str), idx ); + } + + double stod (string_ref str, size_t* idx=0) { + return std::stod ( std::string(str), idx ); + } + + long double stold (string_ref str, size_t* idx=0) { + return std::stold ( std::string(str), idx ); + } + + int stoi (wstring_ref str, size_t* idx=0, int base=10) { + return std::stoi ( std::wstring(str), idx, base ); + } + + long stol (wstring_ref str, size_t* idx=0, int base=10) { + return std::stol ( std::wstring(str), idx, base ); + } + + unsigned long stoul (wstring_ref str, size_t* idx=0, int base=10) { + return std::stoul ( std::wstring(str), idx, base ); + } + + long long stoll (wstring_ref str, size_t* idx=0, int base=10) { + return std::stoll ( std::wstring(str), idx, base ); + } + + unsigned long long stoull (wstring_ref str, size_t* idx=0, int base=10) { + return std::stoull ( std::wstring(str), idx, base ); + } + + float stof (wstring_ref str, size_t* idx=0) { + return std::stof ( std::wstring(str), idx ); + } + + double stod (wstring_ref str, size_t* idx=0) { + return std::stod ( std::wstring(str), idx ); + } + + long double stold (wstring_ref str, size_t* idx=0) { + return std::stold ( std::wstring(str), idx ); + } +#endif + +} + +#if 0 +namespace std { + // Hashing + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; +} +#endif + +#endif diff --git a/index.html b/index.html index d957d79..367fa93 100644 --- a/index.html +++ b/index.html @@ -28,7 +28,9 @@ swap
    throw_exception
    utility
    - value_init

    + string_ref
    + value_init +


    © Copyright Beman Dawes, 2001

    diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index d3fc34c..4b2d6e0 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -31,6 +31,8 @@ test-suite utility [ run ../ref_test.cpp ../../test/build//boost_test_exec_monitor/static ] [ compile result_of_test.cpp ] [ run ../shared_iterator_test.cpp ] + [ run string_ref_test1.cpp ] + [ run string_ref_test2.cpp ] [ run ../value_init_test.cpp ] [ run ../value_init_workaround_test.cpp ] [ run ../initialized_test.cpp ] diff --git a/test/string_ref_test1.cpp b/test/string_ref_test1.cpp new file mode 100644 index 0000000..32ff801 --- /dev/null +++ b/test/string_ref_test1.cpp @@ -0,0 +1,111 @@ +/* + 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 +#include +#include + +#include + + +#include + +typedef boost::string_ref string_ref; + +// Should be equal +void interop ( const std::string &str, string_ref ref ) { +// BOOST_CHECK ( str == ref ); + BOOST_CHECK ( str.size () == ref.size ()); + BOOST_CHECK ( std::equal ( str.begin (), str.end (), ref.begin ())); + BOOST_CHECK ( 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_CHECK ( sr1 == sr2 ); + BOOST_CHECK ( sr1 == sr3 ); + BOOST_CHECK ( sr2 == sr3 ); + BOOST_CHECK ( 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 test_main( int , char* [] ) { + + const char **p = &test_strings[0]; + + while ( *p != NULL ) { + interop ( *p, *p ); + test_substr ( *p ); + test_remove ( *p ); + null_tests ( *p ); + + p++; + } + + return 0; + } diff --git a/test/string_ref_test2.cpp b/test/string_ref_test2.cpp new file mode 100644 index 0000000..dbd5bf9 --- /dev/null +++ b/test/string_ref_test2.cpp @@ -0,0 +1,256 @@ +/* + 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 +#include // for std::strchr + +#include + +#include + +typedef boost::string_ref string_ref; + +void ends_with ( const char *arg ) { + const size_t sz = strlen ( arg ); + string_ref sr ( arg ); + string_ref sr2 ( arg ); + const char *p = arg; + + while ( !*p ) { + BOOST_CHECK ( sr.ends_with ( p )); + ++p; + } + + while ( !sr2.empty ()) { + BOOST_CHECK ( sr.ends_with ( sr2 )); + sr2.remove_prefix (1); + } + + sr2 = arg; + while ( !sr2.empty ()) { + BOOST_CHECK ( sr.ends_with ( sr2 )); + sr2.remove_prefix (1); + } + + char ch = sz == 0 ? '\0' : arg [ sz - 1 ]; + sr2 = arg; + if ( sz > 0 ) + BOOST_CHECK ( sr2.ends_with ( ch )); + BOOST_CHECK ( !sr2.ends_with ( ++ch )); + BOOST_CHECK ( sr2.ends_with ( string_ref ())); + } + +void starts_with ( const char *arg ) { + const size_t sz = 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_CHECK ( sr.starts_with ( foo )); + --p; + } + + while ( !sr2.empty ()) { + BOOST_CHECK ( sr.starts_with ( sr2 )); + sr2.remove_suffix (1); + } + + char ch = *arg; + sr2 = arg; + if ( sz > 0 ) + BOOST_CHECK ( sr2.starts_with ( ch )); + BOOST_CHECK ( !sr2.starts_with ( ++ch )); + BOOST_CHECK ( 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_CHECK ( std::equal ( sr2.rbegin (), sr2.rend (), arg )); + BOOST_CHECK ( string2 == arg ); + BOOST_CHECK ( 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_CHECK ( res >= base ); + return static_cast ( res - base ); + } + +void find ( const char *arg ) { + string_ref sr1; + string_ref sr2; + const char *p; + +// 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_CHECK ( 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_CHECK ( pos != string_ref::npos && pos < sr1.size () && ( pos >= ptr_diff ( 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_CHECK (( strp == NULL ) == ( pos == string_ref::npos )); + if ( strp != NULL ) + BOOST_CHECK ( 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_CHECK (( strp == NULL ) == ( pos == string_ref::npos )); + if ( strp != NULL ) + BOOST_CHECK ( 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_CHECK ( pos == 0 ); + sr1.remove_prefix (1); + ++p; + } + +// Find everything at the end + sr1 = arg; + p = arg + strlen ( arg ) - 1; + while ( !sr1.empty ()) { + string_ref::size_type pos = sr1.rfind(*p); + BOOST_CHECK ( 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_CHECK ( pos == 0 ); + sr1.remove_prefix (1); + ++p; + } + + +// Find everything at the end + sr1 = arg; + p = arg + strlen ( arg ) - 1; + while ( !sr1.empty ()) { + string_ref::size_type pos = sr1.find_last_of(*p); + BOOST_CHECK ( 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_CHECK ( sr1.find_first_of ( sr2 ) == 0 ); + BOOST_CHECK ( 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_CHECK ( 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_CHECK ( sr1[i] == *p ); + BOOST_CHECK ( sr1 [ pos2 ] != *p ); + } + + BOOST_CHECK ( pos2 != pos1 ); + ++p; + } + +// Basic sanity checking for "find_last_of / find_last_not_of" + sr1 = arg; + sr2 = arg; + while ( !sr1.empty() ) { + BOOST_CHECK ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 )); + BOOST_CHECK ( 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_CHECK ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg )); + BOOST_CHECK ( pos2 == string_ref::npos || pos1 < sr1.size ()); + if ( pos2 != string_ref::npos ) { + for ( size_t i = sr1.size () -1 ; i > pos2; --i ) + BOOST_CHECK ( sr1[i] == *p ); + BOOST_CHECK ( sr1 [ pos2 ] != *p ); + } + + BOOST_CHECK ( pos2 != pos1 ); + ++p; + } + + } + +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 test_main( int , char* [] ) { + const char **p = &test_strings[0]; + + while ( *p != NULL ) { + starts_with ( *p ); + ends_with ( *p ); + reverse ( *p ); + find ( *p ); + + p++; + } + + return 0; + } From 1730c1319b0a5aa3d81c20f09e8f1d0373f52453 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Mon, 14 Jan 2013 16:34:16 +0000 Subject: [PATCH 100/126] Merge string_ref doc changes to release [SVN r82490] --- doc/Jamfile.v2 | 6 +- doc/html/string_ref.html | 280 +++++++++++++++++++++++++++++++++++++++ doc/string_ref.qbk | 93 +++++++++++-- 3 files changed, 363 insertions(+), 16 deletions(-) create mode 100644 doc/html/string_ref.html diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 10b7c7e..a0ff034 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -43,7 +43,7 @@ using quickbook ; path-constant boost-images : ../../../doc/src/images ; xml declval : declval.qbk ; -boostbook standalone +boostbook standalone_declval : declval : @@ -63,7 +63,7 @@ boostbook standalone ; xml string_ref : string_ref.qbk ; -boostbook standalone +boostbook standalone_string_ref : string_ref : @@ -79,5 +79,5 @@ boostbook standalone toc.max.depth=1 # How far down we go with TOC's generate.section.toc.level=1 - + ; diff --git a/doc/html/string_ref.html b/doc/html/string_ref.html new file mode 100644 index 0000000..0b8a9d1 --- /dev/null +++ b/doc/html/string_ref.html @@ -0,0 +1,280 @@ + + + +String_Ref + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +
    +
    +
    +

    +String_Ref

    +

    +Marshall Clow +

    +
    +
    +

    + 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) +

    +
    +
    +
    +
    +
    +

    Table of Contents

    +
    +
    Overview
    +
    Examples
    +
    Reference
    +
    History
    +
    +
    +
    + +

    + Boost.StringRef is an implementation of Jeffrey Yaskin's N3442: + string_ref: a non-owning reference to a string. +

    +

    + When you are parsing/processing strings from some external source, frequently + you want to pass a piece of text to a procedure for specialized processing. + The canonical way to do this is as a std::string, + but that has certain drawbacks: +

    +

    + 1) If you are processing a buffer of text (say a HTTP response or the contents + of a file), then you have to create the string from the text you want to pass, + which involves memory allocation and copying of data. +

    +

    + 2) if a routine receives a constant std::string + and wants to pass a portion of that string to another routine, then it must + create a new string of that substring. +

    +

    + 3) A routine receives a constant std::string + and wants to return a portion of the string, then it must create a new string + to return. +

    +

    + string_ref is designed to solve + these efficiency problems. A string_ref + is a read-only reference to a contiguous sequence of characters, and provides + much of the functionality of std::string. + A string_ref is cheap to create, + copy and pass by value, because it does not actually own the storage that it + points to. +

    +

    + A string_ref is implemented + as a small struct that contains a pointer to the start of the character data + and a count. A string_ref is + cheap to create and cheap to copy. +

    +

    + string_ref acts as a container; + it includes all the methods that you would expect in a container, including + iteration support, operator [], + at and size. + It can be used with any of the iterator-based algorithms in the STL - as long + as you don't need to change the underlying data (sort + and remove, for example, will + not work) +

    +

    + Besides generic container functionality, string_ref + provides a subset of the interface of std::string. + This makes it easy to replace parameters of type const + std::string & + with boost::string_ref. Like std::string, + string_ref has a static member + variable named npos to denote + the result of failed searches, and to mean "the end". +

    +

    + Because a string_ref does not + own the data that it "points to", it introduces lifetime issues into + code that uses it. The programmer must ensure that the data that a string_ref refers to exists as long as the + string_ref does. +

    +
    +
    + +

    + Integrating string_ref into + your code is fairly simple. Wherever you pass a const + std::string & + or std::string as a parameter, that's a candidate + for passing a boost::string_ref. +

    +
    std::string extract_part ( const std::string &bar ) {
    +    return bar.substr ( 2, 3 );
    +    }
    +
    +if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ }
    +
    +

    + Let's figure out what happens in this (contrived) example. +

    +

    + First, a temporary string is created from the string literal "ABCDEFG", and it is passed (by reference) + to the routine extract_part. + Then a second string is created in the call std::string::substr + and returned to extract_part + (this copy may be elided by RVO). Then extract_part + returns that string back to the caller (again this copy may be elided). The + first temporary string is deallocated, and front + is called on the second string, and then it is deallocated as well. +

    +

    + Two std::strings are created, and two copy operations. + That's (potentially) four memory allocations and deallocations, and the associated + copying of data. +

    +

    + Now let's look at the same code with string_ref: +

    +
    boost::string_ref extract_part ( boost::string_ref bar ) {
    +    return bar.substr ( 2, 3 );
    +    }
    +
    +if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ }
    +
    +

    + No memory allocations. No copying of character data. No changes to the code + other than the types. There are two string_refs + created, and two string_refs + copied, but those are cheap operations. +

    +
    +
    + +

    + The header file "string_ref.hpp" defines a template boost::basic_string_ref, + and four specializations - for char + / wchar_t / char16_t + / char32_t . +

    +

    + #include <boost/utility/string_ref.hpp> +

    +

    + Construction and copying: +

    +
    BOOST_CONSTEXPR basic_string_ref ();    // Constructs an empty string_ref
    +BOOST_CONSTEXPR basic_string_ref(const charT* str); // Constructs from a NULL-terminated string
    +BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len); // Constructs from a pointer, length pair
    +template<typename Allocator>
    +basic_string_ref(const std::basic_string<charT, traits, Allocator>& str); // Constructs from a std::string
    +basic_string_ref (const basic_string_ref &rhs);
    +basic_string_ref& operator=(const basic_string_ref &rhs);
    +
    +

    + string_ref does not define + a move constructor nor a move-assignment operator because copying a string_ref is just a cheap as moving one. +

    +

    + Basic container-like functions: +

    +
    BOOST_CONSTEXPR size_type size()     const ;
    +BOOST_CONSTEXPR size_type length()   const ;
    +BOOST_CONSTEXPR size_type max_size() const ;
    +BOOST_CONSTEXPR bool empty()         const ;
    +
    +// All iterators are const_iterators
    +BOOST_CONSTEXPR const_iterator  begin() const ;
    +BOOST_CONSTEXPR const_iterator cbegin() const ;
    +BOOST_CONSTEXPR const_iterator    end() const ;
    +BOOST_CONSTEXPR const_iterator   cend() const ;
    +const_reverse_iterator         rbegin() const ;
    +const_reverse_iterator        crbegin() const ;
    +const_reverse_iterator           rend() const ;
    +const_reverse_iterator          crend() const ;
    +
    +

    + Access to the individual elements (all of which are const): +

    +
    BOOST_CONSTEXPR const charT& operator[](size_type pos) const ;
    +const charT& at(size_t pos) const ;
    +BOOST_CONSTEXPR const charT& front() const ;
    +BOOST_CONSTEXPR const charT& back()  const ;
    +BOOST_CONSTEXPR const charT* data()  const ;
    +
    +

    + Modifying the string_ref (but + not the underlying data): +

    +
    void clear();
    +void remove_prefix(size_type n);
    +void remove_suffix(size_type n);
    +
    +

    + Searching: +

    +
    size_type find(basic_string_ref s) const ;
    +size_type find(charT c) const ;
    +size_type rfind(basic_string_ref s) const ;
    +size_type rfind(charT c) const ;
    +size_type find_first_of(charT c) const ;
    +size_type find_last_of (charT c) const ;
    +
    +size_type find_first_of(basic_string_ref s) const ;
    +size_type find_last_of(basic_string_ref s) const ;
    +size_type find_first_not_of(basic_string_ref s) const ;
    +size_type find_first_not_of(charT c) const ;
    +size_type find_last_not_of(basic_string_ref s) const ;
    +size_type find_last_not_of(charT c) const ;
    +
    +

    + String-like operations: +

    +
    BOOST_CONSTEXPR basic_string_ref substr(size_type pos, size_type n=npos) const ; // Creates a new string_ref
    +bool starts_with(charT c) const ;
    +bool starts_with(basic_string_ref x) const ;
    +bool ends_with(charT c) const ;
    +bool ends_with(basic_string_ref x) const ;
    +
    +
    +
    + +

    + + boost + 1.53 +

    +
    • + Introduced +
    +
    +
    + + + +

    Last revised: January 14, 2013 at 16:24:14 GMT

    +
    +
    + + diff --git a/doc/string_ref.qbk b/doc/string_ref.qbk index 0242096..5943eed 100644 --- a/doc/string_ref.qbk +++ b/doc/string_ref.qbk @@ -37,7 +37,7 @@ A `string_ref` is implemented as a small struct that contains a pointer to the s `string_ref` acts as a container; it includes all the methods that you would expect in a container, including iteration support, `operator []`, `at` and `size`. It can be used with any of the iterator-based algorithms in the STL - as long as you don't need to change the underlying data (`sort` and `remove`, for example, will not work) -Besides generic container functionality, `string_ref` provides a subset of the interface of `std::string`. This makes it easy to replace parameters of type `const std::string &` with `boost::string_ref`. +Besides generic container functionality, `string_ref` provides a subset of the interface of `std::string`. This makes it easy to replace parameters of type `const std::string &` with `boost::string_ref`. Like `std::string`, `string_ref` has a static member variable named `npos` to denote the result of failed searches, and to mean "the end". Because a `string_ref` does not own the data that it "points to", it introduces lifetime issues into code that uses it. The programmer must ensure that the data that a `string_ref` refers to exists as long as the `string_ref` does. @@ -50,12 +50,12 @@ Because a `string_ref` does not own the data that it "points to", it introduces Integrating `string_ref` into your code is fairly simple. Wherever you pass a `const std::string &` or `std::string` as a parameter, that's a candidate for passing a `boost::string_ref`. - std::string extract_part ( const std::string &bar ) { - return bar.substr ( 2, 3 ); - } - - if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ } - + std::string extract_part ( const std::string &bar ) { + return bar.substr ( 2, 3 ); + } + + if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ } + Let's figure out what happens in this (contrived) example. First, a temporary string is created from the string literal `"ABCDEFG"`, and it is passed (by reference) to the routine `extract_part`. Then a second string is created in the call `std::string::substr` and returned to `extract_part` (this copy may be elided by RVO). Then `extract_part` returns that string back to the caller (again this copy may be elided). The first temporary string is deallocated, and `front` is called on the second string, and then it is deallocated as well. @@ -64,11 +64,11 @@ Two `std::string`s are created, and two copy operations. That's (potentially) fo Now let's look at the same code with `string_ref`: - boost::string_ref extract_part ( boost::string_ref bar ) { - return bar.substr ( 2, 3 ); - } - - if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ } + boost::string_ref extract_part ( boost::string_ref bar ) { + return bar.substr ( 2, 3 ); + } + + if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ } No memory allocations. No copying of character data. No changes to the code other than the types. There are two `string_ref`s created, and two `string_ref`s copied, but those are cheap operations. @@ -83,6 +83,73 @@ The header file "string_ref.hpp" defines a template `boost::basic_string_ref`, a `#include ` +Construction and copying: + + BOOST_CONSTEXPR basic_string_ref (); // Constructs an empty string_ref + BOOST_CONSTEXPR basic_string_ref(const charT* str); // Constructs from a NULL-terminated string + BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len); // Constructs from a pointer, length pair + template + basic_string_ref(const std::basic_string& str); // Constructs from a std::string + basic_string_ref (const basic_string_ref &rhs); + basic_string_ref& operator=(const basic_string_ref &rhs); + +`string_ref` does not define a move constructor nor a move-assignment operator because copying a `string_ref` is just a cheap as moving one. + +Basic container-like functions: + + BOOST_CONSTEXPR size_type size() const ; + BOOST_CONSTEXPR size_type length() const ; + BOOST_CONSTEXPR size_type max_size() const ; + BOOST_CONSTEXPR bool empty() const ; + + // All iterators are const_iterators + BOOST_CONSTEXPR const_iterator begin() const ; + BOOST_CONSTEXPR const_iterator cbegin() const ; + BOOST_CONSTEXPR const_iterator end() const ; + BOOST_CONSTEXPR const_iterator cend() const ; + const_reverse_iterator rbegin() const ; + const_reverse_iterator crbegin() const ; + const_reverse_iterator rend() const ; + const_reverse_iterator crend() const ; + +Access to the individual elements (all of which are const): + + BOOST_CONSTEXPR const charT& operator[](size_type pos) const ; + const charT& at(size_t pos) const ; + BOOST_CONSTEXPR const charT& front() const ; + BOOST_CONSTEXPR const charT& back() const ; + BOOST_CONSTEXPR const charT* data() const ; + +Modifying the `string_ref` (but not the underlying data): + + void clear(); + void remove_prefix(size_type n); + void remove_suffix(size_type n); + +Searching: + + size_type find(basic_string_ref s) const ; + size_type find(charT c) const ; + size_type rfind(basic_string_ref s) const ; + size_type rfind(charT c) const ; + size_type find_first_of(charT c) const ; + size_type find_last_of (charT c) const ; + + size_type find_first_of(basic_string_ref s) const ; + size_type find_last_of(basic_string_ref s) const ; + size_type find_first_not_of(basic_string_ref s) const ; + size_type find_first_not_of(charT c) const ; + size_type find_last_not_of(basic_string_ref s) const ; + size_type find_last_not_of(charT c) const ; + +String-like operations: + + BOOST_CONSTEXPR basic_string_ref substr(size_type pos, size_type n=npos) const ; // Creates a new string_ref + bool starts_with(charT c) const ; + bool starts_with(basic_string_ref x) const ; + bool ends_with(charT c) const ; + bool ends_with(basic_string_ref x) const ; + [endsect] [/===============] @@ -91,7 +158,7 @@ The header file "string_ref.hpp" defines a template `boost::basic_string_ref`, a [heading boost 1.53] * Introduced - + [endsect] From 9383bbc28377233f68d5541a68bf5ee81eb80e17 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Mon, 11 Feb 2013 16:10:24 +0000 Subject: [PATCH 101/126] Merge typo in docs; Fixes 7974 [SVN r82819] --- in_place_factories.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/in_place_factories.html b/in_place_factories.html index f8a4c7b..8eb7ea8 100644 --- a/in_place_factories.html +++ b/in_place_factories.html @@ -46,7 +46,7 @@ HREF="../../boost/utility/typed_in_place_factory.hpp">boost/utility/typed_in_pla

    Suppose we have a class

    struct X
     {
    -  X ( int, std:::string ) ;
    +  X ( int, std::string ) ;
     } ;

    And a container for it which supports an empty state (that is, which can contain zero objects):

    struct C
    
    From 1b2cd6378b60620aab46a6461eff7d853d8e8d19 Mon Sep 17 00:00:00 2001
    From: Marshall Clow 
    Date: Mon, 11 Feb 2013 16:22:32 +0000
    Subject: [PATCH 102/126] Merge doc typo; Fixes #8002
    
    [SVN r82821]
    ---
     doc/string_ref.qbk | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/doc/string_ref.qbk b/doc/string_ref.qbk
    index 5943eed..4c6fc79 100644
    --- a/doc/string_ref.qbk
    +++ b/doc/string_ref.qbk
    @@ -54,7 +54,7 @@ Integrating `string_ref` into your code is fairly simple. Wherever you pass a `c
             return bar.substr ( 2, 3 );
             }
             
    -    if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ }
    +    if ( extract_part ( "ABCDEFG" ).front() == 'C' ) { /* do something */ }
         
     Let's figure out what happens in this (contrived) example.
     
    
    From c1fdb477c1467b38f82339abe5527623a29e9059 Mon Sep 17 00:00:00 2001
    From: Marshall Clow 
    Date: Mon, 25 Feb 2013 18:43:26 +0000
    Subject: [PATCH 103/126] Merged boost::algorithm::gather and updated tests for
     Utility, Algorithm and Utility libraries
    
    [SVN r83154]
    ---
     test/Jamfile.v2           |  9 +++++++--
     test/string_ref_test1.cpp | 12 +++++-------
     test/string_ref_test2.cpp | 10 +++++-----
     3 files changed, 17 insertions(+), 14 deletions(-)
    
    diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
    index 4b2d6e0..d597cb8 100644
    --- a/test/Jamfile.v2
    +++ b/test/Jamfile.v2
    @@ -8,6 +8,11 @@
     # bring in rules for testing
     import testing ;
     
    +alias unit_test_framework
    +    : # sources
    +        /boost//unit_test_framework
    +    ;        
    +
     # Please keep the tests ordered by filename
     test-suite utility
         :
    @@ -31,8 +36,8 @@ test-suite utility
             [ run ../ref_test.cpp ../../test/build//boost_test_exec_monitor/static ]
             [ compile result_of_test.cpp ]
             [ run ../shared_iterator_test.cpp ]
    -        [ run string_ref_test1.cpp ]
    -        [ run string_ref_test2.cpp ]
    +        [ run string_ref_test1.cpp unit_test_framework ]
    +        [ run string_ref_test2.cpp unit_test_framework ]
             [ run ../value_init_test.cpp ]
             [ run ../value_init_workaround_test.cpp ]
             [ run ../initialized_test.cpp ]
    diff --git a/test/string_ref_test1.cpp b/test/string_ref_test1.cpp
    index 32ff801..7524536 100644
    --- a/test/string_ref_test1.cpp
    +++ b/test/string_ref_test1.cpp
    @@ -13,8 +13,8 @@
     
     #include 
     
    -
    -#include 
    +#define BOOST_TEST_MAIN
    +#include 
     
     typedef boost::string_ref string_ref;
     
    @@ -94,8 +94,8 @@ const char *test_strings [] = {
         NULL
         };
         
    -int test_main( int , char* [] ) {
    -
    +BOOST_AUTO_TEST_CASE( test_main )
    +{
         const char **p = &test_strings[0];
     
         while ( *p != NULL ) {
    @@ -106,6 +106,4 @@ int test_main( int , char* [] ) {
         
             p++;
             }
    -
    -    return 0;
    -    }
    +}
    diff --git a/test/string_ref_test2.cpp b/test/string_ref_test2.cpp
    index dbd5bf9..67733ee 100644
    --- a/test/string_ref_test2.cpp
    +++ b/test/string_ref_test2.cpp
    @@ -12,7 +12,8 @@
     
     #include 
     
    -#include 
    +#define BOOST_TEST_MAIN
    +#include 
     
     typedef boost::string_ref string_ref;
     
    @@ -240,7 +241,8 @@ const char *test_strings [] = {
         NULL
         };
         
    -int test_main( int , char* [] ) {
    +BOOST_AUTO_TEST_CASE( test_main )
    +{
         const char **p = &test_strings[0];
         
         while ( *p != NULL ) {
    @@ -251,6 +253,4 @@ int test_main( int , char* [] ) {
     
             p++;
             }
    -
    -    return 0;
    -    }
    +}
    
    From f9540f360c6dbe794c8816b523958e3474ac2ce9 Mon Sep 17 00:00:00 2001
    From: Eric Niebler 
    Date: Sat, 9 Mar 2013 22:55:05 +0000
    Subject: [PATCH 104/126] merge [82960] to release, fixes #7663
    
    [SVN r83381]
    ---
     include/boost/utility/result_of.hpp | 7 +++++++
     1 file changed, 7 insertions(+)
    
    diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp
    index 4a20254..97e9618 100644
    --- a/include/boost/utility/result_of.hpp
    +++ b/include/boost/utility/result_of.hpp
    @@ -68,6 +68,13 @@ template struct tr1_result_of_im
     
     #ifdef BOOST_NO_SFINAE_EXPR
     
    +// There doesn't seem to be any other way to turn this off such that the presence of
    +// the user-defined operator,() below doesn't cause spurious warning all over the place,
    +// so unconditionally turn it off.
    +#if BOOST_MSVC
    +#  pragma warning(disable: 4913) // user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used
    +#endif
    +
     struct result_of_private_type {};
     
     struct result_of_weird_type {
    
    From d51799518bc031658799fb014bda2b569bc1ef80 Mon Sep 17 00:00:00 2001
    From: Eric Niebler 
    Date: Sun, 10 Mar 2013 21:18:49 +0000
    Subject: [PATCH 105/126] merge [82901], [82902], and [83147] from trunk
    
    [SVN r83403]
    ---
     include/boost/utility/string_ref.hpp | 264 ++++++++++++++++++++-------
     test/string_ref_test1.cpp            |  26 +--
     test/string_ref_test2.cpp            | 108 ++++++++---
     3 files changed, 295 insertions(+), 103 deletions(-)
    
    diff --git a/include/boost/utility/string_ref.hpp b/include/boost/utility/string_ref.hpp
    index d333628..6d5cace 100644
    --- a/include/boost/utility/string_ref.hpp
    +++ b/include/boost/utility/string_ref.hpp
    @@ -1,11 +1,11 @@
    -/* 
    +/*
        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
    -    
    +
         Based on the StringRef implementation in LLVM (http://llvm.org) and
         N3422 by Jeffrey Yasskin
             http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
    @@ -24,7 +24,7 @@
     #include 
     
     namespace boost {
    -    
    +
         namespace detail {
         //  A helper functor because sometimes we don't have lambdas
             template 
    @@ -35,7 +35,7 @@ namespace boost {
                 charT ch_;
                 };
             }
    -    
    +
         template class basic_string_ref;
         typedef basic_string_ref >        string_ref;
         typedef basic_string_ref >    wstring_ref;
    @@ -47,7 +47,7 @@ namespace boost {
     #ifndef BOOST_NO_CXX11_CHAR32_T
         typedef basic_string_ref > u32string_ref;
     #endif
    -    
    +
         template
         class basic_string_ref {
         public:
    @@ -63,7 +63,7 @@ namespace boost {
             typedef std::size_t size_type;
             typedef ptrdiff_t difference_type;
             static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
    -        
    +
             // construct/copy
             BOOST_CONSTEXPR basic_string_ref ()
                 : ptr_(NULL), len_(0) {}
    @@ -76,7 +76,7 @@ namespace boost {
                 len_ = rhs.len_;
                 return *this;
                 }
    -            
    +
             basic_string_ref(const charT* str)
                 : ptr_(str), len_(traits::length(str)) {}
     
    @@ -93,7 +93,11 @@ namespace boost {
                 return std::basic_string ( ptr_, len_ );
                 }
     #endif
    -        
    +
    +        std::basic_string to_string () const {
    +            return std::basic_string ( ptr_, len_ );
    +            }
    +
             // iterators
             BOOST_CONSTEXPR const_iterator   begin() const { return ptr_; }
             BOOST_CONSTEXPR const_iterator  cbegin() const { return ptr_; }
    @@ -103,13 +107,13 @@ namespace boost {
                     const_reverse_iterator crbegin() const { return const_reverse_iterator (end()); }
                     const_reverse_iterator    rend() const { return const_reverse_iterator (begin()); }
                     const_reverse_iterator   crend() const { return const_reverse_iterator (begin()); }
    -        
    +
             // capacity
             BOOST_CONSTEXPR size_type size()     const { return len_; }
             BOOST_CONSTEXPR size_type length()   const { return len_; }
             BOOST_CONSTEXPR size_type max_size() const { return len_; }
             BOOST_CONSTEXPR bool empty()         const { return len_ == 0; }
    -        
    +
             // element access
             BOOST_CONSTEXPR const charT& operator[](size_type pos) const { return ptr_[pos]; }
     
    @@ -118,11 +122,11 @@ namespace boost {
                     throw std::out_of_range ( "boost::string_ref::at" );
                 return ptr_[pos];
                 }
    -            
    +
             BOOST_CONSTEXPR const charT& front() const { return ptr_[0]; }
             BOOST_CONSTEXPR const charT& back()  const { return ptr_[len_-1]; }
             BOOST_CONSTEXPR const charT* data()  const { return ptr_; }
    -        
    +
             // modifiers
             void clear() { len_ = 0; }
             void remove_prefix(size_type n) {
    @@ -131,14 +135,14 @@ namespace boost {
                 ptr_ += n;
                 len_ -= n;
                 }
    -            
    +
             void remove_suffix(size_type n) {
                 if ( n > len_ )
                     n = len_;
                 len_ -= n;
                 }
    -            
    -        
    +
    +
             // basic_string_ref string operations
             BOOST_CONSTEXPR
             basic_string_ref substr(size_type pos, size_type n=npos) const {
    @@ -153,78 +157,78 @@ namespace boost {
                     basic_string_ref ( data() + pos, n == npos || pos + n > size() ? size() - pos : n );
     #endif
                 }
    -        
    +
             int compare(basic_string_ref x) const {
    -            int cmp = traits::compare ( ptr_, x.ptr_, (std::min)(len_, x.len_));
    +            const int cmp = traits::compare ( ptr_, x.ptr_, (std::min)(len_, x.len_));
                 return cmp != 0 ? cmp : ( len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1 );
                 }
    -        
    +
             bool starts_with(charT c) const { return !empty() && traits::eq ( c, front()); }
             bool starts_with(basic_string_ref x) const {
                 return len_ >= x.len_ && traits::compare ( ptr_, x.ptr_, x.len_ ) == 0;
                 }
    -        
    +
             bool ends_with(charT c) const { return !empty() && traits::eq ( c, back()); }
             bool ends_with(basic_string_ref x) const {
                 return len_ >= x.len_ && traits::compare ( ptr_ + len_ - x.len_, x.ptr_, x.len_ ) == 0;
                 }
     
             size_type find(basic_string_ref s) const {
    -            const_iterator iter = std::search ( this->cbegin (), this->cend (), 
    +            const_iterator iter = std::search ( this->cbegin (), this->cend (),
                                                     s.cbegin (), s.cend (), traits::eq );
    -            return iter = this->cend () ? npos : std::distance ( this->cbegin (), iter );
    +            return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
                 }
    -        
    +
             size_type find(charT c) const {
    -            const_iterator iter = std::find_if ( this->cbegin (), this->cend (), 
    +            const_iterator iter = std::find_if ( this->cbegin (), this->cend (),
                                         detail::string_ref_traits_eq ( c ));
                 return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
                 }
    -                        
    +
             size_type rfind(basic_string_ref s) const {
    -            const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (), 
    +            const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (),
                                                     s.crbegin (), s.crend (), traits::eq );
                 return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
                 }
     
             size_type rfind(charT c) const {
    -            const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (), 
    +            const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (),
                                         detail::string_ref_traits_eq ( c ));
                 return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
                 }
    -        
    +
             size_type find_first_of(charT c) const { return  find (c); }
             size_type find_last_of (charT c) const { return rfind (c); }
    -        
    +
             size_type find_first_of(basic_string_ref s) const {
    -            const_iterator iter = std::find_first_of 
    -            	( this->cbegin (), this->cend (), s.cbegin (), s.cend (), traits::eq );
    +            const_iterator iter = std::find_first_of
    +                ( this->cbegin (), this->cend (), s.cbegin (), s.cend (), traits::eq );
                 return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
                 }
    -        
    +
             size_type find_last_of(basic_string_ref s) const {
    -            const_reverse_iterator iter = std::find_first_of 
    +            const_reverse_iterator iter = std::find_first_of
                     ( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq );
                 return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter);
                 }
    -        
    +
             size_type find_first_not_of(basic_string_ref s) const {
    -        	const_iterator iter = find_not_of ( this->cbegin (), this->cend (), s );
    +            const_iterator iter = find_not_of ( this->cbegin (), this->cend (), s );
                 return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
                 }
    -        
    +
             size_type find_first_not_of(charT c) const {
                 for ( const_iterator iter = this->cbegin (); iter != this->cend (); ++iter )
                     if ( !traits::eq ( c, *iter ))
                         return std::distance ( this->cbegin (), iter );
                 return npos;
                 }
    -        
    +
             size_type find_last_not_of(basic_string_ref s) const {
    -        	const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s );
    +            const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s );
                 return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
                 }
    -        
    +
             size_type find_last_not_of(charT c) const {
                 for ( const_reverse_iterator iter = this->crbegin (); iter != this->crend (); ++iter )
                     if ( !traits::eq ( c, *iter ))
    @@ -237,55 +241,181 @@ namespace boost {
             size_type reverse_distance ( r_iter first, r_iter last ) const {
                 return len_ - 1 - std::distance ( first, last );
                 }
    -        
    +
             template 
             Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const {
    -			for ( ; first != last ; ++first )
    -				if ( 0 == traits::find ( s.ptr_, s.len_, *first ))
    -					return first;
    -			return last;
    -			}
    -		
    -       		
    -        
    +            for ( ; first != last ; ++first )
    +                if ( 0 == traits::find ( s.ptr_, s.len_, *first ))
    +                    return first;
    +            return last;
    +            }
    +
    +
    +
             const charT *ptr_;
             std::size_t len_;
             };
    -    
    -    // Comparison operators
    +
    +
    +//  Comparison operators
    +//  Equality
         template
         bool operator==(basic_string_ref x, basic_string_ref y) {
             if ( x.size () != y.size ()) return false;
             return x.compare(y) == 0;
             }
    -    
    +
    +    template
    +    bool operator==(basic_string_ref x, const std::basic_string & y) {
    +        return x == basic_string_ref(y);
    +        }
    +
    +    template
    +    bool operator==(const std::basic_string & x, basic_string_ref y) {
    +        return basic_string_ref(x) == y;
    +        }
    +
    +    template
    +    bool operator==(basic_string_ref x, const charT * y) {
    +        return x == basic_string_ref(y);
    +        }
    +
    +    template
    +    bool operator==(const charT * x, basic_string_ref y) {
    +        return basic_string_ref(x) == y;
    +        }
    +
    +//  Inequality
         template
         bool operator!=(basic_string_ref x, basic_string_ref y) {
             if ( x.size () != y.size ()) return true;
             return x.compare(y) != 0;
             }
     
    +    template
    +    bool operator!=(basic_string_ref x, const std::basic_string & y) {
    +        return x != basic_string_ref(y);
    +        }
    +
    +    template
    +    bool operator!=(const std::basic_string & x, basic_string_ref y) {
    +        return basic_string_ref(x) != y;
    +        }
    +
    +    template
    +    bool operator!=(basic_string_ref x, const charT * y) {
    +        return x != basic_string_ref(y);
    +        }
    +
    +    template
    +    bool operator!=(const charT * x, basic_string_ref y) {
    +        return basic_string_ref(x) != y;
    +        }
    +
    +//  Less than
         template
         bool operator<(basic_string_ref x, basic_string_ref y) {
             return x.compare(y) < 0;
             }
     
    +    template
    +    bool operator<(basic_string_ref x, const std::basic_string & y) {
    +        return x < basic_string_ref(y);
    +        }
    +
    +    template
    +    bool operator<(const std::basic_string & x, basic_string_ref y) {
    +        return basic_string_ref(x) < y;
    +        }
    +
    +    template
    +    bool operator<(basic_string_ref x, const charT * y) {
    +        return x < basic_string_ref(y);
    +        }
    +
    +    template
    +    bool operator<(const charT * x, basic_string_ref y) {
    +        return basic_string_ref(x) < y;
    +        }
    +
    +//  Greater than
         template
         bool operator>(basic_string_ref x, basic_string_ref y) {
             return x.compare(y) > 0;
             }
     
    +    template
    +    bool operator>(basic_string_ref x, const std::basic_string & y) {
    +        return x > basic_string_ref(y);
    +        }
    +
    +    template
    +    bool operator>(const std::basic_string & x, basic_string_ref y) {
    +        return basic_string_ref(x) > y;
    +        }
    +
    +    template
    +    bool operator>(basic_string_ref x, const charT * y) {
    +        return x > basic_string_ref(y);
    +        }
    +
    +    template
    +    bool operator>(const charT * x, basic_string_ref y) {
    +        return basic_string_ref(x) > y;
    +        }
    +
    +//  Less than or equal to
         template
         bool operator<=(basic_string_ref x, basic_string_ref y) {
             return x.compare(y) <= 0;
             }
     
    +    template
    +    bool operator<=(basic_string_ref x, const std::basic_string & y) {
    +        return x <= basic_string_ref(y);
    +        }
    +
    +    template
    +    bool operator<=(const std::basic_string & x, basic_string_ref y) {
    +        return basic_string_ref(x) <= y;
    +        }
    +
    +    template
    +    bool operator<=(basic_string_ref x, const charT * y) {
    +        return x <= basic_string_ref(y);
    +        }
    +
    +    template
    +    bool operator<=(const charT * x, basic_string_ref y) {
    +        return basic_string_ref(x) <= y;
    +        }
    +
    +//  Greater than or equal to
         template
         bool operator>=(basic_string_ref x, basic_string_ref y) {
             return x.compare(y) >= 0;
             }
     
    -    
    +    template
    +    bool operator>=(basic_string_ref x, const std::basic_string & y) {
    +        return x >= basic_string_ref(y);
    +        }
    +
    +    template
    +    bool operator>=(const std::basic_string & x, basic_string_ref y) {
    +        return basic_string_ref(x) >= y;
    +        }
    +
    +    template
    +    bool operator>=(basic_string_ref x, const charT * y) {
    +        return x >= basic_string_ref(y);
    +        }
    +
    +    template
    +    bool operator>=(const charT * x, basic_string_ref y) {
    +        return basic_string_ref(x) >= y;
    +        }
    +
         // Inserter
         template
         std::basic_ostream&
    @@ -299,7 +429,7 @@ namespace boost {
     #endif
             return os;
             }
    -    
    +
     #if 0
         // numeric conversions
         //
    @@ -309,63 +439,63 @@ namespace boost {
         int stoi (string_ref str, size_t* idx=0, int base=10) {
             return std::stoi ( std::string(str), idx, base );
             }
    -    
    +
         long stol (string_ref str, size_t* idx=0, int base=10) {
             return std::stol ( std::string(str), idx, base );
             }
    -        
    +
         unsigned long stoul (string_ref str, size_t* idx=0, int base=10) {
             return std::stoul ( std::string(str), idx, base );
             }
    -        
    +
         long long stoll (string_ref str, size_t* idx=0, int base=10) {
             return std::stoll ( std::string(str), idx, base );
             }
    -    
    +
         unsigned long long stoull (string_ref str, size_t* idx=0, int base=10) {
             return std::stoull ( std::string(str), idx, base );
             }
    -    
    +
         float stof (string_ref str, size_t* idx=0) {
             return std::stof ( std::string(str), idx );
             }
    -        
    +
         double stod (string_ref str, size_t* idx=0) {
             return std::stod ( std::string(str), idx );
             }
    -        
    +
         long double stold (string_ref str, size_t* idx=0)  {
             return std::stold ( std::string(str), idx );
             }
    -    
    +
         int  stoi (wstring_ref str, size_t* idx=0, int base=10) {
             return std::stoi ( std::wstring(str), idx, base );
             }
    -        
    +
         long stol (wstring_ref str, size_t* idx=0, int base=10) {
             return std::stol ( std::wstring(str), idx, base );
             }
    -        
    +
         unsigned long stoul (wstring_ref str, size_t* idx=0, int base=10) {
             return std::stoul ( std::wstring(str), idx, base );
             }
    -        
    +
         long long stoll (wstring_ref str, size_t* idx=0, int base=10) {
             return std::stoll ( std::wstring(str), idx, base );
             }
    -        
    +
         unsigned long long stoull (wstring_ref str, size_t* idx=0, int base=10) {
             return std::stoull ( std::wstring(str), idx, base );
             }
    -    
    +
         float  stof (wstring_ref str, size_t* idx=0) {
             return std::stof ( std::wstring(str), idx );
             }
    -        
    +
         double stod (wstring_ref str, size_t* idx=0) {
             return std::stod ( std::wstring(str), idx );
             }
    -        
    +
         long double stold (wstring_ref str, size_t* idx=0) {
             return std::stold ( std::wstring(str), idx );
             }
    diff --git a/test/string_ref_test1.cpp b/test/string_ref_test1.cpp
    index 7524536..f1d4df2 100644
    --- a/test/string_ref_test1.cpp
    +++ b/test/string_ref_test1.cpp
    @@ -1,4 +1,4 @@
    -/* 
    +/*
        Copyright (c) Marshall Clow 2012-2012.
     
        Distributed under the Boost Software License, Version 1.0. (See accompanying
    @@ -33,30 +33,30 @@ void null_tests ( const char *p ) {
         string_ref sr3 ( p, 0 );
         string_ref sr4 ( p );
         sr4.clear ();
    -    
    +
         BOOST_CHECK ( sr1 == sr2 );
         BOOST_CHECK ( sr1 == sr3 );
         BOOST_CHECK ( sr2 == sr3 );
    -    BOOST_CHECK ( sr1 == sr4 );    
    +    BOOST_CHECK ( 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 ));    
    +            interop ( str.substr ( i, j ), ref.substr ( i, j ));
         }
     
     //  make sure that removing prefixes and suffixes work just like strings
    @@ -64,20 +64,20 @@ 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;     
    +      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;     
    +      ref  = str;
           while ( ref.size () >= i ) {
               interop ( work, ref );
               work.erase ( work.size () - i, i );
    @@ -93,7 +93,7 @@ const char *test_strings [] = {
         "0123456789",
         NULL
         };
    -    
    +
     BOOST_AUTO_TEST_CASE( test_main )
     {
         const char **p = &test_strings[0];
    @@ -103,7 +103,7 @@ BOOST_AUTO_TEST_CASE( test_main )
             test_substr ( *p );
             test_remove ( *p );
             null_tests ( *p );
    -    
    +
             p++;
             }
     }
    diff --git a/test/string_ref_test2.cpp b/test/string_ref_test2.cpp
    index 67733ee..89e1cfc 100644
    --- a/test/string_ref_test2.cpp
    +++ b/test/string_ref_test2.cpp
    @@ -1,4 +1,4 @@
    -/* 
    +/*
        Copyright (c) Marshall Clow 2012-2012.
     
        Distributed under the Boost Software License, Version 1.0. (See accompanying
    @@ -46,7 +46,7 @@ void ends_with ( const char *arg ) {
         BOOST_CHECK ( !sr2.ends_with ( ++ch ));
         BOOST_CHECK ( sr2.ends_with ( string_ref ()));
         }
    -    
    +
     void starts_with ( const char *arg ) {
         const size_t sz = strlen ( arg );
         string_ref sr  ( arg );
    @@ -85,9 +85,9 @@ void reverse ( const char *arg ) {
     
     //	This helper function eliminates signed vs. unsigned warnings
     string_ref::size_type ptr_diff ( const char *res, const char *base ) {
    -	BOOST_CHECK ( res >= base );
    -	return static_cast ( res - base );
    -	}
    +    BOOST_CHECK ( res >= base );
    +    return static_cast ( res - base );
    +    }
     
     void find ( const char *arg ) {
         string_ref sr1;
    @@ -95,22 +95,32 @@ void find ( const char *arg ) {
         const char *p;
     
     //  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_CHECK ( pos != string_ref::npos && ( pos <= ptr_diff ( p, arg )));
    -    ++p;
    -    }
    -  
    +    p = arg;
    +    sr1 = arg;
    +    while ( *p ) {
    +      string_ref::size_type pos = sr1.find(*p);
    +      BOOST_CHECK ( 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_CHECK ( pos != string_ref::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg )));
    -    ++p;
    -    }
    +      string_ref::size_type pos = sr1.rfind(*p);
    +      BOOST_CHECK ( 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_CHECK ( pos != string_ref::npos && pos <= static_cast( p - arg ));
    +        p++;
    +        }
     
         sr1 = arg;
         p = arg;
    @@ -156,7 +166,7 @@ void find ( const char *arg ) {
             sr1.remove_suffix (1);
             --p;
             }
    -        
    +
     //  Find everything at the start
         sr1  = arg;
         p    = arg;
    @@ -177,7 +187,7 @@ void find ( const char *arg ) {
             sr1.remove_suffix (1);
             --p;
             }
    -        
    +
     //  Basic sanity checking for "find_first_of / find_first_not_of"
         sr1 = arg;
         sr2 = arg;
    @@ -202,7 +212,7 @@ void find ( const char *arg ) {
             BOOST_CHECK ( pos2 != pos1 );
             ++p;
             }
    -        
    +
     //  Basic sanity checking for "find_last_of / find_last_not_of"
         sr1 = arg;
         sr2 = arg;
    @@ -224,13 +234,63 @@ void find ( const char *arg ) {
                     BOOST_CHECK ( sr1[i] == *p );
                 BOOST_CHECK ( sr1 [ pos2 ] != *p );
                 }
    -         
    +
             BOOST_CHECK ( 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 > ();
    +    str2 = sr1.to_string ();
    +    BOOST_CHECK ( str1 == str2 );
    +
    +#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
    +    std::string str3 = static_cast ( sr1 );
    +    BOOST_CHECK ( str1 == str3 );
    +#endif
    +    }
    +
    +void compare ( const char *arg ) {
    +    string_ref sr1;
    +    std::string str1;
    +    std::string str2 = str1;
    +
    +    str1.assign ( arg );
    +    sr1 = arg;
    +    BOOST_CHECK ( sr1  == sr1);	    // compare string_ref and string_ref
    +    BOOST_CHECK ( sr1  == str1);	// compare string and string_ref
    +    BOOST_CHECK ( str1 == sr1 );	// compare string_ref and string
    +    BOOST_CHECK ( sr1  == arg );	// compare string_ref and pointer
    +    BOOST_CHECK ( arg  == sr1 );	// compare pointer and string_ref
    +
    +    if ( sr1.size () > 0 ) {
    +        (*str1.rbegin())++;
    +        BOOST_CHECK ( sr1  != str1 );
    +        BOOST_CHECK ( str1 != sr1 );
    +        BOOST_CHECK ( sr1 < str1 );
    +        BOOST_CHECK ( sr1 <= str1 );
    +        BOOST_CHECK ( str1 > sr1 );
    +        BOOST_CHECK ( str1 >= sr1 );
    +
    +        (*str1.rbegin()) -= 2;
    +        BOOST_CHECK ( sr1  != str1 );
    +        BOOST_CHECK ( str1 != sr1 );
    +        BOOST_CHECK ( sr1 > str1 );
    +        BOOST_CHECK ( sr1 >= str1 );
    +        BOOST_CHECK ( str1 < sr1 );
    +        BOOST_CHECK ( str1 <= sr1 );
    +        }
    +    }
    +
     const char *test_strings [] = {
         "",
         "0",
    @@ -240,16 +300,18 @@ const char *test_strings [] = {
         "abc\0asdfadsfasf",
         NULL
         };
    -    
    +
     BOOST_AUTO_TEST_CASE( test_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++;
             }
    
    From 1ab9131bcaddb3ac819edebd2c8d478ab8556f62 Mon Sep 17 00:00:00 2001
    From: "Vicente J. Botet Escriba" 
    Date: Thu, 14 Mar 2013 17:35:42 +0000
    Subject: [PATCH 106/126] Utility: merge [68982] to fix #5213.
    
    [SVN r83427]
    ---
     include/boost/assert.hpp | 7 ++++++-
     1 file changed, 6 insertions(+), 1 deletion(-)
    
    diff --git a/include/boost/assert.hpp b/include/boost/assert.hpp
    index 174f084..a233505 100644
    --- a/include/boost/assert.hpp
    +++ b/include/boost/assert.hpp
    @@ -101,7 +101,12 @@ namespace boost
                   << "***** Internal Program Error - assertion (" << expr << ") failed in "
                   << function << ":\n"
                   << file << '(' << line << "): " << msg << std::endl;
    -            std::abort();
    +			#ifdef UNDER_CE
    +				// The Windows CE CRT library does not have abort() so use exit(-1) instead.
    +				std::exit(-1);
    +			#else
    +				std::abort();
    +			#endif
               }
             } // detail
           } // assertion
    
    From 2eda3f52999e844adf93e753ffee31966a00e8d5 Mon Sep 17 00:00:00 2001
    From: "Vicente J. Botet Escriba" 
    Date: Sat, 23 Mar 2013 01:44:06 +0000
    Subject: [PATCH 107/126] Utility/address_off: fix #7079.
    
    [SVN r83524]
    ---
     include/boost/utility/addressof.hpp | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/include/boost/utility/addressof.hpp b/include/boost/utility/addressof.hpp
    index 95cd92f..ecb7776 100644
    --- a/include/boost/utility/addressof.hpp
    +++ b/include/boost/utility/addressof.hpp
    @@ -1,4 +1,4 @@
    -// Copyright (C) 2002 Brad King (brad.king@kitware.com) 
    +// Copyright (C) 2002 Brad King (brad.king@kitware.com)
     //                    Douglas Gregor (gregod@cs.rpi.edu)
     //
     // Copyright (C) 2002, 2008 Peter Dimov
    @@ -50,7 +50,7 @@ template struct addressof_impl
     
     template T * addressof( T & v )
     {
    -#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) )
    +#if (defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) ) ) || defined( __SUNPRO_CC )
     
         return boost::detail::addressof_impl::f( v, 0 );
     
    
    From 4080fe22e3e4beeb513e5eb3dd3852d3a4b98ca1 Mon Sep 17 00:00:00 2001
    From: "Vicente J. Botet Escriba" 
    Date: Sat, 13 Apr 2013 13:49:52 +0000
    Subject: [PATCH 108/126] utility/noncopyable : fix #6578.
    
    [SVN r83869]
    ---
     include/boost/noncopyable.hpp | 18 +++++++++++++++---
     utility.htm                   | 10 +++++++---
     2 files changed, 22 insertions(+), 6 deletions(-)
    
    diff --git a/include/boost/noncopyable.hpp b/include/boost/noncopyable.hpp
    index 7770bdb..eb8e2e7 100644
    --- a/include/boost/noncopyable.hpp
    +++ b/include/boost/noncopyable.hpp
    @@ -9,6 +9,8 @@
     #ifndef BOOST_NONCOPYABLE_HPP_INCLUDED
     #define BOOST_NONCOPYABLE_HPP_INCLUDED
     
    +#include 
    +
     namespace boost {
     
     //  Private copy constructor and copy assignment ensure classes derived from
    @@ -21,11 +23,21 @@ namespace noncopyable_  // protection from unintended ADL
       class noncopyable
       {
        protected:
    -      noncopyable() {}
    +#ifndef BOOST_NO_DEFAULTED_FUNCTIONS
    +    BOOST_CONSTEXPR noncopyable() = default;
    +    ~noncopyable() = default;
    +#else
    +    noncopyable() {}
           ~noncopyable() {}
    -   private:  // emphasize the following members are private
    +#endif
    +#ifndef BOOST_NO_DELETED_FUNCTIONS
    +        noncopyable( const noncopyable& ) = delete;
    +        noncopyable& operator=( const noncopyable& ) = delete;
    +#else
    +    private:  // emphasize the following members are private
           noncopyable( const noncopyable& );
    -      const noncopyable& operator=( const noncopyable& );
    +      noncopyable& operator=( const noncopyable& );
    +#endif
       };
     }
     
    diff --git a/utility.htm b/utility.htm
    index 94920c3..974776e 100644
    --- a/utility.htm
    +++ b/utility.htm
    @@ -84,8 +84,10 @@ const std::list<T>::iterator next = boost::next(prev, 2);
    will prevent the otherwise implicitly-generated functions (which don't have the proper semantics) from becoming a trap for other programmers.

    The traditional way to deal with these is to declare a private copy constructor - and copy assignment, and then document why this is done.  But deriving - from noncopyable is simpler and clearer, and doesn't require additional + and copy assignment, and then document why this is done.  A new alternative + was introduced in C++2011, declaring a copy constructor and a copy assignment + operator, but marking both as deleted.  Deriving + from noncopyable is simpler and clearer, and doesn't require additional documentation.

    The program noncopyable_test.cpp can be used to verify class noncopyable works as expected. It has have been run @@ -106,7 +108,9 @@ class ResourceLadenFileSystem : boost::noncopyable { about the effect on compiler optimization of adding (even trivial inline) destructor declarations. He says "Probably this concern is misplaced, because noncopyable will be used mostly for classes which own resources and - thus have non-trivial destruction semantics."

    + thus have non-trivial destruction semantics."  With C++2011, using an + optimized and trivial constructor and similar destructor can be enforced by + declaring both and marking them default.

    Function template addressof()

    Function addressof() returns the address of an object.

    From 0d605befd4c053bff3cdfbf071fc4dd602cb0599 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Thu, 23 May 2013 18:38:20 +0000 Subject: [PATCH 109/126] Merge bug fix in test to release [SVN r84449] --- test/string_ref_test2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/string_ref_test2.cpp b/test/string_ref_test2.cpp index 89e1cfc..174405d 100644 --- a/test/string_ref_test2.cpp +++ b/test/string_ref_test2.cpp @@ -23,7 +23,7 @@ void ends_with ( const char *arg ) { string_ref sr2 ( arg ); const char *p = arg; - while ( !*p ) { + while ( *p ) { BOOST_CHECK ( sr.ends_with ( p )); ++p; } From e02523e2863cc9efc5f404a7df25f9cd5dfdd008 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Fri, 7 Jun 2013 17:33:25 +0000 Subject: [PATCH 110/126] Merged changes from trunk. Fixes operator<< handling of width specification. [SVN r84674] --- include/boost/utility/string_ref.hpp | 178 ++++++++++++---------- include/boost/utility/string_ref_fwd.hpp | 37 +++++ test/Jamfile.v2 | 1 + test/string_ref_test_io.cpp | 183 +++++++++++++++++++++++ 4 files changed, 320 insertions(+), 79 deletions(-) create mode 100644 include/boost/utility/string_ref_fwd.hpp create mode 100644 test/string_ref_test_io.cpp diff --git a/include/boost/utility/string_ref.hpp b/include/boost/utility/string_ref.hpp index 6d5cace..9018513 100644 --- a/include/boost/utility/string_ref.hpp +++ b/include/boost/utility/string_ref.hpp @@ -17,11 +17,15 @@ #include #include +#include +#include +#include #include #include -#include +#include #include +#include namespace boost { @@ -36,18 +40,6 @@ namespace boost { }; } - template class basic_string_ref; - typedef basic_string_ref > string_ref; - typedef basic_string_ref > wstring_ref; - -#ifndef BOOST_NO_CXX11_CHAR16_T - typedef basic_string_ref > u16string_ref; -#endif - -#ifndef BOOST_NO_CXX11_CHAR32_T - typedef basic_string_ref > u32string_ref; -#endif - template class basic_string_ref { public: @@ -61,7 +53,7 @@ namespace boost { typedef std::reverse_iterator const_reverse_iterator; typedef const_reverse_iterator reverse_iterator; typedef std::size_t size_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1); // construct/copy @@ -119,7 +111,7 @@ namespace boost { const charT& at(size_t pos) const { if ( pos >= len_ ) - throw std::out_of_range ( "boost::string_ref::at" ); + BOOST_THROW_EXCEPTION( std::out_of_range ( "boost::string_ref::at" ) ); return ptr_[pos]; } @@ -144,18 +136,12 @@ namespace boost { // basic_string_ref string operations - BOOST_CONSTEXPR basic_string_ref substr(size_type pos, size_type n=npos) const { -#if BOOST_WORKAROUND(BOOST_MSVC, <= 1600) - // Looks like msvc 8 and 9 have a codegen bug when one branch of - // a conditional operator is a throw expression. -EAN 2012/12/04 - if ( pos > size()) throw std::out_of_range ( "string_ref::substr" ); - if ( n == npos || pos + n > size()) n = size () - pos; + if ( pos > size()) + BOOST_THROW_EXCEPTION( std::out_of_range ( "string_ref::substr" ) ); + if ( n == npos || pos + n > size()) + n = size () - pos; return basic_string_ref ( data() + pos, n ); -#else - return pos > size() ? throw std::out_of_range ( "string_ref::substr" ) : - basic_string_ref ( data() + pos, n == npos || pos + n > size() ? size() - pos : n ); -#endif } int compare(basic_string_ref x) const { @@ -260,173 +246,207 @@ namespace boost { // Comparison operators // Equality template - bool operator==(basic_string_ref x, basic_string_ref y) { + inline bool operator==(basic_string_ref x, basic_string_ref y) { if ( x.size () != y.size ()) return false; return x.compare(y) == 0; } template - bool operator==(basic_string_ref x, const std::basic_string & y) { + inline bool operator==(basic_string_ref x, const std::basic_string & y) { return x == basic_string_ref(y); } template - bool operator==(const std::basic_string & x, basic_string_ref y) { + inline bool operator==(const std::basic_string & x, basic_string_ref y) { return basic_string_ref(x) == y; } template - bool operator==(basic_string_ref x, const charT * y) { + inline bool operator==(basic_string_ref x, const charT * y) { return x == basic_string_ref(y); } template - bool operator==(const charT * x, basic_string_ref y) { + inline bool operator==(const charT * x, basic_string_ref y) { return basic_string_ref(x) == y; } // Inequality template - bool operator!=(basic_string_ref x, basic_string_ref y) { + inline bool operator!=(basic_string_ref x, basic_string_ref y) { if ( x.size () != y.size ()) return true; return x.compare(y) != 0; } template - bool operator!=(basic_string_ref x, const std::basic_string & y) { + inline bool operator!=(basic_string_ref x, const std::basic_string & y) { return x != basic_string_ref(y); } template - bool operator!=(const std::basic_string & x, basic_string_ref y) { + inline bool operator!=(const std::basic_string & x, basic_string_ref y) { return basic_string_ref(x) != y; } template - bool operator!=(basic_string_ref x, const charT * y) { + inline bool operator!=(basic_string_ref x, const charT * y) { return x != basic_string_ref(y); } template - bool operator!=(const charT * x, basic_string_ref y) { + inline bool operator!=(const charT * x, basic_string_ref y) { return basic_string_ref(x) != y; } // Less than template - bool operator<(basic_string_ref x, basic_string_ref y) { + inline bool operator<(basic_string_ref x, basic_string_ref y) { return x.compare(y) < 0; } template - bool operator<(basic_string_ref x, const std::basic_string & y) { + inline bool operator<(basic_string_ref x, const std::basic_string & y) { return x < basic_string_ref(y); } template - bool operator<(const std::basic_string & x, basic_string_ref y) { + inline bool operator<(const std::basic_string & x, basic_string_ref y) { return basic_string_ref(x) < y; } template - bool operator<(basic_string_ref x, const charT * y) { + inline bool operator<(basic_string_ref x, const charT * y) { return x < basic_string_ref(y); } template - bool operator<(const charT * x, basic_string_ref y) { + inline bool operator<(const charT * x, basic_string_ref y) { return basic_string_ref(x) < y; } // Greater than template - bool operator>(basic_string_ref x, basic_string_ref y) { + inline bool operator>(basic_string_ref x, basic_string_ref y) { return x.compare(y) > 0; } template - bool operator>(basic_string_ref x, const std::basic_string & y) { + inline bool operator>(basic_string_ref x, const std::basic_string & y) { return x > basic_string_ref(y); } template - bool operator>(const std::basic_string & x, basic_string_ref y) { + inline bool operator>(const std::basic_string & x, basic_string_ref y) { return basic_string_ref(x) > y; } template - bool operator>(basic_string_ref x, const charT * y) { + inline bool operator>(basic_string_ref x, const charT * y) { return x > basic_string_ref(y); } template - bool operator>(const charT * x, basic_string_ref y) { + inline bool operator>(const charT * x, basic_string_ref y) { return basic_string_ref(x) > y; } // Less than or equal to template - bool operator<=(basic_string_ref x, basic_string_ref y) { + inline bool operator<=(basic_string_ref x, basic_string_ref y) { return x.compare(y) <= 0; } template - bool operator<=(basic_string_ref x, const std::basic_string & y) { + inline bool operator<=(basic_string_ref x, const std::basic_string & y) { return x <= basic_string_ref(y); } template - bool operator<=(const std::basic_string & x, basic_string_ref y) { + inline bool operator<=(const std::basic_string & x, basic_string_ref y) { return basic_string_ref(x) <= y; } template - bool operator<=(basic_string_ref x, const charT * y) { + inline bool operator<=(basic_string_ref x, const charT * y) { return x <= basic_string_ref(y); } template - bool operator<=(const charT * x, basic_string_ref y) { + inline bool operator<=(const charT * x, basic_string_ref y) { return basic_string_ref(x) <= y; } // Greater than or equal to template - bool operator>=(basic_string_ref x, basic_string_ref y) { + inline bool operator>=(basic_string_ref x, basic_string_ref y) { return x.compare(y) >= 0; } template - bool operator>=(basic_string_ref x, const std::basic_string & y) { + inline bool operator>=(basic_string_ref x, const std::basic_string & y) { return x >= basic_string_ref(y); } template - bool operator>=(const std::basic_string & x, basic_string_ref y) { + inline bool operator>=(const std::basic_string & x, basic_string_ref y) { return basic_string_ref(x) >= y; } template - bool operator>=(basic_string_ref x, const charT * y) { + inline bool operator>=(basic_string_ref x, const charT * y) { return x >= basic_string_ref(y); } template - bool operator>=(const charT * x, basic_string_ref y) { + inline bool operator>=(const charT * x, basic_string_ref y) { return basic_string_ref(x) >= y; } + namespace detail { + + template + inline void insert_fill_chars(std::basic_ostream& os, std::size_t n) { + enum { chunk_size = 8 }; + charT fill_chars[chunk_size]; + std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill()); + for (; n >= chunk_size && os.good(); n -= chunk_size) + os.write(fill_chars, static_cast< std::size_t >(chunk_size)); + if (n > 0 && os.good()) + os.write(fill_chars, n); + } + + template + void insert_aligned(std::basic_ostream& os, const basic_string_ref& str) { + const std::size_t size = str.size(); + const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size; + const bool align_left = (os.flags() & std::basic_ostream::adjustfield) == std::basic_ostream::left; + if (!align_left) { + detail::insert_fill_chars(os, alignment_size); + if (os.good()) + os.write(str.data(), size); + } + else { + os.write(str.data(), size); + if (os.good()) + detail::insert_fill_chars(os, alignment_size); + } + } + + } // namespace detail + // Inserter template - std::basic_ostream& + inline std::basic_ostream& operator<<(std::basic_ostream& os, const basic_string_ref& str) { -#ifdef BOOST_NO_CXX11_RANGE_BASED_FOR - for ( typename basic_string_ref::const_iterator iter = str.begin (); iter != str.end (); ++iter ) - os << *iter; -#else - for ( charT x : str ) - os << x; -#endif + if (os.good()) { + const std::size_t size = str.size(); + const std::size_t w = static_cast< std::size_t >(os.width()); + if (w <= size) + os.write(str.data(), size); + else + detail::insert_aligned(os, str); + os.width(0); + } return os; } @@ -436,67 +456,67 @@ namespace boost { // These are short-term implementations. // In a production environment, I would rather avoid the copying. // - int stoi (string_ref str, size_t* idx=0, int base=10) { + inline int stoi (string_ref str, size_t* idx=0, int base=10) { return std::stoi ( std::string(str), idx, base ); } - long stol (string_ref str, size_t* idx=0, int base=10) { + inline long stol (string_ref str, size_t* idx=0, int base=10) { return std::stol ( std::string(str), idx, base ); } - unsigned long stoul (string_ref str, size_t* idx=0, int base=10) { + inline unsigned long stoul (string_ref str, size_t* idx=0, int base=10) { return std::stoul ( std::string(str), idx, base ); } - long long stoll (string_ref str, size_t* idx=0, int base=10) { + inline long long stoll (string_ref str, size_t* idx=0, int base=10) { return std::stoll ( std::string(str), idx, base ); } - unsigned long long stoull (string_ref str, size_t* idx=0, int base=10) { + inline unsigned long long stoull (string_ref str, size_t* idx=0, int base=10) { return std::stoull ( std::string(str), idx, base ); } - float stof (string_ref str, size_t* idx=0) { + inline float stof (string_ref str, size_t* idx=0) { return std::stof ( std::string(str), idx ); } - double stod (string_ref str, size_t* idx=0) { + inline double stod (string_ref str, size_t* idx=0) { return std::stod ( std::string(str), idx ); } - long double stold (string_ref str, size_t* idx=0) { + inline long double stold (string_ref str, size_t* idx=0) { return std::stold ( std::string(str), idx ); } - int stoi (wstring_ref str, size_t* idx=0, int base=10) { + inline int stoi (wstring_ref str, size_t* idx=0, int base=10) { return std::stoi ( std::wstring(str), idx, base ); } - long stol (wstring_ref str, size_t* idx=0, int base=10) { + inline long stol (wstring_ref str, size_t* idx=0, int base=10) { return std::stol ( std::wstring(str), idx, base ); } - unsigned long stoul (wstring_ref str, size_t* idx=0, int base=10) { + inline unsigned long stoul (wstring_ref str, size_t* idx=0, int base=10) { return std::stoul ( std::wstring(str), idx, base ); } - long long stoll (wstring_ref str, size_t* idx=0, int base=10) { + inline long long stoll (wstring_ref str, size_t* idx=0, int base=10) { return std::stoll ( std::wstring(str), idx, base ); } - unsigned long long stoull (wstring_ref str, size_t* idx=0, int base=10) { + inline unsigned long long stoull (wstring_ref str, size_t* idx=0, int base=10) { return std::stoull ( std::wstring(str), idx, base ); } - float stof (wstring_ref str, size_t* idx=0) { + inline float stof (wstring_ref str, size_t* idx=0) { return std::stof ( std::wstring(str), idx ); } - double stod (wstring_ref str, size_t* idx=0) { + inline double stod (wstring_ref str, size_t* idx=0) { return std::stod ( std::wstring(str), idx ); } - long double stold (wstring_ref str, size_t* idx=0) { + inline long double stold (wstring_ref str, size_t* idx=0) { return std::stold ( std::wstring(str), idx ); } #endif diff --git a/include/boost/utility/string_ref_fwd.hpp b/include/boost/utility/string_ref_fwd.hpp new file mode 100644 index 0000000..f58b98c --- /dev/null +++ b/include/boost/utility/string_ref_fwd.hpp @@ -0,0 +1,37 @@ +/* + 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 + + Based on the StringRef implementation in LLVM (http://llvm.org) and + N3422 by Jeffrey Yasskin + http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html + +*/ + +#ifndef BOOST_STRING_REF_FWD_HPP +#define BOOST_STRING_REF_FWD_HPP + +#include +#include + +namespace boost { + + template > class basic_string_ref; + typedef basic_string_ref > string_ref; + typedef basic_string_ref > wstring_ref; + +#ifndef BOOST_NO_CXX11_CHAR16_T + typedef basic_string_ref > u16string_ref; +#endif + +#ifndef BOOST_NO_CXX11_CHAR32_T + typedef basic_string_ref > u32string_ref; +#endif + +} + +#endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index d597cb8..cec9727 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -38,6 +38,7 @@ test-suite utility [ run ../shared_iterator_test.cpp ] [ run string_ref_test1.cpp unit_test_framework ] [ run string_ref_test2.cpp unit_test_framework ] + [ run string_ref_test_io.cpp unit_test_framework ] [ run ../value_init_test.cpp ] [ run ../value_init_workaround_test.cpp ] [ run ../initialized_test.cpp ] diff --git a/test/string_ref_test_io.cpp b/test/string_ref_test_io.cpp new file mode 100644 index 0000000..376f695 --- /dev/null +++ b/test/string_ref_test_io.cpp @@ -0,0 +1,183 @@ +/* + * 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. + */ + +#define BOOST_TEST_MODULE string_ref_test_io + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +typedef boost::mpl::vector< + char +#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_STD_WSTREAMBUF) && !defined(BOOST_NO_INTRINSIC_WCHAR_T) + , wchar_t +#endif +/* Current implementations seem to be missing codecvt facets to convert chars to char16_t and char32_t even though the types are available. +#if !defined(BOOST_NO_CXX11_CHAR16_T) + , char16_t +#endif +#if !defined(BOOST_NO_CXX11_CHAR32_T) + , char32_t +#endif +*/ +>::type char_types; + +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 +BOOST_AUTO_TEST_CASE_TEMPLATE(string_ref_output, CharT, char_types) +{ + typedef CharT char_type; + typedef std::basic_string< char_type > string_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_CHECK(strm.str() == ctx.abcd); +} + +// Test support for padding +BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types) +{ + typedef CharT char_type; + typedef std::basic_string< char_type > string_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_CHECK(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_CHECK(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_CHECK(strm_ref.str() == strm_correct.str()); + } +} + +// Test support for padding fill +BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types) +{ + typedef CharT char_type; + typedef std::basic_string< char_type > string_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_CHECK(strm_ref.str() == strm_correct.str()); +} + +// Test support for alignment +BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types) +{ + typedef CharT char_type; + typedef std::basic_string< char_type > string_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_CHECK(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_CHECK(strm_ref.str() == strm_correct.str()); + } +} From b813232bba9a7f474e3efa3a2b9ad89cf874fa83 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sat, 20 Jul 2013 17:17:10 +0000 Subject: [PATCH 111/126] Merged recent changes from trunk. [SVN r85088] --- include/boost/assert.hpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/include/boost/assert.hpp b/include/boost/assert.hpp index a233505..ccc776a 100644 --- a/include/boost/assert.hpp +++ b/include/boost/assert.hpp @@ -34,6 +34,7 @@ #elif defined(BOOST_ENABLE_ASSERT_HANDLER) +#include #include namespace boost @@ -42,7 +43,7 @@ namespace boost char const * function, char const * file, long line); // user defined } // namespace boost -#define BOOST_ASSERT(expr) ((expr) \ +#define BOOST_ASSERT(expr) (BOOST_LIKELY(!!(expr)) \ ? ((void)0) \ : ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) @@ -63,6 +64,7 @@ namespace boost #elif defined(BOOST_ENABLE_ASSERT_HANDLER) + #include #include namespace boost @@ -71,7 +73,7 @@ namespace boost char const * function, char const * file, long line); // user defined } // namespace boost - #define BOOST_ASSERT_MSG(expr, msg) ((expr) \ + #define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr)) \ ? ((void)0) \ : ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) @@ -80,6 +82,7 @@ namespace boost #define BOOST_ASSERT_HPP #include #include + #include #include // IDE's like Visual Studio perform better if output goes to std::cout or @@ -89,31 +92,33 @@ namespace boost #endif namespace boost - { - namespace assertion - { + { + namespace assertion + { namespace detail { - inline void assertion_failed_msg(char const * expr, char const * msg, char const * function, + // Note: The template is needed to make the function non-inline and avoid linking errors + template< typename CharT > + BOOST_NOINLINE void assertion_failed_msg(CharT const * expr, char const * msg, char const * function, char const * file, long line) { BOOST_ASSERT_MSG_OSTREAM << "***** Internal Program Error - assertion (" << expr << ") failed in " << function << ":\n" << file << '(' << line << "): " << msg << std::endl; - #ifdef UNDER_CE - // The Windows CE CRT library does not have abort() so use exit(-1) instead. - std::exit(-1); - #else - std::abort(); - #endif +#ifdef UNDER_CE + // The Windows CE CRT library does not have abort() so use exit(-1) instead. + std::exit(-1); +#else + std::abort(); +#endif } } // detail } // assertion } // detail #endif - #define BOOST_ASSERT_MSG(expr, msg) ((expr) \ + #define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr)) \ ? ((void)0) \ : ::boost::assertion::detail::assertion_failed_msg(#expr, msg, \ BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) From b051dd665bac7e3045469ae2f10a0bfb8f178287 Mon Sep 17 00:00:00 2001 From: Robert Kawulak Date: Tue, 13 Aug 2013 21:39:57 +0000 Subject: [PATCH 112/126] [utility] Fixes to value_init docs. [SVN r85335] --- value_init.htm | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/value_init.htm b/value_init.htm index 4ae9177..b82792f 100644 --- a/value_init.htm +++ b/value_init.htm @@ -295,7 +295,7 @@ so for those compilers that need to have such a workaround, based on the
    operator T&() { return x ; }
    T const &data() const { return x ; }
    T& data() { return x ; } -
    void swap( value_initialized<T>& ); +
    void swap( value_initialized& );

    private :
    unspecified x ; @@ -313,6 +313,12 @@ so for those compilers that need to have such a workaround, based on the
    return x.data() ;
    }
    +
    template<class T> +
    void swap ( value_initialized<T>& lhs, value_initialized<T>& rhs ) +
    { +
    lhs.swap(rhs) ; +
    } +

    } // namespace boost
    @@ -385,7 +391,7 @@ the wrapped object is always performed with the get() idiom:


    operator T&();
    T const &data() const;
    T& data(); -
    void swap( value_initialized<T>& ); +
    void swap( initialized& );

    private :
    unspecified x ; @@ -397,6 +403,9 @@ the wrapped object is always performed with the get() idiom:


    template<class T>
    T& get ( initialized<T>& x );
    +
    template<class T> +
    void swap ( initialized<T>& lhs, initialized<T>& rhs ); +

    } // namespace boost
    From e33f8b0055bb78072337d65ab1e5cbf6517221bd Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sun, 8 Sep 2013 19:28:44 +0000 Subject: [PATCH 113/126] Merged new added components from trunk. Merged other sublibraries which tests are passing for a long time as well. [SVN r85613] --- base_from_member.html | 53 ++++++-- call_traits_test.cpp | 8 +- doc/Jamfile.v2 | 23 +++- doc/explicit_operator_bool.qbk | 68 ++++++++++ include/boost/utility/base_from_member.hpp | 73 +++++++++- include/boost/utility/declval.hpp | 41 +++--- .../utility/detail/result_of_iterate.hpp | 25 +++- include/boost/utility/empty_deleter.hpp | 43 ++++++ .../boost/utility/explicit_operator_bool.hpp | 128 ++++++++++++++++++ include/boost/utility/result_of.hpp | 29 ++-- index.html | 12 +- test/Jamfile.v2 | 5 + test/explicit_operator_bool.cpp | 54 ++++++++ ...it_operator_bool_compile_fail_conv_int.cpp | 40 ++++++ ..._operator_bool_compile_fail_conv_pvoid.cpp | 40 ++++++ ...icit_operator_bool_compile_fail_delete.cpp | 40 ++++++ ...licit_operator_bool_compile_fail_shift.cpp | 40 ++++++ test/result_of_test.cpp | 14 +- utility.htm | 40 ++++++ value_init_test.cpp | 87 ++++++------ 20 files changed, 756 insertions(+), 107 deletions(-) create mode 100644 doc/explicit_operator_bool.qbk create mode 100644 include/boost/utility/empty_deleter.hpp create mode 100644 include/boost/utility/explicit_operator_bool.hpp create mode 100644 test/explicit_operator_bool.cpp create mode 100644 test/explicit_operator_bool_compile_fail_conv_int.cpp create mode 100644 test/explicit_operator_bool_compile_fail_conv_pvoid.cpp create mode 100644 test/explicit_operator_bool_compile_fail_delete.cpp create mode 100644 test/explicit_operator_bool_compile_fail_shift.cpp diff --git a/base_from_member.html b/base_from_member.html index 21ee6d2..07e144e 100644 --- a/base_from_member.html +++ b/base_from_member.html @@ -129,6 +129,8 @@ particular member type does not need to concern itself with the integer.

    Synopsis

    +#include <type_traits>  // exposition only
    +
     #ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY
     #define BOOST_BASE_FROM_MEMBER_MAX_ARITY  10
     #endif
    @@ -139,6 +141,11 @@ class boost::base_from_member
     protected:
         MemberType  member;
     
    +#if C++2011 is in use
    +    template< typename ...T >
    +    explicit constexpr   base_from_member( T&& ...x )
    +     noexcept( std::is_nothrow_constructible<MemberType, T...>::value );
    +#else
         base_from_member();
     
         template< typename T1 >
    @@ -154,6 +161,7 @@ protected:
          typename T10 >
         base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7,
          T8 x8, T9 x9, T10 x10 );
    +#endif
     };
     
    @@ -166,13 +174,29 @@ value of zero if it is omitted. The class template has a protected data member called member that the derived class can use for later base classes (or itself).

    -

    There is a default constructor and several constructor member -templates. These constructor templates can take as many arguments -(currently up to ten) as possible and pass them to a constructor of -the data member. Since C++ does not allow any way to explicitly state +

    If the appropriate features of C++2011 are present, there will be a single +constructor template. It implements "perfect forwarding" to the best +constructor call of member (if any). The constructor template is +marked both constexpr and explicit. The former will +be ignored if the corresponding inner constructor call (of member) +does not have the marker. The latter binds the other way; always taking +effect, even when the inner constructor call does not have the marker. The +constructor template propagates the noexcept status of the inner +constructor call. (The constructor template has a trailing parameter with a +default value that disables the template when its signature is too close to the +signatures of the automatically-defined non-template copy- and/or +move-constructors of base_from_member.)

    + +

    On earlier-standard compilers, there is a default constructor and several +constructor member templates. These constructor templates can take as many +arguments (currently up to ten) as possible and pass them to a constructor of +the data member.

    + +

    Since C++ does not allow any way to explicitly state the template parameters of a templated constructor, make sure that the arguments are already close as possible to the actual type used in -the data member's desired constructor.

    +the data member's desired constructor. Explicit conversions may be +necessary.

    The BOOST_BASE_FROM_MEMBER_MAX_ARITY macro constant specifies the maximum argument length for the constructor templates. The constant @@ -180,7 +204,7 @@ may be overridden if more (or less) argument configurations are needed. The constant may be read for code that is expandable like the class template and needs to maintain the same maximum size. (Example code would be a class that uses this class template as a base class for a member with a flexible set of -constructors.)

    +constructors.) This constant is ignored when C++2011 features are present.

    Usage

    @@ -323,11 +347,14 @@ constructor argument for pbase0_type is converted from argument for pbase2_type is converted from int to double. The second constructor argument for pbase3_type is a special case of necessary conversion; all -forms of the null-pointer literal in C++ also look like compile-time -integral expressions, so C++ always interprets such code as an integer -when it has overloads that can take either an integer or a pointer. The -last conversion is necessary for the compiler to call a constructor form -with the exact pointer type used in switcher's constructor.

    +forms of the null-pointer literal in C++ (except nullptr from +C++2011) also look like compile-time integral expressions, so C++ always +interprets such code as an integer when it has overloads that can take either +an integer or a pointer. The last conversion is necessary for the compiler to +call a constructor form with the exact pointer type used in +switcher's constructor. (If C++2011's nullptr is +used, it still needs a conversion if multiple pointer types can be accepted in +a constructor call but std::nullptr_t cannot.)

    Credits

    @@ -360,9 +387,9 @@ with the exact pointer type used in switcher's constructor.


    -

    Revised: 28 August 2004

    +

    Revised: 16 February 2012

    -

    Copyright 2001, 2003, 2004 Daryle Walker. Use, modification, and distribution +

    Copyright 2001, 2003, 2004, 2012 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>.)

    diff --git a/call_traits_test.cpp b/call_traits_test.cpp index 72852c4..9e49b68 100644 --- a/call_traits_test.cpp +++ b/call_traits_test.cpp @@ -210,8 +210,10 @@ int main() comparible_UDT u; c1(u); call_traits_checker c2; + call_traits_checker c2b; int i = 2; c2(i); + c2b(one); int* pi = &i; int a[2] = {1,2}; #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL) @@ -292,7 +294,11 @@ int main() BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits::reference); BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits::const_reference); BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits::param_type); - + // test enum: + BOOST_CHECK_TYPE(enum_UDT, boost::call_traits::value_type); + BOOST_CHECK_TYPE(enum_UDT&, boost::call_traits::reference); + BOOST_CHECK_TYPE(const enum_UDT&, boost::call_traits::const_reference); + BOOST_CHECK_TYPE(const enum_UDT, boost::call_traits::param_type); return 0; } diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index a0ff034..a734cb2 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -6,7 +6,7 @@ project : requirements # Path for links to Boost: boost.root=../../../.. - + # Some general style settings: table.footnote.number.format=1 footnote.number.format=1 @@ -59,7 +59,6 @@ boostbook standalone_declval toc.max.depth=1 # How far down we go with TOC's generate.section.toc.level=1 - ; xml string_ref : string_ref.qbk ; @@ -79,5 +78,23 @@ boostbook standalone_string_ref toc.max.depth=1 # How far down we go with TOC's generate.section.toc.level=1 - + ; + +xml explicit_operator_bool : explicit_operator_bool.qbk ; +boostbook standalone_explicit_operator_bool + : + explicit_operator_bool + : + # File name of HTML output: + root.filename=explicit_operator_bool + # How far down we chunk nested sections, basically all of them: + chunk.section.depth=0 + # Don't put the first section on the same page as the TOC: + chunk.first.sections=0 + # How far down sections get TOC's + toc.section.depth=1 + # Max depth in each TOC: + toc.max.depth=1 + # How far down we go with TOC's + generate.section.toc.level=1 ; diff --git a/doc/explicit_operator_bool.qbk b/doc/explicit_operator_bool.qbk new file mode 100644 index 0000000..4a7e4b1 --- /dev/null +++ b/doc/explicit_operator_bool.qbk @@ -0,0 +1,68 @@ +[/ + / Copyright (c) 2013 Andrey Semashev + / + / 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) + /] + +[article BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL + [quickbook 1.5] + [authors [Semashev, Andrey]] + [copyright 2013 Andrey Semashev] + [license + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + [@http://www.boost.org/LICENSE_1_0.txt]) + ] +] + +[/===============] +[section Overview] +[/===============] + +`BOOST_EXPLICIT_OPERATOR_BOOL()` and `BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()` are compatibility helper macros that expand to an explicit conversion operator to `bool`. For compilers not supporting explicit conversion operators introduced in C++11 the macros expand to a conversion operator that implements the [@http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool safe bool idiom]. In case if the compiler is not able to handle safe bool idiom well the macros expand to a regular conversion operator to `bool`. + +[endsect] + + +[/===============] +[section Examples] +[/===============] + +Both macros are intended to be placed within a user's class definition. The generated conversion operators will be implemented in terms of `operator!()` that should be defined by user in this class. In case of `BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()` the generated conversion operator will be declared `constexpr` which requires the corresponding `operator!()` to also be `constexpr`. + + template< typename T > + class my_ptr + { + T* m_p; + + public: + BOOST_EXPLICIT_OPERATOR_BOOL() + + bool operator!() const + { + return !m_p; + } + }; + +Now `my_ptr` can be used in conditional expressions, similarly to a regular pointer: + + my_ptr< int > p; + if (p) + std::cout << "true" << std::endl; + +[endsect] + +[/===============] +[section History] +[/===============] + +[heading boost 1.55] + +* The macro was extracted from Boost.Log. + +[endsect] + + + + diff --git a/include/boost/utility/base_from_member.hpp b/include/boost/utility/base_from_member.hpp index 04aabb5..e32ecb8 100644 --- a/include/boost/utility/base_from_member.hpp +++ b/include/boost/utility/base_from_member.hpp @@ -1,6 +1,6 @@ // boost utility/base_from_member.hpp header file --------------------------// -// Copyright 2001, 2003, 2004 Daryle Walker. Use, modification, and +// Copyright 2001, 2003, 2004, 2012 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 // .) @@ -10,10 +10,15 @@ #ifndef BOOST_UTILITY_BASE_FROM_MEMBER_HPP #define BOOST_UTILITY_BASE_FROM_MEMBER_HPP +#include #include #include #include #include +#include +#include +#include +#include // Base-from-member arity configuration macro ------------------------------// @@ -53,6 +58,59 @@ namespace boost { +namespace detail +{ + +// Type-unmarking class template -------------------------------------------// + +// Type-trait to get the raw type, i.e. the type without top-level reference nor +// cv-qualification, from a type expression. Mainly for function arguments, any +// reference part is stripped first. + +// Contributed by Daryle Walker + +template < typename T > +struct remove_cv_ref +{ + typedef typename ::boost::remove_cv::type>::type type; + +}; // boost::detail::remove_cv_ref + +// Unmarked-type comparison class template ---------------------------------// + +// Type-trait to check if two type expressions have the same raw type. + +// Contributed by Daryle Walker, based on a work-around by Luc Danton + +template < typename T, typename U > +struct is_related + : public ::boost::is_same< + typename ::boost::detail::remove_cv_ref::type, + typename ::boost::detail::remove_cv_ref::type > +{}; + +// Enable-if-on-unidentical-unmarked-type class template -------------------// + +// Enable-if on the first two type expressions NOT having the same raw type. + +// Contributed by Daryle Walker, based on a work-around by Luc Danton + +#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES +template +struct enable_if_unrelated + : public ::boost::enable_if_c +{}; + +template +struct enable_if_unrelated + : public ::boost::disable_if< ::boost::detail::is_related > +{}; +#endif + +} // namespace boost::detail + + // Base-from-member class template -----------------------------------------// // Helper to initialize a base object so a derived class can use this @@ -68,12 +126,25 @@ class base_from_member protected: MemberType member; +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ + !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && \ + !(defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 4)) + template ::type> + explicit BOOST_CONSTEXPR base_from_member( T&& ...x ) + BOOST_NOEXCEPT_IF( BOOST_NOEXCEPT_EXPR(::new ((void*) 0) MemberType( + static_cast(x)... )) ) // no std::is_nothrow_constructible... + : member( static_cast(x)... ) // ...nor std::forward needed + {} +#else base_from_member() : member() {} BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY), BOOST_PRIVATE_CTR_DEF, _ ) +#endif }; // boost::base_from_member diff --git a/include/boost/utility/declval.hpp b/include/boost/utility/declval.hpp index d74610c..a4ab2c8 100644 --- a/include/boost/utility/declval.hpp +++ b/include/boost/utility/declval.hpp @@ -1,49 +1,44 @@ -// common_type.hpp ---------------------------------------------------------// +// declval.hpp -------------------------------------------------------------// // Copyright 2010 Vicente J. Botet Escriba // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt -#ifndef BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP -#define BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP +#ifndef BOOST_UTILITY_DECLVAL_HPP +#define BOOST_UTILITY_DECLVAL_HPP #include //----------------------------------------------------------------------------// #include -//#include //----------------------------------------------------------------------------// // // // C++03 implementation of // +// 20.2.4 Function template declval [declval] // // Written by Vicente J. Botet Escriba // -//~ 20.3.4 Function template declval [declval] -//~ 1 The library provides the function template declval to simplify the definition of expressions which occur as -//~ unevaluated operands. -//~ 2 Remarks: If this function is used, the program is ill-formed. -//~ 3 Remarks: The template parameter T of declval may be an incomplete type. -//~ [ Example: - -//~ template -//~ decltype(static_cast(declval())) convert(From&&); - -//~ declares a function template convert which only participats in overloading if the type From can be -//~ explicitly converted to type To. For another example see class template common_type (20.7.6.6). —end -//~ example ] // // +// 1 The library provides the function template declval to simplify the +// definition of expressions which occur as unevaluated operands. +// 2 Remarks: If this function is used, the program is ill-formed. +// 3 Remarks: The template parameter T of declval may be an incomplete type. +// [ Example: +// +// template +// decltype(static_cast(declval())) convert(From&&); +// +// declares a function template convert which only participates in overloading +// if the type From can be explicitly converted to type To. For another example +// see class template common_type (20.9.7.6). -end example ] //----------------------------------------------------------------------------// namespace boost { -//#if !defined(BOOST_NO_RVALUE_REFERENCES) template typename add_rvalue_reference::type declval() BOOST_NOEXCEPT; // as unevaluated operand -//#else -// template -// typename add_lvalue_reference::type declval() BOOST_NOEXCEPT; // as unevaluated operand -//#endif + } // namespace boost -#endif // BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP +#endif // BOOST_UTILITY_DECLVAL_HPP diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp index 17fd4d5..5192172 100644 --- a/include/boost/utility/detail/result_of_iterate.hpp +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -38,10 +38,25 @@ struct tr1_result_of #endif #ifdef BOOST_RESULT_OF_USE_DECLTYPE - -// Uses declval following N3225 20.7.7.6 when F is not a pointer. template -struct result_of +struct result_of + : detail::cpp0x_result_of { }; +#endif // BOOST_RESULT_OF_USE_DECLTYPE + +#ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK +template +struct result_of + : mpl::if_, detail::has_result >, + tr1_result_of, + detail::cpp0x_result_of >::type { }; +#endif // BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK + +#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) + +namespace detail { + +template +struct cpp0x_result_of : mpl::if_< is_member_function_pointer , detail::tr1_result_of_impl< @@ -54,8 +69,6 @@ struct result_of >::type {}; -namespace detail { - #ifdef BOOST_NO_SFINAE_EXPR template @@ -139,7 +152,7 @@ struct cpp0x_result_of_impl diff --git a/include/boost/utility/empty_deleter.hpp b/include/boost/utility/empty_deleter.hpp new file mode 100644 index 0000000..ba919cd --- /dev/null +++ b/include/boost/utility/empty_deleter.hpp @@ -0,0 +1,43 @@ +/* + * Copyright Andrey Semashev 2007 - 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 empty_deleter.hpp + * \author Andrey Semashev + * \date 22.04.2007 + * + * This header contains an \c empty_deleter implementation. This is an empty + * function object that receives a pointer and does nothing with it. + * Such empty deletion strategy may be convenient, for example, when + * constructing shared_ptrs that point to some object that should not be + * deleted (i.e. a variable on the stack or some global singleton, like std::cout). + */ + +#ifndef BOOST_UTILITY_EMPTY_DELETER_HPP_INCLUDED_ +#define BOOST_UTILITY_EMPTY_DELETER_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { + +//! A function object that does nothing and can be used as an empty deleter for \c shared_ptr +struct empty_deleter +{ + //! Function object result type + typedef void result_type; + /*! + * Does nothing + */ + void operator() (const volatile void*) const BOOST_NOEXCEPT {} +}; + +} // namespace boost + +#endif // BOOST_UTILITY_EMPTY_DELETER_HPP_INCLUDED_ diff --git a/include/boost/utility/explicit_operator_bool.hpp b/include/boost/utility/explicit_operator_bool.hpp new file mode 100644 index 0000000..650caff --- /dev/null +++ b/include/boost/utility/explicit_operator_bool.hpp @@ -0,0 +1,128 @@ +/* + * Copyright Andrey Semashev 2007 - 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 explicit_operator_bool.hpp + * \author Andrey Semashev + * \date 08.03.2009 + * + * This header defines a compatibility macro that implements an unspecified + * \c bool operator idiom, which is superseded with explicit conversion operators in + * C++11. + */ + +#ifndef BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_ +#define BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) + +/*! + * \brief The macro defines an explicit operator of conversion to \c bool + * + * The macro should be used inside the definition of a class that has to + * support the conversion. The class should also implement operator!, + * in terms of which the conversion operator will be implemented. + */ +#define BOOST_EXPLICIT_OPERATOR_BOOL()\ + BOOST_FORCEINLINE explicit operator bool () const\ + {\ + return !this->operator! ();\ + } + +/*! + * \brief The macro defines a constexpr explicit operator of conversion to \c bool + * + * The macro should be used inside the definition of a class that has to + * support the conversion. The class should also implement operator!, + * in terms of which the conversion operator will be implemented. + */ +#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\ + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit operator bool () const\ + {\ + return !this->operator! ();\ + } + +#else // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) + +#if (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG) +// Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it +#define BOOST_NO_UNSPECIFIED_BOOL +#endif // (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG) + +#if !defined(BOOST_NO_UNSPECIFIED_BOOL) + +namespace boost { + +namespace detail { + +#if !defined(_MSC_VER) && !defined(__IBMCPP__) + + struct unspecified_bool + { + // NOTE TO THE USER: If you see this in error messages then you tried + // to apply an unsupported operator on the object that supports + // explicit conversion to bool. + struct OPERATORS_NOT_ALLOWED; + static void true_value(OPERATORS_NOT_ALLOWED*) {} + }; + typedef void (*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*); + +#else + + // MSVC and VACPP are too eager to convert pointer to function to void* even though they shouldn't + struct unspecified_bool + { + // NOTE TO THE USER: If you see this in error messages then you tried + // to apply an unsupported operator on the object that supports + // explicit conversion to bool. + struct OPERATORS_NOT_ALLOWED; + void true_value(OPERATORS_NOT_ALLOWED*) {} + }; + typedef void (unspecified_bool::*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*); + +#endif + +} // namespace detail + +} // namespace boost + +#define BOOST_EXPLICIT_OPERATOR_BOOL()\ + BOOST_FORCEINLINE operator boost::detail::unspecified_bool_type () const\ + {\ + return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\ + } + +#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\ + BOOST_FORCEINLINE BOOST_CONSTEXPR operator boost::detail::unspecified_bool_type () const\ + {\ + return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\ + } + +#else // !defined(BOOST_NO_UNSPECIFIED_BOOL) + +#define BOOST_EXPLICIT_OPERATOR_BOOL()\ + BOOST_FORCEINLINE operator bool () const\ + {\ + return !this->operator! ();\ + } + +#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\ + BOOST_FORCEINLINE BOOST_CONSTEXPR operator bool () const\ + {\ + return !this->operator! ();\ + } + +#endif // !defined(BOOST_NO_UNSPECIFIED_BOOL) + +#endif // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) + +#endif // BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_ diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp index 97e9618..a530c3a 100644 --- a/include/boost/utility/result_of.hpp +++ b/include/boost/utility/result_of.hpp @@ -38,18 +38,27 @@ // Use the decltype-based version of result_of by default if the compiler // supports N3276 . -// The user can force the choice by defining either BOOST_RESULT_OF_USE_DECLTYPE or -// BOOST_RESULT_OF_USE_TR1, but not both! -#if defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1) -# error Both BOOST_RESULT_OF_USE_DECLTYPE and BOOST_RESULT_OF_USE_TR1 cannot be defined at the same time. +// The user can force the choice by defining BOOST_RESULT_OF_USE_DECLTYPE, +// BOOST_RESULT_OF_USE_TR1, or BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK but not more than one! +#if (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)) || \ + (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) || \ + (defined(BOOST_RESULT_OF_USE_TR1) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) +# error More than one of BOOST_RESULT_OF_USE_DECLTYPE, BOOST_RESULT_OF_USE_TR1 and \ + BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK cannot be defined at the same time. +#endif + +#if defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) && defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) +# error Cannot fallback to decltype if BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE is not defined. #endif #ifndef BOOST_RESULT_OF_USE_TR1 # ifndef BOOST_RESULT_OF_USE_DECLTYPE -# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE) -# define BOOST_RESULT_OF_USE_DECLTYPE -# else -# define BOOST_RESULT_OF_USE_TR1 +# ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK +# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE) +# define BOOST_RESULT_OF_USE_DECLTYPE +# else +# define BOOST_RESULT_OF_USE_TR1 +# endif # endif # endif #endif @@ -64,8 +73,12 @@ namespace detail { BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) +BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result) + template struct tr1_result_of_impl; +template struct cpp0x_result_of; + #ifdef BOOST_NO_SFINAE_EXPR // There doesn't seem to be any other way to turn this off such that the presence of diff --git a/index.html b/index.html index 367fa93..41c8c15 100644 --- a/index.html +++ b/index.html @@ -14,22 +14,29 @@

    But that doesn't mean there isn't useful stuff here. Take a look:

    + addressof
    assert
    base_from_member
    + BOOST_BINARY
    call_traits
    checked_delete
    compressed_pair
    current_function
    declval
    enable_if
    - iterator_adaptors
    - generator iterator adaptors
    + in_place_factory
    + iterator_adaptors
    + generator iterator adaptors
    + next/prior
    + noncopyable
    operators
    + result_of
    swap
    throw_exception
    utility
    string_ref
    value_init + BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL


    @@ -43,4 +50,3 @@ 07 November, 2006

    - diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index cec9727..548dcba 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -48,5 +48,10 @@ test-suite utility [ compile-fail ../initialized_test_fail1.cpp ] [ compile-fail ../initialized_test_fail2.cpp ] [ run ../verify_test.cpp ] + [ run explicit_operator_bool.cpp ] + [ compile-fail explicit_operator_bool_compile_fail_conv_int.cpp ] + [ compile-fail explicit_operator_bool_compile_fail_conv_pvoid.cpp ] + [ compile-fail explicit_operator_bool_compile_fail_delete.cpp ] + [ compile-fail explicit_operator_bool_compile_fail_shift.cpp ] ; diff --git a/test/explicit_operator_bool.cpp b/test/explicit_operator_bool.cpp new file mode 100644 index 0000000..07dd01b --- /dev/null +++ b/test/explicit_operator_bool.cpp @@ -0,0 +1,54 @@ +/* + * Copyright Andrey Semashev 2007 - 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 explicit_operator_bool_compile.cpp + * \author Andrey Semashev + * \date 17.07.2010 + * + * \brief This test checks that explicit operator bool can be used in + * the valid contexts. + */ + +#define BOOST_TEST_MODULE explicit_operator_bool_compile + +#include + +namespace { + + // A test object that has the operator of explicit conversion to bool + struct checkable1 + { + BOOST_EXPLICIT_OPERATOR_BOOL() + bool operator! () const + { + return false; + } + }; + + struct checkable2 + { + BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL() + BOOST_CONSTEXPR bool operator! () const + { + return false; + } + }; + +} // namespace + +int main(int, char*[]) +{ + checkable1 val1; + if (val1) + { + checkable2 val2; + if (val2) + return 0; + } + + return 1; +} diff --git a/test/explicit_operator_bool_compile_fail_conv_int.cpp b/test/explicit_operator_bool_compile_fail_conv_int.cpp new file mode 100644 index 0000000..384f2ab --- /dev/null +++ b/test/explicit_operator_bool_compile_fail_conv_int.cpp @@ -0,0 +1,40 @@ +/* + * Copyright Andrey Semashev 2007 - 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 explicit_operator_bool_compile_fail_conv_int.cpp + * \author Andrey Semashev + * \date 17.07.2010 + * + * \brief This test checks that explicit operator bool cannot be used in + * an unintended context. + */ + +#define BOOST_TEST_MODULE explicit_operator_bool_compile_fail_conv_int + +#include + +namespace { + + // A test object that has the operator of explicit conversion to bool + struct checkable + { + BOOST_EXPLICIT_OPERATOR_BOOL() + bool operator! () const + { + return false; + } + }; + +} // namespace + +int main(int, char*[]) +{ + checkable val; + int n = val; + + return 0; +} diff --git a/test/explicit_operator_bool_compile_fail_conv_pvoid.cpp b/test/explicit_operator_bool_compile_fail_conv_pvoid.cpp new file mode 100644 index 0000000..0c007ba --- /dev/null +++ b/test/explicit_operator_bool_compile_fail_conv_pvoid.cpp @@ -0,0 +1,40 @@ +/* + * Copyright Andrey Semashev 2007 - 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 explicit_operator_bool_compile_fail_conv_pvoid.cpp + * \author Andrey Semashev + * \date 17.07.2010 + * + * \brief This test checks that explicit operator bool cannot be used in + * an unintended context. + */ + +#define BOOST_TEST_MODULE explicit_operator_bool_compile_fail_conv_pvoid + +#include + +namespace { + + // A test object that has the operator of explicit conversion to bool + struct checkable + { + BOOST_EXPLICIT_OPERATOR_BOOL() + bool operator! () const + { + return false; + } + }; + +} // namespace + +int main(int, char*[]) +{ + checkable val; + void* p = val; + + return 0; +} diff --git a/test/explicit_operator_bool_compile_fail_delete.cpp b/test/explicit_operator_bool_compile_fail_delete.cpp new file mode 100644 index 0000000..d780f94 --- /dev/null +++ b/test/explicit_operator_bool_compile_fail_delete.cpp @@ -0,0 +1,40 @@ +/* + * Copyright Andrey Semashev 2007 - 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 explicit_operator_bool_compile_fail_delete.cpp + * \author Andrey Semashev + * \date 17.07.2010 + * + * \brief This test checks that explicit operator bool cannot be used in + * an unintended context. + */ + +#define BOOST_TEST_MODULE util_explicit_operator_bool_delete + +#include + +namespace { + + // A test object that has the operator of explicit conversion to bool + struct checkable + { + BOOST_EXPLICIT_OPERATOR_BOOL() + bool operator! () const + { + return false; + } + }; + +} // namespace + +int main(int, char*[]) +{ + checkable val; + delete val; + + return 0; +} diff --git a/test/explicit_operator_bool_compile_fail_shift.cpp b/test/explicit_operator_bool_compile_fail_shift.cpp new file mode 100644 index 0000000..ce563a6 --- /dev/null +++ b/test/explicit_operator_bool_compile_fail_shift.cpp @@ -0,0 +1,40 @@ +/* + * Copyright Andrey Semashev 2007 - 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 explicit_operator_bool_compile_fail_shift.cpp + * \author Andrey Semashev + * \date 17.07.2010 + * + * \brief This test checks that explicit operator bool cannot be used in + * an unintended context. + */ + +#define BOOST_TEST_MODULE explicit_operator_bool_compile_fail_shift + +#include + +namespace { + + // A test object that has the operator of explicit conversion to bool + struct checkable + { + BOOST_EXPLICIT_OPERATOR_BOOL() + bool operator! () const + { + return false; + } + }; + +} // namespace + +int main(int, char*[]) +{ + checkable val; + val << 2; + + return 0; +} diff --git a/test/result_of_test.cpp b/test/result_of_test.cpp index d06ec64..9ea72f1 100644 --- a/test/result_of_test.cpp +++ b/test/result_of_test.cpp @@ -5,6 +5,12 @@ // 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 // For more information, see http://www.boost.org/libs/utility @@ -190,7 +196,7 @@ int main() BOOST_STATIC_ASSERT((is_same(void)>::type, void>::value)); // Prior to decltype, result_of could not deduce the return type - // nullary function objects unless they exposed a result_type. + // of nullary function objects unless they exposed a result_type. #if defined(BOOST_RESULT_OF_USE_DECLTYPE) BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type, int>::value)); @@ -273,7 +279,7 @@ int main() BOOST_STATIC_ASSERT((is_same::type, int>::value)); BOOST_STATIC_ASSERT((is_same::type,int>::value)); -#if defined(BOOST_RESULT_OF_USE_DECLTYPE) +#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) BOOST_STATIC_ASSERT((is_same::type, short>::value)); BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); BOOST_STATIC_ASSERT((is_same::type, cv_overload_check >::value)); @@ -301,10 +307,10 @@ int main() #endif #endif -#if defined(BOOST_RESULT_OF_USE_DECLTYPE) +#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) +#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) return 0; } diff --git a/utility.htm b/utility.htm index 974776e..1101cc6 100644 --- a/utility.htm +++ b/utility.htm @@ -259,6 +259,46 @@ typedef boost::result_of< represent the return type of operator() given a call expression.

    +

    Additionally, boost::result_of + provides a third mode of operation, which some users + may find convenient. When + BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK + is defined, boost::result_of behaves as + follows. If the function object has a member + type result_type or member + template result<>, then + boost::result_of will use the TR1 + protocol. Otherwise, + boost::result_of will + use decltype. Using TR1 with + a declytpe fallback may workaround + certain problems at the cost of portability. For + example: +

      +
    • Deficient compiler: If your code + requires boost::result_of to work + with incomplete return types but your + compiler's decltype implementation + does not support incomplete return types, then you + can use the TR1 protocol as a workaround. Support + for incomplete return types was added late in the + C++11 standardization process + (see N3276) + and is not implemented by some compilers.
    • + +
    • Deficient legacy code: If your existing TR1 + function object advertises a different type than + the actual result type deduced + by decltype, then using TR1 with a + decltype fallback will allow you to + work with both your existing TR1 function objects + and new C++11 function object. This situation + could occur if your legacy function objects + misused the TR1 protocol. See the documentation on + known differences + between boost::result_of and TR1.
    • +
    +

    This implementation of result_of requires class template partial specialization, the diff --git a/value_init_test.cpp b/value_init_test.cpp index 98b8860..bee8e10 100644 --- a/value_init_test.cpp +++ b/value_init_test.cpp @@ -22,7 +22,7 @@ #pragma hdrstop #endif -#include "boost/test/minimal.hpp" +#include // // Sample POD type @@ -215,7 +215,7 @@ template void check_initialized_value ( T const& y ) { T initializedValue = boost::initialized_value ; - BOOST_CHECK ( y == initializedValue ) ; + BOOST_TEST ( y == initializedValue ) ; } #ifdef __BORLANDC__ @@ -245,128 +245,125 @@ void check_initialized_value( NonPOD const& ) template bool test ( T const& y, T const& z ) { - const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter(); + const int errors_before_test = boost::detail::test_errors(); check_initialized_value(y); boost::value_initialized x ; - BOOST_CHECK ( y == x ) ; - BOOST_CHECK ( y == boost::get(x) ) ; + BOOST_TEST ( y == x ) ; + BOOST_TEST ( y == boost::get(x) ) ; static_cast(x) = z ; boost::get(x) = z ; - BOOST_CHECK ( x == z ) ; + BOOST_TEST ( x == z ) ; boost::value_initialized const x_c ; - BOOST_CHECK ( y == x_c ) ; - BOOST_CHECK ( y == boost::get(x_c) ) ; + BOOST_TEST ( y == x_c ) ; + BOOST_TEST ( y == boost::get(x_c) ) ; T& x_c_ref = const_cast( boost::get(x_c) ) ; x_c_ref = z ; - BOOST_CHECK ( x_c == z ) ; + BOOST_TEST ( x_c == z ) ; boost::value_initialized const copy1 = x; - BOOST_CHECK ( boost::get(copy1) == boost::get(x) ) ; + BOOST_TEST ( boost::get(copy1) == boost::get(x) ) ; boost::value_initialized copy2; copy2 = x; - BOOST_CHECK ( boost::get(copy2) == boost::get(x) ) ; + BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ; boost::shared_ptr > ptr( new boost::value_initialized ); - BOOST_CHECK ( y == *ptr ) ; + BOOST_TEST ( y == *ptr ) ; #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) boost::value_initialized cx ; - BOOST_CHECK ( y == cx ) ; - BOOST_CHECK ( y == boost::get(cx) ) ; + BOOST_TEST ( y == cx ) ; + BOOST_TEST ( y == boost::get(cx) ) ; boost::value_initialized const cx_c ; - BOOST_CHECK ( y == cx_c ) ; - BOOST_CHECK ( y == boost::get(cx_c) ) ; + BOOST_TEST ( y == cx_c ) ; + BOOST_TEST ( y == boost::get(cx_c) ) ; #endif - return boost::minimal_test::errors_counter() == counter_before_test ; + return boost::detail::test_errors() == errors_before_test ; } -int test_main(int, char **) +int main(int, char **) { - BOOST_CHECK ( test( 0,1234 ) ) ; - BOOST_CHECK ( test( 0.0,12.34 ) ) ; - BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ; - BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ; + 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_CHECK ( test( 0, &NonPOD_object ) ) ; + BOOST_TEST ( test( 0, &NonPOD_object ) ) ; AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 }; AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 }; - BOOST_CHECK ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) ); + BOOST_TEST ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) ); StringAndInt stringAndInt0; StringAndInt stringAndInt1; stringAndInt0.i = 0; stringAndInt1.i = 1; stringAndInt1.s = std::string("1"); - BOOST_CHECK ( test(stringAndInt0, stringAndInt1) ); + BOOST_TEST ( test(stringAndInt0, stringAndInt1) ); StructWithDestructor structWithDestructor0; StructWithDestructor structWithDestructor1; structWithDestructor0.i = 0; structWithDestructor1.i = 1; - BOOST_CHECK ( test(structWithDestructor0, structWithDestructor1) ); + BOOST_TEST ( test(structWithDestructor0, structWithDestructor1) ); StructWithVirtualFunction structWithVirtualFunction0; StructWithVirtualFunction structWithVirtualFunction1; structWithVirtualFunction0.i = 0; structWithVirtualFunction1.i = 1; - BOOST_CHECK ( test(structWithVirtualFunction0, structWithVirtualFunction1) ); + BOOST_TEST ( test(structWithVirtualFunction0, structWithVirtualFunction1) ); DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0; DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1; static_cast(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct; static_cast(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct; - BOOST_CHECK ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) ); + BOOST_TEST ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) ); AggregatePODStructWrapper aggregatePODStructWrapper0; AggregatePODStructWrapper aggregatePODStructWrapper1; aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct; aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct; - BOOST_CHECK ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) ); + BOOST_TEST ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) ); ArrayOfBytes zeroInitializedArrayOfBytes = { 0 }; boost::value_initialized valueInitializedArrayOfBytes; - BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0); + BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0); boost::value_initialized valueInitializedArrayOfBytes2; valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes; - BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0); + BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0); boost::value_initialized copyFunctionCallTester1; - BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed); - BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called); + BOOST_TEST ( ! get(copyFunctionCallTester1).is_copy_constructed); + BOOST_TEST ( ! get(copyFunctionCallTester1).is_assignment_called); boost::value_initialized copyFunctionCallTester2 = boost::value_initialized(copyFunctionCallTester1); - BOOST_CHECK ( get(copyFunctionCallTester2).is_copy_constructed); - BOOST_CHECK ( ! get(copyFunctionCallTester2).is_assignment_called); + BOOST_TEST ( get(copyFunctionCallTester2).is_copy_constructed); + BOOST_TEST ( ! get(copyFunctionCallTester2).is_assignment_called); boost::value_initialized copyFunctionCallTester3; copyFunctionCallTester3 = boost::value_initialized(copyFunctionCallTester1); - BOOST_CHECK ( ! get(copyFunctionCallTester3).is_copy_constructed); - BOOST_CHECK ( get(copyFunctionCallTester3).is_assignment_called); + BOOST_TEST ( ! get(copyFunctionCallTester3).is_copy_constructed); + BOOST_TEST ( get(copyFunctionCallTester3).is_assignment_called); boost::value_initialized swapFunctionCallTester1; boost::value_initialized swapFunctionCallTester2; get(swapFunctionCallTester1).data = 1; get(swapFunctionCallTester2).data = 2; boost::swap(swapFunctionCallTester1, swapFunctionCallTester2); - BOOST_CHECK( get(swapFunctionCallTester1).data == 2 ); - BOOST_CHECK( get(swapFunctionCallTester2).data == 1 ); - BOOST_CHECK( get(swapFunctionCallTester1).is_custom_swap_called ); - BOOST_CHECK( get(swapFunctionCallTester2).is_custom_swap_called ); + 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 0; + return boost::report_errors(); } -unsigned int expected_failures = 0; - - From 65d9a787351a6a25031c60da104f71030959aa65 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Sun, 27 Oct 2013 21:05:17 +0000 Subject: [PATCH 114/126] Regnerated string_ref docs. Fixed incorrect example. Fixes #8002 [SVN r86488] --- doc/html/string_ref.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/html/string_ref.html b/doc/html/string_ref.html index 0b8a9d1..3b6ae8d 100644 --- a/doc/html/string_ref.html +++ b/doc/html/string_ref.html @@ -44,7 +44,7 @@

    History
    -
    +
    @@ -115,7 +115,7 @@ string_ref does.

    -
    +
    @@ -130,7 +130,7 @@ return bar.substr ( 2, 3 ); } -if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ } +if ( extract_part ( "ABCDEFG" ).front() == 'C' ) { /* do something */ }

    Let's figure out what happens in this (contrived) example. @@ -166,15 +166,15 @@ copied, but those are cheap operations.

    -
    +

    The header file "string_ref.hpp" defines a template boost::basic_string_ref, and four specializations - for char - / wchar_t / char16_t - / char32_t . + / wchar_t / char16_t + / char32_t .

    #include <boost/utility/string_ref.hpp> @@ -256,7 +256,7 @@ bool ends_with(basic_string_ref x) const ;

    -
    +
    @@ -271,7 +271,7 @@
    - +

    Last revised: January 14, 2013 at 16:24:14 GMT

    Last revised: October 27, 2013 at 21:01:34 GMT


    From 44a98b121b052f722b971a1d19531d1be7e83bff Mon Sep 17 00:00:00 2001 From: Michel Morin Date: Wed, 13 Nov 2013 03:22:55 +0000 Subject: [PATCH 115/126] Merge r86524 (Correct broken links to C++ standard papers); fixes #9212 [SVN r86673] --- utility.htm | 2 +- value_init.htm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/utility.htm b/utility.htm index 1101cc6..5635d48 100644 --- a/utility.htm +++ b/utility.htm @@ -313,7 +313,7 @@ typedef boost::result_of< Technical Report, N1836, or, for motivation and design rationale, - the result_of proposal.

    + the result_of proposal.

    Usage guidelines for boost::result_of

    diff --git a/value_init.htm b/value_init.htm index b82792f..3222f69 100644 --- a/value_init.htm +++ b/value_init.htm @@ -159,10 +159,10 @@ the object shall be value-initialized (but see below). However, if a declara

    value-initialization

    The first Technical + href="http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html">Technical Corrigendum for the C++ Standard (TC1), whose draft was released to the public in November 2001, introduced Core + href="http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#178">Core Issue 178 (among many other issues, of course).

    That issue introduced the new concept of value-initialization From 96da5105ab5b7203a6ef08c9a63b8f523fc8db5e Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 23 Nov 2013 14:23:45 +0000 Subject: [PATCH 116/126] Merge utility documentation. - Fixed duplicate anchors. - Add BOOST_EXPLICIT_OPERATOR_BOOL documentation. - Rebuild some of the utility documentation. [SVN r86797] --- doc/html/declval.html | 44 +++++----- doc/html/explicit_operator_bool.html | 115 +++++++++++++++++++++++++++ doc/html/string_ref.html | 10 +-- enable_if.html | 4 +- index.html | 4 +- 5 files changed, 147 insertions(+), 30 deletions(-) create mode 100644 doc/html/explicit_operator_bool.html diff --git a/doc/html/declval.html b/doc/html/declval.html index 43dd657..305cf36 100644 --- a/doc/html/declval.html +++ b/doc/html/declval.html @@ -3,7 +3,7 @@ Declval - + @@ -31,9 +31,10 @@

    -
    +
    -

    +

    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)

    @@ -43,7 +44,7 @@

    Table of Contents

    -
    +
    Overview
    Reference
    History
    @@ -66,13 +67,13 @@ in a non-using context, e.g. given the declaration

    template<class T>
    -T&& declval(); // not used
    -
    +T&& declval(); // not used +

    as part of the function template declaration

    template<class To, class From>
    -decltype(static_cast<To>(declval<From>())) convert(From&&);
    +decltype(static_cast<To>(declval<From>())) convert(From&&);
     

    or as part of a class template definition @@ -80,9 +81,9 @@

    template<class> class result_of;
     
     template<class Fn, class... ArgTypes>
    -struct result_of<Fn(ArgTypes...)> 
    +struct result_of<Fn(ArgTypes...)>
     {
    -  typedef decltype(declval<Fn>()(declval<ArgTypes>()...)) type;
    +  typedef decltype(declval<Fn>()(declval<ArgTypes>()...)) type;
     };
     

    @@ -94,8 +95,8 @@ to

    template<class T>
    -typename std::add_rvalue_reference<T>::type declval(); // not used
    -
    +typename std::add_rvalue_reference<T>::type declval(); // not used +

    which ensures that we can also use cv void as template parameter. The careful reader might have noticed that declval() already exists under the name create() as @@ -119,10 +120,10 @@

    namespace boost {
     
         template <typename T>
    -    typename add_rvalue_reference<T>::type declval() noexcept; // as unevaluated operand
    -
    -}  // namespace boost
    -
    + typename add_rvalue_reference<T>::type declval() noexcept; // as unevaluated operand + +} // namespace boost +

    The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands. @@ -142,7 +143,7 @@ Example:

    template <class To, class From>
    -decltype(static_cast<To>(declval<From>())) convert(From&&);
    +decltype(static_cast<To>(declval<From>())) convert(From&&);
     

    Declares a function template convert which only participates in overloading @@ -153,21 +154,22 @@

    -

    - - boost 1.50 +

    + + boost + 1.50

    Fixes:

    -
    • +
      • #6570 Adding noexcept to boost::declval.
    - +

    Last revised: May 28, 2012 at 18:59:06 GMT

    Last revised: November 23, 2013 at 14:11:12 GMT


    diff --git a/doc/html/explicit_operator_bool.html b/doc/html/explicit_operator_bool.html new file mode 100644 index 0000000..78a844f --- /dev/null +++ b/doc/html/explicit_operator_bool.html @@ -0,0 +1,115 @@ + + + +BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +
    +
    +
    +

    +BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL

    +

    +Andrey Semashev +

    +
    +
    +

    + 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) +

    +
    +
    +
    +
    +
    +

    Table of Contents

    +
    +
    Overview
    +
    Examples
    +
    History
    +
    +
    +
    + +

    + BOOST_EXPLICIT_OPERATOR_BOOL() and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL() are compatibility helper macros that expand + to an explicit conversion operator to bool. + For compilers not supporting explicit conversion operators introduced in C++11 + the macros expand to a conversion operator that implements the safe + bool idiom. In case if the compiler is not able to handle safe bool + idiom well the macros expand to a regular conversion operator to bool. +

    +
    +
    + +

    + Both macros are intended to be placed within a user's class definition. The + generated conversion operators will be implemented in terms of operator!() + that should be defined by user in this class. In case of BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL() the generated conversion operator will be + declared constexpr which requires + the corresponding operator!() + to also be constexpr. +

    +
    template< typename T >
    +class my_ptr
    +{
    +    T* m_p;
    +
    +public:
    +    BOOST_EXPLICIT_OPERATOR_BOOL()
    +
    +    bool operator!() const
    +    {
    +        return !m_p;
    +    }
    +};
    +
    +

    + Now my_ptr can be used in conditional + expressions, similarly to a regular pointer: +

    +
    my_ptr< int > p;
    +if (p)
    +    std::cout << "true" << std::endl;
    +
    +
    +
    + +

    + + boost + 1.55 +

    +
    • + The macro was extracted from Boost.Log. +
    +
    +
    + + + +

    Last revised: November 17, 2013 at 17:08:52 GMT

    +
    +
    + + diff --git a/doc/html/string_ref.html b/doc/html/string_ref.html index 3b6ae8d..3352614 100644 --- a/doc/html/string_ref.html +++ b/doc/html/string_ref.html @@ -3,7 +3,7 @@ String_Ref - + @@ -37,7 +37,7 @@

    Table of Contents

    -
    +
    Overview
    Examples
    Reference
    @@ -262,16 +262,16 @@

    - boost + boost 1.53

    -
    • +
      • Introduced
    - +

    Last revised: October 27, 2013 at 21:01:34 GMT

    Last revised: November 23, 2013 at 14:12:56 GMT


    diff --git a/enable_if.html b/enable_if.html index 8ea33bb..9988f3a 100644 --- a/enable_if.html +++ b/enable_if.html @@ -201,7 +201,7 @@ extra template parameter. -

    3.1  Enabling function templates in C++0x

    +

    3.1  Enabling function templates in C++0x

    In a compiler which supports C++0x default arguments for function template parameters, you can enable and disable function templates by adding an additional template parameter. This approach @@ -416,7 +416,7 @@ subscript operators). -

    4  Acknowledgements

    +

    4  Acknowledgements

    We are grateful to Howard Hinnant, Jason Shirk, Paul Mensonides, and Richard Smith whose findings have influenced the library.
    diff --git a/index.html b/index.html index 41c8c15..98c82f1 100644 --- a/index.html +++ b/index.html @@ -35,8 +35,8 @@ throw_exception
    utility
    string_ref
    - value_init - BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL
    + value_init
    + BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL


    From fd9f12b8f1a8d2431947ac32f88475ce8a784c7c Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 25 Sep 2013 10:29:44 +0000 Subject: [PATCH 117/126] Remove use of obsolete BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE{,_SPEC} macro. [SVN r85896] --- include/boost/utility/in_place_factory.hpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/boost/utility/in_place_factory.hpp b/include/boost/utility/in_place_factory.hpp index f84b003..1a62ace 100644 --- a/include/boost/utility/in_place_factory.hpp +++ b/include/boost/utility/in_place_factory.hpp @@ -48,15 +48,13 @@ public: {} template - void* apply(void* address - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) const + void* apply(void* address) const { return new(address) T( BOOST_PP_ENUM_PARAMS(N, m_a) ); } template - void* apply(void* address, std::size_t n - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) const + void* apply(void* address, std::size_t n) const { for(char* next = address = this->BOOST_NESTED_TEMPLATE apply(address); !! --n;) From 14e9e95c177a0b5244d9064bcb0e820db94be001 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 26 Sep 2013 09:41:00 +0000 Subject: [PATCH 118/126] Utility: Remove obsolete MSVC version check [SVN r85932] --- include/boost/utility/value_init.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/boost/utility/value_init.hpp b/include/boost/utility/value_init.hpp index 5de9585..2e43287 100644 --- a/include/boost/utility/value_init.hpp +++ b/include/boost/utility/value_init.hpp @@ -33,7 +33,6 @@ #ifdef BOOST_MSVC #pragma warning(push) -#if _MSC_VER >= 1310 // It is safe to ignore the following warning from MSVC 7.1 or higher: // "warning C4351: new behavior: elements of array will be default initialized" #pragma warning(disable: 4351) @@ -41,7 +40,6 @@ // a const type: "warning C4512: assignment operator could not be generated". #pragma warning(disable: 4512) #endif -#endif #ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED From 80895c071c7340519a4ede4463e9b9714cb3f627 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 1 Oct 2013 08:47:11 +0000 Subject: [PATCH 119/126] Operators: Remove obsolete GCC version check. [SVN r86114] --- include/boost/operators.hpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/include/boost/operators.hpp b/include/boost/operators.hpp index b524cee..ac3eaff 100644 --- a/include/boost/operators.hpp +++ b/include/boost/operators.hpp @@ -97,14 +97,7 @@ namespace boost { namespace detail { -template class empty_base { - -// Helmut Zeisel, empty base class optimization bug with GCC 3.0.0 -#if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0 - bool dummy; -#endif - -}; +template class empty_base {}; } // namespace detail } // namespace boost From e25bd18bd82209dfe726cb209fde841d78424501 Mon Sep 17 00:00:00 2001 From: Joel Falcou Date: Tue, 1 Oct 2013 15:05:39 +0000 Subject: [PATCH 120/126] Fix #9170 - Add BOOST_FORCEINLINE in address_of for performance issues [SVN r86125] --- include/boost/utility/addressof.hpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/include/boost/utility/addressof.hpp b/include/boost/utility/addressof.hpp index ecb7776..2b637df 100644 --- a/include/boost/utility/addressof.hpp +++ b/include/boost/utility/addressof.hpp @@ -25,8 +25,8 @@ template struct addr_impl_ref { T & v_; - inline addr_impl_ref( T & v ): v_( v ) {} - inline operator T& () const { return v_; } + BOOST_FORCEINLINE addr_impl_ref( T & v ): v_( v ) {} + BOOST_FORCEINLINE operator T& () const { return v_; } private: addr_impl_ref & operator=(const addr_impl_ref &); @@ -34,13 +34,13 @@ private: template struct addressof_impl { - static inline T * f( T & v, long ) + static BOOST_FORCEINLINE T * f( T & v, long ) { return reinterpret_cast( &const_cast(reinterpret_cast(v))); } - static inline T * f( T * v, int ) + static BOOST_FORCEINLINE T * f( T * v, int ) { return v; } @@ -48,7 +48,9 @@ template struct addressof_impl } // namespace detail -template T * addressof( T & v ) +template +BOOST_FORCEINLINE +T * addressof( T & v ) { #if (defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) ) ) || defined( __SUNPRO_CC ) @@ -74,6 +76,7 @@ template struct addressof_addp } // namespace detail template< class T, std::size_t N > +BOOST_FORCEINLINE typename detail::addressof_addp< T[N] >::type addressof( T (&t)[N] ) { return &t; @@ -85,12 +88,14 @@ typename detail::addressof_addp< T[N] >::type addressof( T (&t)[N] ) // but these overloads work around the problem. #if defined( __BORLANDC__ ) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) template +BOOST_FORCEINLINE T (*addressof(T (&t)[N]))[N] { return reinterpret_cast(&t); } template +BOOST_FORCEINLINE const T (*addressof(const T (&t)[N]))[N] { return reinterpret_cast(&t); From a292dba0212a6bdd2faba137eb16135f69c94a08 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 30 Sep 2013 00:21:39 +0000 Subject: [PATCH 121/126] Detail: Remove obsolete MSVC version checks. [SVN r86039] --- include/boost/detail/ob_compressed_pair.hpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/include/boost/detail/ob_compressed_pair.hpp b/include/boost/detail/ob_compressed_pair.hpp index 727acab..326e454 100644 --- a/include/boost/detail/ob_compressed_pair.hpp +++ b/include/boost/detail/ob_compressed_pair.hpp @@ -167,17 +167,6 @@ public: compressed_pair_1(const ::boost::compressed_pair& x) : T2(x.second()), _first(x.first()) {} -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 - // Total weirdness. If the assignment to _first is moved after - // the call to the inherited operator=, then this breaks graph/test/graph.cpp - // by way of iterator_adaptor. - compressed_pair_1& operator=(const compressed_pair_1& x) { - _first = x._first; - T2::operator=(x); - return *this; - } -#endif - first_reference first() { return _first; } first_const_reference first() const { return _first; } From 52a64d6aec4570543e2029e92dee798be2db5c75 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 11 Oct 2013 23:11:35 +0000 Subject: [PATCH 122/126] Remove obsolete files. [SVN r86242] --- include/boost/call_traits.hpp | 6 +- include/boost/compressed_pair.hpp | 6 +- include/boost/detail/ob_call_traits.hpp | 168 ------------------------ 3 files changed, 2 insertions(+), 178 deletions(-) delete mode 100644 include/boost/detail/ob_call_traits.hpp diff --git a/include/boost/call_traits.hpp b/include/boost/call_traits.hpp index 5253a6d..2c1328e 100644 --- a/include/boost/call_traits.hpp +++ b/include/boost/call_traits.hpp @@ -5,7 +5,7 @@ // // See http://www.boost.org/libs/utility for most recent version including documentation. -// See boost/detail/call_traits.hpp and boost/detail/ob_call_traits.hpp +// See boost/detail/call_traits.hpp // for full copyright notices. #ifndef BOOST_CALL_TRAITS_HPP @@ -15,10 +15,6 @@ #include #endif -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -#include -#else #include -#endif #endif // BOOST_CALL_TRAITS_HPP diff --git a/include/boost/compressed_pair.hpp b/include/boost/compressed_pair.hpp index e6cd6a0..a7be0f2 100644 --- a/include/boost/compressed_pair.hpp +++ b/include/boost/compressed_pair.hpp @@ -5,7 +5,7 @@ // // See http://www.boost.org/libs/utility for most recent version including documentation. -// See boost/detail/compressed_pair.hpp and boost/detail/ob_compressed_pair.hpp +// See boost/detail/compressed_pair.hpp // for full copyright notices. #ifndef BOOST_COMPRESSED_PAIR_HPP @@ -15,10 +15,6 @@ #include #endif -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -#include -#else #include -#endif #endif // BOOST_COMPRESSED_PAIR_HPP diff --git a/include/boost/detail/ob_call_traits.hpp b/include/boost/detail/ob_call_traits.hpp deleted file mode 100644 index eb4df7a..0000000 --- a/include/boost/detail/ob_call_traits.hpp +++ /dev/null @@ -1,168 +0,0 @@ -// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & 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). -// -// See http://www.boost.org/libs/utility for most recent version including documentation. -// -// Crippled version for crippled compilers: -// see libs/utility/call_traits.htm -// - -/* Release notes: - 01st October 2000: - Fixed call_traits on VC6, using "poor man's partial specialisation", - using ideas taken from "Generative programming" by Krzysztof Czarnecki - & Ulrich Eisenecker. -*/ - -#ifndef BOOST_OB_CALL_TRAITS_HPP -#define BOOST_OB_CALL_TRAITS_HPP - -#ifndef BOOST_CONFIG_HPP -#include -#endif - -#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP -#include -#endif -#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP -#include -#endif - -namespace boost{ - -#ifdef BOOST_MSVC6_MEMBER_TEMPLATES -// -// use member templates to emulate -// partial specialisation: -// -namespace detail{ - -template -struct standard_call_traits -{ - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef const T& param_type; -}; -template -struct simple_call_traits -{ - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef const T param_type; -}; -template -struct reference_call_traits -{ - typedef T value_type; - typedef T reference; - typedef T const_reference; - typedef T param_type; -}; - -template -struct call_traits_chooser -{ - template - struct rebind - { - typedef standard_call_traits type; - }; -}; - -template <> -struct call_traits_chooser -{ - template - struct rebind - { - typedef simple_call_traits type; - }; -}; - -template <> -struct call_traits_chooser -{ - template - struct rebind - { - typedef reference_call_traits type; - }; -}; - -template -struct call_traits_sizeof_chooser2 -{ - template - struct small_rebind - { - typedef simple_call_traits small_type; - }; -}; - -template<> -struct call_traits_sizeof_chooser2 -{ - template - struct small_rebind - { - typedef standard_call_traits small_type; - }; -}; - -template <> -struct call_traits_chooser -{ - template - struct rebind - { - enum { sizeof_choice = (sizeof(T) <= sizeof(void*)) }; - typedef call_traits_sizeof_chooser2<(sizeof(T) <= sizeof(void*))> chooser; - typedef typename chooser::template small_rebind bound_type; - typedef typename bound_type::small_type type; - }; -}; - -} // namespace detail -template -struct call_traits -{ -private: - typedef detail::call_traits_chooser< - ::boost::is_pointer::value, - ::boost::is_arithmetic::value, - ::boost::is_reference::value - > chooser; - typedef typename chooser::template rebind bound_type; - typedef typename bound_type::type call_traits_type; -public: - typedef typename call_traits_type::value_type value_type; - typedef typename call_traits_type::reference reference; - typedef typename call_traits_type::const_reference const_reference; - typedef typename call_traits_type::param_type param_type; -}; - -#else -// -// sorry call_traits is completely non-functional -// blame your broken compiler: -// - -template -struct call_traits -{ - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef const T& param_type; -}; - -#endif // member templates - -} - -#endif // BOOST_OB_CALL_TRAITS_HPP From 9382b69eb13f1e1c5c841207bc771eeecf1fabf6 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 11 Oct 2013 23:20:59 +0000 Subject: [PATCH 123/126] Simplify multi-component ifdefs containing BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION [SVN r86248] --- include/boost/utility/result_of.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp index a530c3a..9ea151d 100644 --- a/include/boost/utility/result_of.hpp +++ b/include/boost/utility/result_of.hpp @@ -68,7 +68,7 @@ namespace boost { template struct result_of; template struct tr1_result_of; // a TR1-style implementation of result_of -#if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +#if !defined(BOOST_NO_SFINAE) namespace detail { BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) From 3bac7b132a3641a7ed3ffa580d682e3d13fd7fd4 Mon Sep 17 00:00:00 2001 From: Joel Falcou Date: Tue, 1 Oct 2013 15:02:28 +0000 Subject: [PATCH 124/126] Fix #9169 - Add BOOST_FORCEINLINE on boost::ref for performance issue [SVN r86124] Conflicts: include/boost/ref.hpp --- include/boost/ref.hpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/boost/ref.hpp b/include/boost/ref.hpp index 6058d69..1d9d3ec 100644 --- a/include/boost/ref.hpp +++ b/include/boost/ref.hpp @@ -30,7 +30,7 @@ namespace boost { template class reference_wrapper -{ +{ public: typedef T type; @@ -40,15 +40,15 @@ public: #else - explicit reference_wrapper(T& t): t_(boost::addressof(t)) {} + BOOST_FORCEINLINE explicit reference_wrapper(T& t): t_(boost::addressof(t)) {} #endif - operator T& () const { return *t_; } + BOOST_FORCEINLINE operator T& () const { return *t_; } - T& get() const { return *t_; } + BOOST_FORCEINLINE T& get() const { return *t_; } - T* get_pointer() const { return t_; } + BOOST_FORCEINLINE T* get_pointer() const { return t_; } private: @@ -61,12 +61,12 @@ private: # define BOOST_REF_CONST const # endif -template inline reference_wrapper BOOST_REF_CONST ref(T & t) -{ +template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST ref(T & t) +{ return reference_wrapper(t); } -template inline reference_wrapper BOOST_REF_CONST cref(T const & t) +template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST cref(T const & t) { return reference_wrapper(t); } @@ -125,7 +125,7 @@ namespace detail { typedef char (&yes_reference_wrapper_t)[1]; typedef char (&no_reference_wrapper_t)[2]; - + no_reference_wrapper_t is_reference_wrapper_test(...); template @@ -160,7 +160,7 @@ class is_reference_wrapper bool, value = ( sizeof(detail::is_reference_wrapper_test(type())) == sizeof(detail::yes_reference_wrapper_t))); - + typedef ::boost::mpl::bool_ type; }; @@ -173,13 +173,13 @@ class unwrap_reference # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template inline typename unwrap_reference::type& +template BOOST_FORCEINLINE typename unwrap_reference::type& unwrap_ref(T& t) { return t; } -template inline T* get_pointer( reference_wrapper const & r ) +template BOOST_FORCEINLINE T* get_pointer( reference_wrapper const & r ) { return r.get_pointer(); } From 514e5299ca55ae5d545a193fd6eff177bdf0b1ae Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 11 Oct 2013 23:17:48 +0000 Subject: [PATCH 125/126] Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION Process #ifndef...#else...#endif blocks. [SVN r86245] --- include/boost/operators.hpp | 23 -------------- include/boost/ref.hpp | 61 ------------------------------------- 2 files changed, 84 deletions(-) diff --git a/include/boost/operators.hpp b/include/boost/operators.hpp index ac3eaff..82c374e 100644 --- a/include/boost/operators.hpp +++ b/include/boost/operators.hpp @@ -704,7 +704,6 @@ struct random_access_iteratable // the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as // necessary. // -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // is_chained_base<> - a traits class used to distinguish whether an operator // template argument is being used for base class chaining, or is specifying a @@ -802,24 +801,6 @@ BOOST_OPERATOR_TEMPLATE2(template_name##2) \ BOOST_OPERATOR_TEMPLATE1(template_name##1) -#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -# define BOOST_OPERATOR_TEMPLATE4(template_name4) \ - BOOST_IMPORT_TEMPLATE4(template_name4) -# define BOOST_OPERATOR_TEMPLATE3(template_name3) \ - BOOST_IMPORT_TEMPLATE3(template_name3) -# define BOOST_OPERATOR_TEMPLATE2(template_name2) \ - BOOST_IMPORT_TEMPLATE2(template_name2) -# define BOOST_OPERATOR_TEMPLATE1(template_name1) \ - BOOST_IMPORT_TEMPLATE1(template_name1) - - // In this case we can only assume that template_name<> is equivalent to the - // more commonly needed template_name1<> form. -# define BOOST_OPERATOR_TEMPLATE(template_name) \ - template > \ - struct template_name : template_name##1 {}; - -#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION namespace boost { @@ -890,14 +871,10 @@ struct operators2 , bitwise2 > > {}; -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template struct operators : operators2 {}; template struct operators -#else -template struct operators -#endif : totally_ordered BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST # undef BOOST_REF_CONST -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template class is_reference_wrapper @@ -112,66 +111,6 @@ AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper const volatile) # undef AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF -# else // no partial specialization - -} // namespace boost - -#include - -namespace boost -{ - -namespace detail -{ - typedef char (&yes_reference_wrapper_t)[1]; - typedef char (&no_reference_wrapper_t)[2]; - - no_reference_wrapper_t is_reference_wrapper_test(...); - - template - yes_reference_wrapper_t is_reference_wrapper_test(type< reference_wrapper >); - - template - struct reference_unwrapper - { - template - struct apply - { - typedef T type; - }; - }; - - template<> - struct reference_unwrapper - { - template - struct apply - { - typedef typename T::type type; - }; - }; -} - -template -class is_reference_wrapper -{ - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_reference_wrapper_test(type())) - == sizeof(detail::yes_reference_wrapper_t))); - - typedef ::boost::mpl::bool_ type; -}; - -template -class unwrap_reference - : public detail::reference_unwrapper< - is_reference_wrapper::value - >::template apply -{}; - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template BOOST_FORCEINLINE typename unwrap_reference::type& unwrap_ref(T& t) From c48f86c9e48d1029a8b4675b73c00cee705d22f2 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Tue, 10 Jul 2012 03:43:13 +0000 Subject: [PATCH 126/126] Ticket #7094, thanks 1czajnik [SVN r79398] --- include/boost/exception.hpp | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 include/boost/exception.hpp diff --git a/include/boost/exception.hpp b/include/boost/exception.hpp deleted file mode 100644 index 6424159..0000000 --- a/include/boost/exception.hpp +++ /dev/null @@ -1,11 +0,0 @@ -//Copyright (c) 2006-2008 Emil Dotchevski and Reverge Studios, Inc. - -//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) - -#ifndef UUID_1D94A7C6054E11DB9804B622A1EF5492 -#define UUID_1D94A7C6054E11DB9804B622A1EF5492 - -#error The header has been deprecated. Please #include instead. - -#endif

    If decltype is not used, then automatic result type deduction of function objects is not possible. Instead, result_of uses the following protocol to allow the programmer to specify a type. When F is a class type with a member type result_type, result_of<F(T1, T2, ..., - TN)> is + TN)>::type is F::result_type. When F does not contain result_type, result_of<F(T1, T2, ..., - TN)> is F::result<F(T1, + TN)>::type is F::result<F(T1, T2, ..., TN)>::type when N > 0 or void when N = 0. Note that it is the @@ -221,22 +227,29 @@ typedef boost::result_of< typedef boost::result_of< functor(int) ->::type type; +>::type type; // type is int -