|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r48896 - in branches/proto/v4: . boost boost/archive/impl boost/archive/iterators boost/bind boost/config boost/config/compiler boost/detail boost/fusion/tuple boost/math/concepts boost/test boost/test/impl boost/test/output boost/test/utils/iterator boost/test/utils/runtime/cla/iface boost/unordered libs/config/doc libs/config/doc/html libs/config/doc/html/boost_config libs/config/test libs/config/test/all libs/proto/doc libs/serialization/test libs/smart_ptr libs/smart_ptr/src libs/test/tools/console_test_runner libs/test/tools/console_test_runner/src libs/test/tools/console_test_runner/test libs/unordered/doc libs/unordered/test/objects libs/unordered/test/unordered libs/utility
From: eric_at_[hidden]
Date: 2008-09-19 11:49:04
Author: eric_niebler
Date: 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
New Revision: 48896
URL: http://svn.boost.org/trac/boost/changeset/48896
Log:
merged from trunk
Added:
branches/proto/v4/boost/config/compiler/codegear.hpp
- copied unchanged from r48894, /trunk/boost/config/compiler/codegear.hpp
branches/proto/v4/boost/unordered/unordered_map.hpp
- copied unchanged from r48894, /trunk/boost/unordered/unordered_map.hpp
branches/proto/v4/boost/unordered/unordered_map_fwd.hpp
- copied unchanged from r48894, /trunk/boost/unordered/unordered_map_fwd.hpp
branches/proto/v4/boost/unordered/unordered_set.hpp
- copied unchanged from r48894, /trunk/boost/unordered/unordered_set.hpp
branches/proto/v4/boost/unordered/unordered_set_fwd.hpp
- copied unchanged from r48894, /trunk/boost/unordered/unordered_set_fwd.hpp
branches/proto/v4/libs/config/test/boost_no_typename_with_ctor.ipp
- copied unchanged from r48894, /trunk/libs/config/test/boost_no_typename_with_ctor.ipp
branches/proto/v4/libs/proto/doc/getting_started.qbk
- copied unchanged from r48894, /trunk/libs/proto/doc/getting_started.qbk
branches/proto/v4/libs/test/tools/console_test_runner/Jamfile.v2
- copied unchanged from r48894, /trunk/libs/test/tools/console_test_runner/Jamfile.v2
branches/proto/v4/libs/unordered/test/unordered/fwd_map_test.cpp
- copied unchanged from r48894, /trunk/libs/unordered/test/unordered/fwd_map_test.cpp
branches/proto/v4/libs/unordered/test/unordered/fwd_set_test.cpp
- copied unchanged from r48894, /trunk/libs/unordered/test/unordered/fwd_set_test.cpp
Removed:
branches/proto/v4/boost/binary.hpp
Properties modified:
branches/proto/v4/ (props changed)
Text files modified:
branches/proto/v4/boost/archive/impl/basic_text_iprimitive.ipp | 11
branches/proto/v4/boost/archive/impl/basic_text_oprimitive.ipp | 6
branches/proto/v4/boost/archive/iterators/binary_from_base64.hpp | 2
branches/proto/v4/boost/bind/bind_mf2_cc.hpp | 144 +-
branches/proto/v4/boost/concept_check.hpp | 8
branches/proto/v4/boost/config/compiler/borland.hpp | 54
branches/proto/v4/boost/config/select_compiler_config.hpp | 4
branches/proto/v4/boost/config/suffix.hpp | 6
branches/proto/v4/boost/detail/atomic_count.hpp | 7
branches/proto/v4/boost/detail/atomic_count_sync.hpp | 4
branches/proto/v4/boost/detail/sp_counted_base.hpp | 4
branches/proto/v4/boost/detail/spinlock.hpp | 4
branches/proto/v4/boost/detail/workaround.hpp | 51
branches/proto/v4/boost/fusion/tuple/tuple.hpp | 2
branches/proto/v4/boost/math/concepts/real_concept.hpp | 8
branches/proto/v4/boost/test/floating_point_comparison.hpp | 4
branches/proto/v4/boost/test/framework.hpp | 1
branches/proto/v4/boost/test/impl/execution_monitor.ipp | 12
branches/proto/v4/boost/test/impl/framework.ipp | 12
branches/proto/v4/boost/test/impl/unit_test_parameters.ipp | 4
branches/proto/v4/boost/test/output/xml_log_formatter.hpp | 1
branches/proto/v4/boost/test/utils/iterator/istream_line_iterator.hpp | 2
branches/proto/v4/boost/test/utils/runtime/cla/iface/argument_factory.hpp | 2
branches/proto/v4/boost/test/utils/runtime/cla/iface/id_policy.hpp | 1
branches/proto/v4/boost/throw_exception.hpp | 2
branches/proto/v4/boost/unordered_map.hpp | 808 ---------------
branches/proto/v4/boost/unordered_set.hpp | 763 ---------------
branches/proto/v4/libs/config/doc/html/boost_config/boost_macro_reference.html | 36
branches/proto/v4/libs/config/doc/html/index.html | 2
branches/proto/v4/libs/config/doc/macro_reference.qbk | 8
branches/proto/v4/libs/config/test/all/Jamfile.v2 | 8
branches/proto/v4/libs/config/test/boost_no_is_abstract.ipp | 21
branches/proto/v4/libs/config/test/config_info.cpp | 3
branches/proto/v4/libs/config/test/config_test.cpp | 22
branches/proto/v4/libs/proto/doc/transforms.qbk | 2027 ++++++++++++++++++++-------------------
branches/proto/v4/libs/serialization/test/test_binary.cpp | 4
branches/proto/v4/libs/serialization/test/test_tools.hpp | 15
branches/proto/v4/libs/smart_ptr/shared_array.htm | 2
branches/proto/v4/libs/smart_ptr/src/sp_collector.cpp | 4
branches/proto/v4/libs/test/tools/console_test_runner/src/console_test_runner.cpp | 145 ++
branches/proto/v4/libs/test/tools/console_test_runner/test/test_runner_test.cpp | 7
branches/proto/v4/libs/unordered/doc/changes.qbk | 6
branches/proto/v4/libs/unordered/test/objects/minimal.hpp | 2
branches/proto/v4/libs/unordered/test/unordered/Jamfile.v2 | 2
branches/proto/v4/libs/utility/utility.htm | 4
45 files changed, 1499 insertions(+), 2746 deletions(-)
Modified: branches/proto/v4/boost/archive/impl/basic_text_iprimitive.ipp
==============================================================================
--- branches/proto/v4/boost/archive/impl/basic_text_iprimitive.ipp (original)
+++ branches/proto/v4/boost/archive/impl/basic_text_iprimitive.ipp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -102,8 +102,15 @@
}
*caddr++ = static_cast<char>(*ti_begin);
- while(! is_whitespace(*ti_begin))
- ++ti_begin;
+ iterators::istream_iterator<CharType> i;
+ for(;;){
+ CharType c;
+ c = is.get();
+ if(is.eof())
+ break;
+ if(is_whitespace(c))
+ break;
+ }
}
template<class IStream>
Modified: branches/proto/v4/boost/archive/impl/basic_text_oprimitive.ipp
==============================================================================
--- branches/proto/v4/boost/archive/impl/basic_text_oprimitive.ipp (original)
+++ branches/proto/v4/boost/archive/impl/basic_text_oprimitive.ipp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -66,11 +66,11 @@
);
std::size_t tail = count % 3;
- if(tail > 0)
- *oi = '=';
+ if(tail > 0){
+ *oi++ = '=';
if(tail < 2)
*oi = '=';
-
+ }
}
template<class OStream>
Modified: branches/proto/v4/boost/archive/iterators/binary_from_base64.hpp
==============================================================================
--- branches/proto/v4/boost/archive/iterators/binary_from_base64.hpp (original)
+++ branches/proto/v4/boost/archive/iterators/binary_from_base64.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -43,7 +43,7 @@
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
- 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,
+ 52,53,54,55,56,57,58,59,60,61,-1,-1,-1, 0,-1,-1, // =
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
Deleted: branches/proto/v4/boost/binary.hpp
==============================================================================
--- branches/proto/v4/boost/binary.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
+++ (empty file)
@@ -1,14 +0,0 @@
-/*=============================================================================
- Copyright (c) 2008 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_BINARY_HPP
-#define BOOST_BINARY_HPP
-
-#include <boost/utility/binary.hpp>
-
-#endif
Modified: branches/proto/v4/boost/bind/bind_mf2_cc.hpp
==============================================================================
--- branches/proto/v4/boost/bind/bind_mf2_cc.hpp (original)
+++ branches/proto/v4/boost/bind/bind_mf2_cc.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -15,214 +15,214 @@
// 0
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class A1>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(mf0)<R, T>, typename _bi::list_av_1<A1>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (), A1 a1)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf0)<R, T>, typename _bi::list_av_1<A1>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (), A1 a1)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf0)<R, T> F;
typedef typename _bi::list_av_1<A1>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1));
}
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class A1>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T>, typename _bi::list_av_1<A1>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) () const, A1 a1)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T>, typename _bi::list_av_1<A1>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) () const, A1 a1)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T> F;
typedef typename _bi::list_av_1<A1>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1));
}
// 1
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1,
class A1, class A2>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1), A1 a1, A2 a2)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1), A1 a1, A2 a2)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1> F;
typedef typename _bi::list_av_2<A1, A2>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2));
}
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1,
class A1, class A2>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1) const, A1 a1, A2 a2)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1) const, A1 a1, A2 a2)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1> F;
typedef typename _bi::list_av_2<A1, A2>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2));
}
// 2
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2,
class A1, class A2, class A3>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2), A1 a1, A2 a2, A3 a3)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2), A1 a1, A2 a2, A3 a3)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2> F;
typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3));
}
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2,
class A1, class A2, class A3>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2) const, A1 a1, A2 a2, A3 a3)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2) const, A1 a1, A2 a2, A3 a3)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2> F;
typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3));
}
// 3
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2, class B3,
class A1, class A2, class A3, class A4>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3), A1 a1, A2 a2, A3 a3, A4 a4)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3), A1 a1, A2 a2, A3 a3, A4 a4)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3> F;
typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3, a4));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4));
}
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2, class B3,
class A1, class A2, class A3, class A4>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const, A1 a1, A2 a2, A3 a3, A4 a4)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const, A1 a1, A2 a2, A3 a3, A4 a4)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3> F;
typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3, a4));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4));
}
// 4
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4,
class A1, class A2, class A3, class A4, class A5>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4> F;
typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5));
}
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4,
class A1, class A2, class A3, class A4, class A5>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4> F;
typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5));
}
// 5
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5,
class A1, class A2, class A3, class A4, class A5, class A6>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5> F;
typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6));
}
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5,
class A1, class A2, class A3, class A4, class A5, class A6>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5> F;
typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6));
}
// 6
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6,
class A1, class A2, class A3, class A4, class A5, class A6, class A7>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6> F;
typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7));
}
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6,
class A1, class A2, class A3, class A4, class A5, class A6, class A7>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6> F;
typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7));
}
// 7
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6, class B7,
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F;
typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8));
}
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6, class B7,
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F;
typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8));
}
// 8
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8,
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
{
typedef _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F;
typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
}
-template<class R2, class R, class T,
+template<class Rt2, class R, class T,
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8,
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
- _bi::bind_t<R2, _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
- BOOST_BIND(boost::type<R2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+ _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
+ BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
{
typedef _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F;
typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
- return _bi::bind_t<R2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+ return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
}
Modified: branches/proto/v4/boost/concept_check.hpp
==============================================================================
--- branches/proto/v4/boost/concept_check.hpp (original)
+++ branches/proto/v4/boost/concept_check.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -171,6 +171,11 @@
TT b;
};
+#if (defined _MSC_VER)
+# pragma warning( push )
+# pragma warning( disable : 4510 ) // default constructor could not be generated
+# pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required
+#endif
// The SGI STL version of Assignable requires copy constructor and operator=
BOOST_concept(SGIAssignable,(TT))
{
@@ -192,6 +197,9 @@
}
TT a;
};
+#if (defined _MSC_VER)
+# pragma warning( pop )
+#endif
BOOST_concept(Convertible,(X)(Y))
{
Modified: branches/proto/v4/boost/config/compiler/borland.hpp
==============================================================================
--- branches/proto/v4/boost/config/compiler/borland.hpp (original)
+++ branches/proto/v4/boost/config/compiler/borland.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -19,11 +19,13 @@
// last known and checked version is 0x600 (Builder X preview)
// or 0x593 (CodeGear C++ Builder 2007 December 2007 update):
#if (__BORLANDC__ > 0x593) && (__BORLANDC__ != 0x600)
-# if defined(BOOST_ASSERT_CONFIG)
+//# if defined(BOOST_ASSERT_CONFIG)
# error "Unknown compiler version - please run the configure tests and report the results"
-# else
-# pragma message( "Unknown compiler version - please run the configure tests and report the results")
-# endif
+//# else
+//# pragma message( "Unknown compiler version - please run the configure tests and report the results")
+//# endif
+#elif (__BORLANDC__ == 0x600)
+# error "CBuilderX preview compiler is no longer supported"
#endif
//
@@ -108,21 +110,52 @@
// Borland C++ Builder 2007 December 2007 Update and below:
#if (__BORLANDC__ <= 0x593)
-# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS
-# define BOOST_NO_USING_TEMPLATE
-# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE
-# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
// we shouldn't really need this - but too many things choke
// without it, this needs more investigation:
# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
-# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL
# define BOOST_NO_IS_ABSTRACT
# define BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS
-# define BOOST_NO_TWO_PHASE_NAME_LOOKUP
// Temporary workaround
#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif
+// Borland C++ Builder 2008 and below:
+#if (__BORLANDC__ <= 0x601)
+# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL
+# define BOOST_ILLEGAL_CV_REFERENCES
+# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS
+# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+# define BOOST_NO_TWO_PHASE_NAME_LOOKUP
+# define BOOST_NO_USING_TEMPLATE
+# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE
+#endif
+
+//
+// Positive Feature detection
+//
+// Borland C++ Builder 2008 and below:
+#if (__BORLANDC__ >= 0x599)
+# pragma defineonoption BOOST_CODEGEAR_0X_SUPPORT -Ax
+#endif
+
+#if defined( BOOST_CODEGEAR_0X_SUPPORT )
+# #if __BORLANDC__ >= 0x610
+# define BOOST_HAS_ALIGNOF
+# define BOOST_HAS_CHAR16_T
+# define BOOST_HAS_CHAR32_T
+# define BOOST_HAS_DECLTYPE
+//# define BOOST_HAS_DEFAULTED_FN
+//# define BOOST_HAS_DELETED_FN
+# define BOOST_HAS_EXPLICIT_CONVERSION_OPS
+//# define BOOST_HAS_NULLPTR
+//# define BOOST_HAS_RAW_STRING
+# define BOOST_HAS_REF_QUALIFIER
+# define BOOST_HAS_RVALUE_REFS
+//# define BOOST_HAS_SCOPED_ENUM
+# define BOOST_HAS_STATIC_ASSERT
+//# define BOOST_HAS_VARIADIC_TMPL
+# #endif //__BORLANDC__ >= 0x610
#endif
#if __BORLANDC__ >= 0x590
@@ -207,3 +240,4 @@
#define BOOST_COMPILER "Borland C++ version " BOOST_STRINGIZE(__BORLANDC__)
+
Modified: branches/proto/v4/boost/config/select_compiler_config.hpp
==============================================================================
--- branches/proto/v4/boost/config/select_compiler_config.hpp (original)
+++ branches/proto/v4/boost/config/select_compiler_config.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -72,6 +72,10 @@
// Greenhills C++
# define BOOST_COMPILER_CONFIG "boost/config/compiler/greenhills.hpp"
+#elif defined __CODEGEARC__
+// CodeGear - must be checked for before Borland
+# define BOOST_COMPILER_CONFIG "boost/config/compiler/codegear.hpp"
+
#elif defined __BORLANDC__
// Borland
# define BOOST_COMPILER_CONFIG "boost/config/compiler/borland.hpp"
Modified: branches/proto/v4/boost/config/suffix.hpp
==============================================================================
--- branches/proto/v4/boost/config/suffix.hpp (original)
+++ branches/proto/v4/boost/config/suffix.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -442,6 +442,12 @@
# define BOOST_DEDUCED_TYPENAME
#endif
+#ifndef BOOST_NO_TYPENAME_WITH_CTOR
+# define BOOST_CTOR_TYPENAME typename
+#else
+# define BOOST_CTOR_TYPENAME
+#endif
+
// long long workaround ------------------------------------------//
// On gcc (and maybe other compilers?) long long is alway supported
// but it's use may generate either warnings (with -ansi), or errors
Modified: branches/proto/v4/boost/detail/atomic_count.hpp
==============================================================================
--- branches/proto/v4/boost/detail/atomic_count.hpp (original)
+++ branches/proto/v4/boost/detail/atomic_count.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -90,23 +90,18 @@
}
#elif defined(BOOST_AC_USE_PTHREADS)
-
# include <boost/detail/atomic_count_pthreads.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
-
# include <boost/detail/atomic_count_gcc_x86.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
-
# include <boost/detail/atomic_count_win32.hpp>
-#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
-
+#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa ) && ( !defined( __INTEL_COMPILER ) || defined( __ia64__ ) )
# include <boost/detail/atomic_count_sync.hpp>
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
-
# include <boost/detail/atomic_count_gcc.hpp>
#elif defined(BOOST_HAS_PTHREADS)
Modified: branches/proto/v4/boost/detail/atomic_count_sync.hpp
==============================================================================
--- branches/proto/v4/boost/detail/atomic_count_sync.hpp (original)
+++ branches/proto/v4/boost/detail/atomic_count_sync.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -15,6 +15,10 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
+#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
+# include <ia64intrin.h>
+#endif
+
namespace boost
{
Modified: branches/proto/v4/boost/detail/sp_counted_base.hpp
==============================================================================
--- branches/proto/v4/boost/detail/sp_counted_base.hpp (original)
+++ branches/proto/v4/boost/detail/sp_counted_base.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -46,10 +46,10 @@
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
# include <boost/detail/sp_counted_base_gcc_ppc.hpp>
-#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa )
+#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa ) && ( !defined( __INTEL_COMPILER ) || defined( __ia64__ ) )
# include <boost/detail/sp_counted_base_sync.hpp>
-#elif defined(__GNUC__) && ( defined( __sparcv8 ) || defined( __sparcv9 ) )
+#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
# include <boost/detail/sp_counted_base_gcc_sparc.hpp>
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
Modified: branches/proto/v4/boost/detail/spinlock.hpp
==============================================================================
--- branches/proto/v4/boost/detail/spinlock.hpp (original)
+++ branches/proto/v4/boost/detail/spinlock.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -30,9 +30,9 @@
#include <boost/config.hpp>
-#if defined(__GNUC__) && defined( __arm__ )
+#if defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
# include <boost/detail/spinlock_gcc_arm.hpp>
-#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa ) && ( !defined( __INTEL_COMPILER ) || defined( __ia64__ ) )
# include <boost/detail/spinlock_sync.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# include <boost/detail/spinlock_w32.hpp>
Modified: branches/proto/v4/boost/detail/workaround.hpp
==============================================================================
--- branches/proto/v4/boost/detail/workaround.hpp (original)
+++ branches/proto/v4/boost/detail/workaround.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -45,10 +45,10 @@
#else
#define __BORLANDC___WORKAROUND_GUARD 0
#endif
-#ifndef __MSC_VER
-#define __MSC_VER_WORKAROUND_GUARD 1
+#ifndef _MSC_VER
+#define _MSC_VER_WORKAROUND_GUARD 1
#else
-#define __MSC_VER_WORKAROUND_GUARD 0
+#define _MSC_VER_WORKAROUND_GUARD 0
#endif
#ifndef _MSC_FULL_VER
#define _MSC_FULL_VER_WORKAROUND_GUARD 1
@@ -95,6 +95,11 @@
#else
#define __MWERKS___WORKAROUND_GUARD 0
#endif
+#ifndef __EDG__
+#define __EDG___WORKAROUND_GUARD 1
+#else
+#define __EDG___WORKAROUND_GUARD 0
+#endif
#ifndef __EDG_VERSION__
#define __EDG_VERSION___WORKAROUND_GUARD 1
#else
@@ -105,6 +110,11 @@
#else
#define __HP_aCC_WORKAROUND_GUARD 0
#endif
+#ifndef __hpxstd98
+#define __hpxstd98_WORKAROUND_GUARD 1
+#else
+#define __hpxstd98_WORKAROUND_GUARD 0
+#endif
#ifndef _CRAYC
#define _CRAYC_WORKAROUND_GUARD 1
#else
@@ -120,12 +130,47 @@
#else
#define MPW_CPLUS_WORKAROUND_GUARD 0
#endif
+#ifndef __COMO__
+#define __COMO___WORKAROUND_GUARD 1
+#else
+#define __COMO___WORKAROUND_GUARD 0
+#endif
+#ifndef __COMO_VERSION__
+#define __COMO_VERSION___WORKAROUND_GUARD 1
+#else
+#define __COMO_VERSION___WORKAROUND_GUARD 0
+#endif
+#ifndef __INTEL_COMPILER
+#define __INTEL_COMPILER_WORKAROUND_GUARD 1
+#else
+#define __INTEL_COMPILER_WORKAROUND_GUARD 0
+#endif
+#ifndef __ICL
+#define __ICL_WORKAROUND_GUARD 1
+#else
+#define __ICL_WORKAROUND_GUARD 0
+#endif
+#ifndef _COMPILER_VERSION
+#define _COMPILER_VERSION_WORKAROUND_GUARD 1
+#else
+#define _COMPILER_VERSION_WORKAROUND_GUARD 0
+#endif
#ifndef _RWSTD_VER
#define _RWSTD_VER_WORKAROUND_GUARD 1
#else
#define _RWSTD_VER_WORKAROUND_GUARD 0
#endif
+#ifndef BOOST_RWSTD_VER
+#define BOOST_RWSTD_VER_WORKAROUND_GUARD 1
+#else
+#define BOOST_RWSTD_VER_WORKAROUND_GUARD 0
+#endif
+#ifndef __GLIBCPP__
+#define __GLIBCPP___WORKAROUND_GUARD 1
+#else
+#define __GLIBCPP___WORKAROUND_GUARD 0
+#endif
#ifndef _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC
#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 1
#else
Modified: branches/proto/v4/boost/fusion/tuple/tuple.hpp
==============================================================================
--- branches/proto/v4/boost/fusion/tuple/tuple.hpp (original)
+++ branches/proto/v4/boost/fusion/tuple/tuple.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -16,7 +16,7 @@
#include <boost/fusion/sequence/io.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_const.hpp>
-#include <utility>
+#include <boost/config/no_tr1/utility.hpp>
namespace boost { namespace fusion
{
Modified: branches/proto/v4/boost/math/concepts/real_concept.hpp
==============================================================================
--- branches/proto/v4/boost/math/concepts/real_concept.hpp (original)
+++ branches/proto/v4/boost/math/concepts/real_concept.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -20,6 +20,9 @@
// but note minor additions are needed - see ntl.diff and documentation
// "Using With NTL - a High-Precision Floating-Point Library".
+#ifndef BOOST_MATH_REAL_CONCEPT_HPP
+#define BOOST_MATH_REAL_CONCEPT_HPP
+
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/math/special_functions/round.hpp>
@@ -35,8 +38,9 @@
#include <boost/config/no_tr1/cmath.hpp>
#include <math.h> // fmodl
-#ifndef BOOST_MATH_REAL_CONCEPT_HPP
-#define BOOST_MATH_REAL_CONCEPT_HPP
+#if defined(__SGI_STL_PORT) || defined(_RWSTD_VER) || defined(__LIBCOMO__)
+# include <cstdio>
+#endif
namespace boost{ namespace math{
Modified: branches/proto/v4/boost/test/floating_point_comparison.hpp
==============================================================================
--- branches/proto/v4/boost/test/floating_point_comparison.hpp (original)
+++ branches/proto/v4/boost/test/floating_point_comparison.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -181,8 +181,8 @@
FPT d2 = tt_detail::safe_fpt_division( diff, tt_detail::fpt_abs( left ) );
return p_strong_or_weak
- ? (d1 <= p_fraction_tolerance && d2 <= p_fraction_tolerance)
- : (d1 <= p_fraction_tolerance || d2 <= p_fraction_tolerance);
+ ? (d1 <= p_fraction_tolerance.get() && d2 <= p_fraction_tolerance.get())
+ : (d1 <= p_fraction_tolerance.get() || d2 <= p_fraction_tolerance.get());
}
// Public properties
Modified: branches/proto/v4/boost/test/framework.hpp
==============================================================================
--- branches/proto/v4/boost/test/framework.hpp (original)
+++ branches/proto/v4/boost/test/framework.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -55,6 +55,7 @@
BOOST_TEST_DECL void register_test_unit( test_case* tc );
BOOST_TEST_DECL void register_test_unit( test_suite* ts );
BOOST_TEST_DECL void deregister_test_unit( test_unit* tu );
+BOOST_TEST_DECL void clear();
BOOST_TEST_DECL void register_observer( test_observer& );
BOOST_TEST_DECL void deregister_observer( test_observer& );
Modified: branches/proto/v4/boost/test/impl/execution_monitor.ipp
==============================================================================
--- branches/proto/v4/boost/test/impl/execution_monitor.ipp (original)
+++ branches/proto/v4/boost/test/impl/execution_monitor.ipp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -418,32 +418,32 @@
case CLD_EXITED:
report_error( execution_exception::system_error,
"child has exited; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_uid, (int)m_sig_info->si_pid, (int)m_sig_info->si_status );
+ (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
break;
case CLD_KILLED:
report_error( execution_exception::system_error,
"child was killed; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_uid, (int)m_sig_info->si_pid, (int)m_sig_info->si_status );
+ (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
break;
case CLD_DUMPED:
report_error( execution_exception::system_error,
"child terminated abnormally; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_uid, (int)m_sig_info->si_pid, (int)m_sig_info->si_status );
+ (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
break;
case CLD_TRAPPED:
report_error( execution_exception::system_error,
"traced child has trapped; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_uid, (int)m_sig_info->si_pid, (int)m_sig_info->si_status );
+ (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
break;
case CLD_STOPPED:
report_error( execution_exception::system_error,
"child has stopped; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_uid, (int)m_sig_info->si_pid, (int)m_sig_info->si_status );
+ (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
break;
case CLD_CONTINUED:
report_error( execution_exception::system_error,
"stopped child had continued; pid: %d; uid: %d; exit value: %d",
- (int)m_sig_info->si_uid, (int)m_sig_info->si_pid, (int)m_sig_info->si_status );
+ (int)m_sig_info->si_pid, (int)m_sig_info->si_uid, (int)m_sig_info->si_status );
break;
}
break;
Modified: branches/proto/v4/boost/test/impl/framework.ipp
==============================================================================
--- branches/proto/v4/boost/test/impl/framework.ipp (original)
+++ branches/proto/v4/boost/test/impl/framework.ipp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -119,7 +119,9 @@
, m_test_in_progress( false )
{}
- ~framework_impl()
+ ~framework_impl() { clear(); }
+
+ void clear()
{
while( !m_test_units.empty() ) {
test_unit_store::value_type const& tu = *m_test_units.begin();
@@ -327,6 +329,14 @@
//____________________________________________________________________________//
void
+clear()
+{
+ s_frk_impl().clear();
+}
+
+//____________________________________________________________________________//
+
+void
register_observer( test_observer& to )
{
s_frk_impl().m_observers.insert( &to );
Modified: branches/proto/v4/boost/test/impl/unit_test_parameters.ipp
==============================================================================
--- branches/proto/v4/boost/test/impl/unit_test_parameters.ipp (original)
+++ branches/proto/v4/boost/test/impl/unit_test_parameters.ipp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -208,7 +208,11 @@
s_save_pattern = retrieve_framework_parameter( SAVE_TEST_PATTERN, argc, argv ) == "yes";
s_show_build_info = retrieve_framework_parameter( BUILD_INFO, argc, argv ) == "yes";
s_show_progress = retrieve_framework_parameter( SHOW_PROGRESS, argc, argv ) == "yes";
+#ifdef BOOST_TEST_DEFAULTS_TO_CORE_DUMP
+ s_catch_sys_errors = retrieve_framework_parameter( CATCH_SYS_ERRORS, argc, argv ) == "yes";
+#else
s_catch_sys_errors = retrieve_framework_parameter( CATCH_SYS_ERRORS, argc, argv ) != "no";
+#endif
s_use_alt_stack = retrieve_framework_parameter( USE_ALT_STACK, argc, argv ) != "no";
s_detect_fp_except = retrieve_framework_parameter( DETECT_FP_EXCEPT, argc, argv ) == "yes";
s_tests_to_run = retrieve_framework_parameter( TESTS_TO_RUN, argc, argv );
Modified: branches/proto/v4/boost/test/output/xml_log_formatter.hpp
==============================================================================
--- branches/proto/v4/boost/test/output/xml_log_formatter.hpp (original)
+++ branches/proto/v4/boost/test/output/xml_log_formatter.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -50,6 +50,7 @@
void log_exception( std::ostream&, log_checkpoint_data const&, const_string explanation );
void log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let );
+ using unit_test_log_formatter::log_entry_value; // bring base class functions into overload set
void log_entry_value( std::ostream&, const_string value );
void log_entry_finish( std::ostream& );
Modified: branches/proto/v4/boost/test/utils/iterator/istream_line_iterator.hpp
==============================================================================
--- branches/proto/v4/boost/test/utils/iterator/istream_line_iterator.hpp (original)
+++ branches/proto/v4/boost/test/utils/iterator/istream_line_iterator.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -70,7 +70,7 @@
// increment implementation
bool get()
{
- return std::getline( *m_input_stream, this->m_value, m_delimeter ) != (void*)0;
+ return !!std::getline( *m_input_stream, this->m_value, m_delimeter );
}
// Data members
Modified: branches/proto/v4/boost/test/utils/runtime/cla/iface/argument_factory.hpp
==============================================================================
--- branches/proto/v4/boost/test/utils/runtime/cla/iface/argument_factory.hpp (original)
+++ branches/proto/v4/boost/test/utils/runtime/cla/iface/argument_factory.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -38,6 +38,8 @@
virtual argument_ptr produce_using( parameter& p, argv_traverser& tr ) = 0; /// produce argument based on input
virtual argument_ptr produce_using( parameter& p, parser const& ) = 0; /// produce argument based on internal generator and/or values of other parameters
virtual void argument_usage_info( format_stream& fs ) = 0; /// argument value format information
+protected:
+ BOOST_TEST_PROTECTED_VIRTUAL ~argument_factory() {}
};
} // namespace boost
Modified: branches/proto/v4/boost/test/utils/runtime/cla/iface/id_policy.hpp
==============================================================================
--- branches/proto/v4/boost/test/utils/runtime/cla/iface/id_policy.hpp (original)
+++ branches/proto/v4/boost/test/utils/runtime/cla/iface/id_policy.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -52,6 +52,7 @@
explicit identification_policy( rtti::id_t const& dyn_type )
: p_type_id( dyn_type )
{}
+ BOOST_TEST_PROTECTED_VIRTUAL ~identification_policy() {}
};
} // namespace cla
Modified: branches/proto/v4/boost/throw_exception.hpp
==============================================================================
--- branches/proto/v4/boost/throw_exception.hpp (original)
+++ branches/proto/v4/boost/throw_exception.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -24,7 +24,7 @@
#include <boost/detail/workaround.hpp>
#include <exception>
-#if !defined( BOOST_EXCEPTION_DISABLE ) && defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, < 0x590 )
+#if !defined( BOOST_EXCEPTION_DISABLE ) && defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x593) )
# define BOOST_EXCEPTION_DISABLE
#endif
Modified: branches/proto/v4/boost/unordered_map.hpp
==============================================================================
--- branches/proto/v4/boost/unordered_map.hpp (original)
+++ branches/proto/v4/boost/unordered_map.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -13,812 +13,6 @@
# pragma once
#endif
-#include <boost/config.hpp>
-
-#include <functional>
-#include <memory>
-
-#include <boost/functional/hash.hpp>
-#include <boost/unordered/detail/hash_table.hpp>
-
-#if !defined(BOOST_HAS_RVALUE_REFS)
-#include <boost/unordered/detail/move.hpp>
-#endif
-
-namespace boost
-{
- template <class Key,
- class T,
- class Hash = hash<Key>,
- class Pred = std::equal_to<Key>,
- class Alloc = std::allocator<std::pair<const Key, T> > >
- class unordered_map;
- template <class K, class T, class H, class P, class A>
- bool operator==(unordered_map<K, T, H, P, A> const&,
- unordered_map<K, T, H, P, A> const&);
- template <class K, class T, class H, class P, class A>
- bool operator!=(unordered_map<K, T, H, P, A> const&,
- unordered_map<K, T, H, P, A> const&);
- template <class K, class T, class H, class P, class A>
- void swap(unordered_map<K, T, H, P, A>&,
- unordered_map<K, T, H, P, A>&);
-
- template <class Key,
- class T,
- class Hash = hash<Key>,
- class Pred = std::equal_to<Key>,
- class Alloc = std::allocator<std::pair<const Key, T> > >
- class unordered_multimap;
- template <class K, class T, class H, class P, class A>
- bool operator==(unordered_multimap<K, T, H, P, A> const&,
- unordered_multimap<K, T, H, P, A> const&);
- template <class K, class T, class H, class P, class A>
- bool operator!=(unordered_multimap<K, T, H, P, A> const&,
- unordered_multimap<K, T, H, P, A> const&);
- template <class K, class T, class H, class P, class A>
- void swap(unordered_multimap<K, T, H, P, A>&,
- unordered_multimap<K, T, H, P, A>&);
-
- template <class Key, class T, class Hash, class Pred, class Alloc>
- class unordered_map
- {
- typedef boost::unordered_detail::hash_types_unique_keys<
- std::pair<const Key, T>, Key, Hash, Pred, Alloc
- > implementation;
-
- BOOST_DEDUCED_TYPENAME implementation::hash_table base;
-
- public:
-
- // types
-
- typedef Key key_type;
- typedef std::pair<const Key, T> value_type;
- typedef T mapped_type;
- typedef Hash hasher;
- typedef Pred key_equal;
-
- typedef Alloc allocator_type;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
-
- typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
- typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
-
- typedef BOOST_DEDUCED_TYPENAME implementation::iterator iterator;
- typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
- typedef BOOST_DEDUCED_TYPENAME implementation::local_iterator local_iterator;
- typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
-
- // construct/destroy/copy
-
- explicit unordered_map(
- size_type n = boost::unordered_detail::default_initial_bucket_count,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(n, hf, eql, a)
- {
- }
-
- explicit unordered_map(allocator_type const& a)
- : base(boost::unordered_detail::default_initial_bucket_count,
- hasher(), key_equal(), a)
- {
- }
-
- unordered_map(unordered_map const& other, allocator_type const& a)
- : base(other.base, a)
- {
- }
-
- template <class InputIterator>
- unordered_map(InputIterator f, InputIterator l)
- : base(f, l, boost::unordered_detail::default_initial_bucket_count,
- hasher(), key_equal(), allocator_type())
- {
- }
-
- template <class InputIterator>
- unordered_map(InputIterator f, InputIterator l,
- size_type n,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(f, l, n, hf, eql, a)
- {
- }
-
-#if defined(BOOST_HAS_RVALUE_REFS)
- unordered_map(unordered_map&& other)
- : base(other.base, boost::unordered_detail::move_tag())
- {
- }
-
- unordered_map(unordered_map&& other, allocator_type const& a)
- : base(other.base, a, boost::unordered_detail::move_tag())
- {
- }
-
- unordered_map& operator=(unordered_map&& x)
- {
- base.move(x.base);
- return *this;
- }
-#else
- unordered_map(boost::unordered_detail::move_from<unordered_map<Key, T, Hash, Pred, Alloc> > other)
- : base(other.source.base, boost::unordered_detail::move_tag())
- {
- }
-
-#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
- unordered_map& operator=(unordered_map x)
- {
- base.move(x.base);
- return *this;
- }
-#endif
-#endif
-
- private:
-
- BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
- get(const_iterator const& it)
- {
- return boost::unordered_detail::iterator_access::get(it);
- }
-
- public:
-
- allocator_type get_allocator() const
- {
- return base.get_allocator();
- }
-
- // size and capacity
-
- bool empty() const
- {
- return base.empty();
- }
-
- size_type size() const
- {
- return base.size();
- }
-
- size_type max_size() const
- {
- return base.max_size();
- }
-
- // iterators
-
- iterator begin()
- {
- return iterator(base.data_.begin());
- }
-
- const_iterator begin() const
- {
- return const_iterator(base.data_.begin());
- }
-
- iterator end()
- {
- return iterator(base.data_.end());
- }
-
- const_iterator end() const
- {
- return const_iterator(base.data_.end());
- }
-
- const_iterator cbegin() const
- {
- return const_iterator(base.data_.begin());
- }
-
- const_iterator cend() const
- {
- return const_iterator(base.data_.end());
- }
-
- // modifiers
-
-#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
- template <class... Args>
- std::pair<iterator, bool> emplace(Args&&... args)
- {
- return boost::unordered_detail::pair_cast<iterator, bool>(
- base.insert(std::forward<Args>(args)...));
- }
-
- template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
- {
- return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
- }
-#endif
-
- std::pair<iterator, bool> insert(const value_type& obj)
- {
- return boost::unordered_detail::pair_cast<iterator, bool>(
- base.insert(obj));
- }
-
- iterator insert(const_iterator hint, const value_type& obj)
- {
- return iterator(base.insert_hint(get(hint), obj));
- }
-
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- {
- base.insert_range(first, last);
- }
-
- iterator erase(const_iterator position)
- {
- return iterator(base.data_.erase(get(position)));
- }
-
- size_type erase(const key_type& k)
- {
- return base.erase_key(k);
- }
-
- iterator erase(const_iterator first, const_iterator last)
- {
- return iterator(base.data_.erase_range(get(first), get(last)));
- }
-
- void clear()
- {
- base.data_.clear();
- }
-
- void swap(unordered_map& other)
- {
- base.swap(other.base);
- }
-
- // observers
-
- hasher hash_function() const
- {
- return base.hash_function();
- }
-
- key_equal key_eq() const
- {
- return base.key_eq();
- }
-
- mapped_type& operator[](const key_type &k)
- {
- return base[k].second;
- }
-
- mapped_type& at(const key_type& k)
- {
- return base.at(k).second;
- }
-
- mapped_type const& at(const key_type& k) const
- {
- return base.at(k).second;
- }
-
- // lookup
-
- iterator find(const key_type& k)
- {
- return iterator(base.find(k));
- }
-
- const_iterator find(const key_type& k) const
- {
- return const_iterator(base.find(k));
- }
-
- size_type count(const key_type& k) const
- {
- return base.count(k);
- }
-
- std::pair<iterator, iterator>
- equal_range(const key_type& k)
- {
- return boost::unordered_detail::pair_cast<iterator, iterator>(
- base.equal_range(k));
- }
-
- std::pair<const_iterator, const_iterator>
- equal_range(const key_type& k) const
- {
- return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
- base.equal_range(k));
- }
-
- // bucket interface
-
- size_type bucket_count() const
- {
- return base.bucket_count();
- }
-
- size_type max_bucket_count() const
- {
- return base.max_bucket_count();
- }
-
- size_type bucket_size(size_type n) const
- {
- return base.data_.bucket_size(n);
- }
-
- size_type bucket(const key_type& k) const
- {
- return base.bucket(k);
- }
-
- local_iterator begin(size_type n)
- {
- return local_iterator(base.data_.begin(n));
- }
-
- const_local_iterator begin(size_type n) const
- {
- return const_local_iterator(base.data_.begin(n));
- }
-
- local_iterator end(size_type n)
- {
- return local_iterator(base.data_.end(n));
- }
-
- const_local_iterator end(size_type n) const
- {
- return const_local_iterator(base.data_.end(n));
- }
-
- const_local_iterator cbegin(size_type n) const
- {
- return const_local_iterator(base.data_.begin(n));
- }
-
- const_local_iterator cend(size_type n) const
- {
- return const_local_iterator(base.data_.end(n));
- }
-
- // hash policy
-
- float load_factor() const
- {
- return base.load_factor();
- }
-
- float max_load_factor() const
- {
- return base.max_load_factor();
- }
-
- void max_load_factor(float m)
- {
- base.max_load_factor(m);
- }
-
- void rehash(size_type n)
- {
- base.rehash(n);
- }
-
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
- friend bool operator==(unordered_map const&, unordered_map const&);
- friend bool operator!=(unordered_map const&, unordered_map const&);
-#else
- friend bool operator==<>(unordered_map const&, unordered_map const&);
- friend bool operator!=<>(unordered_map const&, unordered_map const&);
-#endif
- }; // class template unordered_map
-
- template <class K, class T, class H, class P, class A>
- inline bool operator==(unordered_map<K, T, H, P, A> const& m1,
- unordered_map<K, T, H, P, A> const& m2)
- {
- return boost::unordered_detail::equals(m1.base, m2.base);
- }
-
- template <class K, class T, class H, class P, class A>
- inline bool operator!=(unordered_map<K, T, H, P, A> const& m1,
- unordered_map<K, T, H, P, A> const& m2)
- {
- return !boost::unordered_detail::equals(m1.base, m2.base);
- }
-
- template <class K, class T, class H, class P, class A>
- inline void swap(unordered_map<K, T, H, P, A> &m1,
- unordered_map<K, T, H, P, A> &m2)
- {
- m1.swap(m2);
- }
-
- template <class Key, class T, class Hash, class Pred, class Alloc>
- class unordered_multimap
- {
- typedef boost::unordered_detail::hash_types_equivalent_keys<
- std::pair<const Key, T>, Key, Hash, Pred, Alloc
- > implementation;
-
- BOOST_DEDUCED_TYPENAME implementation::hash_table base;
-
- public:
-
- // types
-
- typedef Key key_type;
- typedef std::pair<const Key, T> value_type;
- typedef T mapped_type;
- typedef Hash hasher;
- typedef Pred key_equal;
-
- typedef Alloc allocator_type;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
-
- typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
- typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
-
- typedef BOOST_DEDUCED_TYPENAME implementation::iterator iterator;
- typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
- typedef BOOST_DEDUCED_TYPENAME implementation::local_iterator local_iterator;
- typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
-
- // construct/destroy/copy
-
- explicit unordered_multimap(
- size_type n = boost::unordered_detail::default_initial_bucket_count,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(n, hf, eql, a)
- {
- }
-
- explicit unordered_multimap(allocator_type const& a)
- : base(boost::unordered_detail::default_initial_bucket_count,
- hasher(), key_equal(), a)
- {
- }
-
- unordered_multimap(unordered_multimap const& other, allocator_type const& a)
- : base(other.base, a)
- {
- }
-
- template <class InputIterator>
- unordered_multimap(InputIterator f, InputIterator l)
- : base(f, l, boost::unordered_detail::default_initial_bucket_count,
- hasher(), key_equal(), allocator_type())
- {
- }
-
- template <class InputIterator>
- unordered_multimap(InputIterator f, InputIterator l,
- size_type n,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(f, l, n, hf, eql, a)
- {
- }
-
-#if defined(BOOST_HAS_RVALUE_REFS)
- unordered_multimap(unordered_multimap&& other)
- : base(other.base, boost::unordered_detail::move_tag())
- {
- }
-
- unordered_multimap(unordered_multimap&& other, allocator_type const& a)
- : base(other.base, a, boost::unordered_detail::move_tag())
- {
- }
-
- unordered_multimap& operator=(unordered_multimap&& x)
- {
- base.move(x.base);
- return *this;
- }
-#else
- unordered_multimap(boost::unordered_detail::move_from<unordered_multimap<Key, T, Hash, Pred, Alloc> > other)
- : base(other.source.base, boost::unordered_detail::move_tag())
- {
- }
-
-#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
- unordered_multimap& operator=(unordered_multimap x)
- {
- base.move(x.base);
- return *this;
- }
-#endif
-#endif
-
-
- private:
-
- BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
- get(const_iterator const& it)
- {
- return boost::unordered_detail::iterator_access::get(it);
- }
-
- public:
-
- allocator_type get_allocator() const
- {
- return base.get_allocator();
- }
-
- // size and capacity
-
- bool empty() const
- {
- return base.empty();
- }
-
- size_type size() const
- {
- return base.size();
- }
-
- size_type max_size() const
- {
- return base.max_size();
- }
-
- // iterators
-
- iterator begin()
- {
- return iterator(base.data_.begin());
- }
-
- const_iterator begin() const
- {
- return const_iterator(base.data_.begin());
- }
-
- iterator end()
- {
- return iterator(base.data_.end());
- }
-
- const_iterator end() const
- {
- return const_iterator(base.data_.end());
- }
-
- const_iterator cbegin() const
- {
- return const_iterator(base.data_.begin());
- }
-
- const_iterator cend() const
- {
- return const_iterator(base.data_.end());
- }
-
- // modifiers
-
-#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
- template <class... Args>
- iterator emplace(Args&&... args)
- {
- return iterator(base.insert(std::forward<Args>(args)...));
- }
-
- template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
- {
- return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
- }
-#endif
-
- iterator insert(const value_type& obj)
- {
- return iterator(base.insert(obj));
- }
-
- iterator insert(const_iterator hint, const value_type& obj)
- {
- return iterator(base.insert_hint(get(hint), obj));
- }
-
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- {
- base.insert_range(first, last);
- }
-
- iterator erase(const_iterator position)
- {
- return iterator(base.data_.erase(get(position)));
- }
-
- size_type erase(const key_type& k)
- {
- return base.erase_key(k);
- }
-
- iterator erase(const_iterator first, const_iterator last)
- {
- return iterator(base.data_.erase_range(get(first), get(last)));
- }
-
- void clear()
- {
- base.data_.clear();
- }
-
- void swap(unordered_multimap& other)
- {
- base.swap(other.base);
- }
-
- // observers
-
- hasher hash_function() const
- {
- return base.hash_function();
- }
-
- key_equal key_eq() const
- {
- return base.key_eq();
- }
-
- // lookup
-
- iterator find(const key_type& k)
- {
- return iterator(base.find(k));
- }
-
- const_iterator find(const key_type& k) const
- {
- return const_iterator(base.find(k));
- }
-
- size_type count(const key_type& k) const
- {
- return base.count(k);
- }
-
- std::pair<iterator, iterator>
- equal_range(const key_type& k)
- {
- return boost::unordered_detail::pair_cast<iterator, iterator>(
- base.equal_range(k));
- }
-
- std::pair<const_iterator, const_iterator>
- equal_range(const key_type& k) const
- {
- return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
- base.equal_range(k));
- }
-
- // bucket interface
-
- size_type bucket_count() const
- {
- return base.bucket_count();
- }
-
- size_type max_bucket_count() const
- {
- return base.max_bucket_count();
- }
-
- size_type bucket_size(size_type n) const
- {
- return base.data_.bucket_size(n);
- }
-
- size_type bucket(const key_type& k) const
- {
- return base.bucket(k);
- }
-
- local_iterator begin(size_type n)
- {
- return local_iterator(base.data_.begin(n));
- }
-
- const_local_iterator begin(size_type n) const
- {
- return const_local_iterator(base.data_.begin(n));
- }
-
- local_iterator end(size_type n)
- {
- return local_iterator(base.data_.end(n));
- }
-
- const_local_iterator end(size_type n) const
- {
- return const_local_iterator(base.data_.end(n));
- }
-
- const_local_iterator cbegin(size_type n) const
- {
- return const_local_iterator(base.data_.begin(n));
- }
-
- const_local_iterator cend(size_type n) const
- {
- return const_local_iterator(base.data_.end(n));
- }
-
- // hash policy
-
- float load_factor() const
- {
- return base.load_factor();
- }
-
- float max_load_factor() const
- {
- return base.max_load_factor();
- }
-
- void max_load_factor(float m)
- {
- base.max_load_factor(m);
- }
-
- void rehash(size_type n)
- {
- base.rehash(n);
- }
-
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
- friend bool operator==(unordered_multimap const&, unordered_multimap const&);
- friend bool operator!=(unordered_multimap const&, unordered_multimap const&);
-#else
- friend bool operator==<>(unordered_multimap const&, unordered_multimap const&);
- friend bool operator!=<>(unordered_multimap const&, unordered_multimap const&);
-#endif
- }; // class template unordered_multimap
-
- template <class K, class T, class H, class P, class A>
- inline bool operator==(unordered_multimap<K, T, H, P, A> const& m1,
- unordered_multimap<K, T, H, P, A> const& m2)
- {
- return boost::unordered_detail::equals(m1.base, m2.base);
- }
-
- template <class K, class T, class H, class P, class A>
- inline bool operator!=(unordered_multimap<K, T, H, P, A> const& m1,
- unordered_multimap<K, T, H, P, A> const& m2)
- {
- return !boost::unordered_detail::equals(m1.base, m2.base);
- }
-
- template <class K, class T, class H, class P, class A>
- inline void swap(unordered_multimap<K, T, H, P, A> &m1,
- unordered_multimap<K, T, H, P, A> &m2)
- {
- m1.swap(m2);
- }
-
-} // namespace boost
+#include <boost/unordered/unordered_map.hpp>
#endif // BOOST_UNORDERED_MAP_HPP_INCLUDED
Modified: branches/proto/v4/boost/unordered_set.hpp
==============================================================================
--- branches/proto/v4/boost/unordered_set.hpp (original)
+++ branches/proto/v4/boost/unordered_set.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -13,767 +13,6 @@
# pragma once
#endif
-#include <boost/config.hpp>
-
-#include <functional>
-#include <memory>
-
-#include <boost/functional/hash.hpp>
-#include <boost/unordered/detail/hash_table.hpp>
-
-#if !defined(BOOST_HAS_RVALUE_REFS)
-#include <boost/unordered/detail/move.hpp>
-#endif
-
-namespace boost
-{
- template <class Value,
- class Hash = hash<Value>,
- class Pred = std::equal_to<Value>,
- class Alloc = std::allocator<Value> >
- class unordered_set;
- template <class T, class H, class P, class A>
- bool operator==(unordered_set<T, H, P, A> const&,
- unordered_set<T, H, P, A> const&);
- template <class T, class H, class P, class A>
- bool operator!=(unordered_set<T, H, P, A> const&,
- unordered_set<T, H, P, A> const&);
- template <class T, class H, class P, class A>
- void swap(unordered_set<T, H, P, A> &m1,
- unordered_set<T, H, P, A> &m2);
-
- template <class Value,
- class Hash = hash<Value>,
- class Pred = std::equal_to<Value>,
- class Alloc = std::allocator<Value> >
- class unordered_multiset;
- template <class T, class H, class P, class A>
- bool operator==(unordered_multiset<T, H, P, A> const&,
- unordered_multiset<T, H, P, A> const&);
- template <class T, class H, class P, class A>
- bool operator!=(unordered_multiset<T, H, P, A> const&,
- unordered_multiset<T, H, P, A> const&);
- template <class T, class H, class P, class A>
- void swap(unordered_multiset<T, H, P, A> &m1,
- unordered_multiset<T, H, P, A> &m2);
-
- template <class Value, class Hash, class Pred, class Alloc>
- class unordered_set
- {
- typedef boost::unordered_detail::hash_types_unique_keys<
- Value, Value, Hash, Pred, Alloc
- > implementation;
-
- BOOST_DEDUCED_TYPENAME implementation::hash_table base;
-
- public:
-
- // types
-
- typedef Value key_type;
- typedef Value value_type;
- typedef Hash hasher;
- typedef Pred key_equal;
-
- typedef Alloc allocator_type;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
-
- typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
- typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
-
- typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator iterator;
- typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
- typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator local_iterator;
- typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
-
- // construct/destroy/copy
-
- explicit unordered_set(
- size_type n = boost::unordered_detail::default_initial_bucket_count,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(n, hf, eql, a)
- {
- }
-
- explicit unordered_set(allocator_type const& a)
- : base(boost::unordered_detail::default_initial_bucket_count,
- hasher(), key_equal(), a)
- {
- }
-
- unordered_set(unordered_set const& other, allocator_type const& a)
- : base(other.base, a)
- {
- }
-
- template <class InputIterator>
- unordered_set(InputIterator f, InputIterator l)
- : base(f, l, boost::unordered_detail::default_initial_bucket_count,
- hasher(), key_equal(), allocator_type())
- {
- }
-
- template <class InputIterator>
- unordered_set(InputIterator f, InputIterator l, size_type n,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(f, l, n, hf, eql, a)
- {
- }
-
-#if defined(BOOST_HAS_RVALUE_REFS)
- unordered_set(unordered_set&& other)
- : base(other.base, boost::unordered_detail::move_tag())
- {
- }
-
- unordered_set(unordered_set&& other, allocator_type const& a)
- : base(other.base, a, boost::unordered_detail::move_tag())
- {
- }
-
- unordered_set& operator=(unordered_set&& x)
- {
- base.move(x.base);
- return *this;
- }
-#else
- unordered_set(boost::unordered_detail::move_from<unordered_set<Value, Hash, Pred, Alloc> > other)
- : base(other.source.base, boost::unordered_detail::move_tag())
- {
- }
-
-#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
- unordered_set& operator=(unordered_set x)
- {
- base.move(x.base);
- return *this;
- }
-#endif
-#endif
-
- private:
-
- BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
- get(const_iterator const& it)
- {
- return boost::unordered_detail::iterator_access::get(it);
- }
-
- public:
-
- allocator_type get_allocator() const
- {
- return base.get_allocator();
- }
-
- // size and capacity
-
- bool empty() const
- {
- return base.empty();
- }
-
- size_type size() const
- {
- return base.size();
- }
-
- size_type max_size() const
- {
- return base.max_size();
- }
-
- // iterators
-
- iterator begin()
- {
- return iterator(base.data_.begin());
- }
-
- const_iterator begin() const
- {
- return const_iterator(base.data_.begin());
- }
-
- iterator end()
- {
- return iterator(base.data_.end());
- }
-
- const_iterator end() const
- {
- return const_iterator(base.data_.end());
- }
-
- const_iterator cbegin() const
- {
- return const_iterator(base.data_.begin());
- }
-
- const_iterator cend() const
- {
- return const_iterator(base.data_.end());
- }
-
- // modifiers
-
-#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
- template <class... Args>
- std::pair<iterator, bool> emplace(Args&&... args)
- {
- return boost::unordered_detail::pair_cast<iterator, bool>(
- base.insert(std::forward<Args>(args)...));
- }
-
- template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
- {
- return iterator(
- base.insert_hint(get(hint), std::forward<Args>(args)...));
- }
-#endif
-
- std::pair<iterator, bool> insert(const value_type& obj)
- {
- return boost::unordered_detail::pair_cast<iterator, bool>(
- base.insert(obj));
- }
-
- iterator insert(const_iterator hint, const value_type& obj)
- {
- return iterator(base.insert_hint(get(hint), obj));
- }
-
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- {
- base.insert_range(first, last);
- }
-
- iterator erase(const_iterator position)
- {
- return iterator(base.data_.erase(get(position)));
- }
-
- size_type erase(const key_type& k)
- {
- return base.erase_key(k);
- }
-
- iterator erase(const_iterator first, const_iterator last)
- {
- return iterator(base.data_.erase_range(get(first), get(last)));
- }
-
- void clear()
- {
- base.data_.clear();
- }
-
- void swap(unordered_set& other)
- {
- base.swap(other.base);
- }
-
- // observers
-
- hasher hash_function() const
- {
- return base.hash_function();
- }
-
- key_equal key_eq() const
- {
- return base.key_eq();
- }
-
- // lookup
-
- const_iterator find(const key_type& k) const
- {
- return const_iterator(base.find(k));
- }
-
- size_type count(const key_type& k) const
- {
- return base.count(k);
- }
-
- std::pair<const_iterator, const_iterator>
- equal_range(const key_type& k) const
- {
- return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
- base.equal_range(k));
- }
-
- // bucket interface
-
- size_type bucket_count() const
- {
- return base.bucket_count();
- }
-
- size_type max_bucket_count() const
- {
- return base.max_bucket_count();
- }
-
- size_type bucket_size(size_type n) const
- {
- return base.data_.bucket_size(n);
- }
-
- size_type bucket(const key_type& k) const
- {
- return base.bucket(k);
- }
-
- local_iterator begin(size_type n)
- {
- return local_iterator(base.data_.begin(n));
- }
-
- const_local_iterator begin(size_type n) const
- {
- return const_local_iterator(base.data_.begin(n));
- }
-
- local_iterator end(size_type n)
- {
- return local_iterator(base.data_.end(n));
- }
-
- const_local_iterator end(size_type n) const
- {
- return const_local_iterator(base.data_.end(n));
- }
-
- const_local_iterator cbegin(size_type n) const
- {
- return const_local_iterator(base.data_.begin(n));
- }
-
- const_local_iterator cend(size_type n) const
- {
- return const_local_iterator(base.data_.end(n));
- }
-
- // hash policy
-
- float load_factor() const
- {
- return base.load_factor();
- }
-
- float max_load_factor() const
- {
- return base.max_load_factor();
- }
-
- void max_load_factor(float m)
- {
- base.max_load_factor(m);
- }
-
- void rehash(size_type n)
- {
- base.rehash(n);
- }
-
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
- friend bool operator==(unordered_set const&, unordered_set const&);
- friend bool operator!=(unordered_set const&, unordered_set const&);
-#else
- friend bool operator==<>(unordered_set const&, unordered_set const&);
- friend bool operator!=<>(unordered_set const&, unordered_set const&);
-#endif
- }; // class template unordered_set
-
- template <class T, class H, class P, class A>
- inline bool operator==(unordered_set<T, H, P, A> const& m1,
- unordered_set<T, H, P, A> const& m2)
- {
- return boost::unordered_detail::equals(m1.base, m2.base);
- }
-
- template <class T, class H, class P, class A>
- inline bool operator!=(unordered_set<T, H, P, A> const& m1,
- unordered_set<T, H, P, A> const& m2)
- {
- return !boost::unordered_detail::equals(m1.base, m2.base);
- }
-
- template <class T, class H, class P, class A>
- inline void swap(unordered_set<T, H, P, A> &m1,
- unordered_set<T, H, P, A> &m2)
- {
- m1.swap(m2);
- }
-
- template <class Value, class Hash, class Pred, class Alloc>
- class unordered_multiset
- {
- typedef boost::unordered_detail::hash_types_equivalent_keys<
- Value, Value, Hash, Pred, Alloc
- > implementation;
-
- BOOST_DEDUCED_TYPENAME implementation::hash_table base;
-
- public:
-
- //types
-
- typedef Value key_type;
- typedef Value value_type;
- typedef Hash hasher;
- typedef Pred key_equal;
-
- typedef Alloc allocator_type;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::pointer pointer;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::const_pointer const_pointer;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::reference reference;
- typedef BOOST_DEDUCED_TYPENAME allocator_type::const_reference const_reference;
-
- typedef BOOST_DEDUCED_TYPENAME implementation::size_type size_type;
- typedef BOOST_DEDUCED_TYPENAME implementation::difference_type difference_type;
-
- typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator iterator;
- typedef BOOST_DEDUCED_TYPENAME implementation::const_iterator const_iterator;
- typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator local_iterator;
- typedef BOOST_DEDUCED_TYPENAME implementation::const_local_iterator const_local_iterator;
-
- // construct/destroy/copy
-
- explicit unordered_multiset(
- size_type n = boost::unordered_detail::default_initial_bucket_count,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(n, hf, eql, a)
- {
- }
-
- explicit unordered_multiset(allocator_type const& a)
- : base(boost::unordered_detail::default_initial_bucket_count,
- hasher(), key_equal(), a)
- {
- }
-
- unordered_multiset(unordered_multiset const& other, allocator_type const& a)
- : base(other.base, a)
- {
- }
-
- template <class InputIterator>
- unordered_multiset(InputIterator f, InputIterator l)
- : base(f, l, boost::unordered_detail::default_initial_bucket_count,
- hasher(), key_equal(), allocator_type())
- {
- }
-
- template <class InputIterator>
- unordered_multiset(InputIterator f, InputIterator l, size_type n,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(f, l, n, hf, eql, a)
- {
- }
-
-#if defined(BOOST_HAS_RVALUE_REFS)
- unordered_multiset(unordered_multiset&& other)
- : base(other.base, boost::unordered_detail::move_tag())
- {
- }
-
- unordered_multiset(unordered_multiset&& other, allocator_type const& a)
- : base(other.base, a, boost::unordered_detail::move_tag())
- {
- }
-
- unordered_multiset& operator=(unordered_multiset&& x)
- {
- base.move(x.base);
- return *this;
- }
-#else
- unordered_multiset(boost::unordered_detail::move_from<unordered_multiset<Value, Hash, Pred, Alloc> > other)
- : base(other.source.base, boost::unordered_detail::move_tag())
- {
- }
-
-#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0593)
- unordered_multiset& operator=(unordered_multiset x)
- {
- base.move(x.base);
- return *this;
- }
-#endif
-#endif
-
- private:
-
- BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
- get(const_iterator const& it)
- {
- return boost::unordered_detail::iterator_access::get(it);
- }
-
- public:
-
- allocator_type get_allocator() const
- {
- return base.get_allocator();
- }
-
- // size and capacity
-
- bool empty() const
- {
- return base.empty();
- }
-
- size_type size() const
- {
- return base.size();
- }
-
- size_type max_size() const
- {
- return base.max_size();
- }
-
- // iterators
-
- iterator begin()
- {
- return iterator(base.data_.begin());
- }
-
- const_iterator begin() const
- {
- return const_iterator(base.data_.begin());
- }
-
- iterator end()
- {
- return iterator(base.data_.end());
- }
-
- const_iterator end() const
- {
- return const_iterator(base.data_.end());
- }
-
- const_iterator cbegin() const
- {
- return const_iterator(base.data_.begin());
- }
-
- const_iterator cend() const
- {
- return const_iterator(base.data_.end());
- }
-
- // modifiers
-
-#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
- template <class... Args>
- iterator emplace(Args&&... args)
- {
- return iterator(base.insert(std::forward<Args>(args)...));
- }
-
- template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
- {
- return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
- }
-#endif
-
- iterator insert(const value_type& obj)
- {
- return iterator(base.insert(obj));
- }
-
- iterator insert(const_iterator hint, const value_type& obj)
- {
- return iterator(base.insert_hint(get(hint), obj));
- }
-
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- {
- base.insert_range(first, last);
- }
-
- iterator erase(const_iterator position)
- {
- return iterator(base.data_.erase(get(position)));
- }
-
- size_type erase(const key_type& k)
- {
- return base.erase_key(k);
- }
-
- iterator erase(const_iterator first, const_iterator last)
- {
- return iterator(base.data_.erase_range(get(first), get(last)));
- }
-
- void clear()
- {
- base.data_.clear();
- }
-
- void swap(unordered_multiset& other)
- {
- base.swap(other.base);
- }
-
- // observers
-
- hasher hash_function() const
- {
- return base.hash_function();
- }
-
- key_equal key_eq() const
- {
- return base.key_eq();
- }
-
- // lookup
-
- const_iterator find(const key_type& k) const
- {
- return const_iterator(base.find(k));
- }
-
- size_type count(const key_type& k) const
- {
- return base.count(k);
- }
-
- std::pair<const_iterator, const_iterator>
- equal_range(const key_type& k) const
- {
- return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
- base.equal_range(k));
- }
-
- // bucket interface
-
- size_type bucket_count() const
- {
- return base.bucket_count();
- }
-
- size_type max_bucket_count() const
- {
- return base.max_bucket_count();
- }
-
- size_type bucket_size(size_type n) const
- {
- return base.data_.bucket_size(n);
- }
-
- size_type bucket(const key_type& k) const
- {
- return base.bucket(k);
- }
-
- local_iterator begin(size_type n)
- {
- return local_iterator(base.data_.begin(n));
- }
-
- const_local_iterator begin(size_type n) const
- {
- return const_local_iterator(base.data_.begin(n));
- }
-
- local_iterator end(size_type n)
- {
- return local_iterator(base.data_.end(n));
- }
-
- const_local_iterator end(size_type n) const
- {
- return const_local_iterator(base.data_.end(n));
- }
-
- const_local_iterator cbegin(size_type n) const
- {
- return const_local_iterator(base.data_.begin(n));
- }
-
- const_local_iterator cend(size_type n) const
- {
- return const_local_iterator(base.data_.end(n));
- }
-
- // hash policy
-
- float load_factor() const
- {
- return base.load_factor();
- }
-
- float max_load_factor() const
- {
- return base.max_load_factor();
- }
-
- void max_load_factor(float m)
- {
- base.max_load_factor(m);
- }
-
- void rehash(size_type n)
- {
- base.rehash(n);
- }
-
-#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
- friend bool operator==(unordered_multiset const&, unordered_multiset const&);
- friend bool operator!=(unordered_multiset const&, unordered_multiset const&);
-#else
- friend bool operator==<>(unordered_multiset const&, unordered_multiset const&);
- friend bool operator!=<>(unordered_multiset const&, unordered_multiset const&);
-#endif
- }; // class template unordered_multiset
-
- template <class T, class H, class P, class A>
- inline bool operator==(unordered_multiset<T, H, P, A> const& m1,
- unordered_multiset<T, H, P, A> const& m2)
- {
- return boost::unordered_detail::equals(m1.base, m2.base);
- }
-
- template <class T, class H, class P, class A>
- inline bool operator!=(unordered_multiset<T, H, P, A> const& m1,
- unordered_multiset<T, H, P, A> const& m2)
- {
- return !boost::unordered_detail::equals(m1.base, m2.base);
- }
-
- template <class T, class H, class P, class A>
- inline void swap(unordered_multiset<T, H, P, A> &m1,
- unordered_multiset<T, H, P, A> &m2)
- {
- m1.swap(m2);
- }
-
-} // namespace boost
+#include <boost/unordered/unordered_set.hpp>
#endif // BOOST_UNORDERED_SET_HPP_INCLUDED
Modified: branches/proto/v4/libs/config/doc/html/boost_config/boost_macro_reference.html
==============================================================================
--- branches/proto/v4/libs/config/doc/html/boost_config/boost_macro_reference.html (original)
+++ branches/proto/v4/libs/config/doc/html/boost_config/boost_macro_reference.html 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -652,6 +652,24 @@
<tr>
<td>
<p>
+ <code class="computeroutput"><span class="identifier">BOOST_NO_NESTED_FRIENDSHIP</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ Compiler
+ </p>
+ </td>
+<td>
+ <p>
+ Compiler doesn't allow a nested class to access private members of
+ its containing class. Probably Borland/CodeGear specific.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
<code class="computeroutput"><span class="identifier">BOOST_NO_OPERATORS_IN_NAMESPACE</span></code>
</p>
</td>
@@ -1136,6 +1154,24 @@
<tr>
<td>
<p>
+ <code class="computeroutput"><span class="identifier">BOOST_NO_TYPENAME_WITH_CTOR</span></code>
+ </p>
+ </td>
+<td>
+ <p>
+ Compiler
+ </p>
+ </td>
+<td>
+ <p>
+ The typename keyword cannot be used when creating a temporary of
+ a Dependent type.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
<code class="computeroutput"><span class="identifier">BOOST_NO_UNREACHABLE_RETURN_DETECTION</span></code>
</p>
</td>
Modified: branches/proto/v4/libs/config/doc/html/index.html
==============================================================================
--- branches/proto/v4/libs/config/doc/html/index.html (original)
+++ branches/proto/v4/libs/config/doc/html/index.html 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -962,7 +962,7 @@
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
-<td align="left"><p><small>Last revised: August 25, 2008 at 09:59:24 GMT</small></p></td>
+<td align="left"><p><small>Last revised: September 19, 2008 at 12:01:08 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>
Modified: branches/proto/v4/libs/config/doc/macro_reference.qbk
==============================================================================
--- branches/proto/v4/libs/config/doc/macro_reference.qbk (original)
+++ branches/proto/v4/libs/config/doc/macro_reference.qbk 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -171,6 +171,10 @@
specializations as a standard library "fix", only if the compiler supports
the `__int64` datatype.
]]
+[[`BOOST_NO_NESTED_FRIENDSHIP`][Compiler][
+Compiler doesn't allow a nested class to access private members of its
+containing class. Probably Borland/CodeGear specific.
+]]
[[`BOOST_NO_OPERATORS_IN_NAMESPACE`][Compiler][
Compiler requires inherited operator friend functions to be defined at
namespace scope, then using'ed to boost. Probably GCC specific. See
@@ -271,6 +275,10 @@
[[`BOOST_NO_TYPEID`][Compiler][
The compiler does not support the typeid operator at all.
]]
+[[`BOOST_NO_TYPENAME_WITH_CTOR`][Compiler][
+The typename keyword cannot be used when creating a temporary of a
+Dependent type.
+]]
[[`BOOST_NO_UNREACHABLE_RETURN_DETECTION`][Compiler][
If a return is unreachable, then no return statement should be required,
however some compilers insist on it, while other issue a bunch of warnings
Modified: branches/proto/v4/libs/config/test/all/Jamfile.v2
==============================================================================
--- branches/proto/v4/libs/config/test/all/Jamfile.v2 (original)
+++ branches/proto/v4/libs/config/test/all/Jamfile.v2 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -1,7 +1,7 @@
#
# Regression test Jamfile for boost configuration setup.
# *** DO NOT EDIT THIS FILE BY HAND ***
-# This file was automatically generated on Mon Aug 25 10:51:52 2008
+# This file was automatically generated on Thu Sep 18 23:32:18 2008
# by libs/config/tools/generate.cpp
# Copyright John Maddock.
# Use, modification and distribution are subject to the
@@ -274,6 +274,9 @@
test-suite "BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS" :
[ run ../no_mem_tem_pnts_pass.cpp ]
[ compile-fail ../no_mem_tem_pnts_fail.cpp ] ;
+test-suite "BOOST_NO_NESTED_FRIENDSHIP" :
+[ run ../no_nested_friendship_pass.cpp ]
+[ compile-fail ../no_nested_friendship_fail.cpp ] ;
test-suite "BOOST_NO_OPERATORS_IN_NAMESPACE" :
[ run ../no_ops_in_namespace_pass.cpp ]
[ compile-fail ../no_ops_in_namespace_fail.cpp ] ;
@@ -355,6 +358,9 @@
test-suite "BOOST_NO_TYPEID" :
[ run ../no_typeid_pass.cpp ]
[ compile-fail ../no_typeid_fail.cpp ] ;
+test-suite "BOOST_NO_TYPENAME_WITH_CTOR" :
+[ run ../no_typename_with_ctor_pass.cpp ]
+[ compile-fail ../no_typename_with_ctor_fail.cpp ] ;
test-suite "BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL" :
[ run ../no_using_breaks_adl_pass.cpp ]
[ compile-fail ../no_using_breaks_adl_fail.cpp ] ;
Modified: branches/proto/v4/libs/config/test/boost_no_is_abstract.ipp
==============================================================================
--- branches/proto/v4/libs/config/test/boost_no_is_abstract.ipp (original)
+++ branches/proto/v4/libs/config/test/boost_no_is_abstract.ipp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -12,11 +12,18 @@
namespace boost_no_is_abstract{
+#if defined(__CODEGEARC__)
template<class T>
struct is_abstract_test
{
- // Deduction fails if T is void, function type,
- // reference type (14.8.2/2)or an abstract class type
+ enum{ value = __is_abstract(T) };
+};
+#else
+template<class T>
+struct is_abstract_test
+{
+ // Deduction fails if T is void, function type,
+ // reference type (14.8.2/2)or an abstract class type
// according to review status issue #337
//
template<class U>
@@ -29,9 +36,10 @@
#else
enum{ s1 = sizeof(check_sig<T>(0)) };
#endif
-
+
enum{ value = (s1 == sizeof(char)) };
};
+#endif
struct non_abstract{};
struct abstract{ virtual void foo() = 0; };
@@ -43,10 +51,3 @@
}
-
-
-
-
-
-
-
Modified: branches/proto/v4/libs/config/test/config_info.cpp
==============================================================================
--- branches/proto/v4/libs/config/test/config_info.cpp (original)
+++ branches/proto/v4/libs/config/test/config_info.cpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -982,6 +982,7 @@
PRINT_MACRO(BOOST_NO_MEMBER_TEMPLATE_FRIENDS);
PRINT_MACRO(BOOST_NO_MEMBER_TEMPLATE_KEYWORD);
PRINT_MACRO(BOOST_NO_MS_INT64_NUMERIC_LIMITS);
+ PRINT_MACRO(BOOST_NO_NESTED_FRIENDSHIP);
PRINT_MACRO(BOOST_NO_OPERATORS_IN_NAMESPACE);
PRINT_MACRO(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS);
PRINT_MACRO(BOOST_NO_POINTER_TO_MEMBER_CONST);
@@ -1010,6 +1011,7 @@
PRINT_MACRO(BOOST_NO_TEMPLATE_TEMPLATES);
PRINT_MACRO(BOOST_NO_TWO_PHASE_NAME_LOOKUP);
PRINT_MACRO(BOOST_NO_TYPEID);
+ PRINT_MACRO(BOOST_NO_TYPENAME_WITH_CTOR);
PRINT_MACRO(BOOST_NO_UNREACHABLE_RETURN_DETECTION);
PRINT_MACRO(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE);
PRINT_MACRO(BOOST_NO_USING_TEMPLATE);
@@ -1037,6 +1039,7 @@
+
// END GENERATED BLOCK
PRINT_MACRO(BOOST_INTEL);
Modified: branches/proto/v4/libs/config/test/config_test.cpp
==============================================================================
--- branches/proto/v4/libs/config/test/config_test.cpp (original)
+++ branches/proto/v4/libs/config/test/config_test.cpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -1,4 +1,4 @@
-// This file was automatically generated on Mon Aug 25 10:51:52 2008
+// This file was automatically generated on Thu Sep 18 23:32:18 2008
// by libs/config/tools/generate.cpp
// Copyright John Maddock 2002-4.
// Use, modification and distribution are subject to the
@@ -187,6 +187,11 @@
#else
namespace boost_no_pointer_to_member_template_parameters = empty_boost;
#endif
+#ifndef BOOST_NO_NESTED_FRIENDSHIP
+#include "boost_no_nested_friendship.ipp"
+#else
+namespace boost_no_nested_friendship = empty_boost;
+#endif
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
#include "boost_no_ops_in_namespace.ipp"
#else
@@ -322,6 +327,11 @@
#else
namespace boost_no_typeid = empty_boost;
#endif
+#ifndef BOOST_NO_TYPENAME_WITH_CTOR
+#include "boost_no_typename_with_ctor.ipp"
+#else
+namespace boost_no_typename_with_ctor = empty_boost;
+#endif
#ifndef BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL
#include "boost_no_using_breaks_adl.ipp"
#else
@@ -1026,6 +1036,11 @@
std::cerr << "Failed test for BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS at: " << __FILE__ << ":" << __LINE__ << std::endl;
++error_count;
}
+ if(0 != boost_no_nested_friendship::test())
+ {
+ std::cerr << "Failed test for BOOST_NO_NESTED_FRIENDSHIP at: " << __FILE__ << ":" << __LINE__ << std::endl;
+ ++error_count;
+ }
if(0 != boost_no_operators_in_namespace::test())
{
std::cerr << "Failed test for BOOST_NO_OPERATORS_IN_NAMESPACE at: " << __FILE__ << ":" << __LINE__ << std::endl;
@@ -1161,6 +1176,11 @@
std::cerr << "Failed test for BOOST_NO_TYPEID at: " << __FILE__ << ":" << __LINE__ << std::endl;
++error_count;
}
+ if(0 != boost_no_typename_with_ctor::test())
+ {
+ std::cerr << "Failed test for BOOST_NO_TYPENAME_WITH_CTOR at: " << __FILE__ << ":" << __LINE__ << std::endl;
+ ++error_count;
+ }
if(0 != boost_function_scope_using_declaration_breaks_adl::test())
{
std::cerr << "Failed test for BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL at: " << __FILE__ << ":" << __LINE__ << std::endl;
Modified: branches/proto/v4/libs/proto/doc/transforms.qbk
==============================================================================
--- branches/proto/v4/libs/proto/doc/transforms.qbk (original)
+++ branches/proto/v4/libs/proto/doc/transforms.qbk 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -1,1013 +1,1014 @@
-[/
- / Copyright (c) 2006 Eric Niebler
- /
- / 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)
- /]
-
-[import ../test/examples.cpp]
-
-[/============================================================================]
-[section:expression_transformation Expression Transformation: Semantic Actions]
-[/============================================================================]
-
-If you have ever built a parser with the help of a tool like Antlr, yacc or Boost.Spirit, you might be familiar with /semantic actions/. In addition to allowing you to define the grammar of the language recognized by the parser, these tools let you embed code within your grammar that executes when parts of the grammar participate in a parse. Proto has the equivalent of semantic actions. They are called /transforms/. This section describes how to embed transforms within your Proto grammars, turning your grammars into function objects that can manipulate or evaluate expressions in powerful ways.
-
-Proto transforms are an advanced topic. We'll take it slow, using examples to illustrate the key concepts, starting simple.
-
-[/==================================]
-[section ["Activating] Your Grammars]
-[/==================================]
-
-The Proto grammars we've seen so far are static. You can check at compile-time to see if an expression type matches a grammar, but that's it. Things get more interesting when you give them runtime behaviors. A grammar with embedded transforms is more than just a static grammar. It is a function object that accepts expressions that match the grammar and does /something/ with them.
-
-Below is a very simple grammar. It matches terminal expressions.
-
- // A simple Proto grammar that matches all terminals
- proto::terminal< _ >
-
-Here is the same grammar with a transform that extracts the value from the terminal:
-
- // A simple Proto grammar that matches all terminals
- // *and* a function object that extracts the value from
- // the terminal
- proto::when<
- proto::terminal< _ >
- , proto::_value // <-- Look, a transform!
- >
-
-You can read this as follows: when you match a terminal expression, extract the value. The type `proto::_value` is a so-called transform. Later we'll see what makes it a transform, but for now just think of it as a kind of function object. Note the use of _when_: the first template parameter is the grammar to match and the second is the transform to execute. The result is both a grammar that matches terminal expressions and a function object that accepts terminal expressions and extracts their values.
-
-As with ordinary grammars, we can define an empty struct that inherits from a grammar+transform to give us an easy way to refer back to the thing we're defining, as follows:
-
- // A grammar and a function object, as before
- struct Value
- : proto::when<
- proto::terminal< _ >
- , proto::_value
- >
- {};
-
- // "Value" is a grammar that matches terminal expressions
- BOOST_MPL_ASSERT(( proto::matches< proto::terminal<int>::type, Value > ));
-
- // "Value" also defines a function object that accepts terminals
- // and extracts their value.
- proto::terminal<int>::type answer = {42};
- Value get_value;
- int i = get_value( answer );
-
-As already mentioned, `Value` is a grammar that matches terminal expressions and a function object that operates on terminal expressions. It would be an error to pass a non-terminal expression to the `Value` function object. This is a general property of grammars with transforms; when using them as function objects, expressions passed to them must match the grammar.
-
-Proto grammars are valid TR1-style function objects. That means you can use `boost::result_of<>` to ask a grammar what its return type will be, given a particular expression type. For instance, we can access the `Value` grammar's return type as follows:
-
- // We can use boost::result_of<> to get the return type
- // of a Proto grammar.
- typedef
- typename boost::result_of<Value(proto::terminal<int>::type)>::type
- result_type;
-
- // Check that we got the type we expected
- BOOST_MPL_ASSERT(( boost::is_same<result_type, int> ));
-
-[note A grammar with embedded transforms is both a grammar and a function object. Calling these things "grammars with transforms" would get tedious. We could call them something like "active grammars", but as we'll see /every/ grammar that you can define with Proto is "active"; that is, every grammar has some behavior when used as a function object. So we'll continue calling these things plain "grammars". The term "transform" is reserved for the thing that is used as the second parameter to the _when_ template.]
-
-[endsect]
-
-[/=========================================]
-[section Handling Alternation and Recursion]
-[/=========================================]
-
-Most grammars are a little more complicated than the one in the preceeding section. For the sake of illustration, let's define a rather nonsensical grammar that matches any expression and recurses to the leftmost terminal and returns its value. It will demonstrate how two key concepts of Proto grammars -- alternation and recursion -- interact with transforms. The grammar is described below.
-
- // A grammar that matches any expression, and a function object
- // that returns the value of the leftmost terminal.
- struct LeftmostLeaf
- : proto::or_<
- // If the expression is a terminal, return its value
- proto::when<
- proto::terminal< _ >
- , proto::_value
- >
- // Otherwise, it is a non-terminal. Return the result
- // of invoking LeftmostLeaf on the 0th (leftmost) child.
- , proto::when<
- _
- , LeftmostLeaf( proto::_child0 )
- >
- >
- {};
-
- // A Proto terminal wrapping std::cout
- proto::terminal< std::ostream & >::type cout_ = { std::cout };
-
- // Create an expression and use LeftmostLeaf to extract the
- // value of the leftmost terminal, which will be std::cout.
- std::ostream & sout = LeftmostLeaf()( cout_ << "the answer: " << 42 << '\n' );
-
-We've seen `proto::or_<>` before. Here it is serving two roles. First, it is a grammar that matches any of its alternate sub-grammars; in this case, either a terminal or a non-terminal. Second, it is also a function object that accepts an expression, finds the alternate sub-grammar that matches the expression, and applies its transform. And since `LeftmostLeaf` inherits from `proto::or_<>`, `LeftmostLeaf` is also both a grammar and a function object.
-
-[def _some_transform_ [~some-transform]]
-
-[note The second alternate uses `proto::_` as its grammar. Recall that `proto::_` is the wildcard grammar that matches any expression. Since alternates in `proto::or_<>` are tried in order, and since the first alternate handles all terminals, the second alternate handles all (and only) non-terminals. Often enough, `proto::when< _, _some_transform_ >` is the last alternate in a grammar, so for improved readability, you could use the equivalent `proto::otherwise< _some_transform_ >`.]
-
-The next section describes this grammar further.
-
-[endsect]
-
-[/==========================]
-[section Callable Transforms]
-[/==========================]
-
-[def __bold_transform__ [*LeftmostLeaf( proto::_child0 )]]
-
-In the grammar defined in the preceeding section, the transform associated with non-terminals is a little strange-looking:
-
- proto::when<
- _
- , __bold_transform__ // <-- a "callable" transform
- >
-
-It has the effect of accepting non-terminal expressions, taking the 0th (leftmost) child and recursively invoking the `LeftmostLeaf` function on it. But `LeftmostLeaf( proto::_child0 )` is actually a /function type/. Literally, it is the type of a function that accepts an object of type `proto::_child0` and returns an object of type `LeftmostLeaf`. So how do we make sense of this transform? Clearly, there is no function that actually has this signature, nor would such a function be useful. The key is in understanding how `proto::when<>` /interprets/ its second template parameter.
-
-When the second template parameter to _when_ is a function type, _when_ interprets the function type as a transform. In this case, `LeftmostLeaf` is treated as the type of a function object to invoke, and `proto::_child0` is treated as a transform. First, `proto::_child0` is applied to the current expression (the non-terminal that matched this alternate sub-grammar), and the result (the 0th child) is passed as an argument to `LeftmostLeaf`.
-
-[note *Transforms are a Domain-Specific Language*
-
-`LeftmostLeaf( proto::_child0 )` /looks/ like an invocation of the `LeftmostLeaf` function object, but it's not, but then it actually is! Why this confusing subterfuge? Function types give us a natural and concise syntax for composing more complicated transforms from simpler ones. The fact that the syntax is suggestive of a function invocation is on purpose. It is a domain-specific embedded language for defining expression transformations. If the subterfuge worked, it may have fooled you into thinking the transform is doing exactly what it actually does! And that's the point.]
-
-The type `LeftmostLeaf( proto::_child0 )` is an example of a /callable transform/. It is a function type that represents a function object to call and its arguments. The types `proto::_child0` and `proto::_value` are /primitive transforms/. They are plain structs, not unlike function objects, from which callable transforms can be composed. There is one other type of transform, /object transforms/, that we'll encounter next.
-
-[endsect]
-
-[/========================]
-[section Object Transforms]
-[/========================]
-
-The very first transform we looked at simply extracted the value of terminals. Let's do the same thing, but this time we'll promote all ints to longs first. (Please forgive the contrived-ness of the examples so far; they get more interesting later.) Here's the grammar:
-
- // A simple Proto grammar that matches all terminals,
- // and a function object that extracts the value from
- // the terminal, promoting ints to longs:
- struct ValueWithPomote
- : proto::or_<
- proto::when<
- proto::terminal< int >
- , long(proto::_value) // <-- an "object" transform
- >
- , proto::when<
- proto::terminal< _ >
- , proto::_value
- >
- >
- {};
-
-You can read the above grammar as follows: when you match an int terminal, extract the value from the terminal and use it to initialize a long; otherwise, when you match another kind of terminal, just extract the value. The type `long(proto::_value)` is a so-called /object/ transform. It looks like the creation of a temporary long, but it's really a function type. Just as a callable transform is a function type that represents a function to call and its arguments, an object transforms is a function type that represents an object to construct and the arguments to its constructor.
-
-[/================================================]
-[note *Object Transforms vs. Callable Transforms*
-
-When using function types as Proto transforms, they can either represent an object to construct or a function to call. It is similar to "normal" C++ where the syntax `foo("arg")` can either be interpreted as an object to construct or a function to call, depending on whether `foo` is a type or a function. But consider two of the transforms we've seen so far:
-
-``
- LeftmostLeaf(proto::_child0) // <-- a callable transform
- long(proto::_value) // <-- an object transform
-``
-
-Proto can't know in general which is which, so it uses a trait, `proto::is_callable<>`, to differentiate. `is_callable< long >::value` is false so `long(proto::_value)` is an object to construct, but `is_callable< LeftmostLeaf >::value` is true so `LeftmostLeaf(proto::_child0)` is a function to call. Later on, we'll see how Proto recognizes a type as "callable".]
-[/================================================]
-
-[endsect]
-
-[/================================]
-[section Example: Calculator Arity]
-[/================================]
-
-Now that we have the basics of Proto transforms down, let's consider a slightly more realistic example. We can use transforms to improve the type-safety of the [link boost_proto.users_guide.getting_started.hello_calculator calculator DSEL]. If you recall, it lets you write infix arithmetic expressions involving argument placeholders like `_1` and `_2` and pass them to STL algorithms as function objects, as follows:
-
- double a1[4] = { 56, 84, 37, 69 };
- double a2[4] = { 65, 120, 60, 70 };
- double a3[4] = { 0 };
-
- // Use std::transform() and a calculator expression
- // to calculate percentages given two input sequences:
- std::transform(a1, a1+4, a2, a3, (_2 - _1) / _2 * 100);
-
-This works because we gave calculator expressions an `operator()` that evaluates the expression, replacing the placeholders with the arguments to `operator()`. The overloaded `calculator<>::operator()` looked like this:
-
- // Overload operator() to invoke proto::eval() with
- // our calculator_context.
- template<typename Expr>
- double
- calculator<Expr>::operator()(double a1 = 0, double a2 = 0, double a3 = 0) const
- {
- calculator_context ctx;
- ctx.args.push_back(a1);
- ctx.args.push_back(a2);
- ctx.args.push_back(a3);
-
- return proto::eval(*this, ctx);
- }
-
-Although this works, it's not ideal because it doesn't warn users if they supply too many or too few arguments to a calculator expression. Consider the following mistakes:
-
- (_1 * _1)(4, 2); // Oops, too many arguments!
- (_2 * _2)(42); // Oops, too few arguments!
-
-The expression `_1 * _1` defines a unary calculator expression; it takes one argument and squares it. If we pass more than one argument, the extra arguments will be silently ignored, which might be surprising to users. The next expression, `_2 * _2` defines a binary calculator expression; it takes two arguments, ignores the first and squares the second. If we only pass one argument, the code silently fills in `0.0` for the second argument, which is also probably not what users expect. What can be done?
-
-We can say that the /arity/ of a calculator expression is the number of arguments it expects, and it is equal to the largest placeholder in the expression. So, the arity of `_1 * _1` is one, and the arity of `_2 * _2` is two. We can increase the type-safety of our calculator DSEL by making sure the artiy of an expression equals the actual number of arguments supplied. Computing the artiy of an expression is simple with the help of Proto transforms.
-
-It's straightforward to describe in words how the arity of an expression should
-be calculated. Consider that calculator expressions can be made of `_1`, `_2`, literals, unary expressions and binary expressions. The following table shows the arities for each of these 5 constituents.
-
-[table Calculator Sub-Expression Arities
- [[Sub-Expression] [Arity]]
- [[Placeholder 1] [`1`]]
- [[Placeholder 2] [`2`]]
- [[Literal] [`0`]]
- [[Unary Expression] [ /arity of the operand/ ]]
- [[Binary Expression] [ /max arity of the two operands/ ]]
-]
-
-Using this information, we can write the grammar for calculator expressions and attach transforms for computing the arity of each constituent. The code below computes the expression arity as a compile-time integer, using integral wrappers and metafunctions from the Boost MPL Library. The grammar is described below.
-
-[CalcArity]
-
-When we find a placeholder terminal or a literal, we use an /object transform/ such as `mpl::int_<1>()` to create a (default-constructed) compile-time integer representing the arity of that terminal.
-
-For unary expressions, we use `CalcArity(proto::_child)` which is a /callable transform/ that computes the arity of the expression's child.
-
-The transform for binary expressions has a few new tricks. Let's look more closely:
-
- // Compute the left and right arities and
- // take the larger of the two.
- mpl::max<CalcArity(proto::_left),
- CalcArity(proto::_right)>()
-
-This is an object transform; it default-constructs ... what exactly? The `mpl::max<>` template is an MPL metafunction that accepts two compile-time integers. It has a nested `::type` typedef (not shown) that is the maximum of the two. But here, we appear to be passing it two things that are /not/ compile-time integers; they're Proto callable transforms. Proto is smart enough to recognize that fact. It first evaluates the two nested callable transforms, computing the arities of the left and right child expressions. Then it puts the resulting integers into `mpl::max<>` and evaluates the metafunction by asking for the nested `::type`. That is the type of the object that gets default-constructed and returned.
-
-More generally, when evaluating object transforms, Proto looks at the object type and checks whether it is a template specialization, like `mpl::max<>`. If it is, Proto looks for nested transforms that it can evaluate. After any nested transforms have been evaluated and substituted back into the template, the new template specialization is the result type, unless that type has a nested `::type`, in which case that becomes the result.
-
-Now that we can calculate the arity of a calculator expression, let's redefine the `calculator<>` expression wrapper we wrote in the Getting Started guide to use the `CalcArity` grammar and some macros from Boost.MPL to issue compile-time errors when users specify too many or too few arguments.
-
- // The calculator expression wrapper, as defined in the Hello
- // Calculator example in the Getting Started guide. It behaves
- // just like the expression it wraps, but with extra operator()
- // member functions that evaluate the expression.
- // NEW: Use the CalcArity grammar to ensure that the correct
- // number of arguments are supplied.
- template<typename Expr>
- struct calculator
- : proto::extends<Expr, calculator<Expr>, calculator_domain>
- {
- typedef
- proto::extends<Expr, calculator<Expr>, calculator_domain>
- base_type;
-
- calculator(Expr const &expr = Expr())
- : base_type(expr)
- {}
-
- typedef double result_type;
-
- // Use CalcArity to compute the arity of Expr:
- static int const arity = boost::result_of<CalcArity(Expr)>::type::value;
-
- double operator()() const
- {
- BOOST_MPL_ASSERT_RELATION(0, ==, arity);
- calculator_context ctx;
- return proto::eval(*this, ctx);
- }
-
- double operator()(double a1) const
- {
- BOOST_MPL_ASSERT_RELATION(1, ==, arity);
- calculator_context ctx;
- ctx.args.push_back(a1);
- return proto::eval(*this, ctx);
- }
-
- // ... and additional operator() overloads to handle more arguments ...
- };
-
-Note the use of `boost::result_of<>` to access the return type of the `CalcArity` function object. Since we used compile-time integers in our transforms, the arity of the expression is encoded in the return type of the `CalcArity` function object. Proto grammars are valid TR1-style function objects, so you can use `boost::result_of<>` to figure out their return types.
-
-With our compile-time assertions in place, when users provide too many or too few arguments to a calculator expression, as in:
-
- (_2 * _2)(42); // Oops, too few arguments!
-
-... they will get a compile-time error message on the line with the assertion that reads something like this[footnote This error message was generated with Microsoft Visual C++ 9.0. Different compilers will emit different messages with varying degrees of readability.]:
-
-[pre
-c:\boost\org\trunk\libs\proto\scratch\main.cpp(97) : error C2664: 'boost::mpl::asse
-rtion\_failed' : cannot convert parameter 1 from 'boost::mpl::failed \*\*\*\*\*\*\*\*\*\*\*\*boo
-st::mpl::assert\_relation<x,y,\_\_formal>::\*\*\*\*\*\*\*\*\*\*\*\*' to 'boost::mpl::assert<false>
-::type'
- with
- \[
- x\=1,
- y\=2,
- \_\_formal\=bool boost::mpl::operator\=\=(boost::mpl::failed,boost::mpl::failed)
- \]
-]
-
-The point of this exercise was to show that we can write a fairly simple Proto grammar with embedded transforms that is declarative and readable and can compute interesting properties of arbitrarily complicated expressions. But transforms can do more than that. Boost.Xpressive uses transforms to turn expressions into finite state automata for matching regular expressions, and Boost.Spirit uses transforms to build recursive descent parser generators. Proto comes with a collection of built-in transforms that you can use to perform very sophisticated expression manipulations like these. In the next few sections we'll see some of them in action.
-
-[endsect]
-
-[/===============================================]
-[section:state Transforms With State Accumulation]
-[/===============================================]
-
-So far, we've only seen examples of grammars with transforms that accept one argument: the expression to transform. But consider for a moment how, in ordinary procedural code, you would turn a binary tree into a linked list. You would start with an empty list. Then, you would recursively convert the right branch to a list, and use the result as the initial state while converting the left branch to a list. That is, you would need a function that takes two parameters: the current node and the list so far. These sorts of /accumulation/ problems are quite common when processing trees. The linked list is an example of an accumulation variable or /state/. Each iteration of the algorithm takes the current element and state, applies some binary function to the two and creates a new state. In the STL, this algorithm is called `std::accumulate()`. In many other languages, it is called /fold/. Let's see how to implement a fold algorithm with Proto transforms.
-
-All Proto grammars can optionally accept a state parameter in addition to the expression to transform. If you want to fold a tree to a list, you'll need to make use of the state parameter to pass around the list you've built so far. As for the list, the Boost.Fusion library provides a `fusion::cons<>` type from which you can build heterogenous lists. The type `fusion::nil` represents an empty list.
-
-Below is a grammar that recognizes output expressions like `cout_ << 42 << '\n'` and puts the arguments into a Fusion list. It is explained below.
-
- // Fold the terminals in output statements like
- // "cout_ << 42 << '\n'" into a Fusion cons-list.
- struct FoldToList
- : proto::or_<
- // Don't add the ostream terminal to the list
- proto::when<
- proto::terminal< std::ostream & >
- , proto::_state
- >
- // Put all other terminals at the head of the
- // list that we're building in the "state" parameter
- , proto::when<
- proto::terminal<_>
- , fusion::cons<proto::_value, proto::_state>(
- proto::_value, proto::_state
- )
- >
- // For left-shift operations, first fold the right
- // child to a list using the current state. Use
- // the result as the state parameter when folding
- // the left child to a list.
- , proto::when<
- proto::shift_left<FoldToList, FoldToList>
- , FoldToList(
- proto::_left
- , FoldToList(proto::_right, proto::_state)
- )
- >
- >
- {};
-
-Before reading on, see if you can apply what you know already about object, callable and primitive transforms to figure out how this grammar works.
-
-When you use the `FoldToList` function, you'll need to pass two arguments: the expression to fold, and the initial state: an empty list. Those two arguments get passed around to each transform. We learned previously that `proto::_value` is a primitive transform that accepts a terminal expression and extracts its value. What we didn't know until now was that it also accepts the current state /and ignores it/. `proto::_state` is also a primitive transform. It accepts the current expression, which it ignores, and the current state, which it returns.
-
-When we find a terminal, we stick it at the head of the cons list, using the current state as the tail of the list. (The first alternate causes the `ostream` to be skipped. We don't want `cout` in the list.) When we find a shift-left node, we apply the following transform:
-
- // Fold the right child and use the result as
- // state while folding the right.
- FoldToList(
- proto::_left
- , FoldToList(proto::_right, proto::_state)
- )
-
-You can read this transform as follows: using the current state, fold the right child to a list. Use the new list as the state while folding the left child to a list.
-
-[tip If your compiler is Microsoft Visual C++, you'll find that the above transform does not compile. The compiler has bugs with its handling of nested function types. You can work around the bug by wrapping the inner transform in `proto::call<>` as follows:
-
-``
- FoldToList(
- proto::_left
- , proto::call<FoldToList(proto::_right, proto::_state)>
- )
-``
-
-`proto::call<>` turns a callable transform into a primitive transform, but more on that later.
-]
-
-Now that we have defined the `FoldToList` function object, we can use it to turn output expressions into lists as follows:
-
- proto::terminal<std::ostream &>::type const cout_ = {std::cout};
-
- // This is the type of the list we build below
- typedef
- fusion::cons<
- int
- , fusion::cons<
- double
- , fusion::cons<
- char
- , fusion::nil
- >
- >
- >
- result_type;
-
- // Fold an output expression into a Fusion list, using
- // fusion::nil as the initial state of the transformation.
- FoldToList to_list;
- result_type args = to_list(cout_ << 1 << 3.14 << '\n', fusion::nil());
-
- // Now "args" is the list: {1, 3.14, '\n'}
-
-When writing transforms, "fold" is such a basic operation that Proto provides a number of built-in fold transforms. We'll get to them later. For now, rest assured that you won't always have to strech your brain so far to do such basic things.
-
-[endsect]
-
-[/================================================]
-[section:data Passing Auxiliary Data To Transforms]
-[/================================================]
-
-In the last section, we saw that we can pass a second parameter to grammars with transforms: an accumulation variable or /state/ that gets updated as your transform executes. There are times when your transforms will need to access auxiliary data that does /not/ accumulate, so bundling it with the state parameter is impractical. Instead, you can pass auxiliary data as a third parameter, known as the /data/ parameter. Below we show an example involving string processing where the data parameter is essential.
-
-[note All Proto grammars are function objects that take one, two or three arguments: the expression, the state, and the data. There are no additional arguments to know about, we promise. In Haskell, there is set of a tree traversal technologies known collectively as _SYB_. In that framework, there are also three parameters: the term, the accumulator, and the context. These are Proto's expression, state and data parameters under different names.]
-
-Expression templates are often used as an optimization to eliminate temporary objects. Condsier the problem of string concatenation: a series of concatenations would result in the needless creation of temporary strings. We can use Proto to make string concatenation very efficient. To make the problem more interesting, we can apply a locale-sensitive transformation to each character during the concatenation. The locale information will be passed as the data parameter.
-
-Consider the following expression template:
-
- proto::lit("hello") + " " + "world";
-
-We would like to concatenate this string into a statically allocated wide character buffer, widening each charater in turn using the specified locale. The first step is to write a grammar that describes this expression, with transforms that calculate the total string length. Here it is:
-
- // A grammar that matches string concatenation expressions, and
- // a transform that calculates the total string length.
- struct StringLength
- : proto::or_<
- proto::when<
- // When you find a character array ...
- proto::terminal<char[proto::N]>
- // ... the length is the size of the array minus 1.
- , mpl::prior<mpl::sizeof_<proto::_value> >()
- >
- , proto::when<
- // The length of a concatenated string is ...
- proto::plus<StringLength, StringLength>
- // ... the sum of the lengths of each sub-string.
- , proto::fold<
- _
- , mpl::size_t<0>()
- , mpl::plus<StringLength, proto::_state>()
- >
- >
- >
- {};
-
-Notice the use of _fold_pt_. It is a primitive transform that takes a sequence, a state, and function, just like `std::accumulate()`. The three template parameters are transforms. The first yields the sequence of expressions over which to fold, the second yields the initial state of the fold, and the third is the function to apply at each iteration. The use of `proto::_` as the first parameter might have you confused. In addition to being Proto's wildcard, `proto::_` is also a primitive transform that returns the current expression, which (if it is a non-terminal) is a sequence of its child expressions.
-
-Next, we need a function object that accepts a narrow string, a wide character buffer, and a `std::ctype<>` facet for doing the locale-specific stuff. It's fairly straightforward.
-
- // A function object that writes a narrow string
- // into a wide buffer.
- struct WidenCopy : proto::callable
- {
- typedef wchar_t *result_type;
-
- wchar_t *
- operator()(char const *str, wchar_t *buf, std::ctype<char> const &ct) const
- {
- for(; *str; ++str, ++buf)
- *buf = ct.widen(*str);
- return buf;
- }
- };
-
-Finally, we need some transforms that actually walk the concatenated string expression, widens the characters and writes them to a buffer. We will pass a `wchar_t*` as the state parameter and update it as we go. We'll also pass the `std::ctype<>` facet as the data parameter. It looks like this:
-
- // Write concatenated strings into a buffer, widening
- // them as we go.
- struct StringCopy
- : proto::or_<
- proto::when<
- proto::terminal<char[proto::N]>
- , WidenCopy(proto::_value, proto::_state, proto::_data)
- >
- , proto::when<
- proto::plus<StringCopy, StringCopy>
- , StringCopy(
- proto::_right
- , StringCopy(proto::_left, proto::_state, proto::_data)
- , proto::_data
- )
- >
- >
- {};
-
-Let's look more closely at the transform associated with non-terminals:
-
- StringCopy(
- proto::_right
- , StringCopy(proto::_left, proto::_state, proto::_data)
- , proto::_data
- )
-
-This bears a resemblance to the transform in the previous section that folded an expression tree into a list. First we recurse on the left child, writing its strings into the `wchar_t*` passed in as the state parameter. That returns the new value of the `wchar_t*`, which is passed as state while transforming the right child. Both invocations receive the same `std::ctype<>`, which is passed in as the data parameter.
-
-With these pieces in our pocket, we can implement our concatenate-and-widen function as follows:
-
- template<typename Expr>
- void widen( Expr const &expr )
- {
- // Make sure the expression conforms to our grammar
- BOOST_MPL_ASSERT(( proto::matches<Expr, StringLength> ));
-
- // Calculate the length of the string and allocate a buffer statically
- static std::size_t const length =
- boost::result_of<StringLength(Expr)>::type::value;
- wchar_t buffer[ length + 1 ] = {L'\0'};
-
- // Get the current ctype facet
- std::locale loc;
- std::ctype<char> const &ct(std::use_facet<std::ctype<char> >(loc));
-
- // Concatenate and widen the string expression
- StringCopy()(expr, &buffer[0], ct);
-
- // Write out the buffer.
- std::wcout << buffer << std::endl;
- }
-
- int main()
- {
- widen( proto::lit("hello") + " " + "world" );
- }
-
-The above code displays:
-
-[pre
-hello world
-]
-
-This is a rather round-about way of demonstrating that you can pass extra data to a transform as a third parameter. There are no restrictions on what this parameter can be, and (unlike the state parameter) Proto will never mess with it.
-
-[heading Implicit Parameters to Primitive Transforms]
-
-Let's use the above example to illustrate some other niceties of Proto transforms. We've seen that grammars, when used as function objects, can accept up to 3 parameters, and that when using these grammars in callable transforms, you can also specify up to 3 parameters. Let's take another look at the transform associated with non-terminals above:
-
- StringCopy(
- proto::_right
- , StringCopy(proto::_left, proto::_state, proto::_data)
- , proto::_data
- )
-
-Here we specify all three parameters to both invocations of the `StringCopy` grammar. But we don't have to specify all three. If we don't specify a third parameter, `proto::_data` is assumed. Likewise for the second parameter and `proto::_state`. So the above transform could have been writen more simply as:
-
- StringCopy(
- proto::_right
- , StringCopy(proto::_left)
- )
-
-The same is true for any primitive transform. The following are all equivalent:
-
-[table Implicit Parameters to Primitive Transforms
- [[Equivalent Transforms]]
- [[`proto::when<_, StringCopy>`]]
- [[`proto::when<_, StringCopy(_)>`]]
- [[`proto::when<_, StringCopy(_, proto::_state)>`]]
- [[`proto::when<_, StringCopy(_, proto::_state, proto::_data)>`]]
-]
-
-[note *Grammars Are Primitive Transforms Are Function Objects*
-
-So far, we've said that all Proto grammars are function objects. But it's more accurate to say that Proto grammars are primitive transforms -- a special kind of function object that takes between 1 and 3 arguments, and that Proto knows to treat specially when used in a callable transform, as in the table above.]
-
-[note *Not All Function Objects Are Primitive Transforms*
-
-You might be tempted now to drop the `_state` and `_data` parameters to `WidenCopy(proto::_value, proto::_state, proto::_data)`. That would be an error. `WidenCopy` is just a plain function object, not a primitive transform, so you must specify all its arguments. We'll see later how to write your own primitive transforms.]
-
-Once you know that primitive transforms will always receive all three parameters -- expression, state, and data -- it makes things possible that wouldn't be otherwise. For instance, consider that for binary expressions, these two transforms are equivalent. Can you see why?
-
-[table Two Equivalent Transforms
- [[Without [^proto::fold<>]][With [^proto::fold<>]]]
- [[``StringCopy(
- proto::_right
- , StringCopy(proto::_left)
-)``
-][``proto::fold<_, proto::_state, StringCopy>``]]
-]
-
-[endsect]
-
-[/===========================================]
-[section:built_in Proto's Built-In Transforms]
-[/===========================================]
-
-[def _N_ [~N]]
-[def _G_ [~G]]
-[def _G0_ [~G0]]
-[def _G1_ [~G1]]
-[def _CT_ [~CT]]
-[def _OT_ [~OT]]
-[def _ET_ [~ET]]
-[def _ST_ [~ST]]
-[def _FT_ [~FT]]
-
-Primitive transforms are the building blocks for more interesting composite transforms. Proto defines a bunch of generally useful primitive transforms. They are summarized below.
-
-[variablelist
- [[_value_pt_]
- [Given a terminal expression, return the value of the terminal.]]
- [[_child_c_pt_]
- [Given a non-terminal expression, `proto::_child_c<_N_>` returns the _N_-th
- child.]]
- [[_child_pt_]
- [A synonym for `proto::_child_c<0>`.]]
- [[_left_pt_]
- [A synonym for `proto::_child_c<0>`.]]
- [[_right_pt_]
- [A synonym for `proto::_child_c<1>`.]]
- [[_expr_pt_]
- [Returns the current expression unmodified.]]
- [[_state_pt_]
- [Returns the current state unmodified.]]
- [[_data_pt_]
- [Returns the current data unmodified.]]
- [[_call_pt_]
- [For a given callable transform `_CT_`, `proto::call<_CT_>` turns the
- callable transform into a primitive transform. This is useful for
- disambiguating callable transforms from object transforms, and also for
- working around compiler bugs with nested function types.]]
- [[_make_pt_]
- [For a given object transform `_OT_`, `proto::make<_OT_>` turns the
- object transform into a primitive transform. This is useful for
- disambiguating object transforms from callable transforms, and also for
- working around compiler bugs with nested function types.]]
- [[_default_pt_]
- [Given a grammar _G_, `proto::_default<G>` evaluates the current node
- according to the standard C++ meaning of the operation the node represents.
- For instance, if the current node is a binary plus node, the two children
- will both be evaluated according to `_G_` and the results will be added and
- returned. The return type is deduced with the help of the Boost.Typeof
- library.]]
- [[_fold_pt_]
- [Given three transforms `_ET_`, `_ST_`, and `_FT_`,
- `proto::fold<_ET_, _ST_, _FT_>` first evaluates `_ET_` to obtain a Fusion
- sequence and `_ST_` to obtain an initial state for the fold, and then
- evaluates `_FT_` for each element in the sequnce to generate the next
- state from the previous.]]
- [[_reverse_fold_pt_]
- [Like _fold_pt_, except the elements in the Fusion sequence are iterated in
- reverse order.]]
- [[_fold_tree_pt_]
- [Like `proto::fold<_ET_, _ST_, _FT_>`, except that the result of the `_ET_`
- transform is treated as an expression tree that is /flattened/ to generate
- the sequence to be folded. Flattening an expression tree causes child nodes
- with the same tag type as the parent to be put into sequence. For instance,
- `a >> b >> c` would be flattened to the sequence \[`a`, `b`, `c`\], and this
- is the sequence that would be folded.]]
- [[_reverse_fold_tree_pt_]
- [Like _fold_tree_pt_, except that the flattened sequence is iterated in
- reverse order.]]
- [[_lazy_pt_]
- [A combination of _make_pt_ and _call_pt_ that is useful when the nature of
- the transform depends on the expression, state and/or data parameters.
- `proto::lazy<R(A0,A1...An)>` first evaluates `proto::make<R()>` to compute a
- callable type `R2`. Then, it evaluates `proto::call<R2(A0,A1...An)>`.]]
-]
-
-[/============================================]
-[heading All Grammars Are Primitive Transforms]
-[/============================================]
-
-In addition to the above primitive transforms, all of Proto's grammar elements are also primitive transforms. Their behaviors are described below.
-
-[variablelist
- [[_wild_pt_]
- [Returns the current expression unmodified.]]
- [[_or_]
- [For the specified set of alternate sub-grammars, find the one that matches
- the given expression and apply its associated transform.]]
- [[_and_]
- [For the given set of sub-grammars, take the /last/ sub-grammar and apply its
- associated transform.]]
- [[_not_]
- [Returns the current expression unmodified.]]
- [[_if_]
- [Given three transforms, evaluate the first and treat the result as a
- compile-time Boolean value. If it is true, evaluate the second transform.
- Otherwise, evaluate the third.]]
- [[_terminal_]
- [Returns the current terminal expression unmodified.]]
- [[_plus_, _nary_expr_, et. al.]
- [A Proto grammar that matches a non-terminal such as
- `proto::plus<_G0_, _G1_>`, when used as a primitive transform, creates a new
- plus node where the left child is transformed according to `_G0_` and the
- right child with `_G1_`.]]
-]
-
-[/=================================]
-[heading The Pass-Through Transform]
-[/=================================]
-
-Note the primitive transform associated with grammar elements such as _plus_ described above. They possess a so-called /pass-through/ transform. The pass-through transform accepts an expression of a certain tag type (say, `proto::tag::plus`) and creates a new expression of the same tag type, where each child expression is transformed according to the corresponding child grammar of the pass-through transform. So for instance this grammar ...
-
- proto::function< X, proto::vararg<Y> >
-
-... matches function expressions where the first child matches the `X` grammar and the rest match the `Y` grammar. When used as a transform, the above grammar will create a new function expression where the first child is transformed according to `X` and the rest are transformed according to `Y`.
-
-The following class templates in Proto can be used as grammars with pass-through transforms:
-
-[table Class Templates With Pass-Through Transforms
- [[Templates with Pass-Through Transforms]]
- [[`proto::unary_plus<>`]]
- [[`proto::negate<>`]]
- [[`proto::dereference<>`]]
- [[`proto::complement<>`]]
- [[`proto::address_of<>`]]
- [[`proto::logical_not<>`]]
- [[`proto::pre_inc<>`]]
- [[`proto::pre_dec<>`]]
- [[`proto::post_inc<>`]]
- [[`proto::post_dec<>`]]
- [[`proto::shift_left<>`]]
- [[`proto::shift_right<>`]]
- [[`proto::multiplies<>`]]
- [[`proto::divides<>`]]
- [[`proto::modulus<>`]]
- [[`proto::plus<>`]]
- [[`proto::minus<>`]]
- [[`proto::less<>`]]
- [[`proto::greater<>`]]
- [[`proto::less_equal<>`]]
- [[`proto::greater_equal<>`]]
- [[`proto::equal_to<>`]]
- [[`proto::not_equal_to<>`]]
- [[`proto::logical_or<>`]]
- [[`proto::logical_and<>`]]
- [[`proto::bitwise_and<>`]]
- [[`proto::bitwise_or<>`]]
- [[`proto::bitwise_xor<>`]]
- [[`proto::comma<>`]]
- [[`proto::mem_ptr<>`]]
- [[`proto::assign<>`]]
- [[`proto::shift_left_assign<>`]]
- [[`proto::shift_right_assign<>`]]
- [[`proto::multiplies_assign<>`]]
- [[`proto::divides_assign<>`]]
- [[`proto::modulus_assign<>`]]
- [[`proto::plus_assign<>`]]
- [[`proto::minus_assign<>`]]
- [[`proto::bitwise_and_assign<>`]]
- [[`proto::bitwise_or_assign<>`]]
- [[`proto::bitwise_xor_assign<>`]]
- [[`proto::subscript<>`]]
- [[`proto::if_else_<>`]]
- [[`proto::function<>`]]
- [[`proto::unary_expr<>`]]
- [[`proto::binary_expr<>`]]
- [[`proto::nary_expr<>`]]
-]
-
-[/=====================================================]
-[heading The Many Roles of Proto Operator Metafunctions]
-[/=====================================================]
-
-We've seen templates such as _terminal_, _plus_ and _nary_expr_ fill many roles. They are metafunction that generate expression types. They are grammars that match expression types. And they are primitive transforms. The following code samples show examples of each.
-
-[*As Metafunctions ...]
-
- // proto::terminal<> and proto::plus<> are metafunctions
- // that generate expression types:
- typedef proto::terminal<int>::type int_;
- typedef proto::plus<int_, int_>::type plus_;
-
- int_ i = {42}, j = {24};
- plus_ p = {i, j};
-
-[*As Grammars ...]
-
- // proto::terminal<> and proto::plus<> are grammars that
- // match expression types
- struct Int : proto::terminal<int> {};
- struct Plus : proto::plus<Int, Int> {};
-
- BOOST_MPL_ASSERT(( proto::matches< int_, Int > ));
- BOOST_MPL_ASSERT(( proto::matches< plus_, Plus > ));
-
-[*As Primitive Transforms ...]
-
- // A transform that removes all unary_plus nodes in an expression
- struct RemoveUnaryPlus
- : proto::or_<
- proto::when<
- proto::unary_plus<RemoveUnaryPlus>
- , RemoveUnaryPlus(proto::_child)
- >
- // Use proto::terminal<> and proto::nary_expr<>
- // both as grammars and as primitive transforms.
- , proto::terminal<_>
- , proto::nary_expr<_, proto::vararg<RemoveUnaryPlus> >
- >
- {};
-
- int main()
- {
- proto::literal<int> i(0);
-
- proto::display_expr(
- +i - +(i - +i)
- );
-
- proto::display_expr(
- RemoveUnaryPlus()( +i - +(i - +i) )
- );
- }
-
-The above code displays the following, which shows that unary plus nodes have been stripped from the expression:
-
-[pre
-minus(
- unary_plus(
- terminal(0)
- )
- , unary_plus(
- minus(
- terminal(0)
- , unary_plus(
- terminal(0)
- )
- )
- )
-)
-minus(
- terminal(0)
- , minus(
- terminal(0)
- , terminal(0)
- )
-)
-]
-
-[endsect]
-
-[/======================================================]
-[section:primitives Building Custom Primitive Transforms]
-[/======================================================]
-
-In previous sections, we've seen how to compose larger transforms out of smaller transforms using function types. The smaller transforms from which larger transforms are composed are /primitive transforms/, and Proto provides a bunch of common ones such as `_child0` and `_value`. In this section we'll see how to author your own primitive transforms.
-
-[note There are a few reasons why you might want to write your own primitive transforms. For instance, your transform may be complicated, and composing it out of primitives becomes unwieldy. You might also need to work around compiler bugs on legacy compilers that makes composing transforms using function types problematic. Finally, you might also decide to define your own primitive transforms to improve compile times. Since Proto can simply invoke a primitive transform directly without having to process arguments or differentiate callable transforms from object transforms, primitive transforms are more efficient.]
-
-Primitive transforms inherit from `proto::transform<>` and have a nested `impl<>` template that inherits from `proto::transform_impl<>`. For example, this is how Proto defines the `_child_c<_N_>` transform, which returns the _N_-th child of the current expression:
-
- namespace boost { namespace proto
- {
- // A primitive transform that returns N-th child
- // of the current expression.
- template<int N>
- struct _child_c : transform<_child_c<N> >
- {
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
- typedef
- typename result_of::child_c<Expr, N>::type
- result_type;
-
- result_type operator ()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- ) const
- {
- return proto::child_c<N>(expr);
- }
- };
- };
-
- // Note that _child_c<N> is callable, so that
- // it can be used in callable transforms, as:
- // _child_c<0>(_child_c<1>)
- template<int N>
- struct is_callable<_child_c<N> >
- : mpl::true_
- {};
- }}
-
-The `proto::transform<>` base class provides the `operator()` overloads and the nested `result<>` template that make your transform a valid function object. These are implemented in terms of the nested `impl<>` template you define.
-
-The `proto::transform_impl<>` base class is a convenience. It provides some nested typedefs that are generally useful. The are specified in the table below:
-
-[table proto::transform_impl<Expr, State, Data> typedefs
-[[typedef][Equivalent To]]
-[[`expr`][`typename remove_reference<Expr>::type`]]
-[[`state`][`typename remove_reference<State>::type`]]
-[[`data`][`typename remove_reference<Data>::type`]]
-[[`expr_param`][`typename add_reference<typename add_const<Expr>::type>::type`]]
-[[`state_param`][`typename add_reference<typename add_const<State>::type>::type`]]
-[[`data_param`][`typename add_reference<typename add_const<Data>::type>::type`]]
-]
-
-You'll notice that `_child_c::impl::operator()` takes arguments of types `expr_param`, `state_param`, and `data_param`. The typedefs make it easy to accept arguments by reference or const reference accordingly.
-
-The only other interesting bit is the `is_callable<>` specialization, which will be described in the [link boost_proto.users_guide.expression_transformation.is_callable next section].
-
-[endsect]
-
-[/=================================================]
-[section:is_callable Making Your Transform Callable]
-[/=================================================]
-
-Transforms are typically of the form `proto::when< Something, R(A0,A1,...) >`. The question is whether `R` represents a function to call or an object to construct, and the answer determines how _when_ evaluates the transform. _when_ uses the `proto::is_callable<>` trait to disambiguate between the two. Proto does its best to guess whether a type is callable or not, but it doesn't always get it right. It's best to know the rules Proto uses, so that you know when you need to be more explicit.
-
-For most types `R`, `proto::is_callable<R>` checks for inheritence from `proto::callable`. However, if the type `R` is a template specialization, Proto assumes that it is /not/ callable ['even if the template inherits from `proto::callable`]. We'll see why in a minute. Consider the following erroneous callable object:
-
- // Proto can't tell this defines something callable!
- template<typename T>
- struct times2 : proto::callable
- {
- typedef T result_type;
-
- T operator()(T i) const
- {
- return i * 2;
- }
- };
-
- // ERROR! This is not going to multiply the int by 2:
- struct IntTimes2
- : proto::when<
- proto::terminal<int>
- , times2<int>(proto::_value)
- >
- {};
-
-The problem is that Proto doesn't know that `times2<int>` is callable, so rather that invoking the `times2<int>` function object, Proto will try to construct a `times2<int>` object and initialize it will an `int`. That will not compile.
-
-[note Why can't Proto tell that `times2<int>` is callable? After all, it inherits from `proto::callable`, and that is detectable, right? The problem is that merely asking whether some type `X<Y>` inherits from `callable` will cause the template `X<Y>` to be instantiated. That's a problem for a type like `std::vector<_value(_child1)>`. `std::vector<>` will not suffer to be instantiated with `_value(_child1)` as a template parameter. Since merely asking the question will sometimes result in a hard error, Proto can't ask; it has to assume that `X<Y>` represents an object to construct and not a function to call.]
-
-There are a couple of solutions to the `times2<int>` problem. One solution is to wrap the transform in `proto::call<>`. This forces Proto to treat `times2<int>` as callable:
-
- // OK, calls times2<int>
- struct IntTimes2
- : proto::when<
- proto::terminal<int>
- , proto::call<times2<int>(proto::_value)>
- >
- {};
-
-This can be a bit of a pain, because we need to wrap every use of `times2<int>`, which can be tedious and error prone, and makes our grammar cluttered and harder to read.
-
-Another solution is to specialize `proto::is_callable<>` on our `times2<>` template:
-
- namespace boost { namespace proto
- {
- // Tell Proto that times2<> is callable
- template<typename T>
- struct is_callable<times2<T> >
- : mpl::true_
- {};
- }}
-
- // OK, times2<> is callable
- struct IntTimes2
- : proto::when<
- proto::terminal<int>
- , times2<int>(proto::_value)
- >
- {};
-
-This is better, but still a pain because of the need to open Proto's namespace.
-
-You could simply make sure that the callable type is not a template specialization. Consider the following:
-
- // No longer a template specialization!
- struct times2int : times2<int> {};
-
- // OK, times2int is callable
- struct IntTimes2
- : proto::when<
- proto::terminal<int>
- , times2int(proto::_value)
- >
- {};
-
-This works because now Proto can tell that `times2int` inherits (indirectly) from `proto::callable`. Any non-template types can be safely checked for inheritance because, as they are not templates, there is no worry about instantiation errors.
-
-There is one last way to tell Proto that `times2<>` is callable. You could add an extra dummy template parameter that defaults to `proto::callable`:
-
- // Proto will recognize this as callable
- template<typename T, typename Callable = proto::callable>
- struct times2 : proto::callable
- {
- typedef T result_type;
-
- T operator()(T i) const
- {
- return i * 2;
- }
- };
-
- // OK, this works!
- struct IntTimes2
- : proto::when<
- proto::terminal<int>
- , times2<int>(proto::_value)
- >
- {};
-
-Note that in addition to the extra template parameter, `times2<>` still inherits from `proto::callable`. That's not necessary in this example but it's good style because any types derived from `times2<>` (as `times2int` defined above) will still be considered callable.
-
-[endsect]
-
-[endsect]
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / 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)
+ /]
+
+[import ../test/examples.cpp]
+
+[/============================================================================]
+[section:expression_transformation Expression Transformation: Semantic Actions]
+[/============================================================================]
+
+If you have ever built a parser with the help of a tool like Antlr, yacc or Boost.Spirit, you might be familiar with /semantic actions/. In addition to allowing you to define the grammar of the language recognized by the parser, these tools let you embed code within your grammar that executes when parts of the grammar participate in a parse. Proto has the equivalent of semantic actions. They are called /transforms/. This section describes how to embed transforms within your Proto grammars, turning your grammars into function objects that can manipulate or evaluate expressions in powerful ways.
+
+Proto transforms are an advanced topic. We'll take it slow, using examples to illustrate the key concepts, starting simple.
+
+[/==================================]
+[section ["Activating] Your Grammars]
+[/==================================]
+
+The Proto grammars we've seen so far are static. You can check at compile-time to see if an expression type matches a grammar, but that's it. Things get more interesting when you give them runtime behaviors. A grammar with embedded transforms is more than just a static grammar. It is a function object that accepts expressions that match the grammar and does /something/ with them.
+
+Below is a very simple grammar. It matches terminal expressions.
+
+ // A simple Proto grammar that matches all terminals
+ proto::terminal< _ >
+
+Here is the same grammar with a transform that extracts the value from the terminal:
+
+ // A simple Proto grammar that matches all terminals
+ // *and* a function object that extracts the value from
+ // the terminal
+ proto::when<
+ proto::terminal< _ >
+ , proto::_value // <-- Look, a transform!
+ >
+
+You can read this as follows: when you match a terminal expression, extract the value. The type `proto::_value` is a so-called transform. Later we'll see what makes it a transform, but for now just think of it as a kind of function object. Note the use of _when_: the first template parameter is the grammar to match and the second is the transform to execute. The result is both a grammar that matches terminal expressions and a function object that accepts terminal expressions and extracts their values.
+
+As with ordinary grammars, we can define an empty struct that inherits from a grammar+transform to give us an easy way to refer back to the thing we're defining, as follows:
+
+ // A grammar and a function object, as before
+ struct Value
+ : proto::when<
+ proto::terminal< _ >
+ , proto::_value
+ >
+ {};
+
+ // "Value" is a grammar that matches terminal expressions
+ BOOST_MPL_ASSERT(( proto::matches< proto::terminal<int>::type, Value > ));
+
+ // "Value" also defines a function object that accepts terminals
+ // and extracts their value.
+ proto::terminal<int>::type answer = {42};
+ Value get_value;
+ int i = get_value( answer );
+
+As already mentioned, `Value` is a grammar that matches terminal expressions and a function object that operates on terminal expressions. It would be an error to pass a non-terminal expression to the `Value` function object. This is a general property of grammars with transforms; when using them as function objects, expressions passed to them must match the grammar.
+
+Proto grammars are valid TR1-style function objects. That means you can use `boost::result_of<>` to ask a grammar what its return type will be, given a particular expression type. For instance, we can access the `Value` grammar's return type as follows:
+
+ // We can use boost::result_of<> to get the return type
+ // of a Proto grammar.
+ typedef
+ typename boost::result_of<Value(proto::terminal<int>::type)>::type
+ result_type;
+
+ // Check that we got the type we expected
+ BOOST_MPL_ASSERT(( boost::is_same<result_type, int> ));
+
+[note A grammar with embedded transforms is both a grammar and a function object. Calling these things "grammars with transforms" would get tedious. We could call them something like "active grammars", but as we'll see /every/ grammar that you can define with Proto is "active"; that is, every grammar has some behavior when used as a function object. So we'll continue calling these things plain "grammars". The term "transform" is reserved for the thing that is used as the second parameter to the _when_ template.]
+
+[endsect]
+
+[/=========================================]
+[section Handling Alternation and Recursion]
+[/=========================================]
+
+Most grammars are a little more complicated than the one in the preceeding section. For the sake of illustration, let's define a rather nonsensical grammar that matches any expression and recurses to the leftmost terminal and returns its value. It will demonstrate how two key concepts of Proto grammars -- alternation and recursion -- interact with transforms. The grammar is described below.
+
+ // A grammar that matches any expression, and a function object
+ // that returns the value of the leftmost terminal.
+ struct LeftmostLeaf
+ : proto::or_<
+ // If the expression is a terminal, return its value
+ proto::when<
+ proto::terminal< _ >
+ , proto::_value
+ >
+ // Otherwise, it is a non-terminal. Return the result
+ // of invoking LeftmostLeaf on the 0th (leftmost) child.
+ , proto::when<
+ _
+ , LeftmostLeaf( proto::_child0 )
+ >
+ >
+ {};
+
+ // A Proto terminal wrapping std::cout
+ proto::terminal< std::ostream & >::type cout_ = { std::cout };
+
+ // Create an expression and use LeftmostLeaf to extract the
+ // value of the leftmost terminal, which will be std::cout.
+ std::ostream & sout = LeftmostLeaf()( cout_ << "the answer: " << 42 << '\n' );
+
+We've seen `proto::or_<>` before. Here it is serving two roles. First, it is a grammar that matches any of its alternate sub-grammars; in this case, either a terminal or a non-terminal. Second, it is also a function object that accepts an expression, finds the alternate sub-grammar that matches the expression, and applies its transform. And since `LeftmostLeaf` inherits from `proto::or_<>`, `LeftmostLeaf` is also both a grammar and a function object.
+
+[def _some_transform_ [~some-transform]]
+
+[note The second alternate uses `proto::_` as its grammar. Recall that `proto::_` is the wildcard grammar that matches any expression. Since alternates in `proto::or_<>` are tried in order, and since the first alternate handles all terminals, the second alternate handles all (and only) non-terminals. Often enough, `proto::when< _, _some_transform_ >` is the last alternate in a grammar, so for improved readability, you could use the equivalent `proto::otherwise< _some_transform_ >`.]
+
+The next section describes this grammar further.
+
+[endsect]
+
+[/==========================]
+[section Callable Transforms]
+[/==========================]
+
+[def __bold_transform__ [*LeftmostLeaf( proto::_child0 )]]
+
+In the grammar defined in the preceeding section, the transform associated with non-terminals is a little strange-looking:
+
+ proto::when<
+ _
+ , __bold_transform__ // <-- a "callable" transform
+ >
+
+It has the effect of accepting non-terminal expressions, taking the 0th (leftmost) child and recursively invoking the `LeftmostLeaf` function on it. But `LeftmostLeaf( proto::_child0 )` is actually a /function type/. Literally, it is the type of a function that accepts an object of type `proto::_child0` and returns an object of type `LeftmostLeaf`. So how do we make sense of this transform? Clearly, there is no function that actually has this signature, nor would such a function be useful. The key is in understanding how `proto::when<>` /interprets/ its second template parameter.
+
+When the second template parameter to _when_ is a function type, _when_ interprets the function type as a transform. In this case, `LeftmostLeaf` is treated as the type of a function object to invoke, and `proto::_child0` is treated as a transform. First, `proto::_child0` is applied to the current expression (the non-terminal that matched this alternate sub-grammar), and the result (the 0th child) is passed as an argument to `LeftmostLeaf`.
+
+[note *Transforms are a Domain-Specific Language*
+
+`LeftmostLeaf( proto::_child0 )` /looks/ like an invocation of the `LeftmostLeaf` function object, but it's not, but then it actually is! Why this confusing subterfuge? Function types give us a natural and concise syntax for composing more complicated transforms from simpler ones. The fact that the syntax is suggestive of a function invocation is on purpose. It is a domain-specific embedded language for defining expression transformations. If the subterfuge worked, it may have fooled you into thinking the transform is doing exactly what it actually does! And that's the point.]
+
+The type `LeftmostLeaf( proto::_child0 )` is an example of a /callable transform/. It is a function type that represents a function object to call and its arguments. The types `proto::_child0` and `proto::_value` are /primitive transforms/. They are plain structs, not unlike function objects, from which callable transforms can be composed. There is one other type of transform, /object transforms/, that we'll encounter next.
+
+[endsect]
+
+[/========================]
+[section Object Transforms]
+[/========================]
+
+The very first transform we looked at simply extracted the value of terminals. Let's do the same thing, but this time we'll promote all ints to longs first. (Please forgive the contrived-ness of the examples so far; they get more interesting later.) Here's the grammar:
+
+ // A simple Proto grammar that matches all terminals,
+ // and a function object that extracts the value from
+ // the terminal, promoting ints to longs:
+ struct ValueWithPomote
+ : proto::or_<
+ proto::when<
+ proto::terminal< int >
+ , long(proto::_value) // <-- an "object" transform
+ >
+ , proto::when<
+ proto::terminal< _ >
+ , proto::_value
+ >
+ >
+ {};
+
+You can read the above grammar as follows: when you match an int terminal, extract the value from the terminal and use it to initialize a long; otherwise, when you match another kind of terminal, just extract the value. The type `long(proto::_value)` is a so-called /object/ transform. It looks like the creation of a temporary long, but it's really a function type. Just as a callable transform is a function type that represents a function to call and its arguments, an object transforms is a function type that represents an object to construct and the arguments to its constructor.
+
+[/================================================]
+[note *Object Transforms vs. Callable Transforms*
+
+When using function types as Proto transforms, they can either represent an object to construct or a function to call. It is similar to "normal" C++ where the syntax `foo("arg")` can either be interpreted as an object to construct or a function to call, depending on whether `foo` is a type or a function. But consider two of the transforms we've seen so far:
+
+``
+ LeftmostLeaf(proto::_child0) // <-- a callable transform
+ long(proto::_value) // <-- an object transform
+``
+
+Proto can't know in general which is which, so it uses a trait, `proto::is_callable<>`, to differentiate. `is_callable< long >::value` is false so `long(proto::_value)` is an object to construct, but `is_callable< LeftmostLeaf >::value` is true so `LeftmostLeaf(proto::_child0)` is a function to call. Later on, we'll see how Proto recognizes a type as "callable".]
+[/================================================]
+
+[endsect]
+
+[/================================]
+[section Example: Calculator Arity]
+[/================================]
+
+Now that we have the basics of Proto transforms down, let's consider a slightly more realistic example. We can use transforms to improve the type-safety of the [link boost_proto.users_guide.getting_started.hello_calculator calculator DSEL]. If you recall, it lets you write infix arithmetic expressions involving argument placeholders like `_1` and `_2` and pass them to STL algorithms as function objects, as follows:
+
+ double a1[4] = { 56, 84, 37, 69 };
+ double a2[4] = { 65, 120, 60, 70 };
+ double a3[4] = { 0 };
+
+ // Use std::transform() and a calculator expression
+ // to calculate percentages given two input sequences:
+ std::transform(a1, a1+4, a2, a3, (_2 - _1) / _2 * 100);
+
+This works because we gave calculator expressions an `operator()` that evaluates the expression, replacing the placeholders with the arguments to `operator()`. The overloaded `calculator<>::operator()` looked like this:
+
+ // Overload operator() to invoke proto::eval() with
+ // our calculator_context.
+ template<typename Expr>
+ double
+ calculator<Expr>::operator()(double a1 = 0, double a2 = 0, double a3 = 0) const
+ {
+ calculator_context ctx;
+ ctx.args.push_back(a1);
+ ctx.args.push_back(a2);
+ ctx.args.push_back(a3);
+
+ return proto::eval(*this, ctx);
+ }
+
+Although this works, it's not ideal because it doesn't warn users if they supply too many or too few arguments to a calculator expression. Consider the following mistakes:
+
+ (_1 * _1)(4, 2); // Oops, too many arguments!
+ (_2 * _2)(42); // Oops, too few arguments!
+
+The expression `_1 * _1` defines a unary calculator expression; it takes one argument and squares it. If we pass more than one argument, the extra arguments will be silently ignored, which might be surprising to users. The next expression, `_2 * _2` defines a binary calculator expression; it takes two arguments, ignores the first and squares the second. If we only pass one argument, the code silently fills in `0.0` for the second argument, which is also probably not what users expect. What can be done?
+
+We can say that the /arity/ of a calculator expression is the number of arguments it expects, and it is equal to the largest placeholder in the expression. So, the arity of `_1 * _1` is one, and the arity of `_2 * _2` is two. We can increase the type-safety of our calculator DSEL by making sure the artiy of an expression equals the actual number of arguments supplied. Computing the artiy of an expression is simple with the help of Proto transforms.
+
+It's straightforward to describe in words how the arity of an expression should
+be calculated. Consider that calculator expressions can be made of `_1`, `_2`, literals, unary expressions and binary expressions. The following table shows the arities for each of these 5 constituents.
+
+[table Calculator Sub-Expression Arities
+ [[Sub-Expression] [Arity]]
+ [[Placeholder 1] [`1`]]
+ [[Placeholder 2] [`2`]]
+ [[Literal] [`0`]]
+ [[Unary Expression] [ /arity of the operand/ ]]
+ [[Binary Expression] [ /max arity of the two operands/ ]]
+]
+
+Using this information, we can write the grammar for calculator expressions and attach transforms for computing the arity of each constituent. The code below computes the expression arity as a compile-time integer, using integral wrappers and metafunctions from the Boost MPL Library. The grammar is described below.
+
+[CalcArity]
+
+When we find a placeholder terminal or a literal, we use an /object transform/ such as `mpl::int_<1>()` to create a (default-constructed) compile-time integer representing the arity of that terminal.
+
+For unary expressions, we use `CalcArity(proto::_child)` which is a /callable transform/ that computes the arity of the expression's child.
+
+The transform for binary expressions has a few new tricks. Let's look more closely:
+
+ // Compute the left and right arities and
+ // take the larger of the two.
+ mpl::max<CalcArity(proto::_left),
+ CalcArity(proto::_right)>()
+
+This is an object transform; it default-constructs ... what exactly? The `mpl::max<>` template is an MPL metafunction that accepts two compile-time integers. It has a nested `::type` typedef (not shown) that is the maximum of the two. But here, we appear to be passing it two things that are /not/ compile-time integers; they're Proto callable transforms. Proto is smart enough to recognize that fact. It first evaluates the two nested callable transforms, computing the arities of the left and right child expressions. Then it puts the resulting integers into `mpl::max<>` and evaluates the metafunction by asking for the nested `::type`. That is the type of the object that gets default-constructed and returned.
+
+More generally, when evaluating object transforms, Proto looks at the object type and checks whether it is a template specialization, like `mpl::max<>`. If it is, Proto looks for nested transforms that it can evaluate. After any nested transforms have been evaluated and substituted back into the template, the new template specialization is the result type, unless that type has a nested `::type`, in which case that becomes the result.
+
+Now that we can calculate the arity of a calculator expression, let's redefine the `calculator<>` expression wrapper we wrote in the Getting Started guide to use the `CalcArity` grammar and some macros from Boost.MPL to issue compile-time errors when users specify too many or too few arguments.
+
+ // The calculator expression wrapper, as defined in the Hello
+ // Calculator example in the Getting Started guide. It behaves
+ // just like the expression it wraps, but with extra operator()
+ // member functions that evaluate the expression.
+ // NEW: Use the CalcArity grammar to ensure that the correct
+ // number of arguments are supplied.
+ template<typename Expr>
+ struct calculator
+ : proto::extends<Expr, calculator<Expr>, calculator_domain>
+ {
+ typedef
+ proto::extends<Expr, calculator<Expr>, calculator_domain>
+ base_type;
+
+ calculator(Expr const &expr = Expr())
+ : base_type(expr)
+ {}
+
+ typedef double result_type;
+
+ // Use CalcArity to compute the arity of Expr:
+ static int const arity = boost::result_of<CalcArity(Expr)>::type::value;
+
+ double operator()() const
+ {
+ BOOST_MPL_ASSERT_RELATION(0, ==, arity);
+ calculator_context ctx;
+ return proto::eval(*this, ctx);
+ }
+
+ double operator()(double a1) const
+ {
+ BOOST_MPL_ASSERT_RELATION(1, ==, arity);
+ calculator_context ctx;
+ ctx.args.push_back(a1);
+ return proto::eval(*this, ctx);
+ }
+
+ // ... and additional operator() overloads to handle more arguments ...
+ };
+
+Note the use of `boost::result_of<>` to access the return type of the `CalcArity` function object. Since we used compile-time integers in our transforms, the arity of the expression is encoded in the return type of the `CalcArity` function object. Proto grammars are valid TR1-style function objects, so you can use `boost::result_of<>` to figure out their return types.
+
+With our compile-time assertions in place, when users provide too many or too few arguments to a calculator expression, as in:
+
+ (_2 * _2)(42); // Oops, too few arguments!
+
+... they will get a compile-time error message on the line with the assertion that reads something like this[footnote This error message was generated with Microsoft Visual C++ 9.0. Different compilers will emit different messages with varying degrees of readability.]:
+
+[pre
+c:\boost\org\trunk\libs\proto\scratch\main.cpp(97) : error C2664: 'boost::mpl::asse
+rtion\_failed' : cannot convert parameter 1 from 'boost::mpl::failed \*\*\*\*\*\*\*\*\*\*\*\*boo
+st::mpl::assert\_relation<x,y,\_\_formal>::\*\*\*\*\*\*\*\*\*\*\*\*' to 'boost::mpl::assert<false>
+::type'
+ with
+ \[
+ x\=1,
+ y\=2,
+ \_\_formal\=bool boost::mpl::operator\=\=(boost::mpl::failed,boost::mpl::failed)
+ \]
+]
+
+The point of this exercise was to show that we can write a fairly simple Proto grammar with embedded transforms that is declarative and readable and can compute interesting properties of arbitrarily complicated expressions. But transforms can do more than that. Boost.Xpressive uses transforms to turn expressions into finite state automata for matching regular expressions, and Boost.Spirit uses transforms to build recursive descent parser generators. Proto comes with a collection of built-in transforms that you can use to perform very sophisticated expression manipulations like these. In the next few sections we'll see some of them in action.
+
+[endsect]
+
+[/===============================================]
+[section:state Transforms With State Accumulation]
+[/===============================================]
+
+So far, we've only seen examples of grammars with transforms that accept one argument: the expression to transform. But consider for a moment how, in ordinary procedural code, you would turn a binary tree into a linked list. You would start with an empty list. Then, you would recursively convert the right branch to a list, and use the result as the initial state while converting the left branch to a list. That is, you would need a function that takes two parameters: the current node and the list so far. These sorts of /accumulation/ problems are quite common when processing trees. The linked list is an example of an accumulation variable or /state/. Each iteration of the algorithm takes the current element and state, applies some binary function to the two and creates a new state. In the STL, this algorithm is called `std::accumulate()`. In many other languages, it is called /fold/. Let's see how to implement a fold algorithm with Proto transforms.
+
+All Proto grammars can optionally accept a state parameter in addition to the expression to transform. If you want to fold a tree to a list, you'll need to make use of the state parameter to pass around the list you've built so far. As for the list, the Boost.Fusion library provides a `fusion::cons<>` type from which you can build heterogenous lists. The type `fusion::nil` represents an empty list.
+
+Below is a grammar that recognizes output expressions like `cout_ << 42 << '\n'` and puts the arguments into a Fusion list. It is explained below.
+
+ // Fold the terminals in output statements like
+ // "cout_ << 42 << '\n'" into a Fusion cons-list.
+ struct FoldToList
+ : proto::or_<
+ // Don't add the ostream terminal to the list
+ proto::when<
+ proto::terminal< std::ostream & >
+ , proto::_state
+ >
+ // Put all other terminals at the head of the
+ // list that we're building in the "state" parameter
+ , proto::when<
+ proto::terminal<_>
+ , fusion::cons<proto::_value, proto::_state>(
+ proto::_value, proto::_state
+ )
+ >
+ // For left-shift operations, first fold the right
+ // child to a list using the current state. Use
+ // the result as the state parameter when folding
+ // the left child to a list.
+ , proto::when<
+ proto::shift_left<FoldToList, FoldToList>
+ , FoldToList(
+ proto::_left
+ , FoldToList(proto::_right, proto::_state)
+ )
+ >
+ >
+ {};
+
+Before reading on, see if you can apply what you know already about object, callable and primitive transforms to figure out how this grammar works.
+
+When you use the `FoldToList` function, you'll need to pass two arguments: the expression to fold, and the initial state: an empty list. Those two arguments get passed around to each transform. We learned previously that `proto::_value` is a primitive transform that accepts a terminal expression and extracts its value. What we didn't know until now was that it also accepts the current state /and ignores it/. `proto::_state` is also a primitive transform. It accepts the current expression, which it ignores, and the current state, which it returns.
+
+When we find a terminal, we stick it at the head of the cons list, using the current state as the tail of the list. (The first alternate causes the `ostream` to be skipped. We don't want `cout` in the list.) When we find a shift-left node, we apply the following transform:
+
+ // Fold the right child and use the result as
+ // state while folding the right.
+ FoldToList(
+ proto::_left
+ , FoldToList(proto::_right, proto::_state)
+ )
+
+You can read this transform as follows: using the current state, fold the right child to a list. Use the new list as the state while folding the left child to a list.
+
+[tip If your compiler is Microsoft Visual C++, you'll find that the above transform does not compile. The compiler has bugs with its handling of nested function types. You can work around the bug by wrapping the inner transform in `proto::call<>` as follows:
+
+``
+ FoldToList(
+ proto::_left
+ , proto::call<FoldToList(proto::_right, proto::_state)>
+ )
+``
+
+`proto::call<>` turns a callable transform into a primitive transform, but more on that later.
+]
+
+Now that we have defined the `FoldToList` function object, we can use it to turn output expressions into lists as follows:
+
+ proto::terminal<std::ostream &>::type const cout_ = {std::cout};
+
+ // This is the type of the list we build below
+ typedef
+ fusion::cons<
+ int
+ , fusion::cons<
+ double
+ , fusion::cons<
+ char
+ , fusion::nil
+ >
+ >
+ >
+ result_type;
+
+ // Fold an output expression into a Fusion list, using
+ // fusion::nil as the initial state of the transformation.
+ FoldToList to_list;
+ result_type args = to_list(cout_ << 1 << 3.14 << '\n', fusion::nil());
+
+ // Now "args" is the list: {1, 3.14, '\n'}
+
+When writing transforms, "fold" is such a basic operation that Proto provides a number of built-in fold transforms. We'll get to them later. For now, rest assured that you won't always have to strech your brain so far to do such basic things.
+
+[endsect]
+
+[/================================================]
+[section:data Passing Auxiliary Data To Transforms]
+[/================================================]
+
+In the last section, we saw that we can pass a second parameter to grammars with transforms: an accumulation variable or /state/ that gets updated as your transform executes. There are times when your transforms will need to access auxiliary data that does /not/ accumulate, so bundling it with the state parameter is impractical. Instead, you can pass auxiliary data as a third parameter, known as the /data/ parameter. Below we show an example involving string processing where the data parameter is essential.
+
+[note All Proto grammars are function objects that take one, two or three arguments: the expression, the state, and the data. There are no additional arguments to know about, we promise. In Haskell, there is set of a tree traversal technologies known collectively as _SYB_. In that framework, there are also three parameters: the term, the accumulator, and the context. These are Proto's expression, state and data parameters under different names.]
+
+Expression templates are often used as an optimization to eliminate temporary objects. Condsier the problem of string concatenation: a series of concatenations would result in the needless creation of temporary strings. We can use Proto to make string concatenation very efficient. To make the problem more interesting, we can apply a locale-sensitive transformation to each character during the concatenation. The locale information will be passed as the data parameter.
+
+Consider the following expression template:
+
+ proto::lit("hello") + " " + "world";
+
+We would like to concatenate this string into a statically allocated wide character buffer, widening each charater in turn using the specified locale. The first step is to write a grammar that describes this expression, with transforms that calculate the total string length. Here it is:
+
+ // A grammar that matches string concatenation expressions, and
+ // a transform that calculates the total string length.
+ struct StringLength
+ : proto::or_<
+ proto::when<
+ // When you find a character array ...
+ proto::terminal<char[proto::N]>
+ // ... the length is the size of the array minus 1.
+ , mpl::prior<mpl::sizeof_<proto::_value> >()
+ >
+ , proto::when<
+ // The length of a concatenated string is ...
+ proto::plus<StringLength, StringLength>
+ // ... the sum of the lengths of each sub-string.
+ , proto::fold<
+ _
+ , mpl::size_t<0>()
+ , mpl::plus<StringLength, proto::_state>()
+ >
+ >
+ >
+ {};
+
+Notice the use of _fold_pt_. It is a primitive transform that takes a sequence, a state, and function, just like `std::accumulate()`. The three template parameters are transforms. The first yields the sequence of expressions over which to fold, the second yields the initial state of the fold, and the third is the function to apply at each iteration. The use of `proto::_` as the first parameter might have you confused. In addition to being Proto's wildcard, `proto::_` is also a primitive transform that returns the current expression, which (if it is a non-terminal) is a sequence of its child expressions.
+
+Next, we need a function object that accepts a narrow string, a wide character buffer, and a `std::ctype<>` facet for doing the locale-specific stuff. It's fairly straightforward.
+
+ // A function object that writes a narrow string
+ // into a wide buffer.
+ struct WidenCopy : proto::callable
+ {
+ typedef wchar_t *result_type;
+
+ wchar_t *
+ operator()(char const *str, wchar_t *buf, std::ctype<char> const &ct) const
+ {
+ for(; *str; ++str, ++buf)
+ *buf = ct.widen(*str);
+ return buf;
+ }
+ };
+
+Finally, we need some transforms that actually walk the concatenated string expression, widens the characters and writes them to a buffer. We will pass a `wchar_t*` as the state parameter and update it as we go. We'll also pass the `std::ctype<>` facet as the data parameter. It looks like this:
+
+ // Write concatenated strings into a buffer, widening
+ // them as we go.
+ struct StringCopy
+ : proto::or_<
+ proto::when<
+ proto::terminal<char[proto::N]>
+ , WidenCopy(proto::_value, proto::_state, proto::_data)
+ >
+ , proto::when<
+ proto::plus<StringCopy, StringCopy>
+ , StringCopy(
+ proto::_right
+ , StringCopy(proto::_left, proto::_state, proto::_data)
+ , proto::_data
+ )
+ >
+ >
+ {};
+
+Let's look more closely at the transform associated with non-terminals:
+
+ StringCopy(
+ proto::_right
+ , StringCopy(proto::_left, proto::_state, proto::_data)
+ , proto::_data
+ )
+
+This bears a resemblance to the transform in the previous section that folded an expression tree into a list. First we recurse on the left child, writing its strings into the `wchar_t*` passed in as the state parameter. That returns the new value of the `wchar_t*`, which is passed as state while transforming the right child. Both invocations receive the same `std::ctype<>`, which is passed in as the data parameter.
+
+With these pieces in our pocket, we can implement our concatenate-and-widen function as follows:
+
+ template<typename Expr>
+ void widen( Expr const &expr )
+ {
+ // Make sure the expression conforms to our grammar
+ BOOST_MPL_ASSERT(( proto::matches<Expr, StringLength> ));
+
+ // Calculate the length of the string and allocate a buffer statically
+ static std::size_t const length =
+ boost::result_of<StringLength(Expr)>::type::value;
+ wchar_t buffer[ length + 1 ] = {L'\0'};
+
+ // Get the current ctype facet
+ std::locale loc;
+ std::ctype<char> const &ct(std::use_facet<std::ctype<char> >(loc));
+
+ // Concatenate and widen the string expression
+ StringCopy()(expr, &buffer[0], ct);
+
+ // Write out the buffer.
+ std::wcout << buffer << std::endl;
+ }
+
+ int main()
+ {
+ widen( proto::lit("hello") + " " + "world" );
+ }
+
+The above code displays:
+
+[pre
+hello world
+]
+
+This is a rather round-about way of demonstrating that you can pass extra data to a transform as a third parameter. There are no restrictions on what this parameter can be, and (unlike the state parameter) Proto will never mess with it.
+
+[heading Implicit Parameters to Primitive Transforms]
+
+Let's use the above example to illustrate some other niceties of Proto transforms. We've seen that grammars, when used as function objects, can accept up to 3 parameters, and that when using these grammars in callable transforms, you can also specify up to 3 parameters. Let's take another look at the transform associated with non-terminals above:
+
+ StringCopy(
+ proto::_right
+ , StringCopy(proto::_left, proto::_state, proto::_data)
+ , proto::_data
+ )
+
+Here we specify all three parameters to both invocations of the `StringCopy` grammar. But we don't have to specify all three. If we don't specify a third parameter, `proto::_data` is assumed. Likewise for the second parameter and `proto::_state`. So the above transform could have been writen more simply as:
+
+ StringCopy(
+ proto::_right
+ , StringCopy(proto::_left)
+ )
+
+The same is true for any primitive transform. The following are all equivalent:
+
+[table Implicit Parameters to Primitive Transforms
+ [[Equivalent Transforms]]
+ [[`proto::when<_, StringCopy>`]]
+ [[`proto::when<_, StringCopy(_)>`]]
+ [[`proto::when<_, StringCopy(_, proto::_state)>`]]
+ [[`proto::when<_, StringCopy(_, proto::_state, proto::_data)>`]]
+]
+
+[note *Grammars Are Primitive Transforms Are Function Objects*
+
+So far, we've said that all Proto grammars are function objects. But it's more accurate to say that Proto grammars are primitive transforms -- a special kind of function object that takes between 1 and 3 arguments, and that Proto knows to treat specially when used in a callable transform, as in the table above.]
+
+[note *Not All Function Objects Are Primitive Transforms*
+
+You might be tempted now to drop the `_state` and `_data` parameters to `WidenCopy(proto::_value, proto::_state, proto::_data)`. That would be an error. `WidenCopy` is just a plain function object, not a primitive transform, so you must specify all its arguments. We'll see later how to write your own primitive transforms.]
+
+Once you know that primitive transforms will always receive all three parameters -- expression, state, and data -- it makes things possible that wouldn't be otherwise. For instance, consider that for binary expressions, these two transforms are equivalent. Can you see why?
+
+[table Two Equivalent Transforms
+ [[Without [^proto::fold<>]][With [^proto::fold<>]]]
+ [[``StringCopy(
+ proto::_right
+ , StringCopy(proto::_left, proto::_state, proto::_data)
+ , proto::_data
+)``
+][``proto::fold<_, proto::_state, StringCopy>``]]
+]
+
+[endsect]
+
+[/===========================================]
+[section:built_in Proto's Built-In Transforms]
+[/===========================================]
+
+[def _N_ [~N]]
+[def _G_ [~G]]
+[def _G0_ [~G0]]
+[def _G1_ [~G1]]
+[def _CT_ [~CT]]
+[def _OT_ [~OT]]
+[def _ET_ [~ET]]
+[def _ST_ [~ST]]
+[def _FT_ [~FT]]
+
+Primitive transforms are the building blocks for more interesting composite transforms. Proto defines a bunch of generally useful primitive transforms. They are summarized below.
+
+[variablelist
+ [[_value_pt_]
+ [Given a terminal expression, return the value of the terminal.]]
+ [[_child_c_pt_]
+ [Given a non-terminal expression, `proto::_child_c<_N_>` returns the _N_-th
+ child.]]
+ [[_child_pt_]
+ [A synonym for `proto::_child_c<0>`.]]
+ [[_left_pt_]
+ [A synonym for `proto::_child_c<0>`.]]
+ [[_right_pt_]
+ [A synonym for `proto::_child_c<1>`.]]
+ [[_expr_pt_]
+ [Returns the current expression unmodified.]]
+ [[_state_pt_]
+ [Returns the current state unmodified.]]
+ [[_data_pt_]
+ [Returns the current data unmodified.]]
+ [[_call_pt_]
+ [For a given callable transform `_CT_`, `proto::call<_CT_>` turns the
+ callable transform into a primitive transform. This is useful for
+ disambiguating callable transforms from object transforms, and also for
+ working around compiler bugs with nested function types.]]
+ [[_make_pt_]
+ [For a given object transform `_OT_`, `proto::make<_OT_>` turns the
+ object transform into a primitive transform. This is useful for
+ disambiguating object transforms from callable transforms, and also for
+ working around compiler bugs with nested function types.]]
+ [[_default_pt_]
+ [Given a grammar _G_, `proto::_default<_G_>` evaluates the current node
+ according to the standard C++ meaning of the operation the node represents.
+ For instance, if the current node is a binary plus node, the two children
+ will both be evaluated according to `_G_` and the results will be added and
+ returned. The return type is deduced with the help of the Boost.Typeof
+ library.]]
+ [[_fold_pt_]
+ [Given three transforms `_ET_`, `_ST_`, and `_FT_`,
+ `proto::fold<_ET_, _ST_, _FT_>` first evaluates `_ET_` to obtain a Fusion
+ sequence and `_ST_` to obtain an initial state for the fold, and then
+ evaluates `_FT_` for each element in the sequnce to generate the next
+ state from the previous.]]
+ [[_reverse_fold_pt_]
+ [Like _fold_pt_, except the elements in the Fusion sequence are iterated in
+ reverse order.]]
+ [[_fold_tree_pt_]
+ [Like `proto::fold<_ET_, _ST_, _FT_>`, except that the result of the `_ET_`
+ transform is treated as an expression tree that is /flattened/ to generate
+ the sequence to be folded. Flattening an expression tree causes child nodes
+ with the same tag type as the parent to be put into sequence. For instance,
+ `a >> b >> c` would be flattened to the sequence \[`a`, `b`, `c`\], and this
+ is the sequence that would be folded.]]
+ [[_reverse_fold_tree_pt_]
+ [Like _fold_tree_pt_, except that the flattened sequence is iterated in
+ reverse order.]]
+ [[_lazy_pt_]
+ [A combination of _make_pt_ and _call_pt_ that is useful when the nature of
+ the transform depends on the expression, state and/or data parameters.
+ `proto::lazy<R(A0,A1...An)>` first evaluates `proto::make<R()>` to compute a
+ callable type `R2`. Then, it evaluates `proto::call<R2(A0,A1...An)>`.]]
+]
+
+[/============================================]
+[heading All Grammars Are Primitive Transforms]
+[/============================================]
+
+In addition to the above primitive transforms, all of Proto's grammar elements are also primitive transforms. Their behaviors are described below.
+
+[variablelist
+ [[_wild_pt_]
+ [Returns the current expression unmodified.]]
+ [[_or_]
+ [For the specified set of alternate sub-grammars, find the one that matches
+ the given expression and apply its associated transform.]]
+ [[_and_]
+ [For the given set of sub-grammars, take the /last/ sub-grammar and apply its
+ associated transform.]]
+ [[_not_]
+ [Returns the current expression unmodified.]]
+ [[_if_]
+ [Given three transforms, evaluate the first and treat the result as a
+ compile-time Boolean value. If it is true, evaluate the second transform.
+ Otherwise, evaluate the third.]]
+ [[_terminal_]
+ [Returns the current terminal expression unmodified.]]
+ [[_plus_, _nary_expr_, et. al.]
+ [A Proto grammar that matches a non-terminal such as
+ `proto::plus<_G0_, _G1_>`, when used as a primitive transform, creates a new
+ plus node where the left child is transformed according to `_G0_` and the
+ right child with `_G1_`.]]
+]
+
+[/=================================]
+[heading The Pass-Through Transform]
+[/=================================]
+
+Note the primitive transform associated with grammar elements such as _plus_ described above. They possess a so-called /pass-through/ transform. The pass-through transform accepts an expression of a certain tag type (say, `proto::tag::plus`) and creates a new expression of the same tag type, where each child expression is transformed according to the corresponding child grammar of the pass-through transform. So for instance this grammar ...
+
+ proto::function< X, proto::vararg<Y> >
+
+... matches function expressions where the first child matches the `X` grammar and the rest match the `Y` grammar. When used as a transform, the above grammar will create a new function expression where the first child is transformed according to `X` and the rest are transformed according to `Y`.
+
+The following class templates in Proto can be used as grammars with pass-through transforms:
+
+[table Class Templates With Pass-Through Transforms
+ [[Templates with Pass-Through Transforms]]
+ [[`proto::unary_plus<>`]]
+ [[`proto::negate<>`]]
+ [[`proto::dereference<>`]]
+ [[`proto::complement<>`]]
+ [[`proto::address_of<>`]]
+ [[`proto::logical_not<>`]]
+ [[`proto::pre_inc<>`]]
+ [[`proto::pre_dec<>`]]
+ [[`proto::post_inc<>`]]
+ [[`proto::post_dec<>`]]
+ [[`proto::shift_left<>`]]
+ [[`proto::shift_right<>`]]
+ [[`proto::multiplies<>`]]
+ [[`proto::divides<>`]]
+ [[`proto::modulus<>`]]
+ [[`proto::plus<>`]]
+ [[`proto::minus<>`]]
+ [[`proto::less<>`]]
+ [[`proto::greater<>`]]
+ [[`proto::less_equal<>`]]
+ [[`proto::greater_equal<>`]]
+ [[`proto::equal_to<>`]]
+ [[`proto::not_equal_to<>`]]
+ [[`proto::logical_or<>`]]
+ [[`proto::logical_and<>`]]
+ [[`proto::bitwise_and<>`]]
+ [[`proto::bitwise_or<>`]]
+ [[`proto::bitwise_xor<>`]]
+ [[`proto::comma<>`]]
+ [[`proto::mem_ptr<>`]]
+ [[`proto::assign<>`]]
+ [[`proto::shift_left_assign<>`]]
+ [[`proto::shift_right_assign<>`]]
+ [[`proto::multiplies_assign<>`]]
+ [[`proto::divides_assign<>`]]
+ [[`proto::modulus_assign<>`]]
+ [[`proto::plus_assign<>`]]
+ [[`proto::minus_assign<>`]]
+ [[`proto::bitwise_and_assign<>`]]
+ [[`proto::bitwise_or_assign<>`]]
+ [[`proto::bitwise_xor_assign<>`]]
+ [[`proto::subscript<>`]]
+ [[`proto::if_else_<>`]]
+ [[`proto::function<>`]]
+ [[`proto::unary_expr<>`]]
+ [[`proto::binary_expr<>`]]
+ [[`proto::nary_expr<>`]]
+]
+
+[/=====================================================]
+[heading The Many Roles of Proto Operator Metafunctions]
+[/=====================================================]
+
+We've seen templates such as _terminal_, _plus_ and _nary_expr_ fill many roles. They are metafunction that generate expression types. They are grammars that match expression types. And they are primitive transforms. The following code samples show examples of each.
+
+[*As Metafunctions ...]
+
+ // proto::terminal<> and proto::plus<> are metafunctions
+ // that generate expression types:
+ typedef proto::terminal<int>::type int_;
+ typedef proto::plus<int_, int_>::type plus_;
+
+ int_ i = {42}, j = {24};
+ plus_ p = {i, j};
+
+[*As Grammars ...]
+
+ // proto::terminal<> and proto::plus<> are grammars that
+ // match expression types
+ struct Int : proto::terminal<int> {};
+ struct Plus : proto::plus<Int, Int> {};
+
+ BOOST_MPL_ASSERT(( proto::matches< int_, Int > ));
+ BOOST_MPL_ASSERT(( proto::matches< plus_, Plus > ));
+
+[*As Primitive Transforms ...]
+
+ // A transform that removes all unary_plus nodes in an expression
+ struct RemoveUnaryPlus
+ : proto::or_<
+ proto::when<
+ proto::unary_plus<RemoveUnaryPlus>
+ , RemoveUnaryPlus(proto::_child)
+ >
+ // Use proto::terminal<> and proto::nary_expr<>
+ // both as grammars and as primitive transforms.
+ , proto::terminal<_>
+ , proto::nary_expr<_, proto::vararg<RemoveUnaryPlus> >
+ >
+ {};
+
+ int main()
+ {
+ proto::literal<int> i(0);
+
+ proto::display_expr(
+ +i - +(i - +i)
+ );
+
+ proto::display_expr(
+ RemoveUnaryPlus()( +i - +(i - +i) )
+ );
+ }
+
+The above code displays the following, which shows that unary plus nodes have been stripped from the expression:
+
+[pre
+minus(
+ unary_plus(
+ terminal(0)
+ )
+ , unary_plus(
+ minus(
+ terminal(0)
+ , unary_plus(
+ terminal(0)
+ )
+ )
+ )
+)
+minus(
+ terminal(0)
+ , minus(
+ terminal(0)
+ , terminal(0)
+ )
+)
+]
+
+[endsect]
+
+[/======================================================]
+[section:primitives Building Custom Primitive Transforms]
+[/======================================================]
+
+In previous sections, we've seen how to compose larger transforms out of smaller transforms using function types. The smaller transforms from which larger transforms are composed are /primitive transforms/, and Proto provides a bunch of common ones such as `_child0` and `_value`. In this section we'll see how to author your own primitive transforms.
+
+[note There are a few reasons why you might want to write your own primitive transforms. For instance, your transform may be complicated, and composing it out of primitives becomes unwieldy. You might also need to work around compiler bugs on legacy compilers that makes composing transforms using function types problematic. Finally, you might also decide to define your own primitive transforms to improve compile times. Since Proto can simply invoke a primitive transform directly without having to process arguments or differentiate callable transforms from object transforms, primitive transforms are more efficient.]
+
+Primitive transforms inherit from `proto::transform<>` and have a nested `impl<>` template that inherits from `proto::transform_impl<>`. For example, this is how Proto defines the `_child_c<_N_>` transform, which returns the _N_-th child of the current expression:
+
+ namespace boost { namespace proto
+ {
+ // A primitive transform that returns N-th child
+ // of the current expression.
+ template<int N>
+ struct _child_c : transform<_child_c<N> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef
+ typename result_of::child_c<Expr, N>::type
+ result_type;
+
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ return proto::child_c<N>(expr);
+ }
+ };
+ };
+
+ // Note that _child_c<N> is callable, so that
+ // it can be used in callable transforms, as:
+ // _child_c<0>(_child_c<1>)
+ template<int N>
+ struct is_callable<_child_c<N> >
+ : mpl::true_
+ {};
+ }}
+
+The `proto::transform<>` base class provides the `operator()` overloads and the nested `result<>` template that make your transform a valid function object. These are implemented in terms of the nested `impl<>` template you define.
+
+The `proto::transform_impl<>` base class is a convenience. It provides some nested typedefs that are generally useful. The are specified in the table below:
+
+[table proto::transform_impl<Expr, State, Data> typedefs
+[[typedef][Equivalent To]]
+[[`expr`][`typename remove_reference<Expr>::type`]]
+[[`state`][`typename remove_reference<State>::type`]]
+[[`data`][`typename remove_reference<Data>::type`]]
+[[`expr_param`][`typename add_reference<typename add_const<Expr>::type>::type`]]
+[[`state_param`][`typename add_reference<typename add_const<State>::type>::type`]]
+[[`data_param`][`typename add_reference<typename add_const<Data>::type>::type`]]
+]
+
+You'll notice that `_child_c::impl::operator()` takes arguments of types `expr_param`, `state_param`, and `data_param`. The typedefs make it easy to accept arguments by reference or const reference accordingly.
+
+The only other interesting bit is the `is_callable<>` specialization, which will be described in the [link boost_proto.users_guide.expression_transformation.is_callable next section].
+
+[endsect]
+
+[/=================================================]
+[section:is_callable Making Your Transform Callable]
+[/=================================================]
+
+Transforms are typically of the form `proto::when< Something, R(A0,A1,...) >`. The question is whether `R` represents a function to call or an object to construct, and the answer determines how _when_ evaluates the transform. _when_ uses the `proto::is_callable<>` trait to disambiguate between the two. Proto does its best to guess whether a type is callable or not, but it doesn't always get it right. It's best to know the rules Proto uses, so that you know when you need to be more explicit.
+
+For most types `R`, `proto::is_callable<R>` checks for inheritence from `proto::callable`. However, if the type `R` is a template specialization, Proto assumes that it is /not/ callable ['even if the template inherits from `proto::callable`]. We'll see why in a minute. Consider the following erroneous callable object:
+
+ // Proto can't tell this defines something callable!
+ template<typename T>
+ struct times2 : proto::callable
+ {
+ typedef T result_type;
+
+ T operator()(T i) const
+ {
+ return i * 2;
+ }
+ };
+
+ // ERROR! This is not going to multiply the int by 2:
+ struct IntTimes2
+ : proto::when<
+ proto::terminal<int>
+ , times2<int>(proto::_value)
+ >
+ {};
+
+The problem is that Proto doesn't know that `times2<int>` is callable, so rather that invoking the `times2<int>` function object, Proto will try to construct a `times2<int>` object and initialize it will an `int`. That will not compile.
+
+[note Why can't Proto tell that `times2<int>` is callable? After all, it inherits from `proto::callable`, and that is detectable, right? The problem is that merely asking whether some type `X<Y>` inherits from `callable` will cause the template `X<Y>` to be instantiated. That's a problem for a type like `std::vector<_value(_child1)>`. `std::vector<>` will not suffer to be instantiated with `_value(_child1)` as a template parameter. Since merely asking the question will sometimes result in a hard error, Proto can't ask; it has to assume that `X<Y>` represents an object to construct and not a function to call.]
+
+There are a couple of solutions to the `times2<int>` problem. One solution is to wrap the transform in `proto::call<>`. This forces Proto to treat `times2<int>` as callable:
+
+ // OK, calls times2<int>
+ struct IntTimes2
+ : proto::when<
+ proto::terminal<int>
+ , proto::call<times2<int>(proto::_value)>
+ >
+ {};
+
+This can be a bit of a pain, because we need to wrap every use of `times2<int>`, which can be tedious and error prone, and makes our grammar cluttered and harder to read.
+
+Another solution is to specialize `proto::is_callable<>` on our `times2<>` template:
+
+ namespace boost { namespace proto
+ {
+ // Tell Proto that times2<> is callable
+ template<typename T>
+ struct is_callable<times2<T> >
+ : mpl::true_
+ {};
+ }}
+
+ // OK, times2<> is callable
+ struct IntTimes2
+ : proto::when<
+ proto::terminal<int>
+ , times2<int>(proto::_value)
+ >
+ {};
+
+This is better, but still a pain because of the need to open Proto's namespace.
+
+You could simply make sure that the callable type is not a template specialization. Consider the following:
+
+ // No longer a template specialization!
+ struct times2int : times2<int> {};
+
+ // OK, times2int is callable
+ struct IntTimes2
+ : proto::when<
+ proto::terminal<int>
+ , times2int(proto::_value)
+ >
+ {};
+
+This works because now Proto can tell that `times2int` inherits (indirectly) from `proto::callable`. Any non-template types can be safely checked for inheritance because, as they are not templates, there is no worry about instantiation errors.
+
+There is one last way to tell Proto that `times2<>` is callable. You could add an extra dummy template parameter that defaults to `proto::callable`:
+
+ // Proto will recognize this as callable
+ template<typename T, typename Callable = proto::callable>
+ struct times2 : proto::callable
+ {
+ typedef T result_type;
+
+ T operator()(T i) const
+ {
+ return i * 2;
+ }
+ };
+
+ // OK, this works!
+ struct IntTimes2
+ : proto::when<
+ proto::terminal<int>
+ , times2<int>(proto::_value)
+ >
+ {};
+
+Note that in addition to the extra template parameter, `times2<>` still inherits from `proto::callable`. That's not necessary in this example but it's good style because any types derived from `times2<>` (as `times2int` defined above) will still be considered callable.
+
+[endsect]
+
+[endsect]
Modified: branches/proto/v4/libs/serialization/test/test_binary.cpp
==============================================================================
--- branches/proto/v4/libs/serialization/test/test_binary.cpp (original)
+++ branches/proto/v4/libs/serialization/test/test_binary.cpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -79,7 +79,6 @@
{
test_ostream os(testfile, TEST_STREAM_FLAGS);
test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
- oa << BOOST_SERIALIZATION_NVP(a);
boost::serialization::make_nvp(
"s1", boost::serialization::make_binary_object(s1, sizeof(s1))
);
@@ -92,6 +91,7 @@
oa << boost::serialization::make_nvp(
"s4", boost::serialization::make_binary_object(s4, sizeof(s4))
);
+ oa << BOOST_SERIALIZATION_NVP(a);
// note: add a little bit on the end of the archive to detect
// failure of text mode binary.
oa << BOOST_SERIALIZATION_NVP(i);
@@ -99,7 +99,6 @@
{
test_istream is(testfile, TEST_STREAM_FLAGS);
test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
- ia >> BOOST_SERIALIZATION_NVP(a1);
boost::serialization::make_nvp(
"s1", boost::serialization::make_binary_object(s1_1, sizeof(s1))
);
@@ -112,6 +111,7 @@
ia >> boost::serialization::make_nvp(
"s4", boost::serialization::make_binary_object(s1_4, sizeof(s4))
);
+ ia >> BOOST_SERIALIZATION_NVP(a1);
// note: add a little bit on the end of the archive to detect
// failure of text mode binary.
ia >> BOOST_SERIALIZATION_NVP(i1);
Modified: branches/proto/v4/libs/serialization/test/test_tools.hpp
==============================================================================
--- branches/proto/v4/libs/serialization/test/test_tools.hpp (original)
+++ branches/proto/v4/libs/serialization/test/test_tools.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -74,21 +74,22 @@
namespace archive {
char * test_filename(char * dir = NULL, char *fname = NULL){
static char ibuffer [512];
-
- if(NULL == dir)
+ int i;
+ ibuffer[0] = '\0';
+ if(NULL == dir){
dir = boost::archive::tmpdir();
-
+ }
+ STRCPY(ibuffer, dir);
+ std::strcat(ibuffer, "/");
+ i = std::strlen(ibuffer);
if(NULL == fname){
char old_dir[256];
_getcwd(old_dir, sizeof(old_dir) - 1);
chdir(dir);
-
- std::tmpnam(ibuffer);
+ std::tmpnam(ibuffer + i);
chdir(old_dir);
}
else{
- STRCPY(ibuffer, dir);
- std::strcat(ibuffer, "/");
std::strcat(ibuffer, fname);
}
return ibuffer;
Modified: branches/proto/v4/libs/smart_ptr/shared_array.htm
==============================================================================
--- branches/proto/v4/libs/smart_ptr/shared_array.htm (original)
+++ branches/proto/v4/libs/smart_ptr/shared_array.htm 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -47,7 +47,7 @@
void reset(T * p = 0);
template<class D> void reset(T * p, D d);
- T & operator[](std::ptrdiff_t i) const() const; // never throws
+ T & operator[](std::ptrdiff_t i) const; // never throws
T * get() const; // never throws
bool unique() const; // never throws
Modified: branches/proto/v4/libs/smart_ptr/src/sp_collector.cpp
==============================================================================
--- branches/proto/v4/libs/smart_ptr/src/sp_collector.cpp (original)
+++ branches/proto/v4/libs/smart_ptr/src/sp_collector.cpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -104,6 +104,8 @@
BOOST_ASSERT(p->use_count() != 0); // there should be no inactive counts in the map
+ m2[ i->first ];
+
scan_and_count(i->second.first, i->second.second, m, m2);
}
@@ -121,7 +123,7 @@
if(p->use_count() != i->second) open.push_back(p);
}
- std::cout << "... " << m2.size() << " objects in open.\n";
+ std::cout << "... " << open.size() << " objects in open.\n";
for(open_type::iterator j = open.begin(); j != open.end(); ++j)
{
Modified: branches/proto/v4/libs/test/tools/console_test_runner/src/console_test_runner.cpp
==============================================================================
--- branches/proto/v4/libs/test/tools/console_test_runner/src/console_test_runner.cpp (original)
+++ branches/proto/v4/libs/test/tools/console_test_runner/src/console_test_runner.cpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -6,7 +6,9 @@
// See http://www.boost.org/libs/test for the library home page.
// Boost.Test
+#ifndef BOOST_TEST_DYN_LINK
#define BOOST_TEST_DYN_LINK
+#endif
#include <boost/test/unit_test.hpp>
// Boost.Runtime.Param
@@ -19,38 +21,144 @@
// STL
#include <iostream>
-// PLATFORM HEADER
-#if defined(BOOST_WINDOWS) && !defined(BOOST_DISABLE_WIN32)
-#define USE_WIN32_API
+//_________________________________________________________________//
+
+// System API
+
+namespace dyn_lib {
+
+#if defined(BOOST_WINDOWS) && !defined(BOOST_DISABLE_WIN32) // WIN32 API
+
#include <windows.h>
+
+typedef HINSTANCE handle;
+
+inline handle
+open( std::string const& file_name )
+{
+ return LoadLibrary( file_name.c_str() );
+}
+
+//_________________________________________________________________//
+
+template<typename TargType>
+inline TargType
+locate_symbol( handle h, std::string const& symbol )
+{
+ return reinterpret_cast<TargType>( GetProcAddress( h, symbol.c_str() ) );
+}
+
+//_________________________________________________________________//
+
+inline void
+close( handle h )
+{
+ if( h )
+ FreeLibrary( h );
+}
+
+//_________________________________________________________________//
+
+inline std::string
+error()
+{
+ LPTSTR msg = NULL;
+
+ FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&msg,
+ 0, NULL );
+
+ std::string res( msg );
+
+ if( msg )
+ LocalFree( msg );
+
+ return res;
+}
+
+//_________________________________________________________________//
+
+#elif defined(BOOST_HAS_UNISTD_H) // POSIX API
+
+#include <dlfcn.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+typedef void* handle;
+
+inline handle
+open( std::string const& file_name )
+{
+ return dlopen( file_name.c_str(), RTLD_LOCAL | RTLD_LAZY );
+}
+
+//_________________________________________________________________//
+
+template<typename TargType>
+inline TargType
+locate_symbol( handle h, std::string const& symbol )
+{
+ return reinterpret_cast<TargType>( dlsym( h, symbol.c_str() ) );
+}
+
+//_________________________________________________________________//
+
+inline void
+close( handle h )
+{
+ if( h )
+ dlclose( h );
+}
+
+//_________________________________________________________________//
+
+inline std::string
+error()
+{
+ return dlerror();
+}
+
+//_________________________________________________________________//
+
+#else
+
+#error "Dynamic library API is unknown"
+
#endif
+} // namespace dyn_lib
+
//____________________________________________________________________________//
static std::string test_lib_name;
static std::string init_func_name( "init_unit_test" );
-#ifdef USE_WIN32_API
-static HINSTANCE test_lib_handle;
-#endif
+
+dyn_lib::handle test_lib_handle;
bool load_test_lib()
{
typedef bool (*init_func_ptr)();
init_func_ptr init_func;
-#ifdef USE_WIN32_API
- HINSTANCE test_lib_handle = LoadLibrary( test_lib_name.c_str() );
+ test_lib_handle = dyn_lib::open( test_lib_name );
if( !test_lib_handle )
- throw std::logic_error( std::string("Fail to load test library ").append( test_lib_name ) );
+ throw std::logic_error( std::string("Fail to load test library: ")
+ .append( dyn_lib::error() ) );
- init_func =
- reinterpret_cast<init_func_ptr>( ::GetProcAddress( test_lib_handle, init_func_name.c_str() ) );
+ init_func = dyn_lib::locate_symbol<init_func_ptr>( test_lib_handle, init_func_name );
if( !init_func )
throw std::logic_error( std::string("Couldn't locate test initilization function ")
- .append( init_func_name ) );
-#endif
-
+ .append( init_func_name )
+ .append( ": " )
+ .append( dyn_lib::error() ) );
+
return (*init_func)();
}
@@ -71,12 +179,11 @@
if( P["init"] )
assign_op( init_func_name, P.get( "init" ), 0 );
- bool res = ::boost::unit_test::unit_test_main( &load_test_lib, argc, argv );
+ int res = ::boost::unit_test::unit_test_main( &load_test_lib, argc, argv );
+
+ ::boost::unit_test::framework::clear();
+ dyn_lib::close( test_lib_handle );
-#ifdef USE_WIN32_API
- if( test_lib_handle )
- FreeLibrary( test_lib_handle );
-#endif
return res;
}
catch( rt::logic_error const& ex ) {
Modified: branches/proto/v4/libs/test/tools/console_test_runner/test/test_runner_test.cpp
==============================================================================
--- branches/proto/v4/libs/test/tools/console_test_runner/test/test_runner_test.cpp (original)
+++ branches/proto/v4/libs/test/tools/console_test_runner/test/test_runner_test.cpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -6,7 +6,9 @@
// See http://www.boost.org/libs/test for the library home page.
// Boost.Test
+#ifndef BOOST_TEST_DYN_LINK
#define BOOST_TEST_DYN_LINK
+#endif
#include <boost/test/unit_test.hpp>
using namespace boost::unit_test;
@@ -33,7 +35,10 @@
extern "C" {
-__declspec(dllexport) bool
+#ifdef BOOST_WINDOWS
+__declspec(dllexport)
+#endif
+ bool
init_unit_test()
{
framework::master_test_suite().p_name.value = "Test runner test";
Modified: branches/proto/v4/libs/unordered/doc/changes.qbk
==============================================================================
--- branches/proto/v4/libs/unordered/doc/changes.qbk (original)
+++ branches/proto/v4/libs/unordered/doc/changes.qbk 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -33,9 +33,13 @@
are available.
* Added equality operators.
-[h2 Development...]
+[h2 Boost 1.37.0]
* Rename overload of `emplace` with hint, to `emplace_hint` as specified in
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2691.pdf n2691].
+* Provide forwarding headers at `<boost/unordered/unordered_map_fwd.hpp>` and
+ `<boost/unordered/unordered_set_fwd.hpp>`.
+* Move all the implementation inside `boost/unordered`, to assist
+ modularization and hopefully make it easier to track changes in subversion.
[endsect]
Modified: branches/proto/v4/libs/unordered/test/objects/minimal.hpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/objects/minimal.hpp (original)
+++ branches/proto/v4/libs/unordered/test/objects/minimal.hpp 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -240,7 +240,7 @@
size_type max_size() const { return 1000; }
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) || \
- BOOST_WORKAROUND(MSVC, <= 1300)
+ BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
public: allocator& operator=(allocator const&) { return *this;}
#else
private: allocator& operator=(allocator const&);
Modified: branches/proto/v4/libs/unordered/test/unordered/Jamfile.v2
==============================================================================
--- branches/proto/v4/libs/unordered/test/unordered/Jamfile.v2 (original)
+++ branches/proto/v4/libs/unordered/test/unordered/Jamfile.v2 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -14,6 +14,8 @@
test-suite unordered
:
+ [ run fwd_set_test.cpp ]
+ [ run fwd_map_test.cpp ]
[ run compile_set.cpp ]
[ run compile_map.cpp ]
[ run link_test_1.cpp link_test_2.cpp ]
Modified: branches/proto/v4/libs/utility/utility.htm
==============================================================================
--- branches/proto/v4/libs/utility/utility.htm (original)
+++ branches/proto/v4/libs/utility/utility.htm 2008-09-19 11:48:59 EDT (Fri, 19 Sep 2008)
@@ -211,9 +211,7 @@
href="../../boost/utility/binary.hpp"><boost/utility/binary.hpp></a>
which is automatically included by
<a
- href="../../boost/utility.hpp"><boost/utility.hpp></a> and
- <a
- href="../../boost/binary.hpp"><boost/binary.hpp></a>..
+ href="../../boost/utility.hpp"><boost/utility.hpp></a>.
<p>Contributed by Matt Calabrese.</p><p>
</p><h3>Example</h3>
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk