Revision: 424 Author: alai04 Date: Wed Aug 18 08:21:10 2010 Log: 升级至1.44.0,第一批,libs/目录a-c子目录 http://code.google.com/p/boost-doc-zh/source/detail?r=424 Added: /trunk/libs/algorithm/string/test /trunk/libs/algorithm/string/test/Jamfile.v2 /trunk/libs/algorithm/string/test/conv_test.cpp /trunk/libs/algorithm/string/test/find_format_test.cpp /trunk/libs/algorithm/string/test/find_test.cpp /trunk/libs/algorithm/string/test/join_test.cpp /trunk/libs/algorithm/string/test/predicate_test.cpp /trunk/libs/algorithm/string/test/regex_test.cpp /trunk/libs/algorithm/string/test/replace_test.cpp /trunk/libs/algorithm/string/test/split_test.cpp /trunk/libs/algorithm/string/test/trim_test.cpp /trunk/libs/asio/example/timeouts/async_tcp_client.cpp /trunk/libs/asio/example/timeouts/blocking_tcp_client.cpp /trunk/libs/asio/example/timeouts/blocking_udp_client.cpp /trunk/libs/asio/example/timeouts/server.cpp /trunk/libs/config/test/boost_no_0x_hdr_typeindex.ipp /trunk/libs/config/test/boost_no_com_value_init.ipp /trunk/libs/config/test/no_0x_hdr_typeindex_fail.cpp /trunk/libs/config/test/no_0x_hdr_typeindex_pass.cpp /trunk/libs/config/test/no_com_value_init_fail.cpp /trunk/libs/config/test/no_com_value_init_pass.cpp Deleted: /trunk/libs/asio/example/timeouts/accept_timeout.cpp /trunk/libs/asio/example/timeouts/connect_timeout.cpp /trunk/libs/asio/example/timeouts/datagram_receive_timeout.cpp /trunk/libs/asio/example/timeouts/stream_receive_timeout.cpp Modified: /trunk/libs/accumulators/doc/Jamfile.v2 /trunk/libs/accumulators/doc/accumulators.qbk /trunk/libs/algorithm/minmax/index.html /trunk/libs/algorithm/string/doc/Jamfile.v2 /trunk/libs/algorithm/string/doc/external_concepts.html /trunk/libs/algorithm/string/doc/string_algo.xml /trunk/libs/algorithm/string/doc/usage.xml /trunk/libs/array/doc/array.xml /trunk/libs/array/test/array2.cpp /trunk/libs/asio/doc/Jamfile.v2 /trunk/libs/asio/doc/examples.qbk /trunk/libs/asio/doc/history.qbk /trunk/libs/asio/doc/reference.qbk /trunk/libs/asio/doc/reference.xsl /trunk/libs/asio/doc/tutorial.qbk /trunk/libs/asio/example/http/server4/coroutine.hpp /trunk/libs/asio/example/local/iostream_client.cpp /trunk/libs/asio/example/timeouts/Jamfile /trunk/libs/asio/example/timeouts/Jamfile.v2 /trunk/libs/asio/example/tutorial/timer_dox.txt /trunk/libs/asio/test/Jamfile /trunk/libs/asio/test/Jamfile.v2 /trunk/libs/asio/test/buffer.cpp /trunk/libs/asio/test/buffered_read_stream.cpp /trunk/libs/asio/test/buffered_stream.cpp /trunk/libs/asio/test/buffered_write_stream.cpp /trunk/libs/asio/test/buffers_iterator.cpp /trunk/libs/asio/test/ip/multicast.cpp /trunk/libs/asio/test/ip/tcp.cpp /trunk/libs/asio/test/ip/udp.cpp /trunk/libs/asio/test/ip/unicast.cpp /trunk/libs/asio/test/ip/v6_only.cpp /trunk/libs/asio/test/read.cpp /trunk/libs/asio/test/read_at.cpp /trunk/libs/asio/test/serial_port_base.cpp /trunk/libs/asio/test/socket_base.cpp /trunk/libs/asio/test/write.cpp /trunk/libs/asio/test/write_at.cpp /trunk/libs/bimap/doc/html/boost_bimap/acknowledgements.html/trunk/libs/bimap/doc/html/boost_bimap/bimap_and_boost/boost_libraries_that_work_well_with_boost_bimap.html
/trunk/libs/bimap/doc/html/boost_bimap/bimap_and_boost/dependencies.html /trunk/libs/bimap/doc/html/boost_bimap/bimap_and_boost.html /trunk/libs/bimap/doc/html/boost_bimap/compiler_specifics.html /trunk/libs/bimap/doc/html/boost_bimap/examples/mighty_bimap.html/trunk/libs/bimap/doc/html/boost_bimap/examples/multiindex_to_bimap_path___bidirectional_map.html /trunk/libs/bimap/doc/html/boost_bimap/examples/multiindex_to_bimap_path___hashed_indices.html
/trunk/libs/bimap/doc/html/boost_bimap/examples/simple_bimap.html /trunk/libs/bimap/doc/html/boost_bimap/examples.html /trunk/libs/bimap/doc/html/boost_bimap/future_work.html /trunk/libs/bimap/doc/html/boost_bimap/history/multiindex_and_bimap.html /trunk/libs/bimap/doc/html/boost_bimap/history.html /trunk/libs/bimap/doc/html/boost_bimap/introduction.html /trunk/libs/bimap/doc/html/boost_bimap/one_minute_tutorial.html /trunk/libs/bimap/doc/html/boost_bimap/performance.html /trunk/libs/bimap/doc/html/boost_bimap/rationale/additional_features.html /trunk/libs/bimap/doc/html/boost_bimap/rationale/code.html/trunk/libs/bimap/doc/html/boost_bimap/rationale/the_student_and_the_mentor.html
/trunk/libs/bimap/doc/html/boost_bimap/rationale.html /trunk/libs/bimap/doc/html/boost_bimap/reference/bimap_reference.html /trunk/libs/bimap/doc/html/boost_bimap/reference/list_of_reference.html /trunk/libs/bimap/doc/html/boost_bimap/reference/set_of_reference.html/trunk/libs/bimap/doc/html/boost_bimap/reference/unconstrained_set_of_reference.html /trunk/libs/bimap/doc/html/boost_bimap/reference/unordered_set_of_reference.html
/trunk/libs/bimap/doc/html/boost_bimap/reference/vector_of_reference.html /trunk/libs/bimap/doc/html/boost_bimap/reference.html /trunk/libs/bimap/doc/html/boost_bimap/release_notes.html /trunk/libs/bimap/doc/html/boost_bimap/test_suite.html/trunk/libs/bimap/doc/html/boost_bimap/the_tutorial/additional_information.html /trunk/libs/bimap/doc/html/boost_bimap/the_tutorial/bimaps_with_user_defined_names.html /trunk/libs/bimap/doc/html/boost_bimap/the_tutorial/complete_instantiation_scheme.html /trunk/libs/bimap/doc/html/boost_bimap/the_tutorial/controlling_collection_types.html /trunk/libs/bimap/doc/html/boost_bimap/the_tutorial/differences_with_standard_maps.html /trunk/libs/bimap/doc/html/boost_bimap/the_tutorial/discovering_the_bimap_framework.html /trunk/libs/bimap/doc/html/boost_bimap/the_tutorial/the_collection_of_relations_type.html
/trunk/libs/bimap/doc/html/boost_bimap/the_tutorial/unconstrained_sets.html /trunk/libs/bimap/doc/html/boost_bimap/the_tutorial/useful_functions.html /trunk/libs/bimap/doc/html/boost_bimap/the_tutorial.html /trunk/libs/bimap/doc/html/index.html /trunk/libs/bimap/doc/jamfile.v2 /trunk/libs/bind/doc/Jamfile.v2 /trunk/libs/concept_check/concept_check.htm /trunk/libs/concept_check/doc/Jamfile.v2 /trunk/libs/concept_check/stl_concept_check.cpp /trunk/libs/config/doc/Jamfile.v2 /trunk/libs/config/doc/macro_reference.qbk /trunk/libs/config/test/all/Jamfile.v2 /trunk/libs/config/test/boost_no_0x_hdr_tuple.ipp /trunk/libs/config/test/boost_no_auto_declarations.ipp /trunk/libs/config/test/boost_no_auto_multidecl.ipp /trunk/libs/config/test/boost_no_char16_t.ipp /trunk/libs/config/test/boost_no_char32_t.ipp /trunk/libs/config/test/boost_no_decltype.ipp /trunk/libs/config/test/boost_no_extern_template.ipp /trunk/libs/config/test/boost_no_initializer_lists.ipp /trunk/libs/config/test/boost_no_raw_literals.ipp /trunk/libs/config/test/boost_no_rtti.ipp /trunk/libs/config/test/config_info.cpp /trunk/libs/config/test/config_test.cpp /trunk/libs/config/test/link/Jamfile.v2 /trunk/libs/config/test/link/link_test.cpp /trunk/libs/config/test/link/link_test.hpp /trunk/libs/config/test/link/main.cpp /trunk/libs/config/test/link/test/Jamfile.v2 ======================================= --- /dev/null +++ /trunk/libs/algorithm/string/test/Jamfile.v2 Wed Aug 18 08:21:10 2010 @@ -0,0 +1,69 @@+# Boost string_algo library test suite Jamfile ----------------------------
+# +# Copyright Pavol Droba 2002-2003. Use, modification and +# distribution is subject to the Boost Software License, Version +# 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +#+# See http://www.boost.org for updates, documentation, and revision history.
+ +import testing ; + +test-suite algorithm/string + : [ run + trim_test.cpp + : : + : + : trim + ] + [ run + conv_test.cpp + : : + : + : conv + ] + [ run + predicate_test.cpp + : : + : + : predicate + ] + [ run + find_test.cpp + : : + : + : find + ] + [ run + split_test.cpp + : : + : + : split + ] + [ run + join_test.cpp + : : + : + : join + ] + [ run + replace_test.cpp + : : + : + : replace + ] + [ run + regex_test.cpp + ../../../regex/build//boost_regex + : : + : + : regex + ] + [ run + find_format_test.cpp + : : + : + : find_format + ] + ; + ======================================= --- /dev/null +++ /trunk/libs/algorithm/string/test/conv_test.cpp Wed Aug 18 08:21:10 2010 @@ -0,0 +1,95 @@+// Boost string_algo library conv_test.cpp file ---------------------------//
+ +// Copyright Pavol Droba 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) ++// See http://www.boost.org for updates, documentation, and revision history.
+ +#include <boost/algorithm/string/case_conv.hpp> + +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> + +#include <string> +#include <iostream> +#include <algorithm> +#include <boost/test/test_tools.hpp> + +using namespace std; +using namespace boost; + +void conv_test() +{ + string str1("AbCdEfG 123 xxxYYYzZzZ"); + string str2("AbCdEfG 123 xxxYYYzZzZ"); + string str3(""); + const char pch[]="AbCdEfG 123 xxxYYYzZzZ"; + unsigned int pchlen=sizeof(pch); + + char* pch1=new char[pchlen]; + std::copy(pch, pch+pchlen, pch1); + char* pch2=new char[pchlen]; + std::copy(pch, pch+pchlen, pch2); + + // *** iterator tests *** // + + string strout; + to_lower_copy( back_inserter(strout), str1 ); + BOOST_CHECK( strout=="abcdefg 123 xxxyyyzzzz" ); + strout.clear(); + to_upper_copy( back_inserter(strout), str1 ); + BOOST_CHECK( strout=="ABCDEFG 123 XXXYYYZZZZ" ); + + strout.clear(); + to_lower_copy( back_inserter(strout), "AbCdEfG 123 xxxYYYzZzZ" ); + BOOST_CHECK( strout=="abcdefg 123 xxxyyyzzzz" ); + strout.clear(); + to_upper_copy( back_inserter(strout), "AbCdEfG 123 xxxYYYzZzZ" ); + BOOST_CHECK( strout=="ABCDEFG 123 XXXYYYZZZZ" ); + + strout.clear(); + to_lower_copy( back_inserter(strout), pch1 ); + BOOST_CHECK( strout=="abcdefg 123 xxxyyyzzzz" ); + strout.clear(); + to_upper_copy( back_inserter(strout), pch1 ); + BOOST_CHECK( strout=="ABCDEFG 123 XXXYYYZZZZ" ); + + // *** value passing tests *** // + + BOOST_CHECK( to_lower_copy( str1 )=="abcdefg 123 xxxyyyzzzz" ); + BOOST_CHECK( to_upper_copy( str1 )=="ABCDEFG 123 XXXYYYZZZZ" ); + + BOOST_CHECK( to_lower_copy( str3 )=="" ); + BOOST_CHECK( to_upper_copy( str3 )=="" ); + + // *** inplace tests *** // + + to_lower( str1 ); + BOOST_CHECK( str1=="abcdefg 123 xxxyyyzzzz" ); + to_upper( str2 ); + BOOST_CHECK( str2=="ABCDEFG 123 XXXYYYZZZZ" ); + + // c-string modification + to_lower( pch1 ); + BOOST_CHECK( string(pch1)=="abcdefg 123 xxxyyyzzzz" ); + to_upper( pch2 ); + BOOST_CHECK( string(pch2)=="ABCDEFG 123 XXXYYYZZZZ" ); + + to_lower( str3 ); + BOOST_CHECK( str3=="" ); + to_upper( str3 ); + BOOST_CHECK( str3=="" ); + + delete[] pch1; + delete[] pch2; +} + +// test main +int test_main( int, char*[] ) +{ + conv_test(); + + return 0; +} ======================================= --- /dev/null+++ /trunk/libs/algorithm/string/test/find_format_test.cpp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,163 @@+// Boost string_algo library find_format_test.cpp file ------------------//
+ +// Copyright (c) 2009 Steven Watanabe +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) ++// See http://www.boost.org for updates, documentation, and revision history.
+ +#include <boost/algorithm/string/find_format.hpp> +#include <boost/algorithm/string/finder.hpp> +#include <boost/algorithm/string/formatter.hpp> + +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> + +#include <boost/test/test_tools.hpp> + +// We're only using const_formatter. +template<class Formatter> +struct formatter_result { + typedef boost::iterator_range<const char*> type; +}; + +template<class Formatter> +struct checked_formatter { +public:+ checked_formatter(const Formatter& formatter) : formatter_(formatter) {}
+ template< typename T >+ typename formatter_result<Formatter>::type operator()( const T & s ) const {
+ BOOST_CHECK( !s.empty() ); + return formatter_(s); + } +private: + Formatter formatter_; +}; + +template<class Formatter> +checked_formatter<Formatter> +make_checked_formatter(const Formatter& formatter) { + return checked_formatter<Formatter>(formatter); +} + +void find_format_test() +{ + const std::string source = "$replace $replace"; + std::string expected = "ok $replace"; + std::string output(80, '\0'); + + std::string::iterator pos = + boost::find_format_copy( + output.begin(), + source, + boost::first_finder("$replace"), + make_checked_formatter(boost::const_formatter("ok"))); + BOOST_CHECK(pos == output.begin() + expected.size());+ output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
+ BOOST_CHECK_EQUAL(output, expected); + + output = + boost::find_format_copy( + source, + boost::first_finder("$replace"), + make_checked_formatter(boost::const_formatter("ok"))); + BOOST_CHECK_EQUAL(output, expected); + + // now try finding a string that doesn't exist + output.resize(80); + pos = + boost::find_format_copy( + output.begin(), + source, + boost::first_finder("$noreplace"), + make_checked_formatter(boost::const_formatter("bad"))); + BOOST_CHECK(pos == output.begin() + source.size());+ output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
+ BOOST_CHECK_EQUAL(output, source); + + output = + boost::find_format_copy( + source, + boost::first_finder("$noreplace"), + make_checked_formatter(boost::const_formatter("bad"))); + BOOST_CHECK_EQUAL(output, source); + + // in place version + output = source; + boost::find_format( + output, + boost::first_finder("$replace"), + make_checked_formatter(boost::const_formatter("ok"))); + BOOST_CHECK_EQUAL(output, expected); + output = source; + boost::find_format( + output, + boost::first_finder("$noreplace"), + make_checked_formatter(boost::const_formatter("bad"))); + BOOST_CHECK_EQUAL(output, source); +} + +void find_format_all_test() +{ + const std::string source = "$replace $replace"; + std::string expected = "ok ok"; + std::string output(80, '\0'); + + std::string::iterator pos = + boost::find_format_all_copy(output.begin(), + source, + boost::first_finder("$replace"), + boost::const_formatter("ok")); + BOOST_CHECK(pos == output.begin() + expected.size());+ output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
+ BOOST_CHECK_EQUAL(output, expected); + + output = + boost::find_format_all_copy( + source, + boost::first_finder("$replace"), + make_checked_formatter(boost::const_formatter("ok"))); + BOOST_CHECK_EQUAL(output, expected); + + // now try finding a string that doesn't exist + output.resize(80); + pos = + boost::find_format_all_copy( + output.begin(), + source, + boost::first_finder("$noreplace"), + make_checked_formatter(boost::const_formatter("bad"))); + BOOST_CHECK(pos == output.begin() + source.size());+ output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
+ BOOST_CHECK_EQUAL(output, source); + + output = + boost::find_format_all_copy( + source, + boost::first_finder("$noreplace"), + make_checked_formatter(boost::const_formatter("bad"))); + BOOST_CHECK_EQUAL(output, source); + + // in place version + output = source; + boost::find_format_all( + output, + boost::first_finder("$replace"), + make_checked_formatter(boost::const_formatter("ok"))); + BOOST_CHECK_EQUAL(output, expected); + output = source; + boost::find_format_all( + output, + boost::first_finder("$noreplace"), + make_checked_formatter(boost::const_formatter("bad"))); + BOOST_CHECK_EQUAL(output, source); +} + +int test_main( int, char*[] ) +{ + find_format_test(); + find_format_all_test(); + + return 0; +} ======================================= --- /dev/null +++ /trunk/libs/algorithm/string/test/find_test.cpp Wed Aug 18 08:21:10 2010 @@ -0,0 +1,259 @@ +// Boost string_algo library substr_test.cpp file ------------------// + +// Copyright Pavol Droba 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) ++// See http://www.boost.org for updates, documentation, and revision history.
+ +#include <boost/algorithm/string/find.hpp> +#include <boost/algorithm/string/classification.hpp> + +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> + +#include <string> +#include <vector> +#include <iostream> +#include <iterator> +#include <sstream> +#include <boost/test/test_tools.hpp> + +using namespace std; +using namespace boost; + +void find_test() +{ + string str1("123abcxXxabcXxXabc321"); + string str2("abc"); + string str3(""); + const char* pch1="123abcxxxabcXXXabc321"; + vector<int> vec1( str1.begin(), str1.end() ); ++ // find results ------------------------------------------------------------//
+ iterator_range<string::iterator> nc_result; + iterator_range<string::const_iterator> cv_result; + + iterator_range<vector<int>::iterator> nc_vresult; + iterator_range<vector<int>::const_iterator> cv_vresult; + + iterator_range<const char*> ch_result; ++ // basic tests ------------------------------------------------------------//
+ + + // find_first + BOOST_CHECKPOINT( "find_first" ); + + nc_result=find_first( str1, string("abc") ); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 3) && + ( (nc_result.end()-str1.begin()) == 6) ); + + cv_result=find_first( const_cast<const string&>(str1), str2 ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 3) && + ( (cv_result.end()-str1.begin()) == 6) ); + + cv_result=ifind_first( const_cast<const string&>(str1), "xXX" ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 6) && + ( (cv_result.end()-str1.begin()) == 9) ); + + ch_result=find_first( pch1, "abc" );+ BOOST_CHECK(( (ch_result.begin() - pch1 ) == 3) && ( (ch_result.end() - pch1 ) == 6 ) );
+ + // find_last + BOOST_CHECKPOINT( "find_last" ); + + nc_result=find_last( str1, string("abc") ); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 15) && + ( (nc_result.end()-str1.begin()) == 18) ); + + cv_result=find_last( const_cast<const string&>(str1), str2 ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 15) && + ( (cv_result.end()-str1.begin()) == 18) ); + + cv_result=ifind_last( const_cast<const string&>(str1), "XXx" ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 12) && + ( (cv_result.end()-str1.begin()) == 15) ); + + ch_result=find_last( pch1, "abc" );+ BOOST_CHECK(( (ch_result.begin() - pch1 ) == 15) && ( (ch_result.end() - pch1 ) == 18 ) );
+ + // find_nth + BOOST_CHECKPOINT( "find_nth" ); + + nc_result=find_nth( str1, string("abc"), 1 ); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 9) && + ( (nc_result.end()-str1.begin()) == 12) ); + + nc_result=find_nth( str1, string("abc"), -1 ); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 15) && + ( (nc_result.end()-str1.begin()) == 18) ); + + + cv_result=find_nth( const_cast<const string&>(str1), str2, 1 ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 9) && + ( (cv_result.end()-str1.begin()) == 12) ); + + cv_result=find_nth( const_cast<const string&>(str1), str2, -1 ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 15) && + ( (cv_result.end()-str1.begin()) == 18) ); + + cv_result=ifind_nth( const_cast<const string&>(str1), "xxx", 1 ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 12) && + ( (cv_result.end()-str1.begin()) == 15) ); + + cv_result=ifind_nth( const_cast<const string&>(str1), "xxx", 1 ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 12) && + ( (cv_result.end()-str1.begin()) == 15) ); + + + ch_result=find_nth( pch1, "abc", 1 );+ BOOST_CHECK(( (ch_result.begin() - pch1 ) == 9) && ( (ch_result.end() - pch1 ) == 12 ) );
+ + // find_head + BOOST_CHECKPOINT( "find_head" ); + + nc_result=find_head( str1, 6 ); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 0) && + ( (nc_result.end()-str1.begin()) == 6) ); + + nc_result=find_head( str1, -6 ); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 0) && + ( (str1.end()-nc_result.end()) == 6 ) ); + + cv_result=find_head( const_cast<const string&>(str1), 6 ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 0) && + ( (cv_result.end()-str1.begin()) == 6) ); + + ch_result=find_head( pch1, 6 );+ BOOST_CHECK( ( (ch_result.begin() - pch1 ) == 0 ) && ( (ch_result.end() - pch1 ) == 6 ) );
+ + // find_tail + BOOST_CHECKPOINT( "find_tail" ); + + nc_result=find_tail( str1, 6 ); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 15) && + ( (nc_result.end()-str1.begin()) == 21) ); + + nc_result=find_tail( str1, -6 ); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 6) && + ( (nc_result.end()-str1.begin()) == 21) ); + + + cv_result=find_tail( const_cast<const string&>(str1), 6 ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 15) && + ( (cv_result.end()-str1.begin()) == 21) ); + + ch_result=find_tail( pch1, 6 );+ BOOST_CHECK( ( (ch_result.begin() - pch1 ) == 15 ) && ( (ch_result.end() - pch1 ) == 21 ) );
+ + // find_token + BOOST_CHECKPOINT( "find_token" ); + + nc_result=find_token( str1, is_any_of("abc"), token_compress_on ); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 3) && + ( (nc_result.end()-str1.begin()) == 6) ); ++ cv_result=find_token( const_cast<const string&>(str1), is_any_of("abc"), token_compress_on );
+ BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 3) && + ( (cv_result.end()-str1.begin()) == 6) ); + + nc_result=find_token( str1, is_any_of("abc"), token_compress_off ); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 3) && + ( (nc_result.end()-str1.begin()) == 4) ); ++ cv_result=find_token( const_cast<const string&>(str1), is_any_of("abc"), token_compress_off );
+ BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 3) && + ( (cv_result.end()-str1.begin()) == 4) ); + + ch_result=find_token( pch1, is_any_of("abc"), token_compress_off );+ BOOST_CHECK( ( (ch_result.begin() - pch1 ) == 3 ) && ( (ch_result.end() - pch1 ) == 4 ) );
+ + // generic find + BOOST_CHECKPOINT( "generic find" ); + + nc_result=find(str1, first_finder(string("abc"))); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 3) && + ( (nc_result.end()-str1.begin()) == 6) ); + + cv_result=find(const_cast<const string&>(str1), first_finder(str2) ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 3) && + ( (cv_result.end()-str1.begin()) == 6) ); + + // multi-type comparison test + BOOST_CHECKPOINT( "multi-type" ); + + nc_vresult=find_first( vec1, string("abc") ); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 3) && + ( (nc_result.end()-str1.begin()) == 6) ); + + cv_vresult=find_first( const_cast<const vector<int>&>(vec1), str2 ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 3) && + ( (cv_result.end()-str1.begin()) == 6) ); + + // overflow test + BOOST_CHECKPOINT( "overflow" ); + + nc_result=find_first( str2, string("abcd") ); + BOOST_CHECK( nc_result.begin()==nc_result.end() );+ cv_result=find_first( const_cast<const string&>(str2), string("abcd") );
+ BOOST_CHECK( cv_result.begin()==cv_result.end() ); + + cv_result=find_head( const_cast<const string&>(str2), 4 );+ BOOST_CHECK( string( cv_result.begin(), cv_result.end() )== string("abc") );
+ cv_result=find_tail( const_cast<const string&>(str2), 4 );+ BOOST_CHECK( string( cv_result.begin(), cv_result.end() )== string("abc") );
+ + // Empty string test + BOOST_CHECKPOINT( "empty" ); + + nc_result=find_first( str3, string("abcd") ); + BOOST_CHECK( nc_result.begin()==nc_result.end() ); + nc_result=find_first( str1, string("") ); + BOOST_CHECK( nc_result.begin()==nc_result.end() ); ++ cv_result=find_first( const_cast<const string&>(str3), string("abcd") );
+ BOOST_CHECK( cv_result.begin()==cv_result.end() ); + cv_result=find_first( const_cast<const string&>(str1), string("") ); + BOOST_CHECK( cv_result.begin()==cv_result.end() ); + + // iterator_range specific tests + ostringstream osstr; + osstr << find_first( str1, "abc" ); + BOOST_CHECK( osstr.str()=="abc" ); +} + +// test main +int test_main( int, char*[] ) +{ + find_test(); + + return 0; +} ======================================= --- /dev/null +++ /trunk/libs/algorithm/string/test/join_test.cpp Wed Aug 18 08:21:10 2010 @@ -0,0 +1,79 @@+// Boost string_algo library iterator_test.cpp file ---------------------------//
+ +// Copyright Pavol Droba 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) ++// See http://www.boost.org for updates, documentation, and revision history.
+ +#include <boost/algorithm/string/join.hpp> +#include <boost/algorithm/string/classification.hpp> +// equals predicate is used for result comparison +#include <boost/algorithm/string/predicate.hpp> + +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> + +#include <string> +#include <vector> +#include <iostream> + +#include <boost/test/test_tools.hpp> + + +using namespace std; +using namespace boost; + +bool is_not_empty(const std::string& str) +{ + return !str.empty(); +} + +void join_test() +{ + // Prepare inputs + vector<string> tokens1; + tokens1.push_back("xx"); + tokens1.push_back("abc"); + tokens1.push_back("xx"); + + vector<string> tokens2; + tokens2.push_back(""); + tokens2.push_back("xx"); + tokens2.push_back("abc"); + tokens2.push_back(""); + tokens2.push_back("abc"); + tokens2.push_back("xx"); + tokens2.push_back(""); + + vector<string> tokens3; + tokens3.push_back(""); + tokens3.push_back(""); + tokens3.push_back(""); + + vector<string> empty_tokens; + + vector<vector<int> > vtokens; + for(unsigned int n=0; n<tokens2.size(); ++n) + {+ vtokens.push_back(vector<int>(tokens2[n].begin(), tokens2[n].end()));
+ } + + BOOST_CHECK( equals(join(tokens1, "-"), "xx-abc-xx") ); + BOOST_CHECK( equals(join(tokens2, "-"), "-xx-abc--abc-xx-") ); + BOOST_CHECK( equals(join(vtokens, "-"), "-xx-abc--abc-xx-") ); + BOOST_CHECK( equals(join(empty_tokens, "-"), "") ); ++ BOOST_CHECK( equals(join_if(tokens2, "-", is_not_empty), "xx-abc-abc-xx") );
+ BOOST_CHECK( equals(join_if(empty_tokens, "-", is_not_empty), "") ); + BOOST_CHECK( equals(join_if(tokens3, "-", is_not_empty), "") ); +} + +// test main +int test_main( int, char*[] ) +{ + join_test(); + + return 0; +} ======================================= --- /dev/null+++ /trunk/libs/algorithm/string/test/predicate_test.cpp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,162 @@ +// Boost string_algo library predicate_test.cpp file ------------------// + +// Copyright Pavol Droba 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) ++// See http://www.boost.org for updates, documentation, and revision history.
+ +#include <boost/algorithm/string/predicate.hpp> +#include <boost/algorithm/string/classification.hpp> + +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> + +#include <string> +#include <vector> +#include <iostream> +#include <functional> +#include <boost/test/test_tools.hpp> + +using namespace std; +using namespace boost; + +void predicate_test() +{ + string str1("123xxx321"); + string str1_prefix("123"); + string str2("abc"); + string str3(""); + string str4("abc"); + vector<int> vec1( str1.begin(), str1.end() ); + + // Basic tests + BOOST_CHECK( starts_with( str1, string("123") ) ); + BOOST_CHECK( !starts_with( str1, string("1234") ) ); + + BOOST_CHECK( istarts_with( "aBCxxx", "abc" ) ); + BOOST_CHECK( !istarts_with( "aBCxxx", "abcd" ) ); + + BOOST_CHECK( ends_with( str1, string("321") ) ); + BOOST_CHECK( !ends_with( str1, string("123") ) ); + + BOOST_CHECK( iends_with( "aBCxXx", "XXX" ) ); + BOOST_CHECK( !iends_with( "aBCxxX", "xXXX" ) ); + + BOOST_CHECK( contains( str1, string("xxx") ) ); + BOOST_CHECK( !contains( str1, string("yyy") ) ); + + BOOST_CHECK( icontains( "123XxX321", "xxx" ) ); + BOOST_CHECK( !icontains( "123xXx321", "yyy" ) ); + + BOOST_CHECK( equals( str2, string("abc") ) ); + BOOST_CHECK( !equals( str1, string("yyy") ) ); + + BOOST_CHECK( iequals( "AbC", "abc" ) ); + BOOST_CHECK( !iequals( "aBc", "yyy" ) ); + + BOOST_CHECK( lexicographical_compare("abc", "abd") ); + BOOST_CHECK( !lexicographical_compare("abc", "abc") ); + BOOST_CHECK( lexicographical_compare("abc", "abd", is_less()) ); + + BOOST_CHECK( !ilexicographical_compare("aBD", "AbC") ); + BOOST_CHECK( ilexicographical_compare("aBc", "AbD") ); + BOOST_CHECK( lexicographical_compare("abC", "aBd", is_iless()) ); + + // multi-type comparison test + BOOST_CHECK( starts_with( vec1, string("123") ) ); + BOOST_CHECK( ends_with( vec1, string("321") ) ); + BOOST_CHECK( contains( vec1, string("xxx") ) ); + BOOST_CHECK( equals( vec1, str1 ) ); + + // overflow test + BOOST_CHECK( !starts_with( str2, string("abcd") ) ); + BOOST_CHECK( !ends_with( str2, string("abcd") ) ); + BOOST_CHECK( !contains( str2, string("abcd") ) ); + BOOST_CHECK( !equals( str2, string("abcd") ) ); + + // equal test + BOOST_CHECK( starts_with( str2, string("abc") ) ); + BOOST_CHECK( ends_with( str2, string("abc") ) ); + BOOST_CHECK( contains( str2, string("abc") ) ); + BOOST_CHECK( equals( str2, string("abc") ) ); + + //! Empty string test + BOOST_CHECK( starts_with( str2, string("") ) ); + BOOST_CHECK( ends_with( str2, string("") ) ); + BOOST_CHECK( contains( str2, string("") ) ); + BOOST_CHECK( equals( str3, string("") ) ); + + //! Container compatibility test + BOOST_CHECK( starts_with( "123xxx321", "123" ) ); + BOOST_CHECK( ends_with( "123xxx321", "321" ) ); + BOOST_CHECK( contains( "123xxx321", "xxx" ) ); + BOOST_CHECK( equals( "123xxx321", "123xxx321" ) ); + +} + +template<typename Pred, typename Input> +void test_pred(const Pred& pred, const Input& input, bool bYes) +{ + // test assignment operator + Pred pred1=pred; + pred1=pred; + pred1=pred1; + if(bYes) + { + BOOST_CHECK( all( input, pred ) ); + BOOST_CHECK( all( input, pred1 ) ); + } + else + { + BOOST_CHECK( !all( input, pred ) ); + BOOST_CHECK( !all( input, pred1 ) ); + } +} + +#define TEST_CLASS( Pred, YesInput, NoInput )\ +{\ + test_pred(Pred, YesInput, true); \ + test_pred(Pred, NoInput, false); \ +} + +void classification_test() +{ + TEST_CLASS( is_space(), "\n\r\t ", "..." ); + TEST_CLASS( is_alnum(), "ab129ABc", "_ab129ABc" ); + TEST_CLASS( is_alpha(), "abc", "abc1" ); + TEST_CLASS( is_cntrl(), "\n\t\r", "..." ); + TEST_CLASS( is_digit(), "1234567890", "abc" ); + TEST_CLASS( is_graph(), "123abc.,", " \t" ); + TEST_CLASS( is_lower(), "abc", "Aasdf" ); + TEST_CLASS( is_print(), "abs", "\003\004asdf" ); + TEST_CLASS( is_punct(), ".,;\"", "abc" ); + TEST_CLASS( is_upper(), "ABC", "aBc" ); + TEST_CLASS( is_xdigit(), "ABC123", "XFD" ); + TEST_CLASS( is_any_of( string("abc") ), "aaabbcc", "aaxb" ); + TEST_CLASS( is_any_of( "abc" ), "aaabbcc", "aaxb" ); + TEST_CLASS( is_from_range( 'a', 'c' ), "aaabbcc", "aaxb" ); ++ TEST_CLASS( !is_classified(std::ctype_base::space), "...", "..\n\r\t " ); + TEST_CLASS( ( !is_any_of("abc") && is_from_range('a','e') ) || is_space(), "d e", "abcde" );
+ + // is_any_of test +// TEST_CLASS( !is_any_of(""), "", "aaa" ) + TEST_CLASS( is_any_of("a"), "a", "ab" ) + TEST_CLASS( is_any_of("ba"), "ab", "abc" ) + TEST_CLASS( is_any_of("cba"), "abc", "abcd" ) + TEST_CLASS( is_any_of("hgfedcba"), "abcdefgh", "abcdefghi" )+ TEST_CLASS( is_any_of("qponmlkjihgfedcba"), "abcdefghijklmnopq", "zzz" )
+} + +#undef TEST_CLASS + +// test main +int test_main( int, char*[] ) +{ + predicate_test(); + classification_test(); + + return 0; +} ======================================= --- /dev/null+++ /trunk/libs/algorithm/string/test/regex_test.cpp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,159 @@ +// Boost string_algo library substr_test.cpp file ------------------// + +// Copyright Pavol Droba 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) ++// See http://www.boost.org for updates, documentation, and revision history.
+ +#include <boost/algorithm/string/regex.hpp> +#include <boost/algorithm/string/join.hpp> +#include <boost/algorithm/string/sequence_traits.hpp> +// equals predicate is used for result comparison +#include <boost/algorithm/string/predicate.hpp> + + +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> + +#include <string> +#include <vector> +#include <iostream> +#include <boost/regex.hpp> +#include <boost/test/test_tools.hpp> + +using namespace std; +using namespace boost; + +static void find_test() +{ + string str1("123a1cxxxa23cXXXa456c321"); + const char* pch1="123a1cxxxa23cXXXa456c321"; + regex rx("a[0-9]+c"); + vector<int> vec1( str1.begin(), str1.end() ); + vector<string> tokens; + + // find results + iterator_range<string::iterator> nc_result; + iterator_range<string::const_iterator> cv_result; + + iterator_range<vector<int>::iterator> nc_vresult; + iterator_range<vector<int>::const_iterator> cv_vresult; + + iterator_range<const char*> ch_result; + + // basic tests + nc_result=find_regex( str1, rx ); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 3) && + ( (nc_result.end()-str1.begin()) == 6) ); + + cv_result=find_regex( str1, rx ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 3) && + ( (cv_result.end()-str1.begin()) == 6) ); + + ch_result=find_regex( pch1, rx );+ BOOST_CHECK(( (ch_result.begin() - pch1 ) == 3) && ( (ch_result.end() - pch1 ) == 6 ) );
+ + // multi-type comparison test + nc_vresult=find_regex( vec1, rx ); + BOOST_CHECK( + ( (nc_result.begin()-str1.begin()) == 3) && + ( (nc_result.end()-str1.begin()) == 6) ); + + cv_vresult=find_regex( vec1, rx ); + BOOST_CHECK( + ( (cv_result.begin()-str1.begin()) == 3) && + ( (cv_result.end()-str1.begin()) == 6) ); + + // find_all_regex test + find_all_regex( tokens, str1, rx ); + + BOOST_REQUIRE( tokens.size()==3 ); + BOOST_CHECK( tokens[0]==string("a1c") ); + BOOST_CHECK( tokens[1]==string("a23c") ); + BOOST_CHECK( tokens[2]==string("a456c") ); + + // split_regex test + split_regex( tokens, str1, rx ); + + BOOST_REQUIRE( tokens.size()==4 ); + BOOST_CHECK( tokens[0]==string("123") ); + BOOST_CHECK( tokens[1]==string("xxx") ); + BOOST_CHECK( tokens[2]==string("XXX") ); + BOOST_CHECK( tokens[3]==string("321") ); + +} + +static void join_test() +{ + // Prepare inputs + vector<string> tokens1; + tokens1.push_back("xx"); + tokens1.push_back("abc"); + tokens1.push_back("xx"); + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + BOOST_CHECK( equals(join_if(tokens1, "-", regex("x+")), "xx-xx") ); + BOOST_CHECK( equals(join_if(tokens1, "-", regex("[abc]+")), "abc") ); +#else+ BOOST_CHECK( equals(join_if_regex(tokens1, "-", regex("x+")), "xx-xx") ); + BOOST_CHECK( equals(join_if_regex(tokens1, "-", regex("[abc]+")), "abc") );
+#endif +} + +static void replace_test() +{ + string str1("123a1cxxxa23cXXXa456c321"); + regex rx1("a([0-9]+)c"); + regex rx2("([xX]+)"); + regex rx3("_[^_]*_"); + string fmt1("_A$1C_"); + string fmt2("_xXx_"); + vector<int> vec1( str1.begin(), str1.end() ); + + // inmutable tests + + // basic tests+ BOOST_CHECK( replace_regex_copy( str1, rx1, fmt1 )==string("123_A1C_xxxa23cXXXa456c321") ); + BOOST_CHECK( replace_all_regex_copy( str1, rx1, fmt1 )==string("123_A1C_xxx_A23C_XXX_A456C_321") ); + BOOST_CHECK( erase_regex_copy( str1, rx1 )==string("123xxxa23cXXXa456c321") ); + BOOST_CHECK( erase_all_regex_copy( str1, rx1 )==string(string("123xxxXXX321")) );
+ + // output iterator variants test + string strout; + replace_regex_copy( back_inserter(strout), str1, rx1, fmt1 ); + BOOST_CHECK( strout==string("123_A1C_xxxa23cXXXa456c321") ); + strout.clear(); + replace_all_regex_copy( back_inserter(strout), str1, rx1, fmt1 ); + BOOST_CHECK( strout==string("123_A1C_xxx_A23C_XXX_A456C_321") ); + strout.clear(); + erase_regex_copy( back_inserter(strout), str1, rx1 ); + BOOST_CHECK( strout==string("123xxxa23cXXXa456c321") ); + strout.clear(); + erase_all_regex_copy( back_inserter(strout), str1, rx1 ); + BOOST_CHECK( strout==string("123xxxXXX321") ); + strout.clear(); + + // in-place test + replace_regex( str1, rx1, fmt2 ); + BOOST_CHECK( str1==string("123_xXx_xxxa23cXXXa456c321") ); + + replace_all_regex( str1, rx2, fmt1 ); + BOOST_CHECK( str1==string("123__AxXxC___AxxxC_a23c_AXXXC_a456c321") ); + erase_regex( str1, rx3 ); + BOOST_CHECK( str1==string("123AxXxC___AxxxC_a23c_AXXXC_a456c321") ); + erase_all_regex( str1, rx3 ); + BOOST_CHECK( str1==string("123AxXxCa23ca456c321") ); +} + +int test_main( int, char*[] ) +{ + find_test(); + join_test(); + replace_test(); + + return 0; +} ======================================= --- /dev/null+++ /trunk/libs/algorithm/string/test/replace_test.cpp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,302 @@ +// Boost string_algo library substr_test.cpp file ------------------// + +// Copyright Pavol Droba 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) ++// See http://www.boost.org for updates, documentation, and revision history.
+ +#include <boost/algorithm/string/replace.hpp> +#include <boost/algorithm/string/erase.hpp> +#include <boost/algorithm/string/std/list_traits.hpp> +#include <boost/algorithm/string/std/string_traits.hpp> + +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> + +#include <string> +#include <vector> +#include <list> +#include <iostream> + +// equals predicate is used for result comparison +#include <boost/algorithm/string/predicate.hpp> + +#include <boost/test/test_tools.hpp> + +using namespace std; +using namespace boost; + +void sequence_traits_test() +{ + // basic_string traits + BOOST_CHECK( boost::algorithm::has_native_replace<string>::value ); + BOOST_CHECK( !boost::algorithm::has_stable_iterators<string>::value ); + BOOST_CHECK( !boost::algorithm::has_const_time_insert<string>::value ); + BOOST_CHECK( !boost::algorithm::has_const_time_erase<string>::value ); + + // vector traits+ BOOST_CHECK( !boost::algorithm::has_native_replace< vector<char>
+ BOOST_CHECK( !boost::algorithm::has_stable_iterators< vector<char>::value );
+ BOOST_CHECK( !boost::algorithm::has_const_time_insert< vector<char>::value );
+ BOOST_CHECK( !boost::algorithm::has_const_time_erase< vector<char>::value );
::value );
+ + // list traits+ BOOST_CHECK( !boost::algorithm::has_native_replace< list<char>
+ BOOST_CHECK( boost::algorithm::has_stable_iterators< list<char>::value );
+ BOOST_CHECK( boost::algorithm::has_const_time_insert< list<char>::value );
+ BOOST_CHECK( boost::algorithm::has_const_time_erase< list<char>::value );
::value );
+} + +// Combine tests for all variants of the algorithm +#define C_ , +#define TEST_ALGO( Algo, Input, Params, Output ) \ +{\ + BOOST_CHECKPOINT( #Algo " - Copy" );\ +\ + string str1(Input);\ +\ + /* Copy test */ \ + BOOST_CHECK( Algo##_copy( str1, Params )==Output );\ +\ + BOOST_CHECKPOINT( #Algo " - Iterator" );\ + /* Iterator test */\ + string strout;\ + Algo##_copy( back_inserter(strout), str1, Params );\ + BOOST_CHECK( strout==Output ); \ +\ + /* In-place test */\ + vector<char> vec1( str1.begin(), str1.end() );\ + list<char> list1( str1.begin(), str1.end() );\ +\ + BOOST_CHECKPOINT( #Algo " - Inplace(string)" );\ + Algo( str1, Params ); \ + BOOST_CHECK( equals( str1, Output ) ); \ +\ + BOOST_CHECKPOINT( #Algo " - Inplace(vector)" );\ + Algo( vec1, Params ); \ + BOOST_CHECK( equals( vec1, Output ) );\ +\ + BOOST_CHECKPOINT( #Algo " - Inplace(list)" );\ + Algo( list1, Params ); \ + BOOST_CHECK( equals( list1, Output ) );\ +} + +void replace_first_test() +{ + // replace first+ TEST_ALGO( replace_first, "1abc3abc2", string("abc") C_ string("YYY"), string("1YYY3abc2") ); + TEST_ALGO( ireplace_first, "1AbC3abc2", "aBc" C_ "YYY", string("1YYY3abc2") ); + TEST_ALGO( replace_first, "1abc3abc2", string("abc") C_ string("Z"), string("1Z3abc2") ); + TEST_ALGO( replace_first, "1abc3abc2", string("abc") C_ string("XXXX"), string("1XXXX3abc2") ); + TEST_ALGO( replace_first, "1abc3abc2", string("") C_ string("XXXX"), string("1abc3abc2") ); + TEST_ALGO( replace_first, "1abc3abc2", "" C_ "XXXX", string("1abc3abc2") ); + TEST_ALGO( replace_first, "", string("") C_ string("XXXX"), string("") );
+ TEST_ALGO( erase_first, "1abc3abc2", string("abc"), string("13abc2") ); + TEST_ALGO( ierase_first, "1aBc3abc2", "abC", "13abc2" ); + TEST_ALGO( erase_first, "1abc3abc2", "abc", "13abc2" ); + TEST_ALGO( erase_first, "1abc3abc2", string(""), string("1abc3abc2") ); + TEST_ALGO( erase_first, "", string("abc"), string("") ); +} + +void replace_last_test() +{ + // replace last+ TEST_ALGO( replace_last, "1abc3abc2", string("abc") C_ string("YYY"), string("1abc3YYY2") ); + TEST_ALGO( ireplace_last, "1abc3AbC2", "aBc" C_ "YYY", string("1abc3YYY2") ); + TEST_ALGO( replace_last, "1abc3abc2", string("abc") C_ string("Z"), string("1abc3Z2") ); + TEST_ALGO( replace_last, "1abc3abc2", string("abc") C_ string("XXXX"), string("1abc3XXXX2") ); + TEST_ALGO( replace_last, "1abc3abc2", "abc" C_ "XXXX", string("1abc3XXXX2") ); + TEST_ALGO( replace_last, "", string("") C_ string("XXXX"), string("") );
+ TEST_ALGO( erase_last, "1abc3abc2", string("abc"), string("1abc32") ); + TEST_ALGO( ierase_last, "1aBc3aBc2", "ABC", string("1aBc32") ); + TEST_ALGO( erase_last, "1abc3abc2", "abc", string("1abc32") ); + TEST_ALGO( erase_last, "1abc3abc2", string(""), string("1abc3abc2") ); + TEST_ALGO( erase_last, "", string("abc"), string("") ); +} + +void replace_all_test() +{ + // replace all+ TEST_ALGO( replace_all, "1abc3abc2", string("abc") C_ string("YYY"), string("1YYY3YYY2") ); + TEST_ALGO( replace_all, string("1abc3abc2"), "/" C_ "\\", string("1abc3abc2") ); + TEST_ALGO( ireplace_all, "1aBc3AbC2", "abC" C_ "YYY", string("1YYY3YYY2") ); + TEST_ALGO( replace_all, "1abc3abc2", string("abc") C_ string("Z"), string("1Z3Z2") ); + TEST_ALGO( replace_all, "1abc3abc2", string("abc") C_ string("XXXX"), string("1XXXX3XXXX2") ); + TEST_ALGO( replace_all, "1abc3abc2", "abc" C_ "XXXX", string("1XXXX3XXXX2") );
+ TEST_ALGO( replace_all, "", string("") C_ string("XXXX"), string("") ); + TEST_ALGO( erase_all, "1abc3abc2", string("abc"), string("132") ); + TEST_ALGO( ierase_all, "1aBc3aBc2", "aBC", string("132") ); + TEST_ALGO( erase_all, "1abc3abc2", "abc", string("132") ); + TEST_ALGO( erase_all, "1abc3abc2", string(""), string("1abc3abc2") ); + TEST_ALGO( erase_all, "", string("abc"), string("") ); +} + +void replace_nth_test() +{ + // replace nth+ TEST_ALGO( replace_nth, "1abc3abc2", string("abc") C_ 0 C_ string("YYY"), string("1YYY3abc2") ); + TEST_ALGO( replace_nth, "1abc3abc2", string("abc") C_ -1 C_ string("YYY"), string("1abc3YYY2") ); + TEST_ALGO( ireplace_nth, "1AbC3abc2", "aBc" C_ 0 C_ "YYY", string("1YYY3abc2") ); + TEST_ALGO( ireplace_nth, "1AbC3abc2", "aBc" C_ -1 C_ "YYY", string("1AbC3YYY2") ); + TEST_ALGO( replace_nth, "1abc3abc2", string("abc") C_ 0 C_ string("Z"), string("1Z3abc2") ); + TEST_ALGO( replace_nth, "1abc3abc2", string("abc") C_ 0 C_ string("XXXX"), string("1XXXX3abc2") ); + TEST_ALGO( replace_nth, "1abc3abc2", "abc" C_ 0 C_ "XXXX", string("1XXXX3abc2") ); + TEST_ALGO( replace_nth, "1abc3abc2", "abc" C_ 3 C_ "XXXX", string("1abc3abc2") ); + TEST_ALGO( replace_nth, "1abc3abc2", "abc" C_ -3 C_ "XXXX", string("1abc3abc2") ); + TEST_ALGO( replace_nth, "1abc3abc2", string("") C_ 0 C_ string("XXXX"), string("1abc3abc2") ); + TEST_ALGO( replace_nth, "", string("") C_ 0 C_ string("XXXX"), string("") ); + TEST_ALGO( replace_nth, "", string("") C_ -1 C_ string("XXXX"), string("") ); + TEST_ALGO( erase_nth, "1abc3abc2", string("abc") C_ 0, string("13abc2") ); + TEST_ALGO( erase_nth, "1abc3abc2", string("abc") C_ -1, string("1abc32") ); + TEST_ALGO( erase_nth, "1abc3abc2", string("abc") C_ -3, string("1abc3abc2") );
+ TEST_ALGO( ierase_nth, "1aBc3aBc2", "ABC" C_ 0, string("13aBc2") ); + TEST_ALGO( ierase_nth, "1aBc3aBc2", "ABC" C_ -1, string("1aBc32") ); + TEST_ALGO( ierase_nth, "1aBc3aBc2", "ABC" C_ -3, string("1aBc3aBc2") ); + TEST_ALGO( erase_nth, "1abc3abc2", "abc" C_ 0, string("13abc2") );+ TEST_ALGO( erase_nth, "1abc3abc2", string("") C_ 0, string("1abc3abc2") );
+ TEST_ALGO( erase_nth, "", string("abc") C_ 0, string("") ); + TEST_ALGO( erase_nth, "", string("abc") C_ -1, string("") );+ TEST_ALGO( replace_nth, "1abc3abc2", string("abc") C_ 1 C_ string("YYY"), string("1abc3YYY2") ); + TEST_ALGO( replace_nth, "1abc3abc2", string("abc") C_ 2 C_ string("YYY"), string("1abc3abc2") );
+} + +void replace_head_test() +{ + // replace head+ TEST_ALGO( replace_head, "abc3abc2", 3 C_ string("YYY"), string("YYY3abc2") ); + TEST_ALGO( replace_head, "abc3abc2", -3 C_ string("YYY"), string("YYYbc2") );
+ TEST_ALGO( replace_head, "abc3abc2", 3 C_ "YYY", string("YYY3abc2") ); + TEST_ALGO( replace_head, "abc", 3 C_ string("Z"), string("Z") ); + TEST_ALGO( replace_head, "abc", 6 C_ string("XXXX"), string("XXXX") ); + TEST_ALGO( replace_head, "abc", -6 C_ string("XXXX"), string("abc") );+ TEST_ALGO( replace_head, "abc3abc2", 0 C_ string("XXXX"), string("abc3abc2") );
+ TEST_ALGO( replace_head, "", 4 C_ string("XXXX"), string("") ); + TEST_ALGO( replace_head, "", -4 C_ string("XXXX"), string("") ); + TEST_ALGO( erase_head, "abc3abc2", 3, string("3abc2") ); + TEST_ALGO( erase_head, "abc3abc2", -3, string("bc2") ); + TEST_ALGO( erase_head, "abc3abc2", 0, string("abc3abc2") ); + TEST_ALGO( erase_head, "", 4, string("") ); + TEST_ALGO( erase_head, "", -4, string("") ); +} + +void replace_tail_test() +{ + // replace tail+ TEST_ALGO( replace_tail, "abc3abc", 3 C_ string("YYY"), string("abc3YYY") );
+ TEST_ALGO( replace_tail, "abc3abc", -3 C_ "YYY", string("abcYYY") ); + TEST_ALGO( replace_tail, "abc", 3 C_ string("Z"), string("Z") ); + TEST_ALGO( replace_tail, "abc", 6 C_ string("XXXX"), string("XXXX") ); + TEST_ALGO( replace_tail, "abc", -6 C_ string("XXXX"), string("abc") );+ TEST_ALGO( replace_tail, "abc3abc", 0 C_ string("XXXX"), string("abc3abc") );
+ TEST_ALGO( replace_tail, "", 4 C_ string("XXXX"), string("") ); + TEST_ALGO( replace_tail, "", -4 C_ string("XXXX"), string("") ); + TEST_ALGO( erase_tail, "abc3abc", 3, string("abc3") ); + TEST_ALGO( erase_tail, "abc3abc", -3, string("abc") ); + TEST_ALGO( erase_tail, "abc3abc", 0, string("abc3abc") ); + TEST_ALGO( erase_tail, "", 4, string("") ); + TEST_ALGO( erase_tail, "", -4, string("") ); +} + +void replace_range_test() +{ + // replace_range + { + BOOST_CHECKPOINT( "replace_range" ); + + string str1("1abc3abc2"); + BOOST_CHECK( + replace_range_copy( + str1, + make_iterator_range(str1.begin()+1, str1.begin()+4), + string("XXX") )==string("1XXX3abc2") ); + + string strout; + replace_range_copy( + back_inserter( strout ), + str1, + make_iterator_range(str1.begin()+1, str1.begin()+4), + string("XXX") ); + BOOST_CHECK( strout==string("1XXX3abc2") ); + + replace_range( + str1, + make_iterator_range(str1.begin()+1, str1.begin()+4), + string("XXX") ); + BOOST_CHECK( str1==string("1XXX3abc2") ); + } + // erase_range + { + BOOST_CHECKPOINT( "erase_range" ); + + string str1("1abc3abc2"); + BOOST_CHECK( + erase_range_copy( + str1,+ make_iterator_range(str1.begin()+1, str1.begin()+4))==string("13abc2") );
+ + string strout; + erase_range_copy( + back_inserter( strout ), + str1, + make_iterator_range(str1.begin()+1, str1.begin()+4)); + BOOST_CHECK( strout==string("13abc2") ); + + erase_range( + str1, + make_iterator_range(str1.begin()+1, str1.begin()+4)); + BOOST_CHECK( str1==string("13abc2") ); + } +} + +void collection_comp_test() +{ + // container traits compatibility tests + { + string strout;+ replace_first_copy( back_inserter(strout), "1abc3abc2", "abc", "YYY" );
+ BOOST_CHECK( strout==string("1YYY3abc2") ); + } + { + string strout;+ replace_last_copy( back_inserter(strout), "1abc3abc2", "abc", "YYY" );
+ BOOST_CHECK( strout==string("1abc3YYY2") ); + } + { + string strout;+ replace_all_copy( back_inserter(strout), "1abc3abc2", "abc", "YYY" );
+ BOOST_CHECK( strout==string("1YYY3YYY2") ); + } + { + string strout;+ replace_nth_copy( back_inserter(strout), "1abc3abc2", "abc", 1, "YYY" );
+ BOOST_CHECK( strout==string("1abc3YYY2") ); + } + { + string strout; + replace_head_copy( back_inserter(strout), "abc3abc2", 3 , "YYY" ); + BOOST_CHECK( strout==string("YYY3abc2") ); + } + { + string strout; + replace_tail_copy( back_inserter(strout), "abc3abc", 3 , "YYY" ); + BOOST_CHECK( strout==string("abc3YYY") ); + } +} + +// test main +int test_main( int, char*[] ) +{ + sequence_traits_test(); + replace_first_test(); + replace_last_test(); + replace_all_test(); + replace_nth_test(); + replace_head_test(); + replace_tail_test(); + replace_range_test(); + collection_comp_test(); + + return 0; +} ======================================= --- /dev/null+++ /trunk/libs/algorithm/string/test/split_test.cpp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,153 @@+// Boost string_algo library iterator_test.cpp file ---------------------------//
+ +// Copyright Pavol Droba 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) ++// See http://www.boost.org for updates, documentation, and revision history.
+ +#include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/classification.hpp> +// equals predicate is used for result comparison +#include <boost/algorithm/string/predicate.hpp> + +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> + +#include <string> +#include <vector> +#include <iostream> + +#include <boost/test/test_tools.hpp> + + +using namespace std; +using namespace boost; + +template< typename T1, typename T2 > +void deep_compare( const T1& X, const T2& Y ) +{ + BOOST_REQUIRE( X.size() == Y.size() ); + for( unsigned int nIndex=0; nIndex<X.size(); ++nIndex ) + { + BOOST_CHECK( equals( X[nIndex], Y[nIndex] ) ); + } +} + +void iterator_test() +{ + string str1("xx-abc--xx-abb"); + string str2("Xx-abc--xX-abb-xx"); + string str3("xx"); + const char* pch1="xx-abc--xx-abb"; + vector<string> tokens; + vector< vector<int> > vtokens; + + // find_all tests + find_all( + tokens, + pch1, + "xx" ); + + BOOST_REQUIRE( tokens.size()==2 ); + BOOST_CHECK( tokens[0]==string("xx") ); + BOOST_CHECK( tokens[1]==string("xx") ); + + ifind_all( + tokens, + str2, + "xx" ); + + BOOST_REQUIRE( tokens.size()==3 ); + BOOST_CHECK( tokens[0]==string("Xx") ); + BOOST_CHECK( tokens[1]==string("xX") ); + BOOST_CHECK( tokens[2]==string("xx") ); + + find_all( + tokens, + str1, + "xx" ); + + BOOST_REQUIRE( tokens.size()==2 ); + BOOST_CHECK( tokens[0]==string("xx") ); + BOOST_CHECK( tokens[1]==string("xx") ); + + find_all( + vtokens, + str1, + string("xx") ); + deep_compare( tokens, vtokens ); + + // split tests + split( + tokens, + str2, + is_any_of("xX"), + token_compress_on ); + + BOOST_REQUIRE( tokens.size()==4 ); + BOOST_CHECK( tokens[0]==string("") ); + BOOST_CHECK( tokens[1]==string("-abc--") ); + BOOST_CHECK( tokens[2]==string("-abb-") ); + BOOST_CHECK( tokens[3]==string("") ); + + split( + tokens, + pch1, + is_any_of("x"), + token_compress_on ); + + BOOST_REQUIRE( tokens.size()==3 ); + BOOST_CHECK( tokens[0]==string("") ); + BOOST_CHECK( tokens[1]==string("-abc--") ); + BOOST_CHECK( tokens[2]==string("-abb") ); + + split( + vtokens, + str1, + is_any_of("x"), + token_compress_on ); + deep_compare( tokens, vtokens ); + + split( + tokens, + str1, + is_punct(), + token_compress_off ); + + BOOST_REQUIRE( tokens.size()==5 ); + BOOST_CHECK( tokens[0]==string("xx") ); + BOOST_CHECK( tokens[1]==string("abc") ); + BOOST_CHECK( tokens[2]==string("") ); + BOOST_CHECK( tokens[3]==string("xx") ); + BOOST_CHECK( tokens[4]==string("abb") ); ++ find_iterator<string::iterator> fiter=make_find_iterator(str1, first_finder("xx"));
+ BOOST_CHECK(equals(*fiter, "xx")); + ++fiter; + BOOST_CHECK(equals(*fiter, "xx")); + ++fiter; + BOOST_CHECK(fiter==find_iterator<string::iterator>()); ++ split_iterator<string::iterator> siter=make_split_iterator(str1, token_finder(is_any_of("-"), token_compress_on));
+ BOOST_CHECK(equals(*siter, "xx")); + ++siter; + BOOST_CHECK(equals(*siter, "abc")); + ++siter; + BOOST_CHECK(equals(*siter, "xx")); + ++siter; + BOOST_CHECK(equals(*siter, "abb")); + ++siter; + BOOST_CHECK(siter==split_iterator<string::iterator>(siter)); + BOOST_CHECK(siter==split_iterator<string::iterator>()); + +} + +// test main +int test_main( int, char*[] ) +{ + iterator_test(); + + return 0; +} ======================================= --- /dev/null +++ /trunk/libs/algorithm/string/test/trim_test.cpp Wed Aug 18 08:21:10 2010 @@ -0,0 +1,118 @@+// Boost string_algo library trim_test.cpp file ---------------------------//
+ +// Copyright Pavol Droba 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) ++// See http://www.boost.org for updates, documentation, and revision history.
+ +#include <boost/algorithm/string/trim.hpp> + +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> + +#include <string> +#include <iostream> +#include <boost/test/test_tools.hpp> + +using namespace std; +using namespace boost; + +void trim_test() +{ + string str1(" 1x x x x1 "); + string str2(" 2x x x x2 "); + string str3(" "); + + // *** value passing tests *** // + + // general string test + BOOST_CHECK( trim_left_copy( str1 )=="1x x x x1 " ) ; + BOOST_CHECK( trim_right_copy( str1 )==" 1x x x x1" ) ; + BOOST_CHECK( trim_copy( str1 )=="1x x x x1" ) ; + + // spaces-only string test + BOOST_CHECK( trim_left_copy( str3 )=="" ); + BOOST_CHECK( trim_right_copy( str3 )=="" ); + BOOST_CHECK( trim_copy( str3 )=="" ); + + // empty string check + BOOST_CHECK( trim_left_copy( string("") )=="" ); + BOOST_CHECK( trim_right_copy( string("") )=="" ); + BOOST_CHECK( trim_copy( string("") )=="" ); + + // iterator tests + string str; + trim_left_copy_if( std::back_inserter(str), str1, is_space() ); + BOOST_CHECK( str=="1x x x x1 " ); + + str.clear(); + trim_right_copy_if( std::back_inserter(str), str1, is_space() ); + BOOST_CHECK( str==" 1x x x x1" ); + + str.clear(); + trim_copy_if( std::back_inserter(str), str1, is_space() ); + BOOST_CHECK( str=="1x x x x1" ); + + str.clear(); + trim_left_copy_if( + std::back_inserter(str), + " 1x x x x1 ", + is_space() ); + BOOST_CHECK( str=="1x x x x1 " ); + + str.clear(); + trim_right_copy_if( + std::back_inserter(str), + " 1x x x x1 ", + is_space() ); + BOOST_CHECK( str==" 1x x x x1" ); + + str.clear(); + trim_copy_if( + std::back_inserter(str), + " 1x x x x1 ", + is_space() ); + BOOST_CHECK( str=="1x x x x1" ); + // *** inplace tests *** // + + // general string test + trim_left( str1 ); + BOOST_CHECK( str1=="1x x x x1 " ); + trim_right( str1 ); + BOOST_CHECK( str1=="1x x x x1" ); + trim( str2 ); + BOOST_CHECK( str2=="2x x x x2" ); + + // spaces-only string test + str3 = " "; trim_left( str3 ); + BOOST_CHECK( str3=="" ); + str3 = " "; trim_right( str3 ); + BOOST_CHECK( str3=="" ); + str3 = " "; trim( str3 ); + BOOST_CHECK( str3=="" ); + + // empty string check + str3 = ""; trim_left( str3 ); + BOOST_CHECK( str3=="" ); + str3 = ""; trim_right( str3 ); + BOOST_CHECK( str3=="" ); + str3 = ""; trim( str3 ); + BOOST_CHECK( str3=="" ); + + // *** non-standard predicate tests *** // + BOOST_CHECK( + trim_copy_if( + string("123abc456"), + is_classified(std::ctype_base::digit) )=="abc" );+ BOOST_CHECK( trim_copy_if( string("<>abc<>"), is_any_of( "<<>>" ) )=="abc" );
+} + +// test main +int test_main( int, char*[] ) +{ + trim_test(); + + return 0; +} ======================================= --- /dev/null+++ /trunk/libs/asio/example/timeouts/async_tcp_client.cpp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,305 @@ +// +// async_tcp_client.cpp +// ~~~~~~~~~~~~~~~~~~~~ +//+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include <boost/asio/deadline_timer.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/ip/tcp.hpp> +#include <boost/asio/read_until.hpp> +#include <boost/asio/streambuf.hpp> +#include <boost/asio/write.hpp> +#include <boost/bind.hpp> +#include <iostream> + +using boost::asio::deadline_timer; +using boost::asio::ip::tcp; + +//+// This class manages socket timeouts by applying the concept of a deadline. +// Some asynchronous operations are given deadlines by which they must complete. +// Deadlines are enforced by an "actor" that persists for the lifetime of the
+// client object: +// +// +----------------+ +// | | +// | check_deadline |<---+ +// | | | +// +----------------+ | async_wait() +// | | +// +---------+ +//+// If the deadline actor determines that the deadline has expired, the socket
+// is closed and any outstanding operations are consequently cancelled. +// +// Connection establishment involves trying each endpoint in turn until a+// connection is successful, or the available endpoints are exhausted. If the +// deadline actor closes the socket, the connect actor is woken up and moves to
+// the next endpoint. +// +// +---------------+ +// | | +// | start_connect |<---+ +// | | | +// +---------------+ | +// | | +// async_- | +----------------+ +// connect() | | | +// +--->| handle_connect | +// | | +// +----------------+ +// : +// Once a connection is : +// made, the connect : +// actor forks in two - : +// : +// an actor for reading : and an actor for +// inbound messages: : sending heartbeats: +// : +// +------------+ : +-------------+ +// | |<- - - - -+- - - - ->| | +// | start_read | | start_write |<---+ +// | |<---+ | | | +// +------------+ | +-------------+ | async_wait() +// | | | | +// async_- | +-------------+ async_- | +--------------+ +// read_- | | | write() | | | +// until() +--->| handle_read | +--->| handle_write | +// | | | | +// +-------------+ +--------------+ +//+// The input actor reads messages from the socket, where messages are delimited +// by the newline character. The deadline for a complete message is 30 seconds.
+//+// The heartbeat actor sends a heartbeat (a message that consists of a single +// newline character) every 10 seconds. In this example, no deadline is applied
+// message sending. +// +class client +{ +public: + client(boost::asio::io_service& io_service) + : stopped_(false), + socket_(io_service), + deadline_(io_service), + heartbeat_timer_(io_service) + { + } ++ // Called by the user of the client class to initiate the connection process.
+ // The endpoint iterator will have been obtained using a tcp::resolver. + void start(tcp::resolver::iterator endpoint_iter) + { + // Start the connect actor. + start_connect(endpoint_iter); + + // Start the deadline actor. You will note that we're not setting any + // particular deadline here. Instead, the connect and input actors will + // update the deadline prior to each asynchronous operation. + deadline_.async_wait(boost::bind(&client::check_deadline, this)); + } ++ // This function terminates all the actors to shut down the connection. It + // may be called by the user of the client class, or by the class itself in
+ // response to graceful termination or an unrecoverable error. + void stop() + { + stopped_ = true; + socket_.close(); + deadline_.cancel(); + heartbeat_timer_.cancel(); + } + +private: + void start_connect(tcp::resolver::iterator endpoint_iter) + { + if (endpoint_iter != tcp::resolver::iterator()) + { + std::cout << "Trying " << endpoint_iter->endpoint() << "...\n"; + + // Set a deadline for the connect operation. + deadline_.expires_from_now(boost::posix_time::seconds(60)); + + // Start the asynchronous connect operation. + socket_.async_connect(endpoint_iter->endpoint(), + boost::bind(&client::handle_connect, + this, _1, endpoint_iter)); + } + else + { + // There are no more endpoints to try. Shut down the client. + stop(); + } + } + + void handle_connect(const boost::system::error_code& ec, + tcp::resolver::iterator endpoint_iter) + { + if (stopped_) + return; ++ // The async_connect() function automatically opens the socket at the start + // of the asynchronous operation. If the socket is closed at this time then
+ // the timeout handler must have run first. + if (!socket_.is_open()) + { + std::cout << "Connect timed out\n"; + + // Try the next available endpoint. + start_connect(++endpoint_iter); + } + + // Check if the connect operation failed before the deadline expired. + else if (ec) + { + std::cout << "Connect error: " << ec.message() << "\n"; ++ // We need to close the socket used in the previous connection attempt
+ // before starting a new one. + socket_.close(); + + // Try the next available endpoint. + start_connect(++endpoint_iter); + } + + // Otherwise we have successfully established a connection. + else + { + std::cout << "Connected to " << endpoint_iter->endpoint() << "\n"; + + // Start the input actor. + start_read(); + + // Start the heartbeat actor. + start_write(); + } + } + + void start_read() + { + // Set a deadline for the read operation. + deadline_.expires_from_now(boost::posix_time::seconds(30)); + + // Start an asynchronous operation to read a newline-delimited message. + boost::asio::async_read_until(socket_, input_buffer_, '\n', + boost::bind(&client::handle_read, this, _1)); + } + + void handle_read(const boost::system::error_code& ec) + { + if (stopped_) + return; + + if (!ec) + { + // Extract the newline-delimited message from the buffer. + std::string line; + std::istream is(&input_buffer_); + std::getline(is, line); + + // Empty messages are heartbeats and so ignored. + if (!line.empty()) + { + std::cout << "Received: " << line << "\n"; + } + + start_read(); + } + else + { + std::cout << "Error on receive: " << ec.message() << "\n"; + + stop(); + } + } + + void start_write() + { + if (stopped_) + return; + + // Start an asynchronous operation to send a heartbeat message. + boost::asio::async_write(socket_, boost::asio::buffer("\n", 1), + boost::bind(&client::handle_write, this, _1)); + } + + void handle_write(const boost::system::error_code& ec) + { + if (stopped_) + return; + + if (!ec) + { + // Wait 10 seconds before sending the next heartbeat. + heartbeat_timer_.expires_from_now(boost::posix_time::seconds(10)); + heartbeat_timer_.async_wait(boost::bind(&client::start_write, this)); + } + else + { + std::cout << "Error on heartbeat: " << ec.message() << "\n"; + + stop(); + } + } + + void check_deadline() + { + if (stopped_) + return; ++ // Check whether the deadline has passed. We compare the deadline against + // the current time since a new asynchronous operation may have moved the
+ // deadline before this actor had a chance to run. + if (deadline_.expires_at() <= deadline_timer::traits_type::now()) + {+ // The deadline has passed. The socket is closed so that any outstanding
+ // asynchronous operations are cancelled. + socket_.close(); ++ // There is no longer an active deadline. The expiry is set to positive + // infinity so that the actor takes no action until a new deadline is set.
+ deadline_.expires_at(boost::posix_time::pos_infin); + } + + // Put the actor back to sleep. + deadline_.async_wait(boost::bind(&client::check_deadline, this)); + } + +private: + bool stopped_; + tcp::socket socket_; + boost::asio::streambuf input_buffer_; + deadline_timer deadline_; + deadline_timer heartbeat_timer_; +}; + +int main(int argc, char* argv[]) +{ + try + { + if (argc != 3) + { + std::cerr << "Usage: client <host> <port>\n"; + return 1; + } + + boost::asio::io_service io_service; + tcp::resolver r(io_service); + client c(io_service); + + c.start(r.resolve(tcp::resolver::query(argv[1], argv[2]))); + + io_service.run(); + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} ======================================= --- /dev/null+++ /trunk/libs/asio/example/timeouts/blocking_tcp_client.cpp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,250 @@ +// +// blocking_tcp_client.cpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +//+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include <boost/asio/deadline_timer.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/ip/tcp.hpp> +#include <boost/asio/read_until.hpp> +#include <boost/asio/streambuf.hpp> +#include <boost/system/system_error.hpp> +#include <boost/asio/write.hpp> +#include <cstdlib> +#include <iostream> +#include <string> +#include <boost/lambda/bind.hpp> +#include <boost/lambda/lambda.hpp> + +using boost::asio::deadline_timer; +using boost::asio::ip::tcp; +using boost::lambda::bind; +using boost::lambda::var; +using boost::lambda::_1; + +//---------------------------------------------------------------------- + +//+// This class manages socket timeouts by applying the concept of a deadline. +// Each asynchronous operation is given a deadline by which it must complete. +// Deadlines are enforced by an "actor" that persists for the lifetime of the
+// client object: +// +// +----------------+ +// | | +// | check_deadline |<---+ +// | | | +// +----------------+ | async_wait() +// | | +// +---------+ +//+// If the actor determines that the deadline has expired, the socket is closed
+// and any outstanding operations are consequently cancelled. The socket +// operations themselves use boost::lambda function objects as completion +// handlers. For a given socket operation, the client object runs the +// io_service to block thread execution until the actor completes. +// +class client +{ +public: + client() + : socket_(io_service_), + deadline_(io_service_) + {+ // No deadline is required until the first socket operation is started. We + // set the deadline to positive infinity so that the actor takes no action
+ // until a specific deadline is set. + deadline_.expires_at(boost::posix_time::pos_infin); + + // Start the persistent actor that checks for deadline expiry. + check_deadline(); + } + + void connect(const std::string& host, const std::string& service, + boost::posix_time::time_duration timeout) + { + // Resolve the host name and service to a list of endpoints. + tcp::resolver::query query(host, service);+ tcp::resolver::iterator iter = tcp::resolver(io_service_).resolve(query);
++ // Set a deadline for the asynchronous operation. The host name may resolve + // to multiple endpoints, and this function tries to connect to each one in + // turn. Setting the deadline here means it applies to the entire sequence.
+ deadline_.expires_from_now(timeout); + + boost::system::error_code ec; + + for (; iter != tcp::resolver::iterator(); ++iter) + {+ // We may have an open socket from a previous connection attempt. This + // socket cannot be reused, so we must close it before trying to connect
+ // again. + socket_.close(); + + // Set up the variable that receives the result of the asynchronous + // operation. The error code is set to would_block to signal that the + // operation is incomplete. Asio guarantees that its asynchronous + // operations will never fail with would_block, so any other value in + // ec indicates completion. + ec = boost::asio::error::would_block; ++ // Start the asynchronous operation itself. The boost::lambda function + // object is used as a callback and will update the ec variable when the + // operation completes. The blocking_udp_client.cpp example shows how you
+ // can use boost::bind rather than boost::lambda. + socket_.async_connect(iter->endpoint(), var(ec) = _1); + + // Block until the asynchronous operation has completed.+ do io_service_.run_one(); while (ec == boost::asio::error::would_block);
+ + // Determine whether a connection was successfully established. The+ // deadline actor may have had a chance to run and close our socket, even + // though the connect operation notionally succeeded. Therefore we must
+ // check whether the socket is still open before deciding that the we + // were successful. + if (!ec && socket_.is_open()) + return; + } + + throw boost::system::system_error( + ec ? ec : boost::asio::error::host_not_found); + } + + std::string read_line(boost::posix_time::time_duration timeout) + {+ // Set a deadline for the asynchronous operation. Since this function uses
+ // a composed operation (async_read_until), the deadline applies to the + // entire operation, rather than individual reads from the socket. + deadline_.expires_from_now(timeout); + + // Set up the variable that receives the result of the asynchronous + // operation. The error code is set to would_block to signal that the + // operation is incomplete. Asio guarantees that its asynchronous + // operations will never fail with would_block, so any other value in + // ec indicates completion. + boost::system::error_code ec = boost::asio::error::would_block; + + // Start the asynchronous operation itself. The boost::lambda function+ // object is used as a callback and will update the ec variable when the + // operation completes. The blocking_udp_client.cpp example shows how you
+ // can use boost::bind rather than boost::lambda.+ boost::asio::async_read_until(socket_, input_buffer_, '\n', var(ec) = _1);
+ + // Block until the asynchronous operation has completed.+ do io_service_.run_one(); while (ec == boost::asio::error::would_block);
+ + if (ec) + throw boost::system::system_error(ec); + + std::string line; + std::istream is(&input_buffer_); + std::getline(is, line); + return line; + } + + void write_line(const std::string& line, + boost::posix_time::time_duration timeout) + { + std::string data = line + "\n"; ++ // Set a deadline for the asynchronous operation. Since this function uses + // a composed operation (async_write), the deadline applies to the entire
+ // operation, rather than individual writes to the socket. + deadline_.expires_from_now(timeout); + + // Set up the variable that receives the result of the asynchronous + // operation. The error code is set to would_block to signal that the + // operation is incomplete. Asio guarantees that its asynchronous + // operations will never fail with would_block, so any other value in + // ec indicates completion. + boost::system::error_code ec = boost::asio::error::would_block; + + // Start the asynchronous operation itself. The boost::lambda function+ // object is used as a callback and will update the ec variable when the + // operation completes. The blocking_udp_client.cpp example shows how you
+ // can use boost::bind rather than boost::lambda.+ boost::asio::async_write(socket_, boost::asio::buffer(data), var(ec) = _1);
+ + // Block until the asynchronous operation has completed.+ do io_service_.run_one(); while (ec == boost::asio::error::would_block);
+ + if (ec) + throw boost::system::system_error(ec); + } + +private: + void check_deadline() + {+ // Check whether the deadline has passed. We compare the deadline against + // the current time since a new asynchronous operation may have moved the
+ // deadline before this actor had a chance to run. + if (deadline_.expires_at() <= deadline_timer::traits_type::now()) + {+ // The deadline has passed. The socket is closed so that any outstanding
+ // asynchronous operations are cancelled. This allows the blocked + // connect(), read_line() or write_line() functions to return. + socket_.close(); ++ // There is no longer an active deadline. The expiry is set to positive + // infinity so that the actor takes no action until a new deadline is set.
+ deadline_.expires_at(boost::posix_time::pos_infin); + } + + // Put the actor back to sleep. + deadline_.async_wait(bind(&client::check_deadline, this)); + } + + boost::asio::io_service io_service_; + tcp::socket socket_; + deadline_timer deadline_; + boost::asio::streambuf input_buffer_; +}; + +//---------------------------------------------------------------------- + +int main(int argc, char* argv[]) +{ + try + { + if (argc != 4) + { + std::cerr << "Usage: blocking_tcp <host> <port> <message>\n"; + return 1; + } + + client c; + c.connect(argv[1], argv[2], boost::posix_time::seconds(10)); + + boost::posix_time::ptime time_sent = + boost::posix_time::microsec_clock::universal_time(); + + c.write_line(argv[3], boost::posix_time::seconds(10)); + + for (;;) + { + std::string line = c.read_line(boost::posix_time::seconds(10)); + + // Keep going until we get back the line that was sent. + if (line == argv[3]) + break; + } + + boost::posix_time::ptime time_received = + boost::posix_time::microsec_clock::universal_time(); + + std::cout << "Round trip time: "; + std::cout << (time_received - time_sent).total_microseconds(); + std::cout << " microseconds\n"; + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} ======================================= --- /dev/null+++ /trunk/libs/asio/example/timeouts/blocking_udp_client.cpp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,182 @@ +// +// blocking_udp_client.cpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +//+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include <boost/asio/deadline_timer.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/ip/udp.hpp> +#include <cstdlib> +#include <boost/bind.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> +#include <iostream> + +using boost::asio::deadline_timer; +using boost::asio::ip::udp; + +//---------------------------------------------------------------------- + +//+// This class manages socket timeouts by applying the concept of a deadline. +// Each asynchronous operation is given a deadline by which it must complete. +// Deadlines are enforced by an "actor" that persists for the lifetime of the
+// client object: +// +// +----------------+ +// | | +// | check_deadline |<---+ +// | | | +// +----------------+ | async_wait() +// | | +// +---------+ +// +// If the actor determines that the deadline has expired, any outstanding +// socket operations are cancelled. The socket operations themselves are +// implemented as transient actors: +// +// +---------------+ +// | | +// | receive | +// | | +// +---------------+ +// | +// async_- | +----------------+ +// receive() | | | +// +--->| handle_receive | +// | | +// +----------------+ +//+// The client object runs the io_service to block thread execution until the
+// actor completes. +// +class client +{ +public: + client(const udp::endpoint& listen_endpoint) + : socket_(io_service_, listen_endpoint), + deadline_(io_service_) + {+ // No deadline is required until the first socket operation is started. We + // set the deadline to positive infinity so that the actor takes no action
+ // until a specific deadline is set. + deadline_.expires_at(boost::posix_time::pos_infin); + + // Start the persistent actor that checks for deadline expiry. + check_deadline(); + } + + std::size_t receive(const boost::asio::mutable_buffer& buffer,+ boost::posix_time::time_duration timeout, boost::system::error_code& ec)
+ { + // Set a deadline for the asynchronous operation. + deadline_.expires_from_now(timeout); + + // Set up the variables that receive the result of the asynchronous + // operation. The error code is set to would_block to signal that the + // operation is incomplete. Asio guarantees that its asynchronous + // operations will never fail with would_block, so any other value in + // ec indicates completion. + ec = boost::asio::error::would_block; + std::size_t length = 0; + + // Start the asynchronous operation itself. The handle_receive function + // used as a callback will update the ec and length variables. + socket_.async_receive(boost::asio::buffer(buffer), + boost::bind(&client::handle_receive, _1, _2, &ec, &length)); + + // Block until the asynchronous operation has completed.+ do io_service_.run_one(); while (ec == boost::asio::error::would_block);
+ + return length; + } + +private: + void check_deadline() + {+ // Check whether the deadline has passed. We compare the deadline against + // the current time since a new asynchronous operation may have moved the
+ // deadline before this actor had a chance to run. + if (deadline_.expires_at() <= deadline_timer::traits_type::now()) + {+ // The deadline has passed. The outstanding asynchronous operation needs + // to be cancelled so that the blocked receive() function will return.
+ //+ // Please note that cancel() has portability issues on some versions of
+ // Microsoft Windows, and it may be necessary to use close() instead. + // Consult the documentation for cancel() for further information. + socket_.cancel(); ++ // There is no longer an active deadline. The expiry is set to positive + // infinity so that the actor takes no action until a new deadline is set.
+ deadline_.expires_at(boost::posix_time::pos_infin); + } + + // Put the actor back to sleep. + deadline_.async_wait(boost::bind(&client::check_deadline, this)); + } + + static void handle_receive( + const boost::system::error_code& ec, std::size_t length, + boost::system::error_code* out_ec, std::size_t* out_length) + { + *out_ec = ec; + *out_length = length; + } + +private: + boost::asio::io_service io_service_; + udp::socket socket_; + deadline_timer deadline_; +}; + +//---------------------------------------------------------------------- + +int main(int argc, char* argv[]) +{ + try + { + using namespace std; // For atoi. + + if (argc != 3) + {+ std::cerr << "Usage: blocking_udp_timeout <listen_addr> <listen_port>\n";
+ return 1; + } + + udp::endpoint listen_endpoint( + boost::asio::ip::address::from_string(argv[1]), + std::atoi(argv[2])); + + client c(listen_endpoint); + + for (;;) + { + char data[1024]; + boost::system::error_code ec; + std::size_t n = c.receive(boost::asio::buffer(data), + boost::posix_time::seconds(10), ec); + + if (ec) + { + std::cout << "Receive error: " << ec.message() << "\n"; + } + else + { + std::cout << "Received: "; + std::cout.write(data, n); + std::cout << "\n"; + } + } + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} ======================================= --- /dev/null +++ /trunk/libs/asio/example/timeouts/server.cpp Wed Aug 18 08:21:10 2010 @@ -0,0 +1,424 @@ +// +// server.cpp +// ~~~~~~~~~~ +//+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include <algorithm> +#include <cstdlib> +#include <deque> +#include <iostream> +#include <set> +#include <boost/bind.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <boost/asio/deadline_timer.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/ip/tcp.hpp> +#include <boost/asio/ip/udp.hpp> +#include <boost/asio/read_until.hpp> +#include <boost/asio/streambuf.hpp> +#include <boost/asio/write.hpp> + +using boost::asio::deadline_timer; +using boost::asio::ip::tcp; +using boost::asio::ip::udp; + +//---------------------------------------------------------------------- + +class subscriber +{ +public: + virtual ~subscriber() {} + virtual void deliver(const std::string& msg) = 0; +}; + +typedef boost::shared_ptr<subscriber> subscriber_ptr; + +//---------------------------------------------------------------------- + +class channel +{ +public: + void join(subscriber_ptr subscriber) + { + subscribers_.insert(subscriber); + } + + void leave(subscriber_ptr subscriber) + { + subscribers_.erase(subscriber); + } + + void deliver(const std::string& msg) + { + std::for_each(subscribers_.begin(), subscribers_.end(), + boost::bind(&subscriber::deliver, _1, boost::ref(msg))); + } + +private: + std::set<subscriber_ptr> subscribers_; +}; + +//---------------------------------------------------------------------- + +//+// This class manages socket timeouts by applying the concept of a deadline. +// Some asynchronous operations are given deadlines by which they must complete. +// Deadlines are enforced by two "actors" that persist for the lifetime of the
+// session object, one for input and one for output: +// +// +----------------+ +----------------+ +// | | | | +// | check_deadline |<---+ | check_deadline |<---++// | | | async_wait() | | | async_wait() +// +----------------+ | on input +----------------+ | on output +// | | deadline | | deadline
+// +---------+ +---------+ +// +// If either deadline actor determines that the corresponding deadline has+// expired, the socket is closed and any outstanding operations are cancelled.
+//+// The input actor reads messages from the socket, where messages are delimited
+// by the newline character: +// +// +------------+ +// | | +// | start_read |<---+ +// | | | +// +------------+ | +// | | +// async_- | +-------------+ +// read_- | | | +// until() +--->| handle_read | +// | | +// +-------------+ +//+// The deadline for receiving a complete message is 30 seconds. If a non-empty +// message is received, it is delivered to all subscribers. If a heartbeat (a +// message that consists of a single newline character) is received, a heartbeat +// is enqueued for the client, provided there are no other messages waiting to
+// be sent. +// +// The output actor is responsible for sending messages to the client: +// +// +--------------+ +// | |<---------------------+ +// | await_output | | +// | |<---+ | +// +--------------+ | | +// | | | async_wait() | +// | +--------+ | +// V | +// +-------------+ +--------------+ +// | | async_write() | | +// | start_write |-------------->| handle_write | +// | | | | +// +-------------+ +--------------+ +//+// The output actor first waits for an output message to be enqueued. It does +// this by using a deadline_timer as an asynchronous condition variable. The
+// deadline_timer will be signalled whenever the output queue is non-empty. +// +// Once a message is available, it is sent to the client. The deadline for+// sending a complete message is 30 seconds. After the message is successfully +// sent, the output actor again waits for the output queue to become non-empty.
+// +class tcp_session + : public subscriber, + public boost::enable_shared_from_this<tcp_session> +{ +public: + tcp_session(boost::asio::io_service& io_service, channel& ch) + : channel_(ch), + socket_(io_service), + input_deadline_(io_service), + non_empty_output_queue_(io_service), + output_deadline_(io_service) + { + input_deadline_.expires_at(boost::posix_time::pos_infin); + output_deadline_.expires_at(boost::posix_time::pos_infin); ++ // The non_empty_output_queue_ deadline_timer is set to pos_infin whenever
+ // the output queue is empty. This ensures that the output actor stays + // asleep until a message is put into the queue. + non_empty_output_queue_.expires_at(boost::posix_time::pos_infin); + } + + tcp::socket& socket() + { + return socket_; + } + + // Called by the server object to initiate the four actors. + void start() + { + channel_.join(shared_from_this()); + + start_read(); + + input_deadline_.async_wait( + boost::bind(&tcp_session::check_deadline, + shared_from_this(), &input_deadline_)); + + await_output(); + + output_deadline_.async_wait( + boost::bind(&tcp_session::check_deadline, + shared_from_this(), &output_deadline_)); + } + +private: + void stop() + { + channel_.leave(shared_from_this()); + + socket_.close(); + input_deadline_.cancel(); + non_empty_output_queue_.cancel(); + output_deadline_.cancel(); + } + + bool stopped() const + { + return !socket_.is_open(); + } + + void deliver(const std::string& msg) + { + output_queue_.push_back(msg + "\n"); + + // Signal that the output queue contains messages. Modifying the expiry + // will wake the output actor, if it is waiting on the timer. + non_empty_output_queue_.expires_at(boost::posix_time::neg_infin); + } + + void start_read() + { + // Set a deadline for the read operation. + input_deadline_.expires_from_now(boost::posix_time::seconds(30)); + + // Start an asynchronous operation to read a newline-delimited message. + boost::asio::async_read_until(socket_, input_buffer_, '\n', + boost::bind(&tcp_session::handle_read, shared_from_this(), _1)); + } + + void handle_read(const boost::system::error_code& ec) + { + if (stopped()) + return; + + if (!ec) + { + // Extract the newline-delimited message from the buffer. + std::string msg; + std::istream is(&input_buffer_); + std::getline(is, msg); + + if (!msg.empty()) + { + channel_.deliver(msg); + } + else + {+ // We received a heartbeat message from the client. If there's nothing + // else being sent or ready to be sent, send a heartbeat right back.
+ if (output_queue_.empty()) + { + output_queue_.push_back("\n"); + + // Signal that the output queue contains messages. Modifying the+ // expiry will wake the output actor, if it is waiting on the timer.
+ non_empty_output_queue_.expires_at(boost::posix_time::neg_infin); + } + } + + start_read(); + } + else + { + stop(); + } + } + + void await_output() + { + if (stopped()) + return; + + if (output_queue_.empty()) + { + // There are no messages that are ready to be sent. The actor goes to + // sleep by waiting on the non_empty_output_queue_ timer. When a new+ // message is added, the timer will be modified and the actor will wake.
+ non_empty_output_queue_.expires_at(boost::posix_time::pos_infin); + non_empty_output_queue_.async_wait( + boost::bind(&tcp_session::await_output, shared_from_this())); + } + else + { + start_write(); + } + } + + void start_write() + { + // Set a deadline for the write operation. + output_deadline_.expires_from_now(boost::posix_time::seconds(30)); + + // Start an asynchronous operation to send a message. + boost::asio::async_write(socket_, + boost::asio::buffer(output_queue_.front()), + boost::bind(&tcp_session::handle_write, shared_from_this(), _1)); + } + + void handle_write(const boost::system::error_code& ec) + { + if (stopped()) + return; + + if (!ec) + { + output_queue_.pop_front(); + + await_output(); + } + else + { + stop(); + } + } + + void check_deadline(deadline_timer* deadline) + { + if (stopped()) + return; ++ // Check whether the deadline has passed. We compare the deadline against + // the current time since a new asynchronous operation may have moved the
+ // deadline before this actor had a chance to run. + if (deadline->expires_at() <= deadline_timer::traits_type::now()) + { + // The deadline has passed. Stop the session. The other actors will + // terminate as soon as possible. + stop(); + } + else + { + // Put the actor back to sleep. + deadline->async_wait( + boost::bind(&tcp_session::check_deadline, + shared_from_this(), deadline)); + } + } + + channel& channel_; + tcp::socket socket_; + boost::asio::streambuf input_buffer_; + deadline_timer input_deadline_; + std::deque<std::string> output_queue_; + deadline_timer non_empty_output_queue_; + deadline_timer output_deadline_; +}; + +typedef boost::shared_ptr<tcp_session> tcp_session_ptr; + +//---------------------------------------------------------------------- + +class udp_broadcaster + : public subscriber +{ +public: + udp_broadcaster(boost::asio::io_service& io_service, + const udp::endpoint& broadcast_endpoint) + : socket_(io_service) + { + socket_.connect(broadcast_endpoint); + } + +private: + void deliver(const std::string& msg) + { + boost::system::error_code ignored_ec; + socket_.send(boost::asio::buffer(msg), 0, ignored_ec); + } + + udp::socket socket_; +}; + +//---------------------------------------------------------------------- + +class server +{ +public: + server(boost::asio::io_service& io_service, + const tcp::endpoint& listen_endpoint, + const udp::endpoint& broadcast_endpoint) + : io_service_(io_service), + acceptor_(io_service, listen_endpoint) + {+ subscriber_ptr bc(new udp_broadcaster(io_service_, broadcast_endpoint));
+ channel_.join(bc); + + tcp_session_ptr new_session(new tcp_session(io_service_, channel_)); + + acceptor_.async_accept(new_session->socket(), + boost::bind(&server::handle_accept, this, new_session, _1)); + } + + void handle_accept(tcp_session_ptr session, + const boost::system::error_code& ec) + { + if (!ec) + { + session->start(); + + tcp_session_ptr new_session(new tcp_session(io_service_, channel_)); + + acceptor_.async_accept(new_session->socket(), + boost::bind(&server::handle_accept, this, new_session, _1)); + } + } + +private: + boost::asio::io_service& io_service_; + tcp::acceptor acceptor_; + channel channel_; +}; + +//---------------------------------------------------------------------- + +int main(int argc, char* argv[]) +{ + try + { + using namespace std; // For atoi. + + if (argc != 4) + {+ std::cerr << "Usage: server <listen_port> <bcast_address> <bcast_port>\n";
+ return 1; + } + + boost::asio::io_service io_service; + + tcp::endpoint listen_endpoint(tcp::v4(), atoi(argv[1])); + + udp::endpoint broadcast_endpoint( + boost::asio::ip::address::from_string(argv[2]), atoi(argv[3])); + + server s(io_service, listen_endpoint, broadcast_endpoint); + + io_service.run(); + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} ======================================= --- /dev/null+++ /trunk/libs/config/test/boost_no_0x_hdr_typeindex.ipp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,25 @@ +// (C) Copyright Beman Dawes 2009 + +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/config for more information. + +// MACRO: BOOST_NO_0X_HDR_TYPEINDEX +// TITLE: C++0x header <typeindex> unavailable+// DESCRIPTION: The standard library does not supply C++0x header <typeindex>
+ +#include <typeindex> + +namespace boost_no_0x_hdr_typeindex { + +int test() +{ + std::type_index t1 = typeid(int); + std::type_index t2 = typeid(double); + std::hash<std::type_index> h; + return (t1 != t2) && (h(t1) != h(t2)) ? 0 : 1; +} + +} ======================================= --- /dev/null+++ /trunk/libs/config/test/boost_no_com_value_init.ipp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,1016 @@ +// (C) Copyright Niels Dekker 2010. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/config for most recent version. + +// MACRO: BOOST_NO_COMPLETE_VALUE_INITIALIZATION +// TITLE: No complete value-initialization+// DESCRIPTION: The C++ compiler does not to have implemented value-initialization completely. +// See also boost/libs/utility/value_init.htm#compiler_issues
+ +#include <iostream> + +// This test checks various forms of value-initialization: +// - doing subobject initialization inside a constructor +// - creating a temporary object by T() +// - creating a heap object by doing new T()+// It checks various DefaultConstructible types, including fundamental types, +// enum, union, pointer types, array types, POD and non-POD class types. For +// each type of object, a helper function is_value_initialized(const T&) tells
+// whether the object is value-initialized. +// +// Note: It appeared insufficient to just check a single POD and a single+// non-POD class type, because some compilers correctly value-initialize some
+// POD and some non-POD objects, while failing to value-initialize others. +//+// The test returns the number of encountered value-initialization failures.
+ +namespace boost_no_complete_value_initialization +{ + enum enum_type { negative_number = -1, magic_number = 42 }; + + class incomplete_class; + + typedef int (*function_ptr_type)(int); + typedef int (incomplete_class::*member_function_ptr_type)(int); + + // A POD struct. + struct pod_struct + { + enum_type e; + bool b; + char c; + unsigned char uc; + short s; + int i; + unsigned u; + long l; + float f; + double d; + long double ld; + void* p; + }; + + bool is_value_initialized(const pod_struct& arg) + { + return + arg.b == 0 && + arg.e == 0 && + arg.c == 0 && + arg.uc == 0 && + arg.s == 0 && + arg.i == 0 && + arg.u == 0 && + arg.l == 0 && + arg.f == 0 && + arg.d == 0 && + arg.p == 0; + } + + // A POD struct derived from another POD struct. + struct derived_pod_struct: pod_struct + { + int derived_data; + }; + + bool is_value_initialized(const derived_pod_struct& arg) + { + const pod_struct& base_subobject = arg; + return arg.derived_data == 0 && is_value_initialized(base_subobject); + } + + + struct empty_struct + { + }; + + + // A POD aggregate struct derived from an empty struct. + // Similar to struct Foo1 from Microsoft Visual C++ bug report 484295, + // "VC++ does not value-initialize members of derived classes without + // user-declared constructor", reported in 2009 by Sylvester Hesp: + // https://connect.microsoft.com/VisualStudio/feedback/details/484295 + struct derived_struct: empty_struct + { + int data; + }; + + bool is_value_initialized(const derived_struct& arg) + { + return arg.data == 0; + } + + + // A struct, having a bit-field. + struct bit_field_struct + { + bool b : 1; + char c : 7; + unsigned u: 8 * sizeof(unsigned) - 1; + }; + + bool is_value_initialized(const bit_field_struct& arg) + { + return arg.b == false && arg.c == '\0'&& arg.u == 0U; + } + + // A struct, having a function pointer. + struct function_ptr_struct + { + function_ptr_type data; + }; + + bool is_value_initialized(const function_ptr_struct& arg) + { + return arg.data == 0; + } + + // A struct, having a member function pointer. + struct member_function_ptr_struct + { + member_function_ptr_type data; + }; + + bool is_value_initialized(const member_function_ptr_struct& arg) + { + return arg.data == 0; + } + + struct int_pair_struct + { + int first; + int second; + }; + + typedef int int_pair_struct::*ptr_to_member_type; + + struct ptr_to_member_struct + { + ptr_to_member_type data; + }; + + bool is_value_initialized(const ptr_to_member_struct& arg) + { + return arg.data == 0; + } ++ // A struct, having an int. Equivalent to the struct TData, from CodeGear bug + // report 51854, "Value-initialization: POD struct should be zero-initialized",
+ // reported by me (Niels Dekker, LKEB) in 2007: + // http://qc.embarcadero.com/wc/qcmain.aspx?d=51854 + struct int_struct + { + int data; + }; + + bool is_value_initialized(const int_struct& arg) + { + return arg.data == 0; + } + + + // A struct, having an int_struct. + struct int_struct_holder + { + int_struct data; + }; + + bool is_value_initialized(const int_struct_holder& arg) + { + return is_value_initialized(arg.data); + } + + + // A struct derived from int_struct. + struct derived_int_struct: int_struct + { + }; + + bool is_value_initialized(const derived_int_struct& arg) + { + return arg.data == 0; + } + + + struct char_array_struct + { + char data[42]; + }; + + bool is_value_initialized(const char_array_struct& arg) + { + for ( unsigned i = 0; i < sizeof(arg.data); ++i) + { + if ( arg.data[i] != 0 ) + { + return false; + } + } + return true; + } + + + class private_int_holder + { + private: + int m_data; + + friend bool is_value_initialized(const private_int_holder& arg) + { + return arg.m_data == 0; + } + }; + + + // Equivalent to the Stats class from GCC Bug 33916,+ // "Default constructor fails to initialize array members", reported in 2007 by + // Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
+ class private_int_array_pair + { + friend bool is_value_initialized(const private_int_array_pair& arg); + private: + int first[12]; + int second[12]; + }; + + bool is_value_initialized(const private_int_array_pair& arg) + { + for ( unsigned i = 0; i < 12; ++i) + { + if ( (arg.first[i] != 0) || (arg.second[i] != 0) ) + { + return false; + } + } + return true; + } + + + union pod_struct_and_int_union + { + pod_struct first; + int second; + }; + + bool is_value_initialized(const pod_struct_and_int_union& arg) + { + // When a union is zero-initialized, its first non-static + // named data member is zero-initialized ([dcl.init]). + return is_value_initialized(arg.first); + } + + + union int_and_pod_struct_union + { + int first; + pod_struct second; + }; + + bool is_value_initialized(const int_and_pod_struct_union& arg) + { + return arg.first == 0; + } + + + // A class that holds a "magic" enum value. + // Note: This is not a POD class, because it has a user-defined + // default constructor. + class enum_holder + { + enum_type m_enum; + public: + + enum_holder() + : + m_enum(magic_number) + { + } + + bool is_value_initialized() const + { + return m_enum == magic_number; + } + }; + + bool is_value_initialized(const enum_holder& arg) + { + return arg.is_value_initialized(); + } + + + // An aggregate struct of a non-POD class and an int. + // Similar to struct A from Microsoft Visual C++ bug report 100744, + // "Value-initialization in new-expression", reported in 2005 by + // Pavel Kuznetsov (MetaCommunications Engineering): + // https://connect.microsoft.com/VisualStudio/feedback/details/100744 + struct enum_holder_and_int + { + enum_holder e; + int i; + }; + + bool is_value_initialized(const enum_holder_and_int& arg) + { + return arg.e.is_value_initialized() && arg.i == 0; + } + + class user_defined_copy_constructor_holder + { + public: + int data; + + user_defined_copy_constructor_holder() + : + data(0) + { + } ++ user_defined_copy_constructor_holder(const user_defined_copy_constructor_holder& arg)
+ : + data(arg.data) + { + } + }; + + // An aggregate struct that has a data member which has a user-defined + // copy constructor and a data member of a scalar type. + // Similar to struct B from Microsoft Visual C++ bug report 499606, + // "Presence of copy constructor breaks member class initialization", + // reported in 2009 by Alex Vakulenko: + // https://connect.microsoft.com/VisualStudio/feedback/details/499606 + struct user_defined_copy_constructor_holder_and_int + { + user_defined_copy_constructor_holder first; + int second; + }; ++ bool is_value_initialized(const user_defined_copy_constructor_holder_and_int& arg)
+ { + return arg.first.data == 0 && arg.second == 0; + } + + + // An class that has a private and a protected int data member. + class private_and_protected_int + { + private: + int private_int; + protected: + int protected_int; + public: + friend bool is_value_initialized(const private_and_protected_int& arg) + { + return arg.private_int == 0 && arg.protected_int == 0; + } + }; + + + class user_defined_destructor_holder + { + public: + int i; + ~user_defined_destructor_holder() + { + } + }; + + bool is_value_initialized(const user_defined_destructor_holder& arg) + { + return arg.i == 0; + } + + + class virtual_destructor_holder + { + public: + int i; + virtual ~virtual_destructor_holder() + { + } + }; + + bool is_value_initialized(const virtual_destructor_holder& arg) + { + return arg.i == 0; + } + + + // A class that is not a POD type. + class non_pod_class + { + private: + enum_holder m_enum_holder; + + public: + int i; + + virtual bool is_value_initialized() const + { + return m_enum_holder.is_value_initialized() && i == 0; + } + + virtual ~non_pod_class() {} + }; + + bool is_value_initialized(const non_pod_class& arg) + { + return arg.is_value_initialized(); + } + + + typedef char _2d_char_array_type[3][4]; + + bool is_value_initialized(const _2d_char_array_type& arg) + { + for(unsigned i = 0; i < sizeof(_2d_char_array_type); ++i) + { + if ((*arg)[i] != 0) + { + return false; + } + } + return true; + } + + typedef char _3d_char_array_type[5][6][7]; + + bool is_value_initialized(const _3d_char_array_type& arg) + { + for(unsigned i = 0; i < sizeof(_3d_char_array_type); ++i) + { + if ((**arg)[i] != 0) + { + return false; + } + } + return true; + } + + + + // Tells whether an object of a scalar type T is value-initialized. + template <class T> + bool is_value_initialized(const T& arg) + { + return arg == 0; + } + + + // Wraps a heap object that it has allocated by doing new T(). + template <class T> + class heap_object_wrapper + { + private: + T* const m_ptr; + + // The following function is intentionally left unimplemented + // (as if deleted, "= delete", in C++0x): + void operator=(heap_object_wrapper); + + public: + heap_object_wrapper() + : + m_ptr(new T()) + { + } + + ~heap_object_wrapper() + { + delete m_ptr; + } + + // The copy-constructor is intentionally left unimplemented. + heap_object_wrapper(const heap_object_wrapper&); + + bool is_wrapped_object_value_initialized() const + { + return (m_ptr != 0) && is_value_initialized(*m_ptr); + } + }; + + template <class T> + bool is_value_initialized(const heap_object_wrapper<T>& arg) + { + return arg.is_wrapped_object_value_initialized(); + } + ++ // Returns zero when the specified object is value-initializated, and one otherwise. + // Prints a message to standard output if the value-initialization has failed.
+ template <class T>+ unsigned failed_to_value_initialized(const T& object, const char *const object_name)
+ { + if ( is_value_initialized(object) ) + { + return 0u; + } + else + {+ std::cout << "Note: Failed to value-initialize " << object_name << '.' << std::endl;
+ return 1u; + } + } ++// A macro that passed both the name and the value of the specified object to
+// the function above here.+#define FAILED_TO_VALUE_INITIALIZE(value) failed_to_value_initialized(value, #value)
+ + + // value_initializer initializes each of its data members by means + // of an empty set of parentheses, and allows checking whether + // each of them is indeed value-initialized, as specified by + // the C++ Standard ([dcl.init]). + //+ // Note: its base class, int_struct, is there to try to reproduce GCC Bug 30111, + // "Value-initialization of POD base class doesn't initialize members", reported + // by Jonathan Wakely in 2006: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111
+ class value_initializer: private int_struct + { + private: + enum_holder m_enum_holder; + enum_holder m_enum_holder_array[2]; + enum_type m_enum; + enum_type m_enum_array[2]; + bool m_bool; + bool m_bool_array[2]; + char m_char; + char m_char_array[2]; + _2d_char_array_type m_2d_char_array; + _3d_char_array_type m_3d_char_array; + unsigned char m_unsigned_char; + unsigned char m_unsigned_char_array[2]; + short m_short; + short m_short_array[2]; + int m_int; + int m_int_array[2]; + unsigned m_unsigned; + unsigned m_unsigned_array[2]; + long m_long; + long m_long_array[2]; + float m_float; + float m_float_array[2]; + double m_double; + double m_double_array[2]; + long double m_long_double; + long double m_long_double_array[2]; + void* m_void_ptr; + void* m_void_ptr_array[2]; + function_ptr_type m_function_ptr; + function_ptr_type m_function_ptr_array[2]; + function_ptr_struct m_function_ptr_struct; + function_ptr_struct m_function_ptr_struct_array[2]; + member_function_ptr_type m_member_function_ptr; + member_function_ptr_type m_member_function_ptr_array[2]; + member_function_ptr_struct m_member_function_ptr_struct; + member_function_ptr_struct m_member_function_ptr_struct_array[2]; + ptr_to_member_type m_ptr_to_member; + ptr_to_member_type m_ptr_to_member_array[2]; + ptr_to_member_struct m_ptr_to_member_struct; + ptr_to_member_struct m_ptr_to_member_struct_array[2]; + bit_field_struct m_bit_field_struct; + bit_field_struct m_bit_field_struct_array[2]; + int_struct m_int_struct; + int_struct m_int_struct_array[2]; + int_struct m_int_struct_holder; + int_struct m_int_struct_holder_array[2]; + pod_struct m_pod_struct; + pod_struct m_pod_struct_array[2]; + derived_pod_struct m_derived_pod_struct; + derived_pod_struct m_derived_pod_struct_array[2]; + derived_struct m_derived_struct; + derived_struct m_derived_struct_array[2]; + derived_int_struct m_derived_int_struct; + derived_int_struct m_derived_int_struct_array[2]; + private_int_holder m_private_int_holder; + private_int_holder m_private_int_holder_array[2]; + char_array_struct m_char_array_struct; + char_array_struct m_char_array_struct_array[2]; + private_int_array_pair m_private_int_array_pair; + private_int_array_pair m_private_int_array_pair_array[2]; + enum_holder_and_int m_enum_holder_and_int; + enum_holder_and_int m_enum_holder_and_int_array[2]; + private_and_protected_int m_private_and_protected_int; + private_and_protected_int m_private_and_protected_int_array[2];+ user_defined_copy_constructor_holder_and_int m_user_defined_copy_constructor_holder_and_int; + user_defined_copy_constructor_holder_and_int m_user_defined_copy_constructor_holder_and_int_array[2];
+ user_defined_destructor_holder m_user_defined_destructor_holder;+ user_defined_destructor_holder m_user_defined_destructor_holder_array[2];
+ virtual_destructor_holder m_virtual_destructor_holder; + virtual_destructor_holder m_virtual_destructor_holder_array[2]; + non_pod_class m_non_pod; + non_pod_class m_non_pod_array[2]; + pod_struct_and_int_union m_pod_struct_and_int_union; + pod_struct_and_int_union m_pod_struct_and_int_union_array[2]; + int_and_pod_struct_union m_int_and_pod_struct_union; + int_and_pod_struct_union m_int_and_pod_struct_union_array[2]; + + public:+ // Default constructor. Tries to value-initialize its base subobject and all
+ // of its data.members. + value_initializer() + :+ // Note: CodeGear/Borland may produce a warning, W8039, for each data member + // whose type is an array type, saying "Constructor initializer list ignored". + // If it does, it probably won't value-initialize those arrays, as reported + // by me (Niels Dekker, LKEB) in 2010, report 83751, "Value-initialization:
+ // arrays should have each element value-initialized", + // http://qc.embarcadero.com/wc/qcmain.aspx?d=83751+ // On the other hand, Microsoft Visual C++ may produce warnings of type C4351, + // saying "new behavior: elements of array '...' will be default initialized",
+ // which is actually the right behavior! + int_struct(), + m_enum_holder(), + m_enum_holder_array(), + m_enum(), + m_enum_array(), + m_bool(), + m_bool_array(), + m_char(), + m_char_array(), + m_2d_char_array(), + m_3d_char_array(), + m_unsigned_char(), + m_unsigned_char_array(), + m_short(), + m_short_array(), + m_int(), + m_int_array(), + m_unsigned(), + m_unsigned_array(), + m_long(), + m_long_array(), + m_float(), + m_float_array(), + m_double(), + m_double_array(), + m_long_double(), + m_long_double_array(), + m_void_ptr(), + m_void_ptr_array(), + m_function_ptr(), + m_function_ptr_array(), + m_function_ptr_struct(), + m_function_ptr_struct_array(), + m_member_function_ptr(), + m_member_function_ptr_array(), + m_member_function_ptr_struct(), + m_member_function_ptr_struct_array(), + m_ptr_to_member(), + m_ptr_to_member_array(), + m_ptr_to_member_struct(), + m_ptr_to_member_struct_array(), + m_bit_field_struct(), + m_bit_field_struct_array(), + m_int_struct(), + m_int_struct_array(), + m_int_struct_holder(), + m_int_struct_holder_array(), + m_pod_struct(), + m_pod_struct_array(), + m_derived_pod_struct(), + m_derived_pod_struct_array(), + m_derived_struct(), + m_derived_struct_array(), + m_derived_int_struct(), + m_derived_int_struct_array(), + m_private_int_holder(), + m_private_int_holder_array(), + m_char_array_struct(), + m_char_array_struct_array(), + m_private_int_array_pair(), + m_private_int_array_pair_array(), + m_enum_holder_and_int(), + m_enum_holder_and_int_array(), + m_private_and_protected_int(), + m_private_and_protected_int_array(), + m_user_defined_copy_constructor_holder_and_int(), + m_user_defined_copy_constructor_holder_and_int_array(), + m_user_defined_destructor_holder(), + m_user_defined_destructor_holder_array(), + m_virtual_destructor_holder(), + m_virtual_destructor_holder_array(), + m_non_pod(), + m_non_pod_array(), + m_pod_struct_and_int_union(), + m_pod_struct_and_int_union_array(), + m_int_and_pod_struct_union(), + m_int_and_pod_struct_union_array() + { + } + + // Returns the number of failures. + unsigned check_value_initialization_of_subobjects() const + { + const unsigned num_failures = + FAILED_TO_VALUE_INITIALIZE(int_struct::data) + + FAILED_TO_VALUE_INITIALIZE(m_enum_holder) + + FAILED_TO_VALUE_INITIALIZE(m_enum_holder_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_enum_holder_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_enum) + + FAILED_TO_VALUE_INITIALIZE(m_enum_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_enum_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_bool) + + FAILED_TO_VALUE_INITIALIZE(m_bool_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_bool_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_char) + + FAILED_TO_VALUE_INITIALIZE(m_char_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_char_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_2d_char_array) + + FAILED_TO_VALUE_INITIALIZE(m_3d_char_array) + + FAILED_TO_VALUE_INITIALIZE(m_unsigned_char) + + FAILED_TO_VALUE_INITIALIZE(m_unsigned_char_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_unsigned_char_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_short) + + FAILED_TO_VALUE_INITIALIZE(m_short_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_short_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_int) + + FAILED_TO_VALUE_INITIALIZE(m_int_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_int_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_unsigned) + + FAILED_TO_VALUE_INITIALIZE(m_unsigned_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_unsigned_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_long) + + FAILED_TO_VALUE_INITIALIZE(m_long_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_long_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_float) + + FAILED_TO_VALUE_INITIALIZE(m_float_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_float_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_double) + + FAILED_TO_VALUE_INITIALIZE(m_double_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_double_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_long_double) + + FAILED_TO_VALUE_INITIALIZE(m_long_double_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_long_double_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_void_ptr) + + FAILED_TO_VALUE_INITIALIZE(m_void_ptr_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_void_ptr_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_function_ptr) + + FAILED_TO_VALUE_INITIALIZE(m_function_ptr_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_function_ptr_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_function_ptr_struct) + + FAILED_TO_VALUE_INITIALIZE(m_function_ptr_struct_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_function_ptr_struct_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_member_function_ptr) + + FAILED_TO_VALUE_INITIALIZE(m_member_function_ptr_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_member_function_ptr_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_member_function_ptr_struct) + + FAILED_TO_VALUE_INITIALIZE(m_member_function_ptr_struct_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_member_function_ptr_struct_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_ptr_to_member) + + FAILED_TO_VALUE_INITIALIZE(m_ptr_to_member_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_ptr_to_member_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_ptr_to_member_struct) + + FAILED_TO_VALUE_INITIALIZE(m_ptr_to_member_struct_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_ptr_to_member_struct_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_bit_field_struct) + + FAILED_TO_VALUE_INITIALIZE(m_bit_field_struct_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_bit_field_struct_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_int_struct) + + FAILED_TO_VALUE_INITIALIZE(m_int_struct_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_int_struct_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_int_struct_holder) + + FAILED_TO_VALUE_INITIALIZE(m_int_struct_holder_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_int_struct_holder_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_pod_struct) + + FAILED_TO_VALUE_INITIALIZE(m_pod_struct_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_pod_struct_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_derived_pod_struct) + + FAILED_TO_VALUE_INITIALIZE(m_derived_pod_struct_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_derived_pod_struct_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_derived_struct) + + FAILED_TO_VALUE_INITIALIZE(m_derived_struct_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_derived_struct_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_derived_int_struct) + + FAILED_TO_VALUE_INITIALIZE(m_derived_int_struct_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_derived_int_struct_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_private_int_holder) + + FAILED_TO_VALUE_INITIALIZE(m_private_int_holder_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_private_int_holder_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_char_array_struct) + + FAILED_TO_VALUE_INITIALIZE(m_char_array_struct_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_char_array_struct_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_private_int_array_pair) + + FAILED_TO_VALUE_INITIALIZE(m_private_int_array_pair_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_private_int_array_pair_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_enum_holder_and_int) + + FAILED_TO_VALUE_INITIALIZE(m_enum_holder_and_int_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_enum_holder_and_int_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_private_and_protected_int) + + FAILED_TO_VALUE_INITIALIZE(m_private_and_protected_int_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_private_and_protected_int_array[1]) ++ FAILED_TO_VALUE_INITIALIZE(m_user_defined_copy_constructor_holder_and_int) + + FAILED_TO_VALUE_INITIALIZE(m_user_defined_copy_constructor_holder_and_int_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_user_defined_copy_constructor_holder_and_int_array[1]) +
+ FAILED_TO_VALUE_INITIALIZE(m_user_defined_destructor_holder) ++ FAILED_TO_VALUE_INITIALIZE(m_user_defined_destructor_holder_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_user_defined_destructor_holder_array[1]) +
+ FAILED_TO_VALUE_INITIALIZE(m_virtual_destructor_holder) + + FAILED_TO_VALUE_INITIALIZE(m_virtual_destructor_holder_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_virtual_destructor_holder_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_non_pod) + + FAILED_TO_VALUE_INITIALIZE(m_non_pod_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_non_pod_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_pod_struct_and_int_union) + + FAILED_TO_VALUE_INITIALIZE(m_pod_struct_and_int_union_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_pod_struct_and_int_union_array[1]) + + FAILED_TO_VALUE_INITIALIZE(m_int_and_pod_struct_union) + + FAILED_TO_VALUE_INITIALIZE(m_int_and_pod_struct_union_array[0]) + + FAILED_TO_VALUE_INITIALIZE(m_int_and_pod_struct_union_array[1]); + return num_failures; + } + }; + + // Checks value-initialization of a number of small temporary objects. + // Returns the number of failures. + unsigned check_value_initialization_of_temporaries() + { + typedef long double long_double_type; + typedef unsigned char unsigned_char_type; + typedef void* void_ptr_type; + + const unsigned num_failures = + FAILED_TO_VALUE_INITIALIZE(enum_holder()) + + FAILED_TO_VALUE_INITIALIZE(enum_type()) + + FAILED_TO_VALUE_INITIALIZE(bool()) + + FAILED_TO_VALUE_INITIALIZE(char()) + + FAILED_TO_VALUE_INITIALIZE(unsigned_char_type()) + + FAILED_TO_VALUE_INITIALIZE(short()) + + FAILED_TO_VALUE_INITIALIZE(int()) + + FAILED_TO_VALUE_INITIALIZE(unsigned()) + + FAILED_TO_VALUE_INITIALIZE(long()) + + FAILED_TO_VALUE_INITIALIZE(float()) + + FAILED_TO_VALUE_INITIALIZE(double()) + + FAILED_TO_VALUE_INITIALIZE(long_double_type()) + + FAILED_TO_VALUE_INITIALIZE(void_ptr_type()) + + FAILED_TO_VALUE_INITIALIZE(bit_field_struct()) + + FAILED_TO_VALUE_INITIALIZE(function_ptr_type()) + + FAILED_TO_VALUE_INITIALIZE(function_ptr_struct()) + + FAILED_TO_VALUE_INITIALIZE(member_function_ptr_type()) + + FAILED_TO_VALUE_INITIALIZE(member_function_ptr_struct()) + + FAILED_TO_VALUE_INITIALIZE(ptr_to_member_type()) + + FAILED_TO_VALUE_INITIALIZE(ptr_to_member_struct()) + + FAILED_TO_VALUE_INITIALIZE(int_struct()) + + FAILED_TO_VALUE_INITIALIZE(int_struct_holder()) + + FAILED_TO_VALUE_INITIALIZE(pod_struct()) + + FAILED_TO_VALUE_INITIALIZE(derived_pod_struct()) + + FAILED_TO_VALUE_INITIALIZE(derived_struct()) + + FAILED_TO_VALUE_INITIALIZE(derived_int_struct()) + + FAILED_TO_VALUE_INITIALIZE(private_int_holder()) + + FAILED_TO_VALUE_INITIALIZE(char_array_struct()) + + FAILED_TO_VALUE_INITIALIZE(private_int_array_pair()) ++ // IBM's XL V10.1.0.0 may fail to value-initialize a temporary of a non-POD + // type like enum_holder_and_int, virtual_destructor_holder, or non_pod_class, + // as appeared at the Boost Config/trunk regression page in April 2010. + // Michael Wong (IBM Canada Ltd) confirmed the issue to me (Niels Dekker, LKEB),
+ // and gave it high priority. + FAILED_TO_VALUE_INITIALIZE(enum_holder_and_int()) + + FAILED_TO_VALUE_INITIALIZE(private_and_protected_int()) ++ FAILED_TO_VALUE_INITIALIZE(user_defined_copy_constructor_holder_and_int()) +
+ // The following line, doing user_defined_destructor_holder(), causes + // a compilation error on Embarcadero 2010 (Borland/CodeGear 6.21), + // as reported by me (Niels Dekker, LKEB) in 2010, bug report 83851,+ // "Value-initialized temporary triggers internal backend error C1798",
+ // http://qc.embarcadero.com/wc/qcmain.aspx?d=83851 + FAILED_TO_VALUE_INITIALIZE(user_defined_destructor_holder()) + + FAILED_TO_VALUE_INITIALIZE(virtual_destructor_holder()) + + FAILED_TO_VALUE_INITIALIZE(non_pod_class()) + + FAILED_TO_VALUE_INITIALIZE(pod_struct_and_int_union()) + + FAILED_TO_VALUE_INITIALIZE(int_and_pod_struct_union()); + return num_failures; + } + + // Checks value-initialization of small heap objects. + // Returns the number of failures. + unsigned check_value_initialization_of_heap_objects() + { + const unsigned num_failures = + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<enum_holder>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<enum_type>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<bool>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<char>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<unsigned char>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<short>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<int>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<unsigned>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<long>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<float>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<double>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<long double>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<void*>() ) ++ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<function_ptr_type>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<function_ptr_struct>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<member_function_ptr_type>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<member_function_ptr_struct>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<ptr_to_member_type>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<ptr_to_member_struct>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<bit_field_struct>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<int_struct>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<int_struct>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<pod_struct>() ) ++ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<derived_pod_struct>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<derived_struct>() ) ++ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<derived_int_struct>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<char_array_struct>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<private_int_holder>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<private_int_array_pair>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<enum_holder_and_int>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<private_and_protected_int>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<user_defined_copy_constructor_holder_and_int>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<user_defined_destructor_holder>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<virtual_destructor_holder>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<non_pod_class>() ) ++ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<pod_struct_and_int_union>() ) + + FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<int_and_pod_struct_union>() );
+ return num_failures; + } + + // Equivalent to the dirty_stack() function from GCC Bug 33916,+ // "Default constructor fails to initialize array members", reported in 2007 by + // Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
+ void dirty_stack() + { + unsigned char array_on_stack[sizeof(value_initializer) + 256]; + for (unsigned i = 0; i < sizeof(array_on_stack); ++i) + { + array_on_stack[i] = 0x11; + } + } + + + // Checks value-initialization of the subobjects of a temporary object, + // an object on the stack, an object on the heap; furthermore it checks + // value-initialization of a number of smaller temporary objects and + // heap objects. + int test() + { + unsigned total_num_failures = 0; + + dirty_stack(); + const unsigned num_failures_of_subobjects_of_a_temporary = + value_initializer().check_value_initialization_of_subobjects(); + + total_num_failures += num_failures_of_subobjects_of_a_temporary; + if ( total_num_failures > 0 ) + {+ std::cout << "- Number of subobject initialization failures of a temporary: "
+ << num_failures_of_subobjects_of_a_temporary << std::endl; + } + dirty_stack(); + value_initializer object_on_stack; + const unsigned num_failures_of_subobjects_on_stack = + object_on_stack.check_value_initialization_of_subobjects(); + + total_num_failures += num_failures_of_subobjects_on_stack; + if ( total_num_failures > 0 ) + {+ std::cout << "- Number of subobject initialization failures on the stack: "
+ << num_failures_of_subobjects_on_stack << std::endl; + } + const value_initializer* const ptr = new value_initializer();+ const unsigned num_failures_of_subobjects_on_heap = ptr->check_value_initialization_of_subobjects();
+ delete ptr; + + total_num_failures += num_failures_of_subobjects_on_heap; + if ( total_num_failures > 0 ) + {+ std::cout << "- Number of subobject initialization failures on the heap: "
+ << num_failures_of_subobjects_on_heap << std::endl; + } + + dirty_stack();+ const unsigned num_failures_of_temporaries = check_value_initialization_of_temporaries();
+ + total_num_failures += num_failures_of_temporaries; + if ( total_num_failures > 0 ) + {+ std::cout << "- Number of initialization failures of temporary objects: "
+ << num_failures_of_temporaries << std::endl; + } ++ const unsigned num_failures_of_heap_objects = check_value_initialization_of_heap_objects();
+ + total_num_failures += num_failures_of_heap_objects; + if ( total_num_failures > 0 ) + { + std::cout << "- Number of failures of heap objects: " + << num_failures_of_heap_objects << std::endl; ***The diff for this file has been truncated for email.*** ======================================= --- /dev/null+++ /trunk/libs/config/test/no_0x_hdr_typeindex_fail.cpp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,37 @@ +// This file was automatically generated on Fri Jun 04 12:51:34 2010 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-4. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/config for the most recent version.// +// Revision $Id: generate.cpp 49281 2008-10-11 15:40:44Z johnmaddock $ +// + + +// Test file for macro BOOST_NO_0X_HDR_TYPEINDEX +// This file should not compile, if it does then +// BOOST_NO_0X_HDR_TYPEINDEX should not be defined. +// See file boost_no_0x_hdr_typeindex.ipp for details + +// Must not have BOOST_ASSERT_CONFIG set; it defeats +// the objective of this file: +#ifdef BOOST_ASSERT_CONFIG +# undef BOOST_ASSERT_CONFIG +#endif + +#include <boost/config.hpp> +#include "test.hpp" + +#ifdef BOOST_NO_0X_HDR_TYPEINDEX +#include "boost_no_0x_hdr_typeindex.ipp" +#else +#error "this file should not compile" +#endif + +int main( int, char *[] ) +{ + return boost_no_0x_hdr_typeindex::test(); +} + ======================================= --- /dev/null+++ /trunk/libs/config/test/no_0x_hdr_typeindex_pass.cpp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,37 @@ +// This file was automatically generated on Fri Jun 04 12:51:34 2010 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-4. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/config for the most recent version.// +// Revision $Id: generate.cpp 49281 2008-10-11 15:40:44Z johnmaddock $ +// + + +// Test file for macro BOOST_NO_0X_HDR_TYPEINDEX +// This file should compile, if it does not then +// BOOST_NO_0X_HDR_TYPEINDEX should be defined. +// See file boost_no_0x_hdr_typeindex.ipp for details + +// Must not have BOOST_ASSERT_CONFIG set; it defeats +// the objective of this file: +#ifdef BOOST_ASSERT_CONFIG +# undef BOOST_ASSERT_CONFIG +#endif + +#include <boost/config.hpp> +#include "test.hpp" + +#ifndef BOOST_NO_0X_HDR_TYPEINDEX +#include "boost_no_0x_hdr_typeindex.ipp" +#else +namespace boost_no_0x_hdr_typeindex = empty_boost; +#endif + +int main( int, char *[] ) +{ + return boost_no_0x_hdr_typeindex::test(); +} + ======================================= --- /dev/null+++ /trunk/libs/config/test/no_com_value_init_fail.cpp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,37 @@ +// This file was automatically generated on Fri Apr 09 12:24:53 2010 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-4. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/config for the most recent version.// +// Revision $Id: generate.cpp 49281 2008-10-11 15:40:44Z johnmaddock $ +// + + +// Test file for macro BOOST_NO_COMPLETE_VALUE_INITIALIZATION +// This file should not compile, if it does then +// BOOST_NO_COMPLETE_VALUE_INITIALIZATION should not be defined. +// See file boost_no_com_value_init.ipp for details + +// Must not have BOOST_ASSERT_CONFIG set; it defeats +// the objective of this file: +#ifdef BOOST_ASSERT_CONFIG +# undef BOOST_ASSERT_CONFIG +#endif + +#include <boost/config.hpp> +#include "test.hpp" + +#ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#include "boost_no_com_value_init.ipp" +#else +#error "this file should not compile" +#endif + +int main( int, char *[] ) +{ + return boost_no_complete_value_initialization::test(); +} + ======================================= --- /dev/null+++ /trunk/libs/config/test/no_com_value_init_pass.cpp Wed Aug 18 08:21:10 2010
@@ -0,0 +1,37 @@ +// This file was automatically generated on Fri Apr 09 12:24:53 2010 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-4. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/config for the most recent version.// +// Revision $Id: generate.cpp 49281 2008-10-11 15:40:44Z johnmaddock $ +// + + +// Test file for macro BOOST_NO_COMPLETE_VALUE_INITIALIZATION +// This file should compile, if it does not then +// BOOST_NO_COMPLETE_VALUE_INITIALIZATION should be defined. +// See file boost_no_com_value_init.ipp for details + +// Must not have BOOST_ASSERT_CONFIG set; it defeats +// the objective of this file: +#ifdef BOOST_ASSERT_CONFIG +# undef BOOST_ASSERT_CONFIG +#endif + +#include <boost/config.hpp> +#include "test.hpp" + +#ifndef BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#include "boost_no_com_value_init.ipp" +#else +namespace boost_no_complete_value_initialization = empty_boost; +#endif + +int main( int, char *[] ) +{ + return boost_no_complete_value_initialization::test(); +} + =======================================--- /trunk/libs/asio/example/timeouts/accept_timeout.cpp Sun Feb 7 18:57:55 2010
+++ /dev/null @@ -1,74 +0,0 @@ -// -// accept_timeout.cpp -// ~~~~~~~~~~~~~~~~~~ -//-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include <boost/asio.hpp> -#include <boost/bind.hpp> -#include <boost/date_time/posix_time/posix_time_types.hpp> -#include <iostream> - -using namespace boost::asio; -using boost::asio::ip::tcp; - -class accept_handler -{ -public: - accept_handler(io_service& ios) - : io_service_(ios), - timer_(ios), - acceptor_(ios, tcp::endpoint(tcp::v4(), 32123)), - socket_(ios) - { - acceptor_.async_accept(socket_, - boost::bind(&accept_handler::handle_accept, this, - boost::asio::placeholders::error)); - - timer_.expires_from_now(boost::posix_time::seconds(5)); - timer_.async_wait(boost::bind(&accept_handler::close, this)); - } - - void handle_accept(const boost::system::error_code& err) - { - if (err) - { - std::cout << "Accept error: " << err.message() << "\n"; - } - else - { - std::cout << "Successful accept\n"; - } - } - - void close() - { - acceptor_.close(); - } - -private: - io_service& io_service_; - deadline_timer timer_; - tcp::acceptor acceptor_; - tcp::socket socket_; -}; - -int main() -{ - try - { - io_service ios; - accept_handler ah(ios); - ios.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} =======================================--- /trunk/libs/asio/example/timeouts/connect_timeout.cpp Sun Feb 7 18:57:55 2010
+++ /dev/null @@ -1,85 +0,0 @@ -// -// connect_timeout.cpp -// ~~~~~~~~~~~~~~~~~~~ -//-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include <boost/asio.hpp> -#include <boost/bind.hpp> -#include <boost/date_time/posix_time/posix_time_types.hpp> -#include <iostream> - -using namespace boost::asio; -using boost::asio::ip::tcp; - -class connect_handler -{ -public: - connect_handler(io_service& ios) - : io_service_(ios), - timer_(ios), - socket_(ios) - { - socket_.async_connect( - tcp::endpoint(boost::asio::ip::address_v4::loopback(), 32123), - boost::bind(&connect_handler::handle_connect, this, - boost::asio::placeholders::error)); - - timer_.expires_from_now(boost::posix_time::seconds(5)); - timer_.async_wait(boost::bind(&connect_handler::close, this)); - } - - void handle_connect(const boost::system::error_code& err) - { - if (err) - { - std::cout << "Connect error: " << err.message() << "\n"; - } - else - { - std::cout << "Successful connection\n"; - } - } - - void close() - { - socket_.close(); - } - -private: - io_service& io_service_; - deadline_timer timer_; - tcp::socket socket_; -}; - -int main() -{ - try - { - io_service ios; - tcp::acceptor a(ios, tcp::endpoint(tcp::v4(), 32123), 1); - - // Make lots of connections so that at least some of them will block. - connect_handler ch1(ios); - connect_handler ch2(ios); - connect_handler ch3(ios); - connect_handler ch4(ios); - connect_handler ch5(ios); - connect_handler ch6(ios); - connect_handler ch7(ios); - connect_handler ch8(ios); - connect_handler ch9(ios); - - ios.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} =======================================--- /trunk/libs/asio/example/timeouts/datagram_receive_timeout.cpp Sun Feb 7 18:57:55 2010
+++ /dev/null @@ -1,78 +0,0 @@ -// -// datagram_receive_timeout.cpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include <boost/asio.hpp> -#include <boost/bind.hpp> -#include <boost/date_time/posix_time/posix_time_types.hpp> -#include <iostream> - -using namespace boost::asio; -using boost::asio::ip::udp; - -class datagram_handler -{ -public: - datagram_handler(io_service& ios) - : io_service_(ios), - timer_(ios), - socket_(ios, udp::endpoint(udp::v4(), 32124)) - { - socket_.async_receive_from( - boost::asio::buffer(data_, max_length), sender_endpoint_, - boost::bind(&datagram_handler::handle_receive_from, this, - boost::asio::placeholders::error, - boost::asio::placeholders::bytes_transferred)); - - timer_.expires_from_now(boost::posix_time::seconds(5)); - timer_.async_wait(boost::bind(&datagram_handler::close, this)); - } - - void handle_receive_from(const boost::system::error_code& err, - size_t /*length*/) - { - if (err) - { - std::cout << "Receive error: " << err.message() << "\n"; - } - else - { - std::cout << "Successful receive\n"; - } - } - - void close() - { - socket_.close(); - } - -private: - io_service& io_service_; - deadline_timer timer_; - udp::socket socket_; - udp::endpoint sender_endpoint_; - enum { max_length = 512 }; - char data_[max_length]; -}; - -int main() -{ - try - { - io_service ios; - datagram_handler dh(ios); - ios.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} =======================================--- /trunk/libs/asio/example/timeouts/stream_receive_timeout.cpp Sun Feb 7 18:57:55 2010
+++ /dev/null @@ -1,102 +0,0 @@ -// -// stream_receive_timeout.cpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~ -//-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include <boost/asio.hpp> -#include <boost/bind.hpp> -#include <boost/date_time/posix_time/posix_time_types.hpp> -#include <iostream> - -using namespace boost::asio; -using boost::asio::ip::tcp; - -class stream_handler -{ -public: - stream_handler(io_service& ios) - : io_service_(ios), - timer_(ios), - acceptor_(ios, tcp::endpoint(tcp::v4(), 32123)), - socket_(ios) - { - acceptor_.async_accept(socket_, - boost::bind(&stream_handler::handle_accept, this, - boost::asio::placeholders::error)); - } - - void handle_accept(const boost::system::error_code& err) - { - if (err) - { - std::cout << "Accept error: " << err.message() << "\n"; - } - else - { - std::cout << "Successful accept\n"; - - socket_.async_read_some(boost::asio::buffer(buf_, sizeof(buf_)), - boost::bind(&stream_handler::handle_recv, this, - boost::asio::placeholders::error)); - timer_.expires_from_now(boost::posix_time::seconds(5)); - timer_.async_wait(boost::bind(&stream_handler::close, this)); - } - } - - void handle_recv(const boost::system::error_code& err) - { - if (err) - { - std::cout << "Receive error: " << err.message() << "\n"; - } - else - { - std::cout << "Successful receive\n"; - } - } - - void close() - { - socket_.close(); - } - -private: - io_service& io_service_; - deadline_timer timer_; - tcp::acceptor acceptor_; - tcp::socket socket_; - char buf_[1024]; -}; - -void connect_handler() -{ - std::cout << "Successful connect\n"; -} - -int main() -{ - try - { - io_service ios; - - stream_handler sh(ios); - - tcp::socket s(ios); - s.async_connect( - tcp::endpoint(boost::asio::ip::address_v4::loopback(), 32123), - boost::bind(connect_handler)); - - ios.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} ======================================= --- /trunk/libs/accumulators/doc/Jamfile.v2 Mon Dec 28 23:05:14 2009 +++ /trunk/libs/accumulators/doc/Jamfile.v2 Wed Aug 18 08:21:10 2010 @@ -235,6 +235,7 @@ : accumulators : + <xsl:param>boost.root=../../../.. <xsl:param>boost.max.id.length=1024 <xsl:param>toc.max.depth=4 <xsl:param>toc.section.depth=4 ======================================= --- /trunk/libs/accumulators/doc/accumulators.qbk Sun Feb 7 18:57:55 2010 +++ /trunk/libs/accumulators/doc/accumulators.qbk Wed Aug 18 08:21:10 2010 @@ -1418,10 +1418,12 @@ [[Extractor Complexity 提取器复杂度] [O(1)]] ] -[*Header] +[*Headers][def _COVARIANCE_HPP_ [headerref boost/accumulators/statistics/covariance.hpp]] +[def _COVARIATE_HPP_ [headerref boost/accumulators/statistics/variates/covariate.hpp]]
#include <_COVARIANCE_HPP_> + #include <_COVARIATE_HPP_> [*Example] ======================================= --- /trunk/libs/algorithm/minmax/index.html Tue Jun 2 01:35:23 2009 +++ /trunk/libs/algorithm/minmax/index.html Wed Aug 18 08:21:10 2010 @@ -222,7 +222,7 @@-<pre>#include <boost/tuple/tuple.hpp><br><br>namespace boost {<br><br> template <class T><br> tuple<T const&, T const&> ><br> minmax(const T& a, const T& b);<br><br> template <class T, class <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html";>BinaryPredicate</a>><br> tuple<T const&, T const&> ><br> minmax(const T& a, const T& b, BinaryPredicate comp);<br><br>}<br></pre> +<pre>#include <boost/tuple/tuple.hpp><br><br>namespace boost {<br><br> template <class T><br> tuple<T const&, T const&><br> minmax(const T& a, const T& b);<br><br> template <class T, class <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html";>BinaryPredicate</a>><br> tuple<T const&, T const&><br> minmax(const T& a, const T& b, BinaryPredicate comp);<br><br>}<br></pre>
======================================= --- /trunk/libs/algorithm/string/doc/Jamfile.v2 Mon Dec 28 23:05:14 2009 +++ /trunk/libs/algorithm/string/doc/Jamfile.v2 Wed Aug 18 08:21:10 2010 @@ -12,6 +12,7 @@ boostbook string_algo : string_algo.xml autodoc : + <xsl:param>boost.root=../../../../..<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
; =======================================--- /trunk/libs/algorithm/string/doc/external_concepts.html Thu Sep 4 08:02:36 2008 +++ /trunk/libs/algorithm/string/doc/external_concepts.html Wed Aug 18 08:21:10 2010
@@ -32,7 +32,9 @@free-standing functions and type-generators exists:</p><code>void foo( const T&, int ); <br>
int bar( T& ); <br>foo_type_of< T >::type;</code> <br> <br><hr size="1" ><h3
Literature</h3><ul ><li > <ahref="http://www.boost.org/more/generic_programming.html#type_generator"; target="_self" >Type Generators</a> </li><li > <a href="http://www.boost.org/more/generic_programming.html#concept"; target="_self" >Concepts</a> </li><li > <a href="http://www.sgi.com/tech/stl/stl_introduction.html"; target="_self"
Concepts and SGI STL</a> </li></ul><hr size="1" ><p >© Thorsten
Ottosen 2003-2004 (nesotto_AT_cs.auc.dk).- Permission to copy, use, modify, sell and distribute this software is granted provided this copyright notice appears - in all copies. This software is provided "as is" without express or implied warranty, and with no - claim as to its suitability for any purpose.</p><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></body></html>
+<br>Use, modification and distribution is subject to the Boost + Software License, Version 1.0. (See accompanying file+ <code class="filename">LICENSE_1_0.txt</code> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"; target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+</br> +</p> <!-- Copyright Dezide Aps 2003-2004 --> =======================================--- /trunk/libs/algorithm/string/doc/string_algo.xml Mon Dec 28 23:05:14 2009 +++ /trunk/libs/algorithm/string/doc/string_algo.xml Wed Aug 18 08:21:10 2010
@@ -8,7 +8,7 @@ --><library name="String Algorithms" dirname="algorithm/string" xmlns:xi="http://www.w3.org/2001/XInclude"; - id="string_algo" last-revision="$Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $"> + id="string_algo" last-revision="$Date: 2010-07-10 16:29:03 -0400 (Sat, 10 Jul 2010) $">
<libraryinfo> <author> <firstname>Pavol</firstname> @@ -33,7 +33,7 @@ <librarypurpose> A set of generic string-related algorithms and utilities </librarypurpose> - <librarycategory name="category:algoritms"/> + <librarycategory name="category:algorithms"/> <librarycategory name="category:string-text"/> </libraryinfo> ======================================= --- /trunk/libs/algorithm/string/doc/usage.xml Fri May 28 00:05:44 2010 +++ /trunk/libs/algorithm/string/doc/usage.xml Wed Aug 18 08:21:10 2010 @@ -9,7 +9,7 @@ -->-<section id="string_algo.usage" last-revision="$Date: 2010-04-21 19:00:35 -0400 (Wed, 21 Apr 2010) $"> +<section id="string_algo.usage" last-revision="$Date: 2010-07-10 16:29:03 -0400 (Sat, 10 Jul 2010) $">
<title>Usage 用法</title> <using-namespace name="boost"/> @@ -205,7 +205,7 @@ <programlisting> string str1=" hello world! "; string str2=trim_left_copy(str1); // str2 == "hello world! " - string str3=trim_right_copy(str2); // str3 == " hello world!" + string str3=trim_right_copy(str1); // str3 == " hello world!" trim(str1); // str1 == "hello world!" string phone="00423333444"; @@ -418,7 +418,7 @@ typedef vector< string > split_vector_type; split_vector_type SplitVec; // #2: Search for tokens- split( SplitVec, str1, is_any_of("-*") ); // SplitVec == { "hello abc","ABC","aBc goodbye" } + split( SplitVec, str1, is_any_of("-*"), token_compress_on ); // SplitVec == { "hello abc","ABC","aBc goodbye" }
</programlisting> <para><code>[hello]</code> designates an <code>iterator_range</code> delimiting this substring. <sbr/>
======================================= --- /trunk/libs/array/doc/array.xml Fri May 28 00:05:44 2010 +++ /trunk/libs/array/doc/array.xml Wed Aug 18 08:21:10 2010 @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd";>-<library name="Array" dirname="array" id="array" last-revision="$Date: 2010-05-01 16:29:31 -0400 (Sat, 01 May 2010) $"> +<library name="Array" dirname="array" id="array" last-revision="$Date: 2010-08-11 14:15:46 -0400 (Wed, 11 Aug 2010) $">
<libraryinfo> <author> <firstname>Nicolai</firstname> ======================================= --- /trunk/libs/array/test/array2.cpp Fri May 28 00:05:44 2010 +++ /trunk/libs/array/test/array2.cpp Wed Aug 18 08:21:10 2010 @@ -5,6 +5,11 @@ * http://www.boost.org/LICENSE_1_0.txt) */ +#ifndef _SCL_SECURE_NO_WARNINGS +// Suppress warnings from the std lib: +# define _SCL_SECURE_NO_WARNINGS +#endif + #include <algorithm> #include <functional> #include <boost/array.hpp> ======================================= --- /trunk/libs/asio/doc/Jamfile.v2 Sun Feb 7 18:57:55 2010 +++ /trunk/libs/asio/doc/Jamfile.v2 Wed Aug 18 08:21:10 2010 @@ -15,13 +15,6 @@ asio.qbk ; -install css - : - /boost//doc/html/boostbook.css - : - <location>html - ; - install images : overview/proactor.png @@ -47,8 +40,6 @@ standalone_doc : <xsl:param>boost.root=../../../.. - <xsl:param>boost.libraries=../../../../libs/libraries.htm - <xsl:param>navig.graphics.path="../../../../doc/html/images/" <xsl:param>chapter.autolabel=0 <xsl:param>chunk.section.depth=8 <xsl:param>chunk.first.sections=1 ======================================= --- /trunk/libs/asio/doc/examples.qbk Sun Feb 7 18:57:55 2010 +++ /trunk/libs/asio/doc/examples.qbk Wed Aug 18 08:21:10 2010 @@ -243,10 +243,10 @@ A collection of examples showing how to cancel long running asynchronous operations after a period of time. -* [@boost_asio/example/timeouts/accept_timeout.cpp] -* [@boost_asio/example/timeouts/connect_timeout.cpp] -* [@boost_asio/example/timeouts/datagram_receive_timeout.cpp] -* [@boost_asio/example/timeouts/stream_receive_timeout.cpp] +* [@boost_asio/example/timeouts/async_tcp_client.cpp] +* [@boost_asio/example/timeouts/blocking_tcp_client.cpp] +* [@boost_asio/example/timeouts/blocking_udp_client.cpp] +* [@boost_asio/example/timeouts/server.cpp] [heading Timers] ======================================= --- /trunk/libs/asio/doc/history.qbk Fri May 28 00:05:44 2010 +++ /trunk/libs/asio/doc/history.qbk Wed Aug 18 08:21:10 2010 @@ -7,6 +7,39 @@ [section:history Revision History] +[heading Asio 1.4.6 / Boost 1.44] ++* Reduced compile times. (Note that some programs may need to add additional + `#include`s, e.g. if the program uses `boost::array` but does not explicitly
+ include `<boost/array.hpp>`.) +* Reduced the size of generated code. +* Refactored `deadline_timer` implementation to improve performance.+* Improved multiprocessor scalability on Windows by using a dedicated hidden
+ thread to wait for timers. +* Improved performance of `asio::streambuf` with `async_read()` and+ `async_read_until()`. These read operations now use the existing capacity of
+ the `streambuf` when reading, rather than limiting the read to 512 bytes. +* Added optional separate compilation. To enable, add+ `#include <boost/asio/impl/src.cpp>` to one source file in a program, then
+ build the program with `BOOST_ASIO_SEPARATE_COMPILATION` defined in the + project\/compiler settings. Alternatively, `BOOST_ASIO_DYN_LINK` may be + defined to build a separately-compiled Asio as part of a shared library.+* Added new macro `BOOST_ASIO_DISABLE_FENCED_BLOCK` to permit the disabling of + memory fences around completion handlers, even if thread support is enabled.
+* Reworked timeout examples to better illustrate typical use cases. +* Ensured that handler arguments are passed as `const` types.+* Fixed incorrect parameter order in `null_buffers` variant of `async_send_to`
+ ([@https://svn.boost.org/trac/boost/ticket/4170 #4170]). +* Ensured `unsigned char` is used with `isdigit` in `getaddrinfo` emulation + ([@https://svn.boost.org/trac/boost/ticket/4201 #4201]). +* Fixed handling of very small but non-zero timeouts + ([@https://svn.boost.org/trac/boost/ticket/4205 #4205]). +* Fixed crash that occurred when an empty buffer sequence was passed to a + composed read or write operation. +* Added missing `operator+` overload in `buffers_iterator` + ([@https://svn.boost.org/trac/boost/ticket/4382 #4382]). +* Implemented cancellation of `null_buffers` operations on Windows. + [heading Asio 1.4.5 / Boost 1.43] * Improved performance. ======================================= --- /trunk/libs/asio/doc/reference.qbk Fri May 28 00:05:44 2010 +++ /trunk/libs/asio/doc/reference.qbk Wed Aug 18 08:21:10 2010 File is too large to display a diff. ======================================= --- /trunk/libs/asio/doc/reference.xsl Fri May 28 00:05:44 2010 +++ /trunk/libs/asio/doc/reference.xsl Wed Aug 18 08:21:10 2010 @@ -103,7 +103,8 @@ <xsl:if test=" not(contains(ancestor::*/compoundname, '::detail')) and not(contains(ancestor::*/compoundname, '::service::key')) and - not(contains(ancestor::*/compoundname, '_helper'))"> + not(contains(ancestor::*/compoundname, '_helper')) and + not(contains(name, '_helper'))"> <xsl:call-template name="namespace-memberdef"/> </xsl:if> </xsl:otherwise> @@ -164,6 +165,23 @@ </xsl:template> +<xsl:template name="cleanup-type"> + <xsl:param name="name"/> + <xsl:choose> + <xsl:when test="contains($name, 'BOOST_ASIO_DECL ')"> + <xsl:value-of select="substring-after($name, 'BOOST_ASIO_DECL ')"/> + </xsl:when> + <xsl:when test="contains($name, 'BOOST_ASIO_DECL')"> + <xsl:value-of select="substring-after($name, 'BOOST_ASIO_DECL')"/> + </xsl:when> + <xsl:when test="$name = 'virtual'"></xsl:when> + <xsl:otherwise> + <xsl:value-of select="$name"/> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + + <xsl:template name="make-id"> <xsl:param name="name"/> <xsl:choose> @@ -365,8 +383,11 @@ <xsl:template match="listitem" mode="markup"> -* <xsl:value-of select="."/><xsl:text> -</xsl:text> +* <xsl:call-template name="strip-leading-whitespace"> + <xsl:with-param name="text"> + <xsl:apply-templates mode="markup"/> + </xsl:with-param> +</xsl:call-template> </xsl:template> @@ -1054,8 +1075,14 @@ <xsl:text> </xsl:text> <xsl:if test="@explicit='yes'">explicit </xsl:if> <xsl:if test="@static='yes'">static </xsl:if> - <xsl:if test="string-length(type) > 0"> - <xsl:value-of select="type"/><xsl:text> </xsl:text> + <xsl:if test="@virt='virtual'">virtual </xsl:if> + <xsl:variable name="stripped-type"> + <xsl:call-template name="cleanup-type"> + <xsl:with-param name="name" select="type"/> + </xsl:call-template> + </xsl:variable> + <xsl:if test="string-length($stripped-type) > 0"> + <xsl:value-of select="$stripped-type"/><xsl:text> </xsl:text></xsl:if>``[link boost_asio.reference.<xsl:value-of select="$class-id"/>.<xsl:value-of select="$id"/>.overload<xsl:value-of select="position()"/><xsl:text> </xsl:text><xsl:value-of
select="name"/>]``(<xsl:apply-templates select="param" @@ -1217,8 +1244,14 @@ <xsl:apply-templates select="templateparamlist" mode="class-detail"/> </xsl:otherwise> </xsl:choose> -<xsl:text> </xsl:text><xsl:if test="@static='yes'">static </xsl:if><xsl:if- test="string-length(type) > 0"><xsl:value-of select="type"/><xsl:text> </xsl:text></xsl:if>
+<xsl:variable name="stripped-type"> + <xsl:call-template name="cleanup-type"> + <xsl:with-param name="name" select="type"/> + </xsl:call-template> +</xsl:variable> +<xsl:text> </xsl:text><xsl:if test="@static='yes'">static </xsl:if><xsl:if + test="@virt='virtual'">virtual </xsl:if><xsl:if+ test="string-length($stripped-type) > 0"><xsl:value-of select="$stripped-type"/><xsl:text> </xsl:text></xsl:if>
<xsl:value-of select="name"/>(<xsl:apply-templates select="param" mode="class-detail"/>)<xsl:if test="@const='yes'"> const</xsl:if>; </xsl:template> @@ -1394,10 +1427,15 @@ </xsl:choose> <xsl:for-each select="../memberdef[name = $unqualified-name]"> +<xsl:variable name="stripped-type"> + <xsl:call-template name="cleanup-type"> + <xsl:with-param name="name" select="type"/> + </xsl:call-template> +</xsl:variable> <xsl:text></xsl:text><xsl:apply-templates select="templateparamlist" mode="class-detail"/>
-<xsl:text> </xsl:text><xsl:if test="string-length(type) > 0"><xsl:value-of- select="type"/><xsl:text> </xsl:text></xsl:if>``[link boost_asio.reference.<xsl:value-of +<xsl:text> </xsl:text><xsl:if test="string-length($stripped-type) > 0"><xsl:value-of + select="$stripped-type"/><xsl:text> </xsl:text></xsl:if>``[link boost_asio.reference.<xsl:value-of select="$id"/>.overload<xsl:value-of select="position()"/><xsl:text> </xsl:text> <xsl:value-of select="name"/>]``(<xsl:apply-templates select="param" mode="class-detail"/>);
<xsl:text> `` [''''&raquo;'''</xsl:text> ======================================= --- /trunk/libs/asio/doc/tutorial.qbk Sun Feb 7 18:57:55 2010 +++ /trunk/libs/asio/doc/tutorial.qbk Wed Aug 18 08:21:10 2010 @@ -81,7 +81,7 @@-Since this example users timers, we need to include the appropriate Boost.Date\_Time header file for manipulating times. +Since this example uses timers, we need to include the appropriate Boost.Date\_Time header file for manipulating times.
``''''''``#include <boost/date_time/posix_time/posix_time.hpp> =======================================--- /trunk/libs/asio/example/http/server4/coroutine.hpp Sun Feb 7 18:57:55 2010 +++ /trunk/libs/asio/example/http/server4/coroutine.hpp Wed Aug 18 08:21:10 2010
@@ -50,11 +50,11 @@ } \ else case 0: -#define CORO_YIELD \ - for (_coro_value = __LINE__;;) \ +#define CORO_YIELD_IMPL(n) \ + for (_coro_value = (n);;) \ if (_coro_value == 0) \ { \ - case __LINE__: ; \ + case (n): ; \ break; \ } \ else \ @@ -67,13 +67,21 @@ goto bail_out_of_coroutine; \ else case 0: -#define CORO_FORK \ - for (_coro_value = -__LINE__;; _coro_value = __LINE__) \ - if (_coro_value == __LINE__) \ +#define CORO_FORK_IMPL(n) \ + for (_coro_value = -(n);; _coro_value = (n)) \ + if (_coro_value == (n)) \ { \ - case -__LINE__: ; \ + case -(n): ; \ break; \ } \ else +#if defined(_MSC_VER) +# define CORO_YIELD CORO_YIELD_IMPL(__COUNTER__ + 1) +# define CORO_FORK CORO_FORK_IMPL(__COUNTER__ + 1) +#else // defined(_MSC_VER) +# define CORO_YIELD CORO_YIELD_IMPL(__LINE__) +# define CORO_FORK CORO_FORK_IMPL(__LINE__) +#endif // defined(_MSC_VER) + #endif // COROUTINE_HPP =======================================--- /trunk/libs/asio/example/local/iostream_client.cpp Sun Feb 7 18:57:55 2010 +++ /trunk/libs/asio/example/local/iostream_client.cpp Wed Aug 18 08:21:10 2010
@@ -27,11 +27,14 @@ std::cerr << "Usage: iostream_client <file>\n"; return 1; } - - boost::asio::io_service io_service; stream_protocol::endpoint ep(argv[1]); stream_protocol::iostream s(ep); + if (!s) + { + std::cerr << "Unable to connect\n"; + return 1; + } using namespace std; // For strlen. std::cout << "Enter message: "; ======================================= --- /trunk/libs/asio/example/timeouts/Jamfile Sun Feb 7 18:57:55 2010 +++ /trunk/libs/asio/example/timeouts/Jamfile Wed Aug 18 08:21:10 2010 @@ -32,22 +32,22 @@ $(SOCKET_LIBS) ; -exe accept_timeout +exe async_tcp_client : <template>asio_timeouts_example - accept_timeout.cpp + async_tcp_client.cpp ; -exe connect_timeout +exe blocking_tcp_client : <template>asio_timeouts_example - connect_timeout.cpp + blocking_tcp_client.cpp ; -exe datagram_receive_timeout +exe blocking_udp_client : <template>asio_timeouts_example - datagram_receive_timeout.cpp + blocking_udp_client.cpp ; -exe stream_receive_timeout +exe server : <template>asio_timeouts_example - stream_receive_timeout.cpp - ; + server.cpp + ; ======================================= --- /trunk/libs/asio/example/timeouts/Jamfile.v2 Sun Feb 7 18:57:55 2010 +++ /trunk/libs/asio/example/timeouts/Jamfile.v2 Wed Aug 18 08:21:10 2010 @@ -37,7 +37,7 @@ <os>HPUX:<library>ipv6 ; -exe accept_timeout : accept_timeout.cpp ; -exe connect_timeout : connect_timeout.cpp ; -exe datagram_receive_timeout : datagram_receive_timeout.cpp ; -exe stream_receive_timeout : stream_receive_timeout.cpp ; +exe async_tcp_client : async_tcp_client.cpp ; +exe blocking_tcp_client : blocking_tcp_client.cpp ; +exe blocking_udp_client : blocking_udp_client.cpp ; +exe server : server.cpp ; ======================================= --- /trunk/libs/asio/example/tutorial/timer_dox.txt Sun Feb 7 18:57:55 2010 +++ /trunk/libs/asio/example/tutorial/timer_dox.txt Wed Aug 18 08:21:10 2010 @@ -21,7 +21,7 @@ \until asio.hpp -Since this example users timers, we need to include the appropriate +Since this example uses timers, we need to include the appropriate Boost.Date_Time header file for manipulating times. \until posix_time.hpp ======================================= --- /trunk/libs/asio/test/Jamfile Sun Feb 7 18:57:55 2010 +++ /trunk/libs/asio/test/Jamfile Wed Aug 18 08:21:10 2010 @@ -26,6 +26,7 @@ template asio_unit_test : <lib>@boost/libs/thread/build/boost_thread + <lib>@boost/libs/regex/build/boost_regex <lib>@boost_system/libs/system/build/boost_system : <include>../../.. <include>@boost <include>@boost_system <define>BOOST_ALL_NO_LIB=1 ======================================= --- /trunk/libs/asio/test/Jamfile.v2 Sun Feb 7 18:57:55 2010 +++ /trunk/libs/asio/test/Jamfile.v2 Wed Aug 18 08:21:10 2010 @@ -39,6 +39,7 @@ <library>/boost/date_time//boost_date_time <library>/boost/system//boost_system <library>/boost/thread//boost_thread + <library>/boost/regex//boost_regex <define>BOOST_ALL_NO_LIB=1 <threading>multi <os>LINUX:<define>_XOPEN_SOURCE=600 ======================================= --- /trunk/libs/asio/test/buffer.cpp Sun Feb 7 18:57:55 2010 +++ /trunk/libs/asio/test/buffer.cpp Wed Aug 18 08:21:10 2010 @@ -16,6 +16,7 @@ // Test that header file is self-contained. #include <boost/asio/buffer.hpp> +#include <boost/array.hpp> #include "unit_test.hpp"//------------------------------------------------------------------------------
======================================= --- /trunk/libs/asio/test/buffered_read_stream.cpp Sun Feb 7 18:57:55 2010 +++ /trunk/libs/asio/test/buffered_read_stream.cpp Wed Aug 18 08:21:10 2010 @@ -22,6 +22,7 @@ #include <boost/asio/io_service.hpp> #include <boost/asio/ip/tcp.hpp> #include <boost/asio/placeholders.hpp> +#include <boost/system/system_error.hpp> #include "unit_test.hpp" typedef boost::asio::buffered_read_stream< ======================================= --- /trunk/libs/asio/test/buffered_stream.cpp Sun Feb 7 18:57:55 2010 +++ /trunk/libs/asio/test/buffered_stream.cpp Wed Aug 18 08:21:10 2010 @@ -22,6 +22,7 @@ #include <boost/asio/io_service.hpp> #include <boost/asio/ip/tcp.hpp> #include <boost/asio/placeholders.hpp> +#include <boost/system/system_error.hpp> #include "unit_test.hpp" typedef boost::asio::buffered_stream< ======================================= ***Additional files exist in this changeset.***