diff options
author | Remko Tronçon <git@el-tramo.be> | 2010-11-24 20:33:19 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2010-11-24 20:35:17 (GMT) |
commit | 332d60c56dfaa11fdd135088279d15cd5983b3d4 (patch) | |
tree | dd77717a4e1732da929d5ff8a0471fa3f005e201 /3rdParty/Boost/src | |
parent | 90c44a10fec26d2a0935b2d62e82b6a5be028373 (diff) | |
download | swift-contrib-332d60c56dfaa11fdd135088279d15cd5983b3d4.zip swift-contrib-332d60c56dfaa11fdd135088279d15cd5983b3d4.tar.bz2 |
Upgraded Boost to 1.45.0.
Diffstat (limited to '3rdParty/Boost/src')
518 files changed, 33912 insertions, 18984 deletions
diff --git a/3rdParty/Boost/src/boost/algorithm/string/detail/case_conv.hpp b/3rdParty/Boost/src/boost/algorithm/string/detail/case_conv.hpp index 3440c27..5b0064f 100644 --- a/3rdParty/Boost/src/boost/algorithm/string/detail/case_conv.hpp +++ b/3rdParty/Boost/src/boost/algorithm/string/detail/case_conv.hpp @@ -31,7 +31,7 @@ namespace boost { struct to_lowerF : public std::unary_function<CharT, CharT> { // Constructor - to_lowerF( const std::locale& Loc ) : m_Loc( Loc ) {} + to_lowerF( const std::locale& Loc ) : m_Loc( &Loc ) {} // Operation CharT operator ()( CharT Ch ) const @@ -39,11 +39,11 @@ namespace boost { #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL) return std::tolower( Ch); #else - return std::tolower<CharT>( Ch, m_Loc ); + return std::tolower<CharT>( Ch, *m_Loc ); #endif } private: - const std::locale& m_Loc; + const std::locale* m_Loc; }; // a toupper functor @@ -51,7 +51,7 @@ namespace boost { struct to_upperF : public std::unary_function<CharT, CharT> { // Constructor - to_upperF( const std::locale& Loc ) : m_Loc( Loc ) {} + to_upperF( const std::locale& Loc ) : m_Loc( &Loc ) {} // Operation CharT operator ()( CharT Ch ) const @@ -59,11 +59,11 @@ namespace boost { #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL) return std::toupper( Ch); #else - return std::toupper<CharT>( Ch, m_Loc ); + return std::toupper<CharT>( Ch, *m_Loc ); #endif } private: - const std::locale& m_Loc; + const std::locale* m_Loc; }; #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) diff --git a/3rdParty/Boost/src/boost/algorithm/string/detail/find_format.hpp b/3rdParty/Boost/src/boost/algorithm/string/detail/find_format.hpp index 0d8b104..7f5f780 100644 --- a/3rdParty/Boost/src/boost/algorithm/string/detail/find_format.hpp +++ b/3rdParty/Boost/src/boost/algorithm/string/detail/find_format.hpp @@ -49,17 +49,17 @@ namespace boost { if ( !M ) { // Match not found - return original sequence - std::copy( ::boost::begin(Input), ::boost::end(Input), Output ); + Output = std::copy( ::boost::begin(Input), ::boost::end(Input), Output ); return Output; } // Copy the beginning of the sequence - std::copy( ::boost::begin(Input), ::boost::begin(M), Output ); + Output = std::copy( ::boost::begin(Input), ::boost::begin(M), Output ); // Format find result // Copy formated result - std::copy( ::boost::begin(M.format_result()), ::boost::end(M.format_result()), Output ); + Output = std::copy( ::boost::begin(M.format_result()), ::boost::end(M.format_result()), Output ); // Copy the rest of the sequence - std::copy( M.end(), ::boost::end(Input), Output ); + Output = std::copy( M.end(), ::boost::end(Input), Output ); return Output; } @@ -75,12 +75,16 @@ namespace boost { FormatterT Formatter, const FindResultT& FindResult ) { + if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) { return ::boost::algorithm::detail::find_format_copy_impl2( Output, Input, Formatter, FindResult, Formatter(FindResult) ); + } else { + return std::copy( ::boost::begin(Input), ::boost::end(Input), Output ); + } } @@ -132,11 +136,15 @@ namespace boost { FormatterT Formatter, const FindResultT& FindResult) { + if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) { return ::boost::algorithm::detail::find_format_copy_impl2( Input, Formatter, FindResult, Formatter(FindResult) ); + } else { + return Input; + } } // replace implementation ----------------------------------------------------// @@ -180,12 +188,14 @@ namespace boost { FormatterT Formatter, const FindResultT& FindResult) { + if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) { ::boost::algorithm::detail::find_format_impl2( Input, Formatter, FindResult, Formatter(FindResult) ); } + } } // namespace detail } // namespace algorithm diff --git a/3rdParty/Boost/src/boost/algorithm/string/detail/find_format_all.hpp b/3rdParty/Boost/src/boost/algorithm/string/detail/find_format_all.hpp index 36edf56..0f184a3 100644 --- a/3rdParty/Boost/src/boost/algorithm/string/detail/find_format_all.hpp +++ b/3rdParty/Boost/src/boost/algorithm/string/detail/find_format_all.hpp @@ -57,9 +57,9 @@ namespace boost { while( M ) { // Copy the beginning of the sequence - std::copy( LastMatch, M.begin(), Output ); + Output = std::copy( LastMatch, M.begin(), Output ); // Copy formated result - std::copy( ::boost::begin(M.format_result()), ::boost::end(M.format_result()), Output ); + Output = std::copy( ::boost::begin(M.format_result()), ::boost::end(M.format_result()), Output ); // Proceed to the next match LastMatch=M.end(); @@ -67,7 +67,7 @@ namespace boost { } // Copy the rest of the sequence - std::copy( LastMatch, ::boost::end(Input), Output ); + Output = std::copy( LastMatch, ::boost::end(Input), Output ); return Output; } @@ -85,6 +85,7 @@ namespace boost { FormatterT Formatter, const FindResultT& FindResult ) { + if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) { return ::boost::algorithm::detail::find_format_all_copy_impl2( Output, Input, @@ -92,6 +93,9 @@ namespace boost { Formatter, FindResult, Formatter(FindResult) ); + } else { + return std::copy( ::boost::begin(Input), ::boost::end(Input), Output ); + } } // find_format_all_copy implementation ----------------------------------------------// @@ -156,12 +160,16 @@ namespace boost { FormatterT Formatter, const FindResultT& FindResult) { + if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) { return ::boost::algorithm::detail::find_format_all_copy_impl2( Input, Finder, Formatter, FindResult, Formatter(FindResult) ); + } else { + return Input; + } } // find_format_all implementation ------------------------------------------------// @@ -248,6 +256,7 @@ namespace boost { FormatterT Formatter, FindResultT FindResult) { + if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) { ::boost::algorithm::detail::find_format_all_impl2( Input, Finder, @@ -255,6 +264,7 @@ namespace boost { FindResult, Formatter(FindResult) ); } + } } // namespace detail } // namespace algorithm diff --git a/3rdParty/Boost/src/boost/algorithm/string/detail/find_format_store.hpp b/3rdParty/Boost/src/boost/algorithm/string/detail/find_format_store.hpp index 2260fc2e..4872c5a 100644 --- a/3rdParty/Boost/src/boost/algorithm/string/detail/find_format_store.hpp +++ b/3rdParty/Boost/src/boost/algorithm/string/detail/find_format_store.hpp @@ -52,7 +52,9 @@ namespace boost { find_format_store& operator=( FindResultT FindResult ) { iterator_range<ForwardIteratorT>::operator=(FindResult); + if( !this->empty() ) { m_FormatResult=m_Formatter(FindResult); + } return *this; } @@ -68,6 +70,15 @@ namespace boost { const formatter_type& m_Formatter; }; + template<typename InputT, typename FindResultT> + bool check_find_result(InputT&, FindResultT& FindResult) + { + typedef BOOST_STRING_TYPENAME + range_const_iterator<InputT>::type input_iterator_type; + iterator_range<input_iterator_type> ResultRange(FindResult); + return !ResultRange.empty(); + } + #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) #pragma warning(pop) #endif diff --git a/3rdParty/Boost/src/boost/algorithm/string/erase.hpp b/3rdParty/Boost/src/boost/algorithm/string/erase.hpp index 0951b8a..e738b86 100644 --- a/3rdParty/Boost/src/boost/algorithm/string/erase.hpp +++ b/3rdParty/Boost/src/boost/algorithm/string/erase.hpp @@ -752,7 +752,7 @@ namespace boost { \param Output An output iterator to which the result will be copied \param Input An input string - \param N Length of the head. + \param N Length of the tail. For N>=0, at most N characters are extracted. For N<0, size(Input)-|N| characters are extracted. \return An output iterator pointing just after the last inserted character or @@ -797,7 +797,7 @@ namespace boost { considered to be the tail. The input sequence is modified in-place. \param Input An input string - \param N Length of the head + \param N Length of the tail For N>=0, at most N characters are extracted. For N<0, size(Input)-|N| characters are extracted. */ diff --git a/3rdParty/Boost/src/boost/array.hpp b/3rdParty/Boost/src/boost/array.hpp index 6496469..7df2771 100644 --- a/3rdParty/Boost/src/boost/array.hpp +++ b/3rdParty/Boost/src/boost/array.hpp @@ -14,8 +14,8 @@ * http://www.boost.org/LICENSE_1_0.txt) * * 10 Mar 2010 - (mtc) fill method added, matching resolution of the standard library working group. - * See <http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#776> or Trac issue #3168 - * Eventually, we should remove "assign" which is now a synonym for "fill" (Marshall Clow) + * See <http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#776> or Trac issue #3168 + * Eventually, we should remove "assign" which is now a synonym for "fill" (Marshall Clow) * 10 Mar 2010 - added workaround for SUNCC and !STLPort [trac #3893] (Marshall Clow) * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis) * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries. @@ -169,7 +169,7 @@ namespace boost { } // assign one value to all elements - void assign (const T& value) { fill ( value ); } // A synonym for fill + void assign (const T& value) { fill ( value ); } // A synonym for fill void fill (const T& value) { std::fill_n(begin(),size(),value); @@ -295,8 +295,8 @@ namespace boost { // assign one value to all elements void assign (const T& value) { fill ( value ); } - void fill (const T& ) {} - + void fill (const T& ) {} + // check range (may be private because it is static) static reference failed_rangecheck () { std::out_of_range e("attempt to access element of an empty array"); @@ -346,6 +346,38 @@ namespace boost { x.swap(y); } + // Specific for boost::array: simply returns its elems data member. + template <typename T, std::size_t N> + T(&get_c_array(boost::array<T,N>& arg))[N] + { + return arg.elems; + } + + // Const version. + template <typename T, std::size_t N> + const T(&get_c_array(const boost::array<T,N>& arg))[N] + { + return arg.elems; + } + +#if 0 + // Overload for std::array, assuming that std::array will have + // explicit conversion functions as discussed at the WG21 meeting + // in Summit, March 2009. + template <typename T, std::size_t N> + T(&get_c_array(std::array<T,N>& arg))[N] + { + return static_cast<T(&)[N]>(arg); + } + + // Const version. + template <typename T, std::size_t N> + const T(&get_c_array(const std::array<T,N>& arg))[N] + { + return static_cast<T(&)[N]>(arg); + } +#endif + } /* namespace boost */ diff --git a/3rdParty/Boost/src/boost/asio/basic_datagram_socket.hpp b/3rdParty/Boost/src/boost/asio/basic_datagram_socket.hpp index 3b3dedb..5272809 100644 --- a/3rdParty/Boost/src/boost/asio/basic_datagram_socket.hpp +++ b/3rdParty/Boost/src/boost/asio/basic_datagram_socket.hpp @@ -15,17 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/basic_socket.hpp> #include <boost/asio/datagram_socket_service.hpp> -#include <boost/asio/error.hpp> #include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/basic_deadline_timer.hpp b/3rdParty/Boost/src/boost/asio/basic_deadline_timer.hpp index 1284daa..dc471e2 100644 --- a/3rdParty/Boost/src/boost/asio/basic_deadline_timer.hpp +++ b/3rdParty/Boost/src/boost/asio/basic_deadline_timer.hpp @@ -15,17 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/basic_io_object.hpp> #include <boost/asio/deadline_timer_service.hpp> -#include <boost/asio/error.hpp> #include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/basic_io_object.hpp b/3rdParty/Boost/src/boost/asio/basic_io_object.hpp index 3cb6b68..414f365 100644 --- a/3rdParty/Boost/src/boost/asio/basic_io_object.hpp +++ b/3rdParty/Boost/src/boost/asio/basic_io_object.hpp @@ -15,10 +15,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/io_service.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/io_service.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/basic_raw_socket.hpp b/3rdParty/Boost/src/boost/asio/basic_raw_socket.hpp index 09810d4..0b877de 100644 --- a/3rdParty/Boost/src/boost/asio/basic_raw_socket.hpp +++ b/3rdParty/Boost/src/boost/asio/basic_raw_socket.hpp @@ -15,17 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/basic_socket.hpp> -#include <boost/asio/raw_socket_service.hpp> -#include <boost/asio/error.hpp> #include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/raw_socket_service.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/basic_serial_port.hpp b/3rdParty/Boost/src/boost/asio/basic_serial_port.hpp index 539119a..4936c9c 100644 --- a/3rdParty/Boost/src/boost/asio/basic_serial_port.hpp +++ b/3rdParty/Boost/src/boost/asio/basic_serial_port.hpp @@ -16,21 +16,19 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <string> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \ + || defined(GENERATING_DOCUMENTATION) +#include <string> #include <boost/asio/basic_io_object.hpp> +#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> #include <boost/asio/serial_port_base.hpp> #include <boost/asio/serial_port_service.hpp> -#include <boost/asio/detail/throw_error.hpp> -#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \ - || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -616,9 +614,9 @@ public: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_BASIC_SERIAL_PORT_HPP diff --git a/3rdParty/Boost/src/boost/asio/basic_socket.hpp b/3rdParty/Boost/src/boost/asio/basic_socket.hpp index 6b89623..50a0c47 100644 --- a/3rdParty/Boost/src/boost/asio/basic_socket.hpp +++ b/3rdParty/Boost/src/boost/asio/basic_socket.hpp @@ -15,16 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/basic_io_object.hpp> +#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> #include <boost/asio/socket_base.hpp> -#include <boost/asio/detail/throw_error.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/basic_socket_acceptor.hpp b/3rdParty/Boost/src/boost/asio/basic_socket_acceptor.hpp index d23dc33..5192df7 100644 --- a/3rdParty/Boost/src/boost/asio/basic_socket_acceptor.hpp +++ b/3rdParty/Boost/src/boost/asio/basic_socket_acceptor.hpp @@ -15,14 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/basic_io_object.hpp> #include <boost/asio/basic_socket.hpp> +#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> #include <boost/asio/socket_acceptor_service.hpp> #include <boost/asio/socket_base.hpp> -#include <boost/asio/detail/throw_error.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/basic_socket_iostream.hpp b/3rdParty/Boost/src/boost/asio/basic_socket_iostream.hpp index e4c7ec1..a8cea4f 100644 --- a/3rdParty/Boost/src/boost/asio/basic_socket_iostream.hpp +++ b/3rdParty/Boost/src/boost/asio/basic_socket_iostream.hpp @@ -15,22 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_NO_IOSTREAM) -#include <boost/asio/detail/push_options.hpp> #include <boost/preprocessor/arithmetic/inc.hpp> #include <boost/preprocessor/repetition/enum_binary_params.hpp> #include <boost/preprocessor/repetition/enum_params.hpp> #include <boost/preprocessor/repetition/repeat_from_to.hpp> #include <boost/utility/base_from_member.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/basic_socket_streambuf.hpp> #include <boost/asio/stream_socket_service.hpp> @@ -79,6 +72,8 @@ } \ /**/ +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { @@ -148,11 +143,11 @@ public: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #undef BOOST_ASIO_PRIVATE_CTR_DEF #undef BOOST_ASIO_PRIVATE_CONNECT_DEF #endif // defined(BOOST_NO_IOSTREAM) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP diff --git a/3rdParty/Boost/src/boost/asio/basic_socket_streambuf.hpp b/3rdParty/Boost/src/boost/asio/basic_socket_streambuf.hpp index 695e8e1..35e96d0 100644 --- a/3rdParty/Boost/src/boost/asio/basic_socket_streambuf.hpp +++ b/3rdParty/Boost/src/boost/asio/basic_socket_streambuf.hpp @@ -15,15 +15,10 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_NO_IOSTREAM) -#include <boost/asio/detail/push_options.hpp> #include <streambuf> #include <boost/array.hpp> #include <boost/preprocessor/arithmetic/inc.hpp> @@ -31,12 +26,10 @@ #include <boost/preprocessor/repetition/enum_params.hpp> #include <boost/preprocessor/repetition/repeat_from_to.hpp> #include <boost/utility/base_from_member.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/basic_socket.hpp> +#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/io_service.hpp> #include <boost/asio/stream_socket_service.hpp> -#include <boost/asio/detail/throw_error.hpp> #if !defined(BOOST_ASIO_SOCKET_STREAMBUF_MAX_ARITY) #define BOOST_ASIO_SOCKET_STREAMBUF_MAX_ARITY 5 @@ -74,6 +67,8 @@ } \ /**/ +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { @@ -288,10 +283,10 @@ private: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #undef BOOST_ASIO_PRIVATE_CONNECT_DEF #endif // !defined(BOOST_NO_IOSTREAM) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_BASIC_SOCKET_STREAMBUF_HPP diff --git a/3rdParty/Boost/src/boost/asio/basic_stream_socket.hpp b/3rdParty/Boost/src/boost/asio/basic_stream_socket.hpp index 15658bc..956d623 100644 --- a/3rdParty/Boost/src/boost/asio/basic_stream_socket.hpp +++ b/3rdParty/Boost/src/boost/asio/basic_stream_socket.hpp @@ -15,17 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/basic_socket.hpp> +#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> #include <boost/asio/stream_socket_service.hpp> -#include <boost/asio/detail/throw_error.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/basic_streambuf.hpp b/3rdParty/Boost/src/boost/asio/basic_streambuf.hpp index e5f8a8d..546a4ac 100644 --- a/3rdParty/Boost/src/boost/asio/basic_streambuf.hpp +++ b/3rdParty/Boost/src/boost/asio/basic_streambuf.hpp @@ -15,28 +15,23 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_NO_IOSTREAM) -#include <boost/asio/detail/push_options.hpp> #include <algorithm> #include <cstring> -#include <memory> #include <stdexcept> #include <streambuf> #include <vector> #include <boost/limits.hpp> #include <boost/throw_exception.hpp> -#include <boost/asio/detail/pop_options.hpp> - +#include <boost/asio/basic_streambuf_fwd.hpp> #include <boost/asio/buffer.hpp> #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { @@ -108,7 +103,11 @@ namespace asio { * is >> s; * @endcode */ +#if defined(GENERATING_DOCUMENTATION) template <typename Allocator = std::allocator<char> > +#else +template <typename Allocator> +#endif class basic_streambuf : public std::streambuf, private noncopyable @@ -338,8 +337,27 @@ protected: private: std::size_t max_size_; std::vector<char_type, Allocator> buffer_; + + // Helper function to get the preferred size for reading data. + friend std::size_t read_size_helper( + basic_streambuf& sb, std::size_t max_size) + { + return std::min<std::size_t>( + std::max<std::size_t>(512, sb.buffer_.capacity() - sb.size()), + std::min<std::size_t>(max_size, sb.max_size() - sb.size())); + } }; +// Helper function to get the preferred size for reading data. Used for any +// user-provided specialisations of basic_streambuf. +template <typename Allocator> +inline std::size_t read_size_helper( + basic_streambuf<Allocator>& sb, std::size_t max_size) +{ + return std::min<std::size_t>(512, + std::min<std::size_t>(max_size, sb.max_size() - sb.size())); +} + } // namespace asio } // namespace boost diff --git a/3rdParty/Boost/src/boost/asio/basic_streambuf_fwd.hpp b/3rdParty/Boost/src/boost/asio/basic_streambuf_fwd.hpp new file mode 100644 index 0000000..215937e --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/basic_streambuf_fwd.hpp @@ -0,0 +1,35 @@ +// +// basic_streambuf_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_BASIC_STREAMBUF_FWD_HPP +#define BOOST_ASIO_BASIC_STREAMBUF_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if !defined(BOOST_NO_IOSTREAM) + +#include <memory> + +namespace boost { +namespace asio { + +template <typename Allocator = std::allocator<char> > +class basic_streambuf; + +} // namespace asio +} // namespace boost + +#endif // !defined(BOOST_NO_IOSTREAM) + +#endif // BOOST_ASIO_BASIC_STREAMBUF_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/buffer.hpp b/3rdParty/Boost/src/boost/asio/buffer.hpp index 3fe8192..f925361 100644 --- a/3rdParty/Boost/src/boost/asio/buffer.hpp +++ b/3rdParty/Boost/src/boost/asio/buffer.hpp @@ -15,16 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/array.hpp> -#include <boost/type_traits/is_const.hpp> #include <string> #include <vector> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/asio/detail/array_fwd.hpp> #if defined(BOOST_MSVC) # if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0) @@ -43,11 +39,17 @@ #endif // defined(__GNUC__) #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) -# include <boost/asio/detail/push_options.hpp> # include <boost/function.hpp> -# include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \ + || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) +# include <boost/type_traits/is_const.hpp> +#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) + // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) + +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/buffered_read_stream.hpp b/3rdParty/Boost/src/boost/asio/buffered_read_stream.hpp index d7bf6ff..935f5b9 100644 --- a/3rdParty/Boost/src/boost/asio/buffered_read_stream.hpp +++ b/3rdParty/Boost/src/boost/asio/buffered_read_stream.hpp @@ -15,23 +15,20 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> #include <cstring> -#include <boost/config.hpp> #include <boost/type_traits/remove_reference.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/buffered_read_stream_fwd.hpp> #include <boost/asio/buffer.hpp> -#include <boost/asio/error.hpp> -#include <boost/asio/io_service.hpp> #include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/buffer_resize_guard.hpp> #include <boost/asio/detail/buffered_stream_storage.hpp> #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/io_service.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/buffered_read_stream_fwd.hpp b/3rdParty/Boost/src/boost/asio/buffered_read_stream_fwd.hpp index 8eb24f8..87f27d9 100644 --- a/3rdParty/Boost/src/boost/asio/buffered_read_stream_fwd.hpp +++ b/3rdParty/Boost/src/boost/asio/buffered_read_stream_fwd.hpp @@ -15,8 +15,6 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - namespace boost { namespace asio { @@ -26,6 +24,4 @@ class buffered_read_stream; } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_BUFFERED_READ_STREAM_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/buffered_stream.hpp b/3rdParty/Boost/src/boost/asio/buffered_stream.hpp index 0cbc280..ceeb6f2 100644 --- a/3rdParty/Boost/src/boost/asio/buffered_stream.hpp +++ b/3rdParty/Boost/src/boost/asio/buffered_stream.hpp @@ -15,19 +15,16 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/buffered_read_stream.hpp> #include <boost/asio/buffered_write_stream.hpp> #include <boost/asio/buffered_stream_fwd.hpp> +#include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> -#include <boost/asio/detail/noncopyable.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/buffered_stream_fwd.hpp b/3rdParty/Boost/src/boost/asio/buffered_stream_fwd.hpp index 066f52c..d23bc26 100644 --- a/3rdParty/Boost/src/boost/asio/buffered_stream_fwd.hpp +++ b/3rdParty/Boost/src/boost/asio/buffered_stream_fwd.hpp @@ -15,8 +15,6 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - namespace boost { namespace asio { @@ -26,6 +24,4 @@ class buffered_stream; } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_BUFFERED_STREAM_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/buffered_write_stream.hpp b/3rdParty/Boost/src/boost/asio/buffered_write_stream.hpp index fb38b25..c918a0a 100644 --- a/3rdParty/Boost/src/boost/asio/buffered_write_stream.hpp +++ b/3rdParty/Boost/src/boost/asio/buffered_write_stream.hpp @@ -15,24 +15,21 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> #include <cstring> -#include <boost/config.hpp> #include <boost/type_traits/remove_reference.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/buffered_write_stream_fwd.hpp> #include <boost/asio/buffer.hpp> #include <boost/asio/completion_condition.hpp> -#include <boost/asio/error.hpp> -#include <boost/asio/io_service.hpp> -#include <boost/asio/write.hpp> #include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/buffered_stream_storage.hpp> #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/write.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/buffered_write_stream_fwd.hpp b/3rdParty/Boost/src/boost/asio/buffered_write_stream_fwd.hpp index 74cdb83..8f0f409 100644 --- a/3rdParty/Boost/src/boost/asio/buffered_write_stream_fwd.hpp +++ b/3rdParty/Boost/src/boost/asio/buffered_write_stream_fwd.hpp @@ -15,8 +15,6 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - namespace boost { namespace asio { @@ -26,6 +24,4 @@ class buffered_write_stream; } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_BUFFERED_WRITE_STREAM_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/buffers_iterator.hpp b/3rdParty/Boost/src/boost/asio/buffers_iterator.hpp index 0b654b8..1ffd02d 100644 --- a/3rdParty/Boost/src/boost/asio/buffers_iterator.hpp +++ b/3rdParty/Boost/src/boost/asio/buffers_iterator.hpp @@ -15,20 +15,17 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> #include <boost/assert.hpp> -#include <boost/config.hpp> #include <boost/detail/workaround.hpp> #include <boost/iterator.hpp> #include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/add_const.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/buffer.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { @@ -211,6 +208,15 @@ public: return tmp; } + /// Addition operator. + friend buffers_iterator operator+(std::ptrdiff_t difference, + const buffers_iterator& iter) + { + buffers_iterator tmp(iter); + tmp.advance(difference); + return tmp; + } + /// Subtraction operator. friend buffers_iterator operator-(const buffers_iterator& iter, std::ptrdiff_t difference) diff --git a/3rdParty/Boost/src/boost/asio/completion_condition.hpp b/3rdParty/Boost/src/boost/asio/completion_condition.hpp index 747591c..dfb48ed 100644 --- a/3rdParty/Boost/src/boost/asio/completion_condition.hpp +++ b/3rdParty/Boost/src/boost/asio/completion_condition.hpp @@ -15,12 +15,10 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> +#include <cstddef> #include <boost/asio/detail/push_options.hpp> -#include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/datagram_socket_service.hpp b/3rdParty/Boost/src/boost/asio/datagram_socket_service.hpp index 74bf703..4d324e2 100644 --- a/3rdParty/Boost/src/boost/asio/datagram_socket_service.hpp +++ b/3rdParty/Boost/src/boost/asio/datagram_socket_service.hpp @@ -15,16 +15,10 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> -#include <boost/asio/detail/service_base.hpp> #if defined(BOOST_ASIO_HAS_IOCP) # include <boost/asio/detail/win_iocp_socket_service.hpp> @@ -32,6 +26,8 @@ # include <boost/asio/detail/reactive_socket_service.hpp> #endif +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/deadline_timer.hpp b/3rdParty/Boost/src/boost/asio/deadline_timer.hpp index 7f8d1e3..3ed7b67 100644 --- a/3rdParty/Boost/src/boost/asio/deadline_timer.hpp +++ b/3rdParty/Boost/src/boost/asio/deadline_timer.hpp @@ -15,16 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/socket_types.hpp> // Must come before posix_time. +#include <boost/asio/basic_deadline_timer.hpp> #include <boost/asio/detail/push_options.hpp> #include <boost/date_time/posix_time/posix_time_types.hpp> #include <boost/asio/detail/pop_options.hpp> -#include <boost/asio/basic_deadline_timer.hpp> - namespace boost { namespace asio { @@ -34,6 +32,4 @@ typedef basic_deadline_timer<boost::posix_time::ptime> deadline_timer; } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DEADLINE_TIMER_HPP diff --git a/3rdParty/Boost/src/boost/asio/deadline_timer_service.hpp b/3rdParty/Boost/src/boost/asio/deadline_timer_service.hpp index 624791d..77060c4 100644 --- a/3rdParty/Boost/src/boost/asio/deadline_timer_service.hpp +++ b/3rdParty/Boost/src/boost/asio/deadline_timer_service.hpp @@ -15,17 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - +#include <boost/asio/detail/deadline_timer_service.hpp> #include <boost/asio/io_service.hpp> #include <boost/asio/time_traits.hpp> -#include <boost/asio/detail/deadline_timer_service.hpp> -#include <boost/asio/detail/service_base.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/detail/array_fwd.hpp b/3rdParty/Boost/src/boost/asio/detail/array_fwd.hpp new file mode 100644 index 0000000..3d47a9a --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/array_fwd.hpp @@ -0,0 +1,25 @@ +// +// detail/array_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_ARRAY_FWD_HPP +#define BOOST_ASIO_DETAIL_ARRAY_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +namespace boost { + +template<class T, std::size_t N> +class array; + +} // namespace boost + +#endif // BOOST_ASIO_DETAIL_ARRAY_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/base_from_completion_cond.hpp b/3rdParty/Boost/src/boost/asio/detail/base_from_completion_cond.hpp index 1b1f142..797e3ce 100644 --- a/3rdParty/Boost/src/boost/asio/detail/base_from_completion_cond.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/base_from_completion_cond.hpp @@ -1,6 +1,6 @@ // -// base_from_completion_cond.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/base_from_completion_cond.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,10 +15,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/completion_condition.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -32,7 +33,8 @@ protected: { } - std::size_t check(const boost::system::error_code& ec, + std::size_t check_for_completion( + const boost::system::error_code& ec, std::size_t total_transferred) { return detail::adapt_completion_condition_result( @@ -51,7 +53,8 @@ protected: { } - static std::size_t check(const boost::system::error_code& ec, + static std::size_t check_for_completion( + const boost::system::error_code& ec, std::size_t total_transferred) { return transfer_all_t()(ec, total_transferred); diff --git a/3rdParty/Boost/src/boost/asio/detail/bind_handler.hpp b/3rdParty/Boost/src/boost/asio/detail/bind_handler.hpp index e161893..6b515db 100644 --- a/3rdParty/Boost/src/boost/asio/detail/bind_handler.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/bind_handler.hpp @@ -1,6 +1,6 @@ // -// bind_handler.hpp -// ~~~~~~~~~~~~~~~~ +// detail/bind_handler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,11 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -36,7 +37,7 @@ public: void operator()() { - handler_(arg1_); + handler_(static_cast<const Arg1&>(arg1_)); } void operator()() const @@ -93,7 +94,8 @@ public: void operator()() { - handler_(arg1_, arg2_); + handler_(static_cast<const Arg1&>(arg1_), + static_cast<const Arg2&>(arg2_)); } void operator()() const @@ -153,7 +155,9 @@ public: void operator()() { - handler_(arg1_, arg2_, arg3_); + handler_(static_cast<const Arg1&>(arg1_), + static_cast<const Arg2&>(arg2_), + static_cast<const Arg3&>(arg3_)); } void operator()() const @@ -217,7 +221,10 @@ public: void operator()() { - handler_(arg1_, arg2_, arg3_, arg4_); + handler_(static_cast<const Arg1&>(arg1_), + static_cast<const Arg2&>(arg2_), + static_cast<const Arg3&>(arg3_), + static_cast<const Arg4&>(arg4_)); } void operator()() const @@ -288,7 +295,11 @@ public: void operator()() { - handler_(arg1_, arg2_, arg3_, arg4_, arg5_); + handler_(static_cast<const Arg1&>(arg1_), + static_cast<const Arg2&>(arg2_), + static_cast<const Arg3&>(arg3_), + static_cast<const Arg4&>(arg4_), + static_cast<const Arg5&>(arg5_)); } void operator()() const diff --git a/3rdParty/Boost/src/boost/asio/detail/buffer_resize_guard.hpp b/3rdParty/Boost/src/boost/asio/detail/buffer_resize_guard.hpp index af67c46..bcffc1a 100644 --- a/3rdParty/Boost/src/boost/asio/detail/buffer_resize_guard.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/buffer_resize_guard.hpp @@ -1,6 +1,6 @@ // -// buffer_resize_guard.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~ +// detail/buffer_resize_guard.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,12 +15,10 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> +#include <boost/limits.hpp> #include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/limits.hpp> -#include <boost/asio/detail/pop_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/detail/buffer_sequence_adapter.hpp b/3rdParty/Boost/src/boost/asio/detail/buffer_sequence_adapter.hpp index ce9652e..214cd41 100644 --- a/3rdParty/Boost/src/boost/asio/detail/buffer_sequence_adapter.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/buffer_sequence_adapter.hpp @@ -1,6 +1,6 @@ // -// buffer_sequence_adapter.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/buffer_sequence_adapter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,9 +15,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/buffer.hpp> +#include <boost/asio/detail/socket_types.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -33,14 +35,14 @@ protected: const boost::asio::mutable_buffer& buffer) { buf.buf = boost::asio::buffer_cast<char*>(buffer); - buf.len = boost::asio::buffer_size(buffer); + buf.len = static_cast<ULONG>(boost::asio::buffer_size(buffer)); } static void init_native_buffer(WSABUF& buf, const boost::asio::const_buffer& buffer) { buf.buf = const_cast<char*>(boost::asio::buffer_cast<const char*>(buffer)); - buf.len = boost::asio::buffer_size(buffer); + buf.len = static_cast<ULONG>(boost::asio::buffer_size(buffer)); } #else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) typedef iovec native_buffer_type; @@ -159,7 +161,7 @@ public: explicit buffer_sequence_adapter( const boost::asio::mutable_buffers_1& buffers) { - init_native_buffer(buffer_, buffers); + init_native_buffer(buffer_, Buffer(buffers)); total_buffer_size_ = boost::asio::buffer_size(buffers); } @@ -206,7 +208,7 @@ public: explicit buffer_sequence_adapter( const boost::asio::const_buffers_1& buffers) { - init_native_buffer(buffer_, buffers); + init_native_buffer(buffer_, Buffer(buffers)); total_buffer_size_ = boost::asio::buffer_size(buffers); } diff --git a/3rdParty/Boost/src/boost/asio/detail/buffered_stream_storage.hpp b/3rdParty/Boost/src/boost/asio/detail/buffered_stream_storage.hpp index 9b83426..9a2929e 100644 --- a/3rdParty/Boost/src/boost/asio/detail/buffered_stream_storage.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/buffered_stream_storage.hpp @@ -1,6 +1,6 @@ // -// buffered_stream_storage.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/buffered_stream_storage.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,15 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> +#include <boost/asio/detail/config.hpp> #include <cassert> #include <cstddef> #include <cstring> #include <vector> -#include <boost/asio/detail/pop_options.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/detail/call_stack.hpp b/3rdParty/Boost/src/boost/asio/detail/call_stack.hpp index 0d7d52c..561a826 100644 --- a/3rdParty/Boost/src/boost/asio/detail/call_stack.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/call_stack.hpp @@ -1,6 +1,6 @@ // -// call_stack.hpp -// ~~~~~~~~~~~~~~ +// detail/call_stack.hpp +// ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,11 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/tss_ptr.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { diff --git a/3rdParty/Boost/src/boost/asio/detail/completion_handler.hpp b/3rdParty/Boost/src/boost/asio/detail/completion_handler.hpp index d78e6c8..6701fb3 100644 --- a/3rdParty/Boost/src/boost/asio/detail/completion_handler.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/completion_handler.hpp @@ -1,6 +1,6 @@ // -// completion_handler.hpp -// ~~~~~~~~~~~~~~~~~~~~~~ +// detail/completion_handler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,13 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/fenced_block.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> #include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -30,6 +31,8 @@ template <typename Handler> class completion_handler : public operation { public: + BOOST_ASIO_DEFINE_HANDLER_PTR(completion_handler); + completion_handler(Handler h) : operation(&completion_handler::do_complete), handler_(h) @@ -41,20 +44,21 @@ public: { // Take ownership of the handler object. completion_handler* h(static_cast<completion_handler*>(base)); - typedef handler_alloc_traits<Handler, completion_handler> alloc_traits; - handler_ptr<alloc_traits> ptr(h->handler_, h); + ptr p = { boost::addressof(h->handler_), h, h }; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + Handler handler(h->handler_); + p.h = boost::addressof(handler); + p.reset(); // Make the upcall if required. if (owner) { - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - Handler handler(h->handler_); - ptr.reset(); boost::asio::detail::fenced_block b; boost_asio_handler_invoke_helpers::invoke(handler, handler); } diff --git a/3rdParty/Boost/src/boost/asio/detail/config.hpp b/3rdParty/Boost/src/boost/asio/detail/config.hpp new file mode 100644 index 0000000..abd2044 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/config.hpp @@ -0,0 +1,205 @@ +// +// detail/config.hpp +// ~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_CONFIG_HPP +#define BOOST_ASIO_DETAIL_CONFIG_HPP + +#include <boost/config.hpp> + +// Default to a header-only implementation. The user must specifically request +// separate compilation by defining either BOOST_ASIO_SEPARATE_COMPILATION or +// BOOST_ASIO_DYN_LINK (as a DLL/shared library implies separate compilation). +#if !defined(BOOST_ASIO_HEADER_ONLY) +# if !defined(BOOST_ASIO_SEPARATE_COMPILATION) +# if !defined(BOOST_ASIO_DYN_LINK) +# define BOOST_ASIO_HEADER_ONLY +# endif // !defined(BOOST_ASIO_DYN_LINK) +# endif // !defined(BOOST_ASIO_SEPARATE_COMPILATION) +#endif // !defined(BOOST_ASIO_HEADER_ONLY) + +#if defined(BOOST_ASIO_HEADER_ONLY) +# define BOOST_ASIO_DECL inline +#else // defined(BOOST_ASIO_HEADER_ONLY) +# if defined(BOOST_HAS_DECLSPEC) +// We need to import/export our code only if the user has specifically asked +// for it by defining BOOST_ASIO_DYN_LINK. +# if defined(BOOST_ASIO_DYN_LINK) +// Export if this is our own source, otherwise import. +# if defined(BOOST_ASIO_SOURCE) +# define BOOST_ASIO_DECL __declspec(dllexport) +# else // defined(BOOST_ASIO_SOURCE) +# define BOOST_ASIO_DECL __declspec(dllimport) +# endif // defined(BOOST_ASIO_SOURCE) +# endif // defined(BOOST_ASIO_DYN_LINK) +# endif // defined(BOOST_HAS_DECLSPEC) +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +// If BOOST_ASIO_DECL isn't defined yet define it now. +#if !defined(BOOST_ASIO_DECL) +# define BOOST_ASIO_DECL +#endif // !defined(BOOST_ASIO_DECL) + +// Windows: target OS version. +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) +# if defined(_MSC_VER) || defined(__BORLANDC__) +# pragma message( \ + "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\ + "- add -D_WIN32_WINNT=0x0501 to the compiler command line; or\n"\ + "- add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.\n"\ + "Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).") +# else // defined(_MSC_VER) || defined(__BORLANDC__) +# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. +# warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line. +# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target). +# endif // defined(_MSC_VER) || defined(__BORLANDC__) +# define _WIN32_WINNT 0x0501 +# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) +# if defined(_MSC_VER) +# if defined(_WIN32) && !defined(WIN32) +# if !defined(_WINSOCK2API_) +# define WIN32 // Needed for correct types in winsock2.h +# else // !defined(_WINSOCK2API_) +# error Please define the macro WIN32 in your compiler options +# endif // !defined(_WINSOCK2API_) +# endif // defined(_WIN32) && !defined(WIN32) +# endif // defined(_MSC_VER) +# if defined(__BORLANDC__) +# if defined(__WIN32__) && !defined(WIN32) +# if !defined(_WINSOCK2API_) +# define WIN32 // Needed for correct types in winsock2.h +# else // !defined(_WINSOCK2API_) +# error Please define the macro WIN32 in your compiler options +# endif // !defined(_WINSOCK2API_) +# endif // defined(__WIN32__) && !defined(WIN32) +# endif // defined(__BORLANDC__) +# if defined(__CYGWIN__) +# if !defined(__USE_W32_SOCKETS) +# error You must add -D__USE_W32_SOCKETS to your compiler options. +# endif // !defined(__USE_W32_SOCKETS) +# endif // defined(__CYGWIN__) +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +// Windows: minimise header inclusion. +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if !defined(BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN) +# if !defined(WIN32_LEAN_AND_MEAN) +# define WIN32_LEAN_AND_MEAN +# endif // !defined(WIN32_LEAN_AND_MEAN) +# endif // !defined(BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN) +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +// Windows: suppress definition of "min" and "max" macros. +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if !defined(BOOST_ASIO_NO_NOMINMAX) +# if !defined(NOMINMAX) +# define NOMINMAX 1 +# endif // !defined(NOMINMAX) +# endif // !defined(BOOST_ASIO_NO_NOMINMAX) +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +// Windows: IO Completion Ports. +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400) +# if !defined(UNDER_CE) +# if !defined(BOOST_ASIO_DISABLE_IOCP) +# define BOOST_ASIO_HAS_IOCP 1 +# endif // !defined(BOOST_ASIO_DISABLE_IOCP) +# endif // !defined(UNDER_CE) +# endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400) +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +// Linux: epoll, eventfd and timerfd. +#if defined(__linux__) +# include <linux/version.h> +# if !defined(BOOST_ASIO_DISABLE_EPOLL) +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45) +# define BOOST_ASIO_HAS_EPOLL 1 +# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45) +# endif // !defined(BOOST_ASIO_DISABLE_EVENTFD) +# if !defined(BOOST_ASIO_DISABLE_EVENTFD) +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +# define BOOST_ASIO_HAS_EVENTFD 1 +# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +# endif // !defined(BOOST_ASIO_DISABLE_EVENTFD) +# if defined(BOOST_ASIO_HAS_EPOLL) +# if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) +# define BOOST_ASIO_HAS_TIMERFD 1 +# endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) +# endif // defined(BOOST_ASIO_HAS_EPOLL) +#endif // defined(__linux__) + +// Mac OS X, FreeBSD, NetBSD, OpenBSD: kqueue. +#if (defined(__MACH__) && defined(__APPLE__)) \ + || defined(__FreeBSD__) \ + || defined(__NetBSD__) \ + || defined(__OpenBSD__) +# if !defined(BOOST_ASIO_DISABLE_KQUEUE) +# define BOOST_ASIO_HAS_KQUEUE 1 +# endif // !defined(BOOST_ASIO_DISABLE_KQUEUE) +#endif // (defined(__MACH__) && defined(__APPLE__)) + // || defined(__FreeBSD__) + // || defined(__NetBSD__) + // || defined(__OpenBSD__) + +// Solaris: /dev/poll. +#if defined(__sun) +# if !defined(BOOST_ASIO_DISABLE_DEV_POLL) +# define BOOST_ASIO_HAS_DEV_POLL 1 +# endif // !defined(BOOST_ASIO_DISABLE_DEV_POLL) +#endif // defined(__sun) + +// Serial ports. +#if defined(BOOST_ASIO_HAS_IOCP) \ + || !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +# if !defined(__SYMBIAN32__) +# if !defined(BOOST_ASIO_DISABLE_SERIAL_PORT) +# define BOOST_ASIO_HAS_SERIAL_PORT 1 +# endif // !defined(BOOST_ASIO_DISABLE_SERIAL_PORT) +# endif // !defined(__SYMBIAN32__) +#endif // defined(BOOST_ASIO_HAS_IOCP) + // || !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +// Windows: stream handles. +#if !defined(BOOST_ASIO_DISABLE_WINDOWS_STREAM_HANDLE) +# if defined(BOOST_ASIO_HAS_IOCP) +# define BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE 1 +# endif // defined(BOOST_ASIO_HAS_IOCP) +#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_STREAM_HANDLE) + +// Windows: random access handles. +#if !defined(BOOST_ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE) +# if defined(BOOST_ASIO_HAS_IOCP) +# define BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE 1 +# endif // defined(BOOST_ASIO_HAS_IOCP) +#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE) + +// Windows: OVERLAPPED wrapper. +#if !defined(BOOST_ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR) +# if defined(BOOST_ASIO_HAS_IOCP) +# define BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1 +# endif // defined(BOOST_ASIO_HAS_IOCP) +#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR) + +// POSIX: stream-oriented file descriptors. +#if !defined(BOOST_ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR) +# if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +# define BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR 1 +# endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR) + +// UNIX domain sockets. +#if !defined(BOOST_ASIO_DISABLE_LOCAL_SOCKETS) +# if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +# define BOOST_ASIO_HAS_LOCAL_SOCKETS 1 +# endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_DISABLE_LOCAL_SOCKETS) + +#endif // BOOST_ASIO_DETAIL_CONFIG_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/consuming_buffers.hpp b/3rdParty/Boost/src/boost/asio/detail/consuming_buffers.hpp index 3604cba..23114a0 100644 --- a/3rdParty/Boost/src/boost/asio/detail/consuming_buffers.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/consuming_buffers.hpp @@ -1,6 +1,6 @@ // -// consuming_buffers.hpp -// ~~~~~~~~~~~~~~~~~~~~~ +// detail/consuming_buffers.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,18 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <algorithm> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> #include <boost/iterator.hpp> #include <boost/limits.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/buffer.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -157,12 +153,14 @@ public: consuming_buffers(const Buffers& buffers) : buffers_(buffers), at_end_(buffers_.begin() == buffers_.end()), - first_(*buffers_.begin()), begin_remainder_(buffers_.begin()), max_size_((std::numeric_limits<std::size_t>::max)()) { if (!at_end_) + { + first_ = *buffers_.begin(); ++begin_remainder_; + } } // Copy constructor. diff --git a/3rdParty/Boost/src/boost/asio/detail/deadline_timer_service.hpp b/3rdParty/Boost/src/boost/asio/detail/deadline_timer_service.hpp index 5ba21b1..c391824 100644 --- a/3rdParty/Boost/src/boost/asio/detail/deadline_timer_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/deadline_timer_service.hpp @@ -1,6 +1,6 @@ // -// deadline_timer_service.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/deadline_timer_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,14 +15,8 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/date_time/posix_time/posix_time_types.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> #include <boost/asio/detail/bind_handler.hpp> @@ -33,6 +27,13 @@ #include <boost/asio/detail/timer_op.hpp> #include <boost/asio/detail/timer_queue.hpp> #include <boost/asio/detail/timer_scheduler.hpp> +#include <boost/asio/detail/wait_handler.hpp> + +#include <boost/asio/detail/push_options.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> +#include <boost/asio/detail/pop_options.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -55,6 +56,7 @@ public: { time_type expiry; bool might_have_pending_waits; + typename timer_queue<Time_Traits>::per_timer_data timer_data; }; // Constructor. @@ -98,7 +100,7 @@ public: ec = boost::system::error_code(); return 0; } - std::size_t count = scheduler_.cancel_timer(timer_queue_, &impl); + std::size_t count = scheduler_.cancel_timer(timer_queue_, impl.timer_data); impl.might_have_pending_waits = false; ec = boost::system::error_code(); return count; @@ -152,59 +154,21 @@ public: ec = boost::system::error_code(); } - template <typename Handler> - class wait_handler : public timer_op - { - public: - wait_handler(Handler handler) - : timer_op(&wait_handler::do_complete), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - wait_handler* h(static_cast<wait_handler*>(base)); - typedef handler_alloc_traits<Handler, wait_handler> alloc_traits; - handler_ptr<alloc_traits> ptr(h->handler_, h); - - // Make the upcall if required. - if (owner) - { - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder1<Handler, boost::system::error_code> - handler(h->handler_, h->ec_); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - Handler handler_; - }; - // Start an asynchronous wait on the timer. template <typename Handler> void async_wait(implementation_type& impl, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef wait_handler<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); + typedef wait_handler<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); impl.might_have_pending_waits = true; - scheduler_.schedule_timer(timer_queue_, impl.expiry, ptr.get(), &impl); - ptr.release(); + scheduler_.schedule_timer(timer_queue_, impl.expiry, impl.timer_data, p.p); + p.v = p.p = 0; } private: diff --git a/3rdParty/Boost/src/boost/asio/detail/descriptor_ops.hpp b/3rdParty/Boost/src/boost/asio/detail/descriptor_ops.hpp index c4969f7..4f82cd6 100644 --- a/3rdParty/Boost/src/boost/asio/detail/descriptor_ops.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/descriptor_ops.hpp @@ -1,6 +1,6 @@ // -// descriptor_ops.hpp -// ~~~~~~~~~~~~~~~~~~ +// detail/descriptor_ops.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,28 +15,35 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <cerrno> -#include <boost/asio/detail/pop_options.hpp> +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) -#include <boost/asio/error.hpp> +#include <cstddef> +#include <boost/system/error_code.hpp> #include <boost/asio/detail/socket_types.hpp> -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace detail { namespace descriptor_ops { -inline void clear_error(boost::system::error_code& ec) +// Descriptor state bits. +enum { - errno = 0; - ec = boost::system::error_code(); -} + // The user wants a non-blocking descriptor. + user_set_non_blocking = 1, + + // The descriptor has been set non-blocking. + internal_non_blocking = 2, + + // Helper "state" used to determine whether the descriptor is non-blocking. + non_blocking = user_set_non_blocking | internal_non_blocking +}; + +typedef unsigned char state_type; template <typename ReturnType> inline ReturnType error_wrapper(ReturnType return_value, @@ -47,132 +54,54 @@ inline ReturnType error_wrapper(ReturnType return_value, return return_value; } -inline int open(const char* path, int flags, boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(::open(path, flags), ec); - if (result >= 0) - clear_error(ec); - return result; -} +BOOST_ASIO_DECL int open(const char* path, int flags, + boost::system::error_code& ec); -inline int close(int d, boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(::close(d), ec); - if (result == 0) - clear_error(ec); - return result; -} +BOOST_ASIO_DECL int close(int d, state_type& state, + boost::system::error_code& ec); -inline void init_buf_iov_base(void*& base, void* addr) -{ - base = addr; -} - -template <typename T> -inline void init_buf_iov_base(T& base, void* addr) -{ - base = static_cast<T>(addr); -} +BOOST_ASIO_DECL bool set_internal_non_blocking(int d, + state_type& state, boost::system::error_code& ec); typedef iovec buf; -inline void init_buf(buf& b, void* data, size_t size) -{ - init_buf_iov_base(b.iov_base, data); - b.iov_len = size; -} +BOOST_ASIO_DECL std::size_t sync_read(int d, state_type state, buf* bufs, + std::size_t count, bool all_empty, boost::system::error_code& ec); -inline void init_buf(buf& b, const void* data, size_t size) -{ - init_buf_iov_base(b.iov_base, const_cast<void*>(data)); - b.iov_len = size; -} +BOOST_ASIO_DECL bool non_blocking_read(int d, buf* bufs, std::size_t count, + boost::system::error_code& ec, std::size_t& bytes_transferred); -inline int scatter_read(int d, buf* bufs, size_t count, - boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(::readv(d, bufs, static_cast<int>(count)), ec); - if (result >= 0) - clear_error(ec); - return result; -} +BOOST_ASIO_DECL std::size_t sync_write(int d, state_type state, + const buf* bufs, std::size_t count, bool all_empty, + boost::system::error_code& ec); -inline int gather_write(int d, const buf* bufs, size_t count, - boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(::writev(d, bufs, static_cast<int>(count)), ec); - if (result >= 0) - clear_error(ec); - return result; -} +BOOST_ASIO_DECL bool non_blocking_write(int d, + const buf* bufs, std::size_t count, + boost::system::error_code& ec, std::size_t& bytes_transferred); -inline int ioctl(int d, long cmd, ioctl_arg_type* arg, - boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(::ioctl(d, cmd, arg), ec); - if (result >= 0) - clear_error(ec); - return result; -} +BOOST_ASIO_DECL int ioctl(int d, state_type& state, long cmd, + ioctl_arg_type* arg, boost::system::error_code& ec); -inline int fcntl(int d, long cmd, boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(::fcntl(d, cmd), ec); - if (result != -1) - clear_error(ec); - return result; -} +BOOST_ASIO_DECL int fcntl(int d, long cmd, boost::system::error_code& ec); -inline int fcntl(int d, long cmd, long arg, boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(::fcntl(d, cmd, arg), ec); - if (result != -1) - clear_error(ec); - return result; -} +BOOST_ASIO_DECL int fcntl(int d, long cmd, + long arg, boost::system::error_code& ec); -inline int poll_read(int d, boost::system::error_code& ec) -{ - clear_error(ec); - pollfd fds; - fds.fd = d; - fds.events = POLLIN; - fds.revents = 0; - clear_error(ec); - int result = error_wrapper(::poll(&fds, 1, -1), ec); - if (result >= 0) - clear_error(ec); - return result; -} +BOOST_ASIO_DECL int poll_read(int d, boost::system::error_code& ec); -inline int poll_write(int d, boost::system::error_code& ec) -{ - clear_error(ec); - pollfd fds; - fds.fd = d; - fds.events = POLLOUT; - fds.revents = 0; - clear_error(ec); - int result = error_wrapper(::poll(&fds, 1, -1), ec); - if (result >= 0) - clear_error(ec); - return result; -} +BOOST_ASIO_DECL int poll_write(int d, boost::system::error_code& ec); } // namespace descriptor_ops } // namespace detail } // namespace asio } // namespace boost -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/descriptor_ops.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + #endif // BOOST_ASIO_DETAIL_DESCRIPTOR_OPS_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/descriptor_read_op.hpp b/3rdParty/Boost/src/boost/asio/detail/descriptor_read_op.hpp new file mode 100644 index 0000000..c068108 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/descriptor_read_op.hpp @@ -0,0 +1,116 @@ +// +// detail/descriptor_read_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP +#define BOOST_ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/descriptor_ops.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/reactor_op.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename MutableBufferSequence> +class descriptor_read_op_base : public reactor_op +{ +public: + descriptor_read_op_base(int descriptor, + const MutableBufferSequence& buffers, func_type complete_func) + : reactor_op(&descriptor_read_op_base::do_perform, complete_func), + descriptor_(descriptor), + buffers_(buffers) + { + } + + static bool do_perform(reactor_op* base) + { + descriptor_read_op_base* o(static_cast<descriptor_read_op_base*>(base)); + + buffer_sequence_adapter<boost::asio::mutable_buffer, + MutableBufferSequence> bufs(o->buffers_); + + return descriptor_ops::non_blocking_read(o->descriptor_, + bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_); + } + +private: + int descriptor_; + MutableBufferSequence buffers_; +}; + +template <typename MutableBufferSequence, typename Handler> +class descriptor_read_op + : public descriptor_read_op_base<MutableBufferSequence> +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_read_op); + + descriptor_read_op(int descriptor, + const MutableBufferSequence& buffers, Handler handler) + : descriptor_read_op_base<MutableBufferSequence>( + descriptor, buffers, &descriptor_read_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + descriptor_read_op* o(static_cast<descriptor_read_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#endif // BOOST_ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/descriptor_write_op.hpp b/3rdParty/Boost/src/boost/asio/detail/descriptor_write_op.hpp new file mode 100644 index 0000000..0983854 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/descriptor_write_op.hpp @@ -0,0 +1,116 @@ +// +// detail/descriptor_write_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP +#define BOOST_ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/descriptor_ops.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/reactor_op.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename ConstBufferSequence> +class descriptor_write_op_base : public reactor_op +{ +public: + descriptor_write_op_base(int descriptor, + const ConstBufferSequence& buffers, func_type complete_func) + : reactor_op(&descriptor_write_op_base::do_perform, complete_func), + descriptor_(descriptor), + buffers_(buffers) + { + } + + static bool do_perform(reactor_op* base) + { + descriptor_write_op_base* o(static_cast<descriptor_write_op_base*>(base)); + + buffer_sequence_adapter<boost::asio::const_buffer, + ConstBufferSequence> bufs(o->buffers_); + + return descriptor_ops::non_blocking_write(o->descriptor_, + bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_); + } + +private: + int descriptor_; + ConstBufferSequence buffers_; +}; + +template <typename ConstBufferSequence, typename Handler> +class descriptor_write_op + : public descriptor_write_op_base<ConstBufferSequence> +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_write_op); + + descriptor_write_op(int descriptor, + const ConstBufferSequence& buffers, Handler handler) + : descriptor_write_op_base<ConstBufferSequence>( + descriptor, buffers, &descriptor_write_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + descriptor_write_op* o(static_cast<descriptor_write_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#endif // BOOST_ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/dev_poll_reactor.hpp b/3rdParty/Boost/src/boost/asio/detail/dev_poll_reactor.hpp index e00f501..ef2b0dc 100644 --- a/3rdParty/Boost/src/boost/asio/detail/dev_poll_reactor.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/dev_poll_reactor.hpp @@ -1,6 +1,6 @@ // -// dev_poll_reactor.hpp -// ~~~~~~~~~~~~~~~~~~~~ +// detail/dev_poll_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,36 +15,28 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/dev_poll_reactor_fwd.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_DEV_POLL) -#include <boost/asio/detail/push_options.hpp> #include <cstddef> #include <vector> -#include <boost/config.hpp> -#include <boost/date_time/posix_time/posix_time_types.hpp> -#include <boost/throw_exception.hpp> #include <sys/devpoll.h> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> -#include <boost/asio/io_service.hpp> +#include <boost/asio/detail/dev_poll_reactor_fwd.hpp> #include <boost/asio/detail/hash_map.hpp> #include <boost/asio/detail/mutex.hpp> #include <boost/asio/detail/op_queue.hpp> #include <boost/asio/detail/reactor_op.hpp> #include <boost/asio/detail/reactor_op_queue.hpp> #include <boost/asio/detail/select_interrupter.hpp> -#include <boost/asio/detail/service_base.hpp> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/timer_op.hpp> #include <boost/asio/detail/timer_queue_base.hpp> #include <boost/asio/detail/timer_queue_fwd.hpp> #include <boost/asio/detail/timer_queue_set.hpp> +#include <boost/asio/io_service.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -63,358 +55,93 @@ public: }; // Constructor. - dev_poll_reactor(boost::asio::io_service& io_service) - : boost::asio::detail::service_base<dev_poll_reactor>(io_service), - io_service_(use_service<io_service_impl>(io_service)), - mutex_(), - dev_poll_fd_(do_dev_poll_create()), - interrupter_(), - shutdown_(false) - { - // Add the interrupter's descriptor to /dev/poll. - ::pollfd ev = { 0 }; - ev.fd = interrupter_.read_descriptor(); - ev.events = POLLIN | POLLERR; - ev.revents = 0; - ::write(dev_poll_fd_, &ev, sizeof(ev)); - } + BOOST_ASIO_DECL dev_poll_reactor(boost::asio::io_service& io_service); // Destructor. - ~dev_poll_reactor() - { - shutdown_service(); - ::close(dev_poll_fd_); - } + BOOST_ASIO_DECL ~dev_poll_reactor(); // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - shutdown_ = true; - lock.unlock(); - - op_queue<operation> ops; - - for (int i = 0; i < max_ops; ++i) - op_queue_[i].get_all_operations(ops); - - timer_queues_.get_all_timers(ops); - } + BOOST_ASIO_DECL void shutdown_service(); // Initialise the task. - void init_task() - { - io_service_.init_task(); - } + BOOST_ASIO_DECL void init_task(); // Register a socket with the reactor. Returns 0 on success, system error // code on failure. - int register_descriptor(socket_type, per_descriptor_data&) + BOOST_ASIO_DECL int register_descriptor(socket_type, per_descriptor_data&); + + // Post a reactor operation for immediate completion. + void post_immediate_completion(reactor_op* op) { - return 0; + io_service_.post_immediate_completion(op); } // Start a new operation. The reactor operation will be performed when the // given descriptor is flagged as ready, or an error has occurred. - void start_op(int op_type, socket_type descriptor, - per_descriptor_data&, reactor_op* op, bool allow_speculative) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - - if (shutdown_) - return; - - if (allow_speculative) - { - if (op_type != read_op || !op_queue_[except_op].has_operation(descriptor)) - { - if (!op_queue_[op_type].has_operation(descriptor)) - { - if (op->perform()) - { - lock.unlock(); - io_service_.post_immediate_completion(op); - return; - } - } - } - } - - bool first = op_queue_[op_type].enqueue_operation(descriptor, op); - io_service_.work_started(); - if (first) - { - ::pollfd& ev = add_pending_event_change(descriptor); - ev.events = POLLERR | POLLHUP; - if (op_type == read_op - || op_queue_[read_op].has_operation(descriptor)) - ev.events |= POLLIN; - if (op_type == write_op - || op_queue_[write_op].has_operation(descriptor)) - ev.events |= POLLOUT; - if (op_type == except_op - || op_queue_[except_op].has_operation(descriptor)) - ev.events |= POLLPRI; - interrupter_.interrupt(); - } - } + BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor, + per_descriptor_data&, reactor_op* op, bool allow_speculative); // Cancel all operations associated with the given descriptor. The // handlers associated with the descriptor will be invoked with the // operation_aborted error. - void cancel_ops(socket_type descriptor, per_descriptor_data&) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted); - } + BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&); // Cancel any operations that are running against the descriptor and remove // its registration from the reactor. - void close_descriptor(socket_type descriptor, per_descriptor_data&) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - - // Remove the descriptor from /dev/poll. - ::pollfd& ev = add_pending_event_change(descriptor); - ev.events = POLLREMOVE; - interrupter_.interrupt(); - - // Cancel any outstanding operations associated with the descriptor. - cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted); - } + BOOST_ASIO_DECL void close_descriptor( + socket_type descriptor, per_descriptor_data&); // Add a new timer queue to the reactor. template <typename Time_Traits> - void add_timer_queue(timer_queue<Time_Traits>& timer_queue) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - timer_queues_.insert(&timer_queue); - } + void add_timer_queue(timer_queue<Time_Traits>& queue); // Remove a timer queue from the reactor. template <typename Time_Traits> - void remove_timer_queue(timer_queue<Time_Traits>& timer_queue) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - timer_queues_.erase(&timer_queue); - } + void remove_timer_queue(timer_queue<Time_Traits>& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time. template <typename Time_Traits> - void schedule_timer(timer_queue<Time_Traits>& timer_queue, - const typename Time_Traits::time_type& time, timer_op* op, void* token) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - if (!shutdown_) - { - bool earliest = timer_queue.enqueue_timer(time, op, token); - io_service_.work_started(); - if (earliest) - interrupter_.interrupt(); - } - } + void schedule_timer(timer_queue<Time_Traits>& queue, + const typename Time_Traits::time_type& time, + typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched. template <typename Time_Traits> - std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - op_queue<operation> ops; - std::size_t n = timer_queue.cancel_timer(token, ops); - lock.unlock(); - io_service_.post_deferred_completions(ops); - return n; - } + std::size_t cancel_timer(timer_queue<Time_Traits>& queue, + typename timer_queue<Time_Traits>::per_timer_data& timer); // Run /dev/poll once until interrupted or events are ready to be dispatched. - void run(bool block, op_queue<operation>& ops) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - - // We can return immediately if there's no work to do and the reactor is - // not supposed to block. - if (!block && op_queue_[read_op].empty() && op_queue_[write_op].empty() - && op_queue_[except_op].empty() && timer_queues_.all_empty()) - return; - - // Write the pending event registration changes to the /dev/poll descriptor. - std::size_t events_size = sizeof(::pollfd) * pending_event_changes_.size(); - if (events_size > 0) - { - errno = 0; - int result = ::write(dev_poll_fd_, - &pending_event_changes_[0], events_size); - if (result != static_cast<int>(events_size)) - { - boost::system::error_code ec = boost::system::error_code( - errno, boost::asio::error::get_system_category()); - for (std::size_t i = 0; i < pending_event_changes_.size(); ++i) - { - int descriptor = pending_event_changes_[i].fd; - for (int j = 0; j < max_ops; ++j) - op_queue_[j].cancel_operations(descriptor, ops, ec); - } - } - pending_event_changes_.clear(); - pending_event_change_index_.clear(); - } - - int timeout = block ? get_timeout() : 0; - lock.unlock(); - - // Block on the /dev/poll descriptor. - ::pollfd events[128] = { { 0 } }; - ::dvpoll dp = { 0 }; - dp.dp_fds = events; - dp.dp_nfds = 128; - dp.dp_timeout = timeout; - int num_events = ::ioctl(dev_poll_fd_, DP_POLL, &dp); - - lock.lock(); - - // Dispatch the waiting events. - for (int i = 0; i < num_events; ++i) - { - int descriptor = events[i].fd; - if (descriptor == interrupter_.read_descriptor()) - { - interrupter_.reset(); - } - else - { - bool more_reads = false; - bool more_writes = false; - bool more_except = false; - - // Exception operations must be processed first to ensure that any - // out-of-band data is read before normal data. - if (events[i].events & (POLLPRI | POLLERR | POLLHUP)) - more_except = - op_queue_[except_op].perform_operations(descriptor, ops); - else - more_except = op_queue_[except_op].has_operation(descriptor); - - if (events[i].events & (POLLIN | POLLERR | POLLHUP)) - more_reads = op_queue_[read_op].perform_operations(descriptor, ops); - else - more_reads = op_queue_[read_op].has_operation(descriptor); - - if (events[i].events & (POLLOUT | POLLERR | POLLHUP)) - more_writes = op_queue_[write_op].perform_operations(descriptor, ops); - else - more_writes = op_queue_[write_op].has_operation(descriptor); - - if ((events[i].events & (POLLERR | POLLHUP)) != 0 - && !more_except && !more_reads && !more_writes) - { - // If we have an event and no operations associated with the - // descriptor then we need to delete the descriptor from /dev/poll. - // The poll operation can produce POLLHUP or POLLERR events when there - // is no operation pending, so if we do not remove the descriptor we - // can end up in a tight polling loop. - ::pollfd ev = { 0 }; - ev.fd = descriptor; - ev.events = POLLREMOVE; - ev.revents = 0; - ::write(dev_poll_fd_, &ev, sizeof(ev)); - } - else - { - ::pollfd ev = { 0 }; - ev.fd = descriptor; - ev.events = POLLERR | POLLHUP; - if (more_reads) - ev.events |= POLLIN; - if (more_writes) - ev.events |= POLLOUT; - if (more_except) - ev.events |= POLLPRI; - ev.revents = 0; - int result = ::write(dev_poll_fd_, &ev, sizeof(ev)); - if (result != sizeof(ev)) - { - boost::system::error_code ec(errno, - boost::asio::error::get_system_category()); - for (int j = 0; j < max_ops; ++j) - op_queue_[j].cancel_operations(descriptor, ops, ec); - } - } - } - } - timer_queues_.get_ready_timers(ops); - } + BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops); // Interrupt the select loop. - void interrupt() - { - interrupter_.interrupt(); - } + BOOST_ASIO_DECL void interrupt(); private: // Create the /dev/poll file descriptor. Throws an exception if the descriptor // cannot be created. - static int do_dev_poll_create() - { - int fd = ::open("/dev/poll", O_RDWR); - if (fd == -1) - { - boost::throw_exception( - boost::system::system_error( - boost::system::error_code(errno, - boost::asio::error::get_system_category()), - "/dev/poll")); - } - return fd; - } + BOOST_ASIO_DECL static int do_dev_poll_create(); + + // Helper function to add a new timer queue. + BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); + + // Helper function to remove a timer queue. + BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); // Get the timeout value for the /dev/poll DP_POLL operation. The timeout // value is returned as a number of milliseconds. A return value of -1 // indicates that the poll should block indefinitely. - int get_timeout() - { - // By default we will wait no longer than 5 minutes. This will ensure that - // any changes to the system clock are detected after no longer than this. - return timer_queues_.wait_duration_msec(5 * 60 * 1000); - } + BOOST_ASIO_DECL int get_timeout(); // Cancel all operations associated with the given descriptor. The do_cancel // function of the handler objects will be invoked. This function does not // acquire the dev_poll_reactor's mutex. - void cancel_ops_unlocked(socket_type descriptor, - const boost::system::error_code& ec) - { - bool need_interrupt = false; - op_queue<operation> ops; - for (int i = 0; i < max_ops; ++i) - need_interrupt = op_queue_[i].cancel_operations( - descriptor, ops, ec) || need_interrupt; - io_service_.post_deferred_completions(ops); - if (need_interrupt) - interrupter_.interrupt(); - } + BOOST_ASIO_DECL void cancel_ops_unlocked(socket_type descriptor, + const boost::system::error_code& ec); // Add a pending event entry for the given descriptor. - ::pollfd& add_pending_event_change(int descriptor) - { - hash_map<int, std::size_t>::iterator iter - = pending_event_change_index_.find(descriptor); - if (iter == pending_event_change_index_.end()) - { - std::size_t index = pending_event_changes_.size(); - pending_event_changes_.reserve(pending_event_changes_.size() + 1); - pending_event_change_index_.insert(std::make_pair(descriptor, index)); - pending_event_changes_.push_back(::pollfd()); - pending_event_changes_[index].fd = descriptor; - pending_event_changes_[index].revents = 0; - return pending_event_changes_[index]; - } - else - { - return pending_event_changes_[iter->second]; - } - } + BOOST_ASIO_DECL ::pollfd& add_pending_event_change(int descriptor); // The io_service implementation used to post completions. io_service_impl& io_service_; @@ -448,8 +175,13 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_ASIO_HAS_DEV_POLL) - #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/impl/dev_poll_reactor.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/dev_poll_reactor.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_ASIO_HAS_DEV_POLL) + #endif // BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/dev_poll_reactor_fwd.hpp b/3rdParty/Boost/src/boost/asio/detail/dev_poll_reactor_fwd.hpp index 238cee5..7e8defc 100644 --- a/3rdParty/Boost/src/boost/asio/detail/dev_poll_reactor_fwd.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/dev_poll_reactor_fwd.hpp @@ -1,6 +1,6 @@ // -// dev_poll_reactor_fwd.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/dev_poll_reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,13 +15,9 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#if !defined(BOOST_ASIO_DISABLE_DEV_POLL) -#if defined(__sun) // This service is only supported on Solaris. - -// Define this to indicate that /dev/poll is supported on the target platform. -#define BOOST_ASIO_HAS_DEV_POLL 1 +#if defined(BOOST_ASIO_HAS_DEV_POLL) namespace boost { namespace asio { @@ -33,9 +29,6 @@ class dev_poll_reactor; } // namespace asio } // namespace boost -#endif // defined(__sun) -#endif // !defined(BOOST_ASIO_DISABLE_DEV_POLL) - -#include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_ASIO_HAS_DEV_POLL) #endif // BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/epoll_reactor.hpp b/3rdParty/Boost/src/boost/asio/detail/epoll_reactor.hpp index 40cc3aa..18d87ee 100644 --- a/3rdParty/Boost/src/boost/asio/detail/epoll_reactor.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/epoll_reactor.hpp @@ -1,6 +1,6 @@ // -// epoll_reactor.hpp -// ~~~~~~~~~~~~~~~~~ +// detail/epoll_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,43 +15,24 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/epoll_reactor_fwd.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_EPOLL) -#include <boost/asio/detail/push_options.hpp> -#include <cstddef> -#include <sys/epoll.h> -#include <boost/config.hpp> -#include <boost/throw_exception.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> -#include <boost/asio/detail/hash_map.hpp> +#include <boost/asio/detail/epoll_reactor_fwd.hpp> #include <boost/asio/detail/mutex.hpp> +#include <boost/asio/detail/object_pool.hpp> #include <boost/asio/detail/op_queue.hpp> #include <boost/asio/detail/reactor_op.hpp> #include <boost/asio/detail/select_interrupter.hpp> -#include <boost/asio/detail/service_base.hpp> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/timer_op.hpp> #include <boost/asio/detail/timer_queue_base.hpp> #include <boost/asio/detail/timer_queue_fwd.hpp> #include <boost/asio/detail/timer_queue_set.hpp> -#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) -# define BOOST_ASIO_HAS_TIMERFD 1 -#endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) - -#if defined(BOOST_ASIO_HAS_TIMERFD) -# include <boost/asio/detail/push_options.hpp> -# include <sys/timerfd.h> -# include <boost/asio/detail/pop_options.hpp> -#endif // defined(BOOST_ASIO_HAS_TIMERFD) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -65,357 +46,86 @@ public: connect_op = 1, except_op = 2, max_ops = 3 }; // Per-descriptor queues. - struct descriptor_state + class descriptor_state { - descriptor_state() {} - descriptor_state(const descriptor_state&) {} - void operator=(const descriptor_state&) {} - + friend class epoll_reactor; + friend class object_pool_access; mutex mutex_; op_queue<reactor_op> op_queue_[max_ops]; bool shutdown_; + descriptor_state* next_; + descriptor_state* prev_; }; // Per-descriptor data. typedef descriptor_state* per_descriptor_data; // Constructor. - epoll_reactor(boost::asio::io_service& io_service) - : boost::asio::detail::service_base<epoll_reactor>(io_service), - io_service_(use_service<io_service_impl>(io_service)), - mutex_(), - epoll_fd_(do_epoll_create()), -#if defined(BOOST_ASIO_HAS_TIMERFD) - timer_fd_(timerfd_create(CLOCK_MONOTONIC, 0)), -#else // defined(BOOST_ASIO_HAS_TIMERFD) - timer_fd_(-1), -#endif // defined(BOOST_ASIO_HAS_TIMERFD) - interrupter_(), - shutdown_(false) - { - // Add the interrupter's descriptor to epoll. - epoll_event ev = { 0, { 0 } }; - ev.events = EPOLLIN | EPOLLERR | EPOLLET; - ev.data.ptr = &interrupter_; - epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev); - interrupter_.interrupt(); - - // Add the timer descriptor to epoll. - if (timer_fd_ != -1) - { - ev.events = EPOLLIN | EPOLLERR; - ev.data.ptr = &timer_fd_; - epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &ev); - } - } + BOOST_ASIO_DECL epoll_reactor(boost::asio::io_service& io_service); // Destructor. - ~epoll_reactor() - { - close(epoll_fd_); - if (timer_fd_ != -1) - close(timer_fd_); - } + BOOST_ASIO_DECL ~epoll_reactor(); // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - mutex::scoped_lock lock(mutex_); - shutdown_ = true; - lock.unlock(); - - op_queue<operation> ops; - - descriptor_map::iterator iter = registered_descriptors_.begin(); - descriptor_map::iterator end = registered_descriptors_.end(); - while (iter != end) - { - for (int i = 0; i < max_ops; ++i) - ops.push(iter->second.op_queue_[i]); - iter->second.shutdown_ = true; - ++iter; - } - - timer_queues_.get_all_timers(ops); - } + BOOST_ASIO_DECL void shutdown_service(); // Initialise the task. - void init_task() - { - io_service_.init_task(); - } + BOOST_ASIO_DECL void init_task(); // Register a socket with the reactor. Returns 0 on success, system error // code on failure. - int register_descriptor(socket_type descriptor, - per_descriptor_data& descriptor_data) - { - mutex::scoped_lock lock(registered_descriptors_mutex_); - - descriptor_map::iterator new_entry = registered_descriptors_.insert( - std::make_pair(descriptor, descriptor_state())).first; - descriptor_data = &new_entry->second; - - epoll_event ev = { 0, { 0 } }; - ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLOUT | EPOLLPRI | EPOLLET; - ev.data.ptr = descriptor_data; - int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); - if (result != 0) - return errno; - - descriptor_data->shutdown_ = false; + BOOST_ASIO_DECL int register_descriptor(socket_type descriptor, + per_descriptor_data& descriptor_data); - return 0; + // Post a reactor operation for immediate completion. + void post_immediate_completion(reactor_op* op) + { + io_service_.post_immediate_completion(op); } // Start a new operation. The reactor operation will be performed when the // given descriptor is flagged as ready, or an error has occurred. - void start_op(int op_type, socket_type descriptor, + BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor, per_descriptor_data& descriptor_data, - reactor_op* op, bool allow_speculative) - { - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); - if (descriptor_data->shutdown_) - return; - - if (descriptor_data->op_queue_[op_type].empty()) - { - if (allow_speculative - && (op_type != read_op - || descriptor_data->op_queue_[except_op].empty())) - { - if (op->perform()) - { - descriptor_lock.unlock(); - io_service_.post_immediate_completion(op); - return; - } - } - else - { - epoll_event ev = { 0, { 0 } }; - ev.events = EPOLLIN | EPOLLERR | EPOLLHUP - | EPOLLOUT | EPOLLPRI | EPOLLET; - ev.data.ptr = descriptor_data; - epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); - } - } - - descriptor_data->op_queue_[op_type].push(op); - io_service_.work_started(); - } + reactor_op* op, bool allow_speculative); // Cancel all operations associated with the given descriptor. The // handlers associated with the descriptor will be invoked with the // operation_aborted error. - void cancel_ops(socket_type, per_descriptor_data& descriptor_data) - { - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); - - op_queue<operation> ops; - for (int i = 0; i < max_ops; ++i) - { - while (reactor_op* op = descriptor_data->op_queue_[i].front()) - { - op->ec_ = boost::asio::error::operation_aborted; - descriptor_data->op_queue_[i].pop(); - ops.push(op); - } - } - - descriptor_lock.unlock(); - - io_service_.post_deferred_completions(ops); - } + BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, + per_descriptor_data& descriptor_data); // Cancel any operations that are running against the descriptor and remove // its registration from the reactor. - void close_descriptor(socket_type descriptor, - per_descriptor_data& descriptor_data) - { - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); - mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); - - // Remove the descriptor from the set of known descriptors. The descriptor - // will be automatically removed from the epoll set when it is closed. - descriptor_data->shutdown_ = true; - - op_queue<operation> ops; - for (int i = 0; i < max_ops; ++i) - { - while (reactor_op* op = descriptor_data->op_queue_[i].front()) - { - op->ec_ = boost::asio::error::operation_aborted; - descriptor_data->op_queue_[i].pop(); - ops.push(op); - } - } - - descriptor_lock.unlock(); - - registered_descriptors_.erase(descriptor); - - descriptors_lock.unlock(); - - io_service_.post_deferred_completions(ops); - } + BOOST_ASIO_DECL void close_descriptor(socket_type descriptor, + per_descriptor_data& descriptor_data); // Add a new timer queue to the reactor. template <typename Time_Traits> - void add_timer_queue(timer_queue<Time_Traits>& timer_queue) - { - mutex::scoped_lock lock(mutex_); - timer_queues_.insert(&timer_queue); - } + void add_timer_queue(timer_queue<Time_Traits>& timer_queue); // Remove a timer queue from the reactor. template <typename Time_Traits> - void remove_timer_queue(timer_queue<Time_Traits>& timer_queue) - { - mutex::scoped_lock lock(mutex_); - timer_queues_.erase(&timer_queue); - } + void remove_timer_queue(timer_queue<Time_Traits>& timer_queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time. template <typename Time_Traits> - void schedule_timer(timer_queue<Time_Traits>& timer_queue, - const typename Time_Traits::time_type& time, timer_op* op, void* token) - { - mutex::scoped_lock lock(mutex_); - if (!shutdown_) - { - bool earliest = timer_queue.enqueue_timer(time, op, token); - io_service_.work_started(); - if (earliest) - { -#if defined(BOOST_ASIO_HAS_TIMERFD) - if (timer_fd_ != -1) - { - itimerspec new_timeout; - itimerspec old_timeout; - int flags = get_timeout(new_timeout); - timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout); - return; - } -#endif // defined(BOOST_ASIO_HAS_TIMERFD) - interrupter_.interrupt(); - } - } - } + void schedule_timer(timer_queue<Time_Traits>& queue, + const typename Time_Traits::time_type& time, + typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched. template <typename Time_Traits> - std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token) - { - mutex::scoped_lock lock(mutex_); - op_queue<operation> ops; - std::size_t n = timer_queue.cancel_timer(token, ops); - lock.unlock(); - io_service_.post_deferred_completions(ops); - return n; - } + std::size_t cancel_timer(timer_queue<Time_Traits>& queue, + typename timer_queue<Time_Traits>::per_timer_data& timer); // Run epoll once until interrupted or events are ready to be dispatched. - void run(bool block, op_queue<operation>& ops) - { - // Calculate a timeout only if timerfd is not used. - int timeout; - if (timer_fd_ != -1) - timeout = block ? -1 : 0; - else - { - mutex::scoped_lock lock(mutex_); - timeout = block ? get_timeout() : 0; - } - - // Block on the epoll descriptor. - epoll_event events[128]; - int num_events = epoll_wait(epoll_fd_, events, 128, timeout); - -#if defined(BOOST_ASIO_HAS_TIMERFD) - bool check_timers = (timer_fd_ == -1); -#else // defined(BOOST_ASIO_HAS_TIMERFD) - bool check_timers = true; -#endif // defined(BOOST_ASIO_HAS_TIMERFD) - - // Dispatch the waiting events. - for (int i = 0; i < num_events; ++i) - { - void* ptr = events[i].data.ptr; - if (ptr == &interrupter_) - { - // No need to reset the interrupter since we're leaving the descriptor - // in a ready-to-read state and relying on edge-triggered notifications - // to make it so that we only get woken up when the descriptor's epoll - // registration is updated. - -#if defined(BOOST_ASIO_HAS_TIMERFD) - if (timer_fd_ == -1) - check_timers = true; -#else // defined(BOOST_ASIO_HAS_TIMERFD) - check_timers = true; -#endif // defined(BOOST_ASIO_HAS_TIMERFD) - } -#if defined(BOOST_ASIO_HAS_TIMERFD) - else if (ptr == &timer_fd_) - { - check_timers = true; - } -#endif // defined(BOOST_ASIO_HAS_TIMERFD) - else - { - descriptor_state* descriptor_data = static_cast<descriptor_state*>(ptr); - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); - - // Exception operations must be processed first to ensure that any - // out-of-band data is read before normal data. - static const int flag[max_ops] = { EPOLLIN, EPOLLOUT, EPOLLPRI }; - for (int j = max_ops - 1; j >= 0; --j) - { - if (events[i].events & (flag[j] | EPOLLERR | EPOLLHUP)) - { - while (reactor_op* op = descriptor_data->op_queue_[j].front()) - { - if (op->perform()) - { - descriptor_data->op_queue_[j].pop(); - ops.push(op); - } - else - break; - } - } - } - } - } - - if (check_timers) - { - mutex::scoped_lock common_lock(mutex_); - timer_queues_.get_ready_timers(ops); - -#if defined(BOOST_ASIO_HAS_TIMERFD) - if (timer_fd_ != -1) - { - itimerspec new_timeout; - itimerspec old_timeout; - int flags = get_timeout(new_timeout); - timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout); - } -#endif // defined(BOOST_ASIO_HAS_TIMERFD) - } - } + BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops); // Interrupt the select loop. - void interrupt() - { - epoll_event ev = { 0, { 0 } }; - ev.events = EPOLLIN | EPOLLERR | EPOLLET; - ev.data.ptr = &interrupter_; - epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, interrupter_.read_descriptor(), &ev); - } + BOOST_ASIO_DECL void interrupt(); private: // The hint to pass to epoll_create to size its data structures. @@ -423,44 +133,26 @@ private: // Create the epoll file descriptor. Throws an exception if the descriptor // cannot be created. - static int do_epoll_create() - { - int fd = epoll_create(epoll_size); - if (fd == -1) - { - boost::throw_exception( - boost::system::system_error( - boost::system::error_code(errno, - boost::asio::error::get_system_category()), - "epoll")); - } - return fd; - } + BOOST_ASIO_DECL static int do_epoll_create(); + + // Helper function to add a new timer queue. + BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); + + // Helper function to remove a timer queue. + BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); + + // Called to recalculate and update the timeout. + BOOST_ASIO_DECL void update_timeout(); // Get the timeout value for the epoll_wait call. The timeout value is // returned as a number of milliseconds. A return value of -1 indicates // that epoll_wait should block indefinitely. - int get_timeout() - { - // By default we will wait no longer than 5 minutes. This will ensure that - // any changes to the system clock are detected after no longer than this. - return timer_queues_.wait_duration_msec(5 * 60 * 1000); - } + BOOST_ASIO_DECL int get_timeout(); #if defined(BOOST_ASIO_HAS_TIMERFD) // Get the timeout value for the timer descriptor. The return value is the // flag argument to be used when calling timerfd_settime. - int get_timeout(itimerspec& ts) - { - ts.it_interval.tv_sec = 0; - ts.it_interval.tv_nsec = 0; - - long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000); - ts.it_value.tv_sec = usec / 1000000; - ts.it_value.tv_nsec = usec ? (usec % 1000000) * 1000 : 1; - - return usec ? 0 : TFD_TIMER_ABSTIME; - } + BOOST_ASIO_DECL int get_timeout(itimerspec& ts); #endif // defined(BOOST_ASIO_HAS_TIMERFD) // The io_service implementation used to post completions. @@ -487,23 +179,21 @@ private: // Mutex to protect access to the registered descriptors. mutex registered_descriptors_mutex_; - // Keep track of all registered descriptors. This code relies on the fact that - // the hash_map implementation pools deleted nodes, meaning that we can assume - // our descriptor_state pointer remains valid even after the entry is removed. - // Technically this is not true for C++98, as that standard says that spliced - // elements in a list are invalidated. However, C++0x fixes this shortcoming - // so we'll just assume that C++98 std::list implementations will do the right - // thing anyway. - typedef detail::hash_map<socket_type, descriptor_state> descriptor_map; - descriptor_map registered_descriptors_; + // Keep track of all registered descriptors. + object_pool<descriptor_state> registered_descriptors_; }; } // namespace detail } // namespace asio } // namespace boost -#endif // defined(BOOST_ASIO_HAS_EPOLL) - #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/impl/epoll_reactor.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/epoll_reactor.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_ASIO_HAS_EPOLL) + #endif // BOOST_ASIO_DETAIL_EPOLL_REACTOR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/epoll_reactor_fwd.hpp b/3rdParty/Boost/src/boost/asio/detail/epoll_reactor_fwd.hpp index 214cee5..dc0e92d 100644 --- a/3rdParty/Boost/src/boost/asio/detail/epoll_reactor_fwd.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/epoll_reactor_fwd.hpp @@ -1,6 +1,6 @@ // -// epoll_reactor_fwd.hpp -// ~~~~~~~~~~~~~~~~~~~~~ +// detail/epoll_reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,19 +15,9 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#if !defined(BOOST_ASIO_DISABLE_EPOLL) -#if defined(__linux__) // This service is only supported on Linux. - -#include <boost/asio/detail/push_options.hpp> -#include <linux/version.h> -#include <boost/asio/detail/pop_options.hpp> - -#if LINUX_VERSION_CODE >= KERNEL_VERSION (2,5,45) // Only kernels >= 2.5.45. - -// Define this to indicate that epoll is supported on the target platform. -#define BOOST_ASIO_HAS_EPOLL 1 +#if defined(BOOST_ASIO_HAS_EPOLL) namespace boost { namespace asio { @@ -39,10 +29,6 @@ class epoll_reactor; } // namespace asio } // namespace boost -#endif // LINUX_VERSION_CODE >= KERNEL_VERSION (2,5,45) -#endif // defined(__linux__) -#endif // !defined(BOOST_ASIO_DISABLE_EPOLL) - -#include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_ASIO_HAS_EPOLL) #endif // BOOST_ASIO_DETAIL_EPOLL_REACTOR_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/event.hpp b/3rdParty/Boost/src/boost/asio/detail/event.hpp index e8d185f..c33b65a 100644 --- a/3rdParty/Boost/src/boost/asio/detail/event.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/event.hpp @@ -1,6 +1,6 @@ // -// event.hpp -// ~~~~~~~~~ +// detail/event.hpp +// ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,11 +15,7 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) # include <boost/asio/detail/null_event.hpp> @@ -47,6 +43,4 @@ typedef posix_event event; } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_EVENT_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/eventfd_select_interrupter.hpp b/3rdParty/Boost/src/boost/asio/detail/eventfd_select_interrupter.hpp index 4749ec9..b2cb68b 100644 --- a/3rdParty/Boost/src/boost/asio/detail/eventfd_select_interrupter.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/eventfd_select_interrupter.hpp @@ -1,6 +1,6 @@ // -// eventfd_select_interrupter.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/eventfd_select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com) @@ -16,36 +16,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/throw_exception.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#if defined(__linux__) -# if !defined(BOOST_ASIO_DISABLE_EVENTFD) -# include <linux/version.h> -# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -# define BOOST_ASIO_HAS_EVENTFD -# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -# endif // !defined(BOOST_ASIO_DISABLE_EVENTFD) -#endif // defined(__linux__) +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_EVENTFD) #include <boost/asio/detail/push_options.hpp> -#include <fcntl.h> -#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 -# include <asm/unistd.h> -#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 -# include <sys/eventfd.h> -#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> -#include <boost/asio/detail/socket_types.hpp> namespace boost { namespace asio { @@ -55,87 +30,16 @@ class eventfd_select_interrupter { public: // Constructor. - eventfd_select_interrupter() - { -#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 - write_descriptor_ = read_descriptor_ = syscall(__NR_eventfd, 0); -#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 - write_descriptor_ = read_descriptor_ = ::eventfd(0, 0); -#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 - if (read_descriptor_ != -1) - { - ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); - } - else - { - int pipe_fds[2]; - if (pipe(pipe_fds) == 0) - { - read_descriptor_ = pipe_fds[0]; - ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); - write_descriptor_ = pipe_fds[1]; - ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK); - } - else - { - boost::system::error_code ec(errno, - boost::asio::error::get_system_category()); - boost::system::system_error e(ec, "eventfd_select_interrupter"); - boost::throw_exception(e); - } - } - } + BOOST_ASIO_DECL eventfd_select_interrupter(); // Destructor. - ~eventfd_select_interrupter() - { - if (write_descriptor_ != -1 && write_descriptor_ != read_descriptor_) - ::close(write_descriptor_); - if (read_descriptor_ != -1) - ::close(read_descriptor_); - } + BOOST_ASIO_DECL ~eventfd_select_interrupter(); // Interrupt the select call. - void interrupt() - { - uint64_t counter(1UL); - int result = ::write(write_descriptor_, &counter, sizeof(uint64_t)); - (void)result; - } + BOOST_ASIO_DECL void interrupt(); // Reset the select interrupt. Returns true if the call was interrupted. - bool reset() - { - if (write_descriptor_ == read_descriptor_) - { - for (;;) - { - // Only perform one read. The kernel maintains an atomic counter. - uint64_t counter(0); - errno = 0; - int bytes_read = ::read(read_descriptor_, &counter, sizeof(uint64_t)); - if (bytes_read < 0 && errno == EINTR) - continue; - bool was_interrupted = (bytes_read > 0); - return was_interrupted; - } - } - else - { - for (;;) - { - // Clear all data from the pipe. - char data[1024]; - int bytes_read = ::read(read_descriptor_, data, sizeof(data)); - if (bytes_read < 0 && errno == EINTR) - continue; - bool was_interrupted = (bytes_read > 0); - while (bytes_read == sizeof(data)) - bytes_read = ::read(read_descriptor_, data, sizeof(data)); - return was_interrupted; - } - } - } + BOOST_ASIO_DECL bool reset(); // Get the read descriptor to be passed to select. int read_descriptor() const @@ -161,8 +65,12 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_ASIO_HAS_EVENTFD) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/eventfd_select_interrupter.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_ASIO_HAS_EVENTFD) + #endif // BOOST_ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/fd_set_adapter.hpp b/3rdParty/Boost/src/boost/asio/detail/fd_set_adapter.hpp index 059362e..138264f 100644 --- a/3rdParty/Boost/src/boost/asio/detail/fd_set_adapter.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/fd_set_adapter.hpp @@ -1,6 +1,6 @@ // -// fd_set_adapter.hpp -// ~~~~~~~~~~~~~~~~~~ +// detail/fd_set_adapter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,12 +15,7 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/posix_fd_set_adapter.hpp> #include <boost/asio/detail/win_fd_set_adapter.hpp> @@ -38,6 +33,4 @@ typedef posix_fd_set_adapter fd_set_adapter; } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_FD_SET_ADAPTER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/fenced_block.hpp b/3rdParty/Boost/src/boost/asio/detail/fenced_block.hpp index c80161f..443f487 100644 --- a/3rdParty/Boost/src/boost/asio/detail/fenced_block.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/fenced_block.hpp @@ -1,6 +1,6 @@ // -// fenced_block.hpp -// ~~~~~~~~~~~~~~~~ +// detail/fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,23 +15,25 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) +#if !defined(BOOST_HAS_THREADS) \ + || defined(BOOST_ASIO_DISABLE_THREADS) \ + || defined(BOOST_ASIO_DISABLE_FENCED_BLOCK) # include <boost/asio/detail/null_fenced_block.hpp> #elif defined(__MACH__) && defined(__APPLE__) # include <boost/asio/detail/macos_fenced_block.hpp> #elif defined(__sun) # include <boost/asio/detail/solaris_fenced_block.hpp> +#elif defined(__GNUC__) && defined(__arm__) +# include <boost/asio/detail/gcc_arm_fenced_block.hpp> +#elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__)) +# include <boost/asio/detail/gcc_hppa_fenced_block.hpp> #elif defined(__GNUC__) \ && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \ && !defined(__INTEL_COMPILER) && !defined(__ICL) \ && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) -# include <boost/asio/detail/gcc_fenced_block.hpp> +# include <boost/asio/detail/gcc_sync_fenced_block.hpp> #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) # include <boost/asio/detail/gcc_x86_fenced_block.hpp> #elif defined(BOOST_WINDOWS) && !defined(UNDER_CE) @@ -44,17 +46,23 @@ namespace boost { namespace asio { namespace detail { -#if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) +#if !defined(BOOST_HAS_THREADS) \ + || defined(BOOST_ASIO_DISABLE_THREADS) \ + || defined(BOOST_ASIO_DISABLE_FENCED_BLOCK) typedef null_fenced_block fenced_block; #elif defined(__MACH__) && defined(__APPLE__) typedef macos_fenced_block fenced_block; #elif defined(__sun) typedef solaris_fenced_block fenced_block; +#elif defined(__GNUC__) && defined(__arm__) +typedef gcc_arm_fenced_block fenced_block; +#elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__)) +typedef gcc_hppa_fenced_block fenced_block; #elif defined(__GNUC__) \ && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \ && !defined(__INTEL_COMPILER) && !defined(__ICL) \ && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) -typedef gcc_fenced_block fenced_block; +typedef gcc_sync_fenced_block fenced_block; #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) typedef gcc_x86_fenced_block fenced_block; #elif defined(BOOST_WINDOWS) && !defined(UNDER_CE) @@ -67,6 +75,4 @@ typedef null_fenced_block fenced_block; } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_FENCED_BLOCK_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/gcc_arm_fenced_block.hpp b/3rdParty/Boost/src/boost/asio/detail/gcc_arm_fenced_block.hpp new file mode 100644 index 0000000..1350f09 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/gcc_arm_fenced_block.hpp @@ -0,0 +1,78 @@ +// +// detail/gcc_arm_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP +#define BOOST_ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(__GNUC__) && defined(__arm__) + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +class gcc_arm_fenced_block + : private noncopyable +{ +public: + // Constructor. + gcc_arm_fenced_block() + { + barrier(); + } + + // Destructor. + ~gcc_arm_fenced_block() + { + barrier(); + } + +private: + static void barrier() + { +#if defined(__ARM_ARCH_4__) \ + || defined(__ARM_ARCH_4T__) \ + || defined(__ARM_ARCH_5__) \ + || defined(__ARM_ARCH_5E__) \ + || defined(__ARM_ARCH_5T__) \ + || defined(__ARM_ARCH_5TE__) \ + || defined(__ARM_ARCH_5TEJ__) \ + || defined(__ARM_ARCH_6__) \ + || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6T2__) + int a = 0, b = 0; + __asm__ __volatile__ ("swp %0, %1, [%2]" + : "=&r"(a) : "r"(1), "r"(&b) : "memory", "cc"); +#else + // ARMv7 and later. + __asm__ __volatile__ ("dmb" : : : "memory"); +#endif + } +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(__GNUC__) && defined(__arm__) + +#endif // BOOST_ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/gcc_hppa_fenced_block.hpp b/3rdParty/Boost/src/boost/asio/detail/gcc_hppa_fenced_block.hpp new file mode 100644 index 0000000..ef5c093 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/gcc_hppa_fenced_block.hpp @@ -0,0 +1,60 @@ +// +// detail/gcc_hppa_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP +#define BOOST_ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(__GNUC__) && (defined(__hppa) || defined(__hppa__)) + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +class gcc_hppa_fenced_block + : private noncopyable +{ +public: + // Constructor. + gcc_hppa_fenced_block() + { + barrier(); + } + + // Destructor. + ~gcc_hppa_fenced_block() + { + barrier(); + } + +private: + static void barrier() + { + // This is just a placeholder and almost certainly not sufficient. + __asm__ __volatile__ ("" : : : "memory"); + } +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(__GNUC__) && (defined(__hppa) || defined(__hppa__)) + +#endif // BOOST_ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/gcc_fenced_block.hpp b/3rdParty/Boost/src/boost/asio/detail/gcc_sync_fenced_block.hpp index 0c086a6..83341d5 100644 --- a/3rdParty/Boost/src/boost/asio/detail/gcc_fenced_block.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/gcc_sync_fenced_block.hpp @@ -1,6 +1,6 @@ // -// gcc_fenced_block.hpp -// ~~~~~~~~~~~~~~~~~~~~ +// detail/gcc_sync_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -8,41 +8,39 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef BOOST_ASIO_DETAIL_GCC_FENCED_BLOCK_HPP -#define BOOST_ASIO_DETAIL_GCC_FENCED_BLOCK_HPP +#ifndef BOOST_ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP +#define BOOST_ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if defined(__GNUC__) \ && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \ && !defined(__INTEL_COMPILER) && !defined(__ICL) \ && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { -class gcc_fenced_block +class gcc_sync_fenced_block : private noncopyable { public: // Constructor. - gcc_fenced_block() + gcc_sync_fenced_block() : value_(0) { __sync_lock_test_and_set(&value_, 1); } // Destructor. - ~gcc_fenced_block() + ~gcc_sync_fenced_block() { __sync_lock_release(&value_); } @@ -55,11 +53,11 @@ private: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(__GNUC__) // && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) // && !defined(__INTEL_COMPILER) && !defined(__ICL) // && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__) -#include <boost/asio/detail/pop_options.hpp> - -#endif // BOOST_ASIO_DETAIL_GCC_FENCED_BLOCK_HPP +#endif // BOOST_ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/gcc_x86_fenced_block.hpp b/3rdParty/Boost/src/boost/asio/detail/gcc_x86_fenced_block.hpp index fc23d66..5353f87 100644 --- a/3rdParty/Boost/src/boost/asio/detail/gcc_x86_fenced_block.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/gcc_x86_fenced_block.hpp @@ -1,6 +1,6 @@ // -// gcc_x86_fenced_block.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/gcc_x86_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,14 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -56,8 +54,8 @@ private: } // namespace asio } // namespace boost -#endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - #include <boost/asio/detail/pop_options.hpp> +#endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + #endif // BOOST_ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/handler_alloc_helpers.hpp b/3rdParty/Boost/src/boost/asio/detail/handler_alloc_helpers.hpp index d385972..00d4c02 100644 --- a/3rdParty/Boost/src/boost/asio/detail/handler_alloc_helpers.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/handler_alloc_helpers.hpp @@ -1,6 +1,6 @@ // -// handler_alloc_helpers.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/handler_alloc_helpers.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,15 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/detail/workaround.hpp> #include <boost/utility/addressof.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/handler_alloc_hook.hpp> #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/handler_alloc_hook.hpp> + +#include <boost/asio/detail/push_options.hpp> // Calls to asio_handler_allocate and asio_handler_deallocate must be made from // a namespace that does not contain any overloads of these functions. The @@ -56,205 +54,31 @@ inline void deallocate(void* p, std::size_t s, Handler& h) } // namespace boost_asio_handler_alloc_helpers -namespace boost { -namespace asio { -namespace detail { - -// Traits for handler allocation. -template <typename Handler, typename Object> -struct handler_alloc_traits -{ - typedef Handler handler_type; - typedef Object value_type; - typedef Object* pointer_type; - BOOST_STATIC_CONSTANT(std::size_t, value_size = sizeof(Object)); -}; - -template <typename Alloc_Traits> -class handler_ptr; - -// Helper class to provide RAII on uninitialised handler memory. -template <typename Alloc_Traits> -class raw_handler_ptr - : private noncopyable -{ -public: - typedef typename Alloc_Traits::handler_type handler_type; - typedef typename Alloc_Traits::value_type value_type; - typedef typename Alloc_Traits::pointer_type pointer_type; - BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size); - - // Constructor allocates the memory. - raw_handler_ptr(handler_type& handler) - : handler_(handler), - pointer_(static_cast<pointer_type>( - boost_asio_handler_alloc_helpers::allocate(value_size, handler_))) - { - } - - // Destructor automatically deallocates memory, unless it has been stolen by - // a handler_ptr object. - ~raw_handler_ptr() - { - if (pointer_) - boost_asio_handler_alloc_helpers::deallocate( - pointer_, value_size, handler_); - } - -private: - friend class handler_ptr<Alloc_Traits>; - handler_type& handler_; - pointer_type pointer_; -}; - -// Helper class to provide RAII on uninitialised handler memory. -template <typename Alloc_Traits> -class handler_ptr - : private noncopyable -{ -public: - typedef typename Alloc_Traits::handler_type handler_type; - typedef typename Alloc_Traits::value_type value_type; - typedef typename Alloc_Traits::pointer_type pointer_type; - BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size); - typedef raw_handler_ptr<Alloc_Traits> raw_ptr_type; - - // Take ownership of existing memory. - handler_ptr(handler_type& handler, pointer_type pointer) - : handler_(handler), - pointer_(pointer) - { - } - - // Construct object in raw memory and take ownership if construction succeeds. - handler_ptr(raw_ptr_type& raw_ptr) - : handler_(raw_ptr.handler_), - pointer_(new (raw_ptr.pointer_) value_type) - { - raw_ptr.pointer_ = 0; - } - - // Construct object in raw memory and take ownership if construction succeeds. - template <typename Arg1> - handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1) - : handler_(raw_ptr.handler_), - pointer_(new (raw_ptr.pointer_) value_type(a1)) - { - raw_ptr.pointer_ = 0; - } - - // Construct object in raw memory and take ownership if construction succeeds. - template <typename Arg1, typename Arg2> - handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2) - : handler_(raw_ptr.handler_), - pointer_(new (raw_ptr.pointer_) value_type(a1, a2)) - { - raw_ptr.pointer_ = 0; - } - - // Construct object in raw memory and take ownership if construction succeeds. - template <typename Arg1, typename Arg2, typename Arg3> - handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3) - : handler_(raw_ptr.handler_), - pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3)) - { - raw_ptr.pointer_ = 0; - } - - // Construct object in raw memory and take ownership if construction succeeds. - template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> - handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4) - : handler_(raw_ptr.handler_), - pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4)) - { - raw_ptr.pointer_ = 0; - } - - // Construct object in raw memory and take ownership if construction succeeds. - template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, - typename Arg5> - handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, - Arg5& a5) - : handler_(raw_ptr.handler_), - pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5)) - { - raw_ptr.pointer_ = 0; - } - - // Construct object in raw memory and take ownership if construction succeeds. - template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, - typename Arg5, typename Arg6> - handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, - Arg5& a5, Arg6& a6) - : handler_(raw_ptr.handler_), - pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6)) - { - raw_ptr.pointer_ = 0; - } - - // Construct object in raw memory and take ownership if construction succeeds. - template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, - typename Arg5, typename Arg6, typename Arg7> - handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, - Arg5& a5, Arg6& a6, Arg7& a7) - : handler_(raw_ptr.handler_), - pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6, a7)) - { - raw_ptr.pointer_ = 0; - } - - // Construct object in raw memory and take ownership if construction succeeds. - template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, - typename Arg5, typename Arg6, typename Arg7, typename Arg8> - handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, - Arg5& a5, Arg6& a6, Arg7& a7, Arg8& a8) - : handler_(raw_ptr.handler_), - pointer_(new (raw_ptr.pointer_) value_type( - a1, a2, a3, a4, a5, a6, a7, a8)) - { - raw_ptr.pointer_ = 0; - } - - // Destructor automatically deallocates memory, unless it has been released. - ~handler_ptr() - { - reset(); - } - - // Get the memory. - pointer_type get() const - { - return pointer_; - } - - // Release ownership of the memory. - pointer_type release() - { - pointer_type tmp = pointer_; - pointer_ = 0; - return tmp; - } - - // Explicitly destroy and deallocate the memory. - void reset() - { - if (pointer_) - { - pointer_->value_type::~value_type(); - boost_asio_handler_alloc_helpers::deallocate( - pointer_, value_size, handler_); - pointer_ = 0; - } - } - -private: - handler_type& handler_; - pointer_type pointer_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost +#define BOOST_ASIO_DEFINE_HANDLER_PTR(op) \ + struct ptr \ + { \ + Handler* h; \ + void* v; \ + op* p; \ + ~ptr() \ + { \ + reset(); \ + } \ + void reset() \ + { \ + if (p) \ + { \ + p->~op(); \ + p = 0; \ + } \ + if (v) \ + { \ + boost_asio_handler_alloc_helpers::deallocate(v, sizeof(op), *h); \ + v = 0; \ + } \ + } \ + } \ + /**/ #include <boost/asio/detail/pop_options.hpp> diff --git a/3rdParty/Boost/src/boost/asio/detail/handler_invoke_helpers.hpp b/3rdParty/Boost/src/boost/asio/detail/handler_invoke_helpers.hpp index 8952d8d..996bde9 100644 --- a/3rdParty/Boost/src/boost/asio/detail/handler_invoke_helpers.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/handler_invoke_helpers.hpp @@ -1,6 +1,6 @@ // -// handler_invoke_helpers.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/handler_invoke_helpers.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,15 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/detail/workaround.hpp> #include <boost/utility/addressof.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/handler_invoke_hook.hpp> +#include <boost/asio/detail/push_options.hpp> + // Calls to asio_handler_invoke must be made from a namespace that does not // contain overloads of this function. The boost_asio_handler_invoke_helpers // namespace is defined here for that purpose. diff --git a/3rdParty/Boost/src/boost/asio/detail/hash_map.hpp b/3rdParty/Boost/src/boost/asio/detail/hash_map.hpp index 36c9a99..c58096b 100644 --- a/3rdParty/Boost/src/boost/asio/detail/hash_map.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/hash_map.hpp @@ -1,6 +1,6 @@ // -// hash_map.hpp -// ~~~~~~~~~~~~ +// detail/hash_map.hpp +// ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,34 +15,39 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cassert> #include <list> #include <utility> -#include <boost/functional/hash.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/detail/noncopyable.hpp> -#include <boost/asio/detail/socket_types.hpp> + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# include <boost/asio/detail/socket_types.hpp> +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace detail { -template <typename T> -inline std::size_t calculate_hash_value(const T& t) +inline std::size_t calculate_hash_value(int i) +{ + return static_cast<std::size_t>(i); +} + +inline std::size_t calculate_hash_value(void* p) { - return boost::hash_value(t); + return reinterpret_cast<std::size_t>(p) + + (reinterpret_cast<std::size_t>(p) >> 3); } -#if defined(_WIN64) +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) inline std::size_t calculate_hash_value(SOCKET s) { return static_cast<std::size_t>(s); } -#endif // defined(_WIN64) +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) // Note: assumes K and V are POD types. template <typename K, typename V> diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/descriptor_ops.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/descriptor_ops.ipp new file mode 100644 index 0000000..74a8e6f --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/descriptor_ops.ipp @@ -0,0 +1,372 @@ +// +// detail/impl/descriptor_ops.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP +#define BOOST_ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <cerrno> +#include <boost/asio/detail/descriptor_ops.hpp> +#include <boost/asio/error.hpp> + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { +namespace descriptor_ops { + +int open(const char* path, int flags, boost::system::error_code& ec) +{ + errno = 0; + int result = error_wrapper(::open(path, flags), ec); + if (result >= 0) + ec = boost::system::error_code(); + return result; +} + +int close(int d, state_type& state, boost::system::error_code& ec) +{ + int result = 0; + if (d != -1) + { + if (state & internal_non_blocking) + { +#if defined(__SYMBIAN32__) + int flags = ::fcntl(d, F_GETFL, 0); + if (flags >= 0) + ::fcntl(d, F_SETFL, flags & ~O_NONBLOCK); +#else // defined(__SYMBIAN32__) + ioctl_arg_type arg = 0; + ::ioctl(d, FIONBIO, &arg); +#endif // defined(__SYMBIAN32__) + state &= ~internal_non_blocking; + } + + errno = 0; + result = error_wrapper(::close(d), ec); + } + + if (result == 0) + ec = boost::system::error_code(); + return result; +} + +bool set_internal_non_blocking(int d, + state_type& state, boost::system::error_code& ec) +{ + if (d == -1) + { + ec = boost::asio::error::bad_descriptor; + return false; + } + + errno = 0; +#if defined(__SYMBIAN32__) + int result = error_wrapper(::fcntl(d, F_GETFL, 0), ec); + if (result >= 0) + { + errno = 0; + result = error_wrapper(::fcntl(d, F_SETFL, result | O_NONBLOCK), ec); + } +#else // defined(__SYMBIAN32__) + ioctl_arg_type arg = 1; + int result = error_wrapper(::ioctl(d, FIONBIO, &arg), ec); +#endif // defined(__SYMBIAN32__) + + if (result >= 0) + { + ec = boost::system::error_code(); + state |= internal_non_blocking; + return true; + } + + return false; +} + +std::size_t sync_read(int d, state_type state, buf* bufs, + std::size_t count, bool all_empty, boost::system::error_code& ec) +{ + if (d == -1) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // A request to read 0 bytes on a stream is a no-op. + if (all_empty) + { + ec = boost::system::error_code(); + return 0; + } + + // Read some data. + for (;;) + { + // Try to complete the operation without blocking. + errno = 0; + int bytes = error_wrapper(::readv(d, bufs, static_cast<int>(count)), ec); + + // Check if operation succeeded. + if (bytes > 0) + return bytes; + + // Check for EOF. + if (bytes == 0) + { + ec = boost::asio::error::eof; + return 0; + } + + // Operation failed. + if ((state & user_set_non_blocking) + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) + return 0; + + // Wait for descriptor to become ready. + if (descriptor_ops::poll_read(d, ec) < 0) + return 0; + } +} + +bool non_blocking_read(int d, buf* bufs, std::size_t count, + boost::system::error_code& ec, std::size_t& bytes_transferred) +{ + for (;;) + { + // Read some data. + errno = 0; + int bytes = error_wrapper(::readv(d, bufs, static_cast<int>(count)), ec); + + // Check for end of stream. + if (bytes == 0) + { + ec = boost::asio::error::eof; + return true; + } + + // Retry operation if interrupted by signal. + if (ec == boost::asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + + // Operation is complete. + if (bytes > 0) + { + ec = boost::system::error_code(); + bytes_transferred = bytes; + } + else + bytes_transferred = 0; + + return true; + } +} + +std::size_t sync_write(int d, state_type state, const buf* bufs, + std::size_t count, bool all_empty, boost::system::error_code& ec) +{ + if (d == -1) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // A request to write 0 bytes on a stream is a no-op. + if (all_empty) + { + ec = boost::system::error_code(); + return 0; + } + + // Write some data. + for (;;) + { + // Try to complete the operation without blocking. + errno = 0; + int bytes = error_wrapper(::writev(d, bufs, static_cast<int>(count)), ec); + + // Check if operation succeeded. + if (bytes > 0) + return bytes; + + // Operation failed. + if ((state & user_set_non_blocking) + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) + return 0; + + // Wait for descriptor to become ready. + if (descriptor_ops::poll_write(d, ec) < 0) + return 0; + } +} + +bool non_blocking_write(int d, const buf* bufs, std::size_t count, + boost::system::error_code& ec, std::size_t& bytes_transferred) +{ + for (;;) + { + // Write some data. + errno = 0; + int bytes = error_wrapper(::writev(d, bufs, static_cast<int>(count)), ec); + + // Retry operation if interrupted by signal. + if (ec == boost::asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + + // Operation is complete. + if (bytes >= 0) + { + ec = boost::system::error_code(); + bytes_transferred = bytes; + } + else + bytes_transferred = 0; + + return true; + } +} + +int ioctl(int d, state_type& state, long cmd, + ioctl_arg_type* arg, boost::system::error_code& ec) +{ + if (d == -1) + { + ec = boost::asio::error::bad_descriptor; + return -1; + } + + errno = 0; + int result = error_wrapper(::ioctl(d, cmd, arg), ec); + + if (result >= 0) + { + ec = boost::system::error_code(); + + // When updating the non-blocking mode we always perform the ioctl syscall, + // even if the flags would otherwise indicate that the descriptor is + // already in the correct state. This ensures that the underlying + // descriptor is put into the state that has been requested by the user. If + // the ioctl syscall was successful then we need to update the flags to + // match. + if (cmd == static_cast<long>(FIONBIO)) + { + if (*arg) + { + state |= user_set_non_blocking; + } + else + { + // Clearing the non-blocking mode always overrides any internally-set + // non-blocking flag. Any subsequent asynchronous operations will need + // to re-enable non-blocking I/O. + state &= ~(user_set_non_blocking | internal_non_blocking); + } + } + } + + return result; +} + +int fcntl(int d, long cmd, boost::system::error_code& ec) +{ + if (d == -1) + { + ec = boost::asio::error::bad_descriptor; + return -1; + } + + errno = 0; + int result = error_wrapper(::fcntl(d, cmd), ec); + if (result != -1) + ec = boost::system::error_code(); + return result; +} + +int fcntl(int d, long cmd, long arg, boost::system::error_code& ec) +{ + if (d == -1) + { + ec = boost::asio::error::bad_descriptor; + return -1; + } + + errno = 0; + int result = error_wrapper(::fcntl(d, cmd, arg), ec); + if (result != -1) + ec = boost::system::error_code(); + return result; +} + +int poll_read(int d, boost::system::error_code& ec) +{ + if (d == -1) + { + ec = boost::asio::error::bad_descriptor; + return -1; + } + + pollfd fds; + fds.fd = d; + fds.events = POLLIN; + fds.revents = 0; + errno = 0; + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + ec = boost::system::error_code(); + return result; +} + +int poll_write(int d, boost::system::error_code& ec) +{ + if (d == -1) + { + ec = boost::asio::error::bad_descriptor; + return -1; + } + + pollfd fds; + fds.fd = d; + fds.events = POLLOUT; + fds.revents = 0; + errno = 0; + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + ec = boost::system::error_code(); + return result; +} + +} // namespace descriptor_ops +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#endif // BOOST_ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.hpp new file mode 100644 index 0000000..2aed0a8 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.hpp @@ -0,0 +1,79 @@ +// +// detail/impl/dev_poll_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP +#define BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_DEV_POLL) + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Time_Traits> +void dev_poll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue) +{ + do_add_timer_queue(queue); +} + +template <typename Time_Traits> +void dev_poll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue) +{ + do_remove_timer_queue(queue); +} + +template <typename Time_Traits> +void dev_poll_reactor::schedule_timer(timer_queue<Time_Traits>& queue, + const typename Time_Traits::time_type& time, + typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + { + io_service_.post_immediate_completion(op); + return; + } + + bool earliest = queue.enqueue_timer(time, timer, op); + io_service_.work_started(); + if (earliest) + interrupter_.interrupt(); +} + +template <typename Time_Traits> +std::size_t dev_poll_reactor::cancel_timer(timer_queue<Time_Traits>& queue, + typename timer_queue<Time_Traits>::per_timer_data& timer) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + op_queue<operation> ops; + std::size_t n = queue.cancel_timer(timer, ops); + lock.unlock(); + io_service_.post_deferred_completions(ops); + return n; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_DEV_POLL) + +#endif // BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.ipp new file mode 100644 index 0000000..67f6d50 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.ipp @@ -0,0 +1,340 @@ +// +// detail/impl/dev_poll_reactor.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_IPP +#define BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_DEV_POLL) + +#include <boost/asio/detail/dev_poll_reactor.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +dev_poll_reactor::dev_poll_reactor(boost::asio::io_service& io_service) + : boost::asio::detail::service_base<dev_poll_reactor>(io_service), + io_service_(use_service<io_service_impl>(io_service)), + mutex_(), + dev_poll_fd_(do_dev_poll_create()), + interrupter_(), + shutdown_(false) +{ + // Add the interrupter's descriptor to /dev/poll. + ::pollfd ev = { 0 }; + ev.fd = interrupter_.read_descriptor(); + ev.events = POLLIN | POLLERR; + ev.revents = 0; + ::write(dev_poll_fd_, &ev, sizeof(ev)); +} + +dev_poll_reactor::~dev_poll_reactor() +{ + shutdown_service(); + ::close(dev_poll_fd_); +} + +void dev_poll_reactor::shutdown_service() +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + shutdown_ = true; + lock.unlock(); + + op_queue<operation> ops; + + for (int i = 0; i < max_ops; ++i) + op_queue_[i].get_all_operations(ops); + + timer_queues_.get_all_timers(ops); +} + +void dev_poll_reactor::init_task() +{ + io_service_.init_task(); +} + +int dev_poll_reactor::register_descriptor(socket_type, per_descriptor_data&) +{ + return 0; +} + +void dev_poll_reactor::start_op(int op_type, socket_type descriptor, + dev_poll_reactor::per_descriptor_data&, + reactor_op* op, bool allow_speculative) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + { + post_immediate_completion(op); + return; + } + + if (allow_speculative) + { + if (op_type != read_op || !op_queue_[except_op].has_operation(descriptor)) + { + if (!op_queue_[op_type].has_operation(descriptor)) + { + if (op->perform()) + { + lock.unlock(); + io_service_.post_immediate_completion(op); + return; + } + } + } + } + + bool first = op_queue_[op_type].enqueue_operation(descriptor, op); + io_service_.work_started(); + if (first) + { + ::pollfd& ev = add_pending_event_change(descriptor); + ev.events = POLLERR | POLLHUP; + if (op_type == read_op + || op_queue_[read_op].has_operation(descriptor)) + ev.events |= POLLIN; + if (op_type == write_op + || op_queue_[write_op].has_operation(descriptor)) + ev.events |= POLLOUT; + if (op_type == except_op + || op_queue_[except_op].has_operation(descriptor)) + ev.events |= POLLPRI; + interrupter_.interrupt(); + } +} + +void dev_poll_reactor::cancel_ops(socket_type descriptor, + dev_poll_reactor::per_descriptor_data&) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted); +} + +void dev_poll_reactor::close_descriptor(socket_type descriptor, + dev_poll_reactor::per_descriptor_data&) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // Remove the descriptor from /dev/poll. + ::pollfd& ev = add_pending_event_change(descriptor); + ev.events = POLLREMOVE; + interrupter_.interrupt(); + + // Cancel any outstanding operations associated with the descriptor. + cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted); +} + +void dev_poll_reactor::run(bool block, op_queue<operation>& ops) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // We can return immediately if there's no work to do and the reactor is + // not supposed to block. + if (!block && op_queue_[read_op].empty() && op_queue_[write_op].empty() + && op_queue_[except_op].empty() && timer_queues_.all_empty()) + return; + + // Write the pending event registration changes to the /dev/poll descriptor. + std::size_t events_size = sizeof(::pollfd) * pending_event_changes_.size(); + if (events_size > 0) + { + errno = 0; + int result = ::write(dev_poll_fd_, + &pending_event_changes_[0], events_size); + if (result != static_cast<int>(events_size)) + { + boost::system::error_code ec = boost::system::error_code( + errno, boost::asio::error::get_system_category()); + for (std::size_t i = 0; i < pending_event_changes_.size(); ++i) + { + int descriptor = pending_event_changes_[i].fd; + for (int j = 0; j < max_ops; ++j) + op_queue_[j].cancel_operations(descriptor, ops, ec); + } + } + pending_event_changes_.clear(); + pending_event_change_index_.clear(); + } + + int timeout = block ? get_timeout() : 0; + lock.unlock(); + + // Block on the /dev/poll descriptor. + ::pollfd events[128] = { { 0 } }; + ::dvpoll dp = { 0 }; + dp.dp_fds = events; + dp.dp_nfds = 128; + dp.dp_timeout = timeout; + int num_events = ::ioctl(dev_poll_fd_, DP_POLL, &dp); + + lock.lock(); + + // Dispatch the waiting events. + for (int i = 0; i < num_events; ++i) + { + int descriptor = events[i].fd; + if (descriptor == interrupter_.read_descriptor()) + { + interrupter_.reset(); + } + else + { + bool more_reads = false; + bool more_writes = false; + bool more_except = false; + + // Exception operations must be processed first to ensure that any + // out-of-band data is read before normal data. + if (events[i].events & (POLLPRI | POLLERR | POLLHUP)) + more_except = + op_queue_[except_op].perform_operations(descriptor, ops); + else + more_except = op_queue_[except_op].has_operation(descriptor); + + if (events[i].events & (POLLIN | POLLERR | POLLHUP)) + more_reads = op_queue_[read_op].perform_operations(descriptor, ops); + else + more_reads = op_queue_[read_op].has_operation(descriptor); + + if (events[i].events & (POLLOUT | POLLERR | POLLHUP)) + more_writes = op_queue_[write_op].perform_operations(descriptor, ops); + else + more_writes = op_queue_[write_op].has_operation(descriptor); + + if ((events[i].events & (POLLERR | POLLHUP)) != 0 + && !more_except && !more_reads && !more_writes) + { + // If we have an event and no operations associated with the + // descriptor then we need to delete the descriptor from /dev/poll. + // The poll operation can produce POLLHUP or POLLERR events when there + // is no operation pending, so if we do not remove the descriptor we + // can end up in a tight polling loop. + ::pollfd ev = { 0 }; + ev.fd = descriptor; + ev.events = POLLREMOVE; + ev.revents = 0; + ::write(dev_poll_fd_, &ev, sizeof(ev)); + } + else + { + ::pollfd ev = { 0 }; + ev.fd = descriptor; + ev.events = POLLERR | POLLHUP; + if (more_reads) + ev.events |= POLLIN; + if (more_writes) + ev.events |= POLLOUT; + if (more_except) + ev.events |= POLLPRI; + ev.revents = 0; + int result = ::write(dev_poll_fd_, &ev, sizeof(ev)); + if (result != sizeof(ev)) + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + for (int j = 0; j < max_ops; ++j) + op_queue_[j].cancel_operations(descriptor, ops, ec); + } + } + } + } + timer_queues_.get_ready_timers(ops); +} + +void dev_poll_reactor::interrupt() +{ + interrupter_.interrupt(); +} + +int dev_poll_reactor::do_dev_poll_create() +{ + int fd = ::open("/dev/poll", O_RDWR); + if (fd == -1) + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "/dev/poll"); + } + return fd; +} + +void dev_poll_reactor::do_add_timer_queue(timer_queue_base& queue) +{ + mutex::scoped_lock lock(mutex_); + timer_queues_.insert(&queue); +} + +void dev_poll_reactor::do_remove_timer_queue(timer_queue_base& queue) +{ + mutex::scoped_lock lock(mutex_); + timer_queues_.erase(&queue); +} + +int dev_poll_reactor::get_timeout() +{ + // By default we will wait no longer than 5 minutes. This will ensure that + // any changes to the system clock are detected after no longer than this. + return timer_queues_.wait_duration_msec(5 * 60 * 1000); +} + +void dev_poll_reactor::cancel_ops_unlocked(socket_type descriptor, + const boost::system::error_code& ec) +{ + bool need_interrupt = false; + op_queue<operation> ops; + for (int i = 0; i < max_ops; ++i) + need_interrupt = op_queue_[i].cancel_operations( + descriptor, ops, ec) || need_interrupt; + io_service_.post_deferred_completions(ops); + if (need_interrupt) + interrupter_.interrupt(); +} + +::pollfd& dev_poll_reactor::add_pending_event_change(int descriptor) +{ + hash_map<int, std::size_t>::iterator iter + = pending_event_change_index_.find(descriptor); + if (iter == pending_event_change_index_.end()) + { + std::size_t index = pending_event_changes_.size(); + pending_event_changes_.reserve(pending_event_changes_.size() + 1); + pending_event_change_index_.insert(std::make_pair(descriptor, index)); + pending_event_changes_.push_back(::pollfd()); + pending_event_changes_[index].fd = descriptor; + pending_event_changes_[index].revents = 0; + return pending_event_changes_[index]; + } + else + { + return pending_event_changes_[iter->second]; + } +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_DEV_POLL) + +#endif // BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.hpp new file mode 100644 index 0000000..49f0d50 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.hpp @@ -0,0 +1,77 @@ +// +// detail/impl/epoll_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP +#define BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if defined(BOOST_ASIO_HAS_EPOLL) + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Time_Traits> +void epoll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue) +{ + do_add_timer_queue(queue); +} + +template <typename Time_Traits> +void epoll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue) +{ + do_remove_timer_queue(queue); +} + +template <typename Time_Traits> +void epoll_reactor::schedule_timer(timer_queue<Time_Traits>& queue, + const typename Time_Traits::time_type& time, + typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op) +{ + mutex::scoped_lock lock(mutex_); + + if (shutdown_) + { + io_service_.post_immediate_completion(op); + return; + } + + bool earliest = queue.enqueue_timer(time, timer, op); + io_service_.work_started(); + if (earliest) + update_timeout(); +} + +template <typename Time_Traits> +std::size_t epoll_reactor::cancel_timer(timer_queue<Time_Traits>& queue, + typename timer_queue<Time_Traits>::per_timer_data& timer) +{ + mutex::scoped_lock lock(mutex_); + op_queue<operation> ops; + std::size_t n = queue.cancel_timer(timer, ops); + lock.unlock(); + io_service_.post_deferred_completions(ops); + return n; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_EPOLL) + +#endif // BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.ipp new file mode 100644 index 0000000..a4c2491 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.ipp @@ -0,0 +1,392 @@ +// +// detail/impl/epoll_reactor.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP +#define BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_EPOLL) + +#include <cstddef> +#include <sys/epoll.h> +#include <boost/asio/detail/epoll_reactor.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#if defined(BOOST_ASIO_HAS_TIMERFD) +# include <sys/timerfd.h> +#endif // defined(BOOST_ASIO_HAS_TIMERFD) + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +epoll_reactor::epoll_reactor(boost::asio::io_service& io_service) + : boost::asio::detail::service_base<epoll_reactor>(io_service), + io_service_(use_service<io_service_impl>(io_service)), + mutex_(), + epoll_fd_(do_epoll_create()), +#if defined(BOOST_ASIO_HAS_TIMERFD) + timer_fd_(timerfd_create(CLOCK_MONOTONIC, 0)), +#else // defined(BOOST_ASIO_HAS_TIMERFD) + timer_fd_(-1), +#endif // defined(BOOST_ASIO_HAS_TIMERFD) + interrupter_(), + shutdown_(false) +{ + // Add the interrupter's descriptor to epoll. + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLIN | EPOLLERR | EPOLLET; + ev.data.ptr = &interrupter_; + epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev); + interrupter_.interrupt(); + + // Add the timer descriptor to epoll. + if (timer_fd_ != -1) + { + ev.events = EPOLLIN | EPOLLERR; + ev.data.ptr = &timer_fd_; + epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &ev); + } +} + +epoll_reactor::~epoll_reactor() +{ + close(epoll_fd_); + if (timer_fd_ != -1) + close(timer_fd_); +} + +void epoll_reactor::shutdown_service() +{ + mutex::scoped_lock lock(mutex_); + shutdown_ = true; + lock.unlock(); + + op_queue<operation> ops; + + while (descriptor_state* state = registered_descriptors_.first()) + { + for (int i = 0; i < max_ops; ++i) + ops.push(state->op_queue_[i]); + state->shutdown_ = true; + registered_descriptors_.free(state); + } + + timer_queues_.get_all_timers(ops); +} + +void epoll_reactor::init_task() +{ + io_service_.init_task(); +} + +int epoll_reactor::register_descriptor(socket_type descriptor, + epoll_reactor::per_descriptor_data& descriptor_data) +{ + mutex::scoped_lock lock(registered_descriptors_mutex_); + + descriptor_data = registered_descriptors_.alloc(); + descriptor_data->shutdown_ = false; + + lock.unlock(); + + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLOUT | EPOLLPRI | EPOLLET; + ev.data.ptr = descriptor_data; + int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); + if (result != 0) + return errno; + + return 0; +} + +void epoll_reactor::start_op(int op_type, socket_type descriptor, + epoll_reactor::per_descriptor_data& descriptor_data, + reactor_op* op, bool allow_speculative) +{ + if (!descriptor_data) + { + op->ec_ = boost::asio::error::bad_descriptor; + post_immediate_completion(op); + return; + } + + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + + if (descriptor_data->shutdown_) + { + post_immediate_completion(op); + return; + } + + if (descriptor_data->op_queue_[op_type].empty()) + { + if (allow_speculative + && (op_type != read_op + || descriptor_data->op_queue_[except_op].empty())) + { + if (op->perform()) + { + descriptor_lock.unlock(); + io_service_.post_immediate_completion(op); + return; + } + } + else + { + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLIN | EPOLLERR | EPOLLHUP + | EPOLLOUT | EPOLLPRI | EPOLLET; + ev.data.ptr = descriptor_data; + epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); + } + } + + descriptor_data->op_queue_[op_type].push(op); + io_service_.work_started(); +} + +void epoll_reactor::cancel_ops(socket_type, + epoll_reactor::per_descriptor_data& descriptor_data) +{ + if (!descriptor_data) + return; + + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + + op_queue<operation> ops; + for (int i = 0; i < max_ops; ++i) + { + while (reactor_op* op = descriptor_data->op_queue_[i].front()) + { + op->ec_ = boost::asio::error::operation_aborted; + descriptor_data->op_queue_[i].pop(); + ops.push(op); + } + } + + descriptor_lock.unlock(); + + io_service_.post_deferred_completions(ops); +} + +void epoll_reactor::close_descriptor(socket_type, + epoll_reactor::per_descriptor_data& descriptor_data) +{ + if (!descriptor_data) + return; + + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); + + if (!descriptor_data->shutdown_) + { + // Remove the descriptor from the set of known descriptors. The descriptor + // will be automatically removed from the epoll set when it is closed. + + op_queue<operation> ops; + for (int i = 0; i < max_ops; ++i) + { + while (reactor_op* op = descriptor_data->op_queue_[i].front()) + { + op->ec_ = boost::asio::error::operation_aborted; + descriptor_data->op_queue_[i].pop(); + ops.push(op); + } + } + + descriptor_data->shutdown_ = true; + + descriptor_lock.unlock(); + + registered_descriptors_.free(descriptor_data); + descriptor_data = 0; + + descriptors_lock.unlock(); + + io_service_.post_deferred_completions(ops); + } +} + +void epoll_reactor::run(bool block, op_queue<operation>& ops) +{ + // Calculate a timeout only if timerfd is not used. + int timeout; + if (timer_fd_ != -1) + timeout = block ? -1 : 0; + else + { + mutex::scoped_lock lock(mutex_); + timeout = block ? get_timeout() : 0; + } + + // Block on the epoll descriptor. + epoll_event events[128]; + int num_events = epoll_wait(epoll_fd_, events, 128, timeout); + +#if defined(BOOST_ASIO_HAS_TIMERFD) + bool check_timers = (timer_fd_ == -1); +#else // defined(BOOST_ASIO_HAS_TIMERFD) + bool check_timers = true; +#endif // defined(BOOST_ASIO_HAS_TIMERFD) + + // Dispatch the waiting events. + for (int i = 0; i < num_events; ++i) + { + void* ptr = events[i].data.ptr; + if (ptr == &interrupter_) + { + // No need to reset the interrupter since we're leaving the descriptor + // in a ready-to-read state and relying on edge-triggered notifications + // to make it so that we only get woken up when the descriptor's epoll + // registration is updated. + +#if defined(BOOST_ASIO_HAS_TIMERFD) + if (timer_fd_ == -1) + check_timers = true; +#else // defined(BOOST_ASIO_HAS_TIMERFD) + check_timers = true; +#endif // defined(BOOST_ASIO_HAS_TIMERFD) + } +#if defined(BOOST_ASIO_HAS_TIMERFD) + else if (ptr == &timer_fd_) + { + check_timers = true; + } +#endif // defined(BOOST_ASIO_HAS_TIMERFD) + else + { + descriptor_state* descriptor_data = static_cast<descriptor_state*>(ptr); + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + + // Exception operations must be processed first to ensure that any + // out-of-band data is read before normal data. + static const int flag[max_ops] = { EPOLLIN, EPOLLOUT, EPOLLPRI }; + for (int j = max_ops - 1; j >= 0; --j) + { + if (events[i].events & (flag[j] | EPOLLERR | EPOLLHUP)) + { + while (reactor_op* op = descriptor_data->op_queue_[j].front()) + { + if (op->perform()) + { + descriptor_data->op_queue_[j].pop(); + ops.push(op); + } + else + break; + } + } + } + } + } + + if (check_timers) + { + mutex::scoped_lock common_lock(mutex_); + timer_queues_.get_ready_timers(ops); + +#if defined(BOOST_ASIO_HAS_TIMERFD) + if (timer_fd_ != -1) + { + itimerspec new_timeout; + itimerspec old_timeout; + int flags = get_timeout(new_timeout); + timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout); + } +#endif // defined(BOOST_ASIO_HAS_TIMERFD) + } +} + +void epoll_reactor::interrupt() +{ + epoll_event ev = { 0, { 0 } }; + ev.events = EPOLLIN | EPOLLERR | EPOLLET; + ev.data.ptr = &interrupter_; + epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, interrupter_.read_descriptor(), &ev); +} + +int epoll_reactor::do_epoll_create() +{ + int fd = epoll_create(epoll_size); + if (fd == -1) + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "epoll"); + } + return fd; +} + +void epoll_reactor::do_add_timer_queue(timer_queue_base& queue) +{ + mutex::scoped_lock lock(mutex_); + timer_queues_.insert(&queue); +} + +void epoll_reactor::do_remove_timer_queue(timer_queue_base& queue) +{ + mutex::scoped_lock lock(mutex_); + timer_queues_.erase(&queue); +} + +void epoll_reactor::update_timeout() +{ +#if defined(BOOST_ASIO_HAS_TIMERFD) + if (timer_fd_ != -1) + { + itimerspec new_timeout; + itimerspec old_timeout; + int flags = get_timeout(new_timeout); + timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout); + return; + } +#endif // defined(BOOST_ASIO_HAS_TIMERFD) + interrupter_.interrupt(); +} + +int epoll_reactor::get_timeout() +{ + // By default we will wait no longer than 5 minutes. This will ensure that + // any changes to the system clock are detected after no longer than this. + return timer_queues_.wait_duration_msec(5 * 60 * 1000); +} + +#if defined(BOOST_ASIO_HAS_TIMERFD) +int epoll_reactor::get_timeout(itimerspec& ts) +{ + ts.it_interval.tv_sec = 0; + ts.it_interval.tv_nsec = 0; + + long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000); + ts.it_value.tv_sec = usec / 1000000; + ts.it_value.tv_nsec = usec ? (usec % 1000000) * 1000 : 1; + + return usec ? 0 : TFD_TIMER_ABSTIME; +} +#endif // defined(BOOST_ASIO_HAS_TIMERFD) + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_EPOLL) + +#endif // BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/eventfd_select_interrupter.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/eventfd_select_interrupter.ipp new file mode 100644 index 0000000..5bcc55b --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/eventfd_select_interrupter.ipp @@ -0,0 +1,127 @@ +// +// detail/impl/eventfd_select_interrupter.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_EVENTFD_SELECT_INTERRUPTER_IPP +#define BOOST_ASIO_DETAIL_IMPL_EVENTFD_SELECT_INTERRUPTER_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_EVENTFD) + +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 +# include <asm/unistd.h> +#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 +# include <sys/eventfd.h> +#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 +#include <boost/asio/detail/eventfd_select_interrupter.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +eventfd_select_interrupter::eventfd_select_interrupter() +{ +#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 + write_descriptor_ = read_descriptor_ = syscall(__NR_eventfd, 0); +#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 + write_descriptor_ = read_descriptor_ = ::eventfd(0, 0); +#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 + if (read_descriptor_ != -1) + { + ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); + } + else + { + int pipe_fds[2]; + if (pipe(pipe_fds) == 0) + { + read_descriptor_ = pipe_fds[0]; + ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); + write_descriptor_ = pipe_fds[1]; + ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK); + } + else + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "eventfd_select_interrupter"); + } + } +} + +eventfd_select_interrupter::~eventfd_select_interrupter() +{ + if (write_descriptor_ != -1 && write_descriptor_ != read_descriptor_) + ::close(write_descriptor_); + if (read_descriptor_ != -1) + ::close(read_descriptor_); +} + +void eventfd_select_interrupter::interrupt() +{ + uint64_t counter(1UL); + int result = ::write(write_descriptor_, &counter, sizeof(uint64_t)); + (void)result; +} + +bool eventfd_select_interrupter::reset() +{ + if (write_descriptor_ == read_descriptor_) + { + for (;;) + { + // Only perform one read. The kernel maintains an atomic counter. + uint64_t counter(0); + errno = 0; + int bytes_read = ::read(read_descriptor_, &counter, sizeof(uint64_t)); + if (bytes_read < 0 && errno == EINTR) + continue; + bool was_interrupted = (bytes_read > 0); + return was_interrupted; + } + } + else + { + for (;;) + { + // Clear all data from the pipe. + char data[1024]; + int bytes_read = ::read(read_descriptor_, data, sizeof(data)); + if (bytes_read < 0 && errno == EINTR) + continue; + bool was_interrupted = (bytes_read > 0); + while (bytes_read == sizeof(data)) + bytes_read = ::read(read_descriptor_, data, sizeof(data)); + return was_interrupted; + } + } +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_EVENTFD) + +#endif // BOOST_ASIO_DETAIL_IMPL_EVENTFD_SELECT_INTERRUPTER_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.hpp new file mode 100644 index 0000000..7bb0269 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.hpp @@ -0,0 +1,81 @@ +// +// detail/impl/kqueue_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005 Stefan Arentz (stefan at soze 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP +#define BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_KQUEUE) + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Time_Traits> +void kqueue_reactor::add_timer_queue(timer_queue<Time_Traits>& queue) +{ + do_add_timer_queue(queue); +} + +// Remove a timer queue from the reactor. +template <typename Time_Traits> +void kqueue_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue) +{ + do_remove_timer_queue(queue); +} + +template <typename Time_Traits> +void kqueue_reactor::schedule_timer(timer_queue<Time_Traits>& queue, + const typename Time_Traits::time_type& time, + typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + { + io_service_.post_immediate_completion(op); + return; + } + + bool earliest = queue.enqueue_timer(time, timer, op); + io_service_.work_started(); + if (earliest) + interrupt(); +} + +template <typename Time_Traits> +std::size_t kqueue_reactor::cancel_timer(timer_queue<Time_Traits>& queue, + typename timer_queue<Time_Traits>::per_timer_data& timer) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + op_queue<operation> ops; + std::size_t n = queue.cancel_timer(timer, ops); + lock.unlock(); + io_service_.post_deferred_completions(ops); + return n; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_KQUEUE) + +#endif // BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp new file mode 100644 index 0000000..08209bd --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp @@ -0,0 +1,387 @@ +// +// detail/impl/kqueue_reactor.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2005 Stefan Arentz (stefan at soze 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_IPP +#define BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_KQUEUE) + +#include <boost/asio/detail/kqueue_reactor.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +#if defined(__NetBSD__) +# define BOOST_ASIO_KQUEUE_EV_SET(ev, ident, filt, flags, fflags, data, udata) \ + EV_SET(ev, ident, filt, flags, fflags, \ + data, reinterpret_cast<intptr_t>(udata)) +#else +# define BOOST_ASIO_KQUEUE_EV_SET(ev, ident, filt, flags, fflags, data, udata) \ + EV_SET(ev, ident, filt, flags, fflags, data, udata) +#endif + +namespace boost { +namespace asio { +namespace detail { + +kqueue_reactor::kqueue_reactor(boost::asio::io_service& io_service) + : boost::asio::detail::service_base<kqueue_reactor>(io_service), + io_service_(use_service<io_service_impl>(io_service)), + mutex_(), + kqueue_fd_(do_kqueue_create()), + interrupter_(), + shutdown_(false) +{ + // The interrupter is put into a permanently readable state. Whenever we + // want to interrupt the blocked kevent call we register a one-shot read + // operation against the descriptor. + interrupter_.interrupt(); +} + +kqueue_reactor::~kqueue_reactor() +{ + close(kqueue_fd_); +} + +void kqueue_reactor::shutdown_service() +{ + mutex::scoped_lock lock(mutex_); + shutdown_ = true; + lock.unlock(); + + op_queue<operation> ops; + + while (descriptor_state* state = registered_descriptors_.first()) + { + for (int i = 0; i < max_ops; ++i) + ops.push(state->op_queue_[i]); + state->shutdown_ = true; + registered_descriptors_.free(state); + } + + timer_queues_.get_all_timers(ops); +} + +void kqueue_reactor::init_task() +{ + io_service_.init_task(); +} + +int kqueue_reactor::register_descriptor(socket_type, + kqueue_reactor::per_descriptor_data& descriptor_data) +{ + mutex::scoped_lock lock(registered_descriptors_mutex_); + + descriptor_data = registered_descriptors_.alloc(); + descriptor_data->shutdown_ = false; + + return 0; +} + +void kqueue_reactor::start_op(int op_type, socket_type descriptor, + kqueue_reactor::per_descriptor_data& descriptor_data, + reactor_op* op, bool allow_speculative) +{ + if (!descriptor_data) + { + op->ec_ = boost::asio::error::bad_descriptor; + post_immediate_completion(op); + return; + } + + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + + if (descriptor_data->shutdown_) + { + post_immediate_completion(op); + return; + } + + bool first = descriptor_data->op_queue_[op_type].empty(); + if (first) + { + if (allow_speculative) + { + if (op_type != read_op || descriptor_data->op_queue_[except_op].empty()) + { + if (op->perform()) + { + descriptor_lock.unlock(); + io_service_.post_immediate_completion(op); + return; + } + } + } + } + + descriptor_data->op_queue_[op_type].push(op); + io_service_.work_started(); + + if (first) + { + struct kevent event; + switch (op_type) + { + case read_op: + BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_READ, + EV_ADD | EV_ONESHOT, 0, 0, descriptor_data); + break; + case write_op: + BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_WRITE, + EV_ADD | EV_ONESHOT, 0, 0, descriptor_data); + break; + case except_op: + if (!descriptor_data->op_queue_[read_op].empty()) + return; // Already registered for read events. + BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_READ, + EV_ADD | EV_ONESHOT, EV_OOBAND, 0, descriptor_data); + break; + } + + if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) + { + op->ec_ = boost::system::error_code(errno, + boost::asio::error::get_system_category()); + descriptor_data->op_queue_[op_type].pop(); + io_service_.post_deferred_completion(op); + } + } +} + +void kqueue_reactor::cancel_ops(socket_type, + kqueue_reactor::per_descriptor_data& descriptor_data) +{ + if (!descriptor_data) + return; + + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + + op_queue<operation> ops; + for (int i = 0; i < max_ops; ++i) + { + while (reactor_op* op = descriptor_data->op_queue_[i].front()) + { + op->ec_ = boost::asio::error::operation_aborted; + descriptor_data->op_queue_[i].pop(); + ops.push(op); + } + } + + descriptor_lock.unlock(); + + io_service_.post_deferred_completions(ops); +} + +void kqueue_reactor::close_descriptor(socket_type, + kqueue_reactor::per_descriptor_data& descriptor_data) +{ + if (!descriptor_data) + return; + + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); + + if (!descriptor_data->shutdown_) + { + // Remove the descriptor from the set of known descriptors. The descriptor + // will be automatically removed from the kqueue set when it is closed. + + op_queue<operation> ops; + for (int i = 0; i < max_ops; ++i) + { + while (reactor_op* op = descriptor_data->op_queue_[i].front()) + { + op->ec_ = boost::asio::error::operation_aborted; + descriptor_data->op_queue_[i].pop(); + ops.push(op); + } + } + + descriptor_data->shutdown_ = true; + + descriptor_lock.unlock(); + + registered_descriptors_.free(descriptor_data); + descriptor_data = 0; + + descriptors_lock.unlock(); + + io_service_.post_deferred_completions(ops); + } +} + +void kqueue_reactor::run(bool block, op_queue<operation>& ops) +{ + mutex::scoped_lock lock(mutex_); + + // Determine how long to block while waiting for events. + timespec timeout_buf = { 0, 0 }; + timespec* timeout = block ? get_timeout(timeout_buf) : &timeout_buf; + + lock.unlock(); + + // Block on the kqueue descriptor. + struct kevent events[128]; + int num_events = kevent(kqueue_fd_, 0, 0, events, 128, timeout); + + // Dispatch the waiting events. + for (int i = 0; i < num_events; ++i) + { + int descriptor = events[i].ident; + void* ptr = reinterpret_cast<void*>(events[i].udata); + if (ptr == &interrupter_) + { + // No need to reset the interrupter since we're leaving the descriptor + // in a ready-to-read state and relying on one-shot notifications. + } + else + { + descriptor_state* descriptor_data = static_cast<descriptor_state*>(ptr); + mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + + // Exception operations must be processed first to ensure that any + // out-of-band data is read before normal data. +#if defined(__NetBSD__) + static const unsigned int filter[max_ops] = +#else + static const int filter[max_ops] = +#endif + { EVFILT_READ, EVFILT_WRITE, EVFILT_READ }; + for (int j = max_ops - 1; j >= 0; --j) + { + if (events[i].filter == filter[j]) + { + if (j != except_op || events[i].flags & EV_OOBAND) + { + while (reactor_op* op = descriptor_data->op_queue_[j].front()) + { + if (events[i].flags & EV_ERROR) + { + op->ec_ = boost::system::error_code(events[i].data, + boost::asio::error::get_system_category()); + descriptor_data->op_queue_[j].pop(); + ops.push(op); + } + if (op->perform()) + { + descriptor_data->op_queue_[j].pop(); + ops.push(op); + } + else + break; + } + } + } + } + + // Renew registration for event notifications. + struct kevent event; + switch (events[i].filter) + { + case EVFILT_READ: + if (!descriptor_data->op_queue_[read_op].empty()) + BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_READ, + EV_ADD | EV_ONESHOT, 0, 0, descriptor_data); + else if (!descriptor_data->op_queue_[except_op].empty()) + BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_READ, + EV_ADD | EV_ONESHOT, EV_OOBAND, 0, descriptor_data); + else + continue; + case EVFILT_WRITE: + if (!descriptor_data->op_queue_[write_op].empty()) + BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_WRITE, + EV_ADD | EV_ONESHOT, 0, 0, descriptor_data); + else + continue; + default: + break; + } + if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) + { + boost::system::error_code error(errno, + boost::asio::error::get_system_category()); + for (int j = 0; j < max_ops; ++j) + { + while (reactor_op* op = descriptor_data->op_queue_[j].front()) + { + op->ec_ = error; + descriptor_data->op_queue_[j].pop(); + ops.push(op); + } + } + } + } + } + + lock.lock(); + timer_queues_.get_ready_timers(ops); +} + +void kqueue_reactor::interrupt() +{ + struct kevent event; + BOOST_ASIO_KQUEUE_EV_SET(&event, interrupter_.read_descriptor(), + EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &interrupter_); + ::kevent(kqueue_fd_, &event, 1, 0, 0, 0); +} + +int kqueue_reactor::do_kqueue_create() +{ + int fd = ::kqueue(); + if (fd == -1) + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "kqueue"); + } + return fd; +} + +void kqueue_reactor::do_add_timer_queue(timer_queue_base& queue) +{ + mutex::scoped_lock lock(mutex_); + timer_queues_.insert(&queue); +} + +void kqueue_reactor::do_remove_timer_queue(timer_queue_base& queue) +{ + mutex::scoped_lock lock(mutex_); + timer_queues_.erase(&queue); +} + +timespec* kqueue_reactor::get_timeout(timespec& ts) +{ + // By default we will wait no longer than 5 minutes. This will ensure that + // any changes to the system clock are detected after no longer than this. + long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000); + ts.tv_sec = usec / 1000000; + ts.tv_nsec = (usec % 1000000) * 1000; + return &ts; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#undef BOOST_ASIO_KQUEUE_EV_SET + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_KQUEUE) + +#endif // BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/pipe_select_interrupter.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/pipe_select_interrupter.ipp new file mode 100644 index 0000000..f2a7291 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/pipe_select_interrupter.ipp @@ -0,0 +1,98 @@ +// +// detail/impl/pipe_select_interrupter.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP +#define BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if !defined(BOOST_WINDOWS) +#if !defined(__CYGWIN__) +#if !defined(__SYMBIAN32__) +#if !defined(BOOST_ASIO_HAS_EVENTFD) + +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <boost/asio/detail/pipe_select_interrupter.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +pipe_select_interrupter::pipe_select_interrupter() +{ + int pipe_fds[2]; + if (pipe(pipe_fds) == 0) + { + read_descriptor_ = pipe_fds[0]; + ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); + write_descriptor_ = pipe_fds[1]; + ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK); + } + else + { + boost::system::error_code ec(errno, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "pipe_select_interrupter"); + } +} + +pipe_select_interrupter::~pipe_select_interrupter() +{ + if (read_descriptor_ != -1) + ::close(read_descriptor_); + if (write_descriptor_ != -1) + ::close(write_descriptor_); +} + +void pipe_select_interrupter::interrupt() +{ + char byte = 0; + int result = ::write(write_descriptor_, &byte, 1); + (void)result; +} + +bool pipe_select_interrupter::reset() +{ + for (;;) + { + char data[1024]; + int bytes_read = ::read(read_descriptor_, data, sizeof(data)); + if (bytes_read < 0 && errno == EINTR) + continue; + bool was_interrupted = (bytes_read > 0); + while (bytes_read == sizeof(data)) + bytes_read = ::read(read_descriptor_, data, sizeof(data)); + return was_interrupted; + } +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // !defined(BOOST_ASIO_HAS_EVENTFD) +#endif // !defined(__SYMBIAN32__) +#endif // !defined(__CYGWIN__) +#endif // !defined(BOOST_WINDOWS) + +#endif // BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/posix_event.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/posix_event.ipp new file mode 100644 index 0000000..7e89b6c --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/posix_event.ipp @@ -0,0 +1,48 @@ +// +// detail/impl/posix_event.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_POSIX_EVENT_IPP +#define BOOST_ASIO_DETAIL_IMPL_POSIX_EVENT_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) + +#include <boost/asio/detail/posix_event.hpp> +#include <boost/asio/detail/throw_error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +posix_event::posix_event() + : signalled_(false) +{ + int error = ::pthread_cond_init(&cond_, 0); + boost::system::error_code ec(error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "event"); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) + +#endif // BOOST_ASIO_DETAIL_IMPL_POSIX_EVENT_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/posix_mutex.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/posix_mutex.ipp new file mode 100644 index 0000000..a4f81bb --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/posix_mutex.ipp @@ -0,0 +1,48 @@ +// +// detail/impl/posix_mutex.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_POSIX_MUTEX_IPP +#define BOOST_ASIO_DETAIL_IMPL_POSIX_MUTEX_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) + +#include <boost/asio/detail/posix_mutex.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +posix_mutex::posix_mutex() +{ + int error = ::pthread_mutex_init(&mutex_, 0); + boost::system::error_code ec(error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "mutex"); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) + +#endif // BOOST_ASIO_DETAIL_IMPL_POSIX_MUTEX_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/posix_thread.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/posix_thread.ipp new file mode 100644 index 0000000..5dc41fa --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/posix_thread.ipp @@ -0,0 +1,76 @@ +// +// detail/impl/posix_thread.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_POSIX_THREAD_IPP +#define BOOST_ASIO_DETAIL_IMPL_POSIX_THREAD_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) + +#include <boost/asio/detail/posix_thread.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +posix_thread::~posix_thread() +{ + if (!joined_) + ::pthread_detach(thread_); +} + +void posix_thread::join() +{ + if (!joined_) + { + ::pthread_join(thread_, 0); + joined_ = true; + } +} + +void posix_thread::start_thread(func_base* arg) +{ + int error = ::pthread_create(&thread_, 0, + boost_asio_detail_posix_thread_function, arg); + if (error != 0) + { + delete arg; + boost::system::error_code ec(error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "thread"); + } +} + +void* boost_asio_detail_posix_thread_function(void* arg) +{ + posix_thread::auto_func_base_ptr func = { + static_cast<posix_thread::func_base*>(arg) }; + func.ptr->run(); + return 0; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) + +#endif // BOOST_ASIO_DETAIL_IMPL_POSIX_THREAD_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/posix_tss_ptr.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/posix_tss_ptr.ipp new file mode 100644 index 0000000..1c626e5 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/posix_tss_ptr.ipp @@ -0,0 +1,48 @@ +// +// detail/impl/posix_tss_ptr.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_POSIX_TSS_PTR_IPP +#define BOOST_ASIO_DETAIL_IMPL_POSIX_TSS_PTR_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) + +#include <boost/asio/detail/posix_tss_ptr.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +void posix_tss_ptr_create(pthread_key_t& key) +{ + int error = ::pthread_key_create(&key, 0); + boost::system::error_code ec(error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "tss"); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) + +#endif // BOOST_ASIO_DETAIL_IMPL_POSIX_TSS_PTR_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/reactive_descriptor_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/reactive_descriptor_service.ipp new file mode 100644 index 0000000..6f0dc5a --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/reactive_descriptor_service.ipp @@ -0,0 +1,138 @@ +// +// detail/impl/reactive_descriptor_service.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP +#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include <boost/asio/error.hpp> +#include <boost/asio/detail/reactive_descriptor_service.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +reactive_descriptor_service::reactive_descriptor_service( + boost::asio::io_service& io_service) + : reactor_(boost::asio::use_service<reactor>(io_service)) +{ + reactor_.init_task(); +} + +void reactive_descriptor_service::shutdown_service() +{ +} + +void reactive_descriptor_service::construct( + reactive_descriptor_service::implementation_type& impl) +{ + impl.descriptor_ = -1; + impl.state_ = 0; +} + +void reactive_descriptor_service::destroy( + reactive_descriptor_service::implementation_type& impl) +{ + if (is_open(impl)) + reactor_.close_descriptor(impl.descriptor_, impl.reactor_data_); + + boost::system::error_code ignored_ec; + descriptor_ops::close(impl.descriptor_, impl.state_, ignored_ec); +} + +boost::system::error_code reactive_descriptor_service::assign( + reactive_descriptor_service::implementation_type& impl, + const native_type& native_descriptor, boost::system::error_code& ec) +{ + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + if (int err = reactor_.register_descriptor( + native_descriptor, impl.reactor_data_)) + { + ec = boost::system::error_code(err, + boost::asio::error::get_system_category()); + return ec; + } + + impl.descriptor_ = native_descriptor; + impl.state_ = 0; + ec = boost::system::error_code(); + return ec; +} + +boost::system::error_code reactive_descriptor_service::close( + reactive_descriptor_service::implementation_type& impl, + boost::system::error_code& ec) +{ + if (is_open(impl)) + reactor_.close_descriptor(impl.descriptor_, impl.reactor_data_); + + if (descriptor_ops::close(impl.descriptor_, impl.state_, ec) == 0) + construct(impl); + + return ec; +} + +boost::system::error_code reactive_descriptor_service::cancel( + reactive_descriptor_service::implementation_type& impl, + boost::system::error_code& ec) +{ + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + reactor_.cancel_ops(impl.descriptor_, impl.reactor_data_); + ec = boost::system::error_code(); + return ec; +} + +void reactive_descriptor_service::start_op( + reactive_descriptor_service::implementation_type& impl, + int op_type, reactor_op* op, bool non_blocking, bool noop) +{ + if (!noop) + { + if ((impl.state_ & descriptor_ops::non_blocking) || + descriptor_ops::set_internal_non_blocking( + impl.descriptor_, impl.state_, op->ec_)) + { + reactor_.start_op(op_type, impl.descriptor_, + impl.reactor_data_, op, non_blocking); + return; + } + } + + reactor_.post_immediate_completion(op); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/reactive_serial_port_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/reactive_serial_port_service.ipp new file mode 100644 index 0000000..b467209 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/reactive_serial_port_service.ipp @@ -0,0 +1,153 @@ +// +// detail/impl/reactive_serial_port_service.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SERIAL_PORT_SERVICE_IPP +#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SERIAL_PORT_SERVICE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_SERIAL_PORT) +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +#include <cstring> +#include <boost/asio/detail/reactive_serial_port_service.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +reactive_serial_port_service::reactive_serial_port_service( + boost::asio::io_service& io_service) + : descriptor_service_(io_service) +{ +} + +void reactive_serial_port_service::shutdown_service() +{ + descriptor_service_.shutdown_service(); +} + +boost::system::error_code reactive_serial_port_service::open( + reactive_serial_port_service::implementation_type& impl, + const std::string& device, boost::system::error_code& ec) +{ + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + descriptor_ops::state_type state = 0; + int fd = descriptor_ops::open(device.c_str(), + O_RDWR | O_NONBLOCK | O_NOCTTY, ec); + if (fd < 0) + return ec; + + int s = descriptor_ops::fcntl(fd, F_GETFL, ec); + if (s >= 0) + s = descriptor_ops::fcntl(fd, F_SETFL, s | O_NONBLOCK, ec); + if (s < 0) + { + boost::system::error_code ignored_ec; + descriptor_ops::close(fd, state, ignored_ec); + return ec; + } + + // Set up default serial port options. + termios ios; + errno = 0; + s = descriptor_ops::error_wrapper(::tcgetattr(fd, &ios), ec); + if (s >= 0) + { +#if defined(_BSD_SOURCE) + ::cfmakeraw(&ios); +#else + ios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK + | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + ios.c_oflag &= ~OPOST; + ios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + ios.c_cflag &= ~(CSIZE | PARENB); + ios.c_cflag |= CS8; +#endif + ios.c_iflag |= IGNPAR; + ios.c_cflag |= CREAD | CLOCAL; + errno = 0; + s = descriptor_ops::error_wrapper(::tcsetattr(fd, TCSANOW, &ios), ec); + } + if (s < 0) + { + boost::system::error_code ignored_ec; + descriptor_ops::close(fd, state, ignored_ec); + return ec; + } + + // We're done. Take ownership of the serial port descriptor. + if (descriptor_service_.assign(impl, fd, ec)) + { + boost::system::error_code ignored_ec; + descriptor_ops::close(fd, state, ignored_ec); + } + + return ec; +} + +boost::system::error_code reactive_serial_port_service::do_set_option( + reactive_serial_port_service::implementation_type& impl, + reactive_serial_port_service::store_function_type store, + const void* option, boost::system::error_code& ec) +{ + termios ios; + errno = 0; + descriptor_ops::error_wrapper(::tcgetattr( + descriptor_service_.native(impl), &ios), ec); + if (ec) + return ec; + + if (store(option, ios, ec)) + return ec; + + errno = 0; + descriptor_ops::error_wrapper(::tcsetattr( + descriptor_service_.native(impl), TCSANOW, &ios), ec); + return ec; +} + +boost::system::error_code reactive_serial_port_service::do_get_option( + const reactive_serial_port_service::implementation_type& impl, + reactive_serial_port_service::load_function_type load, + void* option, boost::system::error_code& ec) const +{ + termios ios; + errno = 0; + descriptor_ops::error_wrapper(::tcgetattr( + descriptor_service_.native(impl), &ios), ec); + if (ec) + return ec; + + return load(option, ios, ec); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT) + +#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SERIAL_PORT_SERVICE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/reactive_socket_service_base.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/reactive_socket_service_base.ipp new file mode 100644 index 0000000..cecbe73 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/reactive_socket_service_base.ipp @@ -0,0 +1,214 @@ +// +// detail/reactive_socket_service_base.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_IPP +#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if !defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/asio/detail/reactive_socket_service_base.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +reactive_socket_service_base::reactive_socket_service_base( + boost::asio::io_service& io_service) + : reactor_(use_service<reactor>(io_service)) +{ + reactor_.init_task(); +} + +void reactive_socket_service_base::shutdown_service() +{ +} + +void reactive_socket_service_base::construct( + reactive_socket_service_base::base_implementation_type& impl) +{ + impl.socket_ = invalid_socket; + impl.state_ = 0; +} + +void reactive_socket_service_base::destroy( + reactive_socket_service_base::base_implementation_type& impl) +{ + if (impl.socket_ != invalid_socket) + { + reactor_.close_descriptor(impl.socket_, impl.reactor_data_); + + boost::system::error_code ignored_ec; + socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); + } +} + +boost::system::error_code reactive_socket_service_base::close( + reactive_socket_service_base::base_implementation_type& impl, + boost::system::error_code& ec) +{ + if (is_open(impl)) + reactor_.close_descriptor(impl.socket_, impl.reactor_data_); + + if (socket_ops::close(impl.socket_, impl.state_, true, ec) == 0) + construct(impl); + + return ec; +} + +boost::system::error_code reactive_socket_service_base::cancel( + reactive_socket_service_base::base_implementation_type& impl, + boost::system::error_code& ec) +{ + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + reactor_.cancel_ops(impl.socket_, impl.reactor_data_); + ec = boost::system::error_code(); + return ec; +} + +boost::system::error_code reactive_socket_service_base::do_open( + reactive_socket_service_base::base_implementation_type& impl, + int af, int type, int protocol, boost::system::error_code& ec) +{ + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + socket_holder sock(socket_ops::socket(af, type, protocol, ec)); + if (sock.get() == invalid_socket) + return ec; + + if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) + { + ec = boost::system::error_code(err, + boost::asio::error::get_system_category()); + return ec; + } + + impl.socket_ = sock.release(); + switch (type) + { + case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; + case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; + default: impl.state_ = 0; break; + } + ec = boost::system::error_code(); + return ec; +} + +boost::system::error_code reactive_socket_service_base::do_assign( + reactive_socket_service_base::base_implementation_type& impl, int type, + const reactive_socket_service_base::native_type& native_socket, + boost::system::error_code& ec) +{ + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + if (int err = reactor_.register_descriptor( + native_socket, impl.reactor_data_)) + { + ec = boost::system::error_code(err, + boost::asio::error::get_system_category()); + return ec; + } + + impl.socket_ = native_socket; + switch (type) + { + case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; + case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; + default: impl.state_ = 0; break; + } + ec = boost::system::error_code(); + return ec; +} + +void reactive_socket_service_base::start_op( + reactive_socket_service_base::base_implementation_type& impl, + int op_type, reactor_op* op, bool non_blocking, bool noop) +{ + if (!noop) + { + if ((impl.state_ & socket_ops::non_blocking) + || socket_ops::set_internal_non_blocking( + impl.socket_, impl.state_, op->ec_)) + { + reactor_.start_op(op_type, impl.socket_, + impl.reactor_data_, op, non_blocking); + return; + } + } + + reactor_.post_immediate_completion(op); +} + +void reactive_socket_service_base::start_accept_op( + reactive_socket_service_base::base_implementation_type& impl, + reactor_op* op, bool peer_is_open) +{ + if (!peer_is_open) + start_op(impl, reactor::read_op, op, true, false); + else + { + op->ec_ = boost::asio::error::already_open; + reactor_.post_immediate_completion(op); + } +} + +void reactive_socket_service_base::start_connect_op( + reactive_socket_service_base::base_implementation_type& impl, + reactor_op* op, const socket_addr_type* addr, size_t addrlen) +{ + if ((impl.state_ & socket_ops::non_blocking) + || socket_ops::set_internal_non_blocking( + impl.socket_, impl.state_, op->ec_)) + { + if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) + { + if (op->ec_ == boost::asio::error::in_progress + || op->ec_ == boost::asio::error::would_block) + { + op->ec_ = boost::system::error_code(); + reactor_.start_op(reactor::connect_op, + impl.socket_, impl.reactor_data_, op, false); + return; + } + } + } + + reactor_.post_immediate_completion(op); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // !defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/resolver_service_base.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/resolver_service_base.ipp new file mode 100644 index 0000000..d1af0be --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/resolver_service_base.ipp @@ -0,0 +1,108 @@ +// +// detail/impl/resolver_service_base.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP +#define BOOST_ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/asio/detail/resolver_service_base.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +class resolver_service_base::work_io_service_runner +{ +public: + work_io_service_runner(boost::asio::io_service& io_service) + : io_service_(io_service) {} + void operator()() { io_service_.run(); } +private: + boost::asio::io_service& io_service_; +}; + +resolver_service_base::resolver_service_base( + boost::asio::io_service& io_service) + : io_service_impl_(boost::asio::use_service<io_service_impl>(io_service)), + work_io_service_(new boost::asio::io_service), + work_io_service_impl_(boost::asio::use_service< + io_service_impl>(*work_io_service_)), + work_(new boost::asio::io_service::work(*work_io_service_)), + work_thread_(0) +{ +} + +resolver_service_base::~resolver_service_base() +{ + shutdown_service(); +} + +void resolver_service_base::shutdown_service() +{ + work_.reset(); + if (work_io_service_) + { + work_io_service_->stop(); + if (work_thread_) + { + work_thread_->join(); + work_thread_.reset(); + } + work_io_service_.reset(); + } +} + +void resolver_service_base::construct( + resolver_service_base::implementation_type& impl) +{ + impl.reset(static_cast<void*>(0), socket_ops::noop_deleter()); +} + +void resolver_service_base::destroy( + resolver_service_base::implementation_type&) +{ +} + +void resolver_service_base::cancel( + resolver_service_base::implementation_type& impl) +{ + impl.reset(static_cast<void*>(0), socket_ops::noop_deleter()); +} + +void resolver_service_base::start_resolve_op(operation* op) +{ + start_work_thread(); + io_service_impl_.work_started(); + work_io_service_impl_.post_immediate_completion(op); +} + +void resolver_service_base::start_work_thread() +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (!work_thread_) + { + work_thread_.reset(new boost::asio::detail::thread( + work_io_service_runner(*work_io_service_))); + } +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.hpp new file mode 100644 index 0000000..55e064e --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.hpp @@ -0,0 +1,86 @@ +// +// detail/impl/select_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_SELECT_REACTOR_HPP +#define BOOST_ASIO_DETAIL_IMPL_SELECT_REACTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) \ + || (!defined(BOOST_ASIO_HAS_DEV_POLL) \ + && !defined(BOOST_ASIO_HAS_EPOLL) \ + && !defined(BOOST_ASIO_HAS_KQUEUE)) + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Time_Traits> +void select_reactor::add_timer_queue(timer_queue<Time_Traits>& queue) +{ + do_add_timer_queue(queue); +} + +// Remove a timer queue from the reactor. +template <typename Time_Traits> +void select_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue) +{ + do_remove_timer_queue(queue); +} + +template <typename Time_Traits> +void select_reactor::schedule_timer(timer_queue<Time_Traits>& queue, + const typename Time_Traits::time_type& time, + typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + { + io_service_.post_immediate_completion(op); + return; + } + + bool earliest = queue.enqueue_timer(time, timer, op); + io_service_.work_started(); + if (earliest) + interrupter_.interrupt(); +} + +template <typename Time_Traits> +std::size_t select_reactor::cancel_timer(timer_queue<Time_Traits>& queue, + typename timer_queue<Time_Traits>::per_timer_data& timer) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + op_queue<operation> ops; + std::size_t n = queue.cancel_timer(timer, ops); + lock.unlock(); + io_service_.post_deferred_completions(ops); + return n; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + // || (!defined(BOOST_ASIO_HAS_DEV_POLL) + // && !defined(BOOST_ASIO_HAS_EPOLL) + // && !defined(BOOST_ASIO_HAS_KQUEUE)) + +#endif // BOOST_ASIO_DETAIL_IMPL_SELECT_REACTOR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.ipp new file mode 100644 index 0000000..af6e6c1 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.ipp @@ -0,0 +1,275 @@ +// +// detail/impl/select_reactor.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_SELECT_REACTOR_IPP +#define BOOST_ASIO_DETAIL_IMPL_SELECT_REACTOR_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) \ + || (!defined(BOOST_ASIO_HAS_DEV_POLL) \ + && !defined(BOOST_ASIO_HAS_EPOLL) \ + && !defined(BOOST_ASIO_HAS_KQUEUE)) + +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/fd_set_adapter.hpp> +#include <boost/asio/detail/select_reactor.hpp> +#include <boost/asio/detail/signal_blocker.hpp> +#include <boost/asio/detail/socket_ops.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +select_reactor::select_reactor(boost::asio::io_service& io_service) + : boost::asio::detail::service_base<select_reactor>(io_service), + io_service_(use_service<io_service_impl>(io_service)), + mutex_(), + interrupter_(), +#if defined(BOOST_ASIO_HAS_IOCP) + stop_thread_(false), + thread_(0), +#endif // defined(BOOST_ASIO_HAS_IOCP) + shutdown_(false) +{ +#if defined(BOOST_ASIO_HAS_IOCP) + boost::asio::detail::signal_blocker sb; + thread_ = new boost::asio::detail::thread( + bind_handler(&select_reactor::call_run_thread, this)); +#endif // defined(BOOST_ASIO_HAS_IOCP) +} + +select_reactor::~select_reactor() +{ + shutdown_service(); +} + +void select_reactor::shutdown_service() +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + shutdown_ = true; +#if defined(BOOST_ASIO_HAS_IOCP) + stop_thread_ = true; +#endif // defined(BOOST_ASIO_HAS_IOCP) + lock.unlock(); + +#if defined(BOOST_ASIO_HAS_IOCP) + if (thread_) + { + interrupter_.interrupt(); + thread_->join(); + delete thread_; + thread_ = 0; + } +#endif // defined(BOOST_ASIO_HAS_IOCP) + + op_queue<operation> ops; + + for (int i = 0; i < max_ops; ++i) + op_queue_[i].get_all_operations(ops); + + timer_queues_.get_all_timers(ops); +} + +void select_reactor::init_task() +{ + io_service_.init_task(); +} + +int select_reactor::register_descriptor(socket_type, + select_reactor::per_descriptor_data&) +{ + return 0; +} + +void select_reactor::start_op(int op_type, socket_type descriptor, + select_reactor::per_descriptor_data&, reactor_op* op, bool) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + { + post_immediate_completion(op); + return; + } + + bool first = op_queue_[op_type].enqueue_operation(descriptor, op); + io_service_.work_started(); + if (first) + interrupter_.interrupt(); +} + +void select_reactor::cancel_ops(socket_type descriptor, + select_reactor::per_descriptor_data&) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted); +} + +void select_reactor::close_descriptor(socket_type descriptor, + select_reactor::per_descriptor_data&) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted); +} + +void select_reactor::run(bool block, op_queue<operation>& ops) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + +#if defined(BOOST_ASIO_HAS_IOCP) + // Check if the thread is supposed to stop. + if (stop_thread_) + return; +#endif // defined(BOOST_ASIO_HAS_IOCP) + + // Set up the descriptor sets. + fd_set_adapter fds[max_select_ops]; + fds[read_op].set(interrupter_.read_descriptor()); + socket_type max_fd = 0; + bool have_work_to_do = !timer_queues_.all_empty(); + for (int i = 0; i < max_select_ops; ++i) + { + have_work_to_do = have_work_to_do || !op_queue_[i].empty(); + op_queue_[i].get_descriptors(fds[i], ops); + if (fds[i].max_descriptor() > max_fd) + max_fd = fds[i].max_descriptor(); + } + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Connection operations on Windows use both except and write fd_sets. + have_work_to_do = have_work_to_do || !op_queue_[connect_op].empty(); + op_queue_[connect_op].get_descriptors(fds[write_op], ops); + if (fds[write_op].max_descriptor() > max_fd) + max_fd = fds[write_op].max_descriptor(); + op_queue_[connect_op].get_descriptors(fds[except_op], ops); + if (fds[except_op].max_descriptor() > max_fd) + max_fd = fds[except_op].max_descriptor(); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + + // We can return immediately if there's no work to do and the reactor is + // not supposed to block. + if (!block && !have_work_to_do) + return; + + // Determine how long to block while waiting for events. + timeval tv_buf = { 0, 0 }; + timeval* tv = block ? get_timeout(tv_buf) : &tv_buf; + + lock.unlock(); + + // Block on the select call until descriptors become ready. + boost::system::error_code ec; + int retval = socket_ops::select(static_cast<int>(max_fd + 1), + fds[read_op], fds[write_op], fds[except_op], tv, ec); + + // Reset the interrupter. + if (retval > 0 && fds[read_op].is_set(interrupter_.read_descriptor())) + interrupter_.reset(); + + lock.lock(); + + // Dispatch all ready operations. + if (retval > 0) + { +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Connection operations on Windows use both except and write fd_sets. + op_queue_[connect_op].perform_operations_for_descriptors( + fds[except_op], ops); + op_queue_[connect_op].perform_operations_for_descriptors( + fds[write_op], ops); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + + // Exception operations must be processed first to ensure that any + // out-of-band data is read before normal data. + for (int i = max_select_ops - 1; i >= 0; --i) + op_queue_[i].perform_operations_for_descriptors(fds[i], ops); + } + timer_queues_.get_ready_timers(ops); +} + +void select_reactor::interrupt() +{ + interrupter_.interrupt(); +} + +#if defined(BOOST_ASIO_HAS_IOCP) +void select_reactor::run_thread() +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + while (!stop_thread_) + { + lock.unlock(); + op_queue<operation> ops; + run(true, ops); + io_service_.post_deferred_completions(ops); + lock.lock(); + } +} + +void select_reactor::call_run_thread(select_reactor* reactor) +{ + reactor->run_thread(); +} +#endif // defined(BOOST_ASIO_HAS_IOCP) + +void select_reactor::do_add_timer_queue(timer_queue_base& queue) +{ + mutex::scoped_lock lock(mutex_); + timer_queues_.insert(&queue); +} + +void select_reactor::do_remove_timer_queue(timer_queue_base& queue) +{ + mutex::scoped_lock lock(mutex_); + timer_queues_.erase(&queue); +} + +timeval* select_reactor::get_timeout(timeval& tv) +{ + // By default we will wait no longer than 5 minutes. This will ensure that + // any changes to the system clock are detected after no longer than this. + long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000); + tv.tv_sec = usec / 1000000; + tv.tv_usec = usec % 1000000; + return &tv; +} + +void select_reactor::cancel_ops_unlocked(socket_type descriptor, + const boost::system::error_code& ec) +{ + bool need_interrupt = false; + op_queue<operation> ops; + for (int i = 0; i < max_ops; ++i) + need_interrupt = op_queue_[i].cancel_operations( + descriptor, ops, ec) || need_interrupt; + io_service_.post_deferred_completions(ops); + if (need_interrupt) + interrupter_.interrupt(); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + // || (!defined(BOOST_ASIO_HAS_DEV_POLL) + // && !defined(BOOST_ASIO_HAS_EPOLL) + // && !defined(BOOST_ASIO_HAS_KQUEUE)) + +#endif // BOOST_ASIO_DETAIL_IMPL_SELECT_REACTOR_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.hpp new file mode 100644 index 0000000..59eb3f7 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.hpp @@ -0,0 +1,72 @@ +// +// detail/impl/service_registry.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_HPP +#define BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Service> +Service& service_registry::use_service() +{ + boost::asio::io_service::service::key key; + init_key(key, Service::id); + factory_type factory = &service_registry::create<Service>; + return *static_cast<Service*>(do_use_service(key, factory)); +} + +template <typename Service> +void service_registry::add_service(Service* new_service) +{ + boost::asio::io_service::service::key key; + init_key(key, Service::id); + return do_add_service(key, new_service); +} + +template <typename Service> +bool service_registry::has_service() const +{ + boost::asio::io_service::service::key key; + init_key(key, Service::id); + return do_has_service(key); +} + +#if !defined(BOOST_ASIO_NO_TYPEID) +template <typename Service> +void service_registry::init_key(boost::asio::io_service::service::key& key, + const boost::asio::detail::service_id<Service>& /*id*/) +{ + key.type_info_ = &typeid(typeid_wrapper<Service>); + key.id_ = 0; +} +#endif // !defined(BOOST_ASIO_NO_TYPEID) + +template <typename Service> +boost::asio::io_service::service* service_registry::create( + boost::asio::io_service& owner) +{ + return new Service(owner); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.ipp new file mode 100644 index 0000000..9f7381e --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.ipp @@ -0,0 +1,166 @@ +// +// detail/impl/service_registry.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_IPP +#define BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/throw_exception.hpp> +#include <boost/asio/detail/service_registry.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +service_registry::service_registry(boost::asio::io_service& o) + : owner_(o), + first_service_(0) +{ +} + +service_registry::~service_registry() +{ + // Shutdown all services. This must be done in a separate loop before the + // services are destroyed since the destructors of user-defined handler + // objects may try to access other service objects. + boost::asio::io_service::service* service = first_service_; + while (service) + { + service->shutdown_service(); + service = service->next_; + } + + // Destroy all services. + while (first_service_) + { + boost::asio::io_service::service* next_service = first_service_->next_; + destroy(first_service_); + first_service_ = next_service; + } +} + +void service_registry::init_key(boost::asio::io_service::service::key& key, + const boost::asio::io_service::id& id) +{ + key.type_info_ = 0; + key.id_ = &id; +} + +bool service_registry::keys_match( + const boost::asio::io_service::service::key& key1, + const boost::asio::io_service::service::key& key2) +{ + if (key1.id_ && key2.id_) + if (key1.id_ == key2.id_) + return true; + if (key1.type_info_ && key2.type_info_) + if (*key1.type_info_ == *key2.type_info_) + return true; + return false; +} + +void service_registry::destroy(boost::asio::io_service::service* service) +{ + delete service; +} + +boost::asio::io_service::service* service_registry::do_use_service( + const boost::asio::io_service::service::key& key, + factory_type factory) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // First see if there is an existing service object with the given key. + boost::asio::io_service::service* service = first_service_; + while (service) + { + if (keys_match(service->key_, key)) + return service; + service = service->next_; + } + + // Create a new service object. The service registry's mutex is not locked + // at this time to allow for nested calls into this function from the new + // service's constructor. + lock.unlock(); + auto_service_ptr new_service = { factory(owner_) }; + new_service.ptr_->key_ = key; + lock.lock(); + + // Check that nobody else created another service object of the same type + // while the lock was released. + service = first_service_; + while (service) + { + if (keys_match(service->key_, key)) + return service; + service = service->next_; + } + + // Service was successfully initialised, pass ownership to registry. + new_service.ptr_->next_ = first_service_; + first_service_ = new_service.ptr_; + new_service.ptr_ = 0; + return first_service_; +} + +void service_registry::do_add_service( + const boost::asio::io_service::service::key& key, + boost::asio::io_service::service* new_service) +{ + if (&owner_ != &new_service->io_service()) + boost::throw_exception(invalid_service_owner()); + + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + // Check if there is an existing service object with the given key. + boost::asio::io_service::service* service = first_service_; + while (service) + { + if (keys_match(service->key_, key)) + boost::throw_exception(service_already_exists()); + service = service->next_; + } + + // Take ownership of the service object. + new_service->key_ = key; + new_service->next_ = first_service_; + first_service_ = new_service; +} + +bool service_registry::do_has_service( + const boost::asio::io_service::service::key& key) const +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + boost::asio::io_service::service* service = first_service_; + while (service) + { + if (keys_match(service->key_, key)) + return true; + service = service->next_; + } + + return false; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/socket_ops.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/socket_ops.ipp new file mode 100644 index 0000000..5ac052a --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/socket_ops.ipp @@ -0,0 +1,2865 @@ +// +// detail/impl/socket_ops.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_IPP +#define BOOST_ASIO_DETAIL_SOCKET_OPS_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/assert.hpp> +#include <boost/detail/workaround.hpp> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <cerrno> +#include <new> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { +namespace socket_ops { + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +struct msghdr { int msg_namelen; }; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#if defined(__hpux) +// HP-UX doesn't declare these functions extern "C", so they are declared again +// here to avoid linker errors about undefined symbols. +extern "C" char* if_indextoname(unsigned int, char*); +extern "C" unsigned int if_nametoindex(const char*); +#endif // defined(__hpux) + +inline void clear_last_error() +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + WSASetLastError(0); +#else + errno = 0; +#endif +} + +template <typename ReturnType> +inline ReturnType error_wrapper(ReturnType return_value, + boost::system::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + ec = boost::system::error_code(WSAGetLastError(), + boost::asio::error::get_system_category()); +#else + ec = boost::system::error_code(errno, + boost::asio::error::get_system_category()); +#endif + return return_value; +} + +template <typename SockLenType> +inline socket_type call_accept(SockLenType msghdr::*, + socket_type s, socket_addr_type* addr, std::size_t* addrlen) +{ + SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0; + socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0); + if (addrlen) + *addrlen = (std::size_t)tmp_addrlen; + return result; +} + +socket_type accept(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return invalid_socket; + } + + clear_last_error(); + + socket_type new_s = error_wrapper(call_accept( + &msghdr::msg_namelen, s, addr, addrlen), ec); + if (new_s == invalid_socket) + return new_s; + +#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__) + int optval = 1; + int result = error_wrapper(::setsockopt(new_s, + SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec); + if (result != 0) + { + ::close(new_s); + return invalid_socket; + } +#endif + + ec = boost::system::error_code(); + return new_s; +} + +socket_type sync_accept(socket_type s, state_type state, + socket_addr_type* addr, std::size_t* addrlen, boost::system::error_code& ec) +{ + // Accept a socket. + for (;;) + { + // Try to complete the operation without blocking. + socket_type new_socket = socket_ops::accept(s, addr, addrlen, ec); + + // Check if operation succeeded. + if (new_socket != invalid_socket) + return new_socket; + + // Operation failed. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + { + if (state & user_set_non_blocking) + return invalid_socket; + // Fall through to retry operation. + } + else if (ec == boost::asio::error::connection_aborted) + { + if (state & enable_connection_aborted) + return invalid_socket; + // Fall through to retry operation. + } +#if defined(EPROTO) + else if (ec.value() == EPROTO) + { + if (state & enable_connection_aborted) + return invalid_socket; + // Fall through to retry operation. + } +#endif // defined(EPROTO) + else + return invalid_socket; + + // Wait for socket to become ready. + if (socket_ops::poll_read(s, ec) < 0) + return invalid_socket; + } +} + +#if defined(BOOST_ASIO_HAS_IOCP) + +void complete_iocp_accept(socket_type s, + void* output_buffer, DWORD address_length, + socket_addr_type* addr, std::size_t* addrlen, + socket_type new_socket, boost::system::error_code& ec) +{ + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_NETNAME_DELETED) + ec = boost::asio::error::connection_aborted; + + if (!ec) + { + // Get the address of the peer. + if (addr && addrlen) + { + LPSOCKADDR local_addr = 0; + int local_addr_length = 0; + LPSOCKADDR remote_addr = 0; + int remote_addr_length = 0; + GetAcceptExSockaddrs(output_buffer, 0, address_length, + address_length, &local_addr, &local_addr_length, + &remote_addr, &remote_addr_length); + if (static_cast<std::size_t>(remote_addr_length) > *addrlen) + { + ec = boost::asio::error::invalid_argument; + } + else + { + using namespace std; // For memcpy. + memcpy(addr, remote_addr, remote_addr_length); + *addrlen = static_cast<std::size_t>(remote_addr_length); + } + } + + // Need to set the SO_UPDATE_ACCEPT_CONTEXT option so that getsockname + // and getpeername will work on the accepted socket. + SOCKET update_ctx_param = s; + socket_ops::state_type state = 0; + socket_ops::setsockopt(new_socket, state, + SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, + &update_ctx_param, sizeof(SOCKET), ec); + } +} + +#else // defined(BOOST_ASIO_HAS_IOCP) + +bool non_blocking_accept(socket_type s, + state_type state, socket_addr_type* addr, std::size_t* addrlen, + boost::system::error_code& ec, socket_type& new_socket) +{ + for (;;) + { + // Accept the waiting connection. + new_socket = socket_ops::accept(s, addr, addrlen, ec); + + // Check if operation succeeded. + if (new_socket != invalid_socket) + return true; + + // Retry operation if interrupted by signal. + if (ec == boost::asio::error::interrupted) + continue; + + // Operation failed. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + { + if (state & user_set_non_blocking) + return true; + // Fall through to retry operation. + } + else if (ec == boost::asio::error::connection_aborted) + { + if (state & enable_connection_aborted) + return true; + // Fall through to retry operation. + } +#if defined(EPROTO) + else if (ec.value() == EPROTO) + { + if (state & enable_connection_aborted) + return true; + // Fall through to retry operation. + } +#endif // defined(EPROTO) + else + return true; + + return false; + } +} + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +template <typename SockLenType> +inline int call_bind(SockLenType msghdr::*, + socket_type s, const socket_addr_type* addr, std::size_t addrlen) +{ + return ::bind(s, addr, (SockLenType)addrlen); +} + +int bind(socket_type s, const socket_addr_type* addr, + std::size_t addrlen, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return socket_error_retval; + } + + clear_last_error(); + int result = error_wrapper(call_bind( + &msghdr::msg_namelen, s, addr, addrlen), ec); + if (result == 0) + ec = boost::system::error_code(); + return result; +} + +int close(socket_type s, state_type& state, + bool destruction, boost::system::error_code& ec) +{ + int result = 0; + if (s != invalid_socket) + { +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if ((state & non_blocking) && (state & user_set_linger)) + { + ioctl_arg_type arg = 0; + ::ioctlsocket(s, FIONBIO, &arg); + state &= ~non_blocking; + } +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if (state & non_blocking) + { +#if defined(__SYMBIAN32__) + int flags = ::fcntl(s, F_GETFL, 0); + if (flags >= 0) + ::fcntl(s, F_SETFL, flags & ~O_NONBLOCK); +#else // defined(__SYMBIAN32__) + ioctl_arg_type arg = 0; + ::ioctl(s, FIONBIO, &arg); +#endif // defined(__SYMBIAN32__) + state &= ~non_blocking; + } +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + + if (destruction && (state & user_set_linger)) + { + ::linger opt; + opt.l_onoff = 0; + opt.l_linger = 0; + boost::system::error_code ignored_ec; + socket_ops::setsockopt(s, state, SOL_SOCKET, + SO_LINGER, &opt, sizeof(opt), ignored_ec); + } + + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + result = error_wrapper(::closesocket(s), ec); +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + result = error_wrapper(::close(s), ec); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + } + + if (result == 0) + ec = boost::system::error_code(); + return result; +} + +bool set_internal_non_blocking(socket_type s, + state_type& state, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return false; + } + + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + ioctl_arg_type arg = 1; + int result = error_wrapper(::ioctlsocket(s, FIONBIO, &arg), ec); +#elif defined(__SYMBIAN32__) + int result = error_wrapper(::fcntl(s, F_GETFL, 0), ec); + if (result >= 0) + { + clear_last_error(); + result = error_wrapper(::fcntl(s, F_SETFL, result | O_NONBLOCK), ec); + } +#else + ioctl_arg_type arg = 1; + int result = error_wrapper(::ioctl(s, FIONBIO, &arg), ec); +#endif + + if (result >= 0) + { + ec = boost::system::error_code(); + state |= internal_non_blocking; + return true; + } + + return false; +} + +int shutdown(socket_type s, int what, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return socket_error_retval; + } + + clear_last_error(); + int result = error_wrapper(::shutdown(s, what), ec); + if (result == 0) + ec = boost::system::error_code(); + return result; +} + +template <typename SockLenType> +inline int call_connect(SockLenType msghdr::*, + socket_type s, const socket_addr_type* addr, std::size_t addrlen) +{ + return ::connect(s, addr, (SockLenType)addrlen); +} + +int connect(socket_type s, const socket_addr_type* addr, + std::size_t addrlen, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return socket_error_retval; + } + + clear_last_error(); + int result = error_wrapper(call_connect( + &msghdr::msg_namelen, s, addr, addrlen), ec); + if (result == 0) + ec = boost::system::error_code(); + return result; +} + +void sync_connect(socket_type s, const socket_addr_type* addr, + std::size_t addrlen, boost::system::error_code& ec) +{ + // Perform the connect operation. + socket_ops::connect(s, addr, addrlen, ec); + if (ec != boost::asio::error::in_progress + && ec != boost::asio::error::would_block) + { + // The connect operation finished immediately. + return; + } + + // Wait for socket to become ready. + if (socket_ops::poll_connect(s, ec) < 0) + return; + + // Get the error code from the connect operation. + int connect_error = 0; + size_t connect_error_len = sizeof(connect_error); + if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR, + &connect_error, &connect_error_len, ec) == socket_error_retval) + return; + + // Return the result of the connect operation. + ec = boost::system::error_code(connect_error, + boost::asio::error::get_system_category()); +} + +bool non_blocking_connect(socket_type s, boost::system::error_code& ec) +{ + // Get the error code from the connect operation. + int connect_error = 0; + size_t connect_error_len = sizeof(connect_error); + if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR, + &connect_error, &connect_error_len, ec) == 0) + { + if (connect_error) + { + ec = boost::system::error_code(connect_error, + boost::asio::error::get_system_category()); + } + else + ec = boost::system::error_code(); + } + + return true; +} + +int socketpair(int af, int type, int protocol, + socket_type sv[2], boost::system::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + (void)(af); + (void)(type); + (void)(protocol); + (void)(sv); + ec = boost::asio::error::operation_not_supported; + return socket_error_retval; +#else + clear_last_error(); + int result = error_wrapper(::socketpair(af, type, protocol, sv), ec); + if (result == 0) + ec = boost::system::error_code(); + return result; +#endif +} + +bool sockatmark(socket_type s, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return false; + } + +#if defined(SIOCATMARK) + ioctl_arg_type value = 0; +# if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::ioctlsocket(s, SIOCATMARK, &value), ec); +# else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::ioctl(s, SIOCATMARK, &value), ec); +# endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if (result == 0) + ec = boost::system::error_code(); +# if defined(ENOTTY) + if (ec.value() == ENOTTY) + ec = boost::asio::error::not_socket; +# endif // defined(ENOTTY) +#else // defined(SIOCATMARK) + int value = error_wrapper(::sockatmark(s), ec); + if (value != -1) + ec = boost::system::error_code(); +#endif // defined(SIOCATMARK) + + return ec ? false : value != 0; +} + +size_t available(socket_type s, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + ioctl_arg_type value = 0; +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::ioctlsocket(s, FIONREAD, &value), ec); +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::ioctl(s, FIONREAD, &value), ec); +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if (result == 0) + ec = boost::system::error_code(); +#if defined(ENOTTY) + if (ec.value() == ENOTTY) + ec = boost::asio::error::not_socket; +#endif // defined(ENOTTY) + + return ec ? static_cast<size_t>(0) : static_cast<size_t>(value); +} + +int listen(socket_type s, int backlog, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return socket_error_retval; + } + + clear_last_error(); + int result = error_wrapper(::listen(s, backlog), ec); + if (result == 0) + ec = boost::system::error_code(); + return result; +} + +inline void init_buf_iov_base(void*& base, void* addr) +{ + base = addr; +} + +template <typename T> +inline void init_buf_iov_base(T& base, void* addr) +{ + base = static_cast<T>(addr); +} + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef WSABUF buf; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +typedef iovec buf; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +void init_buf(buf& b, void* data, size_t size) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + b.buf = static_cast<char*>(data); + b.len = static_cast<u_long>(size); +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + init_buf_iov_base(b.iov_base, data); + b.iov_len = size; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +void init_buf(buf& b, const void* data, size_t size) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + b.buf = static_cast<char*>(const_cast<void*>(data)); + b.len = static_cast<u_long>(size); +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + init_buf_iov_base(b.iov_base, const_cast<void*>(data)); + b.iov_len = size; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr) +{ + name = addr; +} + +inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr) +{ + name = const_cast<socket_addr_type*>(addr); +} + +template <typename T> +inline void init_msghdr_msg_name(T& name, socket_addr_type* addr) +{ + name = reinterpret_cast<T>(addr); +} + +template <typename T> +inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr) +{ + name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr)); +} + +int recv(socket_type s, buf* bufs, size_t count, int flags, + boost::system::error_code& ec) +{ + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Receive some data. + DWORD recv_buf_count = static_cast<DWORD>(count); + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int result = error_wrapper(::WSARecv(s, bufs, + recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec); + if (ec.value() == ERROR_NETNAME_DELETED) + ec = boost::asio::error::connection_reset; + else if (ec.value() == ERROR_PORT_UNREACHABLE) + ec = boost::asio::error::connection_refused; + if (result != 0) + return socket_error_retval; + ec = boost::system::error_code(); + return bytes_transferred; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + msg.msg_iov = bufs; + msg.msg_iovlen = count; + int result = error_wrapper(::recvmsg(s, &msg, flags), ec); + if (result >= 0) + ec = boost::system::error_code(); + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +size_t sync_recv(socket_type s, state_type state, buf* bufs, + size_t count, int flags, bool all_empty, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // A request to read 0 bytes on a stream is a no-op. + if (all_empty && (state & stream_oriented)) + { + ec = boost::system::error_code(); + return 0; + } + + // Read some data. + for (;;) + { + // Try to complete the operation without blocking. + int bytes = socket_ops::recv(s, bufs, count, flags, ec); + + // Check if operation succeeded. + if (bytes > 0) + return bytes; + + // Check for EOF. + if ((state & stream_oriented) && bytes == 0) + { + ec = boost::asio::error::eof; + return 0; + } + + // Operation failed. + if ((state & user_set_non_blocking) + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_read(s, ec) < 0) + return 0; + } +} + +#if defined(BOOST_ASIO_HAS_IOCP) + +void complete_iocp_recv(state_type state, + const weak_cancel_token_type& cancel_token, bool all_empty, + boost::system::error_code& ec, size_t bytes_transferred) +{ + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_NETNAME_DELETED) + { + if (cancel_token.expired()) + ec = boost::asio::error::operation_aborted; + else + ec = boost::asio::error::connection_reset; + } + else if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = boost::asio::error::connection_refused; + } + + // Check for connection closed. + else if (!ec && bytes_transferred == 0 + && (state & stream_oriented) != 0 + && !all_empty) + { + ec = boost::asio::error::eof; + } +} + +#else // defined(BOOST_ASIO_HAS_IOCP) + +bool non_blocking_recv(socket_type s, + buf* bufs, size_t count, int flags, bool is_stream, + boost::system::error_code& ec, size_t& bytes_transferred) +{ + for (;;) + { + // Read some data. + int bytes = socket_ops::recv(s, bufs, count, flags, ec); + + // Check for end of stream. + if (is_stream && bytes == 0) + { + ec = boost::asio::error::eof; + return true; + } + + // Retry operation if interrupted by signal. + if (ec == boost::asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + + // Operation is complete. + if (bytes >= 0) + { + ec = boost::system::error_code(); + bytes_transferred = bytes; + } + else + bytes_transferred = 0; + + return true; + } +} + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +int recvfrom(socket_type s, buf* bufs, size_t count, int flags, + socket_addr_type* addr, std::size_t* addrlen, + boost::system::error_code& ec) +{ + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Receive some data. + DWORD recv_buf_count = static_cast<DWORD>(count); + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int tmp_addrlen = (int)*addrlen; + int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, + &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec); + *addrlen = (std::size_t)tmp_addrlen; + if (ec.value() == ERROR_NETNAME_DELETED) + ec = boost::asio::error::connection_reset; + else if (ec.value() == ERROR_PORT_UNREACHABLE) + ec = boost::asio::error::connection_refused; + if (result != 0) + return socket_error_retval; + ec = boost::system::error_code(); + return bytes_transferred; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + init_msghdr_msg_name(msg.msg_name, addr); + msg.msg_namelen = *addrlen; + msg.msg_iov = bufs; + msg.msg_iovlen = count; + int result = error_wrapper(::recvmsg(s, &msg, flags), ec); + *addrlen = msg.msg_namelen; + if (result >= 0) + ec = boost::system::error_code(); + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, + size_t count, int flags, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // Read some data. + for (;;) + { + // Try to complete the operation without blocking. + int bytes = socket_ops::recvfrom(s, bufs, count, flags, addr, addrlen, ec); + + // Check if operation succeeded. + if (bytes >= 0) + return bytes; + + // Operation failed. + if ((state & user_set_non_blocking) + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_read(s, ec) < 0) + return 0; + } +} + +#if defined(BOOST_ASIO_HAS_IOCP) + +void complete_iocp_recvfrom( + const weak_cancel_token_type& cancel_token, + boost::system::error_code& ec) +{ + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_NETNAME_DELETED) + { + if (cancel_token.expired()) + ec = boost::asio::error::operation_aborted; + else + ec = boost::asio::error::connection_reset; + } + else if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = boost::asio::error::connection_refused; + } +} + +#else // defined(BOOST_ASIO_HAS_IOCP) + +bool non_blocking_recvfrom(socket_type s, + buf* bufs, size_t count, int flags, + socket_addr_type* addr, std::size_t* addrlen, + boost::system::error_code& ec, size_t& bytes_transferred) +{ + for (;;) + { + // Read some data. + int bytes = socket_ops::recvfrom(s, bufs, count, flags, addr, addrlen, ec); + + // Retry operation if interrupted by signal. + if (ec == boost::asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + + // Operation is complete. + if (bytes >= 0) + { + ec = boost::system::error_code(); + bytes_transferred = bytes; + } + else + bytes_transferred = 0; + + return true; + } +} + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +int send(socket_type s, const buf* bufs, size_t count, int flags, + boost::system::error_code& ec) +{ + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Send the data. + DWORD send_buf_count = static_cast<DWORD>(count); + DWORD bytes_transferred = 0; + DWORD send_flags = flags; + int result = error_wrapper(::WSASend(s, const_cast<buf*>(bufs), + send_buf_count, &bytes_transferred, send_flags, 0, 0), ec); + if (ec.value() == ERROR_NETNAME_DELETED) + ec = boost::asio::error::connection_reset; + else if (ec.value() == ERROR_PORT_UNREACHABLE) + ec = boost::asio::error::connection_refused; + if (result != 0) + return socket_error_retval; + ec = boost::system::error_code(); + return bytes_transferred; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + msg.msg_iov = const_cast<buf*>(bufs); + msg.msg_iovlen = count; +#if defined(__linux__) + flags |= MSG_NOSIGNAL; +#endif // defined(__linux__) + int result = error_wrapper(::sendmsg(s, &msg, flags), ec); + if (result >= 0) + ec = boost::system::error_code(); + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +size_t sync_send(socket_type s, state_type state, const buf* bufs, + size_t count, int flags, bool all_empty, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // A request to write 0 bytes to a stream is a no-op. + if (all_empty && (state & stream_oriented)) + { + ec = boost::system::error_code(); + return 0; + } + + // Read some data. + for (;;) + { + // Try to complete the operation without blocking. + int bytes = socket_ops::send(s, bufs, count, flags, ec); + + // Check if operation succeeded. + if (bytes >= 0) + return bytes; + + // Operation failed. + if ((state & user_set_non_blocking) + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_write(s, ec) < 0) + return 0; + } +} + +#if defined(BOOST_ASIO_HAS_IOCP) + +void complete_iocp_send( + const weak_cancel_token_type& cancel_token, + boost::system::error_code& ec) +{ + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_NETNAME_DELETED) + { + if (cancel_token.expired()) + ec = boost::asio::error::operation_aborted; + else + ec = boost::asio::error::connection_reset; + } + else if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = boost::asio::error::connection_refused; + } +} + +#else // defined(BOOST_ASIO_HAS_IOCP) + +bool non_blocking_send(socket_type s, + const buf* bufs, size_t count, int flags, + boost::system::error_code& ec, size_t& bytes_transferred) +{ + for (;;) + { + // Write some data. + int bytes = socket_ops::send(s, bufs, count, flags, ec); + + // Retry operation if interrupted by signal. + if (ec == boost::asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + + // Operation is complete. + if (bytes >= 0) + { + ec = boost::system::error_code(); + bytes_transferred = bytes; + } + else + bytes_transferred = 0; + + return true; + } +} + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +int sendto(socket_type s, const buf* bufs, size_t count, int flags, + const socket_addr_type* addr, std::size_t addrlen, + boost::system::error_code& ec) +{ + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // Send the data. + DWORD send_buf_count = static_cast<DWORD>(count); + DWORD bytes_transferred = 0; + int result = error_wrapper(::WSASendTo(s, const_cast<buf*>(bufs), + send_buf_count, &bytes_transferred, flags, addr, + static_cast<int>(addrlen), 0, 0), ec); + if (ec.value() == ERROR_NETNAME_DELETED) + ec = boost::asio::error::connection_reset; + else if (ec.value() == ERROR_PORT_UNREACHABLE) + ec = boost::asio::error::connection_refused; + if (result != 0) + return socket_error_retval; + ec = boost::system::error_code(); + return bytes_transferred; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + init_msghdr_msg_name(msg.msg_name, addr); + msg.msg_namelen = addrlen; + msg.msg_iov = const_cast<buf*>(bufs); + msg.msg_iovlen = count; +#if defined(__linux__) + flags |= MSG_NOSIGNAL; +#endif // defined(__linux__) + int result = error_wrapper(::sendmsg(s, &msg, flags), ec); + if (result >= 0) + ec = boost::system::error_code(); + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +size_t sync_sendto(socket_type s, state_type state, const buf* bufs, + size_t count, int flags, const socket_addr_type* addr, + std::size_t addrlen, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // Write some data. + for (;;) + { + // Try to complete the operation without blocking. + int bytes = socket_ops::sendto(s, bufs, count, flags, addr, addrlen, ec); + + // Check if operation succeeded. + if (bytes >= 0) + return bytes; + + // Operation failed. + if ((state & user_set_non_blocking) + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_write(s, ec) < 0) + return 0; + } +} + +#if !defined(BOOST_ASIO_HAS_IOCP) + +bool non_blocking_sendto(socket_type s, + const buf* bufs, size_t count, int flags, + const socket_addr_type* addr, std::size_t addrlen, + boost::system::error_code& ec, size_t& bytes_transferred) +{ + for (;;) + { + // Write some data. + int bytes = socket_ops::sendto(s, bufs, count, flags, addr, addrlen, ec); + + // Retry operation if interrupted by signal. + if (ec == boost::asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + + // Operation is complete. + if (bytes >= 0) + { + ec = boost::system::error_code(); + bytes_transferred = bytes; + } + else + bytes_transferred = 0; + + return true; + } +} + +#endif // !defined(BOOST_ASIO_HAS_IOCP) + +socket_type socket(int af, int type, int protocol, + boost::system::error_code& ec) +{ + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + socket_type s = error_wrapper(::WSASocket(af, type, protocol, 0, 0, + WSA_FLAG_OVERLAPPED), ec); + if (s == invalid_socket) + return s; + + if (af == AF_INET6) + { + // Try to enable the POSIX default behaviour of having IPV6_V6ONLY set to + // false. This will only succeed on Windows Vista and later versions of + // Windows, where a dual-stack IPv4/v6 implementation is available. + DWORD optval = 0; + ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, + reinterpret_cast<const char*>(&optval), sizeof(optval)); + } + + ec = boost::system::error_code(); + + return s; +#elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__) + socket_type s = error_wrapper(::socket(af, type, protocol), ec); + if (s == invalid_socket) + return s; + + int optval = 1; + int result = error_wrapper(::setsockopt(s, + SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec); + if (result != 0) + { + ::close(s); + return invalid_socket; + } + + return s; +#else + int s = error_wrapper(::socket(af, type, protocol), ec); + if (s >= 0) + ec = boost::system::error_code(); + return s; +#endif +} + +template <typename SockLenType> +inline int call_setsockopt(SockLenType msghdr::*, + socket_type s, int level, int optname, + const void* optval, std::size_t optlen) +{ + return ::setsockopt(s, level, optname, + (const char*)optval, (SockLenType)optlen); +} + +int setsockopt(socket_type s, state_type& state, int level, int optname, + const void* optval, std::size_t optlen, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return socket_error_retval; + } + + if (level == custom_socket_option_level && optname == always_fail_option) + { + ec = boost::asio::error::invalid_argument; + return socket_error_retval; + } + + if (level == custom_socket_option_level + && optname == enable_connection_aborted_option) + { + if (optlen != sizeof(int)) + { + ec = boost::asio::error::invalid_argument; + return socket_error_retval; + } + + if (*static_cast<const int*>(optval)) + state |= enable_connection_aborted; + else + state &= ~enable_connection_aborted; + ec = boost::system::error_code(); + return 0; + } + + if (level == SOL_SOCKET && optname == SO_LINGER) + state |= user_set_linger; + +#if defined(__BORLANDC__) + // Mysteriously, using the getsockopt and setsockopt functions directly with + // Borland C++ results in incorrect values being set and read. The bug can be + // worked around by using function addresses resolved with GetProcAddress. + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + typedef int (WSAAPI *sso_t)(SOCKET, int, int, const char*, int); + if (sso_t sso = (sso_t)::GetProcAddress(winsock_module, "setsockopt")) + { + clear_last_error(); + return error_wrapper(sso(s, level, optname, + reinterpret_cast<const char*>(optval), + static_cast<int>(optlen)), ec); + } + } + ec = boost::asio::error::fault; + return socket_error_retval; +#else // defined(__BORLANDC__) + clear_last_error(); + int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen, + s, level, optname, optval, optlen), ec); + if (result == 0) + { + ec = boost::system::error_code(); + +#if defined(__MACH__) && defined(__APPLE__) \ + || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + // To implement portable behaviour for SO_REUSEADDR with UDP sockets we + // need to also set SO_REUSEPORT on BSD-based platforms. + if ((state & datagram_oriented) + && level == SOL_SOCKET && optname == SO_REUSEADDR) + { + call_setsockopt(&msghdr::msg_namelen, s, + SOL_SOCKET, SO_REUSEPORT, optval, optlen); + } +#endif + } + + return result; +#endif // defined(__BORLANDC__) +} + +template <typename SockLenType> +inline int call_getsockopt(SockLenType msghdr::*, + socket_type s, int level, int optname, + void* optval, std::size_t* optlen) +{ + SockLenType tmp_optlen = (SockLenType)*optlen; + int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen); + *optlen = (std::size_t)tmp_optlen; + return result; +} + +int getsockopt(socket_type s, state_type state, int level, int optname, + void* optval, size_t* optlen, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return socket_error_retval; + } + + if (level == custom_socket_option_level && optname == always_fail_option) + { + ec = boost::asio::error::invalid_argument; + return socket_error_retval; + } + + if (level == custom_socket_option_level + && optname == enable_connection_aborted_option) + { + if (*optlen != sizeof(int)) + { + ec = boost::asio::error::invalid_argument; + return socket_error_retval; + } + + *static_cast<int*>(optval) = (state & enable_connection_aborted) ? 1 : 0; + ec = boost::system::error_code(); + return 0; + } + +#if defined(__BORLANDC__) + // Mysteriously, using the getsockopt and setsockopt functions directly with + // Borland C++ results in incorrect values being set and read. The bug can be + // worked around by using function addresses resolved with GetProcAddress. + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + typedef int (WSAAPI *gso_t)(SOCKET, int, int, char*, int*); + if (gso_t gso = (gso_t)::GetProcAddress(winsock_module, "getsockopt")) + { + clear_last_error(); + int tmp_optlen = static_cast<int>(*optlen); + int result = error_wrapper(gso(s, level, optname, + reinterpret_cast<char*>(optval), &tmp_optlen), ec); + *optlen = static_cast<size_t>(tmp_optlen); + if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY + && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD)) + { + // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are + // only supported on Windows Vista and later. To simplify program logic + // we will fake success of getting this option and specify that the + // value is non-zero (i.e. true). This corresponds to the behavior of + // IPv6 sockets on Windows platforms pre-Vista. + *static_cast<DWORD*>(optval) = 1; + ec = boost::system::error_code(); + } + return result; + } + } + ec = boost::asio::error::fault; + return socket_error_retval; +#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) + clear_last_error(); + int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, + s, level, optname, optval, optlen), ec); + if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY + && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD)) + { + // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are only + // supported on Windows Vista and later. To simplify program logic we will + // fake success of getting this option and specify that the value is + // non-zero (i.e. true). This corresponds to the behavior of IPv6 sockets + // on Windows platforms pre-Vista. + *static_cast<DWORD*>(optval) = 1; + ec = boost::system::error_code(); + } + if (result == 0) + ec = boost::system::error_code(); + return result; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + clear_last_error(); + int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, + s, level, optname, optval, optlen), ec); +#if defined(__linux__) + if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int) + && (optname == SO_SNDBUF || optname == SO_RCVBUF)) + { + // On Linux, setting SO_SNDBUF or SO_RCVBUF to N actually causes the kernel + // to set the buffer size to N*2. Linux puts additional stuff into the + // buffers so that only about half is actually available to the application. + // The retrieved value is divided by 2 here to make it appear as though the + // correct value has been set. + *static_cast<int*>(optval) /= 2; + } +#endif // defined(__linux__) + if (result == 0) + ec = boost::system::error_code(); + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +template <typename SockLenType> +inline int call_getpeername(SockLenType msghdr::*, + socket_type s, socket_addr_type* addr, std::size_t* addrlen) +{ + SockLenType tmp_addrlen = (SockLenType)*addrlen; + int result = ::getpeername(s, addr, &tmp_addrlen); + *addrlen = (std::size_t)tmp_addrlen; + return result; +} + +int getpeername(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, bool cached, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return socket_error_retval; + } + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if (cached) + { + // Check if socket is still connected. + DWORD connect_time = 0; + size_t connect_time_len = sizeof(connect_time); + if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_CONNECT_TIME, + &connect_time, &connect_time_len, ec) == socket_error_retval) + { + return socket_error_retval; + } + if (connect_time == 0xFFFFFFFF) + { + ec = boost::asio::error::not_connected; + return socket_error_retval; + } + + // The cached value is still valid. + ec = boost::system::error_code(); + return 0; + } +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + (void)cached; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + + clear_last_error(); + int result = error_wrapper(call_getpeername( + &msghdr::msg_namelen, s, addr, addrlen), ec); + if (result == 0) + ec = boost::system::error_code(); + return result; +} + +template <typename SockLenType> +inline int call_getsockname(SockLenType msghdr::*, + socket_type s, socket_addr_type* addr, std::size_t* addrlen) +{ + SockLenType tmp_addrlen = (SockLenType)*addrlen; + int result = ::getsockname(s, addr, &tmp_addrlen); + *addrlen = (std::size_t)tmp_addrlen; + return result; +} + +int getsockname(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return socket_error_retval; + } + + clear_last_error(); + int result = error_wrapper(call_getsockname( + &msghdr::msg_namelen, s, addr, addrlen), ec); + if (result == 0) + ec = boost::system::error_code(); + return result; +} + +int ioctl(socket_type s, state_type& state, int cmd, + ioctl_arg_type* arg, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return socket_error_retval; + } + + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec); +#elif defined(__MACH__) && defined(__APPLE__) \ + || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + int result = error_wrapper(::ioctl(s, + static_cast<unsigned int>(cmd), arg), ec); +#else + int result = error_wrapper(::ioctl(s, cmd, arg), ec); +#endif + if (result >= 0) + { + ec = boost::system::error_code(); + + // When updating the non-blocking mode we always perform the ioctl syscall, + // even if the flags would otherwise indicate that the socket is already in + // the correct state. This ensures that the underlying socket is put into + // the state that has been requested by the user. If the ioctl syscall was + // successful then we need to update the flags to match. + if (cmd == static_cast<int>(FIONBIO)) + { + if (*arg) + { + state |= user_set_non_blocking; + } + else + { + // Clearing the non-blocking mode always overrides any internally-set + // non-blocking flag. Any subsequent asynchronous operations will need + // to re-enable non-blocking I/O. + state &= ~(user_set_non_blocking | internal_non_blocking); + } + } + } + + return result; +} + +int select(int nfds, fd_set* readfds, fd_set* writefds, + fd_set* exceptfds, timeval* timeout, boost::system::error_code& ec) +{ + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + if (!readfds && !writefds && !exceptfds && timeout) + { + DWORD milliseconds = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; + if (milliseconds == 0) + milliseconds = 1; // Force context switch. + ::Sleep(milliseconds); + ec = boost::system::error_code(); + return 0; + } + + // The select() call allows timeout values measured in microseconds, but the + // system clock (as wrapped by boost::posix_time::microsec_clock) typically + // has a resolution of 10 milliseconds. This can lead to a spinning select + // reactor, meaning increased CPU usage, when waiting for the earliest + // scheduled timeout if it's less than 10 milliseconds away. To avoid a tight + // spin we'll use a minimum timeout of 1 millisecond. + if (timeout && timeout->tv_sec == 0 + && timeout->tv_usec > 0 && timeout->tv_usec < 1000) + timeout->tv_usec = 1000; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#if defined(__hpux) && defined(__SELECT) + timespec ts; + ts.tv_sec = timeout ? timeout->tv_sec : 0; + ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0; + return error_wrapper(::pselect(nfds, readfds, + writefds, exceptfds, timeout ? &ts : 0, 0), ec); +#else + int result = error_wrapper(::select(nfds, readfds, + writefds, exceptfds, timeout), ec); + if (result >= 0) + ec = boost::system::error_code(); + return result; +#endif +} + +int poll_read(socket_type s, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return socket_error_retval; + } + +#if defined(BOOST_WINDOWS) \ + || defined(__CYGWIN__) \ + || defined(__SYMBIAN32__) + fd_set fds; + FD_ZERO(&fds); + FD_SET(s, &fds); + clear_last_error(); + int result = error_wrapper(::select(s, &fds, 0, 0, 0), ec); + if (result >= 0) + ec = boost::system::error_code(); + return result; +#else // defined(BOOST_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) + pollfd fds; + fds.fd = s; + fds.events = POLLIN; + fds.revents = 0; + clear_last_error(); + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + ec = boost::system::error_code(); + return result; +#endif // defined(BOOST_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) +} + +int poll_write(socket_type s, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return socket_error_retval; + } + +#if defined(BOOST_WINDOWS) \ + || defined(__CYGWIN__) \ + || defined(__SYMBIAN32__) + fd_set fds; + FD_ZERO(&fds); + FD_SET(s, &fds); + clear_last_error(); + int result = error_wrapper(::select(s, 0, &fds, 0, 0), ec); + if (result >= 0) + ec = boost::system::error_code(); + return result; +#else // defined(BOOST_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) + pollfd fds; + fds.fd = s; + fds.events = POLLOUT; + fds.revents = 0; + clear_last_error(); + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + ec = boost::system::error_code(); + return result; +#endif // defined(BOOST_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) +} + +int poll_connect(socket_type s, boost::system::error_code& ec) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return socket_error_retval; + } + +#if defined(BOOST_WINDOWS) \ + || defined(__CYGWIN__) \ + || defined(__SYMBIAN32__) + fd_set write_fds; + FD_ZERO(&write_fds); + FD_SET(s, &write_fds); + fd_set except_fds; + FD_ZERO(&except_fds); + FD_SET(s, &except_fds); + clear_last_error(); + int result = error_wrapper(::select(s, 0, &write_fds, &except_fds, 0), ec); + if (result >= 0) + ec = boost::system::error_code(); + return result; +#else // defined(BOOST_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) + pollfd fds; + fds.fd = s; + fds.events = POLLOUT; + fds.revents = 0; + clear_last_error(); + int result = error_wrapper(::poll(&fds, 1, -1), ec); + if (result >= 0) + ec = boost::system::error_code(); + return result; +#endif // defined(BOOST_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) +} + +const char* inet_ntop(int af, const void* src, char* dest, size_t length, + unsigned long scope_id, boost::system::error_code& ec) +{ + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + using namespace std; // For memcpy. + + if (af != AF_INET && af != AF_INET6) + { + ec = boost::asio::error::address_family_not_supported; + return 0; + } + + union + { + socket_addr_type base; + sockaddr_storage_type storage; + sockaddr_in4_type v4; + sockaddr_in6_type v6; + } address; + DWORD address_length; + if (af == AF_INET) + { + address_length = sizeof(sockaddr_in4_type); + address.v4.sin_family = AF_INET; + address.v4.sin_port = 0; + memcpy(&address.v4.sin_addr, src, sizeof(in4_addr_type)); + } + else // AF_INET6 + { + address_length = sizeof(sockaddr_in6_type); + address.v6.sin6_family = AF_INET6; + address.v6.sin6_port = 0; + address.v6.sin6_flowinfo = 0; + address.v6.sin6_scope_id = scope_id; + memcpy(&address.v6.sin6_addr, src, sizeof(in6_addr_type)); + } + + DWORD string_length = static_cast<DWORD>(length); +#if defined(BOOST_NO_ANSI_APIS) + LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR)); + int result = error_wrapper(::WSAAddressToStringW(&address.base, + address_length, 0, string_buffer, &string_length), ec); + ::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, dest, length, 0, 0); +#else + int result = error_wrapper(::WSAAddressToStringA( + &address.base, address_length, 0, dest, &string_length), ec); +#endif + + // Windows may set error code on success. + if (result != socket_error_retval) + ec = boost::system::error_code(); + + // Windows may not set an error code on failure. + else if (result == socket_error_retval && !ec) + ec = boost::asio::error::invalid_argument; + + return result == socket_error_retval ? 0 : dest; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + const char* result = error_wrapper(::inet_ntop(af, src, dest, length), ec); + if (result == 0 && !ec) + ec = boost::asio::error::invalid_argument; + if (result != 0 && af == AF_INET6 && scope_id != 0) + { + using namespace std; // For strcat and sprintf. + char if_name[IF_NAMESIZE + 1] = "%"; + const in6_addr_type* ipv6_address = static_cast<const in6_addr_type*>(src); + bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address); + if (!is_link_local || if_indextoname(scope_id, if_name + 1) == 0) + sprintf(if_name + 1, "%lu", scope_id); + strcat(dest, if_name); + } + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +int inet_pton(int af, const char* src, void* dest, + unsigned long* scope_id, boost::system::error_code& ec) +{ + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + using namespace std; // For memcpy and strcmp. + + if (af != AF_INET && af != AF_INET6) + { + ec = boost::asio::error::address_family_not_supported; + return -1; + } + + union + { + socket_addr_type base; + sockaddr_storage_type storage; + sockaddr_in4_type v4; + sockaddr_in6_type v6; + } address; + int address_length = sizeof(sockaddr_storage_type); +#if defined(BOOST_NO_ANSI_APIS) + int num_wide_chars = strlen(src) + 1; + LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR)); + ::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars); + int result = error_wrapper(::WSAStringToAddressW( + wide_buffer, af, 0, &address.base, &address_length), ec); +#else + int result = error_wrapper(::WSAStringToAddressA( + const_cast<char*>(src), af, 0, &address.base, &address_length), ec); +#endif + + if (af == AF_INET) + { + if (result != socket_error_retval) + { + memcpy(dest, &address.v4.sin_addr, sizeof(in4_addr_type)); + ec = boost::system::error_code(); + } + else if (strcmp(src, "255.255.255.255") == 0) + { + static_cast<in4_addr_type*>(dest)->s_addr = INADDR_NONE; + ec = boost::system::error_code(); + } + } + else // AF_INET6 + { + if (result != socket_error_retval) + { + memcpy(dest, &address.v6.sin6_addr, sizeof(in6_addr_type)); + if (scope_id) + *scope_id = address.v6.sin6_scope_id; + ec = boost::system::error_code(); + } + } + + // Windows may not set an error code on failure. + if (result == socket_error_retval && !ec) + ec = boost::asio::error::invalid_argument; + + if (result != socket_error_retval) + ec = boost::system::error_code(); + + return result == socket_error_retval ? -1 : 1; +#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int result = error_wrapper(::inet_pton(af, src, dest), ec); + if (result <= 0 && !ec) + ec = boost::asio::error::invalid_argument; + if (result > 0 && af == AF_INET6 && scope_id) + { + using namespace std; // For strchr and atoi. + *scope_id = 0; + if (const char* if_name = strchr(src, '%')) + { + in6_addr_type* ipv6_address = static_cast<in6_addr_type*>(dest); + bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address); + if (is_link_local) + *scope_id = if_nametoindex(if_name + 1); + if (*scope_id == 0) + *scope_id = atoi(if_name + 1); + } + } + return result; +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +} + +int gethostname(char* name, int namelen, boost::system::error_code& ec) +{ + clear_last_error(); + int result = error_wrapper(::gethostname(name, namelen), ec); +#if defined(BOOST_WINDOWS) + if (result == 0) + ec = boost::system::error_code(); +#endif + return result; +} + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) \ + || defined(__MACH__) && defined(__APPLE__) + +// The following functions are only needed for emulation of getaddrinfo and +// getnameinfo. + +inline boost::system::error_code translate_netdb_error(int error) +{ + switch (error) + { + case 0: + return boost::system::error_code(); + case HOST_NOT_FOUND: + return boost::asio::error::host_not_found; + case TRY_AGAIN: + return boost::asio::error::host_not_found_try_again; + case NO_RECOVERY: + return boost::asio::error::no_recovery; + case NO_DATA: + return boost::asio::error::no_data; + default: + BOOST_ASSERT(false); + return boost::asio::error::invalid_argument; + } +} + +inline hostent* gethostbyaddr(const char* addr, int length, int af, + hostent* result, char* buffer, int buflength, boost::system::error_code& ec) +{ + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + (void)(buffer); + (void)(buflength); + hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec); + if (!retval) + return 0; + ec = boost::system::error_code(); + *result = *retval; + return retval; +#elif defined(__sun) || defined(__QNX__) + int error = 0; + hostent* retval = error_wrapper(::gethostbyaddr_r(addr, length, af, result, + buffer, buflength, &error), ec); + if (error) + ec = translate_netdb_error(error); + return retval; +#elif defined(__MACH__) && defined(__APPLE__) + (void)(buffer); + (void)(buflength); + int error = 0; + hostent* retval = error_wrapper(::getipnodebyaddr( + addr, length, af, &error), ec); + if (error) + ec = translate_netdb_error(error); + if (!retval) + return 0; + *result = *retval; + return retval; +#else + hostent* retval = 0; + int error = 0; + error_wrapper(::gethostbyaddr_r(addr, length, af, result, buffer, + buflength, &retval, &error), ec); + if (error) + ec = translate_netdb_error(error); + return retval; +#endif +} + +inline hostent* gethostbyname(const char* name, int af, struct hostent* result, + char* buffer, int buflength, int ai_flags, boost::system::error_code& ec) +{ + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + (void)(buffer); + (void)(buflength); + (void)(ai_flags); + if (af != AF_INET) + { + ec = boost::asio::error::address_family_not_supported; + return 0; + } + hostent* retval = error_wrapper(::gethostbyname(name), ec); + if (!retval) + return 0; + ec = boost::system::error_code(); + *result = *retval; + return result; +#elif defined(__sun) || defined(__QNX__) + (void)(ai_flags); + if (af != AF_INET) + { + ec = boost::asio::error::address_family_not_supported; + return 0; + } + int error = 0; + hostent* retval = error_wrapper(::gethostbyname_r(name, result, buffer, + buflength, &error), ec); + if (error) + ec = translate_netdb_error(error); + return retval; +#elif defined(__MACH__) && defined(__APPLE__) + (void)(buffer); + (void)(buflength); + int error = 0; + hostent* retval = error_wrapper(::getipnodebyname( + name, af, ai_flags, &error), ec); + if (error) + ec = translate_netdb_error(error); + if (!retval) + return 0; + *result = *retval; + return retval; +#else + (void)(ai_flags); + if (af != AF_INET) + { + ec = boost::asio::error::address_family_not_supported; + return 0; + } + hostent* retval = 0; + int error = 0; + error_wrapper(::gethostbyname_r(name, result, + buffer, buflength, &retval, &error), ec); + if (error) + ec = translate_netdb_error(error); + return retval; +#endif +} + +inline void freehostent(hostent* h) +{ +#if defined(__MACH__) && defined(__APPLE__) + if (h) + ::freehostent(h); +#else + (void)(h); +#endif +} + +// Emulation of getaddrinfo based on implementation in: +// Stevens, W. R., UNIX Network Programming Vol. 1, 2nd Ed., Prentice-Hall 1998. + +struct gai_search +{ + const char* host; + int family; +}; + +inline int gai_nsearch(const char* host, + const addrinfo_type* hints, gai_search (&search)[2]) +{ + int search_count = 0; + if (host == 0 || host[0] == '\0') + { + if (hints->ai_flags & AI_PASSIVE) + { + // No host and AI_PASSIVE implies wildcard bind. + switch (hints->ai_family) + { + case AF_INET: + search[search_count].host = "0.0.0.0"; + search[search_count].family = AF_INET; + ++search_count; + break; + case AF_INET6: + search[search_count].host = "0::0"; + search[search_count].family = AF_INET6; + ++search_count; + break; + case AF_UNSPEC: + search[search_count].host = "0::0"; + search[search_count].family = AF_INET6; + ++search_count; + search[search_count].host = "0.0.0.0"; + search[search_count].family = AF_INET; + ++search_count; + break; + default: + break; + } + } + else + { + // No host and not AI_PASSIVE means connect to local host. + switch (hints->ai_family) + { + case AF_INET: + search[search_count].host = "localhost"; + search[search_count].family = AF_INET; + ++search_count; + break; + case AF_INET6: + search[search_count].host = "localhost"; + search[search_count].family = AF_INET6; + ++search_count; + break; + case AF_UNSPEC: + search[search_count].host = "localhost"; + search[search_count].family = AF_INET6; + ++search_count; + search[search_count].host = "localhost"; + search[search_count].family = AF_INET; + ++search_count; + break; + default: + break; + } + } + } + else + { + // Host is specified. + switch (hints->ai_family) + { + case AF_INET: + search[search_count].host = host; + search[search_count].family = AF_INET; + ++search_count; + break; + case AF_INET6: + search[search_count].host = host; + search[search_count].family = AF_INET6; + ++search_count; + break; + case AF_UNSPEC: + search[search_count].host = host; + search[search_count].family = AF_INET6; + ++search_count; + search[search_count].host = host; + search[search_count].family = AF_INET; + ++search_count; + break; + default: + break; + } + } + return search_count; +} + +template <typename T> +inline T* gai_alloc(std::size_t size = sizeof(T)) +{ + using namespace std; + T* p = static_cast<T*>(::operator new(size, std::nothrow)); + if (p) + memset(p, 0, size); + return p; +} + +inline void gai_free(void* p) +{ + ::operator delete(p); +} + +inline void gai_strcpy(char* target, const char* source, std::size_t max_size) +{ + using namespace std; +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) + strcpy_s(target, max_size, source); +#else + *target = 0; + strncat(target, source, max_size); +#endif +} + +enum { gai_clone_flag = 1 << 30 }; + +inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints, + const void* addr, int family) +{ + using namespace std; + + addrinfo_type* ai = gai_alloc<addrinfo_type>(); + if (ai == 0) + return EAI_MEMORY; + + ai->ai_next = 0; + **next = ai; + *next = &ai->ai_next; + + ai->ai_canonname = 0; + ai->ai_socktype = hints->ai_socktype; + if (ai->ai_socktype == 0) + ai->ai_flags |= gai_clone_flag; + ai->ai_protocol = hints->ai_protocol; + ai->ai_family = family; + + switch (ai->ai_family) + { + case AF_INET: + { + sockaddr_in4_type* sinptr = gai_alloc<sockaddr_in4_type>(); + if (sinptr == 0) + return EAI_MEMORY; + sinptr->sin_family = AF_INET; + memcpy(&sinptr->sin_addr, addr, sizeof(in4_addr_type)); + ai->ai_addr = reinterpret_cast<sockaddr*>(sinptr); + ai->ai_addrlen = sizeof(sockaddr_in4_type); + break; + } + case AF_INET6: + { + sockaddr_in6_type* sin6ptr = gai_alloc<sockaddr_in6_type>(); + if (sin6ptr == 0) + return EAI_MEMORY; + sin6ptr->sin6_family = AF_INET6; + memcpy(&sin6ptr->sin6_addr, addr, sizeof(in6_addr_type)); + ai->ai_addr = reinterpret_cast<sockaddr*>(sin6ptr); + ai->ai_addrlen = sizeof(sockaddr_in6_type); + break; + } + default: + break; + } + + return 0; +} + +inline addrinfo_type* gai_clone(addrinfo_type* ai) +{ + using namespace std; + + addrinfo_type* new_ai = gai_alloc<addrinfo_type>(); + if (new_ai == 0) + return new_ai; + + new_ai->ai_next = ai->ai_next; + ai->ai_next = new_ai; + + new_ai->ai_flags = 0; + new_ai->ai_family = ai->ai_family; + new_ai->ai_socktype = ai->ai_socktype; + new_ai->ai_protocol = ai->ai_protocol; + new_ai->ai_canonname = 0; + new_ai->ai_addrlen = ai->ai_addrlen; + new_ai->ai_addr = gai_alloc<sockaddr>(ai->ai_addrlen); + memcpy(new_ai->ai_addr, ai->ai_addr, ai->ai_addrlen); + + return new_ai; +} + +inline int gai_port(addrinfo_type* aihead, int port, int socktype) +{ + int num_found = 0; + + for (addrinfo_type* ai = aihead; ai; ai = ai->ai_next) + { + if (ai->ai_flags & gai_clone_flag) + { + if (ai->ai_socktype != 0) + { + ai = gai_clone(ai); + if (ai == 0) + return -1; + // ai now points to newly cloned entry. + } + } + else if (ai->ai_socktype != socktype) + { + // Ignore if mismatch on socket type. + continue; + } + + ai->ai_socktype = socktype; + + switch (ai->ai_family) + { + case AF_INET: + { + sockaddr_in4_type* sinptr = + reinterpret_cast<sockaddr_in4_type*>(ai->ai_addr); + sinptr->sin_port = port; + ++num_found; + break; + } + case AF_INET6: + { + sockaddr_in6_type* sin6ptr = + reinterpret_cast<sockaddr_in6_type*>(ai->ai_addr); + sin6ptr->sin6_port = port; + ++num_found; + break; + } + default: + break; + } + } + + return num_found; +} + +inline int gai_serv(addrinfo_type* aihead, + const addrinfo_type* hints, const char* serv) +{ + using namespace std; + + int num_found = 0; + + if ( +#if defined(AI_NUMERICSERV) + (hints->ai_flags & AI_NUMERICSERV) || +#endif + isdigit(static_cast<unsigned char>(serv[0]))) + { + int port = htons(atoi(serv)); + if (hints->ai_socktype) + { + // Caller specifies socket type. + int rc = gai_port(aihead, port, hints->ai_socktype); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + } + else + { + // Caller does not specify socket type. + int rc = gai_port(aihead, port, SOCK_STREAM); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + rc = gai_port(aihead, port, SOCK_DGRAM); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + } + } + else + { + // Try service name with TCP first, then UDP. + if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_STREAM) + { + servent* sptr = getservbyname(serv, "tcp"); + if (sptr != 0) + { + int rc = gai_port(aihead, sptr->s_port, SOCK_STREAM); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + } + } + if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_DGRAM) + { + servent* sptr = getservbyname(serv, "udp"); + if (sptr != 0) + { + int rc = gai_port(aihead, sptr->s_port, SOCK_DGRAM); + if (rc < 0) + return EAI_MEMORY; + num_found += rc; + } + } + } + + if (num_found == 0) + { + if (hints->ai_socktype == 0) + { + // All calls to getservbyname() failed. + return EAI_NONAME; + } + else + { + // Service not supported for socket type. + return EAI_SERVICE; + } + } + + return 0; +} + +inline int gai_echeck(const char* host, const char* service, + int flags, int family, int socktype, int protocol) +{ + (void)(flags); + (void)(protocol); + + // Host or service must be specified. + if (host == 0 || host[0] == '\0') + if (service == 0 || service[0] == '\0') + return EAI_NONAME; + + // Check combination of family and socket type. + switch (family) + { + case AF_UNSPEC: + break; + case AF_INET: + case AF_INET6: + if (service != 0 && service[0] != '\0') + if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM) + return EAI_SOCKTYPE; + break; + default: + return EAI_FAMILY; + } + + return 0; +} + +inline void freeaddrinfo_emulation(addrinfo_type* aihead) +{ + addrinfo_type* ai = aihead; + while (ai) + { + gai_free(ai->ai_addr); + gai_free(ai->ai_canonname); + addrinfo_type* ainext = ai->ai_next; + gai_free(ai); + ai = ainext; + } +} + +inline int getaddrinfo_emulation(const char* host, const char* service, + const addrinfo_type* hintsp, addrinfo_type** result) +{ + // Set up linked list of addrinfo structures. + addrinfo_type* aihead = 0; + addrinfo_type** ainext = &aihead; + char* canon = 0; + + // Supply default hints if not specified by caller. + addrinfo_type hints = addrinfo_type(); + hints.ai_family = AF_UNSPEC; + if (hintsp) + hints = *hintsp; + + // If the resolution is not specifically for AF_INET6, remove the AI_V4MAPPED + // and AI_ALL flags. +#if defined(AI_V4MAPPED) + if (hints.ai_family != AF_INET6) + hints.ai_flags &= ~AI_V4MAPPED; +#endif +#if defined(AI_ALL) + if (hints.ai_family != AF_INET6) + hints.ai_flags &= ~AI_ALL; +#endif + + // Basic error checking. + int rc = gai_echeck(host, service, hints.ai_flags, hints.ai_family, + hints.ai_socktype, hints.ai_protocol); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + return rc; + } + + gai_search search[2]; + int search_count = gai_nsearch(host, &hints, search); + for (gai_search* sptr = search; sptr < search + search_count; ++sptr) + { + // Check for IPv4 dotted decimal string. + in4_addr_type inaddr; + boost::system::error_code ec; + if (socket_ops::inet_pton(AF_INET, sptr->host, &inaddr, 0, ec) == 1) + { + if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + return EAI_FAMILY; + } + if (sptr->family == AF_INET) + { + rc = gai_aistruct(&ainext, &hints, &inaddr, AF_INET); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + return rc; + } + } + continue; + } + + // Check for IPv6 hex string. + in6_addr_type in6addr; + if (socket_ops::inet_pton(AF_INET6, sptr->host, &in6addr, 0, ec) == 1) + { + if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET6) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + return EAI_FAMILY; + } + if (sptr->family == AF_INET6) + { + rc = gai_aistruct(&ainext, &hints, &in6addr, AF_INET6); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + return rc; + } + } + continue; + } + + // Look up hostname. + hostent hent; + char hbuf[8192] = ""; + hostent* hptr = socket_ops::gethostbyname(sptr->host, + sptr->family, &hent, hbuf, sizeof(hbuf), hints.ai_flags, ec); + if (hptr == 0) + { + if (search_count == 2) + { + // Failure is OK if there are multiple searches. + continue; + } + freeaddrinfo_emulation(aihead); + gai_free(canon); + if (ec == boost::asio::error::host_not_found) + return EAI_NONAME; + if (ec == boost::asio::error::host_not_found_try_again) + return EAI_AGAIN; + if (ec == boost::asio::error::no_recovery) + return EAI_FAIL; + if (ec == boost::asio::error::no_data) + return EAI_NONAME; + return EAI_NONAME; + } + + // Check for address family mismatch if one was specified. + if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + socket_ops::freehostent(hptr); + return EAI_FAMILY; + } + + // Save canonical name first time. + if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0] + && (hints.ai_flags & AI_CANONNAME) && canon == 0) + { + std::size_t canon_len = strlen(hptr->h_name) + 1; + canon = gai_alloc<char>(canon_len); + if (canon == 0) + { + freeaddrinfo_emulation(aihead); + socket_ops::freehostent(hptr); + return EAI_MEMORY; + } + gai_strcpy(canon, hptr->h_name, canon_len); + } + + // Create an addrinfo structure for each returned address. + for (char** ap = hptr->h_addr_list; *ap; ++ap) + { + rc = gai_aistruct(&ainext, &hints, *ap, hptr->h_addrtype); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + gai_free(canon); + socket_ops::freehostent(hptr); + return EAI_FAMILY; + } + } + + socket_ops::freehostent(hptr); + } + + // Check if we found anything. + if (aihead == 0) + { + gai_free(canon); + return EAI_NONAME; + } + + // Return canonical name in first entry. + if (host != 0 && host[0] != '\0' && (hints.ai_flags & AI_CANONNAME)) + { + if (canon) + { + aihead->ai_canonname = canon; + canon = 0; + } + else + { + std::size_t canonname_len = strlen(search[0].host) + 1; + aihead->ai_canonname = gai_alloc<char>(canonname_len); + if (aihead->ai_canonname == 0) + { + freeaddrinfo_emulation(aihead); + return EAI_MEMORY; + } + gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len); + } + } + gai_free(canon); + + // Process the service name. + if (service != 0 && service[0] != '\0') + { + rc = gai_serv(aihead, &hints, service); + if (rc != 0) + { + freeaddrinfo_emulation(aihead); + return rc; + } + } + + // Return result to caller. + *result = aihead; + return 0; +} + +inline boost::system::error_code getnameinfo_emulation( + const socket_addr_type* sa, std::size_t salen, char* host, + std::size_t hostlen, char* serv, std::size_t servlen, int flags, + boost::system::error_code& ec) +{ + using namespace std; + + const char* addr; + size_t addr_len; + unsigned short port; + switch (sa->sa_family) + { + case AF_INET: + if (salen != sizeof(sockaddr_in4_type)) + { + return ec = boost::asio::error::invalid_argument; + } + addr = reinterpret_cast<const char*>( + &reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_addr); + addr_len = sizeof(in4_addr_type); + port = reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_port; + break; + case AF_INET6: + if (salen != sizeof(sockaddr_in6_type)) + { + return ec = boost::asio::error::invalid_argument; + } + addr = reinterpret_cast<const char*>( + &reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_addr); + addr_len = sizeof(in6_addr_type); + port = reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_port; + break; + default: + return ec = boost::asio::error::address_family_not_supported; + } + + if (host && hostlen > 0) + { + if (flags & NI_NUMERICHOST) + { + if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen, 0, ec) == 0) + { + return ec; + } + } + else + { + hostent hent; + char hbuf[8192] = ""; + hostent* hptr = socket_ops::gethostbyaddr(addr, + static_cast<int>(addr_len), sa->sa_family, + &hent, hbuf, sizeof(hbuf), ec); + if (hptr && hptr->h_name && hptr->h_name[0] != '\0') + { + if (flags & NI_NOFQDN) + { + char* dot = strchr(hptr->h_name, '.'); + if (dot) + { + *dot = 0; + } + } + gai_strcpy(host, hptr->h_name, hostlen); + socket_ops::freehostent(hptr); + } + else + { + socket_ops::freehostent(hptr); + if (flags & NI_NAMEREQD) + { + return ec = boost::asio::error::host_not_found; + } + if (socket_ops::inet_ntop(sa->sa_family, + addr, host, hostlen, 0, ec) == 0) + { + return ec; + } + } + } + } + + if (serv && servlen > 0) + { + if (flags & NI_NUMERICSERV) + { + if (servlen < 6) + { + return ec = boost::asio::error::no_buffer_space; + } +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) + sprintf_s(serv, servlen, "%u", ntohs(port)); +#else + sprintf(serv, "%u", ntohs(port)); +#endif + } + else + { +#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) \ + && !defined(BOOST_ASIO_DISABLE_THREADS) + static ::pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + ::pthread_mutex_lock(&mutex); +#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) + // && !defined(BOOST_ASIO_DISABLE_THREADS) + servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0); + if (sptr && sptr->s_name && sptr->s_name[0] != '\0') + { + gai_strcpy(serv, sptr->s_name, servlen); + } + else + { + if (servlen < 6) + { + return ec = boost::asio::error::no_buffer_space; + } +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) + sprintf_s(serv, servlen, "%u", ntohs(port)); +#else + sprintf(serv, "%u", ntohs(port)); +#endif + } +#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) \ + && !defined(BOOST_ASIO_DISABLE_THREADS) + ::pthread_mutex_unlock(&mutex); +#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) + // && !defined(BOOST_ASIO_DISABLE_THREADS) + } + } + + ec = boost::system::error_code(); + return ec; +} + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + // || defined(__MACH__) && defined(__APPLE__) + +inline boost::system::error_code translate_addrinfo_error(int error) +{ + switch (error) + { + case 0: + return boost::system::error_code(); + case EAI_AGAIN: + return boost::asio::error::host_not_found_try_again; + case EAI_BADFLAGS: + return boost::asio::error::invalid_argument; + case EAI_FAIL: + return boost::asio::error::no_recovery; + case EAI_FAMILY: + return boost::asio::error::address_family_not_supported; + case EAI_MEMORY: + return boost::asio::error::no_memory; + case EAI_NONAME: +#if defined(EAI_ADDRFAMILY) + case EAI_ADDRFAMILY: +#endif +#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) + case EAI_NODATA: +#endif + return boost::asio::error::host_not_found; + case EAI_SERVICE: + return boost::asio::error::service_not_found; + case EAI_SOCKTYPE: + return boost::asio::error::socket_type_not_supported; + default: // Possibly the non-portable EAI_SYSTEM. +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + return boost::system::error_code( + WSAGetLastError(), boost::asio::error::get_system_category()); +#else + return boost::system::error_code( + errno, boost::asio::error::get_system_category()); +#endif + } +} + +boost::system::error_code getaddrinfo(const char* host, + const char* service, const addrinfo_type& hints, + addrinfo_type** result, boost::system::error_code& ec) +{ + host = (host && *host) ? host : 0; + service = (service && *service) ? service : 0; + clear_last_error(); +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) + // Building for Windows XP, Windows Server 2003, or later. + int error = ::getaddrinfo(host, service, &hints, result); + return ec = translate_addrinfo_error(error); +# else + // Building for Windows 2000 or earlier. + typedef int (WSAAPI *gai_t)(const char*, + const char*, const addrinfo_type*, addrinfo_type**); + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + if (gai_t gai = (gai_t)::GetProcAddress(winsock_module, "getaddrinfo")) + { + int error = gai(host, service, &hints, result); + return ec = translate_addrinfo_error(error); + } + } + int error = getaddrinfo_emulation(host, service, &hints, result); + return ec = translate_addrinfo_error(error); +# endif +#elif defined(__MACH__) && defined(__APPLE__) + int error = getaddrinfo_emulation(host, service, &hints, result); + return ec = translate_addrinfo_error(error); +#else + int error = ::getaddrinfo(host, service, &hints, result); + return ec = translate_addrinfo_error(error); +#endif +} + +boost::system::error_code background_getaddrinfo( + const weak_cancel_token_type& cancel_token, const char* host, + const char* service, const addrinfo_type& hints, + addrinfo_type** result, boost::system::error_code& ec) +{ + if (cancel_token.expired()) + ec = boost::asio::error::operation_aborted; + else + socket_ops::getaddrinfo(host, service, hints, result, ec); + return ec; +} + +void freeaddrinfo(addrinfo_type* ai) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) + // Building for Windows XP, Windows Server 2003, or later. + ::freeaddrinfo(ai); +# else + // Building for Windows 2000 or earlier. + typedef int (WSAAPI *fai_t)(addrinfo_type*); + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + if (fai_t fai = (fai_t)::GetProcAddress(winsock_module, "freeaddrinfo")) + { + fai(ai); + return; + } + } + freeaddrinfo_emulation(ai); +# endif +#elif defined(__MACH__) && defined(__APPLE__) + freeaddrinfo_emulation(ai); +#else + ::freeaddrinfo(ai); +#endif +} + +boost::system::error_code getnameinfo(const socket_addr_type* addr, + std::size_t addrlen, char* host, std::size_t hostlen, + char* serv, std::size_t servlen, int flags, boost::system::error_code& ec) +{ +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) + // Building for Windows XP, Windows Server 2003, or later. + clear_last_error(); + int error = ::getnameinfo(addr, static_cast<socklen_t>(addrlen), + host, static_cast<DWORD>(hostlen), + serv, static_cast<DWORD>(servlen), flags); + return ec = translate_addrinfo_error(error); +# else + // Building for Windows 2000 or earlier. + typedef int (WSAAPI *gni_t)(const socket_addr_type*, + int, char*, DWORD, char*, DWORD, int); + if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) + { + if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo")) + { + clear_last_error(); + int error = gni(addr, static_cast<int>(addrlen), + host, static_cast<DWORD>(hostlen), + serv, static_cast<DWORD>(servlen), flags); + return ec = translate_addrinfo_error(error); + } + } + clear_last_error(); + return getnameinfo_emulation(addr, addrlen, + host, hostlen, serv, servlen, flags, ec); +# endif +#elif defined(__MACH__) && defined(__APPLE__) + using namespace std; // For memcpy. + sockaddr_storage_type tmp_addr; + memcpy(&tmp_addr, addr, addrlen); + tmp_addr.ss_len = addrlen; + addr = reinterpret_cast<socket_addr_type*>(&tmp_addr); + clear_last_error(); + return getnameinfo_emulation(addr, addrlen, + host, hostlen, serv, servlen, flags, ec); +#else + clear_last_error(); + int error = ::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags); + return ec = translate_addrinfo_error(error); +#endif +} + +boost::system::error_code sync_getnameinfo( + const socket_addr_type* addr, std::size_t addrlen, + char* host, std::size_t hostlen, char* serv, + std::size_t servlen, int sock_type, boost::system::error_code& ec) +{ + // First try resolving with the service name. If that fails try resolving + // but allow the service to be returned as a number. + int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0; + socket_ops::getnameinfo(addr, addrlen, host, + hostlen, serv, servlen, flags, ec); + if (ec) + { + socket_ops::getnameinfo(addr, addrlen, host, hostlen, + serv, servlen, flags | NI_NUMERICSERV, ec); + } + + return ec; +} + +boost::system::error_code background_getnameinfo( + const weak_cancel_token_type& cancel_token, + const socket_addr_type* addr, std::size_t addrlen, + char* host, std::size_t hostlen, char* serv, + std::size_t servlen, int sock_type, boost::system::error_code& ec) +{ + if (cancel_token.expired()) + { + ec = boost::asio::error::operation_aborted; + } + else + { + // First try resolving with the service name. If that fails try resolving + // but allow the service to be returned as a number. + int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0; + socket_ops::getnameinfo(addr, addrlen, host, + hostlen, serv, servlen, flags, ec); + if (ec) + { + socket_ops::getnameinfo(addr, addrlen, host, hostlen, + serv, servlen, flags | NI_NUMERICSERV, ec); + } + } + + return ec; +} + +u_long_type network_to_host_long(u_long_type value) +{ + return ntohl(value); +} + +u_long_type host_to_network_long(u_long_type value) +{ + return htonl(value); +} + +u_short_type network_to_host_short(u_short_type value) +{ + return ntohs(value); +} + +u_short_type host_to_network_short(u_short_type value) +{ + return htons(value); +} + +} // namespace socket_ops +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/socket_select_interrupter.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/socket_select_interrupter.ipp new file mode 100644 index 0000000..d697a6e --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/socket_select_interrupter.ipp @@ -0,0 +1,153 @@ +// +// detail/impl/socket_select_interrupter.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_SOCKET_SELECT_INTERRUPTER_IPP +#define BOOST_ASIO_DETAIL_IMPL_SOCKET_SELECT_INTERRUPTER_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_WINDOWS) \ + || defined(__CYGWIN__) \ + || defined(__SYMBIAN32__) + +#include <cstdlib> +#include <boost/asio/detail/socket_holder.hpp> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/detail/socket_select_interrupter.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +socket_select_interrupter::socket_select_interrupter() +{ + boost::system::error_code ec; + socket_holder acceptor(socket_ops::socket( + AF_INET, SOCK_STREAM, IPPROTO_TCP, ec)); + if (acceptor.get() == invalid_socket) + boost::asio::detail::throw_error(ec, "socket_select_interrupter"); + + int opt = 1; + socket_ops::state_type acceptor_state = 0; + socket_ops::setsockopt(acceptor.get(), acceptor_state, + SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt), ec); + + using namespace std; // For memset. + sockaddr_in4_type addr; + std::size_t addr_len = sizeof(addr); + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = 0; + if (socket_ops::bind(acceptor.get(), (const socket_addr_type*)&addr, + addr_len, ec) == socket_error_retval) + boost::asio::detail::throw_error(ec, "socket_select_interrupter"); + + if (socket_ops::getsockname(acceptor.get(), (socket_addr_type*)&addr, + &addr_len, ec) == socket_error_retval) + boost::asio::detail::throw_error(ec, "socket_select_interrupter"); + + // Some broken firewalls on Windows will intermittently cause getsockname to + // return 0.0.0.0 when the socket is actually bound to 127.0.0.1. We + // explicitly specify the target address here to work around this problem. + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + + if (socket_ops::listen(acceptor.get(), + SOMAXCONN, ec) == socket_error_retval) + boost::asio::detail::throw_error(ec, "socket_select_interrupter"); + + socket_holder client(socket_ops::socket( + AF_INET, SOCK_STREAM, IPPROTO_TCP, ec)); + if (client.get() == invalid_socket) + boost::asio::detail::throw_error(ec, "socket_select_interrupter"); + + if (socket_ops::connect(client.get(), (const socket_addr_type*)&addr, + addr_len, ec) == socket_error_retval) + boost::asio::detail::throw_error(ec, "socket_select_interrupter"); + + socket_holder server(socket_ops::accept(acceptor.get(), 0, 0, ec)); + if (server.get() == invalid_socket) + boost::asio::detail::throw_error(ec, "socket_select_interrupter"); + + ioctl_arg_type non_blocking = 1; + socket_ops::state_type client_state = 0; + if (socket_ops::ioctl(client.get(), client_state, + FIONBIO, &non_blocking, ec)) + boost::asio::detail::throw_error(ec, "socket_select_interrupter"); + + opt = 1; + socket_ops::setsockopt(client.get(), client_state, + IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec); + + non_blocking = 1; + socket_ops::state_type server_state = 0; + if (socket_ops::ioctl(server.get(), server_state, + FIONBIO, &non_blocking, ec)) + boost::asio::detail::throw_error(ec, "socket_select_interrupter"); + + opt = 1; + socket_ops::setsockopt(server.get(), server_state, + IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec); + + read_descriptor_ = server.release(); + write_descriptor_ = client.release(); +} + +socket_select_interrupter::~socket_select_interrupter() +{ + boost::system::error_code ec; + socket_ops::state_type state = socket_ops::internal_non_blocking; + if (read_descriptor_ != invalid_socket) + socket_ops::close(read_descriptor_, state, true, ec); + if (write_descriptor_ != invalid_socket) + socket_ops::close(write_descriptor_, state, true, ec); +} + +void socket_select_interrupter::interrupt() +{ + char byte = 0; + socket_ops::buf b; + socket_ops::init_buf(b, &byte, 1); + boost::system::error_code ec; + socket_ops::send(write_descriptor_, &b, 1, 0, ec); +} + +bool socket_select_interrupter::reset() +{ + char data[1024]; + socket_ops::buf b; + socket_ops::init_buf(b, data, sizeof(data)); + boost::system::error_code ec; + int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec); + bool was_interrupted = (bytes_read > 0); + while (bytes_read == sizeof(data)) + bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec); + return was_interrupted; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) + +#endif // BOOST_ASIO_DETAIL_IMPL_SOCKET_SELECT_INTERRUPTER_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.hpp new file mode 100644 index 0000000..e959947 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.hpp @@ -0,0 +1,142 @@ +// +// detail/impl/strand_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP +#define BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/call_stack.hpp> +#include <boost/asio/detail/completion_handler.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +inline strand_service::strand_impl::strand_impl() + : operation(&strand_service::do_complete), + count_(0) +{ +} + +struct strand_service::on_dispatch_exit +{ + io_service_impl* io_service_; + strand_impl* impl_; + + ~on_dispatch_exit() + { + impl_->mutex_.lock(); + bool more_handlers = (--impl_->count_ > 0); + impl_->mutex_.unlock(); + + if (more_handlers) + io_service_->post_immediate_completion(impl_); + } +}; + +inline void strand_service::destroy(strand_service::implementation_type& impl) +{ + impl = 0; +} + +template <typename Handler> +void strand_service::dispatch(strand_service::implementation_type& impl, + Handler handler) +{ + // If we are already in the strand then the handler can run immediately. + if (call_stack<strand_impl>::contains(impl)) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler); + return; + } + + // Allocate and construct an operation to wrap the handler. + typedef completion_handler<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + // If we are running inside the io_service, and no other handler is queued + // or running, then the handler can run immediately. + bool can_dispatch = call_stack<io_service_impl>::contains(&io_service_); + impl->mutex_.lock(); + bool first = (++impl->count_ == 1); + if (can_dispatch && first) + { + // Immediate invocation is allowed. + impl->mutex_.unlock(); + + // Memory must be releaesed before any upcall is made. + p.reset(); + + // Indicate that this strand is executing on the current thread. + call_stack<strand_impl>::context ctx(impl); + + // Ensure the next handler, if any, is scheduled on block exit. + on_dispatch_exit on_exit = { &io_service_, impl }; + (void)on_exit; + + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler); + return; + } + + // Immediate invocation is not allowed, so enqueue for later. + impl->queue_.push(p.p); + impl->mutex_.unlock(); + p.v = p.p = 0; + + // The first handler to be enqueued is responsible for scheduling the + // strand. + if (first) + io_service_.post_immediate_completion(impl); +} + +// Request the io_service to invoke the given handler and return immediately. +template <typename Handler> +void strand_service::post(strand_service::implementation_type& impl, + Handler handler) +{ + // Allocate and construct an operation to wrap the handler. + typedef completion_handler<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + // Add the handler to the queue. + impl->mutex_.lock(); + bool first = (++impl->count_ == 1); + impl->queue_.push(p.p); + impl->mutex_.unlock(); + p.v = p.p = 0; + + // The first handler to be enqueue is responsible for scheduling the strand. + if (first) + io_service_.post_immediate_completion(impl); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.ipp new file mode 100644 index 0000000..f94570a --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.ipp @@ -0,0 +1,108 @@ +// +// detail/impl/strand_service.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_IPP +#define BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/asio/detail/call_stack.hpp> +#include <boost/asio/detail/strand_service.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +struct strand_service::on_do_complete_exit +{ + io_service_impl* owner_; + strand_impl* impl_; + + ~on_do_complete_exit() + { + impl_->mutex_.lock(); + bool more_handlers = (--impl_->count_ > 0); + impl_->mutex_.unlock(); + + if (more_handlers) + owner_->post_immediate_completion(impl_); + } +}; + +strand_service::strand_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base<strand_service>(io_service), + io_service_(boost::asio::use_service<io_service_impl>(io_service)), + mutex_(), + salt_(0) +{ +} + +void strand_service::shutdown_service() +{ + op_queue<operation> ops; + + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + for (std::size_t i = 0; i < num_implementations; ++i) + if (strand_impl* impl = implementations_[i].get()) + ops.push(impl->queue_); +} + +void strand_service::construct(strand_service::implementation_type& impl) +{ + std::size_t salt = salt_++; + std::size_t index = reinterpret_cast<std::size_t>(&impl); + index += (reinterpret_cast<std::size_t>(&impl) >> 3); + index ^= salt + 0x9e3779b9 + (index << 6) + (index >> 2); + index = index % num_implementations; + + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (!implementations_[index]) + implementations_[index].reset(new strand_impl); + impl = implementations_[index].get(); +} + +void strand_service::do_complete(io_service_impl* owner, operation* base, + boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) +{ + if (owner) + { + strand_impl* impl = static_cast<strand_impl*>(base); + + // Get the next handler to be executed. + impl->mutex_.lock(); + operation* o = impl->queue_.front(); + impl->queue_.pop(); + impl->mutex_.unlock(); + + // Indicate that this strand is executing on the current thread. + call_stack<strand_impl>::context ctx(impl); + + // Ensure the next handler, if any, is scheduled on block exit. + on_do_complete_exit on_exit = { owner, impl }; + (void)on_exit; + + o->complete(*owner); + } +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.hpp new file mode 100644 index 0000000..ed5b2c4 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.hpp @@ -0,0 +1,62 @@ +// +// detail/impl/task_io_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_TASK_IO_SERVICE_HPP +#define BOOST_ASIO_DETAIL_IMPL_TASK_IO_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/call_stack.hpp> +#include <boost/asio/detail/completion_handler.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Handler> +void task_io_service::dispatch(Handler handler) +{ + if (call_stack<task_io_service>::contains(this)) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler); + } + else + post(handler); +} + +template <typename Handler> +void task_io_service::post(Handler handler) +{ + // Allocate and construct an operation to wrap the handler. + typedef completion_handler<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + post_immediate_completion(p.p); + p.v = p.p = 0; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_IMPL_TASK_IO_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.ipp new file mode 100644 index 0000000..4cc2326 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.ipp @@ -0,0 +1,356 @@ +// +// detail/impl/task_io_service.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_TASK_IO_SERVICE_IPP +#define BOOST_ASIO_DETAIL_IMPL_TASK_IO_SERVICE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if !defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/limits.hpp> +#include <boost/asio/detail/call_stack.hpp> +#include <boost/asio/detail/event.hpp> +#include <boost/asio/detail/reactor.hpp> +#include <boost/asio/detail/task_io_service.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +struct task_io_service::task_cleanup +{ + ~task_cleanup() + { + // Enqueue the completed operations and reinsert the task at the end of + // the operation queue. + lock_->lock(); + task_io_service_->task_interrupted_ = true; + task_io_service_->op_queue_.push(*ops_); + task_io_service_->op_queue_.push(&task_io_service_->task_operation_); + } + + task_io_service* task_io_service_; + mutex::scoped_lock* lock_; + op_queue<operation>* ops_; +}; + +struct task_io_service::work_finished_on_block_exit +{ + ~work_finished_on_block_exit() + { + task_io_service_->work_finished(); + } + + task_io_service* task_io_service_; +}; + +struct task_io_service::idle_thread_info +{ + event wakeup_event; + idle_thread_info* next; +}; + +task_io_service::task_io_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base<task_io_service>(io_service), + mutex_(), + task_(0), + task_interrupted_(true), + outstanding_work_(0), + stopped_(false), + shutdown_(false), + first_idle_thread_(0) +{ +} + +void task_io_service::init(std::size_t /*concurrency_hint*/) +{ +} + +void task_io_service::shutdown_service() +{ + mutex::scoped_lock lock(mutex_); + shutdown_ = true; + lock.unlock(); + + // Destroy handler objects. + while (!op_queue_.empty()) + { + operation* o = op_queue_.front(); + op_queue_.pop(); + if (o != &task_operation_) + o->destroy(); + } + + // Reset to initial state. + task_ = 0; +} + +void task_io_service::init_task() +{ + mutex::scoped_lock lock(mutex_); + if (!shutdown_ && !task_) + { + task_ = &use_service<reactor>(this->get_io_service()); + op_queue_.push(&task_operation_); + wake_one_thread_and_unlock(lock); + } +} + +std::size_t task_io_service::run(boost::system::error_code& ec) +{ + ec = boost::system::error_code(); + if (outstanding_work_ == 0) + { + stop(); + return 0; + } + + call_stack<task_io_service>::context ctx(this); + + idle_thread_info this_idle_thread; + this_idle_thread.next = 0; + + mutex::scoped_lock lock(mutex_); + + std::size_t n = 0; + for (; do_one(lock, &this_idle_thread); lock.lock()) + if (n != (std::numeric_limits<std::size_t>::max)()) + ++n; + return n; +} + +std::size_t task_io_service::run_one(boost::system::error_code& ec) +{ + ec = boost::system::error_code(); + if (outstanding_work_ == 0) + { + stop(); + return 0; + } + + call_stack<task_io_service>::context ctx(this); + + idle_thread_info this_idle_thread; + this_idle_thread.next = 0; + + mutex::scoped_lock lock(mutex_); + + return do_one(lock, &this_idle_thread); +} + +std::size_t task_io_service::poll(boost::system::error_code& ec) +{ + if (outstanding_work_ == 0) + { + stop(); + ec = boost::system::error_code(); + return 0; + } + + call_stack<task_io_service>::context ctx(this); + + mutex::scoped_lock lock(mutex_); + + std::size_t n = 0; + for (; do_one(lock, 0); lock.lock()) + if (n != (std::numeric_limits<std::size_t>::max)()) + ++n; + return n; +} + +std::size_t task_io_service::poll_one(boost::system::error_code& ec) +{ + ec = boost::system::error_code(); + if (outstanding_work_ == 0) + { + stop(); + return 0; + } + + call_stack<task_io_service>::context ctx(this); + + mutex::scoped_lock lock(mutex_); + + return do_one(lock, 0); +} + +void task_io_service::stop() +{ + mutex::scoped_lock lock(mutex_); + stop_all_threads(lock); +} + +void task_io_service::reset() +{ + mutex::scoped_lock lock(mutex_); + stopped_ = false; +} + +void task_io_service::post_immediate_completion(task_io_service::operation* op) +{ + work_started(); + post_deferred_completion(op); +} + +void task_io_service::post_deferred_completion(task_io_service::operation* op) +{ + mutex::scoped_lock lock(mutex_); + op_queue_.push(op); + wake_one_thread_and_unlock(lock); +} + +void task_io_service::post_deferred_completions( + op_queue<task_io_service::operation>& ops) +{ + if (!ops.empty()) + { + mutex::scoped_lock lock(mutex_); + op_queue_.push(ops); + wake_one_thread_and_unlock(lock); + } +} + +std::size_t task_io_service::do_one(mutex::scoped_lock& lock, + task_io_service::idle_thread_info* this_idle_thread) +{ + bool polling = !this_idle_thread; + bool task_has_run = false; + while (!stopped_) + { + if (!op_queue_.empty()) + { + // Prepare to execute first handler from queue. + operation* o = op_queue_.front(); + op_queue_.pop(); + bool more_handlers = (!op_queue_.empty()); + + if (o == &task_operation_) + { + task_interrupted_ = more_handlers || polling; + + // If the task has already run and we're polling then we're done. + if (task_has_run && polling) + { + task_interrupted_ = true; + op_queue_.push(&task_operation_); + return 0; + } + task_has_run = true; + + if (!more_handlers || !wake_one_idle_thread_and_unlock(lock)) + lock.unlock(); + + op_queue<operation> completed_ops; + task_cleanup c = { this, &lock, &completed_ops }; + (void)c; + + // Run the task. May throw an exception. Only block if the operation + // queue is empty and we're not polling, otherwise we want to return + // as soon as possible. + task_->run(!more_handlers && !polling, completed_ops); + } + else + { + if (more_handlers) + wake_one_thread_and_unlock(lock); + else + lock.unlock(); + + // Ensure the count of outstanding work is decremented on block exit. + work_finished_on_block_exit on_exit = { this }; + (void)on_exit; + + // Complete the operation. May throw an exception. + o->complete(*this); // deletes the operation object + + return 1; + } + } + else if (this_idle_thread) + { + // Nothing to run right now, so just wait for work to do. + this_idle_thread->next = first_idle_thread_; + first_idle_thread_ = this_idle_thread; + this_idle_thread->wakeup_event.clear(lock); + this_idle_thread->wakeup_event.wait(lock); + } + else + { + return 0; + } + } + + return 0; +} + +void task_io_service::stop_all_threads( + mutex::scoped_lock& lock) +{ + stopped_ = true; + + while (first_idle_thread_) + { + idle_thread_info* idle_thread = first_idle_thread_; + first_idle_thread_ = idle_thread->next; + idle_thread->next = 0; + idle_thread->wakeup_event.signal(lock); + } + + if (!task_interrupted_ && task_) + { + task_interrupted_ = true; + task_->interrupt(); + } +} + +bool task_io_service::wake_one_idle_thread_and_unlock( + mutex::scoped_lock& lock) +{ + if (first_idle_thread_) + { + idle_thread_info* idle_thread = first_idle_thread_; + first_idle_thread_ = idle_thread->next; + idle_thread->next = 0; + idle_thread->wakeup_event.signal_and_unlock(lock); + return true; + } + return false; +} + +void task_io_service::wake_one_thread_and_unlock( + mutex::scoped_lock& lock) +{ + if (!wake_one_idle_thread_and_unlock(lock)) + { + if (!task_interrupted_ && task_) + { + task_interrupted_ = true; + task_->interrupt(); + } + lock.unlock(); + } +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // !defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_IMPL_TASK_IO_SERVICE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/throw_error.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/throw_error.ipp new file mode 100644 index 0000000..e66cca5 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/throw_error.ipp @@ -0,0 +1,47 @@ +// +// detail/impl/throw_error.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_THROW_ERROR_IPP +#define BOOST_ASIO_DETAIL_IMPL_THROW_ERROR_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/throw_exception.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/system/system_error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +void do_throw_error(const boost::system::error_code& err) +{ + boost::system::system_error e(err); + boost::throw_exception(e); +} + +void do_throw_error(const boost::system::error_code& err, const char* location) +{ + boost::system::system_error e(err, location); + boost::throw_exception(e); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_IMPL_THROW_ERROR_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/timer_queue_set.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/timer_queue_set.ipp new file mode 100644 index 0000000..275b9c5 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/timer_queue_set.ipp @@ -0,0 +1,103 @@ +// +// detail/impl/timer_queue_set.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_TIMER_QUEUE_SET_IPP +#define BOOST_ASIO_DETAIL_IMPL_TIMER_QUEUE_SET_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/asio/detail/timer_queue_set.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +timer_queue_set::timer_queue_set() + : first_(0) +{ +} + +void timer_queue_set::insert(timer_queue_base* q) +{ + q->next_ = first_; + first_ = q; +} + +void timer_queue_set::erase(timer_queue_base* q) +{ + if (first_) + { + if (q == first_) + { + first_ = q->next_; + q->next_ = 0; + return; + } + + for (timer_queue_base* p = first_; p->next_; p = p->next_) + { + if (p->next_ == q) + { + p->next_ = q->next_; + q->next_ = 0; + return; + } + } + } +} + +bool timer_queue_set::all_empty() const +{ + for (timer_queue_base* p = first_; p; p = p->next_) + if (!p->empty()) + return false; + return true; +} + +long timer_queue_set::wait_duration_msec(long max_duration) const +{ + long min_duration = max_duration; + for (timer_queue_base* p = first_; p; p = p->next_) + min_duration = p->wait_duration_msec(min_duration); + return min_duration; +} + +long timer_queue_set::wait_duration_usec(long max_duration) const +{ + long min_duration = max_duration; + for (timer_queue_base* p = first_; p; p = p->next_) + min_duration = p->wait_duration_usec(min_duration); + return min_duration; +} + +void timer_queue_set::get_ready_timers(op_queue<operation>& ops) +{ + for (timer_queue_base* p = first_; p; p = p->next_) + p->get_ready_timers(ops); +} + +void timer_queue_set::get_all_timers(op_queue<operation>& ops) +{ + for (timer_queue_base* p = first_; p; p = p->next_) + p->get_all_timers(ops); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_IMPL_TIMER_QUEUE_SET_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_event.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_event.ipp new file mode 100644 index 0000000..d383c5b --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_event.ipp @@ -0,0 +1,52 @@ +// +// detail/win_event.ipp +// ~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_WIN_EVENT_IPP +#define BOOST_ASIO_DETAIL_IMPL_WIN_EVENT_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_WINDOWS) + +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/detail/win_event.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +win_event::win_event() + : event_(::CreateEvent(0, true, false, 0)) +{ + if (!event_) + { + DWORD last_error = ::GetLastError(); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "event"); + } +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_WINDOWS) + +#endif // BOOST_ASIO_DETAIL_IMPL_WIN_EVENT_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_handle_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_handle_service.ipp new file mode 100644 index 0000000..3169632 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_handle_service.ipp @@ -0,0 +1,454 @@ +// +// detail/impl/win_iocp_handle_service.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_HANDLE_SERVICE_IPP +#define BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_HANDLE_SERVICE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/asio/detail/win_iocp_handle_service.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +class win_iocp_handle_service::overlapped_wrapper + : public OVERLAPPED +{ +public: + explicit overlapped_wrapper(boost::system::error_code& ec) + { + Internal = 0; + InternalHigh = 0; + Offset = 0; + OffsetHigh = 0; + + // Create a non-signalled manual-reset event, for GetOverlappedResult. + hEvent = ::CreateEvent(0, TRUE, FALSE, 0); + if (hEvent) + { + // As documented in GetQueuedCompletionStatus, setting the low order + // bit of this event prevents our synchronous writes from being treated + // as completion port events. + *reinterpret_cast<DWORD_PTR*>(&hEvent) |= 1; + } + else + { + DWORD last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + } + } + + ~overlapped_wrapper() + { + if (hEvent) + { + ::CloseHandle(hEvent); + } + } +}; + +win_iocp_handle_service::win_iocp_handle_service( + boost::asio::io_service& io_service) + : iocp_service_(boost::asio::use_service<win_iocp_io_service>(io_service)), + mutex_(), + impl_list_(0) +{ +} + +void win_iocp_handle_service::shutdown_service() +{ + // Close all implementations, causing all operations to complete. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + implementation_type* impl = impl_list_; + while (impl) + { + close_for_destruction(*impl); + impl = impl->next_; + } +} + +void win_iocp_handle_service::construct( + win_iocp_handle_service::implementation_type& impl) +{ + impl.handle_ = INVALID_HANDLE_VALUE; + impl.safe_cancellation_thread_id_ = 0; + + // Insert implementation into linked list of all implementations. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + impl.next_ = impl_list_; + impl.prev_ = 0; + if (impl_list_) + impl_list_->prev_ = &impl; + impl_list_ = &impl; +} + +void win_iocp_handle_service::destroy( + win_iocp_handle_service::implementation_type& impl) +{ + close_for_destruction(impl); + + // Remove implementation from linked list of all implementations. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (impl_list_ == &impl) + impl_list_ = impl.next_; + if (impl.prev_) + impl.prev_->next_ = impl.next_; + if (impl.next_) + impl.next_->prev_= impl.prev_; + impl.next_ = 0; + impl.prev_ = 0; +} + +boost::system::error_code win_iocp_handle_service::assign( + win_iocp_handle_service::implementation_type& impl, + const native_type& native_handle, boost::system::error_code& ec) +{ + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + if (iocp_service_.register_handle(native_handle, ec)) + return ec; + + impl.handle_ = native_handle; + ec = boost::system::error_code(); + return ec; +} + +boost::system::error_code win_iocp_handle_service::close( + win_iocp_handle_service::implementation_type& impl, + boost::system::error_code& ec) +{ + if (is_open(impl)) + { + if (!::CloseHandle(impl.handle_)) + { + DWORD last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return ec; + } + + impl.handle_ = INVALID_HANDLE_VALUE; + impl.safe_cancellation_thread_id_ = 0; + } + + ec = boost::system::error_code(); + return ec; +} + +boost::system::error_code win_iocp_handle_service::cancel( + win_iocp_handle_service::implementation_type& impl, + boost::system::error_code& ec) +{ + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + } + else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress( + ::GetModuleHandleA("KERNEL32"), "CancelIoEx")) + { + // The version of Windows supports cancellation from any thread. + typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED); + cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr; + if (!cancel_io_ex(impl.handle_, 0)) + { + DWORD last_error = ::GetLastError(); + if (last_error == ERROR_NOT_FOUND) + { + // ERROR_NOT_FOUND means that there were no operations to be + // cancelled. We swallow this error to match the behaviour on other + // platforms. + ec = boost::system::error_code(); + } + else + { + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + } + } + else + { + ec = boost::system::error_code(); + } + } + else if (impl.safe_cancellation_thread_id_ == 0) + { + // No operations have been started, so there's nothing to cancel. + ec = boost::system::error_code(); + } + else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId()) + { + // Asynchronous operations have been started from the current thread only, + // so it is safe to try to cancel them using CancelIo. + if (!::CancelIo(impl.handle_)) + { + DWORD last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + } + else + { + ec = boost::system::error_code(); + } + } + else + { + // Asynchronous operations have been started from more than one thread, + // so cancellation is not safe. + ec = boost::asio::error::operation_not_supported; + } + + return ec; +} + +size_t win_iocp_handle_service::do_write( + win_iocp_handle_service::implementation_type& impl, boost::uint64_t offset, + const boost::asio::const_buffer& buffer, boost::system::error_code& ec) +{ + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // A request to write 0 bytes on a handle is a no-op. + if (boost::asio::buffer_size(buffer) == 0) + { + ec = boost::system::error_code(); + return 0; + } + + overlapped_wrapper overlapped(ec); + if (ec) + { + return 0; + } + + // Write the data. + overlapped.Offset = offset & 0xFFFFFFFF; + overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; + BOOL ok = ::WriteFile(impl.handle_, + boost::asio::buffer_cast<LPCVOID>(buffer), + static_cast<DWORD>(boost::asio::buffer_size(buffer)), 0, &overlapped); + if (!ok) + { + DWORD last_error = ::GetLastError(); + if (last_error != ERROR_IO_PENDING) + { + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return 0; + } + } + + // Wait for the operation to complete. + DWORD bytes_transferred = 0; + ok = ::GetOverlappedResult(impl.handle_, + &overlapped, &bytes_transferred, TRUE); + if (!ok) + { + DWORD last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return 0; + } + + ec = boost::system::error_code(); + return bytes_transferred; +} + +void win_iocp_handle_service::start_write_op( + win_iocp_handle_service::implementation_type& impl, boost::uint64_t offset, + const boost::asio::const_buffer& buffer, operation* op) +{ + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (!is_open(impl)) + { + iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); + } + else if (boost::asio::buffer_size(buffer) == 0) + { + // A request to write 0 bytes on a handle is a no-op. + iocp_service_.on_completion(op); + } + else + { + DWORD bytes_transferred = 0; + op->Offset = offset & 0xFFFFFFFF; + op->OffsetHigh = (offset >> 32) & 0xFFFFFFFF; + BOOL ok = ::WriteFile(impl.handle_, + boost::asio::buffer_cast<LPCVOID>(buffer), + static_cast<DWORD>(boost::asio::buffer_size(buffer)), + &bytes_transferred, op); + DWORD last_error = ::GetLastError(); + if (!ok && last_error != ERROR_IO_PENDING + && last_error != ERROR_MORE_DATA) + { + iocp_service_.on_completion(op, last_error, bytes_transferred); + } + else + { + iocp_service_.on_pending(op); + } + } +} + +size_t win_iocp_handle_service::do_read( + win_iocp_handle_service::implementation_type& impl, boost::uint64_t offset, + const boost::asio::mutable_buffer& buffer, boost::system::error_code& ec) +{ + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // A request to read 0 bytes on a stream handle is a no-op. + if (boost::asio::buffer_size(buffer) == 0) + { + ec = boost::system::error_code(); + return 0; + } + + overlapped_wrapper overlapped(ec); + if (ec) + { + return 0; + } + + // Read some data. + overlapped.Offset = offset & 0xFFFFFFFF; + overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; + BOOL ok = ::ReadFile(impl.handle_, + boost::asio::buffer_cast<LPVOID>(buffer), + static_cast<DWORD>(boost::asio::buffer_size(buffer)), 0, &overlapped); + if (!ok) + { + DWORD last_error = ::GetLastError(); + if (last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA) + { + if (last_error == ERROR_HANDLE_EOF) + { + ec = boost::asio::error::eof; + } + else + { + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + } + return 0; + } + } + + // Wait for the operation to complete. + DWORD bytes_transferred = 0; + ok = ::GetOverlappedResult(impl.handle_, + &overlapped, &bytes_transferred, TRUE); + if (!ok) + { + DWORD last_error = ::GetLastError(); + if (last_error == ERROR_HANDLE_EOF) + { + ec = boost::asio::error::eof; + } + else + { + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + } + return 0; + } + + ec = boost::system::error_code(); + return bytes_transferred; +} + +void win_iocp_handle_service::start_read_op( + win_iocp_handle_service::implementation_type& impl, boost::uint64_t offset, + const boost::asio::mutable_buffer& buffer, operation* op) +{ + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (!is_open(impl)) + { + iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); + } + else if (boost::asio::buffer_size(buffer) == 0) + { + // A request to read 0 bytes on a handle is a no-op. + iocp_service_.on_completion(op); + } + else + { + DWORD bytes_transferred = 0; + op->Offset = offset & 0xFFFFFFFF; + op->OffsetHigh = (offset >> 32) & 0xFFFFFFFF; + BOOL ok = ::ReadFile(impl.handle_, + boost::asio::buffer_cast<LPVOID>(buffer), + static_cast<DWORD>(boost::asio::buffer_size(buffer)), + &bytes_transferred, op); + DWORD last_error = ::GetLastError(); + if (!ok && last_error != ERROR_IO_PENDING + && last_error != ERROR_MORE_DATA) + { + iocp_service_.on_completion(op, last_error, bytes_transferred); + } + else + { + iocp_service_.on_pending(op); + } + } +} + +void win_iocp_handle_service::update_cancellation_thread_id( + win_iocp_handle_service::implementation_type& impl) +{ + if (impl.safe_cancellation_thread_id_ == 0) + impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); + else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) + impl.safe_cancellation_thread_id_ = ~DWORD(0); +} + +void win_iocp_handle_service::close_for_destruction(implementation_type& impl) +{ + if (is_open(impl)) + { + ::CloseHandle(impl.handle_); + impl.handle_ = INVALID_HANDLE_VALUE; + impl.safe_cancellation_thread_id_ = 0; + } +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_HANDLE_SERVICE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.hpp new file mode 100644 index 0000000..cccff70 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.hpp @@ -0,0 +1,117 @@ +// +// detail/impl/win_iocp_io_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_IO_SERVICE_HPP +#define BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_IO_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/asio/detail/call_stack.hpp> +#include <boost/asio/detail/completion_handler.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Handler> +void win_iocp_io_service::dispatch(Handler handler) +{ + if (call_stack<win_iocp_io_service>::contains(this)) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler); + } + else + post(handler); +} + +template <typename Handler> +void win_iocp_io_service::post(Handler handler) +{ + // Allocate and construct an operation to wrap the handler. + typedef completion_handler<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + post_immediate_completion(p.p); + p.v = p.p = 0; +} + +template <typename Time_Traits> +void win_iocp_io_service::add_timer_queue( + timer_queue<Time_Traits>& queue) +{ + do_add_timer_queue(queue); +} + +template <typename Time_Traits> +void win_iocp_io_service::remove_timer_queue( + timer_queue<Time_Traits>& queue) +{ + do_remove_timer_queue(queue); +} + +template <typename Time_Traits> +void win_iocp_io_service::schedule_timer(timer_queue<Time_Traits>& queue, + const typename Time_Traits::time_type& time, + typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op) +{ + // If the service has been shut down we silently discard the timer. + if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) + { + post_immediate_completion(op); + return; + } + + mutex::scoped_lock lock(dispatch_mutex_); + + bool earliest = queue.enqueue_timer(time, timer, op); + work_started(); + if (earliest) + update_timeout(); +} + +template <typename Time_Traits> +std::size_t win_iocp_io_service::cancel_timer(timer_queue<Time_Traits>& queue, + typename timer_queue<Time_Traits>::per_timer_data& timer) +{ + // If the service has been shut down we silently ignore the cancellation. + if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) + return 0; + + mutex::scoped_lock lock(dispatch_mutex_); + op_queue<win_iocp_operation> ops; + std::size_t n = queue.cancel_timer(timer, ops); + post_deferred_completions(ops); + return n; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_IO_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.ipp new file mode 100644 index 0000000..08b81e9 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.ipp @@ -0,0 +1,499 @@ +// +// detail/impl/win_iocp_io_service.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_IO_SERVICE_IPP +#define BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_IO_SERVICE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/limits.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/detail/win_iocp_io_service.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +struct win_iocp_io_service::work_finished_on_block_exit +{ + ~work_finished_on_block_exit() + { + io_service_->work_finished(); + } + + win_iocp_io_service* io_service_; +}; + +struct win_iocp_io_service::timer_thread_function +{ + void operator()() + { + while (::InterlockedExchangeAdd(&io_service_->shutdown_, 0) == 0) + { + if (::WaitForSingleObject(io_service_->waitable_timer_.handle, + INFINITE) == WAIT_OBJECT_0) + { + ::InterlockedExchange(&io_service_->dispatch_required_, 1); + ::PostQueuedCompletionStatus(io_service_->iocp_.handle, + 0, wake_for_dispatch, 0); + } + } + } + + win_iocp_io_service* io_service_; +}; + +win_iocp_io_service::win_iocp_io_service(boost::asio::io_service& io_service) + : boost::asio::detail::service_base<win_iocp_io_service>(io_service), + iocp_(), + outstanding_work_(0), + stopped_(0), + shutdown_(0), + dispatch_required_(0) +{ +} + +void win_iocp_io_service::init(size_t concurrency_hint) +{ + iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, + static_cast<DWORD>((std::min<size_t>)(concurrency_hint, DWORD(~0)))); + if (!iocp_.handle) + { + DWORD last_error = ::GetLastError(); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "iocp"); + } +} + +void win_iocp_io_service::shutdown_service() +{ + ::InterlockedExchange(&shutdown_, 1); + + if (timer_thread_) + { + LARGE_INTEGER timeout; + timeout.QuadPart = 1; + ::SetWaitableTimer(waitable_timer_.handle, &timeout, 1, 0, 0, FALSE); + } + + while (::InterlockedExchangeAdd(&outstanding_work_, 0) > 0) + { + op_queue<win_iocp_operation> ops; + timer_queues_.get_all_timers(ops); + ops.push(completed_ops_); + if (!ops.empty()) + { + while (win_iocp_operation* op = ops.front()) + { + ops.pop(); + ::InterlockedDecrement(&outstanding_work_); + op->destroy(); + } + } + else + { + DWORD bytes_transferred = 0; + dword_ptr_t completion_key = 0; + LPOVERLAPPED overlapped = 0; + ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, + &completion_key, &overlapped, gqcs_timeout); + if (overlapped) + { + ::InterlockedDecrement(&outstanding_work_); + static_cast<win_iocp_operation*>(overlapped)->destroy(); + } + } + } + + if (timer_thread_) + timer_thread_->join(); +} + +boost::system::error_code win_iocp_io_service::register_handle( + HANDLE handle, boost::system::error_code& ec) +{ + if (::CreateIoCompletionPort(handle, iocp_.handle, 0, 0) == 0) + { + DWORD last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + } + else + { + ec = boost::system::error_code(); + } + return ec; +} + +size_t win_iocp_io_service::run(boost::system::error_code& ec) +{ + if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) + { + stop(); + ec = boost::system::error_code(); + return 0; + } + + call_stack<win_iocp_io_service>::context ctx(this); + + size_t n = 0; + while (do_one(true, ec)) + if (n != (std::numeric_limits<size_t>::max)()) + ++n; + return n; +} + +size_t win_iocp_io_service::run_one(boost::system::error_code& ec) +{ + if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) + { + stop(); + ec = boost::system::error_code(); + return 0; + } + + call_stack<win_iocp_io_service>::context ctx(this); + + return do_one(true, ec); +} + +size_t win_iocp_io_service::poll(boost::system::error_code& ec) +{ + if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) + { + stop(); + ec = boost::system::error_code(); + return 0; + } + + call_stack<win_iocp_io_service>::context ctx(this); + + size_t n = 0; + while (do_one(false, ec)) + if (n != (std::numeric_limits<size_t>::max)()) + ++n; + return n; +} + +size_t win_iocp_io_service::poll_one(boost::system::error_code& ec) +{ + if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) + { + stop(); + ec = boost::system::error_code(); + return 0; + } + + call_stack<win_iocp_io_service>::context ctx(this); + + return do_one(false, ec); +} + +void win_iocp_io_service::stop() +{ + if (::InterlockedExchange(&stopped_, 1) == 0) + { + if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) + { + DWORD last_error = ::GetLastError(); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "pqcs"); + } + } +} + +void win_iocp_io_service::post_deferred_completion(win_iocp_operation* op) +{ + // Flag the operation as ready. + op->ready_ = 1; + + // Enqueue the operation on the I/O completion port. + if (!::PostQueuedCompletionStatus(iocp_.handle, + 0, overlapped_contains_result, op)) + { + // Out of resources. Put on completed queue instead. + mutex::scoped_lock lock(dispatch_mutex_); + completed_ops_.push(op); + ::InterlockedExchange(&dispatch_required_, 1); + } +} + +void win_iocp_io_service::post_deferred_completions( + op_queue<win_iocp_operation>& ops) +{ + while (win_iocp_operation* op = ops.front()) + { + ops.pop(); + + // Flag the operation as ready. + op->ready_ = 1; + + // Enqueue the operation on the I/O completion port. + if (!::PostQueuedCompletionStatus(iocp_.handle, + 0, overlapped_contains_result, op)) + { + // Out of resources. Put on completed queue instead. + mutex::scoped_lock lock(dispatch_mutex_); + completed_ops_.push(op); + completed_ops_.push(ops); + ::InterlockedExchange(&dispatch_required_, 1); + } + } +} + +void win_iocp_io_service::on_pending(win_iocp_operation* op) +{ + if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1) + { + // Enqueue the operation on the I/O completion port. + if (!::PostQueuedCompletionStatus(iocp_.handle, + 0, overlapped_contains_result, op)) + { + // Out of resources. Put on completed queue instead. + mutex::scoped_lock lock(dispatch_mutex_); + completed_ops_.push(op); + ::InterlockedExchange(&dispatch_required_, 1); + } + } +} + +void win_iocp_io_service::on_completion(win_iocp_operation* op, + DWORD last_error, DWORD bytes_transferred) +{ + // Flag that the operation is ready for invocation. + op->ready_ = 1; + + // Store results in the OVERLAPPED structure. + op->Internal = reinterpret_cast<ulong_ptr_t>( + &boost::asio::error::get_system_category()); + op->Offset = last_error; + op->OffsetHigh = bytes_transferred; + + // Enqueue the operation on the I/O completion port. + if (!::PostQueuedCompletionStatus(iocp_.handle, + 0, overlapped_contains_result, op)) + { + // Out of resources. Put on completed queue instead. + mutex::scoped_lock lock(dispatch_mutex_); + completed_ops_.push(op); + ::InterlockedExchange(&dispatch_required_, 1); + } +} + +void win_iocp_io_service::on_completion(win_iocp_operation* op, + const boost::system::error_code& ec, DWORD bytes_transferred) +{ + // Flag that the operation is ready for invocation. + op->ready_ = 1; + + // Store results in the OVERLAPPED structure. + op->Internal = reinterpret_cast<ulong_ptr_t>(&ec.category()); + op->Offset = ec.value(); + op->OffsetHigh = bytes_transferred; + + // Enqueue the operation on the I/O completion port. + if (!::PostQueuedCompletionStatus(iocp_.handle, + 0, overlapped_contains_result, op)) + { + // Out of resources. Put on completed queue instead. + mutex::scoped_lock lock(dispatch_mutex_); + completed_ops_.push(op); + ::InterlockedExchange(&dispatch_required_, 1); + } +} + +size_t win_iocp_io_service::do_one(bool block, boost::system::error_code& ec) +{ + for (;;) + { + // Try to acquire responsibility for dispatching timers and completed ops. + if (::InterlockedCompareExchange(&dispatch_required_, 0, 1) == 1) + { + mutex::scoped_lock lock(dispatch_mutex_); + + // Dispatch pending timers and operations. + op_queue<win_iocp_operation> ops; + ops.push(completed_ops_); + timer_queues_.get_ready_timers(ops); + post_deferred_completions(ops); + update_timeout(); + } + + // Get the next operation from the queue. + DWORD bytes_transferred = 0; + dword_ptr_t completion_key = 0; + LPOVERLAPPED overlapped = 0; + ::SetLastError(0); + BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, + &completion_key, &overlapped, block ? gqcs_timeout : 0); + DWORD last_error = ::GetLastError(); + + if (overlapped) + { + win_iocp_operation* op = static_cast<win_iocp_operation*>(overlapped); + boost::system::error_code result_ec(last_error, + boost::asio::error::get_system_category()); + + // We may have been passed the last_error and bytes_transferred in the + // OVERLAPPED structure itself. + if (completion_key == overlapped_contains_result) + { + result_ec = boost::system::error_code(static_cast<int>(op->Offset), + *reinterpret_cast<boost::system::error_category*>(op->Internal)); + bytes_transferred = op->OffsetHigh; + } + + // Otherwise ensure any result has been saved into the OVERLAPPED + // structure. + else + { + op->Internal = reinterpret_cast<ulong_ptr_t>(&result_ec.category()); + op->Offset = result_ec.value(); + op->OffsetHigh = bytes_transferred; + } + + // Dispatch the operation only if ready. The operation may not be ready + // if the initiating function (e.g. a call to WSARecv) has not yet + // returned. This is because the initiating function still wants access + // to the operation's OVERLAPPED structure. + if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1) + { + // Ensure the count of outstanding work is decremented on block exit. + work_finished_on_block_exit on_exit = { this }; + (void)on_exit; + + op->complete(*this, result_ec, bytes_transferred); + ec = boost::system::error_code(); + return 1; + } + } + else if (!ok) + { + if (last_error != WAIT_TIMEOUT) + { + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return 0; + } + + // If we're not polling we need to keep going until we get a real handler. + if (block) + continue; + + ec = boost::system::error_code(); + return 0; + } + else if (completion_key == wake_for_dispatch) + { + // We have been woken up to try to acquire responsibility for dispatching + // timers and completed operations. + } + else + { + // The stopped_ flag is always checked to ensure that any leftover + // interrupts from a previous run invocation are ignored. + if (::InterlockedExchangeAdd(&stopped_, 0) != 0) + { + // Wake up next thread that is blocked on GetQueuedCompletionStatus. + if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) + { + last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return 0; + } + + ec = boost::system::error_code(); + return 0; + } + } + } +} + +void win_iocp_io_service::do_add_timer_queue(timer_queue_base& queue) +{ + mutex::scoped_lock lock(dispatch_mutex_); + + timer_queues_.insert(&queue); + + if (!waitable_timer_.handle) + { + waitable_timer_.handle = ::CreateWaitableTimer(0, FALSE, 0); + if (waitable_timer_.handle == 0) + { + DWORD last_error = ::GetLastError(); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "timer"); + } + + LARGE_INTEGER timeout; + timeout.QuadPart = -max_timeout_usec; + timeout.QuadPart *= 10; + ::SetWaitableTimer(waitable_timer_.handle, + &timeout, max_timeout_msec, 0, 0, FALSE); + } + + if (!timer_thread_) + { + timer_thread_function thread_function = { this }; + timer_thread_.reset(new thread(thread_function, 65536)); + } +} + +void win_iocp_io_service::do_remove_timer_queue(timer_queue_base& queue) +{ + mutex::scoped_lock lock(dispatch_mutex_); + + timer_queues_.erase(&queue); +} + +void win_iocp_io_service::update_timeout() +{ + if (timer_thread_) + { + // There's no point updating the waitable timer if the new timeout period + // exceeds the maximum timeout. In that case, we might as well wait for the + // existing period of the timer to expire. + long timeout_usec = timer_queues_.wait_duration_usec(max_timeout_usec); + if (timeout_usec < max_timeout_usec) + { + LARGE_INTEGER timeout; + timeout.QuadPart = -timeout_usec; + timeout.QuadPart *= 10; + ::SetWaitableTimer(waitable_timer_.handle, + &timeout, max_timeout_msec, 0, 0, FALSE); + } + } +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_IO_SERVICE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_serial_port_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_serial_port_service.ipp new file mode 100644 index 0000000..bd2310c --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_serial_port_service.ipp @@ -0,0 +1,182 @@ +// +// detail/impl/win_iocp_serial_port_service.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP +#define BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) && defined(BOOST_ASIO_HAS_SERIAL_PORT) + +#include <cstring> +#include <boost/asio/detail/win_iocp_serial_port_service.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +win_iocp_serial_port_service::win_iocp_serial_port_service( + boost::asio::io_service& io_service) + : handle_service_(io_service) +{ +} + +void win_iocp_serial_port_service::shutdown_service() +{ +} + +boost::system::error_code win_iocp_serial_port_service::open( + win_iocp_serial_port_service::implementation_type& impl, + const std::string& device, boost::system::error_code& ec) +{ + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + // For convenience, add a leading \\.\ sequence if not already present. + std::string name = (device[0] == '\\') ? device : "\\\\.\\" + device; + + // Open a handle to the serial port. + ::HANDLE handle = ::CreateFileA(name.c_str(), + GENERIC_READ | GENERIC_WRITE, 0, 0, + OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); + if (handle == INVALID_HANDLE_VALUE) + { + DWORD last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return ec; + } + + // Determine the initial serial port parameters. + using namespace std; // For memset. + ::DCB dcb; + memset(&dcb, 0, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + if (!::GetCommState(handle, &dcb)) + { + DWORD last_error = ::GetLastError(); + ::CloseHandle(handle); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return ec; + } + + // Set some default serial port parameters. This implementation does not + // support changing these, so they might as well be in a known state. + dcb.fBinary = TRUE; // Win32 only supports binary mode. + dcb.fDsrSensitivity = FALSE; + dcb.fNull = FALSE; // Do not ignore NULL characters. + dcb.fAbortOnError = FALSE; // Ignore serial framing errors. + if (!::SetCommState(handle, &dcb)) + { + DWORD last_error = ::GetLastError(); + ::CloseHandle(handle); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return ec; + } + + // Set up timeouts so that the serial port will behave similarly to a + // network socket. Reads wait for at least one byte, then return with + // whatever they have. Writes return once everything is out the door. + ::COMMTIMEOUTS timeouts; + timeouts.ReadIntervalTimeout = 1; + timeouts.ReadTotalTimeoutMultiplier = 0; + timeouts.ReadTotalTimeoutConstant = 0; + timeouts.WriteTotalTimeoutMultiplier = 0; + timeouts.WriteTotalTimeoutConstant = 0; + if (!::SetCommTimeouts(handle, &timeouts)) + { + DWORD last_error = ::GetLastError(); + ::CloseHandle(handle); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return ec; + } + + // We're done. Take ownership of the serial port handle. + if (handle_service_.assign(impl, handle, ec)) + ::CloseHandle(handle); + return ec; +} + +boost::system::error_code win_iocp_serial_port_service::do_set_option( + win_iocp_serial_port_service::implementation_type& impl, + win_iocp_serial_port_service::store_function_type store, + const void* option, boost::system::error_code& ec) +{ + using namespace std; // For memcpy. + + ::DCB dcb; + memset(&dcb, 0, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + if (!::GetCommState(handle_service_.native(impl), &dcb)) + { + DWORD last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return ec; + } + + if (store(option, dcb, ec)) + return ec; + + if (!::SetCommState(handle_service_.native(impl), &dcb)) + { + DWORD last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return ec; + } + + ec = boost::system::error_code(); + return ec; +} + +boost::system::error_code win_iocp_serial_port_service::do_get_option( + const win_iocp_serial_port_service::implementation_type& impl, + win_iocp_serial_port_service::load_function_type load, + void* option, boost::system::error_code& ec) const +{ + using namespace std; // For memset. + + ::DCB dcb; + memset(&dcb, 0, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + if (!::GetCommState(handle_service_.native(impl), &dcb)) + { + DWORD last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return ec; + } + + return load(option, dcb, ec); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) && defined(BOOST_ASIO_HAS_SERIAL_PORT) + +#endif // BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_socket_service_base.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_socket_service_base.ipp new file mode 100644 index 0000000..e301658 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_socket_service_base.ipp @@ -0,0 +1,577 @@ +// +// detail/impl/win_iocp_socket_service_base.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SOCKET_SERVICE_BASE_IPP +#define BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SOCKET_SERVICE_BASE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/asio/detail/win_iocp_socket_service_base.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +win_iocp_socket_service_base::win_iocp_socket_service_base( + boost::asio::io_service& io_service) + : io_service_(io_service), + iocp_service_(use_service<win_iocp_io_service>(io_service)), + reactor_(0), + mutex_(), + impl_list_(0) +{ +} + +void win_iocp_socket_service_base::shutdown_service() +{ + // Close all implementations, causing all operations to complete. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + base_implementation_type* impl = impl_list_; + while (impl) + { + boost::system::error_code ignored_ec; + close_for_destruction(*impl); + impl = impl->next_; + } +} + +void win_iocp_socket_service_base::construct( + win_iocp_socket_service_base::base_implementation_type& impl) +{ + impl.socket_ = invalid_socket; + impl.state_ = 0; + impl.cancel_token_.reset(); +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + impl.safe_cancellation_thread_id_ = 0; +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + + // Insert implementation into linked list of all implementations. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + impl.next_ = impl_list_; + impl.prev_ = 0; + if (impl_list_) + impl_list_->prev_ = &impl; + impl_list_ = &impl; +} + +void win_iocp_socket_service_base::destroy( + win_iocp_socket_service_base::base_implementation_type& impl) +{ + close_for_destruction(impl); + + // Remove implementation from linked list of all implementations. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (impl_list_ == &impl) + impl_list_ = impl.next_; + if (impl.prev_) + impl.prev_->next_ = impl.next_; + if (impl.next_) + impl.next_->prev_= impl.prev_; + impl.next_ = 0; + impl.prev_ = 0; +} + +boost::system::error_code win_iocp_socket_service_base::close( + win_iocp_socket_service_base::base_implementation_type& impl, + boost::system::error_code& ec) +{ + if (is_open(impl)) + { + // Check if the reactor was created, in which case we need to close the + // socket on the reactor as well to cancel any operations that might be + // running there. + reactor* r = static_cast<reactor*>( + interlocked_compare_exchange_pointer( + reinterpret_cast<void**>(&reactor_), 0, 0)); + if (r) + r->close_descriptor(impl.socket_, impl.reactor_data_); + } + + if (socket_ops::close(impl.socket_, impl.state_, false, ec) == 0) + { + impl.socket_ = invalid_socket; + impl.state_ = 0; + impl.cancel_token_.reset(); +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + impl.safe_cancellation_thread_id_ = 0; +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + } + + return ec; +} + +boost::system::error_code win_iocp_socket_service_base::cancel( + win_iocp_socket_service_base::base_implementation_type& impl, + boost::system::error_code& ec) +{ + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress( + ::GetModuleHandleA("KERNEL32"), "CancelIoEx")) + { + // The version of Windows supports cancellation from any thread. + typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED); + cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr; + socket_type sock = impl.socket_; + HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock); + if (!cancel_io_ex(sock_as_handle, 0)) + { + DWORD last_error = ::GetLastError(); + if (last_error == ERROR_NOT_FOUND) + { + // ERROR_NOT_FOUND means that there were no operations to be + // cancelled. We swallow this error to match the behaviour on other + // platforms. + ec = boost::system::error_code(); + } + else + { + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + } + } + else + { + ec = boost::system::error_code(); + } + } +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + else if (impl.safe_cancellation_thread_id_ == 0) + { + // No operations have been started, so there's nothing to cancel. + ec = boost::system::error_code(); + } + else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId()) + { + // Asynchronous operations have been started from the current thread only, + // so it is safe to try to cancel them using CancelIo. + socket_type sock = impl.socket_; + HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock); + if (!::CancelIo(sock_as_handle)) + { + DWORD last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + } + else + { + ec = boost::system::error_code(); + } + } + else + { + // Asynchronous operations have been started from more than one thread, + // so cancellation is not safe. + ec = boost::asio::error::operation_not_supported; + } +#else // defined(BOOST_ASIO_ENABLE_CANCELIO) + else + { + // Cancellation is not supported as CancelIo may not be used. + ec = boost::asio::error::operation_not_supported; + } +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + + // Cancel any operations started via the reactor. + if (!ec) + { + reactor* r = static_cast<reactor*>( + interlocked_compare_exchange_pointer( + reinterpret_cast<void**>(&reactor_), 0, 0)); + if (r) + r->cancel_ops(impl.socket_, impl.reactor_data_); + } + + return ec; +} + +boost::system::error_code win_iocp_socket_service_base::do_open( + win_iocp_socket_service_base::base_implementation_type& impl, + int family, int type, int protocol, boost::system::error_code& ec) +{ + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + socket_holder sock(socket_ops::socket(family, type, protocol, ec)); + if (sock.get() == invalid_socket) + return ec; + + HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock.get()); + if (iocp_service_.register_handle(sock_as_handle, ec)) + return ec; + + impl.socket_ = sock.release(); + switch (type) + { + case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; + case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; + default: impl.state_ = 0; break; + } + impl.cancel_token_.reset(static_cast<void*>(0), socket_ops::noop_deleter()); + ec = boost::system::error_code(); + return ec; +} + +boost::system::error_code win_iocp_socket_service_base::do_assign( + win_iocp_socket_service_base::base_implementation_type& impl, + int type, socket_type native_socket, boost::system::error_code& ec) +{ + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + HANDLE sock_as_handle = reinterpret_cast<HANDLE>(native_socket); + if (iocp_service_.register_handle(sock_as_handle, ec)) + return ec; + + impl.socket_ = native_socket; + switch (type) + { + case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; + case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; + default: impl.state_ = 0; break; + } + impl.cancel_token_.reset(static_cast<void*>(0), socket_ops::noop_deleter()); + ec = boost::system::error_code(); + return ec; +} + +void win_iocp_socket_service_base::start_send_op( + win_iocp_socket_service_base::base_implementation_type& impl, + WSABUF* buffers, std::size_t buffer_count, + socket_base::message_flags flags, bool noop, operation* op) +{ + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (noop) + iocp_service_.on_completion(op); + else if (!is_open(impl)) + iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); + else + { + DWORD bytes_transferred = 0; + int result = ::WSASend(impl.socket_, buffers, + static_cast<DWORD>(buffer_count), &bytes_transferred, flags, op, 0); + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + if (result != 0 && last_error != WSA_IO_PENDING) + iocp_service_.on_completion(op, last_error, bytes_transferred); + else + iocp_service_.on_pending(op); + } +} + +void win_iocp_socket_service_base::start_send_to_op( + win_iocp_socket_service_base::base_implementation_type& impl, + WSABUF* buffers, std::size_t buffer_count, + const socket_addr_type* addr, int addrlen, + socket_base::message_flags flags, operation* op) +{ + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (!is_open(impl)) + iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); + else + { + DWORD bytes_transferred = 0; + int result = ::WSASendTo(impl.socket_, buffers, + static_cast<DWORD>(buffer_count), + &bytes_transferred, flags, addr, addrlen, op, 0); + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + if (result != 0 && last_error != WSA_IO_PENDING) + iocp_service_.on_completion(op, last_error, bytes_transferred); + else + iocp_service_.on_pending(op); + } +} + +void win_iocp_socket_service_base::start_receive_op( + win_iocp_socket_service_base::base_implementation_type& impl, + WSABUF* buffers, std::size_t buffer_count, + socket_base::message_flags flags, bool noop, operation* op) +{ + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (noop) + iocp_service_.on_completion(op); + else if (!is_open(impl)) + iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); + else + { + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int result = ::WSARecv(impl.socket_, buffers, + static_cast<DWORD>(buffer_count), + &bytes_transferred, &recv_flags, op, 0); + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_NETNAME_DELETED) + last_error = WSAECONNRESET; + else if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + if (result != 0 && last_error != WSA_IO_PENDING) + iocp_service_.on_completion(op, last_error, bytes_transferred); + else + iocp_service_.on_pending(op); + } +} + +void win_iocp_socket_service_base::start_null_buffers_receive_op( + win_iocp_socket_service_base::base_implementation_type& impl, + socket_base::message_flags flags, reactor_op* op) +{ + if ((impl.state_ & socket_ops::stream_oriented) != 0) + { + // For stream sockets on Windows, we may issue a 0-byte overlapped + // WSARecv to wait until there is data available on the socket. + ::WSABUF buf = { 0, 0 }; + start_receive_op(impl, &buf, 1, flags, false, op); + } + else + { + start_reactor_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + op); + } +} + +void win_iocp_socket_service_base::start_receive_from_op( + win_iocp_socket_service_base::base_implementation_type& impl, + WSABUF* buffers, std::size_t buffer_count, socket_addr_type* addr, + socket_base::message_flags flags, int* addrlen, operation* op) +{ + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (!is_open(impl)) + iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); + else + { + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int result = ::WSARecvFrom(impl.socket_, buffers, + static_cast<DWORD>(buffer_count), + &bytes_transferred, &recv_flags, addr, addrlen, op, 0); + DWORD last_error = ::WSAGetLastError(); + if (last_error == ERROR_PORT_UNREACHABLE) + last_error = WSAECONNREFUSED; + if (result != 0 && last_error != WSA_IO_PENDING) + iocp_service_.on_completion(op, last_error, bytes_transferred); + else + iocp_service_.on_pending(op); + } +} + +void win_iocp_socket_service_base::start_accept_op( + win_iocp_socket_service_base::base_implementation_type& impl, + bool peer_is_open, socket_holder& new_socket, int family, int type, + int protocol, void* output_buffer, DWORD address_length, operation* op) +{ + update_cancellation_thread_id(impl); + iocp_service_.work_started(); + + if (!is_open(impl)) + iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); + else if (peer_is_open) + iocp_service_.on_completion(op, boost::asio::error::already_open); + else + { + boost::system::error_code ec; + new_socket.reset(socket_ops::socket(family, type, protocol, ec)); + if (new_socket.get() == invalid_socket) + iocp_service_.on_completion(op, ec); + else + { + DWORD bytes_read = 0; + BOOL result = ::AcceptEx(impl.socket_, new_socket.get(), output_buffer, + 0, address_length, address_length, &bytes_read, op); + DWORD last_error = ::WSAGetLastError(); + if (!result && last_error != WSA_IO_PENDING) + iocp_service_.on_completion(op, last_error); + else + iocp_service_.on_pending(op); + } + } +} + +void win_iocp_socket_service_base::restart_accept_op( + socket_type s, socket_holder& new_socket, int family, int type, + int protocol, void* output_buffer, DWORD address_length, operation* op) +{ + new_socket.reset(); + iocp_service_.work_started(); + + boost::system::error_code ec; + new_socket.reset(socket_ops::socket(family, type, protocol, ec)); + if (new_socket.get() == invalid_socket) + iocp_service_.on_completion(op, ec); + else + { + DWORD bytes_read = 0; + BOOL result = ::AcceptEx(s, new_socket.get(), output_buffer, + 0, address_length, address_length, &bytes_read, op); + DWORD last_error = ::WSAGetLastError(); + if (!result && last_error != WSA_IO_PENDING) + iocp_service_.on_completion(op, last_error); + else + iocp_service_.on_pending(op); + } +} + +void win_iocp_socket_service_base::start_reactor_op( + win_iocp_socket_service_base::base_implementation_type& impl, + int op_type, reactor_op* op) +{ + reactor& r = get_reactor(); + update_cancellation_thread_id(impl); + + if (is_open(impl)) + { + r.start_op(op_type, impl.socket_, impl.reactor_data_, op, false); + return; + } + else + op->ec_ = boost::asio::error::bad_descriptor; + + iocp_service_.post_immediate_completion(op); +} + +void win_iocp_socket_service_base::start_connect_op( + win_iocp_socket_service_base::base_implementation_type& impl, + reactor_op* op, const socket_addr_type* addr, std::size_t addrlen) +{ + reactor& r = get_reactor(); + update_cancellation_thread_id(impl); + + if ((impl.state_ & socket_ops::non_blocking) != 0 + || socket_ops::set_internal_non_blocking( + impl.socket_, impl.state_, op->ec_)) + { + if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) + { + if (op->ec_ == boost::asio::error::in_progress + || op->ec_ == boost::asio::error::would_block) + { + op->ec_ = boost::system::error_code(); + r.start_op(reactor::connect_op, impl.socket_, + impl.reactor_data_, op, false); + return; + } + } + } + + r.post_immediate_completion(op); +} + +void win_iocp_socket_service_base::close_for_destruction( + win_iocp_socket_service_base::base_implementation_type& impl) +{ + if (is_open(impl)) + { + // Check if the reactor was created, in which case we need to close the + // socket on the reactor as well to cancel any operations that might be + // running there. + reactor* r = static_cast<reactor*>( + interlocked_compare_exchange_pointer( + reinterpret_cast<void**>(&reactor_), 0, 0)); + if (r) + r->close_descriptor(impl.socket_, impl.reactor_data_); + } + + boost::system::error_code ignored_ec; + socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); + impl.socket_ = invalid_socket; + impl.state_ = 0; + impl.cancel_token_.reset(); +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + impl.safe_cancellation_thread_id_ = 0; +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) +} + +void win_iocp_socket_service_base::update_cancellation_thread_id( + win_iocp_socket_service_base::base_implementation_type& impl) +{ +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + if (impl.safe_cancellation_thread_id_ == 0) + impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); + else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) + impl.safe_cancellation_thread_id_ = ~DWORD(0); +#else // defined(BOOST_ASIO_ENABLE_CANCELIO) + (void)impl; +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) +} + +reactor& win_iocp_socket_service_base::get_reactor() +{ + reactor* r = static_cast<reactor*>( + interlocked_compare_exchange_pointer( + reinterpret_cast<void**>(&reactor_), 0, 0)); + if (!r) + { + r = &(use_service<reactor>(io_service_)); + interlocked_exchange_pointer(reinterpret_cast<void**>(&reactor_), r); + } + return *r; +} + +void* win_iocp_socket_service_base::interlocked_compare_exchange_pointer( + void** dest, void* exch, void* cmp) +{ +#if defined(_M_IX86) + return reinterpret_cast<void*>(InterlockedCompareExchange( + reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(exch), + reinterpret_cast<LONG>(cmp))); +#else + return InterlockedCompareExchangePointer(dest, exch, cmp); +#endif +} + +void* win_iocp_socket_service_base::interlocked_exchange_pointer( + void** dest, void* val) +{ +#if defined(_M_IX86) + return reinterpret_cast<void*>(InterlockedExchange( + reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(val))); +#else + return InterlockedExchangePointer(dest, val); +#endif +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SOCKET_SERVICE_BASE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_mutex.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_mutex.ipp new file mode 100644 index 0000000..65ffb3b --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_mutex.ipp @@ -0,0 +1,80 @@ +// +// detail/impl/win_mutex.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_WIN_MUTEX_IPP +#define BOOST_ASIO_DETAIL_IMPL_WIN_MUTEX_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_WINDOWS) + +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/detail/win_mutex.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +win_mutex::win_mutex() +{ + int error = do_init(); + boost::system::error_code ec(error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "mutex"); +} + +int win_mutex::do_init() +{ +#if defined(__MINGW32__) + // Not sure if MinGW supports structured exception handling, so for now + // we'll just call the Windows API and hope. +# if defined(UNDER_CE) + ::InitializeCriticalSection(&crit_section_); +# else + if (!::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000)) + return ::GetLastError(); +# endif + return 0; +#else + __try + { +# if defined(UNDER_CE) + ::InitializeCriticalSection(&crit_section_); +# else + if (!::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000)) + return ::GetLastError(); +# endif + } + __except(GetExceptionCode() == STATUS_NO_MEMORY + ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) + { + return ERROR_OUTOFMEMORY; + } + + return 0; +#endif +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_WINDOWS) + +#endif // BOOST_ASIO_DETAIL_IMPL_WIN_MUTEX_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_thread.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_thread.ipp new file mode 100644 index 0000000..22d2300 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_thread.ipp @@ -0,0 +1,140 @@ +// +// detail/impl/win_thread.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_WIN_THREAD_IPP +#define BOOST_ASIO_DETAIL_IMPL_WIN_THREAD_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_WINDOWS) && !defined(UNDER_CE) + +#include <process.h> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/detail/win_thread.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +win_thread::~win_thread() +{ + ::CloseHandle(thread_); + + // The exit_event_ handle is deliberately allowed to leak here since it + // is an error for the owner of an internal thread not to join() it. +} + +void win_thread::join() +{ + HANDLE handles[2] = { exit_event_, thread_ }; + ::WaitForMultipleObjects(2, handles, FALSE, INFINITE); + ::CloseHandle(exit_event_); + if (terminate_threads()) + { + ::TerminateThread(thread_, 0); + } + else + { + ::QueueUserAPC(apc_function, thread_, 0); + ::WaitForSingleObject(thread_, INFINITE); + } +} + +void win_thread::start_thread(func_base* arg, unsigned int stack_size) +{ + ::HANDLE entry_event = 0; + arg->entry_event_ = entry_event = ::CreateEvent(0, true, false, 0); + if (!entry_event) + { + DWORD last_error = ::GetLastError(); + delete arg; + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "thread.entry_event"); + } + + arg->exit_event_ = exit_event_ = ::CreateEvent(0, true, false, 0); + if (!exit_event_) + { + DWORD last_error = ::GetLastError(); + delete arg; + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "thread.exit_event"); + } + + unsigned int thread_id = 0; + thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0, + stack_size, win_thread_function, arg, 0, &thread_id)); + if (!thread_) + { + DWORD last_error = ::GetLastError(); + delete arg; + if (entry_event) + ::CloseHandle(entry_event); + if (exit_event_) + ::CloseHandle(exit_event_); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "thread"); + } + + if (entry_event) + { + ::WaitForSingleObject(entry_event, INFINITE); + ::CloseHandle(entry_event); + } +} + +unsigned int __stdcall win_thread_function(void* arg) +{ + std::auto_ptr<win_thread::func_base> func( + static_cast<win_thread::func_base*>(arg)); + + ::SetEvent(func->entry_event_); + + func->run(); + + // Signal that the thread has finished its work, but rather than returning go + // to sleep to put the thread into a well known state. If the thread is being + // joined during global object destruction then it may be killed using + // TerminateThread (to avoid a deadlock in DllMain). Otherwise, the SleepEx + // call will be interrupted using QueueUserAPC and the thread will shut down + // cleanly. + HANDLE exit_event = func->exit_event_; + func.reset(); + ::SetEvent(exit_event); + ::SleepEx(INFINITE, TRUE); + + return 0; +} + +#if defined(WINVER) && (WINVER < 0x0500) +void __stdcall apc_function(ULONG) {} +#else +void __stdcall apc_function(ULONG_PTR) {} +#endif + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE) + +#endif // BOOST_ASIO_DETAIL_IMPL_WIN_THREAD_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_tss_ptr.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_tss_ptr.ipp new file mode 100644 index 0000000..7da9be3 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_tss_ptr.ipp @@ -0,0 +1,59 @@ +// +// detail/impl/win_tss_ptr.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_WIN_TSS_PTR_IPP +#define BOOST_ASIO_DETAIL_IMPL_WIN_TSS_PTR_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_WINDOWS) + +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/detail/win_tss_ptr.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +DWORD win_tss_ptr_create() +{ +#if defined(UNDER_CE) + enum { out_of_indexes = 0xFFFFFFFF }; +#else + enum { out_of_indexes = TLS_OUT_OF_INDEXES }; +#endif + + DWORD tss_key = ::TlsAlloc(); + if (tss_key == out_of_indexes) + { + DWORD last_error = ::GetLastError(); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "tss"); + } + return tss_key; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_WINDOWS) + +#endif // BOOST_ASIO_DETAIL_IMPL_WIN_TSS_PTR_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/winsock_init.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/winsock_init.ipp new file mode 100644 index 0000000..082ea84 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/winsock_init.ipp @@ -0,0 +1,71 @@ +// +// detail/impl/winsock_init.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_WINSOCK_INIT_IPP +#define BOOST_ASIO_DETAIL_IMPL_WINSOCK_INIT_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/winsock_init.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +void winsock_init_base::startup(data& d, + unsigned char major, unsigned char minor) +{ + if (::InterlockedIncrement(&d.init_count_) == 1) + { + WSADATA wsa_data; + long result = ::WSAStartup(MAKEWORD(major, minor), &wsa_data); + ::InterlockedExchange(&d.result_, result); + } +} + +void winsock_init_base::cleanup(data& d) +{ + if (::InterlockedDecrement(&d.init_count_) == 0) + { + ::WSACleanup(); + } +} + +void winsock_init_base::throw_on_error(data& d) +{ + long result = ::InterlockedExchangeAdd(&d.result_, 0); + if (result != 0) + { + boost::system::error_code ec(result, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "winsock"); + } +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + +#endif // BOOST_ASIO_DETAIL_IMPL_WINSOCK_INIT_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/io_control.hpp b/3rdParty/Boost/src/boost/asio/detail/io_control.hpp index 5021c2e..cb02fee 100644 --- a/3rdParty/Boost/src/boost/asio/detail/io_control.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/io_control.hpp @@ -1,6 +1,6 @@ // -// io_control.hpp -// ~~~~~~~~~~~~~~ +// detail/io_control.hpp +// ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,15 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> #include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { diff --git a/3rdParty/Boost/src/boost/asio/detail/kqueue_reactor.hpp b/3rdParty/Boost/src/boost/asio/detail/kqueue_reactor.hpp index f33c985..eb2a243 100644 --- a/3rdParty/Boost/src/boost/asio/detail/kqueue_reactor.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/kqueue_reactor.hpp @@ -1,6 +1,6 @@ // -// kqueue_reactor.hpp -// ~~~~~~~~~~~~~~~~~~ +// detail/kqueue_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) @@ -16,41 +16,35 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/kqueue_reactor_fwd.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_KQUEUE) -#include <boost/asio/detail/push_options.hpp> #include <cstddef> #include <sys/types.h> #include <sys/event.h> #include <sys/time.h> -#include <boost/config.hpp> -#include <boost/throw_exception.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> -#include <boost/asio/io_service.hpp> -#include <boost/asio/detail/hash_map.hpp> +#include <boost/asio/detail/kqueue_reactor_fwd.hpp> #include <boost/asio/detail/mutex.hpp> +#include <boost/asio/detail/object_pool.hpp> #include <boost/asio/detail/op_queue.hpp> #include <boost/asio/detail/reactor_op.hpp> #include <boost/asio/detail/select_interrupter.hpp> -#include <boost/asio/detail/service_base.hpp> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/timer_op.hpp> #include <boost/asio/detail/timer_queue_base.hpp> #include <boost/asio/detail/timer_queue_fwd.hpp> #include <boost/asio/detail/timer_queue_set.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/io_service.hpp> // Older versions of Mac OS X may not define EV_OOBAND. #if !defined(EV_OOBAND) # define EV_OOBAND EV_FLAG1 #endif // !defined(EV_OOBAND) +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -65,384 +59,98 @@ public: // Per-descriptor queues. struct descriptor_state { - descriptor_state() {} - descriptor_state(const descriptor_state&) {} - void operator=(const descriptor_state&) {} - + friend class kqueue_reactor; + friend class object_pool_access; mutex mutex_; op_queue<reactor_op> op_queue_[max_ops]; bool shutdown_; + descriptor_state* next_; + descriptor_state* prev_; }; // Per-descriptor data. typedef descriptor_state* per_descriptor_data; // Constructor. - kqueue_reactor(boost::asio::io_service& io_service) - : boost::asio::detail::service_base<kqueue_reactor>(io_service), - io_service_(use_service<io_service_impl>(io_service)), - mutex_(), - kqueue_fd_(do_kqueue_create()), - interrupter_(), - shutdown_(false) - { - // The interrupter is put into a permanently readable state. Whenever we - // want to interrupt the blocked kevent call we register a one-shot read - // operation against the descriptor. - interrupter_.interrupt(); - } + BOOST_ASIO_DECL kqueue_reactor(boost::asio::io_service& io_service); // Destructor. - ~kqueue_reactor() - { - close(kqueue_fd_); - } + BOOST_ASIO_DECL ~kqueue_reactor(); // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - mutex::scoped_lock lock(mutex_); - shutdown_ = true; - lock.unlock(); - - op_queue<operation> ops; - - descriptor_map::iterator iter = registered_descriptors_.begin(); - descriptor_map::iterator end = registered_descriptors_.end(); - while (iter != end) - { - for (int i = 0; i < max_ops; ++i) - ops.push(iter->second.op_queue_[i]); - iter->second.shutdown_ = true; - ++iter; - } - - timer_queues_.get_all_timers(ops); - } + BOOST_ASIO_DECL void shutdown_service(); // Initialise the task. - void init_task() - { - io_service_.init_task(); - } + BOOST_ASIO_DECL void init_task(); // Register a socket with the reactor. Returns 0 on success, system error // code on failure. - int register_descriptor(socket_type descriptor, - per_descriptor_data& descriptor_data) - { - mutex::scoped_lock lock(registered_descriptors_mutex_); - - descriptor_map::iterator new_entry = registered_descriptors_.insert( - std::make_pair(descriptor, descriptor_state())).first; - descriptor_data = &new_entry->second; + BOOST_ASIO_DECL int register_descriptor(socket_type descriptor, + per_descriptor_data& descriptor_data); - descriptor_data->shutdown_ = false; - - return 0; + // Post a reactor operation for immediate completion. + void post_immediate_completion(reactor_op* op) + { + io_service_.post_immediate_completion(op); } // Start a new operation. The reactor operation will be performed when the // given descriptor is flagged as ready, or an error has occurred. - void start_op(int op_type, socket_type descriptor, + BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor, per_descriptor_data& descriptor_data, - reactor_op* op, bool allow_speculative) - { - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); - if (descriptor_data->shutdown_) - return; - - bool first = descriptor_data->op_queue_[op_type].empty(); - if (first) - { - if (allow_speculative) - { - if (op_type != read_op || descriptor_data->op_queue_[except_op].empty()) - { - if (op->perform()) - { - descriptor_lock.unlock(); - io_service_.post_immediate_completion(op); - return; - } - } - } - } - - descriptor_data->op_queue_[op_type].push(op); - io_service_.work_started(); - - if (first) - { - struct kevent event; - switch (op_type) - { - case read_op: - EV_SET(&event, descriptor, EVFILT_READ, - EV_ADD | EV_ONESHOT, 0, 0, descriptor_data); - break; - case write_op: - EV_SET(&event, descriptor, EVFILT_WRITE, - EV_ADD | EV_ONESHOT, 0, 0, descriptor_data); - break; - case except_op: - if (!descriptor_data->op_queue_[read_op].empty()) - return; // Already registered for read events. - EV_SET(&event, descriptor, EVFILT_READ, - EV_ADD | EV_ONESHOT, EV_OOBAND, 0, descriptor_data); - break; - } - - if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) - { - op->ec_ = boost::system::error_code(errno, - boost::asio::error::get_system_category()); - descriptor_data->op_queue_[op_type].pop(); - io_service_.post_deferred_completion(op); - } - } - } + reactor_op* op, bool allow_speculative); // Cancel all operations associated with the given descriptor. The // handlers associated with the descriptor will be invoked with the // operation_aborted error. - void cancel_ops(socket_type /*descriptor*/, per_descriptor_data& descriptor_data) - { - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); - - op_queue<operation> ops; - for (int i = 0; i < max_ops; ++i) - { - while (reactor_op* op = descriptor_data->op_queue_[i].front()) - { - op->ec_ = boost::asio::error::operation_aborted; - descriptor_data->op_queue_[i].pop(); - ops.push(op); - } - } - - descriptor_lock.unlock(); - - io_service_.post_deferred_completions(ops); - } + BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, + per_descriptor_data& descriptor_data); // Cancel any operations that are running against the descriptor and remove // its registration from the reactor. - void close_descriptor(socket_type descriptor, - per_descriptor_data& descriptor_data) - { - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); - mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); - - // Remove the descriptor from the set of known descriptors. The descriptor - // will be automatically removed from the kqueue set when it is closed. - descriptor_data->shutdown_ = true; - - op_queue<operation> ops; - for (int i = 0; i < max_ops; ++i) - { - while (reactor_op* op = descriptor_data->op_queue_[i].front()) - { - op->ec_ = boost::asio::error::operation_aborted; - descriptor_data->op_queue_[i].pop(); - ops.push(op); - } - } - - descriptor_lock.unlock(); - - registered_descriptors_.erase(descriptor); - - descriptors_lock.unlock(); - - io_service_.post_deferred_completions(ops); - } + BOOST_ASIO_DECL void close_descriptor(socket_type descriptor, + per_descriptor_data& descriptor_data); // Add a new timer queue to the reactor. template <typename Time_Traits> - void add_timer_queue(timer_queue<Time_Traits>& timer_queue) - { - mutex::scoped_lock lock(mutex_); - timer_queues_.insert(&timer_queue); - } + void add_timer_queue(timer_queue<Time_Traits>& queue); // Remove a timer queue from the reactor. template <typename Time_Traits> - void remove_timer_queue(timer_queue<Time_Traits>& timer_queue) - { - mutex::scoped_lock lock(mutex_); - timer_queues_.erase(&timer_queue); - } + void remove_timer_queue(timer_queue<Time_Traits>& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time. template <typename Time_Traits> - void schedule_timer(timer_queue<Time_Traits>& timer_queue, - const typename Time_Traits::time_type& time, timer_op* op, void* token) - { - mutex::scoped_lock lock(mutex_); - if (!shutdown_) - { - bool earliest = timer_queue.enqueue_timer(time, op, token); - io_service_.work_started(); - if (earliest) - interrupt(); - } - } + void schedule_timer(timer_queue<Time_Traits>& queue, + const typename Time_Traits::time_type& time, + typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched. template <typename Time_Traits> - std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token) - { - mutex::scoped_lock lock(mutex_); - op_queue<operation> ops; - std::size_t n = timer_queue.cancel_timer(token, ops); - lock.unlock(); - io_service_.post_deferred_completions(ops); - return n; - } + std::size_t cancel_timer(timer_queue<Time_Traits>& queue, + typename timer_queue<Time_Traits>::per_timer_data& timer); // Run the kqueue loop. - void run(bool block, op_queue<operation>& ops) - { - mutex::scoped_lock lock(mutex_); - - // Determine how long to block while waiting for events. - timespec timeout_buf = { 0, 0 }; - timespec* timeout = block ? get_timeout(timeout_buf) : &timeout_buf; - - lock.unlock(); - - // Block on the kqueue descriptor. - struct kevent events[128]; - int num_events = kevent(kqueue_fd_, 0, 0, events, 128, timeout); - - // Dispatch the waiting events. - for (int i = 0; i < num_events; ++i) - { - int descriptor = events[i].ident; - void* ptr = events[i].udata; - if (ptr == &interrupter_) - { - // No need to reset the interrupter since we're leaving the descriptor - // in a ready-to-read state and relying on one-shot notifications. - } - else - { - descriptor_state* descriptor_data = static_cast<descriptor_state*>(ptr); - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); - - // Exception operations must be processed first to ensure that any - // out-of-band data is read before normal data. - static const int filter[max_ops] = - { EVFILT_READ, EVFILT_WRITE, EVFILT_READ }; - for (int j = max_ops - 1; j >= 0; --j) - { - if (events[i].filter == filter[j]) - { - if (j != except_op || events[i].flags & EV_OOBAND) - { - while (reactor_op* op = descriptor_data->op_queue_[j].front()) - { - if (events[i].flags & EV_ERROR) - { - op->ec_ = boost::system::error_code(events[i].data, - boost::asio::error::get_system_category()); - descriptor_data->op_queue_[j].pop(); - ops.push(op); - } - if (op->perform()) - { - descriptor_data->op_queue_[j].pop(); - ops.push(op); - } - else - break; - } - } - } - } - - // Renew registration for event notifications. - struct kevent event; - switch (events[i].filter) - { - case EVFILT_READ: - if (!descriptor_data->op_queue_[read_op].empty()) - EV_SET(&event, descriptor, EVFILT_READ, - EV_ADD | EV_ONESHOT, 0, 0, descriptor_data); - else if (!descriptor_data->op_queue_[except_op].empty()) - EV_SET(&event, descriptor, EVFILT_READ, - EV_ADD | EV_ONESHOT, EV_OOBAND, 0, descriptor_data); - else - continue; - case EVFILT_WRITE: - if (!descriptor_data->op_queue_[write_op].empty()) - EV_SET(&event, descriptor, EVFILT_WRITE, - EV_ADD | EV_ONESHOT, 0, 0, descriptor_data); - else - continue; - default: - break; - } - if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) - { - boost::system::error_code error(errno, - boost::asio::error::get_system_category()); - for (int j = 0; j < max_ops; ++j) - { - while (reactor_op* op = descriptor_data->op_queue_[j].front()) - { - op->ec_ = error; - descriptor_data->op_queue_[j].pop(); - ops.push(op); - } - } - } - } - } - - lock.lock(); - timer_queues_.get_ready_timers(ops); - } + BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops); // Interrupt the kqueue loop. - void interrupt() - { - struct kevent event; - EV_SET(&event, interrupter_.read_descriptor(), - EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &interrupter_); - ::kevent(kqueue_fd_, &event, 1, 0, 0, 0); - } + BOOST_ASIO_DECL void interrupt(); private: // Create the kqueue file descriptor. Throws an exception if the descriptor // cannot be created. - static int do_kqueue_create() - { - int fd = kqueue(); - if (fd == -1) - { - boost::throw_exception( - boost::system::system_error( - boost::system::error_code(errno, - boost::asio::error::get_system_category()), - "kqueue")); - } - return fd; - } + BOOST_ASIO_DECL static int do_kqueue_create(); + + // Helper function to add a new timer queue. + BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); + + // Helper function to remove a timer queue. + BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); // Get the timeout value for the kevent call. - timespec* get_timeout(timespec& ts) - { - // By default we will wait no longer than 5 minutes. This will ensure that - // any changes to the system clock are detected after no longer than this. - long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000); - ts.tv_sec = usec / 1000000; - ts.tv_nsec = (usec % 1000000) * 1000; - return &ts; - } + BOOST_ASIO_DECL timespec* get_timeout(timespec& ts); // The io_service implementation used to post completions. io_service_impl& io_service_; @@ -465,23 +173,21 @@ private: // Mutex to protect access to the registered descriptors. mutex registered_descriptors_mutex_; - // Keep track of all registered descriptors. This code relies on the fact that - // the hash_map implementation pools deleted nodes, meaning that we can assume - // our descriptor_state pointer remains valid even after the entry is removed. - // Technically this is not true for C++98, as that standard says that spliced - // elements in a list are invalidated. However, C++0x fixes this shortcoming - // so we'll just assume that C++98 std::list implementations will do the right - // thing anyway. - typedef detail::hash_map<socket_type, descriptor_state> descriptor_map; - descriptor_map registered_descriptors_; + // Keep track of all registered descriptors. + object_pool<descriptor_state> registered_descriptors_; }; } // namespace detail } // namespace asio } // namespace boost -#endif // defined(BOOST_ASIO_HAS_KQUEUE) - #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/impl/kqueue_reactor.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/kqueue_reactor.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_ASIO_HAS_KQUEUE) + #endif // BOOST_ASIO_DETAIL_KQUEUE_REACTOR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/kqueue_reactor_fwd.hpp b/3rdParty/Boost/src/boost/asio/detail/kqueue_reactor_fwd.hpp index 0471c39..97f8c96 100644 --- a/3rdParty/Boost/src/boost/asio/detail/kqueue_reactor_fwd.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/kqueue_reactor_fwd.hpp @@ -1,6 +1,6 @@ // -// kqueue_reactor_fwd.hpp -// ~~~~~~~~~~~~~~~~~~~~~~ +// detail/kqueue_reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) @@ -16,15 +16,9 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#if !defined(BOOST_ASIO_DISABLE_KQUEUE) - -#if (defined(__MACH__) && defined(__APPLE__)) \ - || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - -// Define this to indicate that kqueue is supported on the target platform. -#define BOOST_ASIO_HAS_KQUEUE 1 +#if defined(BOOST_ASIO_HAS_KQUEUE) namespace boost { namespace asio { @@ -36,11 +30,6 @@ class kqueue_reactor; } // namespace asio } // namespace boost -#endif // (defined(__MACH__) && defined(__APPLE__)) - // || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - -#endif // !defined(BOOST_ASIO_DISABLE_KQUEUE) - -#include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_ASIO_HAS_KQUEUE) #endif // BOOST_ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/macos_fenced_block.hpp b/3rdParty/Boost/src/boost/asio/detail/macos_fenced_block.hpp index 496d7f0..a653aee 100644 --- a/3rdParty/Boost/src/boost/asio/detail/macos_fenced_block.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/macos_fenced_block.hpp @@ -1,6 +1,6 @@ // -// macos_fenced_block.hpp -// ~~~~~~~~~~~~~~~~~~~~~~ +// detail/macos_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,17 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if defined(__MACH__) && defined(__APPLE__) -#include <boost/asio/detail/push_options.hpp> #include <libkern/OSAtomic.h> -#include <boost/asio/detail/pop_options.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -52,8 +48,8 @@ public: } // namespace asio } // namespace boost -#endif // defined(__MACH__) && defined(__APPLE__) - #include <boost/asio/detail/pop_options.hpp> +#endif // defined(__MACH__) && defined(__APPLE__) + #endif // BOOST_ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/mutex.hpp b/3rdParty/Boost/src/boost/asio/detail/mutex.hpp index e804ec2..f601996 100644 --- a/3rdParty/Boost/src/boost/asio/detail/mutex.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/mutex.hpp @@ -1,6 +1,6 @@ // -// mutex.hpp -// ~~~~~~~~~ +// detail/mutex.hpp +// ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,11 +15,7 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) # include <boost/asio/detail/null_mutex.hpp> @@ -47,6 +43,4 @@ typedef posix_mutex mutex; } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_MUTEX_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/noncopyable.hpp b/3rdParty/Boost/src/boost/asio/detail/noncopyable.hpp index b3a6e7c..65ae9a2 100644 --- a/3rdParty/Boost/src/boost/asio/detail/noncopyable.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/noncopyable.hpp @@ -1,6 +1,6 @@ // -// noncopyable.hpp -// ~~~~~~~~~~~~~~~ +// detail/noncopyable.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,13 +15,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/noncopyable.hpp> #include <boost/detail/workaround.hpp> -#include <boost/asio/detail/pop_options.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/detail/null_buffers_op.hpp b/3rdParty/Boost/src/boost/asio/detail/null_buffers_op.hpp deleted file mode 100644 index 02160af..0000000 --- a/3rdParty/Boost/src/boost/asio/detail/null_buffers_op.hpp +++ /dev/null @@ -1,79 +0,0 @@ -// -// null_buffers_op.hpp -// ~~~~~~~~~~~~~~~~~~~ -// -// 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) -// - -#ifndef BOOST_ASIO_DETAIL_NULL_BUFFERS_OP_HPP -#define BOOST_ASIO_DETAIL_NULL_BUFFERS_OP_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/fenced_block.hpp> -#include <boost/asio/detail/handler_alloc_helpers.hpp> -#include <boost/asio/detail/handler_invoke_helpers.hpp> -#include <boost/asio/detail/reactor_op.hpp> - -namespace boost { -namespace asio { -namespace detail { - -template <typename Handler> -class null_buffers_op : public reactor_op -{ -public: - null_buffers_op(Handler handler) - : reactor_op(&null_buffers_op::do_perform, &null_buffers_op::do_complete), - handler_(handler) - { - } - - static bool do_perform(reactor_op*) - { - return true; - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - null_buffers_op* o(static_cast<null_buffers_op*>(base)); - typedef handler_alloc_traits<Handler, null_buffers_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an upcall, - // a sub-object of the handler may be the true owner of the memory - // associated with the handler. Consequently, a local copy of the handler - // is required to ensure that any owning sub-object remains valid until - // after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, o->ec_, o->bytes_transferred_); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include <boost/asio/detail/pop_options.hpp> - -#endif // BOOST_ASIO_DETAIL_NULL_BUFFERS_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/null_event.hpp b/3rdParty/Boost/src/boost/asio/detail/null_event.hpp index 2dc0bf6..3acc26c 100644 --- a/3rdParty/Boost/src/boost/asio/detail/null_event.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/null_event.hpp @@ -1,6 +1,6 @@ // -// null_event.hpp -// ~~~~~~~~~~~~~~ +// detail/null_event.hpp +// ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -72,8 +70,8 @@ public: } // namespace asio } // namespace boost -#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) - #include <boost/asio/detail/pop_options.hpp> +#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) + #endif // BOOST_ASIO_DETAIL_NULL_EVENT_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/null_fenced_block.hpp b/3rdParty/Boost/src/boost/asio/detail/null_fenced_block.hpp index ea8e0fc..ead4c87 100644 --- a/3rdParty/Boost/src/boost/asio/detail/null_fenced_block.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/null_fenced_block.hpp @@ -1,6 +1,6 @@ // -// null_fenced_block.hpp -// ~~~~~~~~~~~~~~~~~~~~~ +// detail/null_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // diff --git a/3rdParty/Boost/src/boost/asio/detail/null_mutex.hpp b/3rdParty/Boost/src/boost/asio/detail/null_mutex.hpp index edc1358..8fca31c 100644 --- a/3rdParty/Boost/src/boost/asio/detail/null_mutex.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/null_mutex.hpp @@ -1,6 +1,6 @@ // -// null_mutex.hpp -// ~~~~~~~~~~~~~~ +// detail/null_mutex.hpp +// ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,17 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/scoped_lock.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -61,8 +59,8 @@ public: } // namespace asio } // namespace boost -#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) - #include <boost/asio/detail/pop_options.hpp> +#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) + #endif // BOOST_ASIO_DETAIL_NULL_MUTEX_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/null_signal_blocker.hpp b/3rdParty/Boost/src/boost/asio/detail/null_signal_blocker.hpp index 65b55e9..9eeccb9 100644 --- a/3rdParty/Boost/src/boost/asio/detail/null_signal_blocker.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/null_signal_blocker.hpp @@ -1,6 +1,6 @@ // -// null_signal_blocker.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~ +// detail/null_signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,18 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> -#if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) +#if !defined(BOOST_HAS_THREADS) \ + || defined(BOOST_ASIO_DISABLE_THREADS) \ + || defined(BOOST_WINDOWS) \ + || defined(__CYGWIN__) \ + || defined(__SYMBIAN32__) #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -58,8 +60,12 @@ public: } // namespace asio } // namespace boost -#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) - #include <boost/asio/detail/pop_options.hpp> +#endif // !defined(BOOST_HAS_THREADS) + // || defined(BOOST_ASIO_DISABLE_THREADS) + // || defined(BOOST_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) + #endif // BOOST_ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/null_thread.hpp b/3rdParty/Boost/src/boost/asio/detail/null_thread.hpp index ba16311..1745011 100644 --- a/3rdParty/Boost/src/boost/asio/detail/null_thread.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/null_thread.hpp @@ -1,6 +1,6 @@ // -// null_thread.hpp -// ~~~~~~~~~~~~~~~ +// detail/null_thread.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,21 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) -#include <boost/asio/detail/push_options.hpp> -#include <boost/throw_exception.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -41,11 +35,10 @@ class null_thread public: // Constructor. template <typename Function> - null_thread(Function f) + null_thread(Function, unsigned int = 0) { - boost::system::system_error e( + boost::asio::detail::throw_error( boost::asio::error::operation_not_supported, "thread"); - boost::throw_exception(e); } // Destructor. @@ -63,8 +56,8 @@ public: } // namespace asio } // namespace boost -#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) - #include <boost/asio/detail/pop_options.hpp> +#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) + #endif // BOOST_ASIO_DETAIL_NULL_THREAD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/null_tss_ptr.hpp b/3rdParty/Boost/src/boost/asio/detail/null_tss_ptr.hpp index bd83e7e..3eff2dc 100644 --- a/3rdParty/Boost/src/boost/asio/detail/null_tss_ptr.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/null_tss_ptr.hpp @@ -1,6 +1,6 @@ // -// null_tss_ptr.hpp -// ~~~~~~~~~~~~~~~~ +// detail/null_tss_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -65,8 +63,8 @@ private: } // namespace asio } // namespace boost -#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) - #include <boost/asio/detail/pop_options.hpp> +#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) + #endif // BOOST_ASIO_DETAIL_NULL_TSS_PTR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/object_pool.hpp b/3rdParty/Boost/src/boost/asio/detail/object_pool.hpp new file mode 100644 index 0000000..87f3902 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/object_pool.hpp @@ -0,0 +1,148 @@ +// +// detail/object_pool.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_OBJECT_POOL_HPP +#define BOOST_ASIO_DETAIL_OBJECT_POOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/noncopyable.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Object> +class object_pool; + +class object_pool_access +{ +public: + template <typename Object> + static Object* create() + { + return new Object; + } + + template <typename Object> + static void destroy(Object* o) + { + delete o; + } + + template <typename Object> + static Object*& next(Object* o) + { + return o->next_; + } + + template <typename Object> + static Object*& prev(Object* o) + { + return o->prev_; + } +}; + +template <typename Object> +class object_pool + : private noncopyable +{ +public: + // Constructor. + object_pool() + : live_list_(0), + free_list_(0) + { + } + + // Destructor destroys all objects. + ~object_pool() + { + destroy_list(live_list_); + destroy_list(free_list_); + } + + // Get the object at the start of the live list. + Object* first() + { + return live_list_; + } + + // Allocate a new object. + Object* alloc() + { + Object* o = free_list_; + if (o) + free_list_ = object_pool_access::next(free_list_); + else + o = object_pool_access::create<Object>(); + + object_pool_access::next(o) = live_list_; + object_pool_access::prev(o) = 0; + if (live_list_) + object_pool_access::prev(live_list_) = o; + live_list_ = o; + + return o; + } + + // Free an object. Moves it to the free list. No destructors are run. + void free(Object* o) + { + if (live_list_ == o) + live_list_ = object_pool_access::next(o); + + if (object_pool_access::prev(o)) + { + object_pool_access::next(object_pool_access::prev(o)) + = object_pool_access::next(o); + } + + if (object_pool_access::next(o)) + { + object_pool_access::prev(object_pool_access::next(o)) + = object_pool_access::prev(o); + } + + object_pool_access::next(o) = free_list_; + object_pool_access::prev(o) = 0; + free_list_ = o; + } + +private: + // Helper function to destroy all elements in a list. + void destroy_list(Object* list) + { + while (list) + { + Object* o = list; + list = object_pool_access::next(o); + object_pool_access::destroy(o); + } + } + + // The list of live objects. + Object* live_list_; + + // The free list. + Object* free_list_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_OBJECT_POOL_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/old_win_sdk_compat.hpp b/3rdParty/Boost/src/boost/asio/detail/old_win_sdk_compat.hpp index 5f84182..10cd898 100644 --- a/3rdParty/Boost/src/boost/asio/detail/old_win_sdk_compat.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/old_win_sdk_compat.hpp @@ -1,6 +1,6 @@ // -// old_win_sdk_compat.hpp -// ~~~~~~~~~~~~~~~~~~~~~~ +// detail/old_win_sdk_compat.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,11 +15,7 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -36,6 +32,8 @@ // a recent (i.e. Vista or later) SDK, as the SDK does not provide IPv6 support // in that case. +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -323,6 +321,8 @@ inline int IN6_IS_ADDR_MC_GLOBAL(const in6_addr_emulation* a) } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_OLD_WIN_SDK) // Even newer Platform SDKs that support IPv6 may not define IPV6_V6ONLY. @@ -337,6 +337,4 @@ inline int IN6_IS_ADDR_MC_GLOBAL(const in6_addr_emulation* a) #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/op_queue.hpp b/3rdParty/Boost/src/boost/asio/detail/op_queue.hpp index ddf3e18..e35e82d 100644 --- a/3rdParty/Boost/src/boost/asio/detail/op_queue.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/op_queue.hpp @@ -1,6 +1,6 @@ // -// op_queue.hpp -// ~~~~~~~~~~~~ +// detail/op_queue.hpp +// ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,10 +15,10 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { diff --git a/3rdParty/Boost/src/boost/asio/detail/operation.hpp b/3rdParty/Boost/src/boost/asio/detail/operation.hpp index 579b6b5..e42455c 100644 --- a/3rdParty/Boost/src/boost/asio/detail/operation.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/operation.hpp @@ -1,6 +1,6 @@ // -// operation.hpp -// ~~~~~~~~~~~~~ +// detail/operation.hpp +// ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,14 +15,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/win_iocp_io_service_fwd.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_IOCP) # include <boost/asio/detail/win_iocp_operation.hpp> #else -# include <boost/asio/detail/reactor_fwd.hpp> # include <boost/asio/detail/task_io_service_operation.hpp> #endif @@ -33,13 +30,11 @@ namespace detail { #if defined(BOOST_ASIO_HAS_IOCP) typedef win_iocp_operation operation; #else -typedef task_io_service_operation<reactor> operation; +typedef task_io_service_operation operation; #endif } // namespace detail } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_OPERATION_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/pipe_select_interrupter.hpp b/3rdParty/Boost/src/boost/asio/detail/pipe_select_interrupter.hpp index 7f9e122..054f731 100644 --- a/3rdParty/Boost/src/boost/asio/detail/pipe_select_interrupter.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/pipe_select_interrupter.hpp @@ -1,6 +1,6 @@ // -// pipe_select_interrupter.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/pipe_select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,22 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/throw_exception.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_WINDOWS) +#if !defined(__CYGWIN__) +#if !defined(__SYMBIAN32__) +#if !defined(BOOST_ASIO_HAS_EVENTFD) #include <boost/asio/detail/push_options.hpp> -#include <fcntl.h> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> -#include <boost/asio/detail/socket_types.hpp> namespace boost { namespace asio { @@ -40,57 +32,16 @@ class pipe_select_interrupter { public: // Constructor. - pipe_select_interrupter() - { - int pipe_fds[2]; - if (pipe(pipe_fds) == 0) - { - read_descriptor_ = pipe_fds[0]; - ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); - write_descriptor_ = pipe_fds[1]; - ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK); - } - else - { - boost::system::error_code ec(errno, - boost::asio::error::get_system_category()); - boost::system::system_error e(ec, "pipe_select_interrupter"); - boost::throw_exception(e); - } - } + BOOST_ASIO_DECL pipe_select_interrupter(); // Destructor. - ~pipe_select_interrupter() - { - if (read_descriptor_ != -1) - ::close(read_descriptor_); - if (write_descriptor_ != -1) - ::close(write_descriptor_); - } + BOOST_ASIO_DECL ~pipe_select_interrupter(); // Interrupt the select call. - void interrupt() - { - char byte = 0; - int result = ::write(write_descriptor_, &byte, 1); - (void)result; - } + BOOST_ASIO_DECL void interrupt(); // Reset the select interrupt. Returns true if the call was interrupted. - bool reset() - { - for (;;) - { - char data[1024]; - int bytes_read = ::read(read_descriptor_, data, sizeof(data)); - if (bytes_read < 0 && errno == EINTR) - continue; - bool was_interrupted = (bytes_read > 0); - while (bytes_read == sizeof(data)) - bytes_read = ::read(read_descriptor_, data, sizeof(data)); - return was_interrupted; - } - } + BOOST_ASIO_DECL bool reset(); // Get the read descriptor to be passed to select. int read_descriptor() const @@ -115,8 +66,15 @@ private: } // namespace asio } // namespace boost -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/pipe_select_interrupter.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // !defined(BOOST_ASIO_HAS_EVENTFD) +#endif // !defined(__SYMBIAN32__) +#endif // !defined(__CYGWIN__) +#endif // !defined(BOOST_WINDOWS) + #endif // BOOST_ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/pop_options.hpp b/3rdParty/Boost/src/boost/asio/detail/pop_options.hpp index a26b203..d589cb7 100644 --- a/3rdParty/Boost/src/boost/asio/detail/pop_options.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/pop_options.hpp @@ -1,6 +1,6 @@ // -// pop_options.hpp -// ~~~~~~~~~~~~~~~ +// detail/pop_options.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -31,6 +31,16 @@ # pragma pack (pop) # endif +# if defined(__OBJC__) +# if !defined(__APPLE_CC__) || (__APPLE_CC__ <= 1) +# if defined(BOOST_ASIO_OBJC_WORKAROUND) +# undef Protocol +# undef id +# undef BOOST_ASIO_OBJC_WORKAROUND +# endif +# endif +# endif + #elif defined(__KCC) // Kai C++ diff --git a/3rdParty/Boost/src/boost/asio/detail/posix_event.hpp b/3rdParty/Boost/src/boost/asio/detail/posix_event.hpp index b2938cf..13fa3d4 100644 --- a/3rdParty/Boost/src/boost/asio/detail/posix_event.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/posix_event.hpp @@ -1,6 +1,6 @@ // -// posix_event.hpp -// ~~~~~~~~~~~~~~~ +// detail/posix_event.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,24 +15,16 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> -#if defined(BOOST_HAS_PTHREADS) +#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) -#include <boost/asio/detail/push_options.hpp> #include <boost/assert.hpp> -#include <boost/throw_exception.hpp> #include <pthread.h> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -42,19 +34,7 @@ class posix_event { public: // Constructor. - posix_event() - : signalled_(false) - { - int error = ::pthread_cond_init(&cond_, 0); - if (error != 0) - { - boost::system::system_error e( - boost::system::error_code(error, - boost::asio::error::get_system_category()), - "event"); - boost::throw_exception(e); - } - } + BOOST_ASIO_DECL posix_event(); // Destructor. ~posix_event() @@ -109,8 +89,12 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_HAS_PTHREADS) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/posix_event.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) + #endif // BOOST_ASIO_DETAIL_POSIX_EVENT_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/posix_fd_set_adapter.hpp b/3rdParty/Boost/src/boost/asio/detail/posix_fd_set_adapter.hpp index 09fc28d..5395eb9 100644 --- a/3rdParty/Boost/src/boost/asio/detail/posix_fd_set_adapter.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/posix_fd_set_adapter.hpp @@ -1,6 +1,6 @@ // -// posix_fd_set_adapter.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/posix_fd_set_adapter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,15 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <cstring> -#include <boost/asio/detail/pop_options.hpp> +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#include <cstring> #include <boost/asio/detail/socket_types.hpp> -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -76,8 +75,8 @@ private: } // namespace asio } // namespace boost -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) - #include <boost/asio/detail/pop_options.hpp> +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + #endif // BOOST_ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/posix_mutex.hpp b/3rdParty/Boost/src/boost/asio/detail/posix_mutex.hpp index 6d9a44f..4fcd8ac 100644 --- a/3rdParty/Boost/src/boost/asio/detail/posix_mutex.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/posix_mutex.hpp @@ -1,6 +1,6 @@ // -// posix_mutex.hpp -// ~~~~~~~~~~~~~~~ +// detail/posix_mutex.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,24 +15,16 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> -#if defined(BOOST_HAS_PTHREADS) +#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) -#include <boost/asio/detail/push_options.hpp> -#include <boost/throw_exception.hpp> #include <pthread.h> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/scoped_lock.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -46,18 +38,7 @@ public: typedef boost::asio::detail::scoped_lock<posix_mutex> scoped_lock; // Constructor. - posix_mutex() - { - int error = ::pthread_mutex_init(&mutex_, 0); - if (error != 0) - { - boost::system::system_error e( - boost::system::error_code(error, - boost::asio::error::get_system_category()), - "mutex"); - boost::throw_exception(e); - } - } + BOOST_ASIO_DECL posix_mutex(); // Destructor. ~posix_mutex() @@ -86,8 +67,12 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_HAS_PTHREADS) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/posix_mutex.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) + #endif // BOOST_ASIO_DETAIL_POSIX_MUTEX_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/posix_signal_blocker.hpp b/3rdParty/Boost/src/boost/asio/detail/posix_signal_blocker.hpp index aebe39b..247a7a8 100644 --- a/3rdParty/Boost/src/boost/asio/detail/posix_signal_blocker.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/posix_signal_blocker.hpp @@ -1,6 +1,6 @@ // -// posix_signal_blocker.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/posix_signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,22 +15,17 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> -#if defined(BOOST_HAS_PTHREADS) +#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) -#include <boost/asio/detail/push_options.hpp> #include <csignal> #include <pthread.h> #include <signal.h> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -85,8 +80,8 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_HAS_PTHREADS) - #include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) + #endif // BOOST_ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/posix_thread.hpp b/3rdParty/Boost/src/boost/asio/detail/posix_thread.hpp index 41d8bc9..a87e396 100644 --- a/3rdParty/Boost/src/boost/asio/detail/posix_thread.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/posix_thread.hpp @@ -1,6 +1,6 @@ // -// posix_thread.hpp -// ~~~~~~~~~~~~~~~~ +// detail/posix_thread.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,29 +15,23 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> -#if defined(BOOST_HAS_PTHREADS) +#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) -#include <boost/asio/detail/push_options.hpp> -#include <memory> -#include <boost/throw_exception.hpp> #include <pthread.h> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { -extern "C" void* boost_asio_detail_posix_thread_function(void* arg); +extern "C" +{ + BOOST_ASIO_DECL void* boost_asio_detail_posix_thread_function(void* arg); +} class posix_thread : private noncopyable @@ -48,36 +42,14 @@ public: posix_thread(Function f) : joined_(false) { - std::auto_ptr<func_base> arg(new func<Function>(f)); - int error = ::pthread_create(&thread_, 0, - boost_asio_detail_posix_thread_function, arg.get()); - if (error != 0) - { - boost::system::system_error e( - boost::system::error_code(error, - boost::asio::error::get_system_category()), - "thread"); - boost::throw_exception(e); - } - arg.release(); + start_thread(new func<Function>(f)); } // Destructor. - ~posix_thread() - { - if (!joined_) - ::pthread_detach(thread_); - } + BOOST_ASIO_DECL ~posix_thread(); // Wait for the thread to exit. - void join() - { - if (!joined_) - { - ::pthread_join(thread_, 0); - joined_ = true; - } - } + BOOST_ASIO_DECL void join(); private: friend void* boost_asio_detail_posix_thread_function(void* arg); @@ -89,6 +61,12 @@ private: virtual void run() = 0; }; + struct auto_func_base_ptr + { + func_base* ptr; + ~auto_func_base_ptr() { delete ptr; } + }; + template <typename Function> class func : public func_base @@ -108,24 +86,22 @@ private: Function f_; }; + BOOST_ASIO_DECL void start_thread(func_base* arg); + ::pthread_t thread_; bool joined_; }; -inline void* boost_asio_detail_posix_thread_function(void* arg) -{ - std::auto_ptr<posix_thread::func_base> f( - static_cast<posix_thread::func_base*>(arg)); - f->run(); - return 0; -} - } // namespace detail } // namespace asio } // namespace boost -#endif // defined(BOOST_HAS_PTHREADS) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/posix_thread.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) + #endif // BOOST_ASIO_DETAIL_POSIX_THREAD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/posix_tss_ptr.hpp b/3rdParty/Boost/src/boost/asio/detail/posix_tss_ptr.hpp index c83df96..dfe8369 100644 --- a/3rdParty/Boost/src/boost/asio/detail/posix_tss_ptr.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/posix_tss_ptr.hpp @@ -1,6 +1,6 @@ // -// posix_tss_ptr.hpp -// ~~~~~~~~~~~~~~~~~ +// detail/posix_tss_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,27 +15,22 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> -#if defined(BOOST_HAS_PTHREADS) +#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) -#include <boost/asio/detail/push_options.hpp> -#include <boost/throw_exception.hpp> #include <pthread.h> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { +// Helper function to create thread-specific storage. +BOOST_ASIO_DECL void posix_tss_ptr_create(pthread_key_t& key); + template <typename T> class posix_tss_ptr : private noncopyable @@ -44,15 +39,7 @@ public: // Constructor. posix_tss_ptr() { - int error = ::pthread_key_create(&tss_key_, 0); - if (error != 0) - { - boost::system::system_error e( - boost::system::error_code(error, - boost::asio::error::get_system_category()), - "tss"); - boost::throw_exception(e); - } + posix_tss_ptr_create(tss_key_); } // Destructor. @@ -77,14 +64,19 @@ private: // Thread-specific storage to allow unlocked access to determine whether a // thread is a member of the pool. pthread_key_t tss_key_; + }; } // namespace detail } // namespace asio } // namespace boost -#endif // defined(BOOST_HAS_PTHREADS) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/posix_tss_ptr.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) + #endif // BOOST_ASIO_DETAIL_POSIX_TSS_PTR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/push_options.hpp b/3rdParty/Boost/src/boost/asio/detail/push_options.hpp index cb0e902..587aef9 100644 --- a/3rdParty/Boost/src/boost/asio/detail/push_options.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/push_options.hpp @@ -1,6 +1,6 @@ // -// push_options.hpp -// ~~~~~~~~~~~~~~~~ +// detail/push_options.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -31,6 +31,18 @@ # pragma pack (push, 8) # endif +# if defined(__OBJC__) +# if !defined(__APPLE_CC__) || (__APPLE_CC__ <= 1) +# if !defined(BOOST_ASIO_DISABLE_OBJC_WORKAROUND) +# if !defined(Protocol) && !defined(id) +# define Protocol cpp_Protocol +# define id cpp_id +# define BOOST_ASIO_OBJC_WORKAROUND +# endif +# endif +# endif +# endif + #elif defined(__KCC) // Kai C++ diff --git a/3rdParty/Boost/src/boost/asio/detail/reactive_descriptor_service.hpp b/3rdParty/Boost/src/boost/asio/detail/reactive_descriptor_service.hpp index 536b96a..993211a 100644 --- a/3rdParty/Boost/src/boost/asio/detail/reactive_descriptor_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/reactive_descriptor_service.hpp @@ -1,6 +1,6 @@ // -// reactive_descriptor_service.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/reactive_descriptor_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,21 +15,24 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#include <boost/utility/addressof.hpp> #include <boost/asio/buffer.hpp> -#include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> #include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/buffer_sequence_adapter.hpp> #include <boost/asio/detail/descriptor_ops.hpp> +#include <boost/asio/detail/descriptor_read_op.hpp> +#include <boost/asio/detail/descriptor_write_op.hpp> #include <boost/asio/detail/fenced_block.hpp> #include <boost/asio/detail/noncopyable.hpp> -#include <boost/asio/detail/null_buffers_op.hpp> +#include <boost/asio/detail/reactive_null_buffers_op.hpp> #include <boost/asio/detail/reactor.hpp> -#include <boost/asio/detail/reactor_op.hpp> -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -49,7 +52,7 @@ public: // Default constructor. implementation_type() : descriptor_(-1), - flags_(0) + state_(0) { } @@ -60,94 +63,29 @@ public: // The native descriptor representation. int descriptor_; - enum - { - // The user wants a non-blocking descriptor. - user_set_non_blocking = 1, - - // The descriptor has been set non-blocking. - internal_non_blocking = 2, - - // Helper "flag" used to determine whether the descriptor is non-blocking. - non_blocking = user_set_non_blocking | internal_non_blocking - }; - - // Flags indicating the current state of the descriptor. - unsigned char flags_; + // The current state of the descriptor. + descriptor_ops::state_type state_; // Per-descriptor data used by the reactor. reactor::per_descriptor_data reactor_data_; }; - // The maximum number of buffers to support in a single operation. - enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len }; - // Constructor. - reactive_descriptor_service(boost::asio::io_service& io_service) - : io_service_impl_(boost::asio::use_service<io_service_impl>(io_service)), - reactor_(boost::asio::use_service<reactor>(io_service)) - { - reactor_.init_task(); - } + BOOST_ASIO_DECL reactive_descriptor_service( + boost::asio::io_service& io_service); // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - } + BOOST_ASIO_DECL void shutdown_service(); // Construct a new descriptor implementation. - void construct(implementation_type& impl) - { - impl.descriptor_ = -1; - impl.flags_ = 0; - } + BOOST_ASIO_DECL void construct(implementation_type& impl); // Destroy a descriptor implementation. - void destroy(implementation_type& impl) - { - if (impl.descriptor_ != -1) - { - reactor_.close_descriptor(impl.descriptor_, impl.reactor_data_); - - if (impl.flags_ & implementation_type::internal_non_blocking) - { - ioctl_arg_type non_blocking = 0; - boost::system::error_code ignored_ec; - descriptor_ops::ioctl(impl.descriptor_, - FIONBIO, &non_blocking, ignored_ec); - impl.flags_ &= ~implementation_type::internal_non_blocking; - } - - boost::system::error_code ignored_ec; - descriptor_ops::close(impl.descriptor_, ignored_ec); - - impl.descriptor_ = -1; - } - } + BOOST_ASIO_DECL void destroy(implementation_type& impl); // Assign a native descriptor to a descriptor implementation. - boost::system::error_code assign(implementation_type& impl, - const native_type& native_descriptor, boost::system::error_code& ec) - { - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_descriptor, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.descriptor_ = native_descriptor; - impl.flags_ = 0; - ec = boost::system::error_code(); - return ec; - } + BOOST_ASIO_DECL boost::system::error_code assign(implementation_type& impl, + const native_type& native_descriptor, boost::system::error_code& ec); // Determine whether the descriptor is open. bool is_open(const implementation_type& impl) const @@ -156,31 +94,8 @@ public: } // Destroy a descriptor implementation. - boost::system::error_code close(implementation_type& impl, - boost::system::error_code& ec) - { - if (is_open(impl)) - { - reactor_.close_descriptor(impl.descriptor_, impl.reactor_data_); - - if (impl.flags_ & implementation_type::internal_non_blocking) - { - ioctl_arg_type non_blocking = 0; - boost::system::error_code ignored_ec; - descriptor_ops::ioctl(impl.descriptor_, - FIONBIO, &non_blocking, ignored_ec); - impl.flags_ &= ~implementation_type::internal_non_blocking; - } - - if (descriptor_ops::close(impl.descriptor_, ec) == -1) - return ec; - - impl.descriptor_ = -1; - } - - ec = boost::system::error_code(); - return ec; - } + BOOST_ASIO_DECL boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec); // Get the native descriptor representation. native_type native(const implementation_type& impl) const @@ -189,56 +104,16 @@ public: } // Cancel all operations associated with the descriptor. - boost::system::error_code cancel(implementation_type& impl, - boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - reactor_.cancel_ops(impl.descriptor_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; - } + BOOST_ASIO_DECL boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec); // Perform an IO control command on the descriptor. template <typename IO_Control_Command> boost::system::error_code io_control(implementation_type& impl, IO_Control_Command& command, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - descriptor_ops::ioctl(impl.descriptor_, command.name(), - static_cast<ioctl_arg_type*>(command.data()), ec); - - // When updating the non-blocking mode we always perform the ioctl syscall, - // even if the flags would otherwise indicate that the descriptor is - // already in the correct state. This ensures that the underlying - // descriptor is put into the state that has been requested by the user. If - // the ioctl syscall was successful then we need to update the flags to - // match. - if (!ec && command.name() == static_cast<int>(FIONBIO)) - { - if (*static_cast<ioctl_arg_type*>(command.data())) - { - impl.flags_ |= implementation_type::user_set_non_blocking; - } - else - { - // Clearing the non-blocking mode always overrides any internally-set - // non-blocking flag. Any subsequent asynchronous operations will need - // to re-enable non-blocking I/O. - impl.flags_ &= ~(implementation_type::user_set_non_blocking - | implementation_type::internal_non_blocking); - } - } - + descriptor_ops::ioctl(impl.descriptor_, impl.state_, + command.name(), static_cast<ioctl_arg_type*>(command.data()), ec); return ec; } @@ -247,148 +122,23 @@ public: size_t write_some(implementation_type& impl, const ConstBufferSequence& buffers, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - buffer_sequence_adapter<boost::asio::const_buffer, ConstBufferSequence> bufs(buffers); - // A request to read_some 0 bytes on a stream is a no-op. - if (bufs.all_empty()) - { - ec = boost::system::error_code(); - return 0; - } - - // Send the data. - for (;;) - { - // Try to complete the operation without blocking. - int bytes_sent = descriptor_ops::gather_write( - impl.descriptor_, bufs.buffers(), bufs.count(), ec); - - // Check if operation succeeded. - if (bytes_sent >= 0) - return bytes_sent; - - // Operation failed. - if ((impl.flags_ & implementation_type::user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for descriptor to become ready. - if (descriptor_ops::poll_write(impl.descriptor_, ec) < 0) - return 0; - } + return descriptor_ops::sync_write(impl.descriptor_, impl.state_, + bufs.buffers(), bufs.count(), bufs.all_empty(), ec); } // Wait until data can be written without blocking. size_t write_some(implementation_type& impl, const null_buffers&, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - // Wait for descriptor to become ready. descriptor_ops::poll_write(impl.descriptor_, ec); return 0; } - template <typename ConstBufferSequence> - class write_op_base : public reactor_op - { - public: - write_op_base(int descriptor, - const ConstBufferSequence& buffers, func_type complete_func) - : reactor_op(&write_op_base::do_perform, complete_func), - descriptor_(descriptor), - buffers_(buffers) - { - } - - static bool do_perform(reactor_op* base) - { - write_op_base* o(static_cast<write_op_base*>(base)); - - buffer_sequence_adapter<boost::asio::const_buffer, - ConstBufferSequence> bufs(o->buffers_); - - for (;;) - { - // Write the data. - boost::system::error_code ec; - int bytes = descriptor_ops::gather_write( - o->descriptor_, bufs.buffers(), bufs.count(), ec); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - o->ec_ = ec; - o->bytes_transferred_ = (bytes < 0 ? 0 : bytes); - return true; - } - } - - private: - int descriptor_; - ConstBufferSequence buffers_; - }; - - template <typename ConstBufferSequence, typename Handler> - class write_op : public write_op_base<ConstBufferSequence> - { - public: - write_op(int descriptor, - const ConstBufferSequence& buffers, Handler handler) - : write_op_base<ConstBufferSequence>( - descriptor, buffers, &write_op::do_complete), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - write_op* o(static_cast<write_op*>(base)); - typedef handler_alloc_traits<Handler, write_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, o->ec_, o->bytes_transferred_); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - Handler handler_; - }; - // Start an asynchronous write. The data being sent must be valid for the // lifetime of the asynchronous operation. template <typename ConstBufferSequence, typename Handler> @@ -396,15 +146,16 @@ public: const ConstBufferSequence& buffers, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef write_op<ConstBufferSequence, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, impl.descriptor_, buffers, handler); + typedef descriptor_write_op<ConstBufferSequence, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.descriptor_, buffers, handler); - start_op(impl, reactor::write_op, ptr.get(), true, + start_op(impl, reactor::write_op, p.p, true, buffer_sequence_adapter<boost::asio::const_buffer, ConstBufferSequence>::all_empty(buffers)); - ptr.release(); + p.v = p.p = 0; } // Start an asynchronous wait until data can be written without blocking. @@ -413,13 +164,14 @@ public: const null_buffers&, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef null_buffers_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); + typedef reactive_null_buffers_op<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); - start_op(impl, reactor::write_op, ptr.get(), false, false); - ptr.release(); + start_op(impl, reactor::write_op, p.p, false, false); + p.v = p.p = 0; } // Read some data from the stream. Returns the number of bytes read. @@ -427,157 +179,23 @@ public: size_t read_some(implementation_type& impl, const MutableBufferSequence& buffers, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - buffer_sequence_adapter<boost::asio::mutable_buffer, MutableBufferSequence> bufs(buffers); - // A request to read_some 0 bytes on a stream is a no-op. - if (bufs.all_empty()) - { - ec = boost::system::error_code(); - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - int bytes_read = descriptor_ops::scatter_read( - impl.descriptor_, bufs.buffers(), bufs.count(), ec); - - // Check if operation succeeded. - if (bytes_read > 0) - return bytes_read; - - // Check for EOF. - if (bytes_read == 0) - { - ec = boost::asio::error::eof; - return 0; - } - - // Operation failed. - if ((impl.flags_ & implementation_type::user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for descriptor to become ready. - if (descriptor_ops::poll_read(impl.descriptor_, ec) < 0) - return 0; - } + return descriptor_ops::sync_read(impl.descriptor_, impl.state_, + bufs.buffers(), bufs.count(), bufs.all_empty(), ec); } // Wait until data can be read without blocking. size_t read_some(implementation_type& impl, const null_buffers&, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - // Wait for descriptor to become ready. descriptor_ops::poll_read(impl.descriptor_, ec); return 0; } - template <typename MutableBufferSequence> - class read_op_base : public reactor_op - { - public: - read_op_base(int descriptor, - const MutableBufferSequence& buffers, func_type complete_func) - : reactor_op(&read_op_base::do_perform, complete_func), - descriptor_(descriptor), - buffers_(buffers) - { - } - - static bool do_perform(reactor_op* base) - { - read_op_base* o(static_cast<read_op_base*>(base)); - - buffer_sequence_adapter<boost::asio::mutable_buffer, - MutableBufferSequence> bufs(o->buffers_); - - for (;;) - { - // Read some data. - boost::system::error_code ec; - int bytes = descriptor_ops::scatter_read( - o->descriptor_, bufs.buffers(), bufs.count(), ec); - if (bytes == 0) - ec = boost::asio::error::eof; - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - o->ec_ = ec; - o->bytes_transferred_ = (bytes < 0 ? 0 : bytes); - return true; - } - } - - private: - int descriptor_; - MutableBufferSequence buffers_; - }; - - template <typename MutableBufferSequence, typename Handler> - class read_op : public read_op_base<MutableBufferSequence> - { - public: - read_op(int descriptor, - const MutableBufferSequence& buffers, Handler handler) - : read_op_base<MutableBufferSequence>( - descriptor, buffers, &read_op::do_complete), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - read_op* o(static_cast<read_op*>(base)); - typedef handler_alloc_traits<Handler, read_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, o->ec_, o->bytes_transferred_); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - Handler handler_; - }; - // Start an asynchronous read. The buffer for the data being read must be // valid for the lifetime of the asynchronous operation. template <typename MutableBufferSequence, typename Handler> @@ -585,16 +203,16 @@ public: const MutableBufferSequence& buffers, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef read_op<MutableBufferSequence, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, - impl.descriptor_, buffers, handler); + typedef descriptor_read_op<MutableBufferSequence, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.descriptor_, buffers, handler); - start_op(impl, reactor::read_op, ptr.get(), true, + start_op(impl, reactor::read_op, p.p, true, buffer_sequence_adapter<boost::asio::mutable_buffer, MutableBufferSequence>::all_empty(buffers)); - ptr.release(); + p.v = p.p = 0; } // Wait until data can be read without blocking. @@ -603,57 +221,20 @@ public: const null_buffers&, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef null_buffers_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); + typedef reactive_null_buffers_op<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); - start_op(impl, reactor::read_op, ptr.get(), false, false); - ptr.release(); + start_op(impl, reactor::read_op, p.p, false, false); + p.v = p.p = 0; } private: // Start the asynchronous operation. - void start_op(implementation_type& impl, int op_type, - reactor_op* op, bool non_blocking, bool noop) - { - if (!noop) - { - if (is_open(impl)) - { - if (is_non_blocking(impl) || set_non_blocking(impl, op->ec_)) - { - reactor_.start_op(op_type, impl.descriptor_, - impl.reactor_data_, op, non_blocking); - return; - } - } - else - op->ec_ = boost::asio::error::bad_descriptor; - } - - io_service_impl_.post_immediate_completion(op); - } - - // Determine whether the descriptor has been set non-blocking. - bool is_non_blocking(implementation_type& impl) const - { - return (impl.flags_ & implementation_type::non_blocking); - } - - // Set the internal non-blocking flag. - bool set_non_blocking(implementation_type& impl, - boost::system::error_code& ec) - { - ioctl_arg_type non_blocking = 1; - if (descriptor_ops::ioctl(impl.descriptor_, FIONBIO, &non_blocking, ec)) - return false; - impl.flags_ |= implementation_type::internal_non_blocking; - return true; - } - - // The io_service implementation used to post completions. - io_service_impl& io_service_impl_; + BOOST_ASIO_DECL void start_op(implementation_type& impl, int op_type, + reactor_op* op, bool non_blocking, bool noop); // The selector that performs event demultiplexing for the service. reactor& reactor_; @@ -663,8 +244,12 @@ private: } // namespace asio } // namespace boost -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/reactive_descriptor_service.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + #endif // BOOST_ASIO_DETAIL_REACTIVE_DESCRIPTOR_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/reactive_null_buffers_op.hpp b/3rdParty/Boost/src/boost/asio/detail/reactive_null_buffers_op.hpp new file mode 100644 index 0000000..a2a6911 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/reactive_null_buffers_op.hpp @@ -0,0 +1,85 @@ +// +// detail/reactive_null_buffers_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_NULL_BUFFERS_OP_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_NULL_BUFFERS_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/reactor_op.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Handler> +class reactive_null_buffers_op : public reactor_op +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_null_buffers_op); + + reactive_null_buffers_op(Handler handler) + : reactor_op(&reactive_null_buffers_op::do_perform, + &reactive_null_buffers_op::do_complete), + handler_(handler) + { + } + + static bool do_perform(reactor_op*) + { + return true; + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_null_buffers_op* o(static_cast<reactive_null_buffers_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_REACTIVE_NULL_BUFFERS_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/reactive_serial_port_service.hpp b/3rdParty/Boost/src/boost/asio/detail/reactive_serial_port_service.hpp index faa2149..0955f1d 100644 --- a/3rdParty/Boost/src/boost/asio/detail/reactive_serial_port_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/reactive_serial_port_service.hpp @@ -1,6 +1,6 @@ // -// reactive_serial_port_service.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/reactive_serial_port_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) @@ -16,23 +16,20 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <cstring> -#include <string> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/serial_port_base.hpp> - -#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \ - && !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if defined(BOOST_ASIO_HAS_SERIAL_PORT) +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#include <string> #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> +#include <boost/asio/serial_port_base.hpp> #include <boost/asio/detail/descriptor_ops.hpp> #include <boost/asio/detail/reactive_descriptor_service.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -47,119 +44,55 @@ public: // The implementation type of the serial port. typedef reactive_descriptor_service::implementation_type implementation_type; - reactive_serial_port_service(boost::asio::io_service& io_service) - : descriptor_service_(io_service) - { - } + BOOST_ASIO_DECL reactive_serial_port_service( + boost::asio::io_service& io_service); // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - descriptor_service_.shutdown_service(); - } + BOOST_ASIO_DECL void shutdown_service(); - // Construct a new handle implementation. + // Construct a new serial port implementation. void construct(implementation_type& impl) { descriptor_service_.construct(impl); } - // Destroy a handle implementation. + // Destroy a serial port implementation. void destroy(implementation_type& impl) { descriptor_service_.destroy(impl); } // Open the serial port using the specified device name. - boost::system::error_code open(implementation_type& impl, - const std::string& device, boost::system::error_code& ec) - { - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - int fd = descriptor_ops::open(device.c_str(), - O_RDWR | O_NONBLOCK | O_NOCTTY, ec); - if (fd < 0) - return ec; - - int s = descriptor_ops::fcntl(fd, F_GETFL, ec); - if (s >= 0) - s = descriptor_ops::fcntl(fd, F_SETFL, s | O_NONBLOCK, ec); - if (s < 0) - { - boost::system::error_code ignored_ec; - descriptor_ops::close(fd, ignored_ec); - return ec; - } - - // Set up default serial port options. - termios ios; - descriptor_ops::clear_error(ec); - s = descriptor_ops::error_wrapper(::tcgetattr(fd, &ios), ec); - if (s >= 0) - { -#if defined(_BSD_SOURCE) - ::cfmakeraw(&ios); -#else - ios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK - | ISTRIP | INLCR | IGNCR | ICRNL | IXON); - ios.c_oflag &= ~OPOST; - ios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - ios.c_cflag &= ~(CSIZE | PARENB); - ios.c_cflag |= CS8; -#endif - ios.c_iflag |= IGNPAR; - ios.c_cflag |= CREAD | CLOCAL; - descriptor_ops::clear_error(ec); - s = descriptor_ops::error_wrapper(::tcsetattr(fd, TCSANOW, &ios), ec); - } - if (s < 0) - { - boost::system::error_code ignored_ec; - descriptor_ops::close(fd, ignored_ec); - return ec; - } - - // We're done. Take ownership of the serial port descriptor. - if (descriptor_service_.assign(impl, fd, ec)) - { - boost::system::error_code ignored_ec; - descriptor_ops::close(fd, ignored_ec); - } - - return ec; - } + BOOST_ASIO_DECL boost::system::error_code open(implementation_type& impl, + const std::string& device, boost::system::error_code& ec); - // Assign a native handle to a handle implementation. + // Assign a native descriptor to a serial port implementation. boost::system::error_code assign(implementation_type& impl, const native_type& native_descriptor, boost::system::error_code& ec) { return descriptor_service_.assign(impl, native_descriptor, ec); } - // Determine whether the handle is open. + // Determine whether the serial port is open. bool is_open(const implementation_type& impl) const { return descriptor_service_.is_open(impl); } - // Destroy a handle implementation. + // Destroy a serial port implementation. boost::system::error_code close(implementation_type& impl, boost::system::error_code& ec) { return descriptor_service_.close(impl, ec); } - // Get the native handle representation. + // Get the native serial port representation. native_type native(implementation_type& impl) { return descriptor_service_.native(impl); } - // Cancel all operations associated with the handle. + // Cancel all operations associated with the serial port. boost::system::error_code cancel(implementation_type& impl, boost::system::error_code& ec) { @@ -171,20 +104,9 @@ public: boost::system::error_code set_option(implementation_type& impl, const SettableSerialPortOption& option, boost::system::error_code& ec) { - termios ios; - descriptor_ops::clear_error(ec); - descriptor_ops::error_wrapper(::tcgetattr( - descriptor_service_.native(impl), &ios), ec); - if (ec) - return ec; - - if (option.store(ios, ec)) - return ec; - - descriptor_ops::clear_error(ec); - descriptor_ops::error_wrapper(::tcsetattr( - descriptor_service_.native(impl), TCSANOW, &ios), ec); - return ec; + return do_set_option(impl, + &reactive_serial_port_service::store_option<SettableSerialPortOption>, + &option, ec); } // Get an option from the serial port. @@ -192,21 +114,16 @@ public: boost::system::error_code get_option(const implementation_type& impl, GettableSerialPortOption& option, boost::system::error_code& ec) const { - termios ios; - descriptor_ops::clear_error(ec); - descriptor_ops::error_wrapper(::tcgetattr( - descriptor_service_.native(impl), &ios), ec); - if (ec) - return ec; - - return option.load(ios, ec); + return do_get_option(impl, + &reactive_serial_port_service::load_option<GettableSerialPortOption>, + &option, ec); } // Send a break sequence to the serial port. boost::system::error_code send_break(implementation_type& impl, boost::system::error_code& ec) { - descriptor_ops::clear_error(ec); + errno = 0; descriptor_ops::error_wrapper(::tcsendbreak( descriptor_service_.native(impl), 0), ec); return ec; @@ -247,6 +164,41 @@ public: } private: + // Function pointer type for storing a serial port option. + typedef boost::system::error_code (*store_function_type)( + const void*, termios&, boost::system::error_code&); + + // Helper function template to store a serial port option. + template <typename SettableSerialPortOption> + static boost::system::error_code store_option(const void* option, + termios& storage, boost::system::error_code& ec) + { + return static_cast<const SettableSerialPortOption*>(option)->store( + storage, ec); + } + + // Helper function to set a serial port option. + BOOST_ASIO_DECL boost::system::error_code do_set_option( + implementation_type& impl, store_function_type store, + const void* option, boost::system::error_code& ec); + + // Function pointer type for loading a serial port option. + typedef boost::system::error_code (*load_function_type)( + void*, const termios&, boost::system::error_code&); + + // Helper function template to load a serial port option. + template <typename GettableSerialPortOption> + static boost::system::error_code load_option(void* option, + const termios& storage, boost::system::error_code& ec) + { + return static_cast<GettableSerialPortOption*>(option)->load(storage, ec); + } + + // Helper function to get a serial port option. + BOOST_ASIO_DECL boost::system::error_code do_get_option( + const implementation_type& impl, load_function_type load, + void* option, boost::system::error_code& ec) const; + // The implementation used for initiating asynchronous operations. reactive_descriptor_service descriptor_service_; }; @@ -255,9 +207,13 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT) - // && !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/reactive_serial_port_service.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT) + #endif // BOOST_ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/reactive_socket_accept_op.hpp b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_accept_op.hpp new file mode 100644 index 0000000..3b2413f --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_accept_op.hpp @@ -0,0 +1,133 @@ +// +// detail/reactive_socket_accept_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/reactor_op.hpp> +#include <boost/asio/detail/socket_holder.hpp> +#include <boost/asio/detail/socket_ops.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Socket, typename Protocol> +class reactive_socket_accept_op_base : public reactor_op +{ +public: + reactive_socket_accept_op_base(socket_type socket, + socket_ops::state_type state, Socket& peer, const Protocol& protocol, + typename Protocol::endpoint* peer_endpoint, func_type complete_func) + : reactor_op(&reactive_socket_accept_op_base::do_perform, complete_func), + socket_(socket), + state_(state), + peer_(peer), + protocol_(protocol), + peer_endpoint_(peer_endpoint) + { + } + + static bool do_perform(reactor_op* base) + { + reactive_socket_accept_op_base* o( + static_cast<reactive_socket_accept_op_base*>(base)); + + std::size_t addrlen = o->peer_endpoint_ ? o->peer_endpoint_->capacity() : 0; + socket_type new_socket = invalid_socket; + bool result = socket_ops::non_blocking_accept(o->socket_, + o->state_, o->peer_endpoint_ ? o->peer_endpoint_->data() : 0, + o->peer_endpoint_ ? &addrlen : 0, o->ec_, new_socket); + + // On success, assign new connection to peer socket object. + if (new_socket >= 0) + { + socket_holder new_socket_holder(new_socket); + if (o->peer_endpoint_) + o->peer_endpoint_->resize(addrlen); + if (!o->peer_.assign(o->protocol_, new_socket, o->ec_)) + new_socket_holder.release(); + } + + return result; + } + +private: + socket_type socket_; + socket_ops::state_type state_; + Socket& peer_; + Protocol protocol_; + typename Protocol::endpoint* peer_endpoint_; +}; + +template <typename Socket, typename Protocol, typename Handler> +class reactive_socket_accept_op : + public reactive_socket_accept_op_base<Socket, Protocol> +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_accept_op); + + reactive_socket_accept_op(socket_type socket, + socket_ops::state_type state, Socket& peer, const Protocol& protocol, + typename Protocol::endpoint* peer_endpoint, Handler handler) + : reactive_socket_accept_op_base<Socket, Protocol>(socket, state, peer, + protocol, peer_endpoint, &reactive_socket_accept_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_accept_op* o(static_cast<reactive_socket_accept_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder1<Handler, boost::system::error_code> + handler(o->handler_, o->ec_); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/reactive_socket_connect_op.hpp b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_connect_op.hpp new file mode 100644 index 0000000..2bfb55d --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_connect_op.hpp @@ -0,0 +1,103 @@ +// +// detail/reactive_socket_connect_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/reactor_op.hpp> +#include <boost/asio/detail/socket_ops.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +class reactive_socket_connect_op_base : public reactor_op +{ +public: + reactive_socket_connect_op_base(socket_type socket, func_type complete_func) + : reactor_op(&reactive_socket_connect_op_base::do_perform, complete_func), + socket_(socket) + { + } + + static bool do_perform(reactor_op* base) + { + reactive_socket_connect_op_base* o( + static_cast<reactive_socket_connect_op_base*>(base)); + + return socket_ops::non_blocking_connect(o->socket_, o->ec_); + } + +private: + socket_type socket_; +}; + +template <typename Handler> +class reactive_socket_connect_op : public reactive_socket_connect_op_base +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_connect_op); + + reactive_socket_connect_op(socket_type socket, Handler handler) + : reactive_socket_connect_op_base(socket, + &reactive_socket_connect_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_connect_op* o + (static_cast<reactive_socket_connect_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder1<Handler, boost::system::error_code> + handler(o->handler_, o->ec_); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler); + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/reactive_socket_recv_op.hpp b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_recv_op.hpp new file mode 100644 index 0000000..d58aa3f --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_recv_op.hpp @@ -0,0 +1,120 @@ +// +// detail/reactive_socket_recv_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/reactor_op.hpp> +#include <boost/asio/detail/socket_ops.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename MutableBufferSequence> +class reactive_socket_recv_op_base : public reactor_op +{ +public: + reactive_socket_recv_op_base(socket_type socket, + socket_ops::state_type state, const MutableBufferSequence& buffers, + socket_base::message_flags flags, func_type complete_func) + : reactor_op(&reactive_socket_recv_op_base::do_perform, complete_func), + socket_(socket), + state_(state), + buffers_(buffers), + flags_(flags) + { + } + + static bool do_perform(reactor_op* base) + { + reactive_socket_recv_op_base* o( + static_cast<reactive_socket_recv_op_base*>(base)); + + buffer_sequence_adapter<boost::asio::mutable_buffer, + MutableBufferSequence> bufs(o->buffers_); + + return socket_ops::non_blocking_recv(o->socket_, + bufs.buffers(), bufs.count(), o->flags_, + (o->state_ & socket_ops::stream_oriented), + o->ec_, o->bytes_transferred_); + } + +private: + socket_type socket_; + socket_ops::state_type state_; + MutableBufferSequence buffers_; + socket_base::message_flags flags_; +}; + +template <typename MutableBufferSequence, typename Handler> +class reactive_socket_recv_op : + public reactive_socket_recv_op_base<MutableBufferSequence> +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op); + + reactive_socket_recv_op(socket_type socket, + socket_ops::state_type state, const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + : reactive_socket_recv_op_base<MutableBufferSequence>(socket, state, + buffers, flags, &reactive_socket_recv_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_recv_op* o(static_cast<reactive_socket_recv_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/reactive_socket_recvfrom_op.hpp b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_recvfrom_op.hpp new file mode 100644 index 0000000..469b6a5 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_recvfrom_op.hpp @@ -0,0 +1,130 @@ +// +// detail/reactive_socket_recvfrom_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/reactor_op.hpp> +#include <boost/asio/detail/socket_ops.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename MutableBufferSequence, typename Endpoint> +class reactive_socket_recvfrom_op_base : public reactor_op +{ +public: + reactive_socket_recvfrom_op_base(socket_type socket, int protocol_type, + const MutableBufferSequence& buffers, Endpoint& endpoint, + socket_base::message_flags flags, func_type complete_func) + : reactor_op(&reactive_socket_recvfrom_op_base::do_perform, complete_func), + socket_(socket), + protocol_type_(protocol_type), + buffers_(buffers), + sender_endpoint_(endpoint), + flags_(flags) + { + } + + static bool do_perform(reactor_op* base) + { + reactive_socket_recvfrom_op_base* o( + static_cast<reactive_socket_recvfrom_op_base*>(base)); + + buffer_sequence_adapter<boost::asio::mutable_buffer, + MutableBufferSequence> bufs(o->buffers_); + + std::size_t addr_len = o->sender_endpoint_.capacity(); + bool result = socket_ops::non_blocking_recvfrom(o->socket_, + bufs.buffers(), bufs.count(), o->flags_, + o->sender_endpoint_.data(), &addr_len, + o->ec_, o->bytes_transferred_); + + if (result && !o->ec_) + o->sender_endpoint_.resize(addr_len); + + return result; + } + +private: + socket_type socket_; + int protocol_type_; + MutableBufferSequence buffers_; + Endpoint& sender_endpoint_; + socket_base::message_flags flags_; +}; + +template <typename MutableBufferSequence, typename Endpoint, typename Handler> +class reactive_socket_recvfrom_op : + public reactive_socket_recvfrom_op_base<MutableBufferSequence, Endpoint> +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op); + + reactive_socket_recvfrom_op(socket_type socket, int protocol_type, + const MutableBufferSequence& buffers, Endpoint& endpoint, + socket_base::message_flags flags, Handler handler) + : reactive_socket_recvfrom_op_base<MutableBufferSequence, Endpoint>( + socket, protocol_type, buffers, endpoint, flags, + &reactive_socket_recvfrom_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_recvfrom_op* o( + static_cast<reactive_socket_recvfrom_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/reactive_socket_send_op.hpp b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_send_op.hpp new file mode 100644 index 0000000..157d075 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_send_op.hpp @@ -0,0 +1,117 @@ +// +// detail/reactive_socket_send_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SEND_OP_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SEND_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/reactor_op.hpp> +#include <boost/asio/detail/socket_ops.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename ConstBufferSequence> +class reactive_socket_send_op_base : public reactor_op +{ +public: + reactive_socket_send_op_base(socket_type socket, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, func_type complete_func) + : reactor_op(&reactive_socket_send_op_base::do_perform, complete_func), + socket_(socket), + buffers_(buffers), + flags_(flags) + { + } + + static bool do_perform(reactor_op* base) + { + reactive_socket_send_op_base* o( + static_cast<reactive_socket_send_op_base*>(base)); + + buffer_sequence_adapter<boost::asio::const_buffer, + ConstBufferSequence> bufs(o->buffers_); + + return socket_ops::non_blocking_send(o->socket_, + bufs.buffers(), bufs.count(), o->flags_, + o->ec_, o->bytes_transferred_); + } + +private: + socket_type socket_; + ConstBufferSequence buffers_; + socket_base::message_flags flags_; +}; + +template <typename ConstBufferSequence, typename Handler> +class reactive_socket_send_op : + public reactive_socket_send_op_base<ConstBufferSequence> +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_send_op); + + reactive_socket_send_op(socket_type socket, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + : reactive_socket_send_op_base<ConstBufferSequence>(socket, + buffers, flags, &reactive_socket_send_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_send_op* o(static_cast<reactive_socket_send_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SEND_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/reactive_socket_sendto_op.hpp b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_sendto_op.hpp new file mode 100644 index 0000000..6199ec2 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_sendto_op.hpp @@ -0,0 +1,120 @@ +// +// detail/reactive_socket_sendto_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SENDTO_OP_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SENDTO_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/reactor_op.hpp> +#include <boost/asio/detail/socket_ops.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename ConstBufferSequence, typename Endpoint> +class reactive_socket_sendto_op_base : public reactor_op +{ +public: + reactive_socket_sendto_op_base(socket_type socket, + const ConstBufferSequence& buffers, const Endpoint& endpoint, + socket_base::message_flags flags, func_type complete_func) + : reactor_op(&reactive_socket_sendto_op_base::do_perform, complete_func), + socket_(socket), + buffers_(buffers), + destination_(endpoint), + flags_(flags) + { + } + + static bool do_perform(reactor_op* base) + { + reactive_socket_sendto_op_base* o( + static_cast<reactive_socket_sendto_op_base*>(base)); + + buffer_sequence_adapter<boost::asio::const_buffer, + ConstBufferSequence> bufs(o->buffers_); + + return socket_ops::non_blocking_sendto(o->socket_, + bufs.buffers(), bufs.count(), o->flags_, + o->destination_.data(), o->destination_.size(), + o->ec_, o->bytes_transferred_); + } + +private: + socket_type socket_; + ConstBufferSequence buffers_; + Endpoint destination_; + socket_base::message_flags flags_; +}; + +template <typename ConstBufferSequence, typename Endpoint, typename Handler> +class reactive_socket_sendto_op : + public reactive_socket_sendto_op_base<ConstBufferSequence, Endpoint> +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_sendto_op); + + reactive_socket_sendto_op(socket_type socket, + const ConstBufferSequence& buffers, const Endpoint& endpoint, + socket_base::message_flags flags, Handler handler) + : reactive_socket_sendto_op_base<ConstBufferSequence, Endpoint>(socket, + buffers, endpoint, flags, &reactive_socket_sendto_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_sendto_op* o(static_cast<reactive_socket_sendto_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, o->ec_, o->bytes_transferred_); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SENDTO_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/reactive_socket_service.hpp b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_service.hpp index 5f7bbf5..7288881 100644 --- a/3rdParty/Boost/src/boost/asio/detail/reactive_socket_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_service.hpp @@ -1,6 +1,6 @@ // -// reactive_socket_service.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/reactive_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,29 +15,38 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> + +#if !defined(BOOST_ASIO_HAS_IOCP) +#include <boost/utility/addressof.hpp> #include <boost/asio/buffer.hpp> #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> #include <boost/asio/socket_base.hpp> -#include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/buffer_sequence_adapter.hpp> -#include <boost/asio/detail/fenced_block.hpp> #include <boost/asio/detail/noncopyable.hpp> -#include <boost/asio/detail/null_buffers_op.hpp> +#include <boost/asio/detail/reactive_null_buffers_op.hpp> +#include <boost/asio/detail/reactive_socket_accept_op.hpp> +#include <boost/asio/detail/reactive_socket_connect_op.hpp> +#include <boost/asio/detail/reactive_socket_recvfrom_op.hpp> +#include <boost/asio/detail/reactive_socket_sendto_op.hpp> +#include <boost/asio/detail/reactive_socket_service_base.hpp> #include <boost/asio/detail/reactor.hpp> #include <boost/asio/detail/reactor_op.hpp> #include <boost/asio/detail/socket_holder.hpp> #include <boost/asio/detail/socket_ops.hpp> #include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { template <typename Protocol> -class reactive_socket_service +class reactive_socket_service : + public reactive_socket_service_base { public: // The protocol type. @@ -50,132 +59,32 @@ public: typedef socket_type native_type; // The implementation type of the socket. - class implementation_type - : private boost::asio::detail::noncopyable + struct implementation_type : + reactive_socket_service_base::base_implementation_type { - public: // Default constructor. implementation_type() - : socket_(invalid_socket), - flags_(0), - protocol_(endpoint_type().protocol()) + : protocol_(endpoint_type().protocol()) { } - private: - // Only this service will have access to the internal values. - friend class reactive_socket_service<Protocol>; - - // The native socket representation. - socket_type socket_; - - enum - { - // The user wants a non-blocking socket. - user_set_non_blocking = 1, - - // The implementation wants a non-blocking socket (in order to be able to - // perform asynchronous read and write operations). - internal_non_blocking = 2, - - // Helper "flag" used to determine whether the socket is non-blocking. - non_blocking = user_set_non_blocking | internal_non_blocking, - - // User wants connection_aborted errors, which are disabled by default. - enable_connection_aborted = 4, - - // The user set the linger option. Needs to be checked when closing. - user_set_linger = 8 - }; - - // Flags indicating the current state of the socket. - unsigned char flags_; - // The protocol associated with the socket. protocol_type protocol_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; }; // Constructor. reactive_socket_service(boost::asio::io_service& io_service) - : io_service_impl_(use_service<io_service_impl>(io_service)), - reactor_(use_service<reactor>(io_service)) - { - reactor_.init_task(); - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - } - - // Construct a new socket implementation. - void construct(implementation_type& impl) + : reactive_socket_service_base(io_service) { - impl.socket_ = invalid_socket; - impl.flags_ = 0; - } - - // Destroy a socket implementation. - void destroy(implementation_type& impl) - { - if (impl.socket_ != invalid_socket) - { - reactor_.close_descriptor(impl.socket_, impl.reactor_data_); - - if (impl.flags_ & implementation_type::non_blocking) - { - ioctl_arg_type non_blocking = 0; - boost::system::error_code ignored_ec; - socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ignored_ec); - impl.flags_ &= ~implementation_type::non_blocking; - } - - if (impl.flags_ & implementation_type::user_set_linger) - { - ::linger opt; - opt.l_onoff = 0; - opt.l_linger = 0; - boost::system::error_code ignored_ec; - socket_ops::setsockopt(impl.socket_, - SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec); - } - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, ignored_ec); - - impl.socket_ = invalid_socket; - } } // Open a new socket implementation. boost::system::error_code open(implementation_type& impl, const protocol_type& protocol, boost::system::error_code& ec) { - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(protocol.family(), - protocol.type(), protocol.protocol(), ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - impl.flags_ = 0; - impl.protocol_ = protocol; - ec = boost::system::error_code(); + if (!do_open(impl, protocol.family(), + protocol.type(), protocol.protocol(), ec)) + impl.protocol_ = protocol; return ec; } @@ -184,56 +93,8 @@ public: const protocol_type& protocol, const native_type& native_socket, boost::system::error_code& ec) { - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - impl.flags_ = 0; - impl.protocol_ = protocol; - ec = boost::system::error_code(); - return ec; - } - - // Determine whether the socket is open. - bool is_open(const implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - boost::system::error_code close(implementation_type& impl, - boost::system::error_code& ec) - { - if (is_open(impl)) - { - reactor_.close_descriptor(impl.socket_, impl.reactor_data_); - - if (impl.flags_ & implementation_type::non_blocking) - { - ioctl_arg_type non_blocking = 0; - boost::system::error_code ignored_ec; - socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ignored_ec); - impl.flags_ &= ~implementation_type::non_blocking; - } - - if (socket_ops::close(impl.socket_, ec) == socket_error_retval) - return ec; - - impl.socket_ = invalid_socket; - } - - ec = boost::system::error_code(); + if (!do_assign(impl, protocol.type(), native_socket, ec)) + impl.protocol_ = protocol; return ec; } @@ -243,153 +104,23 @@ public: return impl.socket_; } - // Cancel all operations associated with the socket. - boost::system::error_code cancel(implementation_type& impl, - boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; - } - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const implementation_type& impl, - boost::system::error_code& ec) const - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return false; - } - -#if defined(SIOCATMARK) - boost::asio::detail::ioctl_arg_type value = 0; - socket_ops::ioctl(impl.socket_, SIOCATMARK, &value, ec); -# if defined(ENOTTY) - if (ec.value() == ENOTTY) - ec = boost::asio::error::not_socket; -# endif // defined(ENOTTY) -#else // defined(SIOCATMARK) - int value = sockatmark(impl.socket_); - if (value == -1) - ec = boost::system::error_code(errno, - boost::asio::error::get_system_category()); - else - ec = boost::system::error_code(); -#endif // defined(SIOCATMARK) - return ec ? false : value != 0; - } - - // Determine the number of bytes available for reading. - std::size_t available(const implementation_type& impl, - boost::system::error_code& ec) const - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - boost::asio::detail::ioctl_arg_type value = 0; - socket_ops::ioctl(impl.socket_, FIONREAD, &value, ec); -#if defined(ENOTTY) - if (ec.value() == ENOTTY) - ec = boost::asio::error::not_socket; -#endif // defined(ENOTTY) - return ec ? static_cast<std::size_t>(0) : static_cast<std::size_t>(value); - } - // Bind the socket to the specified local endpoint. boost::system::error_code bind(implementation_type& impl, const endpoint_type& endpoint, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); return ec; } - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(implementation_type& impl, int backlog, - boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - // Set a socket option. template <typename Option> boost::system::error_code set_option(implementation_type& impl, const Option& option, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - if (option.level(impl.protocol_) == custom_socket_option_level - && option.name(impl.protocol_) == enable_connection_aborted_option) - { - if (option.size(impl.protocol_) != sizeof(int)) - { - ec = boost::asio::error::invalid_argument; - } - else - { - if (*reinterpret_cast<const int*>(option.data(impl.protocol_))) - impl.flags_ |= implementation_type::enable_connection_aborted; - else - impl.flags_ &= ~implementation_type::enable_connection_aborted; - ec = boost::system::error_code(); - } - return ec; - } - else - { - if (option.level(impl.protocol_) == SOL_SOCKET - && option.name(impl.protocol_) == SO_LINGER) - { - impl.flags_ |= implementation_type::user_set_linger; - } - - socket_ops::setsockopt(impl.socket_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - -#if defined(__MACH__) && defined(__APPLE__) \ -|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - // To implement portable behaviour for SO_REUSEADDR with UDP sockets we - // need to also set SO_REUSEPORT on BSD-based platforms. - if (!ec && impl.protocol_.type() == SOCK_DGRAM - && option.level(impl.protocol_) == SOL_SOCKET - && option.name(impl.protocol_) == SO_REUSEADDR) - { - boost::system::error_code ignored_ec; - socket_ops::setsockopt(impl.socket_, SOL_SOCKET, SO_REUSEPORT, - option.data(impl.protocol_), option.size(impl.protocol_), - ignored_ec); - } -#endif - - return ec; - } + socket_ops::setsockopt(impl.socket_, impl.state_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), option.size(impl.protocol_), ec); + return ec; } // Set a socket option. @@ -397,78 +128,12 @@ public: boost::system::error_code get_option(const implementation_type& impl, Option& option, boost::system::error_code& ec) const { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - if (option.level(impl.protocol_) == custom_socket_option_level - && option.name(impl.protocol_) == enable_connection_aborted_option) - { - if (option.size(impl.protocol_) != sizeof(int)) - { - ec = boost::asio::error::invalid_argument; - } - else - { - int* target = reinterpret_cast<int*>(option.data(impl.protocol_)); - if (impl.flags_ & implementation_type::enable_connection_aborted) - *target = 1; - else - *target = 0; - option.resize(impl.protocol_, sizeof(int)); - ec = boost::system::error_code(); - } - return ec; - } - else - { - size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - } - - // Perform an IO control command on the socket. - template <typename IO_Control_Command> - boost::system::error_code io_control(implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - socket_ops::ioctl(impl.socket_, command.name(), - static_cast<ioctl_arg_type*>(command.data()), ec); - - // When updating the non-blocking mode we always perform the ioctl - // syscall, even if the flags would otherwise indicate that the socket is - // already in the correct state. This ensures that the underlying socket - // is put into the state that has been requested by the user. If the ioctl - // syscall was successful then we need to update the flags to match. - if (!ec && command.name() == static_cast<int>(FIONBIO)) - { - if (*static_cast<ioctl_arg_type*>(command.data())) - { - impl.flags_ |= implementation_type::user_set_non_blocking; - } - else - { - // Clearing the non-blocking mode always overrides any internally-set - // non-blocking flag. Any subsequent asynchronous operations will need - // to re-enable non-blocking I/O. - impl.flags_ &= ~(implementation_type::user_set_non_blocking - | implementation_type::internal_non_blocking); - } - } - + std::size_t size = option.size(impl.protocol_); + socket_ops::getsockopt(impl.socket_, impl.state_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), &size, ec); + if (!ec) + option.resize(impl.protocol_, size); return ec; } @@ -476,12 +141,6 @@ public: endpoint_type local_endpoint(const implementation_type& impl, boost::system::error_code& ec) const { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return endpoint_type(); - } - endpoint_type endpoint; std::size_t addr_len = endpoint.capacity(); if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) @@ -494,218 +153,15 @@ public: endpoint_type remote_endpoint(const implementation_type& impl, boost::system::error_code& ec) const { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return endpoint_type(); - } - endpoint_type endpoint; std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec)) + if (socket_ops::getpeername(impl.socket_, + endpoint.data(), &addr_len, false, ec)) return endpoint_type(); endpoint.resize(addr_len); return endpoint; } - /// Disable sends or receives on the socket. - boost::system::error_code shutdown(implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send the given data to the peer. - template <typename ConstBufferSequence> - size_t send(implementation_type& impl, const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - buffer_sequence_adapter<boost::asio::const_buffer, - ConstBufferSequence> bufs(buffers); - - // A request to receive 0 bytes on a stream socket is a no-op. - if (impl.protocol_.type() == SOCK_STREAM && bufs.all_empty()) - { - ec = boost::system::error_code(); - return 0; - } - - // Send the data. - for (;;) - { - // Try to complete the operation without blocking. - int bytes_sent = socket_ops::send(impl.socket_, - bufs.buffers(), bufs.count(), flags, ec); - - // Check if operation succeeded. - if (bytes_sent >= 0) - return bytes_sent; - - // Operation failed. - if ((impl.flags_ & implementation_type::user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_write(impl.socket_, ec) < 0) - return 0; - } - } - - // Wait until data can be sent without blocking. - size_t send(implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, ec); - - return 0; - } - - template <typename ConstBufferSequence> - class send_op_base : public reactor_op - { - public: - send_op_base(socket_type socket, const ConstBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op(&send_op_base::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - flags_(flags) - { - } - - static bool do_perform(reactor_op* base) - { - send_op_base* o(static_cast<send_op_base*>(base)); - - buffer_sequence_adapter<boost::asio::const_buffer, - ConstBufferSequence> bufs(o->buffers_); - - for (;;) - { - // Send the data. - boost::system::error_code ec; - int bytes = socket_ops::send(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, ec); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - o->ec_ = ec; - o->bytes_transferred_ = (bytes < 0 ? 0 : bytes); - return true; - } - } - - private: - socket_type socket_; - ConstBufferSequence buffers_; - socket_base::message_flags flags_; - }; - - template <typename ConstBufferSequence, typename Handler> - class send_op : public send_op_base<ConstBufferSequence> - { - public: - send_op(socket_type socket, const ConstBufferSequence& buffers, - socket_base::message_flags flags, Handler handler) - : send_op_base<ConstBufferSequence>(socket, - buffers, flags, &send_op::do_complete), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - send_op* o(static_cast<send_op*>(base)); - typedef handler_alloc_traits<Handler, send_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, o->ec_, o->bytes_transferred_); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - Handler handler_; - }; - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template <typename ConstBufferSequence, typename Handler> - void async_send(implementation_type& impl, const ConstBufferSequence& buffers, - socket_base::message_flags flags, Handler handler) - { - // Allocate and construct an operation to wrap the handler. - typedef send_op<ConstBufferSequence, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, - impl.socket_, buffers, flags, handler); - - start_op(impl, reactor::write_op, ptr.get(), true, - (impl.protocol_.type() == SOCK_STREAM - && buffer_sequence_adapter<boost::asio::const_buffer, - ConstBufferSequence>::all_empty(buffers))); - ptr.release(); - } - - // Start an asynchronous wait until data can be sent without blocking. - template <typename Handler> - void async_send(implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler handler) - { - // Allocate and construct an operation to wrap the handler. - typedef null_buffers_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); - - start_op(impl, reactor::write_op, ptr.get(), false, false); - ptr.release(); - } - // Send a datagram to the specified endpoint. Returns the number of bytes // sent. template <typename ConstBufferSequence> @@ -713,148 +169,25 @@ public: const endpoint_type& destination, socket_base::message_flags flags, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - buffer_sequence_adapter<boost::asio::const_buffer, ConstBufferSequence> bufs(buffers); - // Send the data. - for (;;) - { - // Try to complete the operation without blocking. - int bytes_sent = socket_ops::sendto(impl.socket_, bufs.buffers(), - bufs.count(), flags, destination.data(), destination.size(), ec); - - // Check if operation succeeded. - if (bytes_sent >= 0) - return bytes_sent; - - // Operation failed. - if ((impl.flags_ & implementation_type::user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_write(impl.socket_, ec) < 0) - return 0; - } + return socket_ops::sync_sendto(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), flags, + destination.data(), destination.size(), ec); } // Wait until data can be sent without blocking. size_t send_to(implementation_type& impl, const null_buffers&, - socket_base::message_flags, const endpoint_type&, + const endpoint_type&, socket_base::message_flags, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - // Wait for socket to become ready. socket_ops::poll_write(impl.socket_, ec); return 0; } - template <typename ConstBufferSequence> - class send_to_op_base : public reactor_op - { - public: - send_to_op_base(socket_type socket, const ConstBufferSequence& buffers, - const endpoint_type& endpoint, socket_base::message_flags flags, - func_type complete_func) - : reactor_op(&send_to_op_base::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - destination_(endpoint), - flags_(flags) - { - } - - static bool do_perform(reactor_op* base) - { - send_to_op_base* o(static_cast<send_to_op_base*>(base)); - - buffer_sequence_adapter<boost::asio::const_buffer, - ConstBufferSequence> bufs(o->buffers_); - - for (;;) - { - // Send the data. - boost::system::error_code ec; - int bytes = socket_ops::sendto(o->socket_, bufs.buffers(), bufs.count(), - o->flags_, o->destination_.data(), o->destination_.size(), ec); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - o->ec_ = ec; - o->bytes_transferred_ = (bytes < 0 ? 0 : bytes); - return true; - } - } - - private: - socket_type socket_; - ConstBufferSequence buffers_; - endpoint_type destination_; - socket_base::message_flags flags_; - }; - - template <typename ConstBufferSequence, typename Handler> - class send_to_op : public send_to_op_base<ConstBufferSequence> - { - public: - send_to_op(socket_type socket, const ConstBufferSequence& buffers, - const endpoint_type& endpoint, socket_base::message_flags flags, - Handler handler) - : send_to_op_base<ConstBufferSequence>(socket, - buffers, endpoint, flags, &send_to_op::do_complete), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - send_to_op* o(static_cast<send_to_op*>(base)); - typedef handler_alloc_traits<Handler, send_to_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, o->ec_, o->bytes_transferred_); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - Handler handler_; - }; - // Start an asynchronous send. The data being sent must be valid for the // lifetime of the asynchronous operation. template <typename ConstBufferSequence, typename Handler> @@ -864,235 +197,31 @@ public: Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef send_to_op<ConstBufferSequence, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, impl.socket_, - buffers, destination, flags, handler); + typedef reactive_socket_sendto_op<ConstBufferSequence, + endpoint_type, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler); - start_op(impl, reactor::write_op, ptr.get(), true, false); - ptr.release(); + start_op(impl, reactor::write_op, p.p, true, false); + p.v = p.p = 0; } // Start an asynchronous wait until data can be sent without blocking. template <typename Handler> void async_send_to(implementation_type& impl, const null_buffers&, - socket_base::message_flags, const endpoint_type&, Handler handler) + const endpoint_type&, socket_base::message_flags, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef null_buffers_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); - - start_op(impl, reactor::write_op, ptr.get(), false, false); - ptr.release(); - } - - // Receive some data from the peer. Returns the number of bytes received. - template <typename MutableBufferSequence> - size_t receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - buffer_sequence_adapter<boost::asio::mutable_buffer, - MutableBufferSequence> bufs(buffers); - - // A request to receive 0 bytes on a stream socket is a no-op. - if (impl.protocol_.type() == SOCK_STREAM && bufs.all_empty()) - { - ec = boost::system::error_code(); - return 0; - } - - // Receive some data. - for (;;) - { - // Try to complete the operation without blocking. - int bytes_recvd = socket_ops::recv(impl.socket_, - bufs.buffers(), bufs.count(), flags, ec); - - // Check if operation succeeded. - if (bytes_recvd > 0) - return bytes_recvd; - - // Check for EOF. - if (bytes_recvd == 0 && impl.protocol_.type() == SOCK_STREAM) - { - ec = boost::asio::error::eof; - return 0; - } - - // Operation failed. - if ((impl.flags_ & implementation_type::user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(impl.socket_, ec) < 0) - return 0; - } - } - - // Wait until data can be received without blocking. - size_t receive(implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, ec); + typedef reactive_null_buffers_op<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); - return 0; - } - - template <typename MutableBufferSequence> - class receive_op_base : public reactor_op - { - public: - receive_op_base(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op(&receive_op_base::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - flags_(flags) - { - } - - static bool do_perform(reactor_op* base) - { - receive_op_base* o(static_cast<receive_op_base*>(base)); - - buffer_sequence_adapter<boost::asio::mutable_buffer, - MutableBufferSequence> bufs(o->buffers_); - - for (;;) - { - // Receive some data. - boost::system::error_code ec; - int bytes = socket_ops::recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, ec); - if (bytes == 0 && o->protocol_type_ == SOCK_STREAM) - ec = boost::asio::error::eof; - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - o->ec_ = ec; - o->bytes_transferred_ = (bytes < 0 ? 0 : bytes); - return true; - } - } - - private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; - }; - - template <typename MutableBufferSequence, typename Handler> - class receive_op : public receive_op_base<MutableBufferSequence> - { - public: - receive_op(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler handler) - : receive_op_base<MutableBufferSequence>(socket, - protocol_type, buffers, flags, &receive_op::do_complete), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - receive_op* o(static_cast<receive_op*>(base)); - typedef handler_alloc_traits<Handler, receive_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, o->ec_, o->bytes_transferred_); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - Handler handler_; - }; - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template <typename MutableBufferSequence, typename Handler> - void async_receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler handler) - { - // Allocate and construct an operation to wrap the handler. - typedef receive_op<MutableBufferSequence, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - int protocol_type = impl.protocol_.type(); - handler_ptr<alloc_traits> ptr(raw_ptr, impl.socket_, - protocol_type, buffers, flags, handler); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - ptr.get(), (flags & socket_base::message_out_of_band) == 0, - (impl.protocol_.type() == SOCK_STREAM - && buffer_sequence_adapter<boost::asio::mutable_buffer, - MutableBufferSequence>::all_empty(buffers))); - ptr.release(); - } - - // Wait until data can be received without blocking. - template <typename Handler> - void async_receive(implementation_type& impl, const null_buffers&, - socket_base::message_flags flags, Handler handler) - { - // Allocate and construct an operation to wrap the handler. - typedef null_buffers_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - ptr.get(), false, false); - ptr.release(); + start_op(impl, reactor::write_op, p.p, false, false); + p.v = p.p = 0; } // Receive a datagram with the endpoint of the sender. Returns the number of @@ -1103,47 +232,18 @@ public: endpoint_type& sender_endpoint, socket_base::message_flags flags, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - buffer_sequence_adapter<boost::asio::mutable_buffer, MutableBufferSequence> bufs(buffers); - // Receive some data. - for (;;) - { - // Try to complete the operation without blocking. - std::size_t addr_len = sender_endpoint.capacity(); - int bytes_recvd = socket_ops::recvfrom(impl.socket_, bufs.buffers(), - bufs.count(), flags, sender_endpoint.data(), &addr_len, ec); + std::size_t addr_len = sender_endpoint.capacity(); + std::size_t bytes_recvd = socket_ops::sync_recvfrom( + impl.socket_, impl.state_, bufs.buffers(), bufs.count(), + flags, sender_endpoint.data(), &addr_len, ec); - // Check if operation succeeded. - if (bytes_recvd > 0) - { - sender_endpoint.resize(addr_len); - return bytes_recvd; - } + if (!ec) + sender_endpoint.resize(addr_len); - // Check for EOF. - if (bytes_recvd == 0 && impl.protocol_.type() == SOCK_STREAM) - { - ec = boost::asio::error::eof; - return 0; - } - - // Operation failed. - if ((impl.flags_ & implementation_type::user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(impl.socket_, ec) < 0) - return 0; - } + return bytes_recvd; } // Wait until data can be received without blocking. @@ -1151,12 +251,6 @@ public: endpoint_type& sender_endpoint, socket_base::message_flags, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - // Wait for socket to become ready. socket_ops::poll_read(impl.socket_, ec); @@ -1166,105 +260,6 @@ public: return 0; } - template <typename MutableBufferSequence> - class receive_from_op_base : public reactor_op - { - public: - receive_from_op_base(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, endpoint_type& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op(&receive_from_op_base::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static bool do_perform(reactor_op* base) - { - receive_from_op_base* o(static_cast<receive_from_op_base*>(base)); - - buffer_sequence_adapter<boost::asio::mutable_buffer, - MutableBufferSequence> bufs(o->buffers_); - - for (;;) - { - // Receive some data. - boost::system::error_code ec; - std::size_t addr_len = o->sender_endpoint_.capacity(); - int bytes = socket_ops::recvfrom(o->socket_, bufs.buffers(), - bufs.count(), o->flags_, o->sender_endpoint_.data(), &addr_len, ec); - if (bytes == 0 && o->protocol_type_ == SOCK_STREAM) - ec = boost::asio::error::eof; - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - o->sender_endpoint_.resize(addr_len); - o->ec_ = ec; - o->bytes_transferred_ = (bytes < 0 ? 0 : bytes); - return true; - } - } - - private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - endpoint_type& sender_endpoint_; - socket_base::message_flags flags_; - }; - - template <typename MutableBufferSequence, typename Handler> - class receive_from_op : public receive_from_op_base<MutableBufferSequence> - { - public: - receive_from_op(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, endpoint_type& endpoint, - socket_base::message_flags flags, Handler handler) - : receive_from_op_base<MutableBufferSequence>(socket, protocol_type, - buffers, endpoint, flags, &receive_from_op::do_complete), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - receive_from_op* o(static_cast<receive_from_op*>(base)); - typedef handler_alloc_traits<Handler, receive_from_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, o->ec_, o->bytes_transferred_); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - Handler handler_; - }; - // Start an asynchronous receive. The buffer for the data being received and // the sender_endpoint object must both be valid for the lifetime of the // asynchronous operation. @@ -1274,18 +269,20 @@ public: socket_base::message_flags flags, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef receive_from_op<MutableBufferSequence, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); + typedef reactive_socket_recvfrom_op<MutableBufferSequence, + endpoint_type, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; int protocol_type = impl.protocol_.type(); - handler_ptr<alloc_traits> ptr(raw_ptr, impl.socket_, - protocol_type, buffers, sender_endpoint, flags, handler); + p.p = new (p.v) op(impl.socket_, protocol_type, + buffers, sender_endpoint, flags, handler); start_op(impl, (flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op, - ptr.get(), true, false); - ptr.release(); + p.p, true, false); + p.v = p.p = 0; } // Wait until data can be received without blocking. @@ -1295,10 +292,11 @@ public: socket_base::message_flags flags, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef null_buffers_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); + typedef reactive_null_buffers_op<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); // Reset endpoint since it can be given no sensible value at this time. sender_endpoint = endpoint_type(); @@ -1306,8 +304,8 @@ public: start_op(impl, (flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op, - ptr.get(), false, false); - ptr.release(); + p.p, false, false); + p.v = p.p = 0; } // Accept a new connection. @@ -1315,12 +313,6 @@ public: boost::system::error_code accept(implementation_type& impl, Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - // We cannot accept a socket that is already open. if (peer.is_open()) { @@ -1328,181 +320,22 @@ public: return ec; } - // Accept a socket. - for (;;) - { - // Try to complete the operation without blocking. - socket_holder new_socket; - std::size_t addr_len = 0; - if (peer_endpoint) - { - addr_len = peer_endpoint->capacity(); - new_socket.reset(socket_ops::accept(impl.socket_, - peer_endpoint->data(), &addr_len, ec)); - } - else - { - new_socket.reset(socket_ops::accept(impl.socket_, 0, 0, ec)); - } - - // Check if operation succeeded. - if (new_socket.get() >= 0) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - return ec; - } + std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; + socket_holder new_socket(socket_ops::sync_accept(impl.socket_, + impl.state_, peer_endpoint ? peer_endpoint->data() : 0, + peer_endpoint ? &addr_len : 0, ec)); - // Operation failed. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - { - if (impl.flags_ & implementation_type::user_set_non_blocking) - return ec; - // Fall through to retry operation. - } - else if (ec == boost::asio::error::connection_aborted) - { - if (impl.flags_ & implementation_type::enable_connection_aborted) - return ec; - // Fall through to retry operation. - } -#if defined(EPROTO) - else if (ec.value() == EPROTO) - { - if (impl.flags_ & implementation_type::enable_connection_aborted) - return ec; - // Fall through to retry operation. - } -#endif // defined(EPROTO) - else - return ec; - - // Wait for socket to become ready. - if (socket_ops::poll_read(impl.socket_, ec) < 0) - return ec; - } - } - - template <typename Socket> - class accept_op_base : public reactor_op - { - public: - accept_op_base(socket_type socket, Socket& peer, - const protocol_type& protocol, endpoint_type* peer_endpoint, - bool enable_connection_aborted, func_type complete_func) - : reactor_op(&accept_op_base::do_perform, complete_func), - socket_(socket), - peer_(peer), - protocol_(protocol), - peer_endpoint_(peer_endpoint), - enable_connection_aborted_(enable_connection_aborted) - { - } - - static bool do_perform(reactor_op* base) + // On success, assign new connection to peer socket object. + if (new_socket.get() != invalid_socket) { - accept_op_base* o(static_cast<accept_op_base*>(base)); - - for (;;) - { - // Accept the waiting connection. - boost::system::error_code ec; - socket_holder new_socket; - std::size_t addr_len = 0; - std::size_t* addr_len_p = 0; - socket_addr_type* addr = 0; - if (o->peer_endpoint_) - { - addr_len = o->peer_endpoint_->capacity(); - addr_len_p = &addr_len; - addr = o->peer_endpoint_->data(); - } - new_socket.reset(socket_ops::accept(o->socket_, addr, addr_len_p, ec)); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - if (ec == boost::asio::error::connection_aborted - && !o->enable_connection_aborted_) - return false; -#if defined(EPROTO) - if (ec.value() == EPROTO && !o->enable_connection_aborted_) - return false; -#endif // defined(EPROTO) - - // Transfer ownership of the new socket to the peer object. - if (!ec) - { - if (o->peer_endpoint_) - o->peer_endpoint_->resize(addr_len); - o->peer_.assign(o->protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - o->ec_ = ec; - return true; - } - } - - private: - socket_type socket_; - Socket& peer_; - protocol_type protocol_; - endpoint_type* peer_endpoint_; - bool enable_connection_aborted_; - }; - - template <typename Socket, typename Handler> - class accept_op : public accept_op_base<Socket> - { - public: - accept_op(socket_type socket, Socket& peer, const protocol_type& protocol, - endpoint_type* peer_endpoint, bool enable_connection_aborted, - Handler handler) - : accept_op_base<Socket>(socket, peer, protocol, peer_endpoint, - enable_connection_aborted, &accept_op::do_complete), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - accept_op* o(static_cast<accept_op*>(base)); - typedef handler_alloc_traits<Handler, accept_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder1<Handler, boost::system::error_code> - handler(o->handler_, o->ec_); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } + if (peer_endpoint) + peer_endpoint->resize(addr_len); + if (!peer.assign(impl.protocol_, new_socket.get(), ec)) + new_socket.release(); } - private: - Handler handler_; - }; + return ec; + } // Start an asynchronous accept. The peer and peer_endpoint objects // must be valid until the accept's handler is invoked. @@ -1511,230 +344,41 @@ public: endpoint_type* peer_endpoint, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef accept_op<Socket, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - bool enable_connection_aborted = - (impl.flags_ & implementation_type::enable_connection_aborted) != 0; - handler_ptr<alloc_traits> ptr(raw_ptr, impl.socket_, peer, - impl.protocol_, peer_endpoint, enable_connection_aborted, handler); + typedef reactive_socket_accept_op<Socket, Protocol, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, impl.state_, peer, + impl.protocol_, peer_endpoint, handler); - start_accept_op(impl, ptr.get(), peer.is_open()); - ptr.release(); + start_accept_op(impl, p.p, peer.is_open()); + p.v = p.p = 0; } // Connect the socket to the specified endpoint. boost::system::error_code connect(implementation_type& impl, const endpoint_type& peer_endpoint, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - // Perform the connect operation. - socket_ops::connect(impl.socket_, + socket_ops::sync_connect(impl.socket_, peer_endpoint.data(), peer_endpoint.size(), ec); - if (ec != boost::asio::error::in_progress - && ec != boost::asio::error::would_block) - { - // The connect operation finished immediately. - return ec; - } - - // Wait for socket to become ready. - if (socket_ops::poll_connect(impl.socket_, ec) < 0) - return ec; - - // Get the error code from the connect operation. - int connect_error = 0; - size_t connect_error_len = sizeof(connect_error); - if (socket_ops::getsockopt(impl.socket_, SOL_SOCKET, SO_ERROR, - &connect_error, &connect_error_len, ec) == socket_error_retval) - return ec; - - // Return the result of the connect operation. - ec = boost::system::error_code(connect_error, - boost::asio::error::get_system_category()); return ec; } - class connect_op_base : public reactor_op - { - public: - connect_op_base(socket_type socket, func_type complete_func) - : reactor_op(&connect_op_base::do_perform, complete_func), - socket_(socket) - { - } - - static bool do_perform(reactor_op* base) - { - connect_op_base* o(static_cast<connect_op_base*>(base)); - - // Get the error code from the connect operation. - int connect_error = 0; - size_t connect_error_len = sizeof(connect_error); - if (socket_ops::getsockopt(o->socket_, SOL_SOCKET, SO_ERROR, - &connect_error, &connect_error_len, o->ec_) == socket_error_retval) - return true; - - // The connection failed so the handler will be posted with an error code. - if (connect_error) - { - o->ec_ = boost::system::error_code(connect_error, - boost::asio::error::get_system_category()); - } - - return true; - } - - private: - socket_type socket_; - }; - - template <typename Handler> - class connect_op : public connect_op_base - { - public: - connect_op(socket_type socket, Handler handler) - : connect_op_base(socket, &connect_op::do_complete), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - connect_op* o(static_cast<connect_op*>(base)); - typedef handler_alloc_traits<Handler, connect_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder1<Handler, boost::system::error_code> - handler(o->handler_, o->ec_); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - Handler handler_; - }; - // Start an asynchronous connect. template <typename Handler> void async_connect(implementation_type& impl, const endpoint_type& peer_endpoint, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef connect_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, impl.socket_, handler); - - start_connect_op(impl, ptr.get(), peer_endpoint); - ptr.release(); - } - -private: - // Start the asynchronous read or write operation. - void start_op(implementation_type& impl, int op_type, - reactor_op* op, bool non_blocking, bool noop) - { - if (!noop) - { - if (is_open(impl)) - { - if (!non_blocking || is_non_blocking(impl) - || set_non_blocking(impl, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, non_blocking); - return; - } - } - else - op->ec_ = boost::asio::error::bad_descriptor; - } + typedef reactive_socket_connect_op<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, handler); - io_service_impl_.post_immediate_completion(op); + start_connect_op(impl, p.p, peer_endpoint.data(), peer_endpoint.size()); + p.v = p.p = 0; } - - // Start the asynchronous accept operation. - void start_accept_op(implementation_type& impl, - reactor_op* op, bool peer_is_open) - { - if (!peer_is_open) - start_op(impl, reactor::read_op, op, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - io_service_impl_.post_immediate_completion(op); - } - } - - // Start the asynchronous connect operation. - void start_connect_op(implementation_type& impl, - reactor_op* op, const endpoint_type& peer_endpoint) - { - if (is_open(impl)) - { - if (is_non_blocking(impl) || set_non_blocking(impl, op->ec_)) - { - if (socket_ops::connect(impl.socket_, peer_endpoint.data(), - peer_endpoint.size(), op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, - impl.socket_, impl.reactor_data_, op, false); - return; - } - } - } - } - else - op->ec_ = boost::asio::error::bad_descriptor; - - io_service_impl_.post_immediate_completion(op); - } - - // Determine whether the socket has been set non-blocking. - bool is_non_blocking(implementation_type& impl) const - { - return (impl.flags_ & implementation_type::non_blocking); - } - - // Set the internal non-blocking flag. - bool set_non_blocking(implementation_type& impl, - boost::system::error_code& ec) - { - ioctl_arg_type non_blocking = 1; - if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec)) - return false; - impl.flags_ |= implementation_type::internal_non_blocking; - return true; - } - - // The io_service implementation used to post completions. - io_service_impl& io_service_impl_; - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; }; } // namespace detail @@ -1743,4 +387,6 @@ private: #include <boost/asio/detail/pop_options.hpp> +#endif // !defined(BOOST_ASIO_HAS_IOCP) + #endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/reactive_socket_service_base.hpp b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_service_base.hpp new file mode 100644 index 0000000..1733ce1 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/reactive_socket_service_base.hpp @@ -0,0 +1,300 @@ +// +// detail/reactive_socket_service_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if !defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/utility/addressof.hpp> +#include <boost/asio/buffer.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/socket_base.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/reactive_null_buffers_op.hpp> +#include <boost/asio/detail/reactive_socket_recv_op.hpp> +#include <boost/asio/detail/reactive_socket_send_op.hpp> +#include <boost/asio/detail/reactor.hpp> +#include <boost/asio/detail/reactor_op.hpp> +#include <boost/asio/detail/socket_holder.hpp> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/detail/socket_types.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +class reactive_socket_service_base +{ +public: + // The native type of a socket. + typedef socket_type native_type; + + // The implementation type of the socket. + struct base_implementation_type + { + // The native socket representation. + socket_type socket_; + + // The current state of the socket. + socket_ops::state_type state_; + + // Per-descriptor data used by the reactor. + reactor::per_descriptor_data reactor_data_; + }; + + // Constructor. + BOOST_ASIO_DECL reactive_socket_service_base( + boost::asio::io_service& io_service); + + // Destroy all user-defined handler objects owned by the service. + BOOST_ASIO_DECL void shutdown_service(); + + // Construct a new socket implementation. + BOOST_ASIO_DECL void construct(base_implementation_type& impl); + + // Destroy a socket implementation. + BOOST_ASIO_DECL void destroy(base_implementation_type& impl); + + // Determine whether the socket is open. + bool is_open(const base_implementation_type& impl) const + { + return impl.socket_ != invalid_socket; + } + + // Destroy a socket implementation. + BOOST_ASIO_DECL boost::system::error_code close( + base_implementation_type& impl, boost::system::error_code& ec); + + // Get the native socket representation. + native_type native(base_implementation_type& impl) + { + return impl.socket_; + } + + // Cancel all operations associated with the socket. + BOOST_ASIO_DECL boost::system::error_code cancel( + base_implementation_type& impl, boost::system::error_code& ec); + + // Determine whether the socket is at the out-of-band data mark. + bool at_mark(const base_implementation_type& impl, + boost::system::error_code& ec) const + { + return socket_ops::sockatmark(impl.socket_, ec); + } + + // Determine the number of bytes available for reading. + std::size_t available(const base_implementation_type& impl, + boost::system::error_code& ec) const + { + return socket_ops::available(impl.socket_, ec); + } + + // Place the socket into the state where it will listen for new connections. + boost::system::error_code listen(base_implementation_type& impl, + int backlog, boost::system::error_code& ec) + { + socket_ops::listen(impl.socket_, backlog, ec); + return ec; + } + + // Perform an IO control command on the socket. + template <typename IO_Control_Command> + boost::system::error_code io_control(base_implementation_type& impl, + IO_Control_Command& command, boost::system::error_code& ec) + { + socket_ops::ioctl(impl.socket_, impl.state_, command.name(), + static_cast<ioctl_arg_type*>(command.data()), ec); + return ec; + } + + /// Disable sends or receives on the socket. + boost::system::error_code shutdown(base_implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) + { + socket_ops::shutdown(impl.socket_, what, ec); + return ec; + } + + // Send the given data to the peer. + template <typename ConstBufferSequence> + size_t send(base_implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + buffer_sequence_adapter<boost::asio::const_buffer, + ConstBufferSequence> bufs(buffers); + + return socket_ops::sync_send(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); + } + + // Wait until data can be sent without blocking. + size_t send(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags, boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_write(impl.socket_, ec); + + return 0; + } + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template <typename ConstBufferSequence, typename Handler> + void async_send(base_implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_send_op<ConstBufferSequence, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, buffers, flags, handler); + + start_op(impl, reactor::write_op, p.p, true, + ((impl.state_ & socket_ops::stream_oriented) + && buffer_sequence_adapter<boost::asio::const_buffer, + ConstBufferSequence>::all_empty(buffers))); + p.v = p.p = 0; + } + + // Start an asynchronous wait until data can be sent without blocking. + template <typename Handler> + void async_send(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef reactive_null_buffers_op<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + start_op(impl, reactor::write_op, p.p, false, false); + p.v = p.p = 0; + } + + // Receive some data from the peer. Returns the number of bytes received. + template <typename MutableBufferSequence> + size_t receive(base_implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + buffer_sequence_adapter<boost::asio::mutable_buffer, + MutableBufferSequence> bufs(buffers); + + return socket_ops::sync_recv(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); + } + + // Wait until data can be received without blocking. + size_t receive(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags, boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_read(impl.socket_, ec); + + return 0; + } + + // Start an asynchronous receive. The buffer for the data being received + // must be valid for the lifetime of the asynchronous operation. + template <typename MutableBufferSequence, typename Handler> + void async_receive(base_implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_recv_op<MutableBufferSequence, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, (flags & socket_base::message_out_of_band) == 0, + ((impl.state_ & socket_ops::stream_oriented) + && buffer_sequence_adapter<boost::asio::mutable_buffer, + MutableBufferSequence>::all_empty(buffers))); + p.v = p.p = 0; + } + + // Wait until data can be received without blocking. + template <typename Handler> + void async_receive(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef reactive_null_buffers_op<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, false, false); + p.v = p.p = 0; + } + +protected: + // Open a new socket implementation. + BOOST_ASIO_DECL boost::system::error_code do_open( + base_implementation_type& impl, int af, + int type, int protocol, boost::system::error_code& ec); + + // Assign a native socket to a socket implementation. + BOOST_ASIO_DECL boost::system::error_code do_assign( + base_implementation_type& impl, int type, + const native_type& native_socket, boost::system::error_code& ec); + + // Start the asynchronous read or write operation. + BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, + reactor_op* op, bool non_blocking, bool noop); + + // Start the asynchronous accept operation. + BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, + reactor_op* op, bool peer_is_open); + + // Start the asynchronous connect operation. + BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, + reactor_op* op, const socket_addr_type* addr, size_t addrlen); + + // The selector that performs event demultiplexing for the service. + reactor& reactor_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/reactive_socket_service_base.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // !defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/reactor.hpp b/3rdParty/Boost/src/boost/asio/detail/reactor.hpp index 43e432b..468276d 100644 --- a/3rdParty/Boost/src/boost/asio/detail/reactor.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/reactor.hpp @@ -1,6 +1,6 @@ // -// reactor.hpp -// ~~~~~~~~~~~ +// detail/reactor.hpp +// ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,8 +15,6 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - #include <boost/asio/detail/reactor_fwd.hpp> #if defined(BOOST_ASIO_HAS_EPOLL) @@ -29,6 +27,4 @@ # include <boost/asio/detail/select_reactor.hpp> #endif -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_REACTOR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/reactor_fwd.hpp b/3rdParty/Boost/src/boost/asio/detail/reactor_fwd.hpp index 9ff05eb..3fae83c 100644 --- a/3rdParty/Boost/src/boost/asio/detail/reactor_fwd.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/reactor_fwd.hpp @@ -1,6 +1,6 @@ // -// reactor_fwd.hpp -// ~~~~~~~~~~~~~~~ +// detail/reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,20 +15,26 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/dev_poll_reactor_fwd.hpp> -#include <boost/asio/detail/epoll_reactor_fwd.hpp> -#include <boost/asio/detail/kqueue_reactor_fwd.hpp> -#include <boost/asio/detail/select_reactor_fwd.hpp> -#include <boost/asio/detail/win_iocp_io_service_fwd.hpp> +#if defined(BOOST_ASIO_HAS_IOCP) +# include <boost/asio/detail/select_reactor_fwd.hpp> +#elif defined(BOOST_ASIO_HAS_EPOLL) +# include <boost/asio/detail/epoll_reactor_fwd.hpp> +#elif defined(BOOST_ASIO_HAS_KQUEUE) +# include <boost/asio/detail/kqueue_reactor_fwd.hpp> +#elif defined(BOOST_ASIO_HAS_DEV_POLL) +# include <boost/asio/detail/dev_poll_reactor_fwd.hpp> +#else +# include <boost/asio/detail/select_reactor_fwd.hpp> +#endif namespace boost { namespace asio { namespace detail { #if defined(BOOST_ASIO_HAS_IOCP) -typedef select_reactor<true> reactor; +typedef select_reactor reactor; #elif defined(BOOST_ASIO_HAS_EPOLL) typedef epoll_reactor reactor; #elif defined(BOOST_ASIO_HAS_KQUEUE) @@ -36,13 +42,11 @@ typedef kqueue_reactor reactor; #elif defined(BOOST_ASIO_HAS_DEV_POLL) typedef dev_poll_reactor reactor; #else -typedef select_reactor<false> reactor; +typedef select_reactor reactor; #endif } // namespace detail } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_REACTOR_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/reactor_op.hpp b/3rdParty/Boost/src/boost/asio/detail/reactor_op.hpp index 40647ec..ed4a33d 100644 --- a/3rdParty/Boost/src/boost/asio/detail/reactor_op.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/reactor_op.hpp @@ -1,6 +1,6 @@ // -// reactor_op.hpp -// ~~~~~~~~~~~~ +// detail/reactor_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,10 +15,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { diff --git a/3rdParty/Boost/src/boost/asio/detail/reactor_op_queue.hpp b/3rdParty/Boost/src/boost/asio/detail/reactor_op_queue.hpp index 0dd5654..830e9b3 100644 --- a/3rdParty/Boost/src/boost/asio/detail/reactor_op_queue.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/reactor_op_queue.hpp @@ -1,6 +1,6 @@ // -// reactor_op_queue.hpp -// ~~~~~~~~~~~~~~~~~~~~ +// detail/reactor_op_queue.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,13 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/error.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/hash_map.hpp> #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/op_queue.hpp> #include <boost/asio/detail/reactor_op.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/detail/regex_fwd.hpp b/3rdParty/Boost/src/boost/asio/detail/regex_fwd.hpp new file mode 100644 index 0000000..2ccb5d1 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/regex_fwd.hpp @@ -0,0 +1,31 @@ +// +// detail/regex_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_REGEX_FWD_HPP +#define BOOST_ASIO_DETAIL_REGEX_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/regex_fwd.hpp> +#include <boost/regex/v4/match_flags.hpp> + +namespace boost { + +template <class BidiIterator> +struct sub_match; + +template <class BidiIterator, class Allocator> +class match_results; + +} // namespace boost + +#endif // BOOST_ASIO_DETAIL_REGEX_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/resolve_endpoint_op.hpp b/3rdParty/Boost/src/boost/asio/detail/resolve_endpoint_op.hpp new file mode 100644 index 0000000..ccf5f53 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/resolve_endpoint_op.hpp @@ -0,0 +1,118 @@ +// +// detail/resolve_endpoint_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP +#define BOOST_ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/ip/basic_resolver_iterator.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/socket_ops.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Protocol, typename Handler> +class resolve_endpoint_op : public operation +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(resolve_endpoint_op); + + typedef typename Protocol::endpoint endpoint_type; + typedef boost::asio::ip::basic_resolver_iterator<Protocol> iterator_type; + + resolve_endpoint_op(socket_ops::weak_cancel_token_type cancel_token, + const endpoint_type& endpoint, io_service_impl& ios, Handler handler) + : operation(&resolve_endpoint_op::do_complete), + cancel_token_(cancel_token), + endpoint_(endpoint), + io_service_impl_(ios), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the operation object. + resolve_endpoint_op* o(static_cast<resolve_endpoint_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + if (owner && owner != &o->io_service_impl_) + { + // The operation is being run on the worker io_service. Time to perform + // the resolver operation. + + // Perform the blocking endpoint resolution operation. + char host_name[NI_MAXHOST]; + char service_name[NI_MAXSERV]; + socket_ops::background_getnameinfo(o->cancel_token_, o->endpoint_.data(), + o->endpoint_.size(), host_name, NI_MAXHOST, service_name, NI_MAXSERV, + o->endpoint_.protocol().type(), o->ec_); + o->iter_ = iterator_type::create(o->endpoint_, host_name, service_name); + + // Pass operation back to main io_service for completion. + o->io_service_impl_.post_deferred_completion(o); + p.v = p.p = 0; + } + else + { + // The operation has been returned to the main io_service. The completion + // handler is ready to be delivered. + + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an upcall, + // a sub-object of the handler may be the true owner of the memory + // associated with the handler. Consequently, a local copy of the handler + // is required to ensure that any owning sub-object remains valid until + // after we have deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, iterator_type> + handler(o->handler_, o->ec_, o->iter_); + p.h = boost::addressof(handler.handler_); + p.reset(); + + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + } + +private: + socket_ops::weak_cancel_token_type cancel_token_; + endpoint_type endpoint_; + io_service_impl& io_service_impl_; + Handler handler_; + boost::system::error_code ec_; + iterator_type iter_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/resolve_op.hpp b/3rdParty/Boost/src/boost/asio/detail/resolve_op.hpp new file mode 100644 index 0000000..aff6104 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/resolve_op.hpp @@ -0,0 +1,128 @@ +// +// detail/resolve_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_RESOLVE_OP_HPP +#define BOOST_ASIO_DETAIL_RESOLVE_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/ip/basic_resolver_iterator.hpp> +#include <boost/asio/ip/basic_resolver_query.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/socket_ops.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Protocol, typename Handler> +class resolve_op : public operation +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(resolve_op); + + typedef boost::asio::ip::basic_resolver_query<Protocol> query_type; + typedef boost::asio::ip::basic_resolver_iterator<Protocol> iterator_type; + + resolve_op(socket_ops::weak_cancel_token_type cancel_token, + const query_type& query, io_service_impl& ios, Handler handler) + : operation(&resolve_op::do_complete), + cancel_token_(cancel_token), + query_(query), + io_service_impl_(ios), + handler_(handler), + addrinfo_(0) + { + } + + ~resolve_op() + { + if (addrinfo_) + socket_ops::freeaddrinfo(addrinfo_); + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the operation object. + resolve_op* o(static_cast<resolve_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + if (owner && owner != &o->io_service_impl_) + { + // The operation is being run on the worker io_service. Time to perform + // the resolver operation. + + // Perform the blocking host resolution operation. + socket_ops::background_getaddrinfo(o->cancel_token_, + o->query_.host_name().c_str(), o->query_.service_name().c_str(), + o->query_.hints(), &o->addrinfo_, o->ec_); + + // Pass operation back to main io_service for completion. + o->io_service_impl_.post_deferred_completion(o); + p.v = p.p = 0; + } + else + { + // The operation has been returned to the main io_service. The completion + // handler is ready to be delivered. + + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an upcall, + // a sub-object of the handler may be the true owner of the memory + // associated with the handler. Consequently, a local copy of the handler + // is required to ensure that any owning sub-object remains valid until + // after we have deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, iterator_type> + handler(o->handler_, o->ec_, iterator_type()); + p.h = boost::addressof(handler.handler_); + if (o->addrinfo_) + { + handler.arg2_ = iterator_type::create(o->addrinfo_, + o->query_.host_name(), o->query_.service_name()); + } + p.reset(); + + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + } + +private: + socket_ops::weak_cancel_token_type cancel_token_; + query_type query_; + io_service_impl& io_service_impl_; + Handler handler_; + boost::system::error_code ec_; + boost::asio::detail::addrinfo_type* addrinfo_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_RESOLVE_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/resolver_service.hpp b/3rdParty/Boost/src/boost/asio/detail/resolver_service.hpp index f9b7a98..1b734a0 100644 --- a/3rdParty/Boost/src/boost/asio/detail/resolver_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/resolver_service.hpp @@ -1,6 +1,6 @@ // -// resolver_service.hpp -// ~~~~~~~~~~~~~~~~~~~~ +// detail/resolver_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,69 +15,26 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <cstring> -#include <boost/scoped_ptr.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/weak_ptr.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> -#include <boost/asio/io_service.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/asio/ip/basic_resolver_iterator.hpp> #include <boost/asio/ip/basic_resolver_query.hpp> -#include <boost/asio/detail/bind_handler.hpp> -#include <boost/asio/detail/fenced_block.hpp> -#include <boost/asio/detail/mutex.hpp> -#include <boost/asio/detail/noncopyable.hpp> -#include <boost/asio/detail/operation.hpp> -#include <boost/asio/detail/service_base.hpp> -#include <boost/asio/detail/socket_ops.hpp> -#include <boost/asio/detail/socket_types.hpp> -#include <boost/asio/detail/thread.hpp> +#include <boost/asio/detail/resolve_endpoint_op.hpp> +#include <boost/asio/detail/resolve_op.hpp> +#include <boost/asio/detail/resolver_service_base.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace detail { template <typename Protocol> -class resolver_service - : public boost::asio::detail::service_base<resolver_service<Protocol> > +class resolver_service : public resolver_service_base { -private: - // Helper class to perform exception-safe cleanup of addrinfo objects. - class auto_addrinfo - : private boost::asio::detail::noncopyable - { - public: - explicit auto_addrinfo(boost::asio::detail::addrinfo_type* ai) - : ai_(ai) - { - } - - ~auto_addrinfo() - { - if (ai_) - socket_ops::freeaddrinfo(ai_); - } - - operator boost::asio::detail::addrinfo_type*() - { - return ai_; - } - - private: - boost::asio::detail::addrinfo_type* ai_; - }; - public: - // The implementation type of the resolver. The shared pointer is used as a - // cancellation token to indicate to the background thread that the operation - // has been cancelled. - typedef boost::shared_ptr<void> implementation_type; - struct noop_deleter { void operator()(void*) {} }; + // The implementation type of the resolver. A cancellation token is used to + // indicate to the background thread that the operation has been cancelled. + typedef socket_ops::shared_cancel_token_type implementation_type; // The endpoint type. typedef typename Protocol::endpoint endpoint_type; @@ -90,55 +47,8 @@ public: // Constructor. resolver_service(boost::asio::io_service& io_service) - : boost::asio::detail::service_base< - resolver_service<Protocol> >(io_service), - mutex_(), - io_service_impl_(boost::asio::use_service<io_service_impl>(io_service)), - work_io_service_(new boost::asio::io_service), - work_io_service_impl_(boost::asio::use_service< - io_service_impl>(*work_io_service_)), - work_(new boost::asio::io_service::work(*work_io_service_)), - work_thread_(0) - { - } - - // Destructor. - ~resolver_service() + : resolver_service_base(io_service) { - shutdown_service(); - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - work_.reset(); - if (work_io_service_) - { - work_io_service_->stop(); - if (work_thread_) - { - work_thread_->join(); - work_thread_.reset(); - } - work_io_service_.reset(); - } - } - - // Construct a new resolver implementation. - void construct(implementation_type& impl) - { - impl.reset(static_cast<void*>(0), noop_deleter()); - } - - // Destroy a resolver implementation. - void destroy(implementation_type&) - { - } - - // Cancel pending asynchronous operations. - void cancel(implementation_type& impl) - { - impl.reset(static_cast<void*>(0), noop_deleter()); } // Resolve a query to a list of entries. @@ -146,293 +56,60 @@ public: boost::system::error_code& ec) { boost::asio::detail::addrinfo_type* address_info = 0; - std::string host_name = query.host_name(); - std::string service_name = query.service_name(); - boost::asio::detail::addrinfo_type hints = query.hints(); - socket_ops::getaddrinfo(!host_name.empty() ? host_name.c_str() : 0, - service_name.c_str(), &hints, &address_info, ec); + socket_ops::getaddrinfo(query.host_name().c_str(), + query.service_name().c_str(), query.hints(), &address_info, ec); auto_addrinfo auto_address_info(address_info); - if (ec) - return iterator_type(); - - return iterator_type::create(address_info, host_name, service_name); + return ec ? iterator_type() : iterator_type::create( + address_info, query.host_name(), query.service_name()); } - template <typename Handler> - class resolve_op - : public operation - { - public: - resolve_op(implementation_type impl, const query_type& query, - io_service_impl& io_service_impl, Handler handler) - : operation(&resolve_op::do_complete), - impl_(impl), - query_(query), - io_service_impl_(io_service_impl), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - // Take ownership of the operation object. - resolve_op* o(static_cast<resolve_op*>(base)); - typedef handler_alloc_traits<Handler, resolve_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - if (owner) - { - if (owner != &o->io_service_impl_) - { - // The operation is being run on the worker io_service. Time to - // perform the resolver operation. - - if (o->impl_.expired()) - { - // THe operation has been cancelled. - o->ec_ = boost::asio::error::operation_aborted; - } - else - { - // Perform the blocking host resolution operation. - boost::asio::detail::addrinfo_type* address_info = 0; - std::string host_name = o->query_.host_name(); - std::string service_name = o->query_.service_name(); - boost::asio::detail::addrinfo_type hints = o->query_.hints(); - socket_ops::getaddrinfo(!host_name.empty() ? host_name.c_str() : 0, - service_name.c_str(), &hints, &address_info, o->ec_); - auto_addrinfo auto_address_info(address_info); - o->iter_ = iterator_type::create( - address_info, host_name, service_name); - } - - o->io_service_impl_.post_deferred_completion(o); - ptr.release(); - } - else - { - // The operation has been returned to the main io_serice. The - // completion handler is ready to be delivered. - - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object - // remains valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, iterator_type> - handler(o->handler_, o->ec_, o->iter_); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - } - - private: - boost::weak_ptr<void> impl_; - query_type query_; - io_service_impl& io_service_impl_; - Handler handler_; - boost::system::error_code ec_; - iterator_type iter_; - }; - // Asynchronously resolve a query to a list of entries. template <typename Handler> void async_resolve(implementation_type& impl, const query_type& query, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef resolve_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, - impl, query, io_service_impl_, handler); - - if (work_io_service_) - { - start_work_thread(); - io_service_impl_.work_started(); - work_io_service_impl_.post_immediate_completion(ptr.get()); - ptr.release(); - } + typedef resolve_op<Protocol, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl, query, io_service_impl_, handler); + + start_resolve_op(p.p); + p.v = p.p = 0; } // Resolve an endpoint to a list of entries. iterator_type resolve(implementation_type&, const endpoint_type& endpoint, boost::system::error_code& ec) { - // First try resolving with the service name. If that fails try resolving - // but allow the service to be returned as a number. char host_name[NI_MAXHOST]; char service_name[NI_MAXSERV]; - int flags = endpoint.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0; - socket_ops::getnameinfo(endpoint.data(), endpoint.size(), - host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec); - if (ec) - { - flags |= NI_NUMERICSERV; - socket_ops::getnameinfo(endpoint.data(), endpoint.size(), - host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec); - } + socket_ops::sync_getnameinfo(endpoint.data(), endpoint.size(), + host_name, NI_MAXHOST, service_name, NI_MAXSERV, + endpoint.protocol().type(), ec); - if (ec) - return iterator_type(); - - return iterator_type::create(endpoint, host_name, service_name); + return ec ? iterator_type() : iterator_type::create( + endpoint, host_name, service_name); } - template <typename Handler> - class resolve_endpoint_op - : public operation - { - public: - resolve_endpoint_op(implementation_type impl, const endpoint_type& ep, - io_service_impl& io_service_impl, Handler handler) - : operation(&resolve_endpoint_op::do_complete), - impl_(impl), - ep_(ep), - io_service_impl_(io_service_impl), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - // Take ownership of the operation object. - resolve_endpoint_op* o(static_cast<resolve_endpoint_op*>(base)); - typedef handler_alloc_traits<Handler, resolve_endpoint_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - if (owner) - { - if (owner != &o->io_service_impl_) - { - // The operation is being run on the worker io_service. Time to - // perform the resolver operation. - - if (o->impl_.expired()) - { - // THe operation has been cancelled. - o->ec_ = boost::asio::error::operation_aborted; - } - else - { - // Perform the blocking endoint resolution operation. - char host_name[NI_MAXHOST]; - char service_name[NI_MAXSERV]; - int flags = o->ep_.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0; - socket_ops::getnameinfo(o->ep_.data(), o->ep_.size(), - host_name, NI_MAXHOST, service_name, - NI_MAXSERV, flags, o->ec_); - if (o->ec_) - { - flags |= NI_NUMERICSERV; - socket_ops::getnameinfo(o->ep_.data(), o->ep_.size(), - host_name, NI_MAXHOST, service_name, - NI_MAXSERV, flags, o->ec_); - } - o->iter_ = iterator_type::create(o->ep_, host_name, service_name); - } - - o->io_service_impl_.post_deferred_completion(o); - ptr.release(); - } - else - { - // The operation has been returned to the main io_serice. The - // completion handler is ready to be delivered. - - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object - // remains valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, iterator_type> - handler(o->handler_, o->ec_, o->iter_); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - } - - private: - boost::weak_ptr<void> impl_; - endpoint_type ep_; - io_service_impl& io_service_impl_; - Handler handler_; - boost::system::error_code ec_; - iterator_type iter_; - }; - // Asynchronously resolve an endpoint to a list of entries. template <typename Handler> void async_resolve(implementation_type& impl, const endpoint_type& endpoint, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef resolve_endpoint_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, - impl, endpoint, io_service_impl_, handler); - - if (work_io_service_) - { - start_work_thread(); - io_service_impl_.work_started(); - work_io_service_impl_.post_immediate_completion(ptr.get()); - ptr.release(); - } - } - -private: - // Helper class to run the work io_service in a thread. - class work_io_service_runner - { - public: - work_io_service_runner(boost::asio::io_service& io_service) - : io_service_(io_service) {} - void operator()() { io_service_.run(); } - private: - boost::asio::io_service& io_service_; - }; - - // Start the work thread if it's not already running. - void start_work_thread() - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - if (!work_thread_) - { - work_thread_.reset(new boost::asio::detail::thread( - work_io_service_runner(*work_io_service_))); - } + typedef resolve_endpoint_op<Protocol, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl, endpoint, io_service_impl_, handler); + + start_resolve_op(p.p); + p.v = p.p = 0; } - - // Mutex to protect access to internal data. - boost::asio::detail::mutex mutex_; - - // The io_service implementation used to post completions. - io_service_impl& io_service_impl_; - - // Private io_service used for performing asynchronous host resolution. - boost::scoped_ptr<boost::asio::io_service> work_io_service_; - - // The work io_service implementation used to post completions. - io_service_impl& work_io_service_impl_; - - // Work for the private io_service to perform. - boost::scoped_ptr<boost::asio::io_service::work> work_; - - // Thread used for running the work io_service's run loop. - boost::scoped_ptr<boost::asio::detail::thread> work_thread_; }; } // namespace detail diff --git a/3rdParty/Boost/src/boost/asio/detail/resolver_service_base.hpp b/3rdParty/Boost/src/boost/asio/detail/resolver_service_base.hpp new file mode 100644 index 0000000..cc6ede6 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/resolver_service_base.hpp @@ -0,0 +1,125 @@ +// +// detail/resolver_service_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP +#define BOOST_ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/scoped_ptr.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/detail/mutex.hpp> +#include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/thread.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +class resolver_service_base +{ +public: + // The implementation type of the resolver. A cancellation token is used to + // indicate to the background thread that the operation has been cancelled. + typedef socket_ops::shared_cancel_token_type implementation_type; + + // Constructor. + BOOST_ASIO_DECL resolver_service_base(boost::asio::io_service& io_service); + + // Destructor. + BOOST_ASIO_DECL ~resolver_service_base(); + + // Destroy all user-defined handler objects owned by the service. + BOOST_ASIO_DECL void shutdown_service(); + + // Construct a new resolver implementation. + BOOST_ASIO_DECL void construct(implementation_type& impl); + + // Destroy a resolver implementation. + BOOST_ASIO_DECL void destroy(implementation_type&); + + // Cancel pending asynchronous operations. + BOOST_ASIO_DECL void cancel(implementation_type& impl); + +protected: + // Helper function to start an asynchronous resolve operation. + BOOST_ASIO_DECL void start_resolve_op(operation* op); + + // Helper class to perform exception-safe cleanup of addrinfo objects. + class auto_addrinfo + : private boost::asio::detail::noncopyable + { + public: + explicit auto_addrinfo(boost::asio::detail::addrinfo_type* ai) + : ai_(ai) + { + } + + ~auto_addrinfo() + { + if (ai_) + socket_ops::freeaddrinfo(ai_); + } + + operator boost::asio::detail::addrinfo_type*() + { + return ai_; + } + + private: + boost::asio::detail::addrinfo_type* ai_; + }; + + // Helper class to run the work io_service in a thread. + class work_io_service_runner; + + // Start the work thread if it's not already running. + BOOST_ASIO_DECL void start_work_thread(); + + // The io_service implementation used to post completions. + io_service_impl& io_service_impl_; + +private: + // Mutex to protect access to internal data. + boost::asio::detail::mutex mutex_; + + // Private io_service used for performing asynchronous host resolution. + boost::scoped_ptr<boost::asio::io_service> work_io_service_; + + // The work io_service implementation used to post completions. + io_service_impl& work_io_service_impl_; + + // Work for the private io_service to perform. + boost::scoped_ptr<boost::asio::io_service::work> work_; + + // Thread used for running the work io_service's run loop. + boost::scoped_ptr<boost::asio::detail::thread> work_thread_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/resolver_service_base.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // BOOST_ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/scoped_lock.hpp b/3rdParty/Boost/src/boost/asio/detail/scoped_lock.hpp index c319263..247411e 100644 --- a/3rdParty/Boost/src/boost/asio/detail/scoped_lock.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/scoped_lock.hpp @@ -1,6 +1,6 @@ // -// scoped_lock.hpp -// ~~~~~~~~~~~~~~~ +// detail/scoped_lock.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,10 +15,10 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { diff --git a/3rdParty/Boost/src/boost/asio/detail/select_interrupter.hpp b/3rdParty/Boost/src/boost/asio/detail/select_interrupter.hpp index f844881..9683e63 100644 --- a/3rdParty/Boost/src/boost/asio/detail/select_interrupter.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/select_interrupter.hpp @@ -1,6 +1,6 @@ // -// select_interrupter.hpp -// ~~~~~~~~~~~~~~~~~~~~~~ +// detail/select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) || defined(__SYMBIAN32__) # include <boost/asio/detail/socket_select_interrupter.hpp> -#else +#elif defined(BOOST_ASIO_HAS_EVENTFD) # include <boost/asio/detail/eventfd_select_interrupter.hpp> +#else # include <boost/asio/detail/pipe_select_interrupter.hpp> #endif @@ -32,7 +29,7 @@ namespace boost { namespace asio { namespace detail { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) || defined(__SYMBIAN32__) typedef socket_select_interrupter select_interrupter; #elif defined(BOOST_ASIO_HAS_EVENTFD) typedef eventfd_select_interrupter select_interrupter; @@ -44,6 +41,4 @@ typedef pipe_select_interrupter select_interrupter; } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_SELECT_INTERRUPTER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/select_reactor.hpp b/3rdParty/Boost/src/boost/asio/detail/select_reactor.hpp index 91030e9..55a819d 100644 --- a/3rdParty/Boost/src/boost/asio/detail/select_reactor.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/select_reactor.hpp @@ -1,6 +1,6 @@ // -// select_reactor.hpp -// ~~~~~~~~~~~~~~~~~~ +// detail/select_reactor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,42 +15,39 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/socket_types.hpp> // Must come before posix_time. +#if defined(BOOST_ASIO_HAS_IOCP) \ + || (!defined(BOOST_ASIO_HAS_DEV_POLL) \ + && !defined(BOOST_ASIO_HAS_EPOLL) \ + && !defined(BOOST_ASIO_HAS_KQUEUE)) -#include <boost/asio/detail/push_options.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/io_service.hpp> -#include <boost/asio/detail/bind_handler.hpp> -#include <boost/asio/detail/fd_set_adapter.hpp> #include <boost/asio/detail/mutex.hpp> -#include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/op_queue.hpp> #include <boost/asio/detail/reactor_op.hpp> #include <boost/asio/detail/reactor_op_queue.hpp> #include <boost/asio/detail/select_interrupter.hpp> #include <boost/asio/detail/select_reactor_fwd.hpp> -#include <boost/asio/detail/service_base.hpp> -#include <boost/asio/detail/signal_blocker.hpp> -#include <boost/asio/detail/socket_ops.hpp> #include <boost/asio/detail/socket_types.hpp> -#include <boost/asio/detail/thread.hpp> #include <boost/asio/detail/timer_op.hpp> #include <boost/asio/detail/timer_queue_base.hpp> #include <boost/asio/detail/timer_queue_fwd.hpp> #include <boost/asio/detail/timer_queue_set.hpp> +#include <boost/asio/io_service.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) +# include <boost/asio/detail/thread.hpp> +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace detail { -template <bool Own_Thread> class select_reactor - : public boost::asio::detail::service_base<select_reactor<Own_Thread> > + : public boost::asio::detail::service_base<select_reactor> { public: #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -67,280 +64,91 @@ public: }; // Constructor. - select_reactor(boost::asio::io_service& io_service) - : boost::asio::detail::service_base< - select_reactor<Own_Thread> >(io_service), - io_service_(use_service<io_service_impl>(io_service)), - mutex_(), - interrupter_(), - stop_thread_(false), - thread_(0), - shutdown_(false) - { - if (Own_Thread) - { - boost::asio::detail::signal_blocker sb; - thread_ = new boost::asio::detail::thread( - bind_handler(&select_reactor::call_run_thread, this)); - } - } + BOOST_ASIO_DECL select_reactor(boost::asio::io_service& io_service); // Destructor. - ~select_reactor() - { - shutdown_service(); - } + BOOST_ASIO_DECL ~select_reactor(); // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - shutdown_ = true; - stop_thread_ = true; - lock.unlock(); - - if (Own_Thread) - { - if (thread_) - { - interrupter_.interrupt(); - thread_->join(); - delete thread_; - thread_ = 0; - } - } - - op_queue<operation> ops; - - for (int i = 0; i < max_ops; ++i) - op_queue_[i].get_all_operations(ops); - - timer_queues_.get_all_timers(ops); - } + BOOST_ASIO_DECL void shutdown_service(); // Initialise the task, but only if the reactor is not in its own thread. - void init_task() - { - io_service_.init_task(); - } + BOOST_ASIO_DECL void init_task(); // Register a socket with the reactor. Returns 0 on success, system error // code on failure. - int register_descriptor(socket_type, per_descriptor_data&) + BOOST_ASIO_DECL int register_descriptor(socket_type, per_descriptor_data&); + + // Post a reactor operation for immediate completion. + void post_immediate_completion(reactor_op* op) { - return 0; + io_service_.post_immediate_completion(op); } // Start a new operation. The reactor operation will be performed when the // given descriptor is flagged as ready, or an error has occurred. - void start_op(int op_type, socket_type descriptor, - per_descriptor_data&, reactor_op* op, bool) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - if (!shutdown_) - { - bool first = op_queue_[op_type].enqueue_operation(descriptor, op); - io_service_.work_started(); - if (first) - interrupter_.interrupt(); - } - } + BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor, + per_descriptor_data&, reactor_op* op, bool); // Cancel all operations associated with the given descriptor. The // handlers associated with the descriptor will be invoked with the // operation_aborted error. - void cancel_ops(socket_type descriptor, per_descriptor_data&) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted); - } + BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&); // Cancel any operations that are running against the descriptor and remove // its registration from the reactor. - void close_descriptor(socket_type descriptor, per_descriptor_data&) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted); - } + BOOST_ASIO_DECL void close_descriptor(socket_type descriptor, + per_descriptor_data&); // Add a new timer queue to the reactor. template <typename Time_Traits> - void add_timer_queue(timer_queue<Time_Traits>& timer_queue) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - timer_queues_.insert(&timer_queue); - } + void add_timer_queue(timer_queue<Time_Traits>& queue); // Remove a timer queue from the reactor. template <typename Time_Traits> - void remove_timer_queue(timer_queue<Time_Traits>& timer_queue) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - timer_queues_.erase(&timer_queue); - } + void remove_timer_queue(timer_queue<Time_Traits>& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time. template <typename Time_Traits> - void schedule_timer(timer_queue<Time_Traits>& timer_queue, - const typename Time_Traits::time_type& time, timer_op* op, void* token) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - if (!shutdown_) - { - bool earliest = timer_queue.enqueue_timer(time, op, token); - io_service_.work_started(); - if (earliest) - interrupter_.interrupt(); - } - } + void schedule_timer(timer_queue<Time_Traits>& queue, + const typename Time_Traits::time_type& time, + typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched. template <typename Time_Traits> - std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - op_queue<operation> ops; - std::size_t n = timer_queue.cancel_timer(token, ops); - lock.unlock(); - io_service_.post_deferred_completions(ops); - return n; - } + std::size_t cancel_timer(timer_queue<Time_Traits>& queue, + typename timer_queue<Time_Traits>::per_timer_data& timer); // Run select once until interrupted or events are ready to be dispatched. - void run(bool block, op_queue<operation>& ops) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - - // Check if the thread is supposed to stop. - if (Own_Thread) - if (stop_thread_) - return; - - // Set up the descriptor sets. - fd_set_adapter fds[max_select_ops]; - fds[read_op].set(interrupter_.read_descriptor()); - socket_type max_fd = 0; - bool have_work_to_do = !timer_queues_.all_empty(); - for (int i = 0; i < max_select_ops; ++i) - { - have_work_to_do = have_work_to_do || !op_queue_[i].empty(); - op_queue_[i].get_descriptors(fds[i], ops); - if (fds[i].max_descriptor() > max_fd) - max_fd = fds[i].max_descriptor(); - } - -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - // Connection operations on Windows use both except and write fd_sets. - have_work_to_do = have_work_to_do || !op_queue_[connect_op].empty(); - op_queue_[connect_op].get_descriptors(fds[write_op], ops); - if (fds[write_op].max_descriptor() > max_fd) - max_fd = fds[write_op].max_descriptor(); - op_queue_[connect_op].get_descriptors(fds[except_op], ops); - if (fds[except_op].max_descriptor() > max_fd) - max_fd = fds[except_op].max_descriptor(); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - - // We can return immediately if there's no work to do and the reactor is - // not supposed to block. - if (!block && !have_work_to_do) - return; - - // Determine how long to block while waiting for events. - timeval tv_buf = { 0, 0 }; - timeval* tv = block ? get_timeout(tv_buf) : &tv_buf; - - lock.unlock(); - - // Block on the select call until descriptors become ready. - boost::system::error_code ec; - int retval = socket_ops::select(static_cast<int>(max_fd + 1), - fds[read_op], fds[write_op], fds[except_op], tv, ec); - - // Reset the interrupter. - if (retval > 0 && fds[read_op].is_set(interrupter_.read_descriptor())) - interrupter_.reset(); - - lock.lock(); - - // Dispatch all ready operations. - if (retval > 0) - { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - // Connection operations on Windows use both except and write fd_sets. - op_queue_[connect_op].perform_operations_for_descriptors( - fds[except_op], ops); - op_queue_[connect_op].perform_operations_for_descriptors( - fds[write_op], ops); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - - // Exception operations must be processed first to ensure that any - // out-of-band data is read before normal data. - for (int i = max_select_ops - 1; i >= 0; --i) - op_queue_[i].perform_operations_for_descriptors(fds[i], ops); - } - timer_queues_.get_ready_timers(ops); - } + BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops); // Interrupt the select loop. - void interrupt() - { - interrupter_.interrupt(); - } + BOOST_ASIO_DECL void interrupt(); private: +#if defined(BOOST_ASIO_HAS_IOCP) // Run the select loop in the thread. - void run_thread() - { - if (Own_Thread) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - while (!stop_thread_) - { - lock.unlock(); - op_queue<operation> ops; - run(true, ops); - io_service_.post_deferred_completions(ops); - lock.lock(); - } - } - } + BOOST_ASIO_DECL void run_thread(); // Entry point for the select loop thread. - static void call_run_thread(select_reactor* reactor) - { - if (Own_Thread) - { - reactor->run_thread(); - } - } + BOOST_ASIO_DECL static void call_run_thread(select_reactor* reactor); +#endif // defined(BOOST_ASIO_HAS_IOCP) + + // Helper function to add a new timer queue. + BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); + + // Helper function to remove a timer queue. + BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); // Get the timeout value for the select call. - timeval* get_timeout(timeval& tv) - { - // By default we will wait no longer than 5 minutes. This will ensure that - // any changes to the system clock are detected after no longer than this. - long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000); - tv.tv_sec = usec / 1000000; - tv.tv_usec = usec % 1000000; - return &tv; - } + BOOST_ASIO_DECL timeval* get_timeout(timeval& tv); // Cancel all operations associated with the given descriptor. This function // does not acquire the select_reactor's mutex. - void cancel_ops_unlocked(socket_type descriptor, - const boost::system::error_code& ec) - { - bool need_interrupt = false; - op_queue<operation> ops; - for (int i = 0; i < max_ops; ++i) - need_interrupt = op_queue_[i].cancel_operations( - descriptor, ops, ec) || need_interrupt; - io_service_.post_deferred_completions(ops); - if (need_interrupt) - interrupter_.interrupt(); - } + BOOST_ASIO_DECL void cancel_ops_unlocked(socket_type descriptor, + const boost::system::error_code& ec); // The io_service implementation used to post completions. io_service_impl& io_service_; @@ -357,11 +165,13 @@ private: // The timer queues. timer_queue_set timer_queues_; +#if defined(BOOST_ASIO_HAS_IOCP) // Does the reactor loop thread need to stop. bool stop_thread_; // The thread that is running the reactor loop. boost::asio::detail::thread* thread_; +#endif // defined(BOOST_ASIO_HAS_IOCP) // Whether the service has been shut down. bool shutdown_; @@ -373,4 +183,14 @@ private: #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/impl/select_reactor.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/select_reactor.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_ASIO_HAS_IOCP) + // || (!defined(BOOST_ASIO_HAS_DEV_POLL) + // && !defined(BOOST_ASIO_HAS_EPOLL) + // && !defined(BOOST_ASIO_HAS_KQUEUE)) + #endif // BOOST_ASIO_DETAIL_SELECT_REACTOR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/select_reactor_fwd.hpp b/3rdParty/Boost/src/boost/asio/detail/select_reactor_fwd.hpp index b48e0f0..f4f9f65 100644 --- a/3rdParty/Boost/src/boost/asio/detail/select_reactor_fwd.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/select_reactor_fwd.hpp @@ -1,6 +1,6 @@ // -// select_reactor_fwd.hpp -// ~~~~~~~~~~~~~~~~~~~~~~ +// detail/select_reactor_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,19 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - namespace boost { namespace asio { namespace detail { -template <bool Own_Thread> class select_reactor; } // namespace detail } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_SELECT_REACTOR_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/service_base.hpp b/3rdParty/Boost/src/boost/asio/detail/service_base.hpp deleted file mode 100644 index 66c2af3..0000000 --- a/3rdParty/Boost/src/boost/asio/detail/service_base.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// -// service_base.hpp -// ~~~~~~~~~~~~~~~~ -// -// 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) -// - -#ifndef BOOST_ASIO_DETAIL_SERVICE_BASE_HPP -#define BOOST_ASIO_DETAIL_SERVICE_BASE_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/io_service.hpp> -#include <boost/asio/detail/service_id.hpp> - -namespace boost { -namespace asio { -namespace detail { - -// Special service base class to keep classes header-file only. -template <typename Type> -class service_base - : public boost::asio::io_service::service -{ -public: - static boost::asio::detail::service_id<Type> id; - - // Constructor. - service_base(boost::asio::io_service& io_service) - : boost::asio::io_service::service(io_service) - { - } -}; - -template <typename Type> -boost::asio::detail::service_id<Type> service_base<Type>::id; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include <boost/asio/detail/pop_options.hpp> - -#endif // BOOST_ASIO_DETAIL_SERVICE_BASE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/service_registry.hpp b/3rdParty/Boost/src/boost/asio/detail/service_registry.hpp index e640ec8..6ba30f1 100644 --- a/3rdParty/Boost/src/boost/asio/detail/service_registry.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/service_registry.hpp @@ -1,6 +1,6 @@ // -// service_registry.hpp -// ~~~~~~~~~~~~~~~~~~~~ +// detail/service_registry.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <typeinfo> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/io_service.hpp> #include <boost/asio/detail/mutex.hpp> #include <boost/asio/detail/noncopyable.hpp> -#include <boost/asio/detail/service_id.hpp> +#include <boost/asio/io_service.hpp> #if defined(BOOST_NO_TYPEID) # if !defined(BOOST_ASIO_NO_TYPEID) @@ -32,6 +27,8 @@ # endif // !defined(BOOST_ASIO_NO_TYPEID) #endif // defined(BOOST_NO_TYPEID) +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -56,98 +53,43 @@ class service_registry { public: // Constructor. - service_registry(boost::asio::io_service& o) - : owner_(o), - first_service_(0) - { - } + BOOST_ASIO_DECL service_registry(boost::asio::io_service& o); // Destructor. - ~service_registry() - { - // Shutdown all services. This must be done in a separate loop before the - // services are destroyed since the destructors of user-defined handler - // objects may try to access other service objects. - boost::asio::io_service::service* service = first_service_; - while (service) - { - service->shutdown_service(); - service = service->next_; - } - - // Destroy all services. - while (first_service_) - { - boost::asio::io_service::service* next_service = first_service_->next_; - destroy(first_service_); - first_service_ = next_service; - } - } + BOOST_ASIO_DECL ~service_registry(); // Get the service object corresponding to the specified service type. Will // create a new service object automatically if no such object already // exists. Ownership of the service object is not transferred to the caller. template <typename Service> - Service& use_service() - { - boost::asio::io_service::service::key key; - init_key(key, Service::id); - factory_type factory = &service_registry::create<Service>; - return *static_cast<Service*>(do_use_service(key, factory)); - } + Service& use_service(); - // Add a service object. Returns false on error, in which case ownership of - // the object is retained by the caller. + // Add a service object. Throws on error, in which case ownership of the + // object is retained by the caller. template <typename Service> - bool add_service(Service* new_service) - { - boost::asio::io_service::service::key key; - init_key(key, Service::id); - return do_add_service(key, new_service); - } + void add_service(Service* new_service); // Check whether a service object of the specified type already exists. template <typename Service> - bool has_service() const - { - boost::asio::io_service::service::key key; - init_key(key, Service::id); - return do_has_service(key); - } + bool has_service() const; private: // Initialise a service's key based on its id. - void init_key(boost::asio::io_service::service::key& key, - const boost::asio::io_service::id& id) - { - key.type_info_ = 0; - key.id_ = &id; - } + BOOST_ASIO_DECL static void init_key( + boost::asio::io_service::service::key& key, + const boost::asio::io_service::id& id); #if !defined(BOOST_ASIO_NO_TYPEID) // Initialise a service's key based on its id. template <typename Service> - void init_key(boost::asio::io_service::service::key& key, - const boost::asio::detail::service_id<Service>& /*id*/) - { - key.type_info_ = &typeid(typeid_wrapper<Service>); - key.id_ = 0; - } + static void init_key(boost::asio::io_service::service::key& key, + const boost::asio::detail::service_id<Service>& /*id*/); #endif // !defined(BOOST_ASIO_NO_TYPEID) // Check if a service matches the given id. - static bool keys_match( + BOOST_ASIO_DECL static bool keys_match( const boost::asio::io_service::service::key& key1, - const boost::asio::io_service::service::key& key2) - { - if (key1.id_ && key2.id_) - if (key1.id_ == key2.id_) - return true; - if (key1.type_info_ && key2.type_info_) - if (*key1.type_info_ == *key2.type_info_) - return true; - return false; - } + const boost::asio::io_service::service::key& key2); // The type of a factory function used for creating a service instance. typedef boost::asio::io_service::service* @@ -156,18 +98,15 @@ private: // Factory function for creating a service instance. template <typename Service> static boost::asio::io_service::service* create( - boost::asio::io_service& owner) - { - return new Service(owner); - } + boost::asio::io_service& owner); // Destroy a service instance. - static void destroy(boost::asio::io_service::service* service) - { - delete service; - } + BOOST_ASIO_DECL static void destroy( + boost::asio::io_service::service* service); // Helper class to manage service pointers. + struct auto_service_ptr; + friend struct auto_service_ptr; struct auto_service_ptr { boost::asio::io_service::service* ptr_; @@ -177,86 +116,19 @@ private: // Get the service object corresponding to the specified service key. Will // create a new service object automatically if no such object already // exists. Ownership of the service object is not transferred to the caller. - boost::asio::io_service::service* do_use_service( + BOOST_ASIO_DECL boost::asio::io_service::service* do_use_service( const boost::asio::io_service::service::key& key, - factory_type factory) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - - // First see if there is an existing service object with the given key. - boost::asio::io_service::service* service = first_service_; - while (service) - { - if (keys_match(service->key_, key)) - return service; - service = service->next_; - } - - // Create a new service object. The service registry's mutex is not locked - // at this time to allow for nested calls into this function from the new - // service's constructor. - lock.unlock(); - auto_service_ptr new_service = { factory(owner_) }; - new_service.ptr_->key_ = key; - lock.lock(); - - // Check that nobody else created another service object of the same type - // while the lock was released. - service = first_service_; - while (service) - { - if (keys_match(service->key_, key)) - return service; - service = service->next_; - } - - // Service was successfully initialised, pass ownership to registry. - new_service.ptr_->next_ = first_service_; - first_service_ = new_service.ptr_; - new_service.ptr_ = 0; - return first_service_; - } + factory_type factory); // Add a service object. Returns false on error, in which case ownership of // the object is retained by the caller. - bool do_add_service( + BOOST_ASIO_DECL void do_add_service( const boost::asio::io_service::service::key& key, - boost::asio::io_service::service* new_service) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - - // Check if there is an existing service object with the given key. - boost::asio::io_service::service* service = first_service_; - while (service) - { - if (keys_match(service->key_, key)) - return false; - service = service->next_; - } - - // Take ownership of the service object. - new_service->key_ = key; - new_service->next_ = first_service_; - first_service_ = new_service; - - return true; - } + boost::asio::io_service::service* new_service); // Check whether a service object with the specified key already exists. - bool do_has_service(const boost::asio::io_service::service::key& key) const - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - - boost::asio::io_service::service* service = first_service_; - while (service) - { - if (keys_match(service->key_, key)) - return true; - service = service->next_; - } - - return false; - } + BOOST_ASIO_DECL bool do_has_service( + const boost::asio::io_service::service::key& key) const; // Mutex to protect access to internal data. mutable boost::asio::detail::mutex mutex_; @@ -274,4 +146,9 @@ private: #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/impl/service_registry.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/service_registry.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + #endif // BOOST_ASIO_DETAIL_SERVICE_REGISTRY_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/service_registry_fwd.hpp b/3rdParty/Boost/src/boost/asio/detail/service_registry_fwd.hpp index 4031b1a..8713a30 100644 --- a/3rdParty/Boost/src/boost/asio/detail/service_registry_fwd.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/service_registry_fwd.hpp @@ -1,6 +1,6 @@ // -// service_registry_fwd.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/service_registry_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,8 +15,6 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - namespace boost { namespace asio { namespace detail { @@ -27,6 +25,4 @@ class service_registry; } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/service_id.hpp b/3rdParty/Boost/src/boost/asio/detail/shared_ptr.hpp index ac0f4d1..0c5586e 100644 --- a/3rdParty/Boost/src/boost/asio/detail/service_id.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/shared_ptr.hpp @@ -1,6 +1,6 @@ // -// service_id.hpp -// ~~~~~~~~~~~~~~ +// detail/shared_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -8,32 +8,33 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef BOOST_ASIO_DETAIL_SERVICE_ID_HPP -#define BOOST_ASIO_DETAIL_SERVICE_ID_HPP +#ifndef BOOST_ASIO_DETAIL_SHARED_PTR_HPP +#define BOOST_ASIO_DETAIL_SHARED_PTR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/io_service.hpp> +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# include <memory> +#else +# include <boost/shared_ptr.hpp> +#endif namespace boost { namespace asio { namespace detail { -// Special derived service id type to keep classes header-file only. -template <typename Type> -class service_id - : public boost::asio::io_service::id -{ -}; +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +using std::shared_ptr; +#else +using boost::shared_ptr; +#endif } // namespace detail } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - -#endif // BOOST_ASIO_DETAIL_SERVICE_ID_HPP +#endif // BOOST_ASIO_DETAIL_SHARED_PTR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/signal_blocker.hpp b/3rdParty/Boost/src/boost/asio/detail/signal_blocker.hpp index 0197e04..67eaac0 100644 --- a/3rdParty/Boost/src/boost/asio/detail/signal_blocker.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/signal_blocker.hpp @@ -1,6 +1,6 @@ // -// signal_blocker.hpp -// ~~~~~~~~~~~~~~~~~~ +// detail/signal_blocker.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) +#if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) \ + || defined(BOOST_WINDOWS) || defined(__CYGWIN__) || defined(__SYMBIAN32__) # include <boost/asio/detail/null_signal_blocker.hpp> -#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) -# include <boost/asio/detail/win_signal_blocker.hpp> #elif defined(BOOST_HAS_PTHREADS) # include <boost/asio/detail/posix_signal_blocker.hpp> #else @@ -35,10 +30,9 @@ namespace boost { namespace asio { namespace detail { -#if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) +#if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) \ + || defined(BOOST_WINDOWS) || defined(__CYGWIN__) || defined(__SYMBIAN32__) typedef null_signal_blocker signal_blocker; -#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) -typedef win_signal_blocker signal_blocker; #elif defined(BOOST_HAS_PTHREADS) typedef posix_signal_blocker signal_blocker; #endif @@ -47,6 +41,4 @@ typedef posix_signal_blocker signal_blocker; } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_SIGNAL_BLOCKER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/signal_init.hpp b/3rdParty/Boost/src/boost/asio/detail/signal_init.hpp index 50e06b8..76d21bf 100644 --- a/3rdParty/Boost/src/boost/asio/detail/signal_init.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/signal_init.hpp @@ -1,6 +1,6 @@ // -// signal_init.hpp -// ~~~~~~~~~~~~~~~ +// detail/signal_init.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,17 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) -#include <boost/asio/detail/push_options.hpp> #include <csignal> -#include <boost/asio/detail/pop_options.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -46,8 +42,8 @@ public: } // namespace asio } // namespace boost -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) - #include <boost/asio/detail/pop_options.hpp> +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + #endif // BOOST_ASIO_DETAIL_SIGNAL_INIT_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/socket_holder.hpp b/3rdParty/Boost/src/boost/asio/detail/socket_holder.hpp index 5d6012b..7815acc 100644 --- a/3rdParty/Boost/src/boost/asio/detail/socket_holder.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/socket_holder.hpp @@ -1,6 +1,6 @@ // -// socket_holder.hpp -// ~~~~~~~~~~~~~~~~~ +// detail/socket_holder.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,11 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -47,7 +48,8 @@ public: if (socket_ != invalid_socket) { boost::system::error_code ec; - socket_ops::close(socket_, ec); + socket_ops::state_type state = 0; + socket_ops::close(socket_, state, true, ec); } } @@ -63,7 +65,8 @@ public: if (socket_ != invalid_socket) { boost::system::error_code ec; - socket_ops::close(socket_, ec); + socket_ops::state_type state = 0; + socket_ops::close(socket_, state, true, ec); socket_ = invalid_socket; } } diff --git a/3rdParty/Boost/src/boost/asio/detail/socket_ops.hpp b/3rdParty/Boost/src/boost/asio/detail/socket_ops.hpp index 475162a..a32b4cc 100644 --- a/3rdParty/Boost/src/boost/asio/detail/socket_ops.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/socket_ops.hpp @@ -1,6 +1,6 @@ // -// socket_ops.hpp -// ~~~~~~~~~~~~~~ +// detail/socket_ops.hpp +// ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,194 +15,103 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/assert.hpp> -#include <cstdio> -#include <cstdlib> -#include <cstring> -#include <cerrno> -#include <boost/detail/workaround.hpp> -#include <new> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/error.hpp> +#include <boost/system/error_code.hpp> +#include <boost/asio/detail/shared_ptr.hpp> #include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/weak_ptr.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace detail { namespace socket_ops { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) -struct msghdr { int msg_namelen; }; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +// Socket state bits. +enum +{ + // The user wants a non-blocking socket. + user_set_non_blocking = 1, -#if defined(__hpux) -// HP-UX doesn't declare these functions extern "C", so they are declared again -// here to avoid linker errors about undefined symbols. -extern "C" char* if_indextoname(unsigned int, char*); -extern "C" unsigned int if_nametoindex(const char*); -#endif // defined(__hpux) + // The socket has been set non-blocking. + internal_non_blocking = 2, -inline void clear_error(boost::system::error_code& ec) -{ -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - WSASetLastError(0); -#else - errno = 0; -#endif - ec = boost::system::error_code(); -} - -template <typename ReturnType> -inline ReturnType error_wrapper(ReturnType return_value, - boost::system::error_code& ec) -{ -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - ec = boost::system::error_code(WSAGetLastError(), - boost::asio::error::get_system_category()); -#else - ec = boost::system::error_code(errno, - boost::asio::error::get_system_category()); -#endif - return return_value; -} - -template <typename SockLenType> -inline socket_type call_accept(SockLenType msghdr::*, - socket_type s, socket_addr_type* addr, std::size_t* addrlen) -{ - SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0; - socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0); - if (addrlen) - *addrlen = (std::size_t)tmp_addrlen; - return result; -} - -inline socket_type accept(socket_type s, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec) -{ - clear_error(ec); - - socket_type new_s = error_wrapper(call_accept( - &msghdr::msg_namelen, s, addr, addrlen), ec); - if (new_s == invalid_socket) - return new_s; - -#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__) - int optval = 1; - int result = error_wrapper(::setsockopt(new_s, - SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec); - if (result != 0) - { - ::close(new_s); - return invalid_socket; - } -#endif - - clear_error(ec); - return new_s; -} - -template <typename SockLenType> -inline int call_bind(SockLenType msghdr::*, - socket_type s, const socket_addr_type* addr, std::size_t addrlen) -{ - return ::bind(s, addr, (SockLenType)addrlen); -} + // Helper "state" used to determine whether the socket is non-blocking. + non_blocking = user_set_non_blocking | internal_non_blocking, -inline int bind(socket_type s, const socket_addr_type* addr, - std::size_t addrlen, boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(call_bind( - &msghdr::msg_namelen, s, addr, addrlen), ec); - if (result == 0) - clear_error(ec); - return result; -} - -inline int close(socket_type s, boost::system::error_code& ec) -{ - clear_error(ec); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - int result = error_wrapper(::closesocket(s), ec); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - int result = error_wrapper(::close(s), ec); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - if (result == 0) - clear_error(ec); - return result; -} + // User wants connection_aborted errors, which are disabled by default. + enable_connection_aborted = 4, -inline int shutdown(socket_type s, int what, boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(::shutdown(s, what), ec); - if (result == 0) - clear_error(ec); - return result; -} - -template <typename SockLenType> -inline int call_connect(SockLenType msghdr::*, - socket_type s, const socket_addr_type* addr, std::size_t addrlen) -{ - return ::connect(s, addr, (SockLenType)addrlen); -} + // The user set the linger option. Needs to be checked when closing. + user_set_linger = 8, -inline int connect(socket_type s, const socket_addr_type* addr, - std::size_t addrlen, boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(call_connect( - &msghdr::msg_namelen, s, addr, addrlen), ec); - if (result == 0) - clear_error(ec); - return result; -} - -inline int socketpair(int af, int type, int protocol, - socket_type sv[2], boost::system::error_code& ec) -{ -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - (void)(af); - (void)(type); - (void)(protocol); - (void)(sv); - ec = boost::asio::error::operation_not_supported; - return -1; -#else - clear_error(ec); - int result = error_wrapper(::socketpair(af, type, protocol, sv), ec); - if (result == 0) - clear_error(ec); - return result; -#endif -} - -inline int listen(socket_type s, int backlog, boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(::listen(s, backlog), ec); - if (result == 0) - clear_error(ec); - return result; -} - -inline void init_buf_iov_base(void*& base, void* addr) -{ - base = addr; -} + // The socket is stream-oriented. + stream_oriented = 16, -template <typename T> -inline void init_buf_iov_base(T& base, void* addr) -{ - base = static_cast<T>(addr); -} + // The socket is datagram-oriented. + datagram_oriented = 32 +}; + +typedef unsigned char state_type; + +struct noop_deleter { void operator()(void*) {} }; +typedef shared_ptr<void> shared_cancel_token_type; +typedef weak_ptr<void> weak_cancel_token_type; + +BOOST_ASIO_DECL socket_type accept(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec); + +BOOST_ASIO_DECL socket_type sync_accept(socket_type s, + state_type state, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec); + +#if defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL void complete_iocp_accept(socket_type s, + void* output_buffer, DWORD address_length, + socket_addr_type* addr, std::size_t* addrlen, + socket_type new_socket, boost::system::error_code& ec); + +#else // defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL bool non_blocking_accept(socket_type s, + state_type state, socket_addr_type* addr, std::size_t* addrlen, + boost::system::error_code& ec, socket_type& new_socket); + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL int bind(socket_type s, const socket_addr_type* addr, + std::size_t addrlen, boost::system::error_code& ec); + +BOOST_ASIO_DECL int close(socket_type s, state_type& state, + bool destruction, boost::system::error_code& ec); + +BOOST_ASIO_DECL bool set_internal_non_blocking(socket_type s, + state_type& state, boost::system::error_code& ec); + +BOOST_ASIO_DECL int shutdown(socket_type s, + int what, boost::system::error_code& ec); + +BOOST_ASIO_DECL int connect(socket_type s, const socket_addr_type* addr, + std::size_t addrlen, boost::system::error_code& ec); + +BOOST_ASIO_DECL void sync_connect(socket_type s, const socket_addr_type* addr, + std::size_t addrlen, boost::system::error_code& ec); + +BOOST_ASIO_DECL bool non_blocking_connect( + socket_type s, boost::system::error_code& ec); + +BOOST_ASIO_DECL int socketpair(int af, int type, int protocol, + socket_type sv[2], boost::system::error_code& ec); + +BOOST_ASIO_DECL bool sockatmark(socket_type s, boost::system::error_code& ec); + +BOOST_ASIO_DECL size_t available(socket_type s, boost::system::error_code& ec); + +BOOST_ASIO_DECL int listen(socket_type s, + int backlog, boost::system::error_code& ec); #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) typedef WSABUF buf; @@ -210,1699 +119,163 @@ typedef WSABUF buf; typedef iovec buf; #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -inline void init_buf(buf& b, void* data, size_t size) -{ -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - b.buf = static_cast<char*>(data); - b.len = static_cast<u_long>(size); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - init_buf_iov_base(b.iov_base, data); - b.iov_len = size; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -} +BOOST_ASIO_DECL void init_buf(buf& b, void* data, size_t size); -inline void init_buf(buf& b, const void* data, size_t size) -{ -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - b.buf = static_cast<char*>(const_cast<void*>(data)); - b.len = static_cast<u_long>(size); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - init_buf_iov_base(b.iov_base, const_cast<void*>(data)); - b.iov_len = size; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -} +BOOST_ASIO_DECL void init_buf(buf& b, const void* data, size_t size); -inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr) -{ - name = addr; -} +BOOST_ASIO_DECL int recv(socket_type s, buf* bufs, size_t count, int flags, + boost::system::error_code& ec); -inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr) -{ - name = const_cast<socket_addr_type*>(addr); -} +BOOST_ASIO_DECL size_t sync_recv(socket_type s, state_type state, buf* bufs, + size_t count, int flags, bool all_empty, boost::system::error_code& ec); -template <typename T> -inline void init_msghdr_msg_name(T& name, socket_addr_type* addr) -{ - name = reinterpret_cast<T>(addr); -} +#if defined(BOOST_ASIO_HAS_IOCP) -template <typename T> -inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr) -{ - name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr)); -} +BOOST_ASIO_DECL void complete_iocp_recv(state_type state, + const weak_cancel_token_type& cancel_token, bool all_empty, + boost::system::error_code& ec, size_t bytes_transferred); -inline int recv(socket_type s, buf* bufs, size_t count, int flags, - boost::system::error_code& ec) -{ - clear_error(ec); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast<DWORD>(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = error_wrapper(::WSARecv(s, bufs, - recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec); - if (result != 0) - return -1; - clear_error(ec); - return bytes_transferred; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - msg.msg_iov = bufs; - msg.msg_iovlen = count; - int result = error_wrapper(::recvmsg(s, &msg, flags), ec); - if (result >= 0) - clear_error(ec); - return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -} +#else // defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL bool non_blocking_recv(socket_type s, + buf* bufs, size_t count, int flags, bool is_stream, + boost::system::error_code& ec, size_t& bytes_transferred); + +#endif // defined(BOOST_ASIO_HAS_IOCP) -inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags, +BOOST_ASIO_DECL int recvfrom(socket_type s, buf* bufs, size_t count, int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec) -{ - clear_error(ec); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast<DWORD>(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int tmp_addrlen = (int)*addrlen; - int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, - &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec); - *addrlen = (std::size_t)tmp_addrlen; - if (result != 0) - return -1; - clear_error(ec); - return bytes_transferred; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = *addrlen; - msg.msg_iov = bufs; - msg.msg_iovlen = count; - int result = error_wrapper(::recvmsg(s, &msg, flags), ec); - *addrlen = msg.msg_namelen; - if (result >= 0) - clear_error(ec); - return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -} + boost::system::error_code& ec); -inline int send(socket_type s, const buf* bufs, size_t count, int flags, - boost::system::error_code& ec) -{ - clear_error(ec); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - // Send the data. - DWORD send_buf_count = static_cast<DWORD>(count); - DWORD bytes_transferred = 0; - DWORD send_flags = flags; - int result = error_wrapper(::WSASend(s, const_cast<buf*>(bufs), - send_buf_count, &bytes_transferred, send_flags, 0, 0), ec); - if (result != 0) - return -1; - clear_error(ec); - return bytes_transferred; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - msg.msg_iov = const_cast<buf*>(bufs); - msg.msg_iovlen = count; -#if defined(__linux__) - flags |= MSG_NOSIGNAL; -#endif // defined(__linux__) - int result = error_wrapper(::sendmsg(s, &msg, flags), ec); - if (result >= 0) - clear_error(ec); - return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -} +BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, + buf* bufs, size_t count, int flags, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec); + +#if defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL void complete_iocp_recvfrom( + const weak_cancel_token_type& cancel_token, + boost::system::error_code& ec); + +#else // defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, + buf* bufs, size_t count, int flags, + socket_addr_type* addr, std::size_t* addrlen, + boost::system::error_code& ec, size_t& bytes_transferred); + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL int send(socket_type s, const buf* bufs, + size_t count, int flags, boost::system::error_code& ec); + +BOOST_ASIO_DECL size_t sync_send(socket_type s, state_type state, + const buf* bufs, size_t count, int flags, + bool all_empty, boost::system::error_code& ec); + +#if defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL void complete_iocp_send( + const weak_cancel_token_type& cancel_token, + boost::system::error_code& ec); + +#else // defined(BOOST_ASIO_HAS_IOCP) -inline int sendto(socket_type s, const buf* bufs, size_t count, int flags, +BOOST_ASIO_DECL bool non_blocking_send(socket_type s, + const buf* bufs, size_t count, int flags, + boost::system::error_code& ec, size_t& bytes_transferred); + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL int sendto(socket_type s, const buf* bufs, size_t count, + int flags, const socket_addr_type* addr, std::size_t addrlen, + boost::system::error_code& ec); + +BOOST_ASIO_DECL size_t sync_sendto(socket_type s, state_type state, + const buf* bufs, size_t count, int flags, const socket_addr_type* addr, + std::size_t addrlen, boost::system::error_code& ec); + +#if !defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL bool non_blocking_sendto(socket_type s, + const buf* bufs, size_t count, int flags, const socket_addr_type* addr, std::size_t addrlen, - boost::system::error_code& ec) -{ - clear_error(ec); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - // Send the data. - DWORD send_buf_count = static_cast<DWORD>(count); - DWORD bytes_transferred = 0; - int result = error_wrapper(::WSASendTo(s, const_cast<buf*>(bufs), - send_buf_count, &bytes_transferred, flags, addr, - static_cast<int>(addrlen), 0, 0), ec); - if (result != 0) - return -1; - clear_error(ec); - return bytes_transferred; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = addrlen; - msg.msg_iov = const_cast<buf*>(bufs); - msg.msg_iovlen = count; -#if defined(__linux__) - flags |= MSG_NOSIGNAL; -#endif // defined(__linux__) - int result = error_wrapper(::sendmsg(s, &msg, flags), ec); - if (result >= 0) - clear_error(ec); - return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -} + boost::system::error_code& ec, size_t& bytes_transferred); -inline socket_type socket(int af, int type, int protocol, - boost::system::error_code& ec) -{ - clear_error(ec); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - socket_type s = error_wrapper(::WSASocket(af, type, protocol, 0, 0, - WSA_FLAG_OVERLAPPED), ec); - if (s == invalid_socket) - return s; - - if (af == AF_INET6) - { - // Try to enable the POSIX default behaviour of having IPV6_V6ONLY set to - // false. This will only succeed on Windows Vista and later versions of - // Windows, where a dual-stack IPv4/v6 implementation is available. - DWORD optval = 0; - ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, - reinterpret_cast<const char*>(&optval), sizeof(optval)); - } - - clear_error(ec); - - return s; -#elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__) - socket_type s = error_wrapper(::socket(af, type, protocol), ec); - if (s == invalid_socket) - return s; - - int optval = 1; - int result = error_wrapper(::setsockopt(s, - SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec); - if (result != 0) - { - ::close(s); - return invalid_socket; - } - - return s; -#else - int s = error_wrapper(::socket(af, type, protocol), ec); - if (s >= 0) - clear_error(ec); - return s; -#endif -} - -template <typename SockLenType> -inline int call_setsockopt(SockLenType msghdr::*, - socket_type s, int level, int optname, - const void* optval, std::size_t optlen) -{ - return ::setsockopt(s, level, optname, - (const char*)optval, (SockLenType)optlen); -} +#endif // !defined(BOOST_ASIO_HAS_IOCP) -inline int setsockopt(socket_type s, int level, int optname, - const void* optval, std::size_t optlen, boost::system::error_code& ec) -{ - if (level == custom_socket_option_level && optname == always_fail_option) - { - ec = boost::asio::error::invalid_argument; - return -1; - } - -#if defined(__BORLANDC__) - // Mysteriously, using the getsockopt and setsockopt functions directly with - // Borland C++ results in incorrect values being set and read. The bug can be - // worked around by using function addresses resolved with GetProcAddress. - if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) - { - typedef int (WSAAPI *sso_t)(SOCKET, int, int, const char*, int); - if (sso_t sso = (sso_t)::GetProcAddress(winsock_module, "setsockopt")) - { - clear_error(ec); - return error_wrapper(sso(s, level, optname, - reinterpret_cast<const char*>(optval), - static_cast<int>(optlen)), ec); - } - } - ec = boost::asio::error::fault; - return -1; -#else // defined(__BORLANDC__) - clear_error(ec); - int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen, - s, level, optname, optval, optlen), ec); - if (result == 0) - clear_error(ec); - return result; -#endif // defined(__BORLANDC__) -} - -template <typename SockLenType> -inline int call_getsockopt(SockLenType msghdr::*, - socket_type s, int level, int optname, - void* optval, std::size_t* optlen) -{ - SockLenType tmp_optlen = (SockLenType)*optlen; - int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen); - *optlen = (std::size_t)tmp_optlen; - return result; -} - -inline int getsockopt(socket_type s, int level, int optname, void* optval, - size_t* optlen, boost::system::error_code& ec) -{ - if (level == custom_socket_option_level && optname == always_fail_option) - { - ec = boost::asio::error::invalid_argument; - return -1; - } - -#if defined(__BORLANDC__) - // Mysteriously, using the getsockopt and setsockopt functions directly with - // Borland C++ results in incorrect values being set and read. The bug can be - // worked around by using function addresses resolved with GetProcAddress. - if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) - { - typedef int (WSAAPI *gso_t)(SOCKET, int, int, char*, int*); - if (gso_t gso = (gso_t)::GetProcAddress(winsock_module, "getsockopt")) - { - clear_error(ec); - int tmp_optlen = static_cast<int>(*optlen); - int result = error_wrapper(gso(s, level, optname, - reinterpret_cast<char*>(optval), &tmp_optlen), ec); - *optlen = static_cast<size_t>(tmp_optlen); - if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY - && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD)) - { - // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are - // only supported on Windows Vista and later. To simplify program logic - // we will fake success of getting this option and specify that the - // value is non-zero (i.e. true). This corresponds to the behavior of - // IPv6 sockets on Windows platforms pre-Vista. - *static_cast<DWORD*>(optval) = 1; - clear_error(ec); - } - return result; - } - } - ec = boost::asio::error::fault; - return -1; -#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) - clear_error(ec); - int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, - s, level, optname, optval, optlen), ec); - if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY - && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD)) - { - // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are only - // supported on Windows Vista and later. To simplify program logic we will - // fake success of getting this option and specify that the value is - // non-zero (i.e. true). This corresponds to the behavior of IPv6 sockets - // on Windows platforms pre-Vista. - *static_cast<DWORD*>(optval) = 1; - clear_error(ec); - } - if (result == 0) - clear_error(ec); - return result; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - clear_error(ec); - int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, - s, level, optname, optval, optlen), ec); -#if defined(__linux__) - if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int) - && (optname == SO_SNDBUF || optname == SO_RCVBUF)) - { - // On Linux, setting SO_SNDBUF or SO_RCVBUF to N actually causes the kernel - // to set the buffer size to N*2. Linux puts additional stuff into the - // buffers so that only about half is actually available to the application. - // The retrieved value is divided by 2 here to make it appear as though the - // correct value has been set. - *static_cast<int*>(optval) /= 2; - } -#endif // defined(__linux__) - if (result == 0) - clear_error(ec); - return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -} +BOOST_ASIO_DECL socket_type socket(int af, int type, int protocol, + boost::system::error_code& ec); -template <typename SockLenType> -inline int call_getpeername(SockLenType msghdr::*, - socket_type s, socket_addr_type* addr, std::size_t* addrlen) -{ - SockLenType tmp_addrlen = (SockLenType)*addrlen; - int result = ::getpeername(s, addr, &tmp_addrlen); - *addrlen = (std::size_t)tmp_addrlen; - return result; -} - -inline int getpeername(socket_type s, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(call_getpeername( - &msghdr::msg_namelen, s, addr, addrlen), ec); - if (result == 0) - clear_error(ec); - return result; -} - -template <typename SockLenType> -inline int call_getsockname(SockLenType msghdr::*, - socket_type s, socket_addr_type* addr, std::size_t* addrlen) -{ - SockLenType tmp_addrlen = (SockLenType)*addrlen; - int result = ::getsockname(s, addr, &tmp_addrlen); - *addrlen = (std::size_t)tmp_addrlen; - return result; -} - -inline int getsockname(socket_type s, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(call_getsockname( - &msghdr::msg_namelen, s, addr, addrlen), ec); - if (result == 0) - clear_error(ec); - return result; -} - -inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg, - boost::system::error_code& ec) -{ - clear_error(ec); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - int result = error_wrapper(::ioctl(s, cmd, arg), ec); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - if (result >= 0) - clear_error(ec); - return result; -} +BOOST_ASIO_DECL int setsockopt(socket_type s, state_type& state, + int level, int optname, const void* optval, + std::size_t optlen, boost::system::error_code& ec); -inline int select(int nfds, fd_set* readfds, fd_set* writefds, - fd_set* exceptfds, timeval* timeout, boost::system::error_code& ec) -{ - clear_error(ec); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - if (!readfds && !writefds && !exceptfds && timeout) - { - DWORD milliseconds = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; - if (milliseconds == 0) - milliseconds = 1; // Force context switch. - ::Sleep(milliseconds); - ec = boost::system::error_code(); - return 0; - } - - // The select() call allows timeout values measured in microseconds, but the - // system clock (as wrapped by boost::posix_time::microsec_clock) typically - // has a resolution of 10 milliseconds. This can lead to a spinning select - // reactor, meaning increased CPU usage, when waiting for the earliest - // scheduled timeout if it's less than 10 milliseconds away. To avoid a tight - // spin we'll use a minimum timeout of 1 millisecond. - if (timeout && timeout->tv_sec == 0 - && timeout->tv_usec > 0 && timeout->tv_usec < 1000) - timeout->tv_usec = 1000; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +BOOST_ASIO_DECL int getsockopt(socket_type s, state_type state, + int level, int optname, void* optval, + size_t* optlen, boost::system::error_code& ec); -#if defined(__hpux) && defined(__HP_aCC) - timespec ts; - ts.tv_sec = timeout ? timeout->tv_sec : 0; - ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0; - return error_wrapper(::pselect(nfds, readfds, - writefds, exceptfds, timeout ? &ts : 0, 0), ec); -#else - int result = error_wrapper(::select(nfds, readfds, - writefds, exceptfds, timeout), ec); - if (result >= 0) - clear_error(ec); - return result; -#endif -} - -inline int poll_read(socket_type s, boost::system::error_code& ec) -{ -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - FD_SET fds; - FD_ZERO(&fds); - FD_SET(s, &fds); - clear_error(ec); - int result = error_wrapper(::select(s, &fds, 0, 0, 0), ec); - if (result >= 0) - clear_error(ec); - return result; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - pollfd fds; - fds.fd = s; - fds.events = POLLIN; - fds.revents = 0; - clear_error(ec); - int result = error_wrapper(::poll(&fds, 1, -1), ec); - if (result >= 0) - clear_error(ec); - return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -} +BOOST_ASIO_DECL int getpeername(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, bool cached, boost::system::error_code& ec); -inline int poll_write(socket_type s, boost::system::error_code& ec) -{ -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - FD_SET fds; - FD_ZERO(&fds); - FD_SET(s, &fds); - clear_error(ec); - int result = error_wrapper(::select(s, 0, &fds, 0, 0), ec); - if (result >= 0) - clear_error(ec); - return result; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - pollfd fds; - fds.fd = s; - fds.events = POLLOUT; - fds.revents = 0; - clear_error(ec); - int result = error_wrapper(::poll(&fds, 1, -1), ec); - if (result >= 0) - clear_error(ec); - return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -} +BOOST_ASIO_DECL int getsockname(socket_type s, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec); -inline int poll_connect(socket_type s, boost::system::error_code& ec) -{ -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - FD_SET write_fds; - FD_ZERO(&write_fds); - FD_SET(s, &write_fds); - FD_SET except_fds; - FD_ZERO(&except_fds); - FD_SET(s, &except_fds); - clear_error(ec); - int result = error_wrapper(::select(s, 0, &write_fds, &except_fds, 0), ec); - if (result >= 0) - clear_error(ec); - return result; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - pollfd fds; - fds.fd = s; - fds.events = POLLOUT; - fds.revents = 0; - clear_error(ec); - int result = error_wrapper(::poll(&fds, 1, -1), ec); - if (result >= 0) - clear_error(ec); - return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -} +BOOST_ASIO_DECL int ioctl(socket_type s, state_type& state, + int cmd, ioctl_arg_type* arg, boost::system::error_code& ec); -inline const char* inet_ntop(int af, const void* src, char* dest, size_t length, - unsigned long scope_id, boost::system::error_code& ec) -{ - clear_error(ec); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - using namespace std; // For memcpy. - - if (af != AF_INET && af != AF_INET6) - { - ec = boost::asio::error::address_family_not_supported; - return 0; - } - - union - { - socket_addr_type base; - sockaddr_storage_type storage; - sockaddr_in4_type v4; - sockaddr_in6_type v6; - } address; - DWORD address_length; - if (af == AF_INET) - { - address_length = sizeof(sockaddr_in4_type); - address.v4.sin_family = AF_INET; - address.v4.sin_port = 0; - memcpy(&address.v4.sin_addr, src, sizeof(in4_addr_type)); - } - else // AF_INET6 - { - address_length = sizeof(sockaddr_in6_type); - address.v6.sin6_family = AF_INET6; - address.v6.sin6_port = 0; - address.v6.sin6_flowinfo = 0; - address.v6.sin6_scope_id = scope_id; - memcpy(&address.v6.sin6_addr, src, sizeof(in6_addr_type)); - } - - DWORD string_length = static_cast<DWORD>(length); -#if defined(BOOST_NO_ANSI_APIS) - LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR)); - int result = error_wrapper(::WSAAddressToStringW(&address.base, - address_length, 0, string_buffer, &string_length), ec); - ::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, dest, length, 0, 0); -#else - int result = error_wrapper(::WSAAddressToStringA( - &address.base, address_length, 0, dest, &string_length), ec); -#endif - - // Windows may set error code on success. - if (result != socket_error_retval) - clear_error(ec); - - // Windows may not set an error code on failure. - else if (result == socket_error_retval && !ec) - ec = boost::asio::error::invalid_argument; - - return result == socket_error_retval ? 0 : dest; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - const char* result = error_wrapper(::inet_ntop(af, src, dest, length), ec); - if (result == 0 && !ec) - ec = boost::asio::error::invalid_argument; - if (result != 0 && af == AF_INET6 && scope_id != 0) - { - using namespace std; // For strcat and sprintf. - char if_name[IF_NAMESIZE + 1] = "%"; - const in6_addr_type* ipv6_address = static_cast<const in6_addr_type*>(src); - bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address); - if (!is_link_local || if_indextoname(scope_id, if_name + 1) == 0) - sprintf(if_name + 1, "%lu", scope_id); - strcat(dest, if_name); - } - return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -} +BOOST_ASIO_DECL int select(int nfds, fd_set* readfds, fd_set* writefds, + fd_set* exceptfds, timeval* timeout, boost::system::error_code& ec); -inline int inet_pton(int af, const char* src, void* dest, - unsigned long* scope_id, boost::system::error_code& ec) -{ - clear_error(ec); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - using namespace std; // For memcpy and strcmp. - - if (af != AF_INET && af != AF_INET6) - { - ec = boost::asio::error::address_family_not_supported; - return -1; - } - - union - { - socket_addr_type base; - sockaddr_storage_type storage; - sockaddr_in4_type v4; - sockaddr_in6_type v6; - } address; - int address_length = sizeof(sockaddr_storage_type); -#if defined(BOOST_NO_ANSI_APIS) - int num_wide_chars = strlen(src) + 1; - LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR)); - ::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars); - int result = error_wrapper(::WSAStringToAddressW( - wide_buffer, af, 0, &address.base, &address_length), ec); -#else - int result = error_wrapper(::WSAStringToAddressA( - const_cast<char*>(src), af, 0, &address.base, &address_length), ec); -#endif - - if (af == AF_INET) - { - if (result != socket_error_retval) - { - memcpy(dest, &address.v4.sin_addr, sizeof(in4_addr_type)); - clear_error(ec); - } - else if (strcmp(src, "255.255.255.255") == 0) - { - static_cast<in4_addr_type*>(dest)->s_addr = INADDR_NONE; - clear_error(ec); - } - } - else // AF_INET6 - { - if (result != socket_error_retval) - { - memcpy(dest, &address.v6.sin6_addr, sizeof(in6_addr_type)); - if (scope_id) - *scope_id = address.v6.sin6_scope_id; - clear_error(ec); - } - } - - // Windows may not set an error code on failure. - if (result == socket_error_retval && !ec) - ec = boost::asio::error::invalid_argument; - - if (result != socket_error_retval) - clear_error(ec); - - return result == socket_error_retval ? -1 : 1; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - int result = error_wrapper(::inet_pton(af, src, dest), ec); - if (result <= 0 && !ec) - ec = boost::asio::error::invalid_argument; - if (result > 0 && af == AF_INET6 && scope_id) - { - using namespace std; // For strchr and atoi. - *scope_id = 0; - if (const char* if_name = strchr(src, '%')) - { - in6_addr_type* ipv6_address = static_cast<in6_addr_type*>(dest); - bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address); - if (is_link_local) - *scope_id = if_nametoindex(if_name + 1); - if (*scope_id == 0) - *scope_id = atoi(if_name + 1); - } - } - return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -} +BOOST_ASIO_DECL int poll_read(socket_type s, boost::system::error_code& ec); -inline int gethostname(char* name, int namelen, boost::system::error_code& ec) -{ - clear_error(ec); - int result = error_wrapper(::gethostname(name, namelen), ec); -#if defined(BOOST_WINDOWS) - if (result == 0) - clear_error(ec); -#endif - return result; -} - -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) \ - || defined(__MACH__) && defined(__APPLE__) - -// The following functions are only needed for emulation of getaddrinfo and -// getnameinfo. - -inline boost::system::error_code translate_netdb_error(int error) -{ - switch (error) - { - case 0: - return boost::system::error_code(); - case HOST_NOT_FOUND: - return boost::asio::error::host_not_found; - case TRY_AGAIN: - return boost::asio::error::host_not_found_try_again; - case NO_RECOVERY: - return boost::asio::error::no_recovery; - case NO_DATA: - return boost::asio::error::no_data; - default: - BOOST_ASSERT(false); - return boost::asio::error::invalid_argument; - } -} - -inline hostent* gethostbyaddr(const char* addr, int length, int af, - hostent* result, char* buffer, int buflength, boost::system::error_code& ec) -{ - clear_error(ec); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - (void)(buffer); - (void)(buflength); - hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec); - if (!retval) - return 0; - clear_error(ec); - *result = *retval; - return retval; -#elif defined(__sun) || defined(__QNX__) - int error = 0; - hostent* retval = error_wrapper(::gethostbyaddr_r(addr, length, af, result, - buffer, buflength, &error), ec); - if (error) - ec = translate_netdb_error(error); - return retval; -#elif defined(__MACH__) && defined(__APPLE__) - (void)(buffer); - (void)(buflength); - int error = 0; - hostent* retval = error_wrapper(::getipnodebyaddr( - addr, length, af, &error), ec); - if (error) - ec = translate_netdb_error(error); - if (!retval) - return 0; - *result = *retval; - return retval; -#else - hostent* retval = 0; - int error = 0; - error_wrapper(::gethostbyaddr_r(addr, length, af, result, buffer, - buflength, &retval, &error), ec); - if (error) - ec = translate_netdb_error(error); - return retval; -#endif -} - -inline hostent* gethostbyname(const char* name, int af, struct hostent* result, - char* buffer, int buflength, int ai_flags, boost::system::error_code& ec) -{ - clear_error(ec); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - (void)(buffer); - (void)(buflength); - (void)(ai_flags); - if (af != AF_INET) - { - ec = boost::asio::error::address_family_not_supported; - return 0; - } - hostent* retval = error_wrapper(::gethostbyname(name), ec); - if (!retval) - return 0; - clear_error(ec); - *result = *retval; - return result; -#elif defined(__sun) || defined(__QNX__) - (void)(ai_flags); - if (af != AF_INET) - { - ec = boost::asio::error::address_family_not_supported; - return 0; - } - int error = 0; - hostent* retval = error_wrapper(::gethostbyname_r(name, result, buffer, - buflength, &error), ec); - if (error) - ec = translate_netdb_error(error); - return retval; -#elif defined(__MACH__) && defined(__APPLE__) - (void)(buffer); - (void)(buflength); - int error = 0; - hostent* retval = error_wrapper(::getipnodebyname( - name, af, ai_flags, &error), ec); - if (error) - ec = translate_netdb_error(error); - if (!retval) - return 0; - *result = *retval; - return retval; -#else - (void)(ai_flags); - if (af != AF_INET) - { - ec = boost::asio::error::address_family_not_supported; - return 0; - } - hostent* retval = 0; - int error = 0; - error_wrapper(::gethostbyname_r(name, result, - buffer, buflength, &retval, &error), ec); - if (error) - ec = translate_netdb_error(error); - return retval; -#endif -} - -inline void freehostent(hostent* h) -{ -#if defined(__MACH__) && defined(__APPLE__) - if (h) - ::freehostent(h); -#else - (void)(h); -#endif -} - -// Emulation of getaddrinfo based on implementation in: -// Stevens, W. R., UNIX Network Programming Vol. 1, 2nd Ed., Prentice-Hall 1998. - -struct gai_search -{ - const char* host; - int family; -}; +BOOST_ASIO_DECL int poll_write(socket_type s, boost::system::error_code& ec); -inline int gai_nsearch(const char* host, - const addrinfo_type* hints, gai_search (&search)[2]) -{ - int search_count = 0; - if (host == 0 || host[0] == '\0') - { - if (hints->ai_flags & AI_PASSIVE) - { - // No host and AI_PASSIVE implies wildcard bind. - switch (hints->ai_family) - { - case AF_INET: - search[search_count].host = "0.0.0.0"; - search[search_count].family = AF_INET; - ++search_count; - break; - case AF_INET6: - search[search_count].host = "0::0"; - search[search_count].family = AF_INET6; - ++search_count; - break; - case AF_UNSPEC: - search[search_count].host = "0::0"; - search[search_count].family = AF_INET6; - ++search_count; - search[search_count].host = "0.0.0.0"; - search[search_count].family = AF_INET; - ++search_count; - break; - default: - break; - } - } - else - { - // No host and not AI_PASSIVE means connect to local host. - switch (hints->ai_family) - { - case AF_INET: - search[search_count].host = "localhost"; - search[search_count].family = AF_INET; - ++search_count; - break; - case AF_INET6: - search[search_count].host = "localhost"; - search[search_count].family = AF_INET6; - ++search_count; - break; - case AF_UNSPEC: - search[search_count].host = "localhost"; - search[search_count].family = AF_INET6; - ++search_count; - search[search_count].host = "localhost"; - search[search_count].family = AF_INET; - ++search_count; - break; - default: - break; - } - } - } - else - { - // Host is specified. - switch (hints->ai_family) - { - case AF_INET: - search[search_count].host = host; - search[search_count].family = AF_INET; - ++search_count; - break; - case AF_INET6: - search[search_count].host = host; - search[search_count].family = AF_INET6; - ++search_count; - break; - case AF_UNSPEC: - search[search_count].host = host; - search[search_count].family = AF_INET6; - ++search_count; - search[search_count].host = host; - search[search_count].family = AF_INET; - ++search_count; - break; - default: - break; - } - } - return search_count; -} - -template <typename T> -inline T* gai_alloc(std::size_t size = sizeof(T)) -{ - using namespace std; - T* p = static_cast<T*>(::operator new(size, std::nothrow)); - if (p) - memset(p, 0, size); - return p; -} - -inline void gai_free(void* p) -{ - ::operator delete(p); -} +BOOST_ASIO_DECL int poll_connect(socket_type s, boost::system::error_code& ec); -inline void gai_strcpy(char* target, const char* source, std::size_t max_size) -{ - using namespace std; -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) - strcpy_s(target, max_size, source); -#else - *target = 0; - strncat(target, source, max_size); -#endif -} - -enum { gai_clone_flag = 1 << 30 }; - -inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints, - const void* addr, int family) -{ - using namespace std; - - addrinfo_type* ai = gai_alloc<addrinfo_type>(); - if (ai == 0) - return EAI_MEMORY; - - ai->ai_next = 0; - **next = ai; - *next = &ai->ai_next; - - ai->ai_canonname = 0; - ai->ai_socktype = hints->ai_socktype; - if (ai->ai_socktype == 0) - ai->ai_flags |= gai_clone_flag; - ai->ai_protocol = hints->ai_protocol; - ai->ai_family = family; - - switch (ai->ai_family) - { - case AF_INET: - { - sockaddr_in4_type* sinptr = gai_alloc<sockaddr_in4_type>(); - if (sinptr == 0) - return EAI_MEMORY; - sinptr->sin_family = AF_INET; - memcpy(&sinptr->sin_addr, addr, sizeof(in4_addr_type)); - ai->ai_addr = reinterpret_cast<sockaddr*>(sinptr); - ai->ai_addrlen = sizeof(sockaddr_in4_type); - break; - } - case AF_INET6: - { - sockaddr_in6_type* sin6ptr = gai_alloc<sockaddr_in6_type>(); - if (sin6ptr == 0) - return EAI_MEMORY; - sin6ptr->sin6_family = AF_INET6; - memcpy(&sin6ptr->sin6_addr, addr, sizeof(in6_addr_type)); - ai->ai_addr = reinterpret_cast<sockaddr*>(sin6ptr); - ai->ai_addrlen = sizeof(sockaddr_in6_type); - break; - } - default: - break; - } - - return 0; -} - -inline addrinfo_type* gai_clone(addrinfo_type* ai) -{ - using namespace std; +BOOST_ASIO_DECL const char* inet_ntop(int af, const void* src, char* dest, + size_t length, unsigned long scope_id, boost::system::error_code& ec); - addrinfo_type* new_ai = gai_alloc<addrinfo_type>(); - if (new_ai == 0) - return new_ai; +BOOST_ASIO_DECL int inet_pton(int af, const char* src, void* dest, + unsigned long* scope_id, boost::system::error_code& ec); - new_ai->ai_next = ai->ai_next; - ai->ai_next = new_ai; +BOOST_ASIO_DECL int gethostname(char* name, + int namelen, boost::system::error_code& ec); - new_ai->ai_flags = 0; - new_ai->ai_family = ai->ai_family; - new_ai->ai_socktype = ai->ai_socktype; - new_ai->ai_protocol = ai->ai_protocol; - new_ai->ai_canonname = 0; - new_ai->ai_addrlen = ai->ai_addrlen; - new_ai->ai_addr = gai_alloc<sockaddr>(ai->ai_addrlen); - memcpy(new_ai->ai_addr, ai->ai_addr, ai->ai_addrlen); +BOOST_ASIO_DECL boost::system::error_code getaddrinfo(const char* host, + const char* service, const addrinfo_type& hints, + addrinfo_type** result, boost::system::error_code& ec); - return new_ai; -} +BOOST_ASIO_DECL boost::system::error_code background_getaddrinfo( + const weak_cancel_token_type& cancel_token, const char* host, + const char* service, const addrinfo_type& hints, + addrinfo_type** result, boost::system::error_code& ec); -inline int gai_port(addrinfo_type* aihead, int port, int socktype) -{ - int num_found = 0; - - for (addrinfo_type* ai = aihead; ai; ai = ai->ai_next) - { - if (ai->ai_flags & gai_clone_flag) - { - if (ai->ai_socktype != 0) - { - ai = gai_clone(ai); - if (ai == 0) - return -1; - // ai now points to newly cloned entry. - } - } - else if (ai->ai_socktype != socktype) - { - // Ignore if mismatch on socket type. - continue; - } - - ai->ai_socktype = socktype; - - switch (ai->ai_family) - { - case AF_INET: - { - sockaddr_in4_type* sinptr = - reinterpret_cast<sockaddr_in4_type*>(ai->ai_addr); - sinptr->sin_port = port; - ++num_found; - break; - } - case AF_INET6: - { - sockaddr_in6_type* sin6ptr = - reinterpret_cast<sockaddr_in6_type*>(ai->ai_addr); - sin6ptr->sin6_port = port; - ++num_found; - break; - } - default: - break; - } - } - - return num_found; -} - -inline int gai_serv(addrinfo_type* aihead, - const addrinfo_type* hints, const char* serv) -{ - using namespace std; - - int num_found = 0; - - if ( -#if defined(AI_NUMERICSERV) - (hints->ai_flags & AI_NUMERICSERV) || -#endif - isdigit(serv[0])) - { - int port = htons(atoi(serv)); - if (hints->ai_socktype) - { - // Caller specifies socket type. - int rc = gai_port(aihead, port, hints->ai_socktype); - if (rc < 0) - return EAI_MEMORY; - num_found += rc; - } - else - { - // Caller does not specify socket type. - int rc = gai_port(aihead, port, SOCK_STREAM); - if (rc < 0) - return EAI_MEMORY; - num_found += rc; - rc = gai_port(aihead, port, SOCK_DGRAM); - if (rc < 0) - return EAI_MEMORY; - num_found += rc; - } - } - else - { - // Try service name with TCP first, then UDP. - if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_STREAM) - { - servent* sptr = getservbyname(serv, "tcp"); - if (sptr != 0) - { - int rc = gai_port(aihead, sptr->s_port, SOCK_STREAM); - if (rc < 0) - return EAI_MEMORY; - num_found += rc; - } - } - if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_DGRAM) - { - servent* sptr = getservbyname(serv, "udp"); - if (sptr != 0) - { - int rc = gai_port(aihead, sptr->s_port, SOCK_DGRAM); - if (rc < 0) - return EAI_MEMORY; - num_found += rc; - } - } - } - - if (num_found == 0) - { - if (hints->ai_socktype == 0) - { - // All calls to getservbyname() failed. - return EAI_NONAME; - } - else - { - // Service not supported for socket type. - return EAI_SERVICE; - } - } - - return 0; -} - -inline int gai_echeck(const char* host, const char* service, - int flags, int family, int socktype, int protocol) -{ - (void)(flags); - (void)(protocol); - - // Host or service must be specified. - if (host == 0 || host[0] == '\0') - if (service == 0 || service[0] == '\0') - return EAI_NONAME; - - // Check combination of family and socket type. - switch (family) - { - case AF_UNSPEC: - break; - case AF_INET: - case AF_INET6: - if (service != 0 && service[0] != '\0') - if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM) - return EAI_SOCKTYPE; - break; - default: - return EAI_FAMILY; - } - - return 0; -} - -inline void freeaddrinfo_emulation(addrinfo_type* aihead) -{ - addrinfo_type* ai = aihead; - while (ai) - { - gai_free(ai->ai_addr); - gai_free(ai->ai_canonname); - addrinfo_type* ainext = ai->ai_next; - gai_free(ai); - ai = ainext; - } -} - -inline int getaddrinfo_emulation(const char* host, const char* service, - const addrinfo_type* hintsp, addrinfo_type** result) -{ - // Set up linked list of addrinfo structures. - addrinfo_type* aihead = 0; - addrinfo_type** ainext = &aihead; - char* canon = 0; - - // Supply default hints if not specified by caller. - addrinfo_type hints = addrinfo_type(); - hints.ai_family = AF_UNSPEC; - if (hintsp) - hints = *hintsp; - - // If the resolution is not specifically for AF_INET6, remove the AI_V4MAPPED - // and AI_ALL flags. -#if defined(AI_V4MAPPED) - if (hints.ai_family != AF_INET6) - hints.ai_flags &= ~AI_V4MAPPED; -#endif -#if defined(AI_ALL) - if (hints.ai_family != AF_INET6) - hints.ai_flags &= ~AI_ALL; -#endif - - // Basic error checking. - int rc = gai_echeck(host, service, hints.ai_flags, hints.ai_family, - hints.ai_socktype, hints.ai_protocol); - if (rc != 0) - { - freeaddrinfo_emulation(aihead); - return rc; - } - - gai_search search[2]; - int search_count = gai_nsearch(host, &hints, search); - for (gai_search* sptr = search; sptr < search + search_count; ++sptr) - { - // Check for IPv4 dotted decimal string. - in4_addr_type inaddr; - boost::system::error_code ec; - if (socket_ops::inet_pton(AF_INET, sptr->host, &inaddr, 0, ec) == 1) - { - if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET) - { - freeaddrinfo_emulation(aihead); - gai_free(canon); - return EAI_FAMILY; - } - if (sptr->family == AF_INET) - { - rc = gai_aistruct(&ainext, &hints, &inaddr, AF_INET); - if (rc != 0) - { - freeaddrinfo_emulation(aihead); - gai_free(canon); - return rc; - } - } - continue; - } - - // Check for IPv6 hex string. - in6_addr_type in6addr; - if (socket_ops::inet_pton(AF_INET6, sptr->host, &in6addr, 0, ec) == 1) - { - if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET6) - { - freeaddrinfo_emulation(aihead); - gai_free(canon); - return EAI_FAMILY; - } - if (sptr->family == AF_INET6) - { - rc = gai_aistruct(&ainext, &hints, &in6addr, AF_INET6); - if (rc != 0) - { - freeaddrinfo_emulation(aihead); - gai_free(canon); - return rc; - } - } - continue; - } - - // Look up hostname. - hostent hent; - char hbuf[8192] = ""; - hostent* hptr = socket_ops::gethostbyname(sptr->host, - sptr->family, &hent, hbuf, sizeof(hbuf), hints.ai_flags, ec); - if (hptr == 0) - { - if (search_count == 2) - { - // Failure is OK if there are multiple searches. - continue; - } - freeaddrinfo_emulation(aihead); - gai_free(canon); - if (ec == boost::asio::error::host_not_found) - return EAI_NONAME; - if (ec == boost::asio::error::host_not_found_try_again) - return EAI_AGAIN; - if (ec == boost::asio::error::no_recovery) - return EAI_FAIL; - if (ec == boost::asio::error::no_data) - return EAI_NONAME; - return EAI_NONAME; - } - - // Check for address family mismatch if one was specified. - if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype) - { - freeaddrinfo_emulation(aihead); - gai_free(canon); - socket_ops::freehostent(hptr); - return EAI_FAMILY; - } - - // Save canonical name first time. - if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0] - && (hints.ai_flags & AI_CANONNAME) && canon == 0) - { - std::size_t canon_len = strlen(hptr->h_name) + 1; - canon = gai_alloc<char>(canon_len); - if (canon == 0) - { - freeaddrinfo_emulation(aihead); - socket_ops::freehostent(hptr); - return EAI_MEMORY; - } - gai_strcpy(canon, hptr->h_name, canon_len); - } - - // Create an addrinfo structure for each returned address. - for (char** ap = hptr->h_addr_list; *ap; ++ap) - { - rc = gai_aistruct(&ainext, &hints, *ap, hptr->h_addrtype); - if (rc != 0) - { - freeaddrinfo_emulation(aihead); - gai_free(canon); - socket_ops::freehostent(hptr); - return EAI_FAMILY; - } - } - - socket_ops::freehostent(hptr); - } - - // Check if we found anything. - if (aihead == 0) - { - gai_free(canon); - return EAI_NONAME; - } - - // Return canonical name in first entry. - if (host != 0 && host[0] != '\0' && (hints.ai_flags & AI_CANONNAME)) - { - if (canon) - { - aihead->ai_canonname = canon; - canon = 0; - } - else - { - std::size_t canonname_len = strlen(search[0].host) + 1; - aihead->ai_canonname = gai_alloc<char>(canonname_len); - if (aihead->ai_canonname == 0) - { - freeaddrinfo_emulation(aihead); - return EAI_MEMORY; - } - gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len); - } - } - gai_free(canon); - - // Process the service name. - if (service != 0 && service[0] != '\0') - { - rc = gai_serv(aihead, &hints, service); - if (rc != 0) - { - freeaddrinfo_emulation(aihead); - return rc; - } - } - - // Return result to caller. - *result = aihead; - return 0; -} - -inline boost::system::error_code getnameinfo_emulation( - const socket_addr_type* sa, std::size_t salen, char* host, - std::size_t hostlen, char* serv, std::size_t servlen, int flags, - boost::system::error_code& ec) -{ - using namespace std; - - const char* addr; - size_t addr_len; - unsigned short port; - switch (sa->sa_family) - { - case AF_INET: - if (salen != sizeof(sockaddr_in4_type)) - { - return ec = boost::asio::error::invalid_argument; - } - addr = reinterpret_cast<const char*>( - &reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_addr); - addr_len = sizeof(in4_addr_type); - port = reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_port; - break; - case AF_INET6: - if (salen != sizeof(sockaddr_in6_type)) - { - return ec = boost::asio::error::invalid_argument; - } - addr = reinterpret_cast<const char*>( - &reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_addr); - addr_len = sizeof(in6_addr_type); - port = reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_port; - break; - default: - return ec = boost::asio::error::address_family_not_supported; - } - - if (host && hostlen > 0) - { - if (flags & NI_NUMERICHOST) - { - if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen, 0, ec) == 0) - { - return ec; - } - } - else - { - hostent hent; - char hbuf[8192] = ""; - hostent* hptr = socket_ops::gethostbyaddr(addr, - static_cast<int>(addr_len), sa->sa_family, - &hent, hbuf, sizeof(hbuf), ec); - if (hptr && hptr->h_name && hptr->h_name[0] != '\0') - { - if (flags & NI_NOFQDN) - { - char* dot = strchr(hptr->h_name, '.'); - if (dot) - { - *dot = 0; - } - } - gai_strcpy(host, hptr->h_name, hostlen); - socket_ops::freehostent(hptr); - } - else - { - socket_ops::freehostent(hptr); - if (flags & NI_NAMEREQD) - { - return ec = boost::asio::error::host_not_found; - } - if (socket_ops::inet_ntop(sa->sa_family, - addr, host, hostlen, 0, ec) == 0) - { - return ec; - } - } - } - } - - if (serv && servlen > 0) - { - if (flags & NI_NUMERICSERV) - { - if (servlen < 6) - { - return ec = boost::asio::error::no_buffer_space; - } -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) - sprintf_s(serv, servlen, "%u", ntohs(port)); -#else - sprintf(serv, "%u", ntohs(port)); -#endif - } - else - { -#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) - static ::pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - ::pthread_mutex_lock(&mutex); -#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) - servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0); - if (sptr && sptr->s_name && sptr->s_name[0] != '\0') - { - gai_strcpy(serv, sptr->s_name, servlen); - } - else - { - if (servlen < 6) - { - return ec = boost::asio::error::no_buffer_space; - } -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) - sprintf_s(serv, servlen, "%u", ntohs(port)); -#else - sprintf(serv, "%u", ntohs(port)); -#endif - } -#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) - ::pthread_mutex_unlock(&mutex); -#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) - } - } - - clear_error(ec); - return ec; -} +BOOST_ASIO_DECL void freeaddrinfo(addrinfo_type* ai); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - // || defined(__MACH__) && defined(__APPLE__) +BOOST_ASIO_DECL boost::system::error_code getnameinfo( + const socket_addr_type* addr, std::size_t addrlen, + char* host, std::size_t hostlen, char* serv, + std::size_t servlen, int flags, boost::system::error_code& ec); -inline boost::system::error_code translate_addrinfo_error(int error) -{ - switch (error) - { - case 0: - return boost::system::error_code(); - case EAI_AGAIN: - return boost::asio::error::host_not_found_try_again; - case EAI_BADFLAGS: - return boost::asio::error::invalid_argument; - case EAI_FAIL: - return boost::asio::error::no_recovery; - case EAI_FAMILY: - return boost::asio::error::address_family_not_supported; - case EAI_MEMORY: - return boost::asio::error::no_memory; - case EAI_NONAME: -#if defined(EAI_ADDRFAMILY) - case EAI_ADDRFAMILY: -#endif -#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) - case EAI_NODATA: -#endif - return boost::asio::error::host_not_found; - case EAI_SERVICE: - return boost::asio::error::service_not_found; - case EAI_SOCKTYPE: - return boost::asio::error::socket_type_not_supported; - default: // Possibly the non-portable EAI_SYSTEM. -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - return boost::system::error_code( - WSAGetLastError(), boost::asio::error::get_system_category()); -#else - return boost::system::error_code( - errno, boost::asio::error::get_system_category()); -#endif - } -} - -inline boost::system::error_code getaddrinfo(const char* host, - const char* service, const addrinfo_type* hints, addrinfo_type** result, - boost::system::error_code& ec) -{ - clear_error(ec); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) -# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) - // Building for Windows XP, Windows Server 2003, or later. - int error = ::getaddrinfo(host, service, hints, result); - return ec = translate_addrinfo_error(error); -# else - // Building for Windows 2000 or earlier. - typedef int (WSAAPI *gai_t)(const char*, - const char*, const addrinfo_type*, addrinfo_type**); - if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) - { - if (gai_t gai = (gai_t)::GetProcAddress(winsock_module, "getaddrinfo")) - { - int error = gai(host, service, hints, result); - return ec = translate_addrinfo_error(error); - } - } - int error = getaddrinfo_emulation(host, service, hints, result); - return ec = translate_addrinfo_error(error); -# endif -#elif defined(__MACH__) && defined(__APPLE__) - int error = getaddrinfo_emulation(host, service, hints, result); - return ec = translate_addrinfo_error(error); -#else - int error = ::getaddrinfo(host, service, hints, result); - return ec = translate_addrinfo_error(error); -#endif -} - -inline void freeaddrinfo(addrinfo_type* ai) -{ -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) -# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) - // Building for Windows XP, Windows Server 2003, or later. - ::freeaddrinfo(ai); -# else - // Building for Windows 2000 or earlier. - typedef int (WSAAPI *fai_t)(addrinfo_type*); - if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) - { - if (fai_t fai = (fai_t)::GetProcAddress(winsock_module, "freeaddrinfo")) - { - fai(ai); - return; - } - } - freeaddrinfo_emulation(ai); -# endif -#elif defined(__MACH__) && defined(__APPLE__) - freeaddrinfo_emulation(ai); -#else - ::freeaddrinfo(ai); -#endif -} - -inline boost::system::error_code getnameinfo(const socket_addr_type* addr, - std::size_t addrlen, char* host, std::size_t hostlen, - char* serv, std::size_t servlen, int flags, boost::system::error_code& ec) -{ -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) -# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) - // Building for Windows XP, Windows Server 2003, or later. - clear_error(ec); - int error = ::getnameinfo(addr, static_cast<socklen_t>(addrlen), - host, static_cast<DWORD>(hostlen), - serv, static_cast<DWORD>(servlen), flags); - return ec = translate_addrinfo_error(error); -# else - // Building for Windows 2000 or earlier. - typedef int (WSAAPI *gni_t)(const socket_addr_type*, - int, char*, DWORD, char*, DWORD, int); - if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32")) - { - if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo")) - { - clear_error(ec); - int error = gni(addr, static_cast<int>(addrlen), - host, static_cast<DWORD>(hostlen), - serv, static_cast<DWORD>(servlen), flags); - return ec = translate_addrinfo_error(error); - } - } - clear_error(ec); - return getnameinfo_emulation(addr, addrlen, - host, hostlen, serv, servlen, flags, ec); -# endif -#elif defined(__MACH__) && defined(__APPLE__) - using namespace std; // For memcpy. - sockaddr_storage_type tmp_addr; - memcpy(&tmp_addr, addr, addrlen); - tmp_addr.ss_len = addrlen; - addr = reinterpret_cast<socket_addr_type*>(&tmp_addr); - clear_error(ec); - return getnameinfo_emulation(addr, addrlen, - host, hostlen, serv, servlen, flags, ec); -#else - clear_error(ec); - int error = ::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags); - return ec = translate_addrinfo_error(error); -#endif -} - -inline u_long_type network_to_host_long(u_long_type value) -{ - return ntohl(value); -} +BOOST_ASIO_DECL boost::system::error_code sync_getnameinfo( + const socket_addr_type* addr, std::size_t addrlen, + char* host, std::size_t hostlen, char* serv, + std::size_t servlen, int sock_type, boost::system::error_code& ec); -inline u_long_type host_to_network_long(u_long_type value) -{ - return htonl(value); -} +BOOST_ASIO_DECL boost::system::error_code background_getnameinfo( + const weak_cancel_token_type& cancel_token, + const socket_addr_type* addr, std::size_t addrlen, + char* host, std::size_t hostlen, char* serv, + std::size_t servlen, int sock_type, boost::system::error_code& ec); -inline u_short_type network_to_host_short(u_short_type value) -{ - return ntohs(value); -} +BOOST_ASIO_DECL u_long_type network_to_host_long(u_long_type value); -inline u_short_type host_to_network_short(u_short_type value) -{ - return htons(value); -} +BOOST_ASIO_DECL u_long_type host_to_network_long(u_long_type value); + +BOOST_ASIO_DECL u_short_type network_to_host_short(u_short_type value); + +BOOST_ASIO_DECL u_short_type host_to_network_short(u_short_type value); } // namespace socket_ops } // namespace detail @@ -1911,4 +284,8 @@ inline u_short_type host_to_network_short(u_short_type value) #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/socket_ops.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + #endif // BOOST_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/socket_option.hpp b/3rdParty/Boost/src/boost/asio/detail/socket_option.hpp index e31aae4..37efa83 100644 --- a/3rdParty/Boost/src/boost/asio/detail/socket_option.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/socket_option.hpp @@ -1,6 +1,6 @@ // -// socket_option.hpp -// ~~~~~~~~~~~~~~~~~ +// detail/socket_option.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,17 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> #include <stdexcept> #include <boost/config.hpp> #include <boost/throw_exception.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { diff --git a/3rdParty/Boost/src/boost/asio/detail/socket_select_interrupter.hpp b/3rdParty/Boost/src/boost/asio/detail/socket_select_interrupter.hpp index a538ae5..b674514 100644 --- a/3rdParty/Boost/src/boost/asio/detail/socket_select_interrupter.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/socket_select_interrupter.hpp @@ -1,6 +1,6 @@ // -// socket_select_interrupter.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/socket_select_interrupter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,19 +15,16 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <cstdlib> -#include <boost/throw_exception.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_WINDOWS) \ + || defined(__CYGWIN__) \ + || defined(__SYMBIAN32__) -#include <boost/asio/error.hpp> -#include <boost/asio/detail/socket_holder.hpp> -#include <boost/asio/detail/socket_ops.hpp> #include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -36,135 +33,16 @@ class socket_select_interrupter { public: // Constructor. - socket_select_interrupter() - { - boost::system::error_code ec; - socket_holder acceptor(socket_ops::socket( - AF_INET, SOCK_STREAM, IPPROTO_TCP, ec)); - if (acceptor.get() == invalid_socket) - { - boost::system::system_error e(ec, "socket_select_interrupter"); - boost::throw_exception(e); - } - - int opt = 1; - socket_ops::setsockopt(acceptor.get(), - SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt), ec); - - using namespace std; // For memset. - sockaddr_in4_type addr; - std::size_t addr_len = sizeof(addr); - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - addr.sin_port = 0; - if (socket_ops::bind(acceptor.get(), (const socket_addr_type*)&addr, - addr_len, ec) == socket_error_retval) - { - boost::system::system_error e(ec, "socket_select_interrupter"); - boost::throw_exception(e); - } - - if (socket_ops::getsockname(acceptor.get(), (socket_addr_type*)&addr, - &addr_len, ec) == socket_error_retval) - { - boost::system::system_error e(ec, "socket_select_interrupter"); - boost::throw_exception(e); - } - - // Some broken firewalls on Windows will intermittently cause getsockname to - // return 0.0.0.0 when the socket is actually bound to 127.0.0.1. We - // explicitly specify the target address here to work around this problem. - addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - - if (socket_ops::listen(acceptor.get(), - SOMAXCONN, ec) == socket_error_retval) - { - boost::system::system_error e(ec, "socket_select_interrupter"); - boost::throw_exception(e); - } - - socket_holder client(socket_ops::socket( - AF_INET, SOCK_STREAM, IPPROTO_TCP, ec)); - if (client.get() == invalid_socket) - { - boost::system::system_error e(ec, "socket_select_interrupter"); - boost::throw_exception(e); - } - - if (socket_ops::connect(client.get(), (const socket_addr_type*)&addr, - addr_len, ec) == socket_error_retval) - { - boost::system::system_error e(ec, "socket_select_interrupter"); - boost::throw_exception(e); - } - - socket_holder server(socket_ops::accept(acceptor.get(), 0, 0, ec)); - if (server.get() == invalid_socket) - { - boost::system::system_error e(ec, "socket_select_interrupter"); - boost::throw_exception(e); - } - - ioctl_arg_type non_blocking = 1; - if (socket_ops::ioctl(client.get(), FIONBIO, &non_blocking, ec)) - { - boost::system::system_error e(ec, "socket_select_interrupter"); - boost::throw_exception(e); - } - - opt = 1; - socket_ops::setsockopt(client.get(), - IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec); - - non_blocking = 1; - if (socket_ops::ioctl(server.get(), FIONBIO, &non_blocking, ec)) - { - boost::system::system_error e(ec, "socket_select_interrupter"); - boost::throw_exception(e); - } - - opt = 1; - socket_ops::setsockopt(server.get(), - IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec); - - read_descriptor_ = server.release(); - write_descriptor_ = client.release(); - } + BOOST_ASIO_DECL socket_select_interrupter(); // Destructor. - ~socket_select_interrupter() - { - boost::system::error_code ec; - if (read_descriptor_ != invalid_socket) - socket_ops::close(read_descriptor_, ec); - if (write_descriptor_ != invalid_socket) - socket_ops::close(write_descriptor_, ec); - } + BOOST_ASIO_DECL ~socket_select_interrupter(); // Interrupt the select call. - void interrupt() - { - char byte = 0; - socket_ops::buf b; - socket_ops::init_buf(b, &byte, 1); - boost::system::error_code ec; - socket_ops::send(write_descriptor_, &b, 1, 0, ec); - } + BOOST_ASIO_DECL void interrupt(); // Reset the select interrupt. Returns true if the call was interrupted. - bool reset() - { - char data[1024]; - socket_ops::buf b; - socket_ops::init_buf(b, data, sizeof(data)); - boost::system::error_code ec; - int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec); - bool was_interrupted = (bytes_read > 0); - while (bytes_read == sizeof(data)) - bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec); - return was_interrupted; - } + BOOST_ASIO_DECL bool reset(); // Get the read descriptor to be passed to select. socket_type read_descriptor() const @@ -191,4 +69,12 @@ private: #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/socket_select_interrupter.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) + #endif // BOOST_ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/socket_types.hpp b/3rdParty/Boost/src/boost/asio/detail/socket_types.hpp index 1009164..616e85a 100644 --- a/3rdParty/Boost/src/boost/asio/detail/socket_types.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/socket_types.hpp @@ -1,6 +1,6 @@ // -// socket_types.hpp -// ~~~~~~~~~~~~~~~~ +// detail/socket_types.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,69 +15,19 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) # if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) # error WinSock.h has already been included # endif // defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) -# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) -# if defined(_MSC_VER) || defined(__BORLANDC__) -# pragma message( \ - "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\ - "- add -D_WIN32_WINNT=0x0501 to the compiler command line; or\n"\ - "- add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.\n"\ - "Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).") -# else // defined(_MSC_VER) || defined(__BORLANDC__) -# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. -# warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line. -# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target). -# endif // defined(_MSC_VER) || defined(__BORLANDC__) -# define _WIN32_WINNT 0x0501 -# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) -# if defined(_MSC_VER) -# if defined(_WIN32) && !defined(WIN32) -# if !defined(_WINSOCK2API_) -# define WIN32 // Needed for correct types in winsock2.h -# else // !defined(_WINSOCK2API_) -# error Please define the macro WIN32 in your compiler options -# endif // !defined(_WINSOCK2API_) -# endif // defined(_WIN32) && !defined(WIN32) -# endif // defined(_MSC_VER) # if defined(__BORLANDC__) # include <stdlib.h> // Needed for __errno -# if defined(__WIN32__) && !defined(WIN32) -# if !defined(_WINSOCK2API_) -# define WIN32 // Needed for correct types in winsock2.h -# else // !defined(_WINSOCK2API_) -# error Please define the macro WIN32 in your compiler options -# endif // !defined(_WINSOCK2API_) -# endif // defined(__WIN32__) && !defined(WIN32) # if !defined(_WSPIAPI_H_) # define _WSPIAPI_H_ # define BOOST_ASIO_WSPIAPI_H_DEFINED # endif // !defined(_WSPIAPI_H_) # endif // defined(__BORLANDC__) -# if !defined(BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN) -# if !defined(WIN32_LEAN_AND_MEAN) -# define WIN32_LEAN_AND_MEAN -# endif // !defined(WIN32_LEAN_AND_MEAN) -# endif // !defined(BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN) -# if !defined(BOOST_ASIO_NO_NOMINMAX) -# if !defined(NOMINMAX) -# define NOMINMAX 1 -# endif // !defined(NOMINMAX) -# endif // !defined(BOOST_ASIO_NO_NOMINMAX) -# if defined(__CYGWIN__) -# if !defined(__USE_W32_SOCKETS) -# error You must add -D__USE_W32_SOCKETS to your compiler options. -# endif // !defined(__USE_W32_SOCKETS) -# endif // defined(__CYGWIN__) # include <winsock2.h> # include <ws2tcpip.h> # include <mswsock.h> @@ -96,18 +46,25 @@ # include <boost/asio/detail/old_win_sdk_compat.hpp> #else # include <sys/ioctl.h> -# include <sys/poll.h> +# if !defined(__SYMBIAN32__) +# include <sys/poll.h> +# endif # include <sys/types.h> -# if defined(__hpux) && !defined(__HP_aCC) +# include <sys/stat.h> +# include <fcntl.h> +# if defined(__hpux) # include <sys/time.h> -# else +# endif +# if !defined(__hpux) || defined(__SELECT) # include <sys/select.h> # endif # include <sys/socket.h> # include <sys/uio.h> # include <sys/un.h> # include <netinet/in.h> -# include <netinet/tcp.h> +# if !defined(__SYMBIAN32__) +# include <netinet/tcp.h> +# endif # include <arpa/inet.h> # include <netdb.h> # include <net/if.h> @@ -117,7 +74,8 @@ # include <sys/sockio.h> # endif #endif -#include <boost/asio/detail/pop_options.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/detail/solaris_fenced_block.hpp b/3rdParty/Boost/src/boost/asio/detail/solaris_fenced_block.hpp index be9803e..db6cb98 100644 --- a/3rdParty/Boost/src/boost/asio/detail/solaris_fenced_block.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/solaris_fenced_block.hpp @@ -1,6 +1,6 @@ // -// solaris_fenced_block.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/solaris_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,17 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if defined(__sun) -#include <boost/asio/detail/push_options.hpp> #include <atomic.h> -#include <boost/asio/detail/pop_options.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -52,8 +48,8 @@ public: } // namespace asio } // namespace boost -#endif // defined(__sun) - #include <boost/asio/detail/pop_options.hpp> +#endif // defined(__sun) + #endif // BOOST_ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/strand_service.hpp b/3rdParty/Boost/src/boost/asio/detail/strand_service.hpp index d6b45b1..24bec7c 100644 --- a/3rdParty/Boost/src/boost/asio/detail/strand_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/strand_service.hpp @@ -1,6 +1,6 @@ // -// strand_service.hpp -// ~~~~~~~~~~~~~~~~~~ +// detail/strand_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,23 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/functional/hash.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/scoped_ptr.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/io_service.hpp> -#include <boost/asio/detail/call_stack.hpp> -#include <boost/asio/detail/completion_handler.hpp> -#include <boost/asio/detail/fenced_block.hpp> -#include <boost/asio/detail/handler_alloc_helpers.hpp> -#include <boost/asio/detail/handler_invoke_helpers.hpp> #include <boost/asio/detail/mutex.hpp> #include <boost/asio/detail/op_queue.hpp> #include <boost/asio/detail/operation.hpp> -#include <boost/asio/detail/service_base.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -42,7 +33,10 @@ class strand_service : public boost::asio::detail::service_base<strand_service> { private: + // Helper class to re-post the strand on exit. struct on_do_complete_exit; + + // Helper class to re-post the strand on exit. struct on_dispatch_exit; public: @@ -52,11 +46,7 @@ public: : public operation { public: - strand_impl() - : operation(&strand_service::do_complete), - count_(0) - { - } + strand_impl(); private: // Only this service will have access to the internal values. @@ -77,180 +67,29 @@ public: typedef strand_impl* implementation_type; // Construct a new strand service for the specified io_service. - explicit strand_service(boost::asio::io_service& io_service) - : boost::asio::detail::service_base<strand_service>(io_service), - io_service_(boost::asio::use_service<io_service_impl>(io_service)), - mutex_(), - salt_(0) - { - } + BOOST_ASIO_DECL explicit strand_service(boost::asio::io_service& io_service); // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - op_queue<operation> ops; - - boost::asio::detail::mutex::scoped_lock lock(mutex_); - - for (std::size_t i = 0; i < num_implementations; ++i) - if (strand_impl* impl = implementations_[i].get()) - ops.push(impl->queue_); - } + BOOST_ASIO_DECL void shutdown_service(); // Construct a new strand implementation. - void construct(implementation_type& impl) - { - std::size_t index = boost::hash_value(&impl); - boost::hash_combine(index, salt_++); - index = index % num_implementations; - - boost::asio::detail::mutex::scoped_lock lock(mutex_); - - if (!implementations_[index]) - implementations_[index].reset(new strand_impl); - impl = implementations_[index].get(); - } + BOOST_ASIO_DECL void construct(implementation_type& impl); // Destroy a strand implementation. - void destroy(implementation_type& impl) - { - impl = 0; - } + void destroy(implementation_type& impl); // Request the io_service to invoke the given handler. template <typename Handler> - void dispatch(implementation_type& impl, Handler handler) - { - // If we are already in the strand then the handler can run immediately. - if (call_stack<strand_impl>::contains(impl)) - { - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - return; - } - - // Allocate and construct an object to wrap the handler. - typedef completion_handler<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); - - // If we are running inside the io_service, and no other handler is queued - // or running, then the handler can run immediately. - bool can_dispatch = call_stack<io_service_impl>::contains(&io_service_); - impl->mutex_.lock(); - bool first = (++impl->count_ == 1); - if (can_dispatch && first) - { - // Immediate invocation is allowed. - impl->mutex_.unlock(); - - // Memory must be releaesed before any upcall is made. - ptr.reset(); - - // Indicate that this strand is executing on the current thread. - call_stack<strand_impl>::context ctx(impl); - - // Ensure the next handler, if any, is scheduled on block exit. - on_dispatch_exit on_exit = { &io_service_, impl }; - (void)on_exit; - - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - return; - } - - // Immediate invocation is not allowed, so enqueue for later. - impl->queue_.push(ptr.get()); - impl->mutex_.unlock(); - ptr.release(); - - // The first handler to be enqueued is responsible for scheduling the - // strand. - if (first) - io_service_.post_immediate_completion(impl); - } + void dispatch(implementation_type& impl, Handler handler); // Request the io_service to invoke the given handler and return immediately. template <typename Handler> - void post(implementation_type& impl, Handler handler) - { - // Allocate and construct an object to wrap the handler. - typedef completion_handler<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); - - // Add the handler to the queue. - impl->mutex_.lock(); - bool first = (++impl->count_ == 1); - impl->queue_.push(ptr.get()); - impl->mutex_.unlock(); - ptr.release(); - - // The first handler to be enqueue is responsible for scheduling the strand. - if (first) - io_service_.post_immediate_completion(impl); - } + void post(implementation_type& impl, Handler handler); private: - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - if (owner) - { - strand_impl* impl = static_cast<strand_impl*>(base); - - // Get the next handler to be executed. - impl->mutex_.lock(); - operation* o = impl->queue_.front(); - impl->queue_.pop(); - impl->mutex_.unlock(); - - // Indicate that this strand is executing on the current thread. - call_stack<strand_impl>::context ctx(impl); - - // Ensure the next handler, if any, is scheduled on block exit. - on_do_complete_exit on_exit = { owner, impl }; - (void)on_exit; - - o->complete(*owner); - } - } - - // Helper class to re-post the strand on exit. - struct on_do_complete_exit - { - io_service_impl* owner_; - strand_impl* impl_; - - ~on_do_complete_exit() - { - impl_->mutex_.lock(); - bool more_handlers = (--impl_->count_ > 0); - impl_->mutex_.unlock(); - - if (more_handlers) - owner_->post_immediate_completion(impl_); - } - }; - - // Helper class to re-post the strand on exit. - struct on_dispatch_exit - { - io_service_impl* io_service_; - strand_impl* impl_; - - ~on_dispatch_exit() - { - impl_->mutex_.lock(); - bool more_handlers = (--impl_->count_ > 0); - impl_->mutex_.unlock(); - - if (more_handlers) - io_service_->post_immediate_completion(impl_); - } - }; + BOOST_ASIO_DECL static void do_complete(io_service_impl* owner, + operation* base, boost::system::error_code ec, + std::size_t bytes_transferred); // The io_service implementation used to post completions. io_service_impl& io_service_; @@ -275,4 +114,9 @@ private: #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/impl/strand_service.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/strand_service.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + #endif // BOOST_ASIO_DETAIL_STRAND_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/task_io_service.hpp b/3rdParty/Boost/src/boost/asio/detail/task_io_service.hpp index f6de370..a9a7053 100644 --- a/3rdParty/Boost/src/boost/asio/detail/task_io_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/task_io_service.hpp @@ -1,6 +1,6 @@ // -// task_io_service.hpp -// ~~~~~~~~~~~~~~~~~~~ +// detail/task_io_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,181 +15,60 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> + +#if !defined(BOOST_ASIO_HAS_IOCP) +#include <boost/detail/atomic_count.hpp> +#include <boost/system/error_code.hpp> #include <boost/asio/io_service.hpp> -#include <boost/asio/detail/call_stack.hpp> -#include <boost/asio/detail/completion_handler.hpp> -#include <boost/asio/detail/event.hpp> -#include <boost/asio/detail/fenced_block.hpp> -#include <boost/asio/detail/handler_alloc_helpers.hpp> -#include <boost/asio/detail/handler_invoke_helpers.hpp> #include <boost/asio/detail/mutex.hpp> #include <boost/asio/detail/op_queue.hpp> -#include <boost/asio/detail/service_base.hpp> +#include <boost/asio/detail/reactor_fwd.hpp> #include <boost/asio/detail/task_io_service_fwd.hpp> #include <boost/asio/detail/task_io_service_operation.hpp> #include <boost/asio/detail/push_options.hpp> -#include <boost/detail/atomic_count.hpp> -#include <boost/system/error_code.hpp> -#include <boost/asio/detail/pop_options.hpp> namespace boost { namespace asio { namespace detail { -template <typename Task> class task_io_service - : public boost::asio::detail::service_base<task_io_service<Task> > + : public boost::asio::detail::service_base<task_io_service> { public: - typedef task_io_service_operation<Task> operation; + typedef task_io_service_operation operation; // Constructor. - task_io_service(boost::asio::io_service& io_service) - : boost::asio::detail::service_base<task_io_service<Task> >(io_service), - mutex_(), - task_(0), - task_interrupted_(true), - outstanding_work_(0), - stopped_(false), - shutdown_(false), - first_idle_thread_(0) - { - } + BOOST_ASIO_DECL task_io_service(boost::asio::io_service& io_service); - void init(size_t /*concurrency_hint*/) - { - } + // How many concurrent threads are likely to run the io_service. + BOOST_ASIO_DECL void init(std::size_t concurrency_hint); // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - shutdown_ = true; - lock.unlock(); - - // Destroy handler objects. - while (!op_queue_.empty()) - { - operation* o = op_queue_.front(); - op_queue_.pop(); - if (o != &task_operation_) - o->destroy(); - } - - // Reset to initial state. - task_ = 0; - } + BOOST_ASIO_DECL void shutdown_service(); // Initialise the task, if required. - void init_task() - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - if (!shutdown_ && !task_) - { - task_ = &use_service<Task>(this->get_io_service()); - op_queue_.push(&task_operation_); - wake_one_thread_and_unlock(lock); - } - } + BOOST_ASIO_DECL void init_task(); // Run the event loop until interrupted or no more work. - size_t run(boost::system::error_code& ec) - { - ec = boost::system::error_code(); - if (outstanding_work_ == 0) - { - stop(); - return 0; - } - - typename call_stack<task_io_service>::context ctx(this); - - idle_thread_info this_idle_thread; - this_idle_thread.next = 0; - - boost::asio::detail::mutex::scoped_lock lock(mutex_); - - size_t n = 0; - for (; do_one(lock, &this_idle_thread); lock.lock()) - if (n != (std::numeric_limits<size_t>::max)()) - ++n; - return n; - } + BOOST_ASIO_DECL std::size_t run(boost::system::error_code& ec); // Run until interrupted or one operation is performed. - size_t run_one(boost::system::error_code& ec) - { - ec = boost::system::error_code(); - if (outstanding_work_ == 0) - { - stop(); - return 0; - } - - typename call_stack<task_io_service>::context ctx(this); - - idle_thread_info this_idle_thread; - this_idle_thread.next = 0; - - boost::asio::detail::mutex::scoped_lock lock(mutex_); - - return do_one(lock, &this_idle_thread); - } + BOOST_ASIO_DECL std::size_t run_one(boost::system::error_code& ec); // Poll for operations without blocking. - size_t poll(boost::system::error_code& ec) - { - if (outstanding_work_ == 0) - { - stop(); - ec = boost::system::error_code(); - return 0; - } - - typename call_stack<task_io_service>::context ctx(this); - - boost::asio::detail::mutex::scoped_lock lock(mutex_); - - size_t n = 0; - for (; do_one(lock, 0); lock.lock()) - if (n != (std::numeric_limits<size_t>::max)()) - ++n; - return n; - } + BOOST_ASIO_DECL std::size_t poll(boost::system::error_code& ec); // Poll for one operation without blocking. - size_t poll_one(boost::system::error_code& ec) - { - ec = boost::system::error_code(); - if (outstanding_work_ == 0) - { - stop(); - return 0; - } - - typename call_stack<task_io_service>::context ctx(this); - - boost::asio::detail::mutex::scoped_lock lock(mutex_); - - return do_one(lock, 0); - } + BOOST_ASIO_DECL std::size_t poll_one(boost::system::error_code& ec); // Interrupt the event processing loop. - void stop() - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - stop_all_threads(lock); - } + BOOST_ASIO_DECL void stop(); // Reset in preparation for a subsequent run invocation. - void reset() - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - stopped_ = false; - } + BOOST_ASIO_DECL void reset(); // Notify that some work has started. void work_started() @@ -206,228 +85,60 @@ public: // Request invocation of the given handler. template <typename Handler> - void dispatch(Handler handler) - { - if (call_stack<task_io_service>::contains(this)) - { - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - else - post(handler); - } + void dispatch(Handler handler); // Request invocation of the given handler and return immediately. template <typename Handler> - void post(Handler handler) - { - // Allocate and construct an operation to wrap the handler. - typedef completion_handler<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); - - post_immediate_completion(ptr.get()); - ptr.release(); - } + void post(Handler handler); // Request invocation of the given operation and return immediately. Assumes // that work_started() has not yet been called for the operation. - void post_immediate_completion(operation* op) - { - work_started(); - post_deferred_completion(op); - } + BOOST_ASIO_DECL void post_immediate_completion(operation* op); // Request invocation of the given operation and return immediately. Assumes // that work_started() was previously called for the operation. - void post_deferred_completion(operation* op) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - op_queue_.push(op); - wake_one_thread_and_unlock(lock); - } + BOOST_ASIO_DECL void post_deferred_completion(operation* op); // Request invocation of the given operations and return immediately. Assumes // that work_started() was previously called for each operation. - void post_deferred_completions(op_queue<operation>& ops) - { - if (!ops.empty()) - { - boost::asio::detail::mutex::scoped_lock lock(mutex_); - op_queue_.push(ops); - wake_one_thread_and_unlock(lock); - } - } + BOOST_ASIO_DECL void post_deferred_completions(op_queue<operation>& ops); private: + // Structure containing information about an idle thread. struct idle_thread_info; - size_t do_one(boost::asio::detail::mutex::scoped_lock& lock, - idle_thread_info* this_idle_thread) - { - bool polling = !this_idle_thread; - bool task_has_run = false; - while (!stopped_) - { - if (!op_queue_.empty()) - { - // Prepare to execute first handler from queue. - operation* o = op_queue_.front(); - op_queue_.pop(); - bool more_handlers = (!op_queue_.empty()); - - if (o == &task_operation_) - { - task_interrupted_ = more_handlers || polling; - - // If the task has already run and we're polling then we're done. - if (task_has_run && polling) - { - task_interrupted_ = true; - op_queue_.push(&task_operation_); - return 0; - } - task_has_run = true; - - if (!more_handlers || !wake_one_idle_thread_and_unlock(lock)) - lock.unlock(); - - op_queue<operation> completed_ops; - task_cleanup c = { this, &lock, &completed_ops }; - (void)c; - - // Run the task. May throw an exception. Only block if the operation - // queue is empty and we're not polling, otherwise we want to return - // as soon as possible. - task_->run(!more_handlers && !polling, completed_ops); - } - else - { - if (more_handlers) - wake_one_thread_and_unlock(lock); - else - lock.unlock(); - - // Ensure the count of outstanding work is decremented on block exit. - work_finished_on_block_exit on_exit = { this }; - (void)on_exit; - - // Complete the operation. May throw an exception. - o->complete(*this); // deletes the operation object - - return 1; - } - } - else if (this_idle_thread) - { - // Nothing to run right now, so just wait for work to do. - this_idle_thread->next = first_idle_thread_; - first_idle_thread_ = this_idle_thread; - this_idle_thread->wakeup_event.clear(lock); - this_idle_thread->wakeup_event.wait(lock); - } - else - { - return 0; - } - } - - return 0; - } + // Run at most one operation. Blocks only if this_idle_thread is non-null. + BOOST_ASIO_DECL std::size_t do_one(mutex::scoped_lock& lock, + idle_thread_info* this_idle_thread); // Stop the task and all idle threads. - void stop_all_threads( - boost::asio::detail::mutex::scoped_lock& lock) - { - stopped_ = true; - - while (first_idle_thread_) - { - idle_thread_info* idle_thread = first_idle_thread_; - first_idle_thread_ = idle_thread->next; - idle_thread->next = 0; - idle_thread->wakeup_event.signal(lock); - } - - if (!task_interrupted_ && task_) - { - task_interrupted_ = true; - task_->interrupt(); - } - } + BOOST_ASIO_DECL void stop_all_threads(mutex::scoped_lock& lock); // Wakes a single idle thread and unlocks the mutex. Returns true if an idle // thread was found. If there is no idle thread, returns false and leaves the // mutex locked. - bool wake_one_idle_thread_and_unlock( - boost::asio::detail::mutex::scoped_lock& lock) - { - if (first_idle_thread_) - { - idle_thread_info* idle_thread = first_idle_thread_; - first_idle_thread_ = idle_thread->next; - idle_thread->next = 0; - idle_thread->wakeup_event.signal_and_unlock(lock); - return true; - } - return false; - } + BOOST_ASIO_DECL bool wake_one_idle_thread_and_unlock( + mutex::scoped_lock& lock); // Wake a single idle thread, or the task, and always unlock the mutex. - void wake_one_thread_and_unlock( - boost::asio::detail::mutex::scoped_lock& lock) - { - if (!wake_one_idle_thread_and_unlock(lock)) - { - if (!task_interrupted_ && task_) - { - task_interrupted_ = true; - task_->interrupt(); - } - lock.unlock(); - } - } + BOOST_ASIO_DECL void wake_one_thread_and_unlock( + mutex::scoped_lock& lock); // Helper class to perform task-related operations on block exit. struct task_cleanup; friend struct task_cleanup; - struct task_cleanup - { - ~task_cleanup() - { - // Enqueue the completed operations and reinsert the task at the end of - // the operation queue. - lock_->lock(); - task_io_service_->task_interrupted_ = true; - task_io_service_->op_queue_.push(*ops_); - task_io_service_->op_queue_.push(&task_io_service_->task_operation_); - } - - task_io_service* task_io_service_; - boost::asio::detail::mutex::scoped_lock* lock_; - op_queue<operation>* ops_; - }; // Helper class to call work_finished() on block exit. - struct work_finished_on_block_exit - { - ~work_finished_on_block_exit() - { - task_io_service_->work_finished(); - } - - task_io_service* task_io_service_; - }; + struct work_finished_on_block_exit; // Mutex to protect access to internal data. - boost::asio::detail::mutex mutex_; + mutex mutex_; // The task to be run by this service. - Task* task_; + reactor* task_; // Operation object to represent the position of the task in the queue. - struct task_operation : public operation + struct task_operation : operation { task_operation() : operation(0) {} } task_operation_; @@ -447,13 +158,6 @@ private: // Flag to indicate that the dispatcher has been shut down. bool shutdown_; - // Structure containing information about an idle thread. - struct idle_thread_info - { - event wakeup_event; - idle_thread_info* next; - }; - // The threads that are currently idle. idle_thread_info* first_idle_thread_; }; @@ -464,4 +168,11 @@ private: #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/impl/task_io_service.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/task_io_service.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // !defined(BOOST_ASIO_HAS_IOCP) + #endif // BOOST_ASIO_DETAIL_TASK_IO_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/task_io_service_fwd.hpp b/3rdParty/Boost/src/boost/asio/detail/task_io_service_fwd.hpp index 60a0790..24dd11b 100644 --- a/3rdParty/Boost/src/boost/asio/detail/task_io_service_fwd.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/task_io_service_fwd.hpp @@ -1,6 +1,6 @@ // -// task_io_service_fwd.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~ +// detail/task_io_service_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,19 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - namespace boost { namespace asio { namespace detail { -template <typename Task> class task_io_service; } // namespace detail } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_TASK_IO_SERVICE_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/task_io_service_operation.hpp b/3rdParty/Boost/src/boost/asio/detail/task_io_service_operation.hpp index 557f673..e234c07 100644 --- a/3rdParty/Boost/src/boost/asio/detail/task_io_service_operation.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/task_io_service_operation.hpp @@ -1,6 +1,6 @@ // -// task_io_service_operation.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/task_io_service_operation.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,22 +15,22 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/system/error_code.hpp> #include <boost/asio/detail/op_queue.hpp> #include <boost/asio/detail/task_io_service_fwd.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { // Base class for all operations. A function pointer is used instead of virtual // functions to avoid the associated overhead. -template <typename Task> class task_io_service_operation { public: - void complete(task_io_service<Task>& owner) + void complete(task_io_service& owner) { func_(&owner, this, boost::system::error_code(), 0); } @@ -41,8 +41,9 @@ public: } protected: - typedef void (*func_type)(task_io_service<Task>*, - task_io_service_operation*, boost::system::error_code, std::size_t); + typedef void (*func_type)(task_io_service*, + task_io_service_operation*, + boost::system::error_code, std::size_t); task_io_service_operation(func_type func) : next_(0), @@ -65,7 +66,6 @@ private: } // namespace asio } // namespace boost -#include <boost/system/error_code.hpp> #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_DETAIL_TASK_IO_SERVICE_OPERATION_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/thread.hpp b/3rdParty/Boost/src/boost/asio/detail/thread.hpp index 3e2e215..8848cd0 100644 --- a/3rdParty/Boost/src/boost/asio/detail/thread.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/thread.hpp @@ -1,6 +1,6 @@ // -// thread.hpp -// ~~~~~~~~~~ +// detail/thread.hpp +// ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,11 +15,7 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) # include <boost/asio/detail/null_thread.hpp> @@ -55,6 +51,4 @@ typedef posix_thread thread; } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_THREAD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/throw_error.hpp b/3rdParty/Boost/src/boost/asio/detail/throw_error.hpp index e9406a7..713a196 100644 --- a/3rdParty/Boost/src/boost/asio/detail/throw_error.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/throw_error.hpp @@ -1,6 +1,6 @@ // -// throw_error.hpp -// ~~~~~~~~~~~~~~~ +// detail/throw_error.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,26 +15,31 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/throw_exception.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/system/error_code.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace detail { +BOOST_ASIO_DECL void do_throw_error(const boost::system::error_code& err); + +BOOST_ASIO_DECL void do_throw_error(const boost::system::error_code& err, + const char* location); + inline void throw_error(const boost::system::error_code& err) { if (err) - { - boost::system::system_error e(err); - boost::throw_exception(e); - } + do_throw_error(err); +} + +inline void throw_error(const boost::system::error_code& err, + const char* location) +{ + if (err) + do_throw_error(err, location); } } // namespace detail @@ -43,4 +48,8 @@ inline void throw_error(const boost::system::error_code& err) #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/throw_error.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + #endif // BOOST_ASIO_DETAIL_THROW_ERROR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/timer_op.hpp b/3rdParty/Boost/src/boost/asio/detail/timer_op.hpp index 9973d89..8f82339 100644 --- a/3rdParty/Boost/src/boost/asio/detail/timer_op.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/timer_op.hpp @@ -1,6 +1,6 @@ // -// timer_op.hpp -// ~~~~~~~~~~~~ +// detail/timer_op.hpp +// ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,10 +15,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { diff --git a/3rdParty/Boost/src/boost/asio/detail/timer_queue.hpp b/3rdParty/Boost/src/boost/asio/detail/timer_queue.hpp index 164b342..09eb825 100644 --- a/3rdParty/Boost/src/boost/asio/detail/timer_queue.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/timer_queue.hpp @@ -1,6 +1,6 @@ // -// timer_queue.hpp -// ~~~~~~~~~~~~~~~ +// detail/timer_queue.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,21 +15,22 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <memory> #include <vector> #include <boost/config.hpp> #include <boost/limits.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> -#include <boost/asio/detail/hash_map.hpp> #include <boost/asio/detail/op_queue.hpp> #include <boost/asio/detail/timer_op.hpp> #include <boost/asio/detail/timer_queue_base.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/time_traits.hpp> + +#include <boost/asio/detail/push_options.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> +#include <boost/asio/detail/pop_options.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -46,6 +47,26 @@ public: // The duration type. typedef typename Time_Traits::duration_type duration_type; + // Per-timer data. + class per_timer_data + { + public: + per_timer_data() : next_(0), prev_(0) {} + + private: + friend class timer_queue; + + // The operations waiting on the timer. + op_queue<timer_op> op_queue_; + + // The index of the timer in the heap. + std::size_t heap_index_; + + // Pointers to adjacent timers in a linked list. + per_timer_data* next_; + per_timer_data* prev_; + }; + // Constructor. timer_queue() : timers_(), @@ -56,35 +77,45 @@ public: // Add a new timer to the queue. Returns true if this is the timer that is // earliest in the queue, in which case the reactor's event demultiplexing // function call may need to be interrupted and restarted. - bool enqueue_timer(const time_type& time, timer_op* op, void* token) + bool enqueue_timer(const time_type& time, per_timer_data& timer, timer_op* op) { - // Ensure that there is space for the timer in the heap. We reserve here so - // that the push_back below will not throw due to a reallocation failure. - heap_.reserve(heap_.size() + 1); - - // Insert the new timer into the hash. - typedef typename hash_map<void*, timer>::iterator iterator; - typedef typename hash_map<void*, timer>::value_type value_type; - std::pair<iterator, bool> result = - timers_.insert(value_type(token, timer())); - result.first->second.op_queue_.push(op); - if (result.second) + // Enqueue the timer object. + if (timer.prev_ == 0 && &timer != timers_) { - // Put the new timer at the correct position in the heap. - result.first->second.time_ = time; - result.first->second.heap_index_ = heap_.size(); - result.first->second.token_ = token; - heap_.push_back(&result.first->second); - up_heap(heap_.size() - 1); + if (this->is_positive_infinity(time)) + { + // No heap entry is required for timers that never expire. + timer.heap_index_ = (std::numeric_limits<std::size_t>::max)(); + } + else + { + // Put the new timer at the correct position in the heap. This is done + // first since push_back() can throw due to allocation failure. + timer.heap_index_ = heap_.size(); + heap_entry entry = { time, &timer }; + heap_.push_back(entry); + up_heap(heap_.size() - 1); + } + + // Insert the new timer into the linked list of active timers. + timer.next_ = timers_; + timer.prev_ = 0; + if (timers_) + timers_->prev_ = &timer; + timers_ = &timer; } - return (heap_[0] == &result.first->second); + // Enqueue the individual timer operation. + timer.op_queue_.push(op); + + // Interrupt reactor only if newly added timer is first to expire. + return timer.heap_index_ == 0 && timer.op_queue_.front() == op; } // Whether there are no timers in the queue. virtual bool empty() const { - return heap_.empty(); + return timers_ == 0; } // Get the time for the timer that is earliest in the queue. @@ -94,12 +125,14 @@ public: return max_duration; boost::posix_time::time_duration duration = Time_Traits::to_posix_duration( - Time_Traits::subtract(heap_[0]->time_, Time_Traits::now())); + Time_Traits::subtract(heap_[0].time_, Time_Traits::now())); if (duration > boost::posix_time::milliseconds(max_duration)) duration = boost::posix_time::milliseconds(max_duration); - else if (duration < boost::posix_time::milliseconds(0)) + else if (duration <= boost::posix_time::milliseconds(0)) duration = boost::posix_time::milliseconds(0); + else if (duration < boost::posix_time::milliseconds(1)) + duration = boost::posix_time::milliseconds(1); return duration.total_milliseconds(); } @@ -111,12 +144,14 @@ public: return max_duration; boost::posix_time::time_duration duration = Time_Traits::to_posix_duration( - Time_Traits::subtract(heap_[0]->time_, Time_Traits::now())); + Time_Traits::subtract(heap_[0].time_, Time_Traits::now())); if (duration > boost::posix_time::microseconds(max_duration)) duration = boost::posix_time::microseconds(max_duration); - else if (duration < boost::posix_time::microseconds(0)) + else if (duration <= boost::posix_time::microseconds(0)) duration = boost::posix_time::microseconds(0); + else if (duration < boost::posix_time::microseconds(1)) + duration = boost::posix_time::microseconds(1); return duration.total_microseconds(); } @@ -125,77 +160,54 @@ public: virtual void get_ready_timers(op_queue<operation>& ops) { const time_type now = Time_Traits::now(); - while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0]->time_)) + while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0].time_)) { - timer* t = heap_[0]; - ops.push(t->op_queue_); - remove_timer(t); + per_timer_data* timer = heap_[0].timer_; + ops.push(timer->op_queue_); + remove_timer(*timer); } } // Dequeue all timers. virtual void get_all_timers(op_queue<operation>& ops) { - typename hash_map<void*, timer>::iterator i = timers_.begin(); - typename hash_map<void*, timer>::iterator end = timers_.end(); - while (i != end) + while (timers_) { - ops.push(i->second.op_queue_); - typename hash_map<void*, timer>::iterator old_i = i++; - timers_.erase(old_i); + per_timer_data* timer = timers_; + timers_ = timers_->next_; + ops.push(timer->op_queue_); + timer->next_ = 0; + timer->prev_ = 0; } heap_.clear(); - timers_.clear(); } // Cancel and dequeue the timers with the given token. - std::size_t cancel_timer(void* timer_token, op_queue<operation>& ops) + std::size_t cancel_timer(per_timer_data& timer, op_queue<operation>& ops) { std::size_t num_cancelled = 0; - typedef typename hash_map<void*, timer>::iterator iterator; - iterator it = timers_.find(timer_token); - if (it != timers_.end()) + if (timer.prev_ != 0 || &timer == timers_) { - while (timer_op* op = it->second.op_queue_.front()) + while (timer_op* op = timer.op_queue_.front()) { op->ec_ = boost::asio::error::operation_aborted; - it->second.op_queue_.pop(); + timer.op_queue_.pop(); ops.push(op); ++num_cancelled; } - remove_timer(&it->second); + remove_timer(timer); } return num_cancelled; } private: - // Structure representing a single outstanding timer. - struct timer - { - timer() {} - timer(const timer&) {} - void operator=(const timer&) {} - - // The time when the timer should fire. - time_type time_; - - // The operations waiting on the timer. - op_queue<timer_op> op_queue_; - - // The index of the timer in the heap. - size_t heap_index_; - - // The token associated with the timer. - void* token_; - }; - // Move the item at the given index up the heap to its correct position. - void up_heap(size_t index) + void up_heap(std::size_t index) { - size_t parent = (index - 1) / 2; + std::size_t parent = (index - 1) / 2; while (index > 0 - && Time_Traits::less_than(heap_[index]->time_, heap_[parent]->time_)) + && Time_Traits::less_than(heap_[index].time_, heap_[parent].time_)) { swap_heap(index, parent); index = parent; @@ -204,16 +216,16 @@ private: } // Move the item at the given index down the heap to its correct position. - void down_heap(size_t index) + void down_heap(std::size_t index) { - size_t child = index * 2 + 1; + std::size_t child = index * 2 + 1; while (child < heap_.size()) { - size_t min_child = (child + 1 == heap_.size() + std::size_t min_child = (child + 1 == heap_.size() || Time_Traits::less_than( - heap_[child]->time_, heap_[child + 1]->time_)) + heap_[child].time_, heap_[child + 1].time_)) ? child : child + 1; - if (Time_Traits::less_than(heap_[index]->time_, heap_[min_child]->time_)) + if (Time_Traits::less_than(heap_[index].time_, heap_[min_child].time_)) break; swap_heap(index, min_child); index = min_child; @@ -222,20 +234,20 @@ private: } // Swap two entries in the heap. - void swap_heap(size_t index1, size_t index2) + void swap_heap(std::size_t index1, std::size_t index2) { - timer* tmp = heap_[index1]; + heap_entry tmp = heap_[index1]; heap_[index1] = heap_[index2]; heap_[index2] = tmp; - heap_[index1]->heap_index_ = index1; - heap_[index2]->heap_index_ = index2; + heap_[index1].timer_->heap_index_ = index1; + heap_[index2].timer_->heap_index_ = index2; } // Remove a timer from the heap and list of timers. - void remove_timer(timer* t) + void remove_timer(per_timer_data& timer) { // Remove the timer from the heap. - size_t index = t->heap_index_; + std::size_t index = timer.heap_index_; if (!heap_.empty() && index < heap_.size()) { if (index == heap_.size() - 1) @@ -246,29 +258,112 @@ private: { swap_heap(index, heap_.size() - 1); heap_.pop_back(); - size_t parent = (index - 1) / 2; + std::size_t parent = (index - 1) / 2; if (index > 0 && Time_Traits::less_than( - heap_[index]->time_, heap_[parent]->time_)) + heap_[index].time_, heap_[parent].time_)) up_heap(index); else down_heap(index); } } - // Remove the timer from the hash. - typedef typename hash_map<void*, timer>::iterator iterator; - iterator it = timers_.find(t->token_); - if (it != timers_.end()) - timers_.erase(it); + // Remove the timer from the linked list of active timers. + if (timers_ == &timer) + timers_ = timer.next_; + if (timer.prev_) + timer.prev_->next_ = timer.next_; + if (timer.next_) + timer.next_->prev_= timer.prev_; + timer.next_ = 0; + timer.prev_ = 0; + } + + // Determine if the specified absolute time is positive infinity. + template <typename Time_Type> + static bool is_positive_infinity(const Time_Type&) + { + return false; + } + + // Determine if the specified absolute time is positive infinity. + static bool is_positive_infinity(const boost::posix_time::ptime& time) + { + return time == boost::posix_time::pos_infin; } - // A hash of timer token to linked lists of timers. - hash_map<void*, timer> timers_; + // The head of a linked list of all active timers. + per_timer_data* timers_; + + struct heap_entry + { + // The time when the timer should fire. + time_type time_; + + // The associated timer with enqueued operations. + per_timer_data* timer_; + }; // The heap of timers, with the earliest timer at the front. - std::vector<timer*> heap_; + std::vector<heap_entry> heap_; }; +#if !defined(BOOST_ASIO_HEADER_ONLY) + +struct forwarding_posix_time_traits : time_traits<boost::posix_time::ptime> {}; + +// Template specialisation for the commonly used instantation. +template <> +class timer_queue<time_traits<boost::posix_time::ptime> > + : public timer_queue_base +{ +public: + // The time type. + typedef boost::posix_time::ptime time_type; + + // The duration type. + typedef boost::posix_time::time_duration duration_type; + + // Per-timer data. + typedef timer_queue<forwarding_posix_time_traits>::per_timer_data + per_timer_data; + + // Constructor. + BOOST_ASIO_DECL timer_queue(); + + // Destructor. + BOOST_ASIO_DECL virtual ~timer_queue(); + + // Add a new timer to the queue. Returns true if this is the timer that is + // earliest in the queue, in which case the reactor's event demultiplexing + // function call may need to be interrupted and restarted. + BOOST_ASIO_DECL bool enqueue_timer(const time_type& time, + per_timer_data& timer, timer_op* op); + + // Whether there are no timers in the queue. + BOOST_ASIO_DECL virtual bool empty() const; + + // Get the time for the timer that is earliest in the queue. + BOOST_ASIO_DECL virtual long wait_duration_msec(long max_duration) const; + + // Get the time for the timer that is earliest in the queue. + BOOST_ASIO_DECL virtual long wait_duration_usec(long max_duration) const; + + // Dequeue all timers not later than the current time. + BOOST_ASIO_DECL virtual void get_ready_timers(op_queue<operation>& ops); + + // Dequeue all timers. + BOOST_ASIO_DECL virtual void get_all_timers(op_queue<operation>& ops); + + // Cancel and dequeue the timers with the given token. + BOOST_ASIO_DECL std::size_t cancel_timer( + per_timer_data& timer, op_queue<operation>& ops); + +private: + timer_queue<forwarding_posix_time_traits> impl_; +}; + +#endif // !defined(BOOST_ASIO_HEADER_ONLY) + } // namespace detail } // namespace asio } // namespace boost diff --git a/3rdParty/Boost/src/boost/asio/detail/timer_queue_base.hpp b/3rdParty/Boost/src/boost/asio/detail/timer_queue_base.hpp index 074c2e1..0290308 100644 --- a/3rdParty/Boost/src/boost/asio/detail/timer_queue_base.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/timer_queue_base.hpp @@ -1,6 +1,6 @@ // -// timer_queue_base.hpp -// ~~~~~~~~~~~~~~~~~~~~ +// detail/timer_queue_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,12 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/op_queue.hpp> #include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { diff --git a/3rdParty/Boost/src/boost/asio/detail/timer_queue_fwd.hpp b/3rdParty/Boost/src/boost/asio/detail/timer_queue_fwd.hpp index b8bc5f2..0a62a44 100644 --- a/3rdParty/Boost/src/boost/asio/detail/timer_queue_fwd.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/timer_queue_fwd.hpp @@ -1,6 +1,6 @@ // -// timer_queue_fwd.hpp -// ~~~~~~~~~~~~~~~~~~~ +// detail/timer_queue_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,8 +15,6 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - namespace boost { namespace asio { namespace detail { @@ -28,6 +26,4 @@ class timer_queue; } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_TIMER_QUEUE_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/timer_queue_set.hpp b/3rdParty/Boost/src/boost/asio/detail/timer_queue_set.hpp index a92a6b9..c2cea66 100644 --- a/3rdParty/Boost/src/boost/asio/detail/timer_queue_set.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/timer_queue_set.hpp @@ -1,6 +1,6 @@ // -// timer_queue_set.hpp -// ~~~~~~~~~~~~~~~~~~~ +// detail/timer_queue_set.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,10 +15,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/timer_queue_base.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -27,82 +28,28 @@ class timer_queue_set { public: // Constructor. - timer_queue_set() - : first_(0) - { - } + BOOST_ASIO_DECL timer_queue_set(); // Add a timer queue to the set. - void insert(timer_queue_base* q) - { - q->next_ = first_; - first_ = q; - } + BOOST_ASIO_DECL void insert(timer_queue_base* q); // Remove a timer queue from the set. - void erase(timer_queue_base* q) - { - if (first_) - { - if (q == first_) - { - first_ = q->next_; - q->next_ = 0; - return; - } - - for (timer_queue_base* p = first_; p->next_; p = p->next_) - { - if (p->next_ == q) - { - p->next_ = q->next_; - q->next_ = 0; - return; - } - } - } - } + BOOST_ASIO_DECL void erase(timer_queue_base* q); // Determine whether all queues are empty. - bool all_empty() const - { - for (timer_queue_base* p = first_; p; p = p->next_) - if (!p->empty()) - return false; - return true; - } + BOOST_ASIO_DECL bool all_empty() const; // Get the wait duration in milliseconds. - long wait_duration_msec(long max_duration) const - { - long min_duration = max_duration; - for (timer_queue_base* p = first_; p; p = p->next_) - min_duration = p->wait_duration_msec(min_duration); - return min_duration; - } + BOOST_ASIO_DECL long wait_duration_msec(long max_duration) const; // Get the wait duration in microseconds. - long wait_duration_usec(long max_duration) const - { - long min_duration = max_duration; - for (timer_queue_base* p = first_; p; p = p->next_) - min_duration = p->wait_duration_usec(min_duration); - return min_duration; - } + BOOST_ASIO_DECL long wait_duration_usec(long max_duration) const; // Dequeue all ready timers. - void get_ready_timers(op_queue<operation>& ops) - { - for (timer_queue_base* p = first_; p; p = p->next_) - p->get_ready_timers(ops); - } + BOOST_ASIO_DECL void get_ready_timers(op_queue<operation>& ops); // Dequeue all timers. - void get_all_timers(op_queue<operation>& ops) - { - for (timer_queue_base* p = first_; p; p = p->next_) - p->get_all_timers(ops); - } + BOOST_ASIO_DECL void get_all_timers(op_queue<operation>& ops); private: timer_queue_base* first_; @@ -114,4 +61,8 @@ private: #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/timer_queue_set.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + #endif // BOOST_ASIO_DETAIL_TIMER_QUEUE_SET_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/timer_scheduler.hpp b/3rdParty/Boost/src/boost/asio/detail/timer_scheduler.hpp index bc837ee..ec80f40 100644 --- a/3rdParty/Boost/src/boost/asio/detail/timer_scheduler.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/timer_scheduler.hpp @@ -1,6 +1,6 @@ // -// timer_scheduler.hpp -// ~~~~~~~~~~~~~~~~~~~ +// detail/timer_scheduler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,8 +15,7 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/timer_scheduler_fwd.hpp> #if defined(BOOST_ASIO_HAS_IOCP) @@ -31,6 +30,4 @@ # include <boost/asio/detail/select_reactor.hpp> #endif -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_TIMER_SCHEDULER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/timer_scheduler_fwd.hpp b/3rdParty/Boost/src/boost/asio/detail/timer_scheduler_fwd.hpp index 9d0b1e6..77d6c99 100644 --- a/3rdParty/Boost/src/boost/asio/detail/timer_scheduler_fwd.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/timer_scheduler_fwd.hpp @@ -1,6 +1,6 @@ // -// timer_scheduler_fwd.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~ +// detail/timer_scheduler_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,13 +15,19 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/dev_poll_reactor_fwd.hpp> -#include <boost/asio/detail/epoll_reactor_fwd.hpp> -#include <boost/asio/detail/kqueue_reactor_fwd.hpp> -#include <boost/asio/detail/select_reactor_fwd.hpp> -#include <boost/asio/detail/win_iocp_io_service_fwd.hpp> +#if defined(BOOST_ASIO_HAS_IOCP) +# include <boost/asio/detail/win_iocp_io_service_fwd.hpp> +#elif defined(BOOST_ASIO_HAS_EPOLL) +# include <boost/asio/detail/epoll_reactor_fwd.hpp> +#elif defined(BOOST_ASIO_HAS_KQUEUE) +# include <boost/asio/detail/kqueue_reactor_fwd.hpp> +#elif defined(BOOST_ASIO_HAS_DEV_POLL) +# include <boost/asio/detail/dev_poll_reactor_fwd.hpp> +#else +# include <boost/asio/detail/select_reactor_fwd.hpp> +#endif namespace boost { namespace asio { @@ -36,13 +42,11 @@ typedef kqueue_reactor timer_scheduler; #elif defined(BOOST_ASIO_HAS_DEV_POLL) typedef dev_poll_reactor timer_scheduler; #else -typedef select_reactor<false> timer_scheduler; +typedef select_reactor timer_scheduler; #endif } // namespace detail } // namespace asio } // namespace boost -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_DETAIL_TIMER_SCHEDULER_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/tss_ptr.hpp b/3rdParty/Boost/src/boost/asio/detail/tss_ptr.hpp index 7ccfcf3..8edf15b 100644 --- a/3rdParty/Boost/src/boost/asio/detail/tss_ptr.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/tss_ptr.hpp @@ -1,6 +1,6 @@ // -// tss_ptr.hpp -// ~~~~~~~~~~~ +// detail/tss_ptr.hpp +// ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,11 +15,7 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS) # include <boost/asio/detail/null_tss_ptr.hpp> @@ -31,6 +27,8 @@ # error Only Windows and POSIX are supported! #endif +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { diff --git a/3rdParty/Boost/src/boost/asio/detail/wait_handler.hpp b/3rdParty/Boost/src/boost/asio/detail/wait_handler.hpp new file mode 100644 index 0000000..e451f19 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/wait_handler.hpp @@ -0,0 +1,78 @@ +// +// detail/wait_handler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_WAIT_HANDLER_HPP +#define BOOST_ASIO_DETAIL_WAIT_HANDLER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/timer_op.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Handler> +class wait_handler : public timer_op +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(wait_handler); + + wait_handler(Handler h) + : timer_op(&wait_handler::do_complete), + handler_(h) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + wait_handler* h(static_cast<wait_handler*>(base)); + ptr p = { boost::addressof(h->handler_), h, h }; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder1<Handler, boost::system::error_code> + handler(h->handler_, h->ec_); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_DETAIL_WAIT_HANDLER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/weak_ptr.hpp b/3rdParty/Boost/src/boost/asio/detail/weak_ptr.hpp new file mode 100644 index 0000000..9a14297 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/weak_ptr.hpp @@ -0,0 +1,41 @@ +// +// detail/weak_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_WEAK_PTR_HPP +#define BOOST_ASIO_DETAIL_WEAK_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/version.hpp> + +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# include <memory> +#else +# include <boost/weak_ptr.hpp> +#endif + +namespace boost { +namespace asio { +namespace detail { + +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +using std::weak_ptr; +#else +using boost::weak_ptr; +#endif + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // BOOST_ASIO_DETAIL_WEAK_PTR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_event.hpp b/3rdParty/Boost/src/boost/asio/detail/win_event.hpp index bddf09d..736ebb2 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_event.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_event.hpp @@ -1,6 +1,6 @@ // -// win_event.hpp -// ~~~~~~~~~~~~~ +// detail/win_event.hpp +// ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,23 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_WINDOWS) -#include <boost/asio/error.hpp> +#include <boost/assert.hpp> #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/push_options.hpp> -#include <boost/assert.hpp> -#include <boost/throw_exception.hpp> -#include <boost/asio/detail/pop_options.hpp> namespace boost { namespace asio { @@ -42,19 +34,7 @@ class win_event { public: // Constructor. - win_event() - : event_(::CreateEvent(0, true, false, 0)) - { - if (!event_) - { - DWORD last_error = ::GetLastError(); - boost::system::system_error e( - boost::system::error_code(last_error, - boost::asio::error::get_system_category()), - "event"); - boost::throw_exception(e); - } - } + BOOST_ASIO_DECL win_event(); // Destructor. ~win_event() @@ -107,8 +87,12 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_WINDOWS) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/win_event.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_WINDOWS) + #endif // BOOST_ASIO_DETAIL_WIN_EVENT_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_fd_set_adapter.hpp b/3rdParty/Boost/src/boost/asio/detail/win_fd_set_adapter.hpp index 11c1e15..4a5d7fa 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_fd_set_adapter.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_fd_set_adapter.hpp @@ -1,6 +1,6 @@ // -// win_fd_set_adapter.hpp -// ~~~~~~~~~~~~~~~~~~~~~~ +// detail/win_fd_set_adapter.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,11 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) #include <boost/asio/detail/socket_types.hpp> -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -83,8 +85,8 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - #include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + #endif // BOOST_ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_fenced_block.hpp b/3rdParty/Boost/src/boost/asio/detail/win_fenced_block.hpp index ff4a21c..928395e 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_fenced_block.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_fenced_block.hpp @@ -1,6 +1,6 @@ // -// win_fenced_block.hpp -// ~~~~~~~~~~~~~~~~~~~~ +// detail/win_fenced_block.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_WINDOWS) && !defined(UNDER_CE) #include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -36,7 +34,10 @@ public: // Constructor. win_fenced_block() { -#if defined(BOOST_MSVC) && (BOOST_MSVC < 1400) +#if defined(__BORLANDC__) + LONG barrier = 0; + ::InterlockedExchange(&barrier, 1); +#elif defined(BOOST_MSVC) && ((BOOST_MSVC < 1400) || !defined(MemoryBarrier)) # if defined(_M_IX86) # pragma warning(push) # pragma warning(disable:4793) @@ -44,15 +45,18 @@ public: __asm { xchg barrier, eax } # pragma warning(pop) # endif // defined(_M_IX86) -#else // defined(BOOST_MSVC) && (BOOST_MSVC < 1400) +#else MemoryBarrier(); -#endif // defined(BOOST_MSVC) && (BOOST_MSVC < 1400) +#endif } // Destructor. ~win_fenced_block() { -#if defined(BOOST_MSVC) && (BOOST_MSVC < 1400) +#if defined(__BORLANDC__) + LONG barrier = 0; + ::InterlockedExchange(&barrier, 1); +#elif defined(BOOST_MSVC) && ((BOOST_MSVC < 1400) || !defined(MemoryBarrier)) # if defined(_M_IX86) # pragma warning(push) # pragma warning(disable:4793) @@ -60,9 +64,9 @@ public: __asm { xchg barrier, eax } # pragma warning(pop) # endif // defined(_M_IX86) -#else // defined(BOOST_MSVC) && (BOOST_MSVC < 1400) +#else MemoryBarrier(); -#endif // defined(BOOST_MSVC) && (BOOST_MSVC < 1400) +#endif } }; @@ -70,8 +74,8 @@ public: } // namespace asio } // namespace boost -#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE) - #include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE) + #endif // BOOST_ASIO_DETAIL_WIN_FENCED_BLOCK_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_handle_read_op.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_handle_read_op.hpp new file mode 100644 index 0000000..f1a9b1f --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_handle_read_op.hpp @@ -0,0 +1,103 @@ +// +// detail/win_iocp_handle_read_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_IOCP_HANDLE_READ_OP_HPP +#define BOOST_ASIO_DETAIL_WIN_IOCP_HANDLE_READ_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/asio/error.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/operation.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename MutableBufferSequence, typename Handler> +class win_iocp_handle_read_op : public operation +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_handle_read_op); + + win_iocp_handle_read_op(const MutableBufferSequence& buffers, Handler handler) + : operation(&win_iocp_handle_read_op::do_complete), + buffers_(buffers), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + win_iocp_handle_read_op* o(static_cast<win_iocp_handle_read_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + if (owner) + { + // Check whether buffers are still valid. + buffer_sequence_adapter<boost::asio::mutable_buffer, + MutableBufferSequence>::validate(o->buffers_); + } +#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_HANDLE_EOF) + ec = boost::asio::error::eof; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, ec, bytes_transferred); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + MutableBufferSequence buffers_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_WIN_IOCP_HANDLE_READ_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_handle_service.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_handle_service.hpp index a6d6599..291a06f 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_iocp_handle_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_handle_service.hpp @@ -1,6 +1,6 @@ // -// win_iocp_handle_service.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/win_iocp_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) @@ -16,26 +16,23 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/win_iocp_io_service_fwd.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_IOCP) -#include <boost/asio/detail/push_options.hpp> #include <boost/cstdint.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> -#include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/buffer_sequence_adapter.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> -#include <boost/asio/detail/handler_invoke_helpers.hpp> #include <boost/asio/detail/mutex.hpp> #include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/win_iocp_handle_read_op.hpp> +#include <boost/asio/detail/win_iocp_handle_write_op.hpp> #include <boost/asio/detail/win_iocp_io_service.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -77,75 +74,20 @@ public: implementation_type* prev_; }; - win_iocp_handle_service(boost::asio::io_service& io_service) - : iocp_service_(boost::asio::use_service<win_iocp_io_service>(io_service)), - mutex_(), - impl_list_(0) - { - } + BOOST_ASIO_DECL win_iocp_handle_service(boost::asio::io_service& io_service); // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - // Close all implementations, causing all operations to complete. - boost::asio::detail::mutex::scoped_lock lock(mutex_); - implementation_type* impl = impl_list_; - while (impl) - { - close_for_destruction(*impl); - impl = impl->next_; - } - } + BOOST_ASIO_DECL void shutdown_service(); // Construct a new handle implementation. - void construct(implementation_type& impl) - { - impl.handle_ = INVALID_HANDLE_VALUE; - impl.safe_cancellation_thread_id_ = 0; - - // Insert implementation into linked list of all implementations. - boost::asio::detail::mutex::scoped_lock lock(mutex_); - impl.next_ = impl_list_; - impl.prev_ = 0; - if (impl_list_) - impl_list_->prev_ = &impl; - impl_list_ = &impl; - } + BOOST_ASIO_DECL void construct(implementation_type& impl); // Destroy a handle implementation. - void destroy(implementation_type& impl) - { - close_for_destruction(impl); - - // Remove implementation from linked list of all implementations. - boost::asio::detail::mutex::scoped_lock lock(mutex_); - if (impl_list_ == &impl) - impl_list_ = impl.next_; - if (impl.prev_) - impl.prev_->next_ = impl.next_; - if (impl.next_) - impl.next_->prev_= impl.prev_; - impl.next_ = 0; - impl.prev_ = 0; - } + BOOST_ASIO_DECL void destroy(implementation_type& impl); // Assign a native handle to a handle implementation. - boost::system::error_code assign(implementation_type& impl, - const native_type& native_handle, boost::system::error_code& ec) - { - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (iocp_service_.register_handle(native_handle, ec)) - return ec; - - impl.handle_ = native_handle; - ec = boost::system::error_code(); - return ec; - } + BOOST_ASIO_DECL boost::system::error_code assign(implementation_type& impl, + const native_type& native_handle, boost::system::error_code& ec); // Determine whether the handle is open. bool is_open(const implementation_type& impl) const @@ -154,26 +96,8 @@ public: } // Destroy a handle implementation. - boost::system::error_code close(implementation_type& impl, - boost::system::error_code& ec) - { - if (is_open(impl)) - { - if (!::CloseHandle(impl.handle_)) - { - DWORD last_error = ::GetLastError(); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return ec; - } - - impl.handle_ = INVALID_HANDLE_VALUE; - impl.safe_cancellation_thread_id_ = 0; - } - - ec = boost::system::error_code(); - return ec; - } + BOOST_ASIO_DECL boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec); // Get the native handle representation. native_type native(const implementation_type& impl) const @@ -182,106 +106,8 @@ public: } // Cancel all operations associated with the handle. - boost::system::error_code cancel(implementation_type& impl, - boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - } - else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress( - ::GetModuleHandleA("KERNEL32"), "CancelIoEx")) - { - // The version of Windows supports cancellation from any thread. - typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED); - cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr; - if (!cancel_io_ex(impl.handle_, 0)) - { - DWORD last_error = ::GetLastError(); - if (last_error == ERROR_NOT_FOUND) - { - // ERROR_NOT_FOUND means that there were no operations to be - // cancelled. We swallow this error to match the behaviour on other - // platforms. - ec = boost::system::error_code(); - } - else - { - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - } - } - else - { - ec = boost::system::error_code(); - } - } - else if (impl.safe_cancellation_thread_id_ == 0) - { - // No operations have been started, so there's nothing to cancel. - ec = boost::system::error_code(); - } - else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId()) - { - // Asynchronous operations have been started from the current thread only, - // so it is safe to try to cancel them using CancelIo. - if (!::CancelIo(impl.handle_)) - { - DWORD last_error = ::GetLastError(); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - } - else - { - ec = boost::system::error_code(); - } - } - else - { - // Asynchronous operations have been started from more than one thread, - // so cancellation is not safe. - ec = boost::asio::error::operation_not_supported; - } - - return ec; - } - - class overlapped_wrapper - : public OVERLAPPED - { - public: - explicit overlapped_wrapper(boost::system::error_code& ec) - { - Internal = 0; - InternalHigh = 0; - Offset = 0; - OffsetHigh = 0; - - // Create a non-signalled manual-reset event, for GetOverlappedResult. - hEvent = ::CreateEvent(0, TRUE, FALSE, 0); - if (hEvent) - { - // As documented in GetQueuedCompletionStatus, setting the low order - // bit of this event prevents our synchronous writes from being treated - // as completion port events. - *reinterpret_cast<DWORD_PTR*>(&hEvent) |= 1; - } - else - { - DWORD last_error = ::GetLastError(); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - } - } - - ~overlapped_wrapper() - { - if (hEvent) - { - ::CloseHandle(hEvent); - } - } - }; + BOOST_ASIO_DECL boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec); // Write the given data. Returns the number of bytes written. template <typename ConstBufferSequence> @@ -297,109 +123,13 @@ public: size_t write_some_at(implementation_type& impl, boost::uint64_t offset, const ConstBufferSequence& buffers, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - boost::asio::const_buffer buffer = buffer_sequence_adapter<boost::asio::const_buffer, ConstBufferSequence>::first(buffers); - // A request to write 0 bytes on a handle is a no-op. - if (boost::asio::buffer_size(buffer) == 0) - { - ec = boost::system::error_code(); - return 0; - } - - overlapped_wrapper overlapped(ec); - if (ec) - { - return 0; - } - - // Write the data. - overlapped.Offset = offset & 0xFFFFFFFF; - overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; - BOOL ok = ::WriteFile(impl.handle_, - boost::asio::buffer_cast<LPCVOID>(buffer), - static_cast<DWORD>(boost::asio::buffer_size(buffer)), 0, &overlapped); - if (!ok) - { - DWORD last_error = ::GetLastError(); - if (last_error != ERROR_IO_PENDING) - { - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return 0; - } - } - - // Wait for the operation to complete. - DWORD bytes_transferred = 0; - ok = ::GetOverlappedResult(impl.handle_, - &overlapped, &bytes_transferred, TRUE); - if (!ok) - { - DWORD last_error = ::GetLastError(); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return 0; - } - - ec = boost::system::error_code(); - return bytes_transferred; + return do_write(impl, offset, buffer, ec); } - template <typename ConstBufferSequence, typename Handler> - class write_op : public operation - { - public: - write_op(const ConstBufferSequence& buffers, Handler handler) - : operation(&write_op::do_complete), - buffers_(buffers), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code ec, std::size_t bytes_transferred) - { - // Take ownership of the operation object. - write_op* o(static_cast<write_op*>(base)); - typedef handler_alloc_traits<Handler, write_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { -#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) - // Check whether buffers are still valid. - buffer_sequence_adapter<boost::asio::const_buffer, - ConstBufferSequence>::validate(o->buffers_); -#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) - - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, ec, bytes_transferred); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - ConstBufferSequence buffers_; - Handler handler_; - }; - // Start an asynchronous write. The data being written must be valid for the // lifetime of the asynchronous operation. template <typename ConstBufferSequence, typename Handler> @@ -416,15 +146,16 @@ public: const ConstBufferSequence& buffers, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef write_op<ConstBufferSequence, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, buffers, handler); + typedef win_iocp_handle_write_op<ConstBufferSequence, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(buffers, handler); start_write_op(impl, offset, buffer_sequence_adapter<boost::asio::const_buffer, - ConstBufferSequence>::first(buffers), ptr.get()); - ptr.release(); + ConstBufferSequence>::first(buffers), p.p); + p.v = p.p = 0; } // Read some data. Returns the number of bytes received. @@ -440,129 +171,13 @@ public: size_t read_some_at(implementation_type& impl, boost::uint64_t offset, const MutableBufferSequence& buffers, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - boost::asio::mutable_buffer buffer = buffer_sequence_adapter<boost::asio::mutable_buffer, MutableBufferSequence>::first(buffers); - // A request to read 0 bytes on a stream handle is a no-op. - if (boost::asio::buffer_size(buffer) == 0) - { - ec = boost::system::error_code(); - return 0; - } - - overlapped_wrapper overlapped(ec); - if (ec) - { - return 0; - } - - // Read some data. - overlapped.Offset = offset & 0xFFFFFFFF; - overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; - BOOL ok = ::ReadFile(impl.handle_, - boost::asio::buffer_cast<LPVOID>(buffer), - static_cast<DWORD>(boost::asio::buffer_size(buffer)), 0, &overlapped); - if (!ok) - { - DWORD last_error = ::GetLastError(); - if (last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA) - { - if (last_error == ERROR_HANDLE_EOF) - { - ec = boost::asio::error::eof; - } - else - { - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - } - return 0; - } - } - - // Wait for the operation to complete. - DWORD bytes_transferred = 0; - ok = ::GetOverlappedResult(impl.handle_, - &overlapped, &bytes_transferred, TRUE); - if (!ok) - { - DWORD last_error = ::GetLastError(); - if (last_error == ERROR_HANDLE_EOF) - { - ec = boost::asio::error::eof; - } - else - { - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - } - return 0; - } - - ec = boost::system::error_code(); - return bytes_transferred; + return do_read(impl, offset, buffer, ec); } - template <typename MutableBufferSequence, typename Handler> - class read_op : public operation - { - public: - read_op(const MutableBufferSequence& buffers, Handler handler) - : operation(&read_op::do_complete), - buffers_(buffers), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code ec, std::size_t bytes_transferred) - { - // Take ownership of the operation object. - read_op* o(static_cast<read_op*>(base)); - typedef handler_alloc_traits<Handler, read_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { -#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) - // Check whether buffers are still valid. - buffer_sequence_adapter<boost::asio::mutable_buffer, - MutableBufferSequence>::validate(o->buffers_); -#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) - - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_HANDLE_EOF) - { - ec = boost::asio::error::eof; - } - - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, ec, bytes_transferred); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - MutableBufferSequence buffers_; - Handler handler_; - }; - // Start an asynchronous read. The buffer for the data being received must be // valid for the lifetime of the asynchronous operation. template <typename MutableBufferSequence, typename Handler> @@ -580,15 +195,16 @@ public: const MutableBufferSequence& buffers, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef read_op<MutableBufferSequence, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, buffers, handler); + typedef win_iocp_handle_read_op<MutableBufferSequence, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(buffers, handler); start_read_op(impl, offset, buffer_sequence_adapter<boost::asio::mutable_buffer, - MutableBufferSequence>::first(buffers), ptr.get()); - ptr.release(); + MutableBufferSequence>::first(buffers), p.p); + p.v = p.p = 0; } private: @@ -614,113 +230,42 @@ private: void async_read_some_at(implementation_type& impl, boost::uint64_t offset, const null_buffers& buffers, Handler handler); + // Helper class for waiting for synchronous operations to complete. + class overlapped_wrapper; + + // Helper function to perform a synchronous write operation. + BOOST_ASIO_DECL size_t do_write(implementation_type& impl, + boost::uint64_t offset, const boost::asio::const_buffer& buffer, + boost::system::error_code& ec); + // Helper function to start a write operation. - void start_write_op(implementation_type& impl, boost::uint64_t offset, - const boost::asio::const_buffer& buffer, operation* op) - { - update_cancellation_thread_id(impl); - iocp_service_.work_started(); + BOOST_ASIO_DECL void start_write_op(implementation_type& impl, + boost::uint64_t offset, const boost::asio::const_buffer& buffer, + operation* op); - if (!is_open(impl)) - { - iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); - } - else if (boost::asio::buffer_size(buffer) == 0) - { - // A request to write 0 bytes on a handle is a no-op. - iocp_service_.on_completion(op); - } - else - { - DWORD bytes_transferred = 0; - op->Offset = offset & 0xFFFFFFFF; - op->OffsetHigh = (offset >> 32) & 0xFFFFFFFF; - BOOL ok = ::WriteFile(impl.handle_, - boost::asio::buffer_cast<LPCVOID>(buffer), - static_cast<DWORD>(boost::asio::buffer_size(buffer)), - &bytes_transferred, op); - DWORD last_error = ::GetLastError(); - if (!ok && last_error != ERROR_IO_PENDING - && last_error != ERROR_MORE_DATA) - { - iocp_service_.on_completion(op, last_error, bytes_transferred); - } - else - { - iocp_service_.on_pending(op); - } - } - } + // Helper function to perform a synchronous write operation. + BOOST_ASIO_DECL size_t do_read(implementation_type& impl, + boost::uint64_t offset, const boost::asio::mutable_buffer& buffer, + boost::system::error_code& ec); // Helper function to start a read operation. - void start_read_op(implementation_type& impl, boost::uint64_t offset, - const boost::asio::mutable_buffer& buffer, operation* op) - { - update_cancellation_thread_id(impl); - iocp_service_.work_started(); - - if (!is_open(impl)) - { - iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); - } - else if (boost::asio::buffer_size(buffer) == 0) - { - // A request to read 0 bytes on a handle is a no-op. - iocp_service_.on_completion(op); - } - else - { - DWORD bytes_transferred = 0; - op->Offset = offset & 0xFFFFFFFF; - op->OffsetHigh = (offset >> 32) & 0xFFFFFFFF; - BOOL ok = ::ReadFile(impl.handle_, - boost::asio::buffer_cast<LPVOID>(buffer), - static_cast<DWORD>(boost::asio::buffer_size(buffer)), - &bytes_transferred, op); - DWORD last_error = ::GetLastError(); - if (!ok && last_error != ERROR_IO_PENDING - && last_error != ERROR_MORE_DATA) - { - iocp_service_.on_completion(op, last_error, bytes_transferred); - } - else - { - iocp_service_.on_pending(op); - } - } - } + BOOST_ASIO_DECL void start_read_op(implementation_type& impl, + boost::uint64_t offset, const boost::asio::mutable_buffer& buffer, + operation* op); // Update the ID of the thread from which cancellation is safe. - void update_cancellation_thread_id(implementation_type& impl) - { -#if defined(BOOST_ASIO_ENABLE_CANCELIO) - if (impl.safe_cancellation_thread_id_ == 0) - impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); - else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) - impl.safe_cancellation_thread_id_ = ~DWORD(0); -#else // defined(BOOST_ASIO_ENABLE_CANCELIO) - (void)impl; -#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) - } + BOOST_ASIO_DECL void update_cancellation_thread_id(implementation_type& impl); // Helper function to close a handle when the associated object is being // destroyed. - void close_for_destruction(implementation_type& impl) - { - if (is_open(impl)) - { - ::CloseHandle(impl.handle_); - impl.handle_ = INVALID_HANDLE_VALUE; - impl.safe_cancellation_thread_id_ = 0; - } - } + BOOST_ASIO_DECL void close_for_destruction(implementation_type& impl); // The IOCP service used for running asynchronous operations and dispatching // handlers. win_iocp_io_service& iocp_service_; // Mutex to protect access to the linked list of implementations. - boost::asio::detail::mutex mutex_; + mutex mutex_; // The head of a linked list of all implementations. implementation_type* impl_list_; @@ -730,8 +275,12 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_ASIO_HAS_IOCP) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/win_iocp_handle_service.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_ASIO_HAS_IOCP) + #endif // BOOST_ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_handle_write_op.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_handle_write_op.hpp new file mode 100644 index 0000000..971f174 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_handle_write_op.hpp @@ -0,0 +1,99 @@ +// +// detail/win_iocp_handle_write_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_IOCP_HANDLE_WRITE_OP_HPP +#define BOOST_ASIO_DETAIL_WIN_IOCP_HANDLE_WRITE_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/asio/error.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/operation.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename ConstBufferSequence, typename Handler> +class win_iocp_handle_write_op : public operation +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_handle_write_op); + + win_iocp_handle_write_op(const ConstBufferSequence& buffers, Handler handler) + : operation(&win_iocp_handle_write_op::do_complete), + buffers_(buffers), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + win_iocp_handle_write_op* o(static_cast<win_iocp_handle_write_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + if (owner) + { + // Check whether buffers are still valid. + buffer_sequence_adapter<boost::asio::const_buffer, + ConstBufferSequence>::validate(o->buffers_); + } +#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, ec, bytes_transferred); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + ConstBufferSequence buffers_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_WIN_IOCP_HANDLE_WRITE_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_io_service.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_io_service.hpp index 83b16bf..235424e 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_iocp_io_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_io_service.hpp @@ -1,6 +1,6 @@ // -// win_iocp_io_service.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~ +// detail/win_iocp_io_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,33 +15,24 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/win_iocp_io_service_fwd.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_IOCP) -#include <boost/asio/detail/push_options.hpp> -#include <boost/limits.hpp> -#include <boost/throw_exception.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> - +#include <boost/scoped_ptr.hpp> #include <boost/asio/io_service.hpp> -#include <boost/asio/detail/call_stack.hpp> -#include <boost/asio/detail/completion_handler.hpp> -#include <boost/asio/detail/fenced_block.hpp> -#include <boost/asio/detail/handler_alloc_helpers.hpp> -#include <boost/asio/detail/handler_invoke_helpers.hpp> #include <boost/asio/detail/mutex.hpp> #include <boost/asio/detail/op_queue.hpp> -#include <boost/asio/detail/service_base.hpp> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/timer_op.hpp> #include <boost/asio/detail/timer_queue_base.hpp> #include <boost/asio/detail/timer_queue_fwd.hpp> #include <boost/asio/detail/timer_queue_set.hpp> +#include <boost/asio/detail/win_iocp_io_service_fwd.hpp> #include <boost/asio/detail/win_iocp_operation.hpp> +#include <boost/asio/detail/thread.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -53,69 +44,13 @@ class win_iocp_io_service : public boost::asio::detail::service_base<win_iocp_io_service> { public: - typedef win_iocp_operation operation; - // Constructor. - win_iocp_io_service(boost::asio::io_service& io_service) - : boost::asio::detail::service_base<win_iocp_io_service>(io_service), - iocp_(), - outstanding_work_(0), - stopped_(0), - shutdown_(0), - timer_thread_(0), - timer_interrupt_issued_(false) - { - } + BOOST_ASIO_DECL win_iocp_io_service(boost::asio::io_service& io_service); - void init(size_t concurrency_hint) - { - iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, - static_cast<DWORD>((std::min<size_t>)(concurrency_hint, DWORD(~0)))); - if (!iocp_.handle) - { - DWORD last_error = ::GetLastError(); - boost::system::system_error e( - boost::system::error_code(last_error, - boost::asio::error::get_system_category()), - "iocp"); - boost::throw_exception(e); - } - } + BOOST_ASIO_DECL void init(size_t concurrency_hint); // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - ::InterlockedExchange(&shutdown_, 1); - - while (::InterlockedExchangeAdd(&outstanding_work_, 0) > 0) - { - op_queue<operation> ops; - timer_queues_.get_all_timers(ops); - ops.push(completed_ops_); - if (!ops.empty()) - { - while (operation* op = ops.front()) - { - ops.pop(); - ::InterlockedDecrement(&outstanding_work_); - op->destroy(); - } - } - else - { - DWORD bytes_transferred = 0; - dword_ptr_t completion_key = 0; - LPOVERLAPPED overlapped = 0; - ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, - &completion_key, &overlapped, max_timeout); - if (overlapped) - { - ::InterlockedDecrement(&outstanding_work_); - static_cast<operation*>(overlapped)->destroy(); - } - } - } - } + BOOST_ASIO_DECL void shutdown_service(); // Initialise the task. Nothing to do here. void init_task() @@ -123,106 +58,23 @@ public: } // Register a handle with the IO completion port. - boost::system::error_code register_handle( - HANDLE handle, boost::system::error_code& ec) - { - if (::CreateIoCompletionPort(handle, iocp_.handle, 0, 0) == 0) - { - DWORD last_error = ::GetLastError(); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - } - else - { - ec = boost::system::error_code(); - } - return ec; - } + BOOST_ASIO_DECL boost::system::error_code register_handle( + HANDLE handle, boost::system::error_code& ec); // Run the event loop until stopped or no more work. - size_t run(boost::system::error_code& ec) - { - if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) - { - stop(); - ec = boost::system::error_code(); - return 0; - } - - call_stack<win_iocp_io_service>::context ctx(this); - - size_t n = 0; - while (do_one(true, ec)) - if (n != (std::numeric_limits<size_t>::max)()) - ++n; - return n; - } + BOOST_ASIO_DECL size_t run(boost::system::error_code& ec); // Run until stopped or one operation is performed. - size_t run_one(boost::system::error_code& ec) - { - if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) - { - stop(); - ec = boost::system::error_code(); - return 0; - } - - call_stack<win_iocp_io_service>::context ctx(this); - - return do_one(true, ec); - } + BOOST_ASIO_DECL size_t run_one(boost::system::error_code& ec); // Poll for operations without blocking. - size_t poll(boost::system::error_code& ec) - { - if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) - { - stop(); - ec = boost::system::error_code(); - return 0; - } - - call_stack<win_iocp_io_service>::context ctx(this); - - size_t n = 0; - while (do_one(false, ec)) - if (n != (std::numeric_limits<size_t>::max)()) - ++n; - return n; - } + BOOST_ASIO_DECL size_t poll(boost::system::error_code& ec); // Poll for one operation without blocking. - size_t poll_one(boost::system::error_code& ec) - { - if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) - { - stop(); - ec = boost::system::error_code(); - return 0; - } - - call_stack<win_iocp_io_service>::context ctx(this); - - return do_one(false, ec); - } + BOOST_ASIO_DECL size_t poll_one(boost::system::error_code& ec); // Stop the event processing loop. - void stop() - { - if (::InterlockedExchange(&stopped_, 1) == 0) - { - if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) - { - DWORD last_error = ::GetLastError(); - boost::system::system_error e( - boost::system::error_code(last_error, - boost::asio::error::get_system_category()), - "pqcs"); - boost::throw_exception(e); - } - } - } + BOOST_ASIO_DECL void stop(); // Reset in preparation for a subsequent run invocation. void reset() @@ -245,34 +97,15 @@ public: // Request invocation of the given handler. template <typename Handler> - void dispatch(Handler handler) - { - if (call_stack<win_iocp_io_service>::contains(this)) - { - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - else - post(handler); - } + void dispatch(Handler handler); // Request invocation of the given handler and return immediately. template <typename Handler> - void post(Handler handler) - { - // Allocate and construct an operation to wrap the handler. - typedef completion_handler<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); - - post_immediate_completion(ptr.get()); - ptr.release(); - } + void post(Handler handler); // Request invocation of the given operation and return immediately. Assumes // that work_started() has not yet been called for the operation. - void post_immediate_completion(operation* op) + void post_immediate_completion(win_iocp_operation* op) { work_started(); post_deferred_completion(op); @@ -280,171 +113,50 @@ public: // Request invocation of the given operation and return immediately. Assumes // that work_started() was previously called for the operation. - void post_deferred_completion(operation* op) - { - // Flag the operation as ready. - op->ready_ = 1; - - // Enqueue the operation on the I/O completion port. - if (!::PostQueuedCompletionStatus(iocp_.handle, - 0, overlapped_contains_result, op)) - { - // Out of resources. Put on completed queue instead. - boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); - completed_ops_.push(op); - } - } + BOOST_ASIO_DECL void post_deferred_completion(win_iocp_operation* op); // Request invocation of the given operation and return immediately. Assumes // that work_started() was previously called for the operations. - void post_deferred_completions(op_queue<operation>& ops) - { - while (operation* op = ops.front()) - { - ops.pop(); - - // Flag the operation as ready. - op->ready_ = 1; - - // Enqueue the operation on the I/O completion port. - if (!::PostQueuedCompletionStatus(iocp_.handle, - 0, overlapped_contains_result, op)) - { - // Out of resources. Put on completed queue instead. - boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); - completed_ops_.push(op); - completed_ops_.push(ops); - } - } - } + BOOST_ASIO_DECL void post_deferred_completions( + op_queue<win_iocp_operation>& ops); // Called after starting an overlapped I/O operation that did not complete // immediately. The caller must have already called work_started() prior to // starting the operation. - void on_pending(operation* op) - { - if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1) - { - // Enqueue the operation on the I/O completion port. - if (!::PostQueuedCompletionStatus(iocp_.handle, - 0, overlapped_contains_result, op)) - { - // Out of resources. Put on completed queue instead. - boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); - completed_ops_.push(op); - } - } - } + BOOST_ASIO_DECL void on_pending(win_iocp_operation* op); // Called after starting an overlapped I/O operation that completed // immediately. The caller must have already called work_started() prior to // starting the operation. - void on_completion(operation* op, - DWORD last_error = 0, DWORD bytes_transferred = 0) - { - // Flag that the operation is ready for invocation. - op->ready_ = 1; - - // Store results in the OVERLAPPED structure. - op->Internal = reinterpret_cast<ulong_ptr_t>( - &boost::asio::error::get_system_category()); - op->Offset = last_error; - op->OffsetHigh = bytes_transferred; - - // Enqueue the operation on the I/O completion port. - if (!::PostQueuedCompletionStatus(iocp_.handle, - 0, overlapped_contains_result, op)) - { - // Out of resources. Put on completed queue instead. - boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); - completed_ops_.push(op); - } - } + BOOST_ASIO_DECL void on_completion(win_iocp_operation* op, + DWORD last_error = 0, DWORD bytes_transferred = 0); // Called after starting an overlapped I/O operation that completed // immediately. The caller must have already called work_started() prior to // starting the operation. - void on_completion(operation* op, - const boost::system::error_code& ec, DWORD bytes_transferred = 0) - { - // Flag that the operation is ready for invocation. - op->ready_ = 1; - - // Store results in the OVERLAPPED structure. - op->Internal = reinterpret_cast<ulong_ptr_t>(&ec.category()); - op->Offset = ec.value(); - op->OffsetHigh = bytes_transferred; - - // Enqueue the operation on the I/O completion port. - if (!::PostQueuedCompletionStatus(iocp_.handle, - 0, overlapped_contains_result, op)) - { - // Out of resources. Put on completed queue instead. - boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); - completed_ops_.push(op); - } - } + BOOST_ASIO_DECL void on_completion(win_iocp_operation* op, + const boost::system::error_code& ec, DWORD bytes_transferred = 0); // Add a new timer queue to the service. template <typename Time_Traits> - void add_timer_queue(timer_queue<Time_Traits>& timer_queue) - { - boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); - timer_queues_.insert(&timer_queue); - } + void add_timer_queue(timer_queue<Time_Traits>& timer_queue); // Remove a timer queue from the service. template <typename Time_Traits> - void remove_timer_queue(timer_queue<Time_Traits>& timer_queue) - { - boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); - timer_queues_.erase(&timer_queue); - } + void remove_timer_queue(timer_queue<Time_Traits>& timer_queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time. template <typename Time_Traits> - void schedule_timer(timer_queue<Time_Traits>& timer_queue, - const typename Time_Traits::time_type& time, timer_op* op, void* token) - { - // If the service has been shut down we silently discard the timer. - if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) - return; - - boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); - bool interrupt = timer_queue.enqueue_timer(time, op, token); - work_started(); - if (interrupt && !timer_interrupt_issued_) - { - timer_interrupt_issued_ = true; - lock.unlock(); - ::PostQueuedCompletionStatus(iocp_.handle, - 0, steal_timer_dispatching, 0); - } - } + void schedule_timer(timer_queue<Time_Traits>& queue, + const typename Time_Traits::time_type& time, + typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op); // Cancel the timer associated with the given token. Returns the number of // handlers that have been posted or dispatched. template <typename Time_Traits> - std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token) - { - // If the service has been shut down we silently ignore the cancellation. - if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) - return 0; - - boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); - op_queue<operation> ops; - std::size_t n = timer_queue.cancel_timer(token, ops); - post_deferred_completions(ops); - if (n > 0 && !timer_interrupt_issued_) - { - timer_interrupt_issued_ = true; - lock.unlock(); - ::PostQueuedCompletionStatus(iocp_.handle, - 0, steal_timer_dispatching, 0); - } - return n; - } + std::size_t cancel_timer(timer_queue<Time_Traits>& queue, + typename timer_queue<Time_Traits>::per_timer_data& timer); private: #if defined(WINVER) && (WINVER < 0x0500) @@ -458,181 +170,30 @@ private: // Dequeues at most one operation from the I/O completion port, and then // executes it. Returns the number of operations that were dequeued (i.e. // either 0 or 1). - size_t do_one(bool block, boost::system::error_code& ec) - { - long this_thread_id = static_cast<long>(::GetCurrentThreadId()); - - for (;;) - { - // Try to acquire responsibility for dispatching timers. - bool dispatching_timers = (::InterlockedCompareExchange( - &timer_thread_, this_thread_id, 0) == 0); - - // Calculate timeout for GetQueuedCompletionStatus call. - DWORD timeout = max_timeout; - if (dispatching_timers) - { - boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); - timer_interrupt_issued_ = false; - timeout = get_timeout(); - } - - // Get the next operation from the queue. - DWORD bytes_transferred = 0; - dword_ptr_t completion_key = 0; - LPOVERLAPPED overlapped = 0; - ::SetLastError(0); - BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, - &completion_key, &overlapped, block ? timeout : 0); - DWORD last_error = ::GetLastError(); - - // Dispatch any pending timers. - if (dispatching_timers) - { - boost::asio::detail::mutex::scoped_lock lock(timer_mutex_); - op_queue<operation> ops; - ops.push(completed_ops_); - timer_queues_.get_ready_timers(ops); - post_deferred_completions(ops); - } - - if (!ok && overlapped == 0) - { - if (block && last_error == WAIT_TIMEOUT) - { - // Relinquish responsibility for dispatching timers. - if (dispatching_timers) - { - ::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id); - } - - continue; - } - - // Transfer responsibility for dispatching timers to another thread. - if (dispatching_timers && ::InterlockedCompareExchange( - &timer_thread_, 0, this_thread_id) == this_thread_id) - { - ::PostQueuedCompletionStatus(iocp_.handle, - 0, transfer_timer_dispatching, 0); - } - - ec = boost::system::error_code(); - return 0; - } - else if (overlapped) - { - operation* op = static_cast<operation*>(overlapped); - boost::system::error_code result_ec(last_error, - boost::asio::error::get_system_category()); - - // Transfer responsibility for dispatching timers to another thread. - if (dispatching_timers && ::InterlockedCompareExchange( - &timer_thread_, 0, this_thread_id) == this_thread_id) - { - ::PostQueuedCompletionStatus(iocp_.handle, - 0, transfer_timer_dispatching, 0); - } - - // We may have been passed the last_error and bytes_transferred in the - // OVERLAPPED structure itself. - if (completion_key == overlapped_contains_result) - { - result_ec = boost::system::error_code(static_cast<int>(op->Offset), - *reinterpret_cast<boost::system::error_category*>(op->Internal)); - bytes_transferred = op->OffsetHigh; - } - - // Otherwise ensure any result has been saved into the OVERLAPPED - // structure. - else - { - op->Internal = reinterpret_cast<ulong_ptr_t>(&result_ec.category()); - op->Offset = result_ec.value(); - op->OffsetHigh = bytes_transferred; - } - - // Dispatch the operation only if ready. The operation may not be ready - // if the initiating function (e.g. a call to WSARecv) has not yet - // returned. This is because the initiating function still wants access - // to the operation's OVERLAPPED structure. - if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1) - { - // Ensure the count of outstanding work is decremented on block exit. - work_finished_on_block_exit on_exit = { this }; - (void)on_exit; - - op->complete(*this, result_ec, bytes_transferred); - ec = boost::system::error_code(); - return 1; - } - } - else if (completion_key == transfer_timer_dispatching) - { - // Woken up to try to acquire responsibility for dispatching timers. - ::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id); - } - else if (completion_key == steal_timer_dispatching) - { - // Woken up to steal responsibility for dispatching timers. - ::InterlockedExchange(&timer_thread_, 0); - } - else - { - // Relinquish responsibility for dispatching timers. If the io_service - // is not being stopped then the thread will get an opportunity to - // reacquire timer responsibility on the next loop iteration. - if (dispatching_timers) - { - ::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id); - } - - // The stopped_ flag is always checked to ensure that any leftover - // interrupts from a previous run invocation are ignored. - if (::InterlockedExchangeAdd(&stopped_, 0) != 0) - { - // Wake up next thread that is blocked on GetQueuedCompletionStatus. - if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) - { - last_error = ::GetLastError(); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return 0; - } - - ec = boost::system::error_code(); - return 0; - } - } - } - } + BOOST_ASIO_DECL size_t do_one(bool block, boost::system::error_code& ec); - // Get the timeout value for the GetQueuedCompletionStatus call. The timeout - // value is returned as a number of milliseconds. We will wait no longer than - // 1000 milliseconds. - DWORD get_timeout() - { - return timer_queues_.wait_duration_msec(max_timeout); - } + // Helper function to add a new timer queue. + BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); + + // Helper function to remove a timer queue. + BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); + + // Called to recalculate and update the timeout. + BOOST_ASIO_DECL void update_timeout(); // Helper class to call work_finished() on block exit. - struct work_finished_on_block_exit - { - ~work_finished_on_block_exit() - { - io_service_->work_finished(); - } + struct work_finished_on_block_exit; - win_iocp_io_service* io_service_; + // Helper class for managing a HANDLE. + struct auto_handle + { + HANDLE handle; + auto_handle() : handle(0) {} + ~auto_handle() { if (handle) ::CloseHandle(handle); } }; // The IO completion port used for queueing operations. - struct iocp_holder - { - HANDLE handle; - iocp_holder() : handle(0) {} - ~iocp_holder() { if (handle) ::CloseHandle(handle); } - } iocp_; + auto_handle iocp_; // The count of unfinished work. long outstanding_work_; @@ -645,45 +206,62 @@ private: enum { - // Maximum GetQueuedCompletionStatus timeout, in milliseconds. - max_timeout = 500, + // Timeout to use with GetQueuedCompletionStatus. Some versions of windows + // have a "bug" where a call to GetQueuedCompletionStatus can appear stuck + // even though there are events waiting on the queue. Using a timeout helps + // to work around the issue. + gqcs_timeout = 500, + + // Maximum waitable timer timeout, in milliseconds. + max_timeout_msec = 5 * 60 * 1000, - // Completion key value to indicate that responsibility for dispatching - // timers is being cooperatively transferred from one thread to another. - transfer_timer_dispatching = 1, + // Maximum waitable timer timeout, in microseconds. + max_timeout_usec = max_timeout_msec * 1000, - // Completion key value to indicate that responsibility for dispatching - // timers should be stolen from another thread. - steal_timer_dispatching = 2, + // Completion key value used to wake up a thread to dispatch timers or + // completed operations. + wake_for_dispatch = 1, // Completion key value to indicate that an operation has posted with the // original last_error and bytes_transferred values stored in the fields of // the OVERLAPPED structure. - overlapped_contains_result = 3 + overlapped_contains_result = 2 }; - // The thread that's currently in charge of dispatching timers. - long timer_thread_; + // Function object for processing timeouts in a background thread. + struct timer_thread_function; + friend struct timer_thread_function; + + // Background thread used for processing timeouts. + boost::scoped_ptr<thread> timer_thread_; + + // A waitable timer object used for waiting for timeouts. + auto_handle waitable_timer_; - // Mutex for protecting access to the timer queues. - mutex timer_mutex_; + // Non-zero if timers or completed operations need to be dispatched. + long dispatch_required_; - // Whether a thread has been interrupted to process a new timeout. - bool timer_interrupt_issued_; + // Mutex for protecting access to the timer queues and completed operations. + mutex dispatch_mutex_; // The timer queues. timer_queue_set timer_queues_; // The operations that are ready to dispatch. - op_queue<operation> completed_ops_; + op_queue<win_iocp_operation> completed_ops_; }; } // namespace detail } // namespace asio } // namespace boost -#endif // defined(BOOST_ASIO_HAS_IOCP) - #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/impl/win_iocp_io_service.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/win_iocp_io_service.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_ASIO_HAS_IOCP) + #endif // BOOST_ASIO_DETAIL_WIN_IOCP_IO_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_io_service_fwd.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_io_service_fwd.hpp index be413ec..1357603 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_iocp_io_service_fwd.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_io_service_fwd.hpp @@ -1,6 +1,6 @@ // -// win_iocp_io_service_fwd.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/win_iocp_io_service_fwd.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,22 +15,9 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/detail/socket_types.hpp> - -// This service is only supported on Win32 (NT4 and later). -#if !defined(BOOST_ASIO_DISABLE_IOCP) -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) -#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400) -#if !defined(UNDER_CE) - -// Define this to indicate that IOCP is supported on the target platform. -#define BOOST_ASIO_HAS_IOCP 1 +#if defined(BOOST_ASIO_HAS_IOCP) namespace boost { namespace asio { @@ -43,11 +30,6 @@ class win_iocp_overlapped_ptr; } // namespace asio } // namespace boost -#endif // !defined(UNDER_CE) -#endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400) -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) -#endif // !defined(BOOST_ASIO_DISABLE_IOCP) - -#include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_ASIO_HAS_IOCP) #endif // BOOST_ASIO_DETAIL_WIN_IOCP_IO_SERVICE_FWD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_null_buffers_op.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_null_buffers_op.hpp new file mode 100644 index 0000000..ed1c28f --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_null_buffers_op.hpp @@ -0,0 +1,114 @@ +// +// detail/win_iocp_null_buffers_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_IOCP_NULL_BUFFERS_OP_HPP +#define BOOST_ASIO_DETAIL_WIN_IOCP_NULL_BUFFERS_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/reactor_op.hpp> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Handler> +class win_iocp_null_buffers_op : public reactor_op +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_null_buffers_op); + + win_iocp_null_buffers_op(socket_ops::weak_cancel_token_type cancel_token, + Handler handler) + : reactor_op(&win_iocp_null_buffers_op::do_perform, + &win_iocp_null_buffers_op::do_complete), + cancel_token_(cancel_token), + handler_(handler) + { + } + + static bool do_perform(reactor_op*) + { + return true; + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + win_iocp_null_buffers_op* o(static_cast<win_iocp_null_buffers_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + // The reactor may have stored a result in the operation object. + if (o->ec_) + ec = o->ec_; + + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_NETNAME_DELETED) + { + if (o->cancel_token_.expired()) + ec = boost::asio::error::operation_aborted; + else + ec = boost::asio::error::connection_reset; + } + else if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = boost::asio::error::connection_refused; + } + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, ec, bytes_transferred); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + socket_ops::weak_cancel_token_type cancel_token_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_WIN_IOCP_NULL_BUFFERS_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_operation.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_operation.hpp index d7d5723..c9b3041 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_iocp_operation.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_operation.hpp @@ -1,6 +1,6 @@ // -// win_iocp_operation.hpp -// ~~~~~~~~~~~~~~~~~~~~~~ +// detail/win_iocp_operation.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,13 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/win_iocp_io_service_fwd.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_IOCP) #include <boost/asio/detail/op_queue.hpp> +#include <boost/asio/detail/win_iocp_io_service_fwd.hpp> +#include <boost/system/error_code.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -83,9 +85,8 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_ASIO_HAS_IOCP) - -#include <boost/system/error_code.hpp> #include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_ASIO_HAS_IOCP) + #endif // BOOST_ASIO_DETAIL_WIN_IOCP_OPERATION_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_op.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_op.hpp new file mode 100644 index 0000000..911449d --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_op.hpp @@ -0,0 +1,86 @@ +// +// detail/win_iocp_overlapped_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_IOCP_OVERLAPPED_OP_HPP +#define BOOST_ASIO_DETAIL_WIN_IOCP_OVERLAPPED_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/asio/error.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/operation.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Handler> +class win_iocp_overlapped_op : public operation +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_overlapped_op); + + win_iocp_overlapped_op(Handler handler) + : operation(&win_iocp_overlapped_op::do_complete), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + win_iocp_overlapped_op* o(static_cast<win_iocp_overlapped_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, ec, bytes_transferred); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_WIN_IOCP_OVERLAPPED_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_ptr.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_ptr.hpp index 082a5b1..5589c11 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_ptr.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_ptr.hpp @@ -1,6 +1,6 @@ // -// win_iocp_overlapped_ptr.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/win_iocp_overlapped_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,18 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/win_iocp_io_service_fwd.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_IOCP) -#include <boost/asio/detail/fenced_block.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/win_iocp_overlapped_op.hpp> #include <boost/asio/detail/win_iocp_io_service.hpp> -#include <boost/asio/detail/win_iocp_operation.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -75,13 +77,15 @@ public: template <typename Handler> void reset(boost::asio::io_service& io_service, Handler handler) { - typedef overlapped_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); + typedef win_iocp_overlapped_op<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); io_service.impl_.work_started(); reset(); - ptr_ = ptr.release(); + ptr_ = p.p; + p.v = p.p = 0; iocp_service_ = &io_service.impl_; } @@ -123,44 +127,6 @@ public: } private: - template <typename Handler> - struct overlapped_op : public win_iocp_operation - { - overlapped_op(Handler handler) - : win_iocp_operation(&overlapped_op::do_complete), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code ec, std::size_t bytes_transferred) - { - // Take ownership of the operation object. - overlapped_op* o(static_cast<overlapped_op*>(base)); - typedef handler_alloc_traits<Handler, overlapped_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, ec, bytes_transferred); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - Handler handler_; - }; - win_iocp_operation* ptr_; win_iocp_io_service* iocp_service_; }; @@ -169,8 +135,8 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_ASIO_HAS_IOCP) - #include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_ASIO_HAS_IOCP) + #endif // BOOST_ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_serial_port_service.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_serial_port_service.hpp index 288287c..a0caa69 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_iocp_serial_port_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_serial_port_service.hpp @@ -1,6 +1,6 @@ // -// win_iocp_serial_port_service.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/win_iocp_serial_port_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) @@ -16,21 +16,17 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <cstring> -#include <string> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/detail/win_iocp_io_service_fwd.hpp> +#include <boost/asio/detail/config.hpp> -#if defined(BOOST_ASIO_HAS_IOCP) +#if defined(BOOST_ASIO_HAS_IOCP) && defined(BOOST_ASIO_HAS_SERIAL_PORT) +#include <string> #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> #include <boost/asio/detail/win_iocp_handle_service.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -39,133 +35,56 @@ namespace detail { class win_iocp_serial_port_service { public: - // The native type of a stream handle. + // The native type of a serial port. typedef win_iocp_handle_service::native_type native_type; - // The implementation type of the stream handle. + // The implementation type of the serial port. typedef win_iocp_handle_service::implementation_type implementation_type; - win_iocp_serial_port_service(boost::asio::io_service& io_service) - : handle_service_(io_service) - { - } + // Constructor. + BOOST_ASIO_DECL win_iocp_serial_port_service( + boost::asio::io_service& io_service); // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - } + BOOST_ASIO_DECL void shutdown_service(); - // Construct a new handle implementation. + // Construct a new serial port implementation. void construct(implementation_type& impl) { handle_service_.construct(impl); } - // Destroy a handle implementation. + // Destroy a serial port implementation. void destroy(implementation_type& impl) { handle_service_.destroy(impl); } // Open the serial port using the specified device name. - boost::system::error_code open(implementation_type& impl, - const std::string& device, boost::system::error_code& ec) - { - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - // For convenience, add a leading \\.\ sequence if not already present. - std::string name = (device[0] == '\\') ? device : "\\\\.\\" + device; - - // Open a handle to the serial port. - ::HANDLE handle = ::CreateFileA(name.c_str(), - GENERIC_READ | GENERIC_WRITE, 0, 0, - OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); - if (handle == INVALID_HANDLE_VALUE) - { - DWORD last_error = ::GetLastError(); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return ec; - } - - // Determine the initial serial port parameters. - using namespace std; // For memcpy. - ::DCB dcb; - memset(&dcb, 0, sizeof(DCB)); - dcb.DCBlength = sizeof(DCB); - if (!::GetCommState(handle, &dcb)) - { - DWORD last_error = ::GetLastError(); - ::CloseHandle(handle); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return ec; - } - - // Set some default serial port parameters. This implementation does not - // support changing these, so they might as well be in a known state. - dcb.fBinary = TRUE; // Win32 only supports binary mode. - dcb.fDsrSensitivity = FALSE; - dcb.fNull = FALSE; // Do not ignore NULL characters. - dcb.fAbortOnError = FALSE; // Ignore serial framing errors. - if (!::SetCommState(handle, &dcb)) - { - DWORD last_error = ::GetLastError(); - ::CloseHandle(handle); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return ec; - } - - // Set up timeouts so that the serial port will behave similarly to a - // network socket. Reads wait for at least one byte, then return with - // whatever they have. Writes return once everything is out the door. - ::COMMTIMEOUTS timeouts; - timeouts.ReadIntervalTimeout = 1; - timeouts.ReadTotalTimeoutMultiplier = 0; - timeouts.ReadTotalTimeoutConstant = 0; - timeouts.WriteTotalTimeoutMultiplier = 0; - timeouts.WriteTotalTimeoutConstant = 0; - if (!::SetCommTimeouts(handle, &timeouts)) - { - DWORD last_error = ::GetLastError(); - ::CloseHandle(handle); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return ec; - } - - // We're done. Take ownership of the serial port handle. - if (handle_service_.assign(impl, handle, ec)) - ::CloseHandle(handle); - return ec; - } + BOOST_ASIO_DECL boost::system::error_code open(implementation_type& impl, + const std::string& device, boost::system::error_code& ec); - // Assign a native handle to a handle implementation. + // Assign a native handle to a serial port implementation. boost::system::error_code assign(implementation_type& impl, const native_type& native_handle, boost::system::error_code& ec) { return handle_service_.assign(impl, native_handle, ec); } - // Determine whether the handle is open. + // Determine whether the serial port is open. bool is_open(const implementation_type& impl) const { return handle_service_.is_open(impl); } - // Destroy a handle implementation. + // Destroy a serial port implementation. boost::system::error_code close(implementation_type& impl, boost::system::error_code& ec) { return handle_service_.close(impl, ec); } - // Get the native handle representation. + // Get the native serial port representation. native_type native(implementation_type& impl) { return handle_service_.native(impl); @@ -183,32 +102,9 @@ public: boost::system::error_code set_option(implementation_type& impl, const SettableSerialPortOption& option, boost::system::error_code& ec) { - using namespace std; // For memcpy. - - ::DCB dcb; - memset(&dcb, 0, sizeof(DCB)); - dcb.DCBlength = sizeof(DCB); - if (!::GetCommState(handle_service_.native(impl), &dcb)) - { - DWORD last_error = ::GetLastError(); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return ec; - } - - if (option.store(dcb, ec)) - return ec; - - if (!::SetCommState(handle_service_.native(impl), &dcb)) - { - DWORD last_error = ::GetLastError(); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return ec; - } - - ec = boost::system::error_code(); - return ec; + return do_set_option(impl, + &win_iocp_serial_port_service::store_option<SettableSerialPortOption>, + &option, ec); } // Get an option from the serial port. @@ -216,20 +112,9 @@ public: boost::system::error_code get_option(const implementation_type& impl, GettableSerialPortOption& option, boost::system::error_code& ec) const { - using namespace std; // For memcpy. - - ::DCB dcb; - memset(&dcb, 0, sizeof(DCB)); - dcb.DCBlength = sizeof(DCB); - if (!::GetCommState(handle_service_.native(impl), &dcb)) - { - DWORD last_error = ::GetLastError(); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return ec; - } - - return option.load(dcb, ec); + return do_get_option(impl, + &win_iocp_serial_port_service::load_option<GettableSerialPortOption>, + &option, ec); } // Send a break sequence to the serial port. @@ -275,6 +160,41 @@ public: } private: + // Function pointer type for storing a serial port option. + typedef boost::system::error_code (*store_function_type)( + const void*, ::DCB&, boost::system::error_code&); + + // Helper function template to store a serial port option. + template <typename SettableSerialPortOption> + static boost::system::error_code store_option(const void* option, + ::DCB& storage, boost::system::error_code& ec) + { + return static_cast<const SettableSerialPortOption*>(option)->store( + storage, ec); + } + + // Helper function to set a serial port option. + BOOST_ASIO_DECL boost::system::error_code do_set_option( + implementation_type& impl, store_function_type store, + const void* option, boost::system::error_code& ec); + + // Function pointer type for loading a serial port option. + typedef boost::system::error_code (*load_function_type)( + void*, const ::DCB&, boost::system::error_code&); + + // Helper function template to load a serial port option. + template <typename GettableSerialPortOption> + static boost::system::error_code load_option(void* option, + const ::DCB& storage, boost::system::error_code& ec) + { + return static_cast<GettableSerialPortOption*>(option)->load(storage, ec); + } + + // Helper function to get a serial port option. + BOOST_ASIO_DECL boost::system::error_code do_get_option( + const implementation_type& impl, load_function_type load, + void* option, boost::system::error_code& ec) const; + // The implementation used for initiating asynchronous operations. win_iocp_handle_service handle_service_; }; @@ -283,8 +203,12 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_ASIO_HAS_IOCP) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/win_iocp_serial_port_service.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_ASIO_HAS_IOCP) && defined(BOOST_ASIO_HAS_SERIAL_PORT) + #endif // BOOST_ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_accept_op.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_accept_op.hpp new file mode 100644 index 0000000..89dff0c --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_accept_op.hpp @@ -0,0 +1,160 @@ +// +// detail/win_iocp_socket_accept_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_HPP +#define BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/detail/win_iocp_socket_service_base.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Socket, typename Protocol, typename Handler> +class win_iocp_socket_accept_op : public operation +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_accept_op); + + win_iocp_socket_accept_op(win_iocp_socket_service_base& socket_service, + socket_type socket, Socket& peer, const Protocol& protocol, + typename Protocol::endpoint* peer_endpoint, + bool enable_connection_aborted, Handler handler) + : operation(&win_iocp_socket_accept_op::do_complete), + socket_service_(socket_service), + socket_(socket), + peer_(peer), + protocol_(protocol), + peer_endpoint_(peer_endpoint), + enable_connection_aborted_(enable_connection_aborted), + handler_(handler) + { + } + + socket_holder& new_socket() + { + return new_socket_; + } + + void* output_buffer() + { + return output_buffer_; + } + + DWORD address_length() + { + return sizeof(sockaddr_storage_type) + 16; + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code ec, std::size_t /*bytes_transferred*/) + { + // Take ownership of the operation object. + win_iocp_socket_accept_op* o(static_cast<win_iocp_socket_accept_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + + if (owner) + { + typename Protocol::endpoint peer_endpoint; + std::size_t addr_len = peer_endpoint.capacity(); + socket_ops::complete_iocp_accept(o->socket_, + o->output_buffer(), o->address_length(), + peer_endpoint.data(), &addr_len, + o->new_socket_.get(), ec); + + // Restart the accept operation if we got the connection_aborted error + // and the enable_connection_aborted socket option is not set. + if (ec == boost::asio::error::connection_aborted + && !o->enable_connection_aborted_) + { + o->reset(); + o->socket_service_.restart_accept_op(o->socket_, + o->new_socket_, o->protocol_.family(), + o->protocol_.type(), o->protocol_.protocol(), + o->output_buffer(), o->address_length(), o); + p.v = p.p = 0; + return; + } + + // If the socket was successfully accepted, transfer ownership of the + // socket to the peer object. + if (!ec) + { + o->peer_.assign(o->protocol_, + typename Socket::native_type( + o->new_socket_.get(), peer_endpoint), ec); + if (!ec) + o->new_socket_.release(); + } + + // Pass endpoint back to caller. + if (o->peer_endpoint_) + *o->peer_endpoint_ = peer_endpoint; + } + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder1<Handler, boost::system::error_code> + handler(o->handler_, ec); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + win_iocp_socket_service_base& socket_service_; + socket_type socket_; + socket_holder new_socket_; + Socket& peer_; + Protocol protocol_; + typename Protocol::endpoint* peer_endpoint_; + unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2]; + bool enable_connection_aborted_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_recv_op.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_recv_op.hpp new file mode 100644 index 0000000..98d7e99 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_recv_op.hpp @@ -0,0 +1,110 @@ +// +// detail/win_iocp_socket_recv_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_RECV_OP_HPP +#define BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_RECV_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename MutableBufferSequence, typename Handler> +class win_iocp_socket_recv_op : public operation +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_recv_op); + + win_iocp_socket_recv_op(socket_ops::state_type state, + socket_ops::weak_cancel_token_type cancel_token, + const MutableBufferSequence& buffers, Handler handler) + : operation(&win_iocp_socket_recv_op::do_complete), + state_(state), + cancel_token_(cancel_token), + buffers_(buffers), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + win_iocp_socket_recv_op* o(static_cast<win_iocp_socket_recv_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + if (owner) + { + buffer_sequence_adapter<boost::asio::mutable_buffer, + MutableBufferSequence>::validate(o->buffers_); + } +#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + + socket_ops::complete_iocp_recv(o->state_, o->cancel_token_, + buffer_sequence_adapter<boost::asio::mutable_buffer, + MutableBufferSequence>::all_empty(o->buffers_), + ec, bytes_transferred); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, ec, bytes_transferred); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + socket_ops::state_type state_; + socket_ops::weak_cancel_token_type cancel_token_; + MutableBufferSequence buffers_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_RECV_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_recvfrom_op.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_recvfrom_op.hpp new file mode 100644 index 0000000..eca34df --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_recvfrom_op.hpp @@ -0,0 +1,118 @@ +// +// detail/win_iocp_socket_recvfrom_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_RECVFROM_OP_HPP +#define BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_RECVFROM_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename MutableBufferSequence, typename Endpoint, typename Handler> +class win_iocp_socket_recvfrom_op : public operation +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_recvfrom_op); + + win_iocp_socket_recvfrom_op(Endpoint& endpoint, + socket_ops::weak_cancel_token_type cancel_token, + const MutableBufferSequence& buffers, Handler handler) + : operation(&win_iocp_socket_recvfrom_op::do_complete), + endpoint_(endpoint), + endpoint_size_(static_cast<int>(endpoint.capacity())), + cancel_token_(cancel_token), + buffers_(buffers), + handler_(handler) + { + } + + int& endpoint_size() + { + return endpoint_size_; + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + win_iocp_socket_recvfrom_op* o( + static_cast<win_iocp_socket_recvfrom_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + if (owner) + { + buffer_sequence_adapter<boost::asio::mutable_buffer, + MutableBufferSequence>::validate(o->buffers_); + } +#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + + socket_ops::complete_iocp_recvfrom(o->cancel_token_, ec); + + // Record the size of the endpoint returned by the operation. + o->endpoint_.resize(o->endpoint_size_); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, ec, bytes_transferred); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + Endpoint& endpoint_; + int endpoint_size_; + socket_ops::weak_cancel_token_type cancel_token_; + MutableBufferSequence buffers_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_RECVFROM_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_send_op.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_send_op.hpp new file mode 100644 index 0000000..2dcb4af --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_send_op.hpp @@ -0,0 +1,104 @@ +// +// detail/win_iocp_socket_send_op.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SEND_OP_HPP +#define BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SEND_OP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/utility/addressof.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename ConstBufferSequence, typename Handler> +class win_iocp_socket_send_op : public operation +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_send_op); + + win_iocp_socket_send_op(socket_ops::weak_cancel_token_type cancel_token, + const ConstBufferSequence& buffers, Handler handler) + : operation(&win_iocp_socket_send_op::do_complete), + cancel_token_(cancel_token), + buffers_(buffers), + handler_(handler) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code ec, std::size_t bytes_transferred) + { + // Take ownership of the operation object. + win_iocp_socket_send_op* o(static_cast<win_iocp_socket_send_op*>(base)); + ptr p = { boost::addressof(o->handler_), o, o }; + +#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + // Check whether buffers are still valid. + if (owner) + { + buffer_sequence_adapter<boost::asio::const_buffer, + ConstBufferSequence>::validate(o->buffers_); + } +#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) + + socket_ops::complete_iocp_send(o->cancel_token_, ec); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, ec, bytes_transferred); + p.h = boost::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + } + } + +private: + socket_ops::weak_cancel_token_type cancel_token_; + ConstBufferSequence buffers_; + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SEND_OP_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_service.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_service.hpp index 5d545a8..6f1f2bd 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_service.hpp @@ -1,6 +1,6 @@ // -// win_iocp_socket_service.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// detail/win_iocp_socket_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,19 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/win_iocp_io_service_fwd.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_IOCP) -#include <boost/asio/detail/push_options.hpp> #include <cstring> -#include <boost/shared_ptr.hpp> -#include <boost/type_traits/is_same.hpp> -#include <boost/weak_ptr.hpp> -#include <boost/asio/detail/pop_options.hpp> - +#include <boost/utility/addressof.hpp> #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> #include <boost/asio/socket_base.hpp> @@ -37,21 +30,28 @@ #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> #include <boost/asio/detail/mutex.hpp> -#include <boost/asio/detail/null_buffers_op.hpp> #include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/reactive_socket_connect_op.hpp> #include <boost/asio/detail/reactor.hpp> #include <boost/asio/detail/reactor_op.hpp> #include <boost/asio/detail/socket_holder.hpp> #include <boost/asio/detail/socket_ops.hpp> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/win_iocp_io_service.hpp> +#include <boost/asio/detail/win_iocp_null_buffers_op.hpp> +#include <boost/asio/detail/win_iocp_socket_accept_op.hpp> +#include <boost/asio/detail/win_iocp_socket_recvfrom_op.hpp> +#include <boost/asio/detail/win_iocp_socket_send_op.hpp> +#include <boost/asio/detail/win_iocp_socket_service_base.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace detail { template <typename Protocol> -class win_iocp_socket_service +class win_iocp_socket_service : public win_iocp_socket_service_base { public: // The protocol type. @@ -60,10 +60,6 @@ public: // The endpoint type. typedef typename Protocol::endpoint endpoint_type; - struct noop_deleter { void operator()(void*) {} }; - typedef boost::shared_ptr<void> shared_cancel_token_type; - typedef boost::weak_ptr<void> weak_cancel_token_type; - // The native type of a socket. class native_type { @@ -93,11 +89,6 @@ public: return socket_; } - HANDLE as_handle() const - { - return reinterpret_cast<HANDLE>(socket_); - } - bool have_remote_endpoint() const { return have_remote_endpoint_; @@ -115,148 +106,44 @@ public: }; // The implementation type of the socket. - class implementation_type + struct implementation_type : + win_iocp_socket_service_base::base_implementation_type { - public: // Default constructor. implementation_type() - : socket_(invalid_socket), - flags_(0), - cancel_token_(), - protocol_(endpoint_type().protocol()), - next_(0), - prev_(0) + : protocol_(endpoint_type().protocol()), + have_remote_endpoint_(false), + remote_endpoint_() { } - private: - // Only this service will have access to the internal values. - friend class win_iocp_socket_service; - - // The native socket representation. - native_type socket_; - - enum - { - enable_connection_aborted = 1, // User wants connection_aborted errors. - close_might_block = 2, // User set linger option for blocking close. - user_set_non_blocking = 4 // The user wants a non-blocking socket. - }; - - // Flags indicating the current state of the socket. - unsigned char flags_; - - // We use a shared pointer as a cancellation token here to work around the - // broken Windows support for cancellation. MSDN says that when you call - // closesocket any outstanding WSARecv or WSASend operations will complete - // with the error ERROR_OPERATION_ABORTED. In practice they complete with - // ERROR_NETNAME_DELETED, which means you can't tell the difference between - // a local cancellation and the socket being hard-closed by the peer. - shared_cancel_token_type cancel_token_; - // The protocol associated with the socket. protocol_type protocol_; - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - -#if defined(BOOST_ASIO_ENABLE_CANCELIO) - // The ID of the thread from which it is safe to cancel asynchronous - // operations. 0 means no asynchronous operations have been started yet. - // ~0 means asynchronous operations have been started from more than one - // thread, and cancellation is not supported for the socket. - DWORD safe_cancellation_thread_id_; -#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + // Whether we have a cached remote endpoint. + bool have_remote_endpoint_; - // Pointers to adjacent socket implementations in linked list. - implementation_type* next_; - implementation_type* prev_; + // A cached remote endpoint. + endpoint_type remote_endpoint_; }; // Constructor. win_iocp_socket_service(boost::asio::io_service& io_service) - : io_service_(io_service), - iocp_service_(use_service<win_iocp_io_service>(io_service)), - reactor_(0), - mutex_(), - impl_list_(0) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown_service() + : win_iocp_socket_service_base(io_service) { - // Close all implementations, causing all operations to complete. - boost::asio::detail::mutex::scoped_lock lock(mutex_); - implementation_type* impl = impl_list_; - while (impl) - { - boost::system::error_code ignored_ec; - close_for_destruction(*impl); - impl = impl->next_; - } - } - - // Construct a new socket implementation. - void construct(implementation_type& impl) - { - impl.socket_ = invalid_socket; - impl.flags_ = 0; - impl.cancel_token_.reset(); -#if defined(BOOST_ASIO_ENABLE_CANCELIO) - impl.safe_cancellation_thread_id_ = 0; -#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) - - // Insert implementation into linked list of all implementations. - boost::asio::detail::mutex::scoped_lock lock(mutex_); - impl.next_ = impl_list_; - impl.prev_ = 0; - if (impl_list_) - impl_list_->prev_ = &impl; - impl_list_ = &impl; - } - - // Destroy a socket implementation. - void destroy(implementation_type& impl) - { - close_for_destruction(impl); - - // Remove implementation from linked list of all implementations. - boost::asio::detail::mutex::scoped_lock lock(mutex_); - if (impl_list_ == &impl) - impl_list_ = impl.next_; - if (impl.prev_) - impl.prev_->next_ = impl.next_; - if (impl.next_) - impl.next_->prev_= impl.prev_; - impl.next_ = 0; - impl.prev_ = 0; } // Open a new socket implementation. boost::system::error_code open(implementation_type& impl, const protocol_type& protocol, boost::system::error_code& ec) { - if (is_open(impl)) + if (!do_open(impl, protocol.family(), + protocol.type(), protocol.protocol(), ec)) { - ec = boost::asio::error::already_open; - return ec; + impl.protocol_ = protocol; + impl.have_remote_endpoint_ = false; + impl.remote_endpoint_ = endpoint_type(); } - - socket_holder sock(socket_ops::socket(protocol.family(), protocol.type(), - protocol.protocol(), ec)); - if (sock.get() == invalid_socket) - return ec; - - HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock.get()); - if (iocp_service_.register_handle(sock_as_handle, ec)) - return ec; - - impl.socket_ = sock.release(); - impl.flags_ = 0; - impl.cancel_token_.reset(static_cast<void*>(0), noop_deleter()); - impl.protocol_ = protocol; - ec = boost::system::error_code(); return ec; } @@ -265,247 +152,40 @@ public: const protocol_type& protocol, const native_type& native_socket, boost::system::error_code& ec) { - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (iocp_service_.register_handle(native_socket.as_handle(), ec)) - return ec; - - impl.socket_ = native_socket; - impl.flags_ = 0; - impl.cancel_token_.reset(static_cast<void*>(0), noop_deleter()); - impl.protocol_ = protocol; - ec = boost::system::error_code(); - return ec; - } - - // Determine whether the socket is open. - bool is_open(const implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - boost::system::error_code close(implementation_type& impl, - boost::system::error_code& ec) - { - if (is_open(impl)) + if (!do_assign(impl, protocol.type(), native_socket, ec)) { - // Check if the reactor was created, in which case we need to close the - // socket on the reactor as well to cancel any operations that might be - // running there. - reactor* r = static_cast<reactor*>( - interlocked_compare_exchange_pointer( - reinterpret_cast<void**>(&reactor_), 0, 0)); - if (r) - r->close_descriptor(impl.socket_, impl.reactor_data_); - - if (socket_ops::close(impl.socket_, ec) == socket_error_retval) - return ec; - - impl.socket_ = invalid_socket; - impl.flags_ = 0; - impl.cancel_token_.reset(); -#if defined(BOOST_ASIO_ENABLE_CANCELIO) - impl.safe_cancellation_thread_id_ = 0; -#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + impl.protocol_ = protocol; + impl.have_remote_endpoint_ = native_socket.have_remote_endpoint(); + impl.remote_endpoint_ = native_socket.remote_endpoint(); } - - ec = boost::system::error_code(); return ec; } // Get the native socket representation. native_type native(implementation_type& impl) { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - boost::system::error_code cancel(implementation_type& impl, - boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress( - ::GetModuleHandleA("KERNEL32"), "CancelIoEx")) - { - // The version of Windows supports cancellation from any thread. - typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED); - cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr; - socket_type sock = impl.socket_; - HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock); - if (!cancel_io_ex(sock_as_handle, 0)) - { - DWORD last_error = ::GetLastError(); - if (last_error == ERROR_NOT_FOUND) - { - // ERROR_NOT_FOUND means that there were no operations to be - // cancelled. We swallow this error to match the behaviour on other - // platforms. - ec = boost::system::error_code(); - } - else - { - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - } - } - else - { - ec = boost::system::error_code(); - } - } -#if defined(BOOST_ASIO_ENABLE_CANCELIO) - else if (impl.safe_cancellation_thread_id_ == 0) - { - // No operations have been started, so there's nothing to cancel. - ec = boost::system::error_code(); - } - else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId()) - { - // Asynchronous operations have been started from the current thread only, - // so it is safe to try to cancel them using CancelIo. - socket_type sock = impl.socket_; - HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock); - if (!::CancelIo(sock_as_handle)) - { - DWORD last_error = ::GetLastError(); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - } - else - { - ec = boost::system::error_code(); - } - } - else - { - // Asynchronous operations have been started from more than one thread, - // so cancellation is not safe. - ec = boost::asio::error::operation_not_supported; - } -#else // defined(BOOST_ASIO_ENABLE_CANCELIO) - else - { - // Cancellation is not supported as CancelIo may not be used. - ec = boost::asio::error::operation_not_supported; - } -#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) - - return ec; - } - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const implementation_type& impl, - boost::system::error_code& ec) const - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return false; - } - - boost::asio::detail::ioctl_arg_type value = 0; - socket_ops::ioctl(impl.socket_, SIOCATMARK, &value, ec); - return ec ? false : value != 0; - } - - // Determine the number of bytes available for reading. - std::size_t available(const implementation_type& impl, - boost::system::error_code& ec) const - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - boost::asio::detail::ioctl_arg_type value = 0; - socket_ops::ioctl(impl.socket_, FIONREAD, &value, ec); - return ec ? static_cast<std::size_t>(0) : static_cast<std::size_t>(value); + if (impl.have_remote_endpoint_) + return native_type(impl.socket_, impl.remote_endpoint_); + return native_type(impl.socket_); } // Bind the socket to the specified local endpoint. boost::system::error_code bind(implementation_type& impl, const endpoint_type& endpoint, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); return ec; } - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(implementation_type& impl, int backlog, - boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - // Set a socket option. template <typename Option> boost::system::error_code set_option(implementation_type& impl, const Option& option, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - if (option.level(impl.protocol_) == custom_socket_option_level - && option.name(impl.protocol_) == enable_connection_aborted_option) - { - if (option.size(impl.protocol_) != sizeof(int)) - { - ec = boost::asio::error::invalid_argument; - } - else - { - if (*reinterpret_cast<const int*>(option.data(impl.protocol_))) - impl.flags_ |= implementation_type::enable_connection_aborted; - else - impl.flags_ &= ~implementation_type::enable_connection_aborted; - ec = boost::system::error_code(); - } - return ec; - } - else - { - if (option.level(impl.protocol_) == SOL_SOCKET - && option.name(impl.protocol_) == SO_LINGER) - { - const ::linger* linger_option = - reinterpret_cast<const ::linger*>(option.data(impl.protocol_)); - if (linger_option->l_onoff != 0 && linger_option->l_linger != 0) - impl.flags_ |= implementation_type::close_might_block; - else - impl.flags_ &= ~implementation_type::close_might_block; - } - - socket_ops::setsockopt(impl.socket_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } + socket_ops::setsockopt(impl.socket_, impl.state_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), option.size(impl.protocol_), ec); + return ec; } // Set a socket option. @@ -513,65 +193,12 @@ public: boost::system::error_code get_option(const implementation_type& impl, Option& option, boost::system::error_code& ec) const { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - if (option.level(impl.protocol_) == custom_socket_option_level - && option.name(impl.protocol_) == enable_connection_aborted_option) - { - if (option.size(impl.protocol_) != sizeof(int)) - { - ec = boost::asio::error::invalid_argument; - } - else - { - int* target = reinterpret_cast<int*>(option.data(impl.protocol_)); - if (impl.flags_ & implementation_type::enable_connection_aborted) - *target = 1; - else - *target = 0; - option.resize(impl.protocol_, sizeof(int)); - ec = boost::system::error_code(); - } - return ec; - } - else - { - size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - } - - // Perform an IO control command on the socket. - template <typename IO_Control_Command> - boost::system::error_code io_control(implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - socket_ops::ioctl(impl.socket_, command.name(), - static_cast<ioctl_arg_type*>(command.data()), ec); - - if (!ec && command.name() == static_cast<int>(FIONBIO)) - { - if (*static_cast<ioctl_arg_type*>(command.data())) - impl.flags_ |= implementation_type::user_set_non_blocking; - else - impl.flags_ &= ~implementation_type::user_set_non_blocking; - } - + std::size_t size = option.size(impl.protocol_); + socket_ops::getsockopt(impl.socket_, impl.state_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), &size, ec); + if (!ec) + option.resize(impl.protocol_, size); return ec; } @@ -579,12 +206,6 @@ public: endpoint_type local_endpoint(const implementation_type& impl, boost::system::error_code& ec) const { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return endpoint_type(); - } - endpoint_type endpoint; std::size_t addr_len = endpoint.capacity(); if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) @@ -597,210 +218,13 @@ public: endpoint_type remote_endpoint(const implementation_type& impl, boost::system::error_code& ec) const { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; + endpoint_type endpoint = impl.remote_endpoint_; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getpeername(impl.socket_, endpoint.data(), + &addr_len, impl.have_remote_endpoint_, ec)) return endpoint_type(); - } - - if (impl.socket_.have_remote_endpoint()) - { - // Check if socket is still connected. - DWORD connect_time = 0; - size_t connect_time_len = sizeof(connect_time); - if (socket_ops::getsockopt(impl.socket_, SOL_SOCKET, SO_CONNECT_TIME, - &connect_time, &connect_time_len, ec) == socket_error_retval) - { - return endpoint_type(); - } - if (connect_time == 0xFFFFFFFF) - { - ec = boost::asio::error::not_connected; - return endpoint_type(); - } - - ec = boost::system::error_code(); - return impl.socket_.remote_endpoint(); - } - else - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - } - - /// Disable sends or receives on the socket. - boost::system::error_code shutdown(implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send the given data to the peer. Returns the number of bytes sent. - template <typename ConstBufferSequence> - size_t send(implementation_type& impl, const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - buffer_sequence_adapter<boost::asio::const_buffer, - ConstBufferSequence> bufs(buffers); - - // A request to receive 0 bytes on a stream socket is a no-op. - if (impl.protocol_.type() == SOCK_STREAM && bufs.all_empty()) - { - ec = boost::system::error_code(); - return 0; - } - - // Send the data. - DWORD bytes_transferred = 0; - int result = ::WSASend(impl.socket_, bufs.buffers(), - bufs.count(), &bytes_transferred, flags, 0, 0); - if (result != 0) - { - DWORD last_error = ::WSAGetLastError(); - if (last_error == ERROR_NETNAME_DELETED) - last_error = WSAECONNRESET; - else if (last_error == ERROR_PORT_UNREACHABLE) - last_error = WSAECONNREFUSED; - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return 0; - } - - ec = boost::system::error_code(); - return bytes_transferred; - } - - // Wait until data can be sent without blocking. - size_t send(implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, ec); - - return 0; - } - - template <typename ConstBufferSequence, typename Handler> - class send_op : public operation - { - public: - send_op(weak_cancel_token_type cancel_token, - const ConstBufferSequence& buffers, Handler handler) - : operation(&send_op::do_complete), - cancel_token_(cancel_token), - buffers_(buffers), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code ec, std::size_t bytes_transferred) - { - // Take ownership of the operation object. - send_op* o(static_cast<send_op*>(base)); - typedef handler_alloc_traits<Handler, send_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { -#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) - // Check whether buffers are still valid. - buffer_sequence_adapter<boost::asio::const_buffer, - ConstBufferSequence>::validate(o->buffers_); -#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) - - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (o->cancel_token_.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } - - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, ec, bytes_transferred); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - weak_cancel_token_type cancel_token_; - ConstBufferSequence buffers_; - Handler handler_; - }; - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template <typename ConstBufferSequence, typename Handler> - void async_send(implementation_type& impl, const ConstBufferSequence& buffers, - socket_base::message_flags flags, Handler handler) - { - // Allocate and construct an operation to wrap the handler. - typedef send_op<ConstBufferSequence, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, - impl.cancel_token_, buffers, handler); - - buffer_sequence_adapter<boost::asio::const_buffer, - ConstBufferSequence> bufs(buffers); - - start_send_op(impl, bufs.buffers(), bufs.count(), flags, - impl.protocol_.type() == SOCK_STREAM && bufs.all_empty(), ptr.get()); - ptr.release(); - } - - // Start an asynchronous wait until data can be sent without blocking. - template <typename Handler> - void async_send(implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler handler) - { - // Allocate and construct an operation to wrap the handler. - typedef null_buffers_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); - - start_reactor_op(impl, reactor::write_op, ptr.get()); - ptr.release(); + endpoint.resize(addr_len); + return endpoint; } // Send a datagram to the specified endpoint. Returns the number of bytes @@ -810,107 +234,25 @@ public: const endpoint_type& destination, socket_base::message_flags flags, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - buffer_sequence_adapter<boost::asio::const_buffer, ConstBufferSequence> bufs(buffers); - // Send the data. - DWORD bytes_transferred = 0; - int result = ::WSASendTo(impl.socket_, bufs.buffers(), bufs.count(), - &bytes_transferred, flags, destination.data(), - static_cast<int>(destination.size()), 0, 0); - if (result != 0) - { - DWORD last_error = ::WSAGetLastError(); - if (last_error == ERROR_PORT_UNREACHABLE) - last_error = WSAECONNREFUSED; - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return 0; - } - - ec = boost::system::error_code(); - return bytes_transferred; + return socket_ops::sync_sendto(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), flags, + destination.data(), destination.size(), ec); } // Wait until data can be sent without blocking. size_t send_to(implementation_type& impl, const null_buffers&, - socket_base::message_flags, const endpoint_type&, + const endpoint_type&, socket_base::message_flags, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - // Wait for socket to become ready. socket_ops::poll_write(impl.socket_, ec); return 0; } - template <typename ConstBufferSequence, typename Handler> - class send_to_op : public operation - { - public: - send_to_op(weak_cancel_token_type cancel_token, - const ConstBufferSequence& buffers, Handler handler) - : operation(&send_to_op::do_complete), - cancel_token_(cancel_token), - buffers_(buffers), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code ec, std::size_t bytes_transferred) - { - // Take ownership of the operation object. - send_to_op* o(static_cast<send_to_op*>(base)); - typedef handler_alloc_traits<Handler, send_to_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { -#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) - // Check whether buffers are still valid. - buffer_sequence_adapter<boost::asio::const_buffer, - ConstBufferSequence>::validate(o->buffers_); -#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) - - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } - - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, ec, bytes_transferred); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - weak_cancel_token_type cancel_token_; - ConstBufferSequence buffers_; - Handler handler_; - }; - // Start an asynchronous send. The data being sent must be valid for the // lifetime of the asynchronous operation. template <typename ConstBufferSequence, typename Handler> @@ -919,233 +261,35 @@ public: socket_base::message_flags flags, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef send_to_op<ConstBufferSequence, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, - impl.cancel_token_, buffers, handler); + typedef win_iocp_socket_send_op<ConstBufferSequence, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, buffers, handler); buffer_sequence_adapter<boost::asio::const_buffer, ConstBufferSequence> bufs(buffers); - start_send_to_op(impl, bufs.buffers(), - bufs.count(), destination, flags, ptr.get()); - ptr.release(); + start_send_to_op(impl, bufs.buffers(), bufs.count(), + destination.data(), static_cast<int>(destination.size()), + flags, p.p); + p.v = p.p = 0; } // Start an asynchronous wait until data can be sent without blocking. template <typename Handler> void async_send_to(implementation_type& impl, const null_buffers&, - socket_base::message_flags, const endpoint_type&, Handler handler) - { - // Allocate and construct an operation to wrap the handler. - typedef null_buffers_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); - - start_reactor_op(impl, reactor::write_op, ptr.get()); - ptr.release(); - } - - // Receive some data from the peer. Returns the number of bytes received. - template <typename MutableBufferSequence> - size_t receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - buffer_sequence_adapter<boost::asio::mutable_buffer, - MutableBufferSequence> bufs(buffers); - - // A request to receive 0 bytes on a stream socket is a no-op. - if (impl.protocol_.type() == SOCK_STREAM && bufs.all_empty()) - { - ec = boost::system::error_code(); - return 0; - } - - // Receive some data. - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = ::WSARecv(impl.socket_, bufs.buffers(), - bufs.count(), &bytes_transferred, &recv_flags, 0, 0); - if (result != 0) - { - DWORD last_error = ::WSAGetLastError(); - if (last_error == ERROR_NETNAME_DELETED) - last_error = WSAECONNRESET; - else if (last_error == ERROR_PORT_UNREACHABLE) - last_error = WSAECONNREFUSED; - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return 0; - } - if (bytes_transferred == 0 && impl.protocol_.type() == SOCK_STREAM) - { - ec = boost::asio::error::eof; - return 0; - } - - ec = boost::system::error_code(); - return bytes_transferred; - } - - // Wait until data can be received without blocking. - size_t receive(implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, ec); - - return 0; - } - - template <typename MutableBufferSequence, typename Handler> - class receive_op : public operation - { - public: - receive_op(int protocol_type, weak_cancel_token_type cancel_token, - const MutableBufferSequence& buffers, Handler handler) - : operation(&receive_op::do_complete), - protocol_type_(protocol_type), - cancel_token_(cancel_token), - buffers_(buffers), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code ec, std::size_t bytes_transferred) - { - // Take ownership of the operation object. - receive_op* o(static_cast<receive_op*>(base)); - typedef handler_alloc_traits<Handler, receive_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { -#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) - // Check whether buffers are still valid. - buffer_sequence_adapter<boost::asio::mutable_buffer, - MutableBufferSequence>::validate(o->buffers_); -#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) - - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (o->cancel_token_.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } - - // Check for connection closed. - else if (!ec && bytes_transferred == 0 - && o->protocol_type_ == SOCK_STREAM - && !buffer_sequence_adapter<boost::asio::mutable_buffer, - MutableBufferSequence>::all_empty(o->buffers_) - && !boost::is_same<MutableBufferSequence, null_buffers>::value) - { - ec = boost::asio::error::eof; - } - - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, ec, bytes_transferred); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - int protocol_type_; - weak_cancel_token_type cancel_token_; - MutableBufferSequence buffers_; - Handler handler_; - }; - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template <typename MutableBufferSequence, typename Handler> - void async_receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler handler) + const endpoint_type&, socket_base::message_flags, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef receive_op<MutableBufferSequence, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - int protocol_type = impl.protocol_.type(); - handler_ptr<alloc_traits> ptr(raw_ptr, protocol_type, - impl.cancel_token_, buffers, handler); - - buffer_sequence_adapter<boost::asio::mutable_buffer, - MutableBufferSequence> bufs(buffers); + typedef win_iocp_null_buffers_op<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, handler); - start_receive_op(impl, bufs.buffers(), bufs.count(), flags, - protocol_type == SOCK_STREAM && bufs.all_empty(), ptr.get()); - ptr.release(); - } - - // Wait until data can be received without blocking. - template <typename Handler> - void async_receive(implementation_type& impl, const null_buffers& buffers, - socket_base::message_flags flags, Handler handler) - { - if (impl.protocol_.type() == SOCK_STREAM) - { - // For stream sockets on Windows, we may issue a 0-byte overlapped - // WSARecv to wait until there is data available on the socket. - - // Allocate and construct an operation to wrap the handler. - typedef receive_op<null_buffers, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - int protocol_type = impl.protocol_.type(); - handler_ptr<alloc_traits> ptr(raw_ptr, protocol_type, - impl.cancel_token_, buffers, handler); - - ::WSABUF buf = { 0, 0 }; - start_receive_op(impl, &buf, 1, flags, false, ptr.get()); - ptr.release(); - } - else - { - // Allocate and construct an operation to wrap the handler. - typedef null_buffers_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); - - start_reactor_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - ptr.get()); - ptr.release(); - } + start_reactor_op(impl, reactor::write_op, p.p); + p.v = p.p = 0; } // Receive a datagram with the endpoint of the sender. Returns the number of @@ -1156,41 +300,18 @@ public: endpoint_type& sender_endpoint, socket_base::message_flags flags, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - buffer_sequence_adapter<boost::asio::mutable_buffer, MutableBufferSequence> bufs(buffers); - // Receive some data. - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int endpoint_size = static_cast<int>(sender_endpoint.capacity()); - int result = ::WSARecvFrom(impl.socket_, bufs.buffers(), - bufs.count(), &bytes_transferred, &recv_flags, - sender_endpoint.data(), &endpoint_size, 0, 0); - if (result != 0) - { - DWORD last_error = ::WSAGetLastError(); - if (last_error == ERROR_PORT_UNREACHABLE) - last_error = WSAECONNREFUSED; - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return 0; - } - if (bytes_transferred == 0 && impl.protocol_.type() == SOCK_STREAM) - { - ec = boost::asio::error::eof; - return 0; - } + std::size_t addr_len = sender_endpoint.capacity(); + std::size_t bytes_recvd = socket_ops::sync_recvfrom( + impl.socket_, impl.state_, bufs.buffers(), bufs.count(), + flags, sender_endpoint.data(), &addr_len, ec); - sender_endpoint.resize(static_cast<std::size_t>(endpoint_size)); + if (!ec) + sender_endpoint.resize(addr_len); - ec = boost::system::error_code(); - return bytes_transferred; + return bytes_recvd; } // Wait until data can be received without blocking. @@ -1198,12 +319,6 @@ public: const null_buffers&, endpoint_type& sender_endpoint, socket_base::message_flags, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - // Wait for socket to become ready. socket_ops::poll_read(impl.socket_, ec); @@ -1213,75 +328,6 @@ public: return 0; } - template <typename MutableBufferSequence, typename Handler> - class receive_from_op : public operation - { - public: - receive_from_op(int protocol_type, endpoint_type& endpoint, - const MutableBufferSequence& buffers, Handler handler) - : operation(&receive_from_op::do_complete), - protocol_type_(protocol_type), - endpoint_(endpoint), - endpoint_size_(static_cast<int>(endpoint.capacity())), - buffers_(buffers), - handler_(handler) - { - } - - int& endpoint_size() - { - return endpoint_size_; - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code ec, std::size_t bytes_transferred) - { - // Take ownership of the operation object. - receive_from_op* o(static_cast<receive_from_op*>(base)); - typedef handler_alloc_traits<Handler, receive_from_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { -#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) - // Check whether buffers are still valid. - buffer_sequence_adapter<boost::asio::mutable_buffer, - MutableBufferSequence>::validate(o->buffers_); -#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) - - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } - - // Record the size of the endpoint returned by the operation. - o->endpoint_.resize(o->endpoint_size_); - - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder2<Handler, boost::system::error_code, std::size_t> - handler(o->handler_, ec, bytes_transferred); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - int protocol_type_; - endpoint_type& endpoint_; - int endpoint_size_; - weak_cancel_token_type cancel_token_; - MutableBufferSequence buffers_; - Handler handler_; - }; - // Start an asynchronous receive. The buffer for the data being received and // the sender_endpoint object must both be valid for the lifetime of the // asynchronous operation. @@ -1291,19 +337,19 @@ public: socket_base::message_flags flags, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef receive_from_op<MutableBufferSequence, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - int protocol_type = impl.protocol_.type(); - handler_ptr<alloc_traits> ptr(raw_ptr, - protocol_type, sender_endp, buffers, handler); + typedef win_iocp_socket_recvfrom_op< + MutableBufferSequence, endpoint_type, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(sender_endp, impl.cancel_token_, buffers, handler); buffer_sequence_adapter<boost::asio::mutable_buffer, MutableBufferSequence> bufs(buffers); start_receive_from_op(impl, bufs.buffers(), bufs.count(), - sender_endp, flags, &ptr.get()->endpoint_size(), ptr.get()); - ptr.release(); + sender_endp.data(), flags, &p.p->endpoint_size(), p.p); + p.v = p.p = 0; } // Wait until data can be received without blocking. @@ -1313,19 +359,17 @@ public: socket_base::message_flags flags, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef null_buffers_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, handler); + typedef win_iocp_null_buffers_op<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, handler); // Reset endpoint since it can be given no sensible value at this time. sender_endpoint = endpoint_type(); - start_reactor_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - ptr.get()); - ptr.release(); + start_null_buffers_receive_op(impl, flags, p.p); + p.v = p.p = 0; } // Accept a new connection. @@ -1333,12 +377,6 @@ public: boost::system::error_code accept(implementation_type& impl, Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - // We cannot accept a socket that is already open. if (peer.is_open()) { @@ -1346,222 +384,22 @@ public: return ec; } - for (;;) - { - socket_holder new_socket; - std::size_t addr_len = 0; - if (peer_endpoint) - { - addr_len = peer_endpoint->capacity(); - new_socket.reset(socket_ops::accept(impl.socket_, - peer_endpoint->data(), &addr_len, ec)); - } - else - { - new_socket.reset(socket_ops::accept(impl.socket_, 0, 0, ec)); - } - - if (ec) - { - if (ec == boost::asio::error::connection_aborted - && !(impl.flags_ & implementation_type::enable_connection_aborted)) - { - // Retry accept operation. - continue; - } - else - { - return ec; - } - } + std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; + socket_holder new_socket(socket_ops::sync_accept(impl.socket_, + impl.state_, peer_endpoint ? peer_endpoint->data() : 0, + peer_endpoint ? &addr_len : 0, ec)); + // On success, assign new connection to peer socket object. + if (new_socket.get() >= 0) + { if (peer_endpoint) peer_endpoint->resize(addr_len); - - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) + if (!peer.assign(impl.protocol_, new_socket.get(), ec)) new_socket.release(); - return ec; - } - } - - template <typename Socket, typename Handler> - class accept_op : public operation - { - public: - accept_op(win_iocp_io_service& iocp_service, socket_type socket, - Socket& peer, const protocol_type& protocol, - endpoint_type* peer_endpoint, bool enable_connection_aborted, - Handler handler) - : operation(&accept_op::do_complete), - iocp_service_(iocp_service), - socket_(socket), - peer_(peer), - protocol_(protocol), - peer_endpoint_(peer_endpoint), - enable_connection_aborted_(enable_connection_aborted), - handler_(handler) - { } - socket_holder& new_socket() - { - return new_socket_; - } - - void* output_buffer() - { - return output_buffer_; - } - - DWORD address_length() - { - return sizeof(sockaddr_storage_type) + 16; - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code ec, std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - accept_op* o(static_cast<accept_op*>(base)); - typedef handler_alloc_traits<Handler, accept_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { - // Map Windows error ERROR_NETNAME_DELETED to connection_aborted. - if (ec.value() == ERROR_NETNAME_DELETED) - { - ec = boost::asio::error::connection_aborted; - } - - // Restart the accept operation if we got the connection_aborted error - // and the enable_connection_aborted socket option is not set. - if (ec == boost::asio::error::connection_aborted - && !o->enable_connection_aborted_) - { - // Reset OVERLAPPED structure. - o->reset(); - - // Create a new socket for the next connection, since the AcceptEx - // call fails with WSAEINVAL if we try to reuse the same socket. - o->new_socket_.reset(); - o->new_socket_.reset(socket_ops::socket(o->protocol_.family(), - o->protocol_.type(), o->protocol_.protocol(), ec)); - if (o->new_socket_.get() != invalid_socket) - { - // Accept a connection. - DWORD bytes_read = 0; - BOOL result = ::AcceptEx(o->socket_, o->new_socket_.get(), - o->output_buffer(), 0, o->address_length(), - o->address_length(), &bytes_read, o); - DWORD last_error = ::WSAGetLastError(); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - - // Check if the operation completed immediately. - if (!result && last_error != WSA_IO_PENDING) - { - if (last_error == ERROR_NETNAME_DELETED - || last_error == WSAECONNABORTED) - { - // Post this handler so that operation will be restarted again. - o->iocp_service_.work_started(); - o->iocp_service_.on_completion(o, ec); - ptr.release(); - return; - } - else - { - // Operation already complete. Continue with rest of this - // handler. - } - } - else - { - // Asynchronous operation has been successfully restarted. - o->iocp_service_.work_started(); - o->iocp_service_.on_pending(o); - ptr.release(); - return; - } - } - } - - // Get the address of the peer. - endpoint_type peer_endpoint; - if (!ec) - { - LPSOCKADDR local_addr = 0; - int local_addr_length = 0; - LPSOCKADDR remote_addr = 0; - int remote_addr_length = 0; - GetAcceptExSockaddrs(o->output_buffer(), 0, o->address_length(), - o->address_length(), &local_addr, &local_addr_length, - &remote_addr, &remote_addr_length); - if (static_cast<std::size_t>(remote_addr_length) - > peer_endpoint.capacity()) - { - ec = boost::asio::error::invalid_argument; - } - else - { - using namespace std; // For memcpy. - memcpy(peer_endpoint.data(), remote_addr, remote_addr_length); - peer_endpoint.resize(static_cast<std::size_t>(remote_addr_length)); - } - } - - // Need to set the SO_UPDATE_ACCEPT_CONTEXT option so that getsockname - // and getpeername will work on the accepted socket. - if (!ec) - { - SOCKET update_ctx_param = o->socket_; - socket_ops::setsockopt(o->new_socket_.get(), - SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, - &update_ctx_param, sizeof(SOCKET), ec); - } - - // If the socket was successfully accepted, transfer ownership of the - // socket to the peer object. - if (!ec) - { - o->peer_.assign(o->protocol_, - native_type(o->new_socket_.get(), peer_endpoint), ec); - if (!ec) - o->new_socket_.release(); - } - - // Pass endpoint back to caller. - if (o->peer_endpoint_) - *o->peer_endpoint_ = peer_endpoint; - - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder1<Handler, boost::system::error_code> - handler(o->handler_, ec); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - win_iocp_io_service& iocp_service_; - socket_type socket_; - socket_holder new_socket_; - Socket& peer_; - protocol_type protocol_; - endpoint_type* peer_endpoint_; - unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2]; - bool enable_connection_aborted_; - Handler handler_; - }; + return ec; + } // Start an asynchronous accept. The peer and peer_endpoint objects // must be valid until the accept's handler is invoked. @@ -1570,443 +408,55 @@ public: endpoint_type* peer_endpoint, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef accept_op<Socket, Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); + typedef win_iocp_socket_accept_op<Socket, protocol_type, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; bool enable_connection_aborted = - (impl.flags_ & implementation_type::enable_connection_aborted); - handler_ptr<alloc_traits> ptr(raw_ptr, iocp_service_, impl.socket_, peer, - impl.protocol_, peer_endpoint, enable_connection_aborted, handler); + (impl.state_ & socket_ops::enable_connection_aborted) != 0; + p.p = new (p.v) op(*this, impl.socket_, peer, impl.protocol_, + peer_endpoint, enable_connection_aborted, handler); - start_accept_op(impl, peer.is_open(), ptr.get()->new_socket(), - ptr.get()->output_buffer(), ptr.get()->address_length(), ptr.get()); - ptr.release(); + start_accept_op(impl, peer.is_open(), p.p->new_socket(), + impl.protocol_.family(), impl.protocol_.type(), + impl.protocol_.protocol(), p.p->output_buffer(), + p.p->address_length(), p.p); + p.v = p.p = 0; } // Connect the socket to the specified endpoint. boost::system::error_code connect(implementation_type& impl, const endpoint_type& peer_endpoint, boost::system::error_code& ec) { - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - // Perform the connect operation. - socket_ops::connect(impl.socket_, + socket_ops::sync_connect(impl.socket_, peer_endpoint.data(), peer_endpoint.size(), ec); return ec; } - class connect_op_base : public reactor_op - { - public: - connect_op_base(socket_type socket, func_type complete_func) - : reactor_op(&connect_op_base::do_perform, complete_func), - socket_(socket) - { - } - - static bool do_perform(reactor_op* base) - { - connect_op_base* o(static_cast<connect_op_base*>(base)); - - // Get the error code from the connect operation. - int connect_error = 0; - size_t connect_error_len = sizeof(connect_error); - if (socket_ops::getsockopt(o->socket_, SOL_SOCKET, SO_ERROR, - &connect_error, &connect_error_len, o->ec_) == socket_error_retval) - return true; - - // The connection failed so the handler will be posted with an error code. - if (connect_error) - { - o->ec_ = boost::system::error_code(connect_error, - boost::asio::error::get_system_category()); - } - - return true; - } - - private: - socket_type socket_; - }; - - template <typename Handler> - class connect_op : public connect_op_base - { - public: - connect_op(socket_type socket, Handler handler) - : connect_op_base(socket, &connect_op::do_complete), - handler_(handler) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - connect_op* o(static_cast<connect_op*>(base)); - typedef handler_alloc_traits<Handler, connect_op> alloc_traits; - handler_ptr<alloc_traits> ptr(o->handler_, o); - - // Make the upcall if required. - if (owner) - { - // Make a copy of the handler so that the memory can be deallocated - // before the upcall is made. Even if we're not about to make an - // upcall, a sub-object of the handler may be the true owner of the - // memory associated with the handler. Consequently, a local copy of - // the handler is required to ensure that any owning sub-object remains - // valid until after we have deallocated the memory here. - detail::binder1<Handler, boost::system::error_code> - handler(o->handler_, o->ec_); - ptr.reset(); - boost::asio::detail::fenced_block b; - boost_asio_handler_invoke_helpers::invoke(handler, handler); - } - } - - private: - Handler handler_; - }; - // Start an asynchronous connect. template <typename Handler> void async_connect(implementation_type& impl, const endpoint_type& peer_endpoint, Handler handler) { // Allocate and construct an operation to wrap the handler. - typedef connect_op<Handler> value_type; - typedef handler_alloc_traits<Handler, value_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, impl.socket_, handler); - - start_connect_op(impl, ptr.get(), peer_endpoint); - ptr.release(); - } - -private: - // Helper function to start an asynchronous send operation. - void start_send_op(implementation_type& impl, WSABUF* buffers, - std::size_t buffer_count, socket_base::message_flags flags, - bool noop, operation* op) - { - update_cancellation_thread_id(impl); - iocp_service_.work_started(); - - if (noop) - iocp_service_.on_completion(op); - else if (!is_open(impl)) - iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); - else - { - DWORD bytes_transferred = 0; - int result = ::WSASend(impl.socket_, buffers, - buffer_count, &bytes_transferred, flags, op, 0); - DWORD last_error = ::WSAGetLastError(); - if (last_error == ERROR_PORT_UNREACHABLE) - last_error = WSAECONNREFUSED; - if (result != 0 && last_error != WSA_IO_PENDING) - iocp_service_.on_completion(op, last_error, bytes_transferred); - else - iocp_service_.on_pending(op); - } - } - - // Helper function to start an asynchronous send_to operation. - void start_send_to_op(implementation_type& impl, WSABUF* buffers, - std::size_t buffer_count, const endpoint_type& destination, - socket_base::message_flags flags, operation* op) - { - update_cancellation_thread_id(impl); - iocp_service_.work_started(); + typedef reactive_socket_connect_op<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, handler); - if (!is_open(impl)) - iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); - else - { - DWORD bytes_transferred = 0; - int result = ::WSASendTo(impl.socket_, buffers, buffer_count, - &bytes_transferred, flags, destination.data(), - static_cast<int>(destination.size()), op, 0); - DWORD last_error = ::WSAGetLastError(); - if (last_error == ERROR_PORT_UNREACHABLE) - last_error = WSAECONNREFUSED; - if (result != 0 && last_error != WSA_IO_PENDING) - iocp_service_.on_completion(op, last_error, bytes_transferred); - else - iocp_service_.on_pending(op); - } + start_connect_op(impl, p.p, peer_endpoint.data(), + static_cast<int>(peer_endpoint.size())); + p.v = p.p = 0; } - - // Helper function to start an asynchronous receive operation. - void start_receive_op(implementation_type& impl, WSABUF* buffers, - std::size_t buffer_count, socket_base::message_flags flags, - bool noop, operation* op) - { - update_cancellation_thread_id(impl); - iocp_service_.work_started(); - - if (noop) - iocp_service_.on_completion(op); - else if (!is_open(impl)) - iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); - else - { - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = ::WSARecv(impl.socket_, buffers, buffer_count, - &bytes_transferred, &recv_flags, op, 0); - DWORD last_error = ::WSAGetLastError(); - if (last_error == ERROR_NETNAME_DELETED) - last_error = WSAECONNRESET; - else if (last_error == ERROR_PORT_UNREACHABLE) - last_error = WSAECONNREFUSED; - if (result != 0 && last_error != WSA_IO_PENDING) - iocp_service_.on_completion(op, last_error, bytes_transferred); - else - iocp_service_.on_pending(op); - } - } - - // Helper function to start an asynchronous receive_from operation. - void start_receive_from_op(implementation_type& impl, WSABUF* buffers, - std::size_t buffer_count, endpoint_type& sender_endpoint, - socket_base::message_flags flags, int* endpoint_size, operation* op) - { - update_cancellation_thread_id(impl); - iocp_service_.work_started(); - - if (!is_open(impl)) - iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); - else - { - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = ::WSARecvFrom(impl.socket_, buffers, - buffer_count, &bytes_transferred, &recv_flags, - sender_endpoint.data(), endpoint_size, op, 0); - DWORD last_error = ::WSAGetLastError(); - if (last_error == ERROR_PORT_UNREACHABLE) - last_error = WSAECONNREFUSED; - if (result != 0 && last_error != WSA_IO_PENDING) - iocp_service_.on_completion(op, last_error, bytes_transferred); - else - iocp_service_.on_pending(op); - } - } - - // Helper function to start an asynchronous receive_from operation. - void start_accept_op(implementation_type& impl, - bool peer_is_open, socket_holder& new_socket, - void* output_buffer, DWORD address_length, operation* op) - { - update_cancellation_thread_id(impl); - iocp_service_.work_started(); - - if (!is_open(impl)) - iocp_service_.on_completion(op, boost::asio::error::bad_descriptor); - else if (peer_is_open) - iocp_service_.on_completion(op, boost::asio::error::already_open); - else - { - boost::system::error_code ec; - new_socket.reset(socket_ops::socket(impl.protocol_.family(), - impl.protocol_.type(), impl.protocol_.protocol(), ec)); - if (new_socket.get() == invalid_socket) - iocp_service_.on_completion(op, ec); - else - { - DWORD bytes_read = 0; - BOOL result = ::AcceptEx(impl.socket_, new_socket.get(), output_buffer, - 0, address_length, address_length, &bytes_read, op); - DWORD last_error = ::WSAGetLastError(); - if (!result && last_error != WSA_IO_PENDING) - iocp_service_.on_completion(op, last_error); - else - iocp_service_.on_pending(op); - } - } - } - - // Start an asynchronous read or write operation using the the reactor. - void start_reactor_op(implementation_type& impl, int op_type, reactor_op* op) - { - reactor& r = get_reactor(); - update_cancellation_thread_id(impl); - - if (is_open(impl)) - { - r.start_op(op_type, impl.socket_, impl.reactor_data_, op, false); - return; - } - else - op->ec_ = boost::asio::error::bad_descriptor; - - iocp_service_.post_immediate_completion(op); - } - - // Start the asynchronous connect operation using the reactor. - void start_connect_op(implementation_type& impl, - reactor_op* op, const endpoint_type& peer_endpoint) - { - reactor& r = get_reactor(); - update_cancellation_thread_id(impl); - - if (is_open(impl)) - { - ioctl_arg_type non_blocking = 1; - if (!socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, op->ec_)) - { - if (socket_ops::connect(impl.socket_, peer_endpoint.data(), - peer_endpoint.size(), op->ec_) != 0) - { - if (!op->ec_ - && !(impl.flags_ & implementation_type::user_set_non_blocking)) - { - non_blocking = 0; - socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, op->ec_); - } - - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - r.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, true); - return; - } - } - } - } - else - op->ec_ = boost::asio::error::bad_descriptor; - - iocp_service_.post_immediate_completion(op); - } - - // Helper function to close a socket when the associated object is being - // destroyed. - void close_for_destruction(implementation_type& impl) - { - if (is_open(impl)) - { - // Check if the reactor was created, in which case we need to close the - // socket on the reactor as well to cancel any operations that might be - // running there. - reactor* r = static_cast<reactor*>( - interlocked_compare_exchange_pointer( - reinterpret_cast<void**>(&reactor_), 0, 0)); - if (r) - r->close_descriptor(impl.socket_, impl.reactor_data_); - - // The socket destructor must not block. If the user has changed the - // linger option to block in the foreground, we will change it back to the - // default so that the closure is performed in the background. - if (impl.flags_ & implementation_type::close_might_block) - { - ::linger opt; - opt.l_onoff = 0; - opt.l_linger = 0; - boost::system::error_code ignored_ec; - socket_ops::setsockopt(impl.socket_, - SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec); - } - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, ignored_ec); - impl.socket_ = invalid_socket; - impl.flags_ = 0; - impl.cancel_token_.reset(); -#if defined(BOOST_ASIO_ENABLE_CANCELIO) - impl.safe_cancellation_thread_id_ = 0; -#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) - } - } - - // Update the ID of the thread from which cancellation is safe. - void update_cancellation_thread_id(implementation_type& impl) - { -#if defined(BOOST_ASIO_ENABLE_CANCELIO) - if (impl.safe_cancellation_thread_id_ == 0) - impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); - else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) - impl.safe_cancellation_thread_id_ = ~DWORD(0); -#else // defined(BOOST_ASIO_ENABLE_CANCELIO) - (void)impl; -#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) - } - - // Helper function to get the reactor. If no reactor has been created yet, a - // new one is obtained from the io_service and a pointer to it is cached in - // this service. - reactor& get_reactor() - { - reactor* r = static_cast<reactor*>( - interlocked_compare_exchange_pointer( - reinterpret_cast<void**>(&reactor_), 0, 0)); - if (!r) - { - r = &(use_service<reactor>(io_service_)); - interlocked_exchange_pointer(reinterpret_cast<void**>(&reactor_), r); - } - return *r; - } - - // Helper function to emulate InterlockedCompareExchangePointer functionality - // for: - // - very old Platform SDKs; and - // - platform SDKs where MSVC's /Wp64 option causes spurious warnings. - void* interlocked_compare_exchange_pointer(void** dest, void* exch, void* cmp) - { -#if defined(_M_IX86) - return reinterpret_cast<void*>(InterlockedCompareExchange( - reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(exch), - reinterpret_cast<LONG>(cmp))); -#else - return InterlockedCompareExchangePointer(dest, exch, cmp); -#endif - } - - // Helper function to emulate InterlockedExchangePointer functionality for: - // - very old Platform SDKs; and - // - platform SDKs where MSVC's /Wp64 option causes spurious warnings. - void* interlocked_exchange_pointer(void** dest, void* val) - { -#if defined(_M_IX86) - return reinterpret_cast<void*>(InterlockedExchange( - reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(val))); -#else - return InterlockedExchangePointer(dest, val); -#endif - } - - // The io_service used to obtain the reactor, if required. - boost::asio::io_service& io_service_; - - // The IOCP service used for running asynchronous operations and dispatching - // handlers. - win_iocp_io_service& iocp_service_; - - // The reactor used for performing connect operations. This object is created - // only if needed. - reactor* reactor_; - - // Mutex to protect access to the linked list of implementations. - boost::asio::detail::mutex mutex_; - - // The head of a linked list of all implementations. - implementation_type* impl_list_; }; } // namespace detail } // namespace asio } // namespace boost -#endif // defined(BOOST_ASIO_HAS_IOCP) - #include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_ASIO_HAS_IOCP) + #endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_service_base.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_service_base.hpp new file mode 100644 index 0000000..2dd3ba3 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_socket_service_base.hpp @@ -0,0 +1,387 @@ +// +// detail/win_iocp_socket_service_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_BASE_HPP +#define BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) + +#include <boost/type_traits/is_same.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/socket_base.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/fenced_block.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/mutex.hpp> +#include <boost/asio/detail/operation.hpp> +#include <boost/asio/detail/reactor.hpp> +#include <boost/asio/detail/reactor_op.hpp> +#include <boost/asio/detail/socket_holder.hpp> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/win_iocp_io_service.hpp> +#include <boost/asio/detail/win_iocp_null_buffers_op.hpp> +#include <boost/asio/detail/win_iocp_socket_send_op.hpp> +#include <boost/asio/detail/win_iocp_socket_recv_op.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +class win_iocp_socket_service_base +{ +public: + // The implementation type of the socket. + struct base_implementation_type + { + // The native socket representation. + socket_type socket_; + + // The current state of the socket. + socket_ops::state_type state_; + + // We use a shared pointer as a cancellation token here to work around the + // broken Windows support for cancellation. MSDN says that when you call + // closesocket any outstanding WSARecv or WSASend operations will complete + // with the error ERROR_OPERATION_ABORTED. In practice they complete with + // ERROR_NETNAME_DELETED, which means you can't tell the difference between + // a local cancellation and the socket being hard-closed by the peer. + socket_ops::shared_cancel_token_type cancel_token_; + + // Per-descriptor data used by the reactor. + reactor::per_descriptor_data reactor_data_; + +#if defined(BOOST_ASIO_ENABLE_CANCELIO) + // The ID of the thread from which it is safe to cancel asynchronous + // operations. 0 means no asynchronous operations have been started yet. + // ~0 means asynchronous operations have been started from more than one + // thread, and cancellation is not supported for the socket. + DWORD safe_cancellation_thread_id_; +#endif // defined(BOOST_ASIO_ENABLE_CANCELIO) + + // Pointers to adjacent socket implementations in linked list. + base_implementation_type* next_; + base_implementation_type* prev_; + }; + + // Constructor. + BOOST_ASIO_DECL win_iocp_socket_service_base( + boost::asio::io_service& io_service); + + // Destroy all user-defined handler objects owned by the service. + BOOST_ASIO_DECL void shutdown_service(); + + // Construct a new socket implementation. + BOOST_ASIO_DECL void construct(base_implementation_type& impl); + + // Destroy a socket implementation. + BOOST_ASIO_DECL void destroy(base_implementation_type& impl); + + // Determine whether the socket is open. + bool is_open(const base_implementation_type& impl) const + { + return impl.socket_ != invalid_socket; + } + + // Destroy a socket implementation. + BOOST_ASIO_DECL boost::system::error_code close( + base_implementation_type& impl, boost::system::error_code& ec); + + // Cancel all operations associated with the socket. + BOOST_ASIO_DECL boost::system::error_code cancel( + base_implementation_type& impl, boost::system::error_code& ec); + + // Determine whether the socket is at the out-of-band data mark. + bool at_mark(const base_implementation_type& impl, + boost::system::error_code& ec) const + { + return socket_ops::sockatmark(impl.socket_, ec); + } + + // Determine the number of bytes available for reading. + std::size_t available(const base_implementation_type& impl, + boost::system::error_code& ec) const + { + return socket_ops::available(impl.socket_, ec); + } + + // Place the socket into the state where it will listen for new connections. + boost::system::error_code listen(base_implementation_type& impl, + int backlog, boost::system::error_code& ec) + { + socket_ops::listen(impl.socket_, backlog, ec); + return ec; + } + + // Perform an IO control command on the socket. + template <typename IO_Control_Command> + boost::system::error_code io_control(base_implementation_type& impl, + IO_Control_Command& command, boost::system::error_code& ec) + { + socket_ops::ioctl(impl.socket_, impl.state_, command.name(), + static_cast<ioctl_arg_type*>(command.data()), ec); + return ec; + } + + /// Disable sends or receives on the socket. + boost::system::error_code shutdown(base_implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) + { + socket_ops::shutdown(impl.socket_, what, ec); + return ec; + } + + // Send the given data to the peer. Returns the number of bytes sent. + template <typename ConstBufferSequence> + size_t send(base_implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + buffer_sequence_adapter<boost::asio::const_buffer, + ConstBufferSequence> bufs(buffers); + + return socket_ops::sync_send(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); + } + + // Wait until data can be sent without blocking. + size_t send(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags, boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_write(impl.socket_, ec); + + return 0; + } + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template <typename ConstBufferSequence, typename Handler> + void async_send(base_implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_socket_send_op<ConstBufferSequence, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, buffers, handler); + + buffer_sequence_adapter<boost::asio::const_buffer, + ConstBufferSequence> bufs(buffers); + + start_send_op(impl, bufs.buffers(), bufs.count(), flags, + (impl.state_ & socket_ops::stream_oriented) != 0 && bufs.all_empty(), + p.p); + p.v = p.p = 0; + } + + // Start an asynchronous wait until data can be sent without blocking. + template <typename Handler> + void async_send(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_null_buffers_op<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, handler); + + start_reactor_op(impl, reactor::write_op, p.p); + p.v = p.p = 0; + } + + // Receive some data from the peer. Returns the number of bytes received. + template <typename MutableBufferSequence> + size_t receive(base_implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + buffer_sequence_adapter<boost::asio::mutable_buffer, + MutableBufferSequence> bufs(buffers); + + return socket_ops::sync_recv(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); + } + + // Wait until data can be received without blocking. + size_t receive(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags, boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_read(impl.socket_, ec); + + return 0; + } + + // Start an asynchronous receive. The buffer for the data being received + // must be valid for the lifetime of the asynchronous operation. + template <typename MutableBufferSequence, typename Handler> + void async_receive(base_implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_socket_recv_op<MutableBufferSequence, Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.state_, impl.cancel_token_, buffers, handler); + + buffer_sequence_adapter<boost::asio::mutable_buffer, + MutableBufferSequence> bufs(buffers); + + start_receive_op(impl, bufs.buffers(), bufs.count(), flags, + (impl.state_ & socket_ops::stream_oriented) != 0 && bufs.all_empty(), + p.p); + p.v = p.p = 0; + } + + // Wait until data can be received without blocking. + template <typename Handler> + void async_receive(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags flags, Handler handler) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_null_buffers_op<Handler> op; + typename op::ptr p = { boost::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.cancel_token_, handler); + + start_null_buffers_receive_op(impl, flags, p.p); + p.v = p.p = 0; + } + + // Helper function to restart an asynchronous accept operation. + BOOST_ASIO_DECL void restart_accept_op(socket_type s, + socket_holder& new_socket, int family, int type, int protocol, + void* output_buffer, DWORD address_length, operation* op); + +protected: + // Open a new socket implementation. + BOOST_ASIO_DECL boost::system::error_code do_open( + base_implementation_type& impl, int family, int type, + int protocol, boost::system::error_code& ec); + + // Assign a native socket to a socket implementation. + BOOST_ASIO_DECL boost::system::error_code do_assign( + base_implementation_type& impl, int type, + socket_type native_socket, boost::system::error_code& ec); + + // Helper function to start an asynchronous send operation. + BOOST_ASIO_DECL void start_send_op(base_implementation_type& impl, + WSABUF* buffers, std::size_t buffer_count, + socket_base::message_flags flags, bool noop, operation* op); + + // Helper function to start an asynchronous send_to operation. + BOOST_ASIO_DECL void start_send_to_op(base_implementation_type& impl, + WSABUF* buffers, std::size_t buffer_count, + const socket_addr_type* addr, int addrlen, + socket_base::message_flags flags, operation* op); + + // Helper function to start an asynchronous receive operation. + BOOST_ASIO_DECL void start_receive_op(base_implementation_type& impl, + WSABUF* buffers, std::size_t buffer_count, + socket_base::message_flags flags, bool noop, operation* op); + + // Helper function to start an asynchronous null_buffers receive operation. + BOOST_ASIO_DECL void start_null_buffers_receive_op( + base_implementation_type& impl, + socket_base::message_flags flags, reactor_op* op); + + // Helper function to start an asynchronous receive_from operation. + BOOST_ASIO_DECL void start_receive_from_op(base_implementation_type& impl, + WSABUF* buffers, std::size_t buffer_count, socket_addr_type* addr, + socket_base::message_flags flags, int* addrlen, operation* op); + + // Helper function to start an asynchronous accept operation. + BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, + bool peer_is_open, socket_holder& new_socket, int family, int type, + int protocol, void* output_buffer, DWORD address_length, operation* op); + + // Start an asynchronous read or write operation using the the reactor. + BOOST_ASIO_DECL void start_reactor_op(base_implementation_type& impl, + int op_type, reactor_op* op); + + // Start the asynchronous connect operation using the reactor. + BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, + reactor_op* op, const socket_addr_type* addr, std::size_t addrlen); + + // Helper function to close a socket when the associated object is being + // destroyed. + BOOST_ASIO_DECL void close_for_destruction(base_implementation_type& impl); + + // Update the ID of the thread from which cancellation is safe. + BOOST_ASIO_DECL void update_cancellation_thread_id( + base_implementation_type& impl); + + // Helper function to get the reactor. If no reactor has been created yet, a + // new one is obtained from the io_service and a pointer to it is cached in + // this service. + BOOST_ASIO_DECL reactor& get_reactor(); + + // Helper function to emulate InterlockedCompareExchangePointer functionality + // for: + // - very old Platform SDKs; and + // - platform SDKs where MSVC's /Wp64 option causes spurious warnings. + BOOST_ASIO_DECL void* interlocked_compare_exchange_pointer( + void** dest, void* exch, void* cmp); + + // Helper function to emulate InterlockedExchangePointer functionality for: + // - very old Platform SDKs; and + // - platform SDKs where MSVC's /Wp64 option causes spurious warnings. + BOOST_ASIO_DECL void* interlocked_exchange_pointer(void** dest, void* val); + + // The io_service used to obtain the reactor, if required. + boost::asio::io_service& io_service_; + + // The IOCP service used for running asynchronous operations and dispatching + // handlers. + win_iocp_io_service& iocp_service_; + + // The reactor used for performing connect operations. This object is created + // only if needed. + reactor* reactor_; + + // Mutex to protect access to the linked list of implementations. + boost::asio::detail::mutex mutex_; + + // The head of a linked list of all implementations. + base_implementation_type* impl_list_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/win_iocp_socket_service_base.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_BASE_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_mutex.hpp b/3rdParty/Boost/src/boost/asio/detail/win_mutex.hpp index 176a5fd..3f6dadb 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_mutex.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_mutex.hpp @@ -1,6 +1,6 @@ // -// win_mutex.hpp -// ~~~~~~~~~~~~~ +// detail/win_mutex.hpp +// ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,23 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_WINDOWS) -#include <boost/asio/error.hpp> #include <boost/asio/detail/noncopyable.hpp> -#include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/scoped_lock.hpp> +#include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/push_options.hpp> -#include <boost/throw_exception.hpp> -#include <boost/asio/detail/pop_options.hpp> namespace boost { namespace asio { @@ -44,18 +36,7 @@ public: typedef boost::asio::detail::scoped_lock<win_mutex> scoped_lock; // Constructor. - win_mutex() - { - int error = do_init(); - if (error != 0) - { - boost::system::system_error e( - boost::system::error_code(error, - boost::asio::error::get_system_category()), - "mutex"); - boost::throw_exception(e); - } - } + BOOST_ASIO_DECL win_mutex(); // Destructor. ~win_mutex() @@ -79,35 +60,7 @@ private: // Initialisation must be performed in a separate function to the constructor // since the compiler does not support the use of structured exceptions and // C++ exceptions in the same function. - int do_init() - { -#if defined(__MINGW32__) - // Not sure if MinGW supports structured exception handling, so for now - // we'll just call the Windows API and hope. -# if defined(UNDER_CE) - ::InitializeCriticalSection(&crit_section_); -# else - ::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000); -# endif - return 0; -#else - __try - { -# if defined(UNDER_CE) - ::InitializeCriticalSection(&crit_section_); -# else - ::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000); -# endif - } - __except(GetExceptionCode() == STATUS_NO_MEMORY - ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { - return ERROR_OUTOFMEMORY; - } - - return 0; -#endif - } + BOOST_ASIO_DECL int do_init(); ::CRITICAL_SECTION crit_section_; }; @@ -116,8 +69,12 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_WINDOWS) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/win_mutex.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_WINDOWS) + #endif // BOOST_ASIO_DETAIL_WIN_MUTEX_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_signal_blocker.hpp b/3rdParty/Boost/src/boost/asio/detail/win_signal_blocker.hpp deleted file mode 100644 index 6d70a16..0000000 --- a/3rdParty/Boost/src/boost/asio/detail/win_signal_blocker.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// win_signal_blocker.hpp -// ~~~~~~~~~~~~~~~~~~~~~~ -// -// 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) -// - -#ifndef BOOST_ASIO_DETAIL_WIN_SIGNAL_BLOCKER_HPP -#define BOOST_ASIO_DETAIL_WIN_SIGNAL_BLOCKER_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - -#include <boost/asio/detail/noncopyable.hpp> - -namespace boost { -namespace asio { -namespace detail { - -class win_signal_blocker - : private noncopyable -{ -public: - // Constructor blocks all signals for the calling thread. - win_signal_blocker() - { - // No-op. - } - - // Destructor restores the previous signal mask. - ~win_signal_blocker() - { - // No-op. - } - - // Block all signals for the calling thread. - void block() - { - // No-op. - } - - // Restore the previous signal mask. - void unblock() - { - // No-op. - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - -#include <boost/asio/detail/pop_options.hpp> - -#endif // BOOST_ASIO_DETAIL_WIN_SIGNAL_BLOCKER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_thread.hpp b/3rdParty/Boost/src/boost/asio/detail/win_thread.hpp index 61c9b8a..cba546f 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_thread.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_thread.hpp @@ -1,6 +1,6 @@ // -// win_thread.hpp -// ~~~~~~~~~~~~~~ +// detail/win_thread.hpp +// ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,35 +15,25 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_WINDOWS) && !defined(UNDER_CE) -#include <boost/asio/error.hpp> #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/push_options.hpp> -#include <boost/throw_exception.hpp> -#include <memory> -#include <process.h> -#include <boost/asio/detail/pop_options.hpp> namespace boost { namespace asio { namespace detail { -unsigned int __stdcall win_thread_function(void* arg); +BOOST_ASIO_DECL unsigned int __stdcall win_thread_function(void* arg); #if defined(WINVER) && (WINVER < 0x0500) -void __stdcall apc_function(ULONG data); +BOOST_ASIO_DECL void __stdcall apc_function(ULONG data); #else -void __stdcall apc_function(ULONG_PTR data); +BOOST_ASIO_DECL void __stdcall apc_function(ULONG_PTR data); #endif template <typename T> @@ -74,92 +64,26 @@ class win_thread public: // Constructor. template <typename Function> - win_thread(Function f) - : exit_event_(0) + win_thread(Function f, unsigned int stack_size = 0) + : thread_(0), + exit_event_(0) { - std::auto_ptr<func_base> arg(new func<Function>(f)); - - ::HANDLE entry_event = 0; - arg->entry_event_ = entry_event = ::CreateEvent(0, true, false, 0); - if (!entry_event) - { - DWORD last_error = ::GetLastError(); - boost::system::system_error e( - boost::system::error_code(last_error, - boost::asio::error::get_system_category()), - "thread.entry_event"); - boost::throw_exception(e); - } - - arg->exit_event_ = exit_event_ = ::CreateEvent(0, true, false, 0); - if (!exit_event_) - { - DWORD last_error = ::GetLastError(); - ::CloseHandle(entry_event); - boost::system::system_error e( - boost::system::error_code(last_error, - boost::asio::error::get_system_category()), - "thread.exit_event"); - boost::throw_exception(e); - } - - unsigned int thread_id = 0; - thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0, 0, - win_thread_function, arg.get(), 0, &thread_id)); - if (!thread_) - { - DWORD last_error = ::GetLastError(); - if (entry_event) - ::CloseHandle(entry_event); - if (exit_event_) - ::CloseHandle(exit_event_); - boost::system::system_error e( - boost::system::error_code(last_error, - boost::asio::error::get_system_category()), - "thread"); - boost::throw_exception(e); - } - arg.release(); - - if (entry_event) - { - ::WaitForSingleObject(entry_event, INFINITE); - ::CloseHandle(entry_event); - } + start_thread(new func<Function>(f), stack_size); } // Destructor. - ~win_thread() - { - ::CloseHandle(thread_); - - // The exit_event_ handle is deliberately allowed to leak here since it - // is an error for the owner of an internal thread not to join() it. - } + BOOST_ASIO_DECL ~win_thread(); // Wait for the thread to exit. - void join() - { - ::WaitForSingleObject(exit_event_, INFINITE); - ::CloseHandle(exit_event_); - if (terminate_threads()) - { - ::TerminateThread(thread_, 0); - } - else - { - ::QueueUserAPC(apc_function, thread_, 0); - ::WaitForSingleObject(thread_, INFINITE); - } - } + BOOST_ASIO_DECL void join(); private: - friend unsigned int __stdcall win_thread_function(void* arg); + friend BOOST_ASIO_DECL unsigned int __stdcall win_thread_function(void* arg); #if defined(WINVER) && (WINVER < 0x0500) - friend void __stdcall apc_function(ULONG); + friend BOOST_ASIO_DECL void __stdcall apc_function(ULONG); #else - friend void __stdcall apc_function(ULONG_PTR); + friend BOOST_ASIO_DECL void __stdcall apc_function(ULONG_PTR); #endif class func_base @@ -171,6 +95,12 @@ private: ::HANDLE exit_event_; }; + struct auto_func_base_ptr + { + func_base* ptr; + ~auto_func_base_ptr() { delete ptr; } + }; + template <typename Function> class func : public func_base @@ -190,45 +120,22 @@ private: Function f_; }; + BOOST_ASIO_DECL void start_thread(func_base* arg, unsigned int stack_size); + ::HANDLE thread_; ::HANDLE exit_event_; }; -inline unsigned int __stdcall win_thread_function(void* arg) -{ - std::auto_ptr<win_thread::func_base> func( - static_cast<win_thread::func_base*>(arg)); - - ::SetEvent(func->entry_event_); - - func->run(); - - // Signal that the thread has finished its work, but rather than returning go - // to sleep to put the thread into a well known state. If the thread is being - // joined during global object destruction then it may be killed using - // TerminateThread (to avoid a deadlock in DllMain). Otherwise, the SleepEx - // call will be interrupted using QueueUserAPC and the thread will shut down - // cleanly. - HANDLE exit_event = func->exit_event_; - func.reset(); - ::SetEvent(exit_event); - ::SleepEx(INFINITE, TRUE); - - return 0; -} - -#if defined(WINVER) && (WINVER < 0x0500) -inline void __stdcall apc_function(ULONG) {} -#else -inline void __stdcall apc_function(ULONG_PTR) {} -#endif - } // namespace detail } // namespace asio } // namespace boost -#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/win_thread.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE) + #endif // BOOST_ASIO_DETAIL_WIN_THREAD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/win_tss_ptr.hpp b/3rdParty/Boost/src/boost/asio/detail/win_tss_ptr.hpp index fa04613..2c5ee3b 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_tss_ptr.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_tss_ptr.hpp @@ -1,6 +1,6 @@ // -// win_tss_ptr.hpp -// ~~~~~~~~~~~~~~~ +// detail/win_tss_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,51 +15,31 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_WINDOWS) -#include <boost/asio/error.hpp> #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/push_options.hpp> -#include <boost/throw_exception.hpp> -#include <boost/asio/detail/pop_options.hpp> namespace boost { namespace asio { namespace detail { +// Helper function to create thread-specific storage. +BOOST_ASIO_DECL DWORD win_tss_ptr_create(); + template <typename T> class win_tss_ptr : private noncopyable { public: -#if defined(UNDER_CE) - enum { out_of_indexes = 0xFFFFFFFF }; -#else - enum { out_of_indexes = TLS_OUT_OF_INDEXES }; -#endif - // Constructor. win_tss_ptr() + : tss_key_(win_tss_ptr_create()) { - tss_key_ = ::TlsAlloc(); - if (tss_key_ == out_of_indexes) - { - DWORD last_error = ::GetLastError(); - boost::system::system_error e( - boost::system::error_code(last_error, - boost::asio::error::get_system_category()), - "tss"); - boost::throw_exception(e); - } } // Destructor. @@ -90,8 +70,12 @@ private: } // namespace asio } // namespace boost -#endif // defined(BOOST_WINDOWS) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/win_tss_ptr.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_WINDOWS) + #endif // BOOST_ASIO_DETAIL_WIN_TSS_PTR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/wince_thread.hpp b/3rdParty/Boost/src/boost/asio/detail/wince_thread.hpp index 1cb9a7a..82ca544 100644 --- a/3rdParty/Boost/src/boost/asio/detail/wince_thread.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/wince_thread.hpp @@ -1,6 +1,6 @@ // -// wince_thread.hpp -// ~~~~~~~~~~~~~~~~ +// detail/wince_thread.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,23 +15,17 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_WINDOWS) && defined(UNDER_CE) -#include <boost/asio/error.hpp> +#include <memory> #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> #include <boost/asio/detail/push_options.hpp> -#include <boost/throw_exception.hpp> -#include <memory> -#include <boost/asio/detail/pop_options.hpp> namespace boost { namespace asio { @@ -54,11 +48,9 @@ public: if (!thread_) { DWORD last_error = ::GetLastError(); - boost::system::system_error e( - boost::system::error_code(last_error, - boost::asio::error::get_system_category()), - "thread"); - boost::throw_exception(e); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "thread"); } arg.release(); } @@ -119,8 +111,8 @@ inline DWORD WINAPI wince_thread_function(LPVOID arg) } // namespace asio } // namespace boost -#endif // defined(BOOST_WINDOWS) && defined(UNDER_CE) - #include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_WINDOWS) && defined(UNDER_CE) + #endif // BOOST_ASIO_DETAIL_WINCE_THREAD_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/winsock_init.hpp b/3rdParty/Boost/src/boost/asio/detail/winsock_init.hpp index 186a8b5..ac24b0d 100644 --- a/3rdParty/Boost/src/boost/asio/detail/winsock_init.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/winsock_init.hpp @@ -1,6 +1,6 @@ // -// winsock_init.hpp -// ~~~~~~~~~~~~~~~~ +// detail/winsock_init.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,108 +15,78 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) #include <boost/asio/detail/push_options.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/throw_exception.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> -#include <boost/asio/detail/noncopyable.hpp> -#include <boost/asio/detail/socket_types.hpp> namespace boost { namespace asio { namespace detail { -template <int Major = 2, int Minor = 0> -class winsock_init - : private noncopyable +class winsock_init_base { -private: - // Structure to perform the actual initialisation. - struct do_init +protected: + // Structure to track result of initialisation and number of uses. POD is used + // to ensure that the values are zero-initialised prior to any code being run. + struct data { - do_init() - { - WSADATA wsa_data; - result_ = ::WSAStartup(MAKEWORD(Major, Minor), &wsa_data); - } - - ~do_init() - { - ::WSACleanup(); - } - - int result() const - { - return result_; - } - - // Helper function to manage a do_init singleton. The static instance of the - // winsock_init object ensures that this function is always called before - // main, and therefore before any other threads can get started. The do_init - // instance must be static in this function to ensure that it gets - // initialised before any other global objects try to use it. - static boost::shared_ptr<do_init> instance() - { - static boost::shared_ptr<do_init> init(new do_init); - return init; - } - - private: - int result_; + long init_count_; + long result_; }; + BOOST_ASIO_DECL static void startup(data& d, + unsigned char major, unsigned char minor); + + BOOST_ASIO_DECL static void cleanup(data& d); + + BOOST_ASIO_DECL static void throw_on_error(data& d); +}; + +template <int Major = 2, int Minor = 0> +class winsock_init : private winsock_init_base +{ public: - // Constructor. - winsock_init() - : ref_(do_init::instance()) + winsock_init(bool allow_throw = true) + { + startup(data_, Major, Minor); + if (allow_throw) + throw_on_error(data_); + } + + winsock_init(const winsock_init&) { - // Check whether winsock was successfully initialised. This check is not - // performed for the global instance since there will be nobody around to - // catch the exception. - if (this != &instance_ && ref_->result() != 0) - { - boost::system::system_error e( - boost::system::error_code(ref_->result(), - boost::asio::error::get_system_category()), - "winsock"); - boost::throw_exception(e); - } + startup(data_, Major, Minor); + throw_on_error(data_); } - // Destructor. ~winsock_init() { + cleanup(data_); } private: - // Instance to force initialisation of winsock at global scope. - static winsock_init instance_; - - // Reference to singleton do_init object to ensure that winsock does not get - // cleaned up until the last user has finished with it. - boost::shared_ptr<do_init> ref_; + static data data_; }; template <int Major, int Minor> -winsock_init<Major, Minor> winsock_init<Major, Minor>::instance_; +winsock_init_base::data winsock_init<Major, Minor>::data_; + +// Static variable to ensure that winsock is initialised before main, and +// therefore before any other threads can get started. +static const winsock_init<>& winsock_init_instance = winsock_init<>(false); } // namespace detail } // namespace asio } // namespace boost -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/winsock_init.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + #endif // BOOST_ASIO_DETAIL_WINSOCK_INIT_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/wrapped_handler.hpp b/3rdParty/Boost/src/boost/asio/detail/wrapped_handler.hpp index 8f2f625..9645b64 100644 --- a/3rdParty/Boost/src/boost/asio/detail/wrapped_handler.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/wrapped_handler.hpp @@ -1,6 +1,6 @@ // -// wrapped_handler.hpp -// ~~~~~~~~~~~~~~~~~~~ +// detail/wrapped_handler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/type_traits/add_reference.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace detail { @@ -35,9 +31,7 @@ class wrapped_handler public: typedef void result_type; - wrapped_handler( - typename boost::add_reference<Dispatcher>::type dispatcher, - Handler handler) + wrapped_handler(Dispatcher dispatcher, Handler handler) : dispatcher_(dispatcher), handler_(handler) { diff --git a/3rdParty/Boost/src/boost/asio/error.hpp b/3rdParty/Boost/src/boost/asio/error.hpp index 0dcb3dc..569ad80 100644 --- a/3rdParty/Boost/src/boost/asio/error.hpp +++ b/3rdParty/Boost/src/boost/asio/error.hpp @@ -15,15 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/cerrno.hpp> #include <boost/system/error_code.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/detail/socket_types.hpp> +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# include <winerror.h> +#else +# include <cerrno> +# include <netdb.h> +#endif #if defined(GENERATING_DOCUMENTATION) /// INTERNAL ONLY. @@ -50,6 +50,8 @@ # define BOOST_ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix #endif +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace error { @@ -215,70 +217,16 @@ enum ssl_errors inline const boost::system::error_category& get_system_category() { - return boost::system::get_system_category(); + return boost::system::system_category(); } #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) -namespace detail { - -class netdb_category : public boost::system::error_category -{ -public: - const char* name() const - { - return "asio.netdb"; - } - - std::string message(int value) const - { - if (value == error::host_not_found) - return "Host not found (authoritative)"; - if (value == error::host_not_found_try_again) - return "Host not found (non-authoritative), try again later"; - if (value == error::no_data) - return "The query is valid, but it does not have associated data"; - if (value == error::no_recovery) - return "A non-recoverable error occurred during database lookup"; - return "asio.netdb error"; - } -}; - -} // namespace detail - -inline const boost::system::error_category& get_netdb_category() -{ - static detail::netdb_category instance; - return instance; -} +extern BOOST_ASIO_DECL +const boost::system::error_category& get_netdb_category(); -namespace detail { - -class addrinfo_category : public boost::system::error_category -{ -public: - const char* name() const - { - return "asio.addrinfo"; - } - - std::string message(int value) const - { - if (value == error::service_not_found) - return "Service not found"; - if (value == error::socket_type_not_supported) - return "Socket type not supported"; - return "asio.addrinfo error"; - } -}; - -} // namespace detail - -inline const boost::system::error_category& get_addrinfo_category() -{ - static detail::addrinfo_category instance; - return instance; -} +extern BOOST_ASIO_DECL +const boost::system::error_category& get_addrinfo_category(); #else // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) @@ -294,61 +242,11 @@ inline const boost::system::error_category& get_addrinfo_category() #endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) -namespace detail { - -class misc_category : public boost::system::error_category -{ -public: - const char* name() const - { - return "asio.misc"; - } - - std::string message(int value) const - { - if (value == error::already_open) - return "Already open"; - if (value == error::eof) - return "End of file"; - if (value == error::not_found) - return "Element not found"; - if (value == error::fd_set_failure) - return "The descriptor does not fit into the select call's fd_set"; - return "asio.misc error"; - } -}; +extern BOOST_ASIO_DECL +const boost::system::error_category& get_misc_category(); -} // namespace detail - -inline const boost::system::error_category& get_misc_category() -{ - static detail::misc_category instance; - return instance; -} - -namespace detail { - -class ssl_category : public boost::system::error_category -{ -public: - const char* name() const - { - return "asio.ssl"; - } - - std::string message(int) const - { - return "asio.ssl error"; - } -}; - -} // namespace detail - -inline const boost::system::error_category& get_ssl_category() -{ - static detail::ssl_category instance; - return instance; -} +extern BOOST_ASIO_DECL +const boost::system::error_category& get_ssl_category(); static const boost::system::error_category& system_category = boost::asio::error::get_system_category(); @@ -430,13 +328,16 @@ inline boost::system::error_code make_error_code(ssl_errors e) } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #undef BOOST_ASIO_NATIVE_ERROR #undef BOOST_ASIO_SOCKET_ERROR #undef BOOST_ASIO_NETDB_ERROR #undef BOOST_ASIO_GETADDRINFO_ERROR #undef BOOST_ASIO_WIN_OR_POSIX - -#include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/impl/error.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) #endif // BOOST_ASIO_ERROR_HPP diff --git a/3rdParty/Boost/src/boost/asio/handler_alloc_hook.hpp b/3rdParty/Boost/src/boost/asio/handler_alloc_hook.hpp index 5dada4e..179f75e 100644 --- a/3rdParty/Boost/src/boost/asio/handler_alloc_hook.hpp +++ b/3rdParty/Boost/src/boost/asio/handler_alloc_hook.hpp @@ -15,12 +15,10 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> +#include <cstddef> #include <boost/asio/detail/push_options.hpp> -#include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/handler_invoke_hook.hpp b/3rdParty/Boost/src/boost/asio/handler_invoke_hook.hpp index 184f449..f997f11 100644 --- a/3rdParty/Boost/src/boost/asio/handler_invoke_hook.hpp +++ b/3rdParty/Boost/src/boost/asio/handler_invoke_hook.hpp @@ -15,6 +15,8 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#include <boost/asio/detail/config.hpp> + #include <boost/asio/detail/push_options.hpp> namespace boost { diff --git a/3rdParty/Boost/src/boost/asio/impl/error.ipp b/3rdParty/Boost/src/boost/asio/impl/error.ipp new file mode 100644 index 0000000..708654e --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/impl/error.ipp @@ -0,0 +1,155 @@ +// +// impl/error.ipp +// ~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_IMPL_ERROR_IPP +#define BOOST_ASIO_IMPL_ERROR_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/cerrno.hpp> +#include <boost/system/error_code.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace error { + +#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +namespace detail { + +class netdb_category : public boost::system::error_category +{ +public: + const char* name() const + { + return "asio.netdb"; + } + + std::string message(int value) const + { + if (value == error::host_not_found) + return "Host not found (authoritative)"; + if (value == error::host_not_found_try_again) + return "Host not found (non-authoritative), try again later"; + if (value == error::no_data) + return "The query is valid, but it does not have associated data"; + if (value == error::no_recovery) + return "A non-recoverable error occurred during database lookup"; + return "asio.netdb error"; + } +}; + +} // namespace detail + +const boost::system::error_category& get_netdb_category() +{ + static detail::netdb_category instance; + return instance; +} + +namespace detail { + +class addrinfo_category : public boost::system::error_category +{ +public: + const char* name() const + { + return "asio.addrinfo"; + } + + std::string message(int value) const + { + if (value == error::service_not_found) + return "Service not found"; + if (value == error::socket_type_not_supported) + return "Socket type not supported"; + return "asio.addrinfo error"; + } +}; + +} // namespace detail + +const boost::system::error_category& get_addrinfo_category() +{ + static detail::addrinfo_category instance; + return instance; +} + +#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + +namespace detail { + +class misc_category : public boost::system::error_category +{ +public: + const char* name() const + { + return "asio.misc"; + } + + std::string message(int value) const + { + if (value == error::already_open) + return "Already open"; + if (value == error::eof) + return "End of file"; + if (value == error::not_found) + return "Element not found"; + if (value == error::fd_set_failure) + return "The descriptor does not fit into the select call's fd_set"; + return "asio.misc error"; + } +}; + +} // namespace detail + +const boost::system::error_category& get_misc_category() +{ + static detail::misc_category instance; + return instance; +} + +namespace detail { + +class ssl_category : public boost::system::error_category +{ +public: + const char* name() const + { + return "asio.ssl"; + } + + std::string message(int) const + { + return "asio.ssl error"; + } +}; + +} // namespace detail + +const boost::system::error_category& get_ssl_category() +{ + static detail::ssl_category instance; + return instance; +} + +} // namespace error +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_IMPL_ERROR_IPP diff --git a/3rdParty/Boost/src/boost/asio/impl/io_service.hpp b/3rdParty/Boost/src/boost/asio/impl/io_service.hpp new file mode 100644 index 0000000..3c082cb --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/impl/io_service.hpp @@ -0,0 +1,136 @@ +// +// impl/io_service.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_IMPL_IO_SERVICE_HPP +#define BOOST_ASIO_IMPL_IO_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/service_registry.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { + +template <typename Service> +inline Service& use_service(io_service& ios) +{ + // Check that Service meets the necessary type requirements. + (void)static_cast<io_service::service*>(static_cast<Service*>(0)); + (void)static_cast<const io_service::id*>(&Service::id); + + return ios.service_registry_->template use_service<Service>(); +} + +template <typename Service> +inline void add_service(io_service& ios, Service* svc) +{ + // Check that Service meets the necessary type requirements. + (void)static_cast<io_service::service*>(static_cast<Service*>(0)); + (void)static_cast<const io_service::id*>(&Service::id); + + ios.service_registry_->template add_service<Service>(svc); +} + +template <typename Service> +inline bool has_service(io_service& ios) +{ + // Check that Service meets the necessary type requirements. + (void)static_cast<io_service::service*>(static_cast<Service*>(0)); + (void)static_cast<const io_service::id*>(&Service::id); + + return ios.service_registry_->template has_service<Service>(); +} + +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) +# include <boost/asio/detail/win_iocp_io_service.hpp> +#else +# include <boost/asio/detail/task_io_service.hpp> +#endif + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { + +template <typename Handler> +inline void io_service::dispatch(Handler handler) +{ + impl_.dispatch(handler); +} + +template <typename Handler> +inline void io_service::post(Handler handler) +{ + impl_.post(handler); +} + +template <typename Handler> +#if defined(GENERATING_DOCUMENTATION) +unspecified +#else +inline detail::wrapped_handler<io_service&, Handler> +#endif +io_service::wrap(Handler handler) +{ + return detail::wrapped_handler<io_service&, Handler>(*this, handler); +} + +inline io_service::work::work(boost::asio::io_service& io_service) + : io_service_(io_service) +{ + io_service_.impl_.work_started(); +} + +inline io_service::work::work(const work& other) + : io_service_(other.io_service_) +{ + io_service_.impl_.work_started(); +} + +inline io_service::work::~work() +{ + io_service_.impl_.work_finished(); +} + +inline boost::asio::io_service& io_service::work::io_service() +{ + return io_service_; +} + +inline boost::asio::io_service& io_service::work::get_io_service() +{ + return io_service_; +} + +inline boost::asio::io_service& io_service::service::io_service() +{ + return owner_; +} + +inline boost::asio::io_service& io_service::service::get_io_service() +{ + return owner_; +} + +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_IMPL_IO_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/impl/io_service.ipp b/3rdParty/Boost/src/boost/asio/impl/io_service.ipp index 20f868d..731adb8 100644 --- a/3rdParty/Boost/src/boost/asio/impl/io_service.ipp +++ b/3rdParty/Boost/src/boost/asio/impl/io_service.ipp @@ -1,6 +1,6 @@ // -// io_service.ipp -// ~~~~~~~~~~~~~~ +// impl/io_service.ipp +// ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -8,19 +8,16 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef BOOST_ASIO_IO_SERVICE_IPP -#define BOOST_ASIO_IO_SERVICE_IPP +#ifndef BOOST_ASIO_IMPL_IO_SERVICE_IPP +#define BOOST_ASIO_IMPL_IO_SERVICE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/limits.hpp> -#include <boost/asio/detail/pop_options.hpp> - +#include <boost/asio/io_service.hpp> #include <boost/asio/detail/service_registry.hpp> #include <boost/asio/detail/throw_error.hpp> @@ -28,32 +25,33 @@ # include <boost/asio/detail/win_iocp_io_service.hpp> #else # include <boost/asio/detail/task_io_service.hpp> -# include <boost/asio/detail/reactor.hpp> #endif +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { -inline io_service::io_service() +io_service::io_service() : service_registry_(new boost::asio::detail::service_registry(*this)), impl_(service_registry_->use_service<impl_type>()) { impl_.init((std::numeric_limits<std::size_t>::max)()); } -inline io_service::io_service(std::size_t concurrency_hint) +io_service::io_service(std::size_t concurrency_hint) : service_registry_(new boost::asio::detail::service_registry(*this)), impl_(service_registry_->use_service<impl_type>()) { impl_.init(concurrency_hint); } -inline io_service::~io_service() +io_service::~io_service() { delete service_registry_; } -inline std::size_t io_service::run() +std::size_t io_service::run() { boost::system::error_code ec; std::size_t s = impl_.run(ec); @@ -61,12 +59,12 @@ inline std::size_t io_service::run() return s; } -inline std::size_t io_service::run(boost::system::error_code& ec) +std::size_t io_service::run(boost::system::error_code& ec) { return impl_.run(ec); } -inline std::size_t io_service::run_one() +std::size_t io_service::run_one() { boost::system::error_code ec; std::size_t s = impl_.run_one(ec); @@ -74,12 +72,12 @@ inline std::size_t io_service::run_one() return s; } -inline std::size_t io_service::run_one(boost::system::error_code& ec) +std::size_t io_service::run_one(boost::system::error_code& ec) { return impl_.run_one(ec); } -inline std::size_t io_service::poll() +std::size_t io_service::poll() { boost::system::error_code ec; std::size_t s = impl_.poll(ec); @@ -87,12 +85,12 @@ inline std::size_t io_service::poll() return s; } -inline std::size_t io_service::poll(boost::system::error_code& ec) +std::size_t io_service::poll(boost::system::error_code& ec) { return impl_.poll(ec); } -inline std::size_t io_service::poll_one() +std::size_t io_service::poll_one() { boost::system::error_code ec; std::size_t s = impl_.poll_one(ec); @@ -100,122 +98,39 @@ inline std::size_t io_service::poll_one() return s; } -inline std::size_t io_service::poll_one(boost::system::error_code& ec) +std::size_t io_service::poll_one(boost::system::error_code& ec) { return impl_.poll_one(ec); } -inline void io_service::stop() +void io_service::stop() { impl_.stop(); } -inline void io_service::reset() +void io_service::reset() { impl_.reset(); } -template <typename Handler> -inline void io_service::dispatch(Handler handler) -{ - impl_.dispatch(handler); -} - -template <typename Handler> -inline void io_service::post(Handler handler) -{ - impl_.post(handler); -} - -template <typename Handler> -#if defined(GENERATING_DOCUMENTATION) -unspecified -#else -inline detail::wrapped_handler<io_service&, Handler> -#endif -io_service::wrap(Handler handler) -{ - return detail::wrapped_handler<io_service&, Handler>(*this, handler); -} - -inline io_service::work::work(boost::asio::io_service& io_service) - : io_service_(io_service) -{ - io_service_.impl_.work_started(); -} - -inline io_service::work::work(const work& other) - : io_service_(other.io_service_) -{ - io_service_.impl_.work_started(); -} - -inline io_service::work::~work() -{ - io_service_.impl_.work_finished(); -} - -inline boost::asio::io_service& io_service::work::io_service() -{ - return io_service_; -} - -inline boost::asio::io_service& io_service::work::get_io_service() -{ - return io_service_; -} - -inline io_service::service::service(boost::asio::io_service& owner) +io_service::service::service(boost::asio::io_service& owner) : owner_(owner), next_(0) { } -inline io_service::service::~service() -{ -} - -inline boost::asio::io_service& io_service::service::io_service() -{ - return owner_; -} - -inline boost::asio::io_service& io_service::service::get_io_service() +io_service::service::~service() { - return owner_; } -template <typename Service> -inline Service& use_service(io_service& ios) +service_already_exists::service_already_exists() + : std::logic_error("Service already exists.") { - // Check that Service meets the necessary type requirements. - (void)static_cast<io_service::service*>(static_cast<Service*>(0)); - (void)static_cast<const io_service::id*>(&Service::id); - - return ios.service_registry_->template use_service<Service>(); } -template <typename Service> -void add_service(io_service& ios, Service* svc) +invalid_service_owner::invalid_service_owner() + : std::logic_error("Invalid service owner.") { - // Check that Service meets the necessary type requirements. - (void)static_cast<io_service::service*>(static_cast<Service*>(0)); - (void)static_cast<const io_service::id*>(&Service::id); - - if (&ios != &svc->io_service()) - boost::throw_exception(invalid_service_owner()); - if (!ios.service_registry_->template add_service<Service>(svc)) - boost::throw_exception(service_already_exists()); -} - -template <typename Service> -bool has_service(io_service& ios) -{ - // Check that Service meets the necessary type requirements. - (void)static_cast<io_service::service*>(static_cast<Service*>(0)); - (void)static_cast<const io_service::id*>(&Service::id); - - return ios.service_registry_->template has_service<Service>(); } } // namespace asio @@ -223,4 +138,4 @@ bool has_service(io_service& ios) #include <boost/asio/detail/pop_options.hpp> -#endif // BOOST_ASIO_IO_SERVICE_IPP +#endif // BOOST_ASIO_IMPL_IO_SERVICE_IPP diff --git a/3rdParty/Boost/src/boost/asio/impl/read.ipp b/3rdParty/Boost/src/boost/asio/impl/read.hpp index 772c06b..6f9842c 100644 --- a/3rdParty/Boost/src/boost/asio/impl/read.ipp +++ b/3rdParty/Boost/src/boost/asio/impl/read.hpp @@ -1,6 +1,6 @@ // -// read.ipp -// ~~~~~~~~ +// impl/read.hpp +// ~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -8,28 +8,25 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef BOOST_ASIO_READ_IPP -#define BOOST_ASIO_READ_IPP +#ifndef BOOST_ASIO_IMPL_READ_HPP +#define BOOST_ASIO_IMPL_READ_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> #include <algorithm> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/buffer.hpp> #include <boost/asio/completion_condition.hpp> -#include <boost/asio/error.hpp> #include <boost/asio/detail/base_from_completion_cond.hpp> #include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/consuming_buffers.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> #include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -88,8 +85,7 @@ std::size_t read(SyncReadStream& s, std::size_t total_transferred = 0; std::size_t max_size = detail::adapt_completion_condition_result( completion_condition(ec, total_transferred)); - std::size_t bytes_available = std::min<std::size_t>(512, - std::min<std::size_t>(max_size, b.max_size() - b.size())); + std::size_t bytes_available = read_size_helper(b, max_size); while (bytes_available > 0) { std::size_t bytes_transferred = s.read_some(b.prepare(bytes_available), ec); @@ -97,8 +93,7 @@ std::size_t read(SyncReadStream& s, total_transferred += bytes_transferred; max_size = detail::adapt_completion_condition_result( completion_condition(ec, total_transferred)); - bytes_available = std::min<std::size_t>(512, - std::min<std::size_t>(max_size, b.max_size() - b.size())); + bytes_available = read_size_helper(b, max_size); } return total_transferred; } @@ -142,31 +137,30 @@ namespace detail stream_(stream), buffers_(buffers), total_transferred_(0), - handler_(handler), - start_(true) + handler_(handler) { } void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) + std::size_t bytes_transferred, int start = 0) { - switch (start_) + switch (start) { - case true: start_ = false; - buffers_.prepare(this->check(ec, total_transferred_)); + case 1: + buffers_.prepare(this->check_for_completion(ec, total_transferred_)); for (;;) { stream_.async_read_some(buffers_, *this); return; default: total_transferred_ += bytes_transferred; buffers_.consume(bytes_transferred); - buffers_.prepare(this->check(ec, total_transferred_)); + buffers_.prepare(this->check_for_completion(ec, total_transferred_)); if ((!ec && bytes_transferred == 0) || buffers_.begin() == buffers_.end()) break; } - handler_(ec, total_transferred_); + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); } } @@ -176,7 +170,6 @@ namespace detail mutable_buffer, MutableBufferSequence> buffers_; std::size_t total_transferred_; ReadHandler handler_; - bool start_; }; template <typename AsyncReadStream, @@ -195,19 +188,18 @@ namespace detail stream_(stream), buffer_(buffers), total_transferred_(0), - handler_(handler), - start_(true) + handler_(handler) { } void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) + std::size_t bytes_transferred, int start = 0) { std::size_t n = 0; - switch (start_) + switch (start) { - case true: start_ = false; - n = this->check(ec, total_transferred_); + case 1: + n = this->check_for_completion(ec, total_transferred_); for (;;) { stream_.async_read_some(boost::asio::buffer( @@ -215,12 +207,12 @@ namespace detail return; default: total_transferred_ += bytes_transferred; if ((!ec && bytes_transferred == 0) - || (n = this->check(ec, total_transferred_)) == 0 + || (n = this->check_for_completion(ec, total_transferred_)) == 0 || total_transferred_ == boost::asio::buffer_size(buffer_)) break; } - handler_(ec, total_transferred_); + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); } } @@ -229,7 +221,6 @@ namespace detail boost::asio::mutable_buffer buffer_; std::size_t total_transferred_; ReadHandler handler_; - bool start_; }; template <typename AsyncReadStream, typename MutableBufferSequence, @@ -272,7 +263,7 @@ inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, detail::read_op<AsyncReadStream, MutableBufferSequence, CompletionCondition, ReadHandler>( s, buffers, completion_condition, handler)( - boost::system::error_code(), 0); + boost::system::error_code(), 0, 1); } template <typename AsyncReadStream, typename MutableBufferSequence, @@ -301,37 +292,32 @@ namespace detail stream_(stream), streambuf_(streambuf), total_transferred_(0), - handler_(handler), - start_(true) + handler_(handler) { } void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) + std::size_t bytes_transferred, int start = 0) { std::size_t max_size, bytes_available; - switch (start_) + switch (start) { - case true: start_ = false; - max_size = this->check(ec, total_transferred_); - bytes_available = std::min<std::size_t>(512, - std::min<std::size_t>(max_size, - streambuf_.max_size() - streambuf_.size())); + case 1: + max_size = this->check_for_completion(ec, total_transferred_); + bytes_available = read_size_helper(streambuf_, max_size); for (;;) { stream_.async_read_some(streambuf_.prepare(bytes_available), *this); return; default: total_transferred_ += bytes_transferred; streambuf_.commit(bytes_transferred); - max_size = this->check(ec, total_transferred_); - bytes_available = std::min<std::size_t>(512, - std::min<std::size_t>(max_size, - streambuf_.max_size() - streambuf_.size())); + max_size = this->check_for_completion(ec, total_transferred_); + bytes_available = read_size_helper(streambuf_, max_size); if ((!ec && bytes_transferred == 0) || bytes_available == 0) break; } - handler_(ec, total_transferred_); + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); } } @@ -340,7 +326,6 @@ namespace detail boost::asio::basic_streambuf<Allocator>& streambuf_; std::size_t total_transferred_; ReadHandler handler_; - bool start_; }; template <typename AsyncReadStream, typename Allocator, @@ -383,7 +368,7 @@ inline void async_read(AsyncReadStream& s, detail::read_streambuf_op<AsyncReadStream, Allocator, CompletionCondition, ReadHandler>( s, b, completion_condition, handler)( - boost::system::error_code(), 0); + boost::system::error_code(), 0, 1); } template <typename AsyncReadStream, typename Allocator, typename ReadHandler> @@ -400,4 +385,4 @@ inline void async_read(AsyncReadStream& s, #include <boost/asio/detail/pop_options.hpp> -#endif // BOOST_ASIO_READ_IPP +#endif // BOOST_ASIO_IMPL_READ_HPP diff --git a/3rdParty/Boost/src/boost/asio/impl/read_at.ipp b/3rdParty/Boost/src/boost/asio/impl/read_at.hpp index eb3c3f8..f6ea0b3 100644 --- a/3rdParty/Boost/src/boost/asio/impl/read_at.ipp +++ b/3rdParty/Boost/src/boost/asio/impl/read_at.hpp @@ -1,6 +1,6 @@ // -// read_at.ipp -// ~~~~~~~~~~~ +// impl/read_at.hpp +// ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -8,27 +8,25 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef BOOST_ASIO_READ_AT_IPP -#define BOOST_ASIO_READ_AT_IPP +#ifndef BOOST_ASIO_IMPL_READ_AT_HPP +#define BOOST_ASIO_IMPL_READ_AT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> #include <algorithm> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/buffer.hpp> #include <boost/asio/completion_condition.hpp> -#include <boost/asio/error.hpp> +#include <boost/asio/detail/base_from_completion_cond.hpp> #include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/consuming_buffers.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> #include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -89,19 +87,22 @@ std::size_t read_at(SyncRandomAccessReadDevice& d, boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b, CompletionCondition completion_condition, boost::system::error_code& ec) { + ec = boost::system::error_code(); std::size_t total_transferred = 0; - for (;;) + std::size_t max_size = detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred)); + std::size_t bytes_available = read_size_helper(b, max_size); + while (bytes_available > 0) { - std::size_t bytes_available = - std::min<std::size_t>(512, b.max_size() - b.size()); std::size_t bytes_transferred = d.read_some_at( offset + total_transferred, b.prepare(bytes_available), ec); b.commit(bytes_transferred); total_transferred += bytes_transferred; - if (b.size() == b.max_size() - || completion_condition(ec, total_transferred)) - return total_transferred; + max_size = detail::adapt_completion_condition_result( + completion_condition(ec, total_transferred)); + bytes_available = read_size_helper(b, max_size); } + return total_transferred; } template <typename SyncRandomAccessReadDevice, typename Allocator> @@ -135,48 +136,105 @@ namespace detail template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, typename CompletionCondition, typename ReadHandler> - class read_at_handler + class read_at_op + : detail::base_from_completion_cond<CompletionCondition> { public: - typedef boost::asio::detail::consuming_buffers< - mutable_buffer, MutableBufferSequence> buffers_type; - - read_at_handler(AsyncRandomAccessReadDevice& stream, - boost::uint64_t offset, const buffers_type& buffers, + read_at_op(AsyncRandomAccessReadDevice& device, + boost::uint64_t offset, const MutableBufferSequence& buffers, CompletionCondition completion_condition, ReadHandler handler) - : stream_(stream), + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + device_(device), offset_(offset), buffers_(buffers), total_transferred_(0), - completion_condition_(completion_condition), handler_(handler) { } void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) + std::size_t bytes_transferred, int start = 0) { - total_transferred_ += bytes_transferred; - buffers_.consume(bytes_transferred); - buffers_.prepare(detail::adapt_completion_condition_result( - completion_condition_(ec, total_transferred_))); - if (buffers_.begin() == buffers_.end()) + switch (start) { - handler_(ec, total_transferred_); + case 1: + buffers_.prepare(this->check_for_completion(ec, total_transferred_)); + for (;;) + { + device_.async_read_some_at( + offset_ + total_transferred_, buffers_, *this); + return; default: + total_transferred_ += bytes_transferred; + buffers_.consume(bytes_transferred); + buffers_.prepare(this->check_for_completion(ec, total_transferred_)); + if ((!ec && bytes_transferred == 0) + || buffers_.begin() == buffers_.end()) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); } - else + } + + //private: + AsyncRandomAccessReadDevice& device_; + boost::uint64_t offset_; + boost::asio::detail::consuming_buffers< + mutable_buffer, MutableBufferSequence> buffers_; + std::size_t total_transferred_; + ReadHandler handler_; + }; + + template <typename AsyncRandomAccessReadDevice, + typename CompletionCondition, typename ReadHandler> + class read_at_op<AsyncRandomAccessReadDevice, + boost::asio::mutable_buffers_1, CompletionCondition, ReadHandler> + : detail::base_from_completion_cond<CompletionCondition> + { + public: + read_at_op(AsyncRandomAccessReadDevice& device, + boost::uint64_t offset, const boost::asio::mutable_buffers_1& buffers, + CompletionCondition completion_condition, ReadHandler handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + device_(device), + offset_(offset), + buffer_(buffers), + total_transferred_(0), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + std::size_t n = 0; + switch (start) { - stream_.async_read_some_at( - offset_ + total_transferred_, buffers_, *this); + case 1: + n = this->check_for_completion(ec, total_transferred_); + for (;;) + { + device_.async_read_some_at(offset_ + total_transferred_, + boost::asio::buffer(buffer_ + total_transferred_, n), *this); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check_for_completion(ec, total_transferred_)) == 0 + || total_transferred_ == boost::asio::buffer_size(buffer_)) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); } } //private: - AsyncRandomAccessReadDevice& stream_; + AsyncRandomAccessReadDevice& device_; boost::uint64_t offset_; - buffers_type buffers_; + boost::asio::mutable_buffer buffer_; std::size_t total_transferred_; - CompletionCondition completion_condition_; ReadHandler handler_; }; @@ -184,7 +242,7 @@ namespace detail typename MutableBufferSequence, typename CompletionCondition, typename ReadHandler> inline void* asio_handler_allocate(std::size_t size, - read_at_handler<AsyncRandomAccessReadDevice, MutableBufferSequence, + read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence, CompletionCondition, ReadHandler>* this_handler) { return boost_asio_handler_alloc_helpers::allocate( @@ -195,7 +253,7 @@ namespace detail typename MutableBufferSequence, typename CompletionCondition, typename ReadHandler> inline void asio_handler_deallocate(void* pointer, std::size_t size, - read_at_handler<AsyncRandomAccessReadDevice, MutableBufferSequence, + read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence, CompletionCondition, ReadHandler>* this_handler) { boost_asio_handler_alloc_helpers::deallocate( @@ -206,7 +264,7 @@ namespace detail typename MutableBufferSequence, typename CompletionCondition, typename ReadHandler> inline void asio_handler_invoke(const Function& function, - read_at_handler<AsyncRandomAccessReadDevice, MutableBufferSequence, + read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence, CompletionCondition, ReadHandler>* this_handler) { boost_asio_handler_invoke_helpers::invoke( @@ -220,24 +278,10 @@ inline void async_read_at(AsyncRandomAccessReadDevice& d, boost::uint64_t offset, const MutableBufferSequence& buffers, CompletionCondition completion_condition, ReadHandler handler) { - boost::asio::detail::consuming_buffers< - mutable_buffer, MutableBufferSequence> tmp(buffers); - - boost::system::error_code ec; - std::size_t total_transferred = 0; - tmp.prepare(detail::adapt_completion_condition_result( - completion_condition(ec, total_transferred))); - if (tmp.begin() == tmp.end()) - { - d.get_io_service().post(detail::bind_handler( - handler, ec, total_transferred)); - return; - } - - d.async_read_some_at(offset, tmp, - detail::read_at_handler<AsyncRandomAccessReadDevice, - MutableBufferSequence, CompletionCondition, ReadHandler>( - d, offset, tmp, completion_condition, handler)); + detail::read_at_op<AsyncRandomAccessReadDevice, + MutableBufferSequence, CompletionCondition, ReadHandler>( + d, offset, buffers, completion_condition, handler)( + boost::system::error_code(), 0, 1); } template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, @@ -255,55 +299,61 @@ namespace detail { template <typename AsyncRandomAccessReadDevice, typename Allocator, typename CompletionCondition, typename ReadHandler> - class read_at_streambuf_handler + class read_at_streambuf_op + : detail::base_from_completion_cond<CompletionCondition> { public: - read_at_streambuf_handler(AsyncRandomAccessReadDevice& stream, + read_at_streambuf_op(AsyncRandomAccessReadDevice& device, boost::uint64_t offset, basic_streambuf<Allocator>& streambuf, CompletionCondition completion_condition, ReadHandler handler) - : stream_(stream), + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + device_(device), offset_(offset), streambuf_(streambuf), total_transferred_(0), - completion_condition_(completion_condition), handler_(handler) { } void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) + std::size_t bytes_transferred, int start = 0) { - total_transferred_ += bytes_transferred; - streambuf_.commit(bytes_transferred); - std::size_t max_size = detail::adapt_completion_condition_result( - completion_condition_(ec, total_transferred_)); - std::size_t bytes_available = std::min<std::size_t>(512, - std::min<std::size_t>(max_size, - streambuf_.max_size() - streambuf_.size())); - if (bytes_available == 0) + std::size_t max_size, bytes_available; + switch (start) { - handler_(ec, total_transferred_); - } - else - { - stream_.async_read_some_at(offset_ + total_transferred_, - streambuf_.prepare(bytes_available), *this); + case 1: + max_size = this->check_for_completion(ec, total_transferred_); + bytes_available = read_size_helper(streambuf_, max_size); + for (;;) + { + device_.async_read_some_at(offset_ + total_transferred_, + streambuf_.prepare(bytes_available), *this); + return; default: + total_transferred_ += bytes_transferred; + streambuf_.commit(bytes_transferred); + max_size = this->check_for_completion(ec, total_transferred_); + bytes_available = read_size_helper(streambuf_, max_size); + if ((!ec && bytes_transferred == 0) || bytes_available == 0) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); } } //private: - AsyncRandomAccessReadDevice& stream_; + AsyncRandomAccessReadDevice& device_; boost::uint64_t offset_; boost::asio::basic_streambuf<Allocator>& streambuf_; std::size_t total_transferred_; - CompletionCondition completion_condition_; ReadHandler handler_; }; template <typename AsyncRandomAccessReadDevice, typename Allocator, typename CompletionCondition, typename ReadHandler> inline void* asio_handler_allocate(std::size_t size, - read_at_streambuf_handler<AsyncRandomAccessReadDevice, Allocator, + read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator, CompletionCondition, ReadHandler>* this_handler) { return boost_asio_handler_alloc_helpers::allocate( @@ -313,7 +363,7 @@ namespace detail template <typename AsyncRandomAccessReadDevice, typename Allocator, typename CompletionCondition, typename ReadHandler> inline void asio_handler_deallocate(void* pointer, std::size_t size, - read_at_streambuf_handler<AsyncRandomAccessReadDevice, Allocator, + read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator, CompletionCondition, ReadHandler>* this_handler) { boost_asio_handler_alloc_helpers::deallocate( @@ -323,7 +373,7 @@ namespace detail template <typename Function, typename AsyncRandomAccessReadDevice, typename Allocator, typename CompletionCondition, typename ReadHandler> inline void asio_handler_invoke(const Function& function, - read_at_streambuf_handler<AsyncRandomAccessReadDevice, Allocator, + read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator, CompletionCondition, ReadHandler>* this_handler) { boost_asio_handler_invoke_helpers::invoke( @@ -337,23 +387,10 @@ inline void async_read_at(AsyncRandomAccessReadDevice& d, boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b, CompletionCondition completion_condition, ReadHandler handler) { - boost::system::error_code ec; - std::size_t total_transferred = 0; - std::size_t max_size = detail::adapt_completion_condition_result( - completion_condition(ec, total_transferred)); - std::size_t bytes_available = std::min<std::size_t>(512, - std::min<std::size_t>(max_size, b.max_size() - b.size())); - if (bytes_available == 0) - { - d.get_io_service().post(detail::bind_handler( - handler, ec, total_transferred)); - return; - } - - d.async_read_some_at(offset, b.prepare(bytes_available), - detail::read_at_streambuf_handler<AsyncRandomAccessReadDevice, Allocator, - CompletionCondition, ReadHandler>( - d, offset, b, completion_condition, handler)); + detail::read_at_streambuf_op<AsyncRandomAccessReadDevice, + Allocator, CompletionCondition, ReadHandler>( + d, offset, b, completion_condition, handler)( + boost::system::error_code(), 0, 1); } template <typename AsyncRandomAccessReadDevice, typename Allocator, @@ -372,4 +409,4 @@ inline void async_read_at(AsyncRandomAccessReadDevice& d, #include <boost/asio/detail/pop_options.hpp> -#endif // BOOST_ASIO_READ_AT_IPP +#endif // BOOST_ASIO_IMPL_READ_AT_HPP diff --git a/3rdParty/Boost/src/boost/asio/impl/read_until.hpp b/3rdParty/Boost/src/boost/asio/impl/read_until.hpp new file mode 100644 index 0000000..73f8773 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/impl/read_until.hpp @@ -0,0 +1,904 @@ +// +// impl/read_until.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_IMPL_READ_UNTIL_HPP +#define BOOST_ASIO_IMPL_READ_UNTIL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <algorithm> +#include <string> +#include <vector> +#include <utility> +#include <boost/limits.hpp> +#include <boost/asio/buffer.hpp> +#include <boost/asio/buffers_iterator.hpp> +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/throw_error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { + +template <typename SyncReadStream, typename Allocator> +inline std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, char delim) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = read_until(s, b, delim, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +template <typename SyncReadStream, typename Allocator> +std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, char delim, + boost::system::error_code& ec) +{ + std::size_t search_position = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::buffers_iterator<const_buffers_type> iterator; + const_buffers_type buffers = b.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + search_position; + iterator end = iterator::end(buffers); + + // Look for a match. + iterator iter = std::find(start, end, delim); + if (iter != end) + { + // Found a match. We're done. + ec = boost::system::error_code(); + return iter - begin + 1; + } + else + { + // No match. Next search can start with the new data. + search_position = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_to_read = read_size_helper(b, 65536); + b.commit(s.read_some(b.prepare(bytes_to_read), ec)); + if (ec) + return 0; + } +} + +template <typename SyncReadStream, typename Allocator> +inline std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, const std::string& delim) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = read_until(s, b, delim, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +namespace detail +{ + // Algorithm that finds a subsequence of equal values in a sequence. Returns + // (iterator,true) if a full match was found, in which case the iterator + // points to the beginning of the match. Returns (iterator,false) if a + // partial match was found at the end of the first sequence, in which case + // the iterator points to the beginning of the partial match. Returns + // (last1,false) if no full or partial match was found. + template <typename Iterator1, typename Iterator2> + std::pair<Iterator1, bool> partial_search( + Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) + { + for (Iterator1 iter1 = first1; iter1 != last1; ++iter1) + { + Iterator1 test_iter1 = iter1; + Iterator2 test_iter2 = first2; + for (;; ++test_iter1, ++test_iter2) + { + if (test_iter2 == last2) + return std::make_pair(iter1, true); + if (test_iter1 == last1) + { + if (test_iter2 != first2) + return std::make_pair(iter1, false); + else + break; + } + if (*test_iter1 != *test_iter2) + break; + } + } + return std::make_pair(last1, false); + } +} // namespace detail + +template <typename SyncReadStream, typename Allocator> +std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, const std::string& delim, + boost::system::error_code& ec) +{ + std::size_t search_position = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::buffers_iterator<const_buffers_type> iterator; + const_buffers_type buffers = b.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + search_position; + iterator end = iterator::end(buffers); + + // Look for a match. + std::pair<iterator, bool> result = detail::partial_search( + start, end, delim.begin(), delim.end()); + if (result.first != end) + { + if (result.second) + { + // Full match. We're done. + ec = boost::system::error_code(); + return result.first - begin + delim.length(); + } + else + { + // Partial match. Next search needs to start from beginning of match. + search_position = result.first - begin; + } + } + else + { + // No match. Next search can start with the new data. + search_position = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_to_read = read_size_helper(b, 65536); + b.commit(s.read_some(b.prepare(bytes_to_read), ec)); + if (ec) + return 0; + } +} + +template <typename SyncReadStream, typename Allocator> +inline std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = read_until(s, b, expr, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +template <typename SyncReadStream, typename Allocator> +std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr, + boost::system::error_code& ec) +{ + std::size_t search_position = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::buffers_iterator<const_buffers_type> iterator; + const_buffers_type buffers = b.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + search_position; + iterator end = iterator::end(buffers); + + // Look for a match. + boost::match_results<iterator, + typename std::vector<boost::sub_match<iterator> >::allocator_type> + match_results; + if (regex_search(start, end, match_results, expr, + boost::match_default | boost::match_partial)) + { + if (match_results[0].matched) + { + // Full match. We're done. + ec = boost::system::error_code(); + return match_results[0].second - begin; + } + else + { + // Partial match. Next search needs to start from beginning of match. + search_position = match_results[0].first - begin; + } + } + else + { + // No match. Next search can start with the new data. + search_position = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_to_read = read_size_helper(b, 65536); + b.commit(s.read_some(b.prepare(bytes_to_read), ec)); + if (ec) + return 0; + } +} + +template <typename SyncReadStream, typename Allocator, typename MatchCondition> +std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, + MatchCondition match_condition, boost::system::error_code& ec, + typename boost::enable_if<is_match_condition<MatchCondition> >::type*) +{ + std::size_t search_position = 0; + for (;;) + { + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::buffers_iterator<const_buffers_type> iterator; + const_buffers_type buffers = b.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + search_position; + iterator end = iterator::end(buffers); + + // Look for a match. + std::pair<iterator, bool> result = match_condition(start, end); + if (result.second) + { + // Full match. We're done. + ec = boost::system::error_code(); + return result.first - begin; + } + else if (result.first != end) + { + // Partial match. Next search needs to start from beginning of match. + search_position = result.first - begin; + } + else + { + // No match. Next search can start with the new data. + search_position = end - begin; + } + + // Check if buffer is full. + if (b.size() == b.max_size()) + { + ec = error::not_found; + return 0; + } + + // Need more data. + std::size_t bytes_to_read = read_size_helper(b, 65536); + b.commit(s.read_some(b.prepare(bytes_to_read), ec)); + if (ec) + return 0; + } +} + +template <typename SyncReadStream, typename Allocator, typename MatchCondition> +inline std::size_t read_until(SyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, MatchCondition match_condition, + typename boost::enable_if<is_match_condition<MatchCondition> >::type*) +{ + boost::system::error_code ec; + std::size_t bytes_transferred = read_until(s, b, match_condition, ec); + boost::asio::detail::throw_error(ec); + return bytes_transferred; +} + +namespace detail +{ + template <typename AsyncReadStream, typename Allocator, typename ReadHandler> + class read_until_delim_op + { + public: + read_until_delim_op(AsyncReadStream& stream, + boost::asio::basic_streambuf<Allocator>& streambuf, + char delim, ReadHandler handler) + : stream_(stream), + streambuf_(streambuf), + delim_(delim), + search_position_(0), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + const std::size_t not_found = (std::numeric_limits<std::size_t>::max)(); + std::size_t bytes_to_read; + switch (start) + { + case 1: + for (;;) + { + { + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::buffers_iterator<const_buffers_type> iterator; + const_buffers_type buffers = streambuf_.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + search_position_; + iterator end = iterator::end(buffers); + + // Look for a match. + iterator iter = std::find(start, end, delim_); + if (iter != end) + { + // Found a match. We're done. + search_position_ = iter - begin + 1; + bytes_to_read = 0; + } + + // No match yet. Check if buffer is full. + else if (streambuf_.size() == streambuf_.max_size()) + { + search_position_ = not_found; + bytes_to_read = 0; + } + + // Need to read some more data. + else + { + // Next search can start with the new data. + search_position_ = end - begin; + bytes_to_read = read_size_helper(streambuf_, 65536); + } + } + + // Check if we're done. + if (!start && bytes_to_read == 0) + break; + + // Start a new asynchronous read operation to obtain more data. + stream_.async_read_some(streambuf_.prepare(bytes_to_read), *this); + return; default: + streambuf_.commit(bytes_transferred); + if (ec || bytes_transferred == 0) + break; + } + + const boost::system::error_code result_ec = + (search_position_ == not_found) + ? error::not_found : ec; + + const std::size_t result_n = + (ec || search_position_ == not_found) + ? 0 : search_position_; + + handler_(result_ec, result_n); + } + } + + //private: + AsyncReadStream& stream_; + boost::asio::basic_streambuf<Allocator>& streambuf_; + char delim_; + std::size_t search_position_; + ReadHandler handler_; + }; + + template <typename AsyncReadStream, typename Allocator, typename ReadHandler> + inline void* asio_handler_allocate(std::size_t size, + read_until_delim_op<AsyncReadStream, + Allocator, ReadHandler>* this_handler) + { + return boost_asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template <typename AsyncReadStream, typename Allocator, typename ReadHandler> + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_delim_op<AsyncReadStream, + Allocator, ReadHandler>* this_handler) + { + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template <typename Function, typename AsyncReadStream, typename Allocator, + typename ReadHandler> + inline void asio_handler_invoke(const Function& function, + read_until_delim_op<AsyncReadStream, + Allocator, ReadHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template <typename AsyncReadStream, typename Allocator, typename ReadHandler> +void async_read_until(AsyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, char delim, ReadHandler handler) +{ + detail::read_until_delim_op< + AsyncReadStream, Allocator, ReadHandler>( + s, b, delim, handler)( + boost::system::error_code(), 0, 1); +} + +namespace detail +{ + template <typename AsyncReadStream, typename Allocator, typename ReadHandler> + class read_until_delim_string_op + { + public: + read_until_delim_string_op(AsyncReadStream& stream, + boost::asio::basic_streambuf<Allocator>& streambuf, + const std::string& delim, ReadHandler handler) + : stream_(stream), + streambuf_(streambuf), + delim_(delim), + search_position_(0), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + const std::size_t not_found = (std::numeric_limits<std::size_t>::max)(); + std::size_t bytes_to_read; + switch (start) + { + case 1: + for (;;) + { + { + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::buffers_iterator<const_buffers_type> iterator; + const_buffers_type buffers = streambuf_.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + search_position_; + iterator end = iterator::end(buffers); + + // Look for a match. + std::pair<iterator, bool> result = detail::partial_search( + start, end, delim_.begin(), delim_.end()); + if (result.first != end && result.second) + { + // Full match. We're done. + search_position_ = result.first - begin + delim_.length(); + bytes_to_read = 0; + } + + // No match yet. Check if buffer is full. + else if (streambuf_.size() == streambuf_.max_size()) + { + search_position_ = not_found; + bytes_to_read = 0; + } + + // Need to read some more data. + else + { + if (result.first != end) + { + // Partial match. Next search needs to start from beginning of + // match. + search_position_ = result.first - begin; + } + else + { + // Next search can start with the new data. + search_position_ = end - begin; + } + + bytes_to_read = read_size_helper(streambuf_, 65536); + } + } + + // Check if we're done. + if (!start && bytes_to_read == 0) + break; + + // Start a new asynchronous read operation to obtain more data. + stream_.async_read_some(streambuf_.prepare(bytes_to_read), *this); + return; default: + streambuf_.commit(bytes_transferred); + if (ec || bytes_transferred == 0) + break; + } + + const boost::system::error_code result_ec = + (search_position_ == not_found) + ? error::not_found : ec; + + const std::size_t result_n = + (ec || search_position_ == not_found) + ? 0 : search_position_; + + handler_(result_ec, result_n); + } + } + + //private: + AsyncReadStream& stream_; + boost::asio::basic_streambuf<Allocator>& streambuf_; + std::string delim_; + std::size_t search_position_; + ReadHandler handler_; + }; + + template <typename AsyncReadStream, typename Allocator, typename ReadHandler> + inline void* asio_handler_allocate(std::size_t size, + read_until_delim_string_op<AsyncReadStream, + Allocator, ReadHandler>* this_handler) + { + return boost_asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template <typename AsyncReadStream, typename Allocator, typename ReadHandler> + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_delim_string_op<AsyncReadStream, + Allocator, ReadHandler>* this_handler) + { + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template <typename Function, typename AsyncReadStream, + typename Allocator, typename ReadHandler> + inline void asio_handler_invoke(const Function& function, + read_until_delim_string_op<AsyncReadStream, + Allocator, ReadHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template <typename AsyncReadStream, typename Allocator, typename ReadHandler> +void async_read_until(AsyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, const std::string& delim, + ReadHandler handler) +{ + detail::read_until_delim_string_op< + AsyncReadStream, Allocator, ReadHandler>( + s, b, delim, handler)( + boost::system::error_code(), 0, 1); +} + +namespace detail +{ + template <typename AsyncReadStream, typename Allocator, + typename RegEx, typename ReadHandler> + class read_until_expr_op + { + public: + read_until_expr_op(AsyncReadStream& stream, + boost::asio::basic_streambuf<Allocator>& streambuf, + const boost::regex& expr, ReadHandler handler) + : stream_(stream), + streambuf_(streambuf), + expr_(expr), + search_position_(0), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + const std::size_t not_found = (std::numeric_limits<std::size_t>::max)(); + std::size_t bytes_to_read; + switch (start) + { + case 1: + for (;;) + { + { + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::buffers_iterator<const_buffers_type> iterator; + const_buffers_type buffers = streambuf_.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + search_position_; + iterator end = iterator::end(buffers); + + // Look for a match. + boost::match_results<iterator, + typename std::vector<boost::sub_match<iterator> >::allocator_type> + match_results; + bool match = regex_search(start, end, match_results, expr_, + boost::match_default | boost::match_partial); + if (match && match_results[0].matched) + { + // Full match. We're done. + search_position_ = match_results[0].second - begin; + bytes_to_read = 0; + } + + // No match yet. Check if buffer is full. + else if (streambuf_.size() == streambuf_.max_size()) + { + search_position_ = not_found; + bytes_to_read = 0; + } + + // Need to read some more data. + else + { + if (match) + { + // Partial match. Next search needs to start from beginning of + // match. + search_position_ = match_results[0].first - begin; + } + else + { + // Next search can start with the new data. + search_position_ = end - begin; + } + + bytes_to_read = read_size_helper(streambuf_, 65536); + } + } + + // Check if we're done. + if (!start && bytes_to_read == 0) + break; + + // Start a new asynchronous read operation to obtain more data. + stream_.async_read_some(streambuf_.prepare(bytes_to_read), *this); + return; default: + streambuf_.commit(bytes_transferred); + if (ec || bytes_transferred == 0) + break; + } + + const boost::system::error_code result_ec = + (search_position_ == not_found) + ? error::not_found : ec; + + const std::size_t result_n = + (ec || search_position_ == not_found) + ? 0 : search_position_; + + handler_(result_ec, result_n); + } + } + + //private: + AsyncReadStream& stream_; + boost::asio::basic_streambuf<Allocator>& streambuf_; + RegEx expr_; + std::size_t search_position_; + ReadHandler handler_; + }; + + template <typename AsyncReadStream, typename Allocator, + typename RegEx, typename ReadHandler> + inline void* asio_handler_allocate(std::size_t size, + read_until_expr_op<AsyncReadStream, + Allocator, RegEx, ReadHandler>* this_handler) + { + return boost_asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template <typename AsyncReadStream, typename Allocator, + typename RegEx, typename ReadHandler> + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_expr_op<AsyncReadStream, + Allocator, RegEx, ReadHandler>* this_handler) + { + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template <typename Function, typename AsyncReadStream, typename Allocator, + typename RegEx, typename ReadHandler> + inline void asio_handler_invoke(const Function& function, + read_until_expr_op<AsyncReadStream, + Allocator, RegEx, ReadHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template <typename AsyncReadStream, typename Allocator, typename ReadHandler> +void async_read_until(AsyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr, + ReadHandler handler) +{ + detail::read_until_expr_op<AsyncReadStream, + Allocator, boost::regex, ReadHandler>( + s, b, expr, handler)( + boost::system::error_code(), 0, 1); +} + +namespace detail +{ + template <typename AsyncReadStream, typename Allocator, + typename MatchCondition, typename ReadHandler> + class read_until_match_op + { + public: + read_until_match_op(AsyncReadStream& stream, + boost::asio::basic_streambuf<Allocator>& streambuf, + MatchCondition match_condition, ReadHandler handler) + : stream_(stream), + streambuf_(streambuf), + match_condition_(match_condition), + search_position_(0), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + const std::size_t not_found = (std::numeric_limits<std::size_t>::max)(); + std::size_t bytes_to_read; + switch (start) + { + case 1: + for (;;) + { + { + // Determine the range of the data to be searched. + typedef typename boost::asio::basic_streambuf< + Allocator>::const_buffers_type const_buffers_type; + typedef boost::asio::buffers_iterator<const_buffers_type> iterator; + const_buffers_type buffers = streambuf_.data(); + iterator begin = iterator::begin(buffers); + iterator start = begin + search_position_; + iterator end = iterator::end(buffers); + + // Look for a match. + std::pair<iterator, bool> result = match_condition_(start, end); + if (result.second) + { + // Full match. We're done. + search_position_ = result.first - begin; + bytes_to_read = 0; + } + + // No match yet. Check if buffer is full. + else if (streambuf_.size() == streambuf_.max_size()) + { + search_position_ = not_found; + bytes_to_read = 0; + } + + // Need to read some more data. + else + { + if (result.first != end) + { + // Partial match. Next search needs to start from beginning of + // match. + search_position_ = result.first - begin; + } + else + { + // Next search can start with the new data. + search_position_ = end - begin; + } + + bytes_to_read = read_size_helper(streambuf_, 65536); + } + } + + // Check if we're done. + if (!start && bytes_to_read == 0) + break; + + // Start a new asynchronous read operation to obtain more data. + stream_.async_read_some(streambuf_.prepare(bytes_to_read), *this); + return; default: + streambuf_.commit(bytes_transferred); + if (ec || bytes_transferred == 0) + break; + } + + const boost::system::error_code result_ec = + (search_position_ == not_found) + ? error::not_found : ec; + + const std::size_t result_n = + (ec || search_position_ == not_found) + ? 0 : search_position_; + + handler_(result_ec, result_n); + } + } + + //private: + AsyncReadStream& stream_; + boost::asio::basic_streambuf<Allocator>& streambuf_; + MatchCondition match_condition_; + std::size_t search_position_; + ReadHandler handler_; + }; + + template <typename AsyncReadStream, typename Allocator, + typename MatchCondition, typename ReadHandler> + inline void* asio_handler_allocate(std::size_t size, + read_until_match_op<AsyncReadStream, + Allocator, MatchCondition, ReadHandler>* this_handler) + { + return boost_asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template <typename AsyncReadStream, typename Allocator, + typename MatchCondition, typename ReadHandler> + inline void asio_handler_deallocate(void* pointer, std::size_t size, + read_until_match_op<AsyncReadStream, + Allocator, MatchCondition, ReadHandler>* this_handler) + { + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template <typename Function, typename AsyncReadStream, typename Allocator, + typename MatchCondition, typename ReadHandler> + inline void asio_handler_invoke(const Function& function, + read_until_match_op<AsyncReadStream, + Allocator, MatchCondition, ReadHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template <typename AsyncReadStream, typename Allocator, + typename MatchCondition, typename ReadHandler> +void async_read_until(AsyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, + MatchCondition match_condition, ReadHandler handler, + typename boost::enable_if<is_match_condition<MatchCondition> >::type*) +{ + detail::read_until_match_op< + AsyncReadStream, Allocator, MatchCondition, ReadHandler>( + s, b, match_condition, handler)( + boost::system::error_code(), 0, 1); +} + +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_IMPL_READ_UNTIL_HPP diff --git a/3rdParty/Boost/src/boost/asio/impl/read_until.ipp b/3rdParty/Boost/src/boost/asio/impl/read_until.ipp deleted file mode 100644 index 0ee0de0..0000000 --- a/3rdParty/Boost/src/boost/asio/impl/read_until.ipp +++ /dev/null @@ -1,989 +0,0 @@ -// -// read_until.ipp -// ~~~~~~~~~~~~~~ -// -// 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) -// - -#ifndef BOOST_ASIO_READ_UNTIL_IPP -#define BOOST_ASIO_READ_UNTIL_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <algorithm> -#include <string> -#include <utility> -#include <boost/limits.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/buffer.hpp> -#include <boost/asio/buffers_iterator.hpp> -#include <boost/asio/detail/bind_handler.hpp> -#include <boost/asio/detail/handler_alloc_helpers.hpp> -#include <boost/asio/detail/handler_invoke_helpers.hpp> -#include <boost/asio/detail/throw_error.hpp> - -namespace boost { -namespace asio { - -template <typename SyncReadStream, typename Allocator> -inline std::size_t read_until(SyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, char delim) -{ - boost::system::error_code ec; - std::size_t bytes_transferred = read_until(s, b, delim, ec); - boost::asio::detail::throw_error(ec); - return bytes_transferred; -} - -template <typename SyncReadStream, typename Allocator> -std::size_t read_until(SyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, char delim, - boost::system::error_code& ec) -{ - std::size_t next_search_start = 0; - for (;;) - { - // Determine the range of the data to be searched. - typedef typename boost::asio::basic_streambuf< - Allocator>::const_buffers_type const_buffers_type; - typedef boost::asio::buffers_iterator<const_buffers_type> iterator; - const_buffers_type buffers = b.data(); - iterator begin = iterator::begin(buffers); - iterator start = begin + next_search_start; - iterator end = iterator::end(buffers); - - // Look for a match. - iterator iter = std::find(start, end, delim); - if (iter != end) - { - // Found a match. We're done. - ec = boost::system::error_code(); - return iter - begin + 1; - } - else - { - // No match. Next search can start with the new data. - next_search_start = end - begin; - } - - // Check if buffer is full. - if (b.size() == b.max_size()) - { - ec = error::not_found; - return 0; - } - - // Need more data. - std::size_t bytes_available = - std::min<std::size_t>(512, b.max_size() - b.size()); - b.commit(s.read_some(b.prepare(bytes_available), ec)); - if (ec) - return 0; - } -} - -template <typename SyncReadStream, typename Allocator> -inline std::size_t read_until(SyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, const std::string& delim) -{ - boost::system::error_code ec; - std::size_t bytes_transferred = read_until(s, b, delim, ec); - boost::asio::detail::throw_error(ec); - return bytes_transferred; -} - -namespace detail -{ - // Algorithm that finds a subsequence of equal values in a sequence. Returns - // (iterator,true) if a full match was found, in which case the iterator - // points to the beginning of the match. Returns (iterator,false) if a - // partial match was found at the end of the first sequence, in which case - // the iterator points to the beginning of the partial match. Returns - // (last1,false) if no full or partial match was found. - template <typename Iterator1, typename Iterator2> - std::pair<Iterator1, bool> partial_search( - Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) - { - for (Iterator1 iter1 = first1; iter1 != last1; ++iter1) - { - Iterator1 test_iter1 = iter1; - Iterator2 test_iter2 = first2; - for (;; ++test_iter1, ++test_iter2) - { - if (test_iter2 == last2) - return std::make_pair(iter1, true); - if (test_iter1 == last1) - { - if (test_iter2 != first2) - return std::make_pair(iter1, false); - else - break; - } - if (*test_iter1 != *test_iter2) - break; - } - } - return std::make_pair(last1, false); - } -} // namespace detail - -template <typename SyncReadStream, typename Allocator> -std::size_t read_until(SyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, const std::string& delim, - boost::system::error_code& ec) -{ - std::size_t next_search_start = 0; - for (;;) - { - // Determine the range of the data to be searched. - typedef typename boost::asio::basic_streambuf< - Allocator>::const_buffers_type const_buffers_type; - typedef boost::asio::buffers_iterator<const_buffers_type> iterator; - const_buffers_type buffers = b.data(); - iterator begin = iterator::begin(buffers); - iterator start = begin + next_search_start; - iterator end = iterator::end(buffers); - - // Look for a match. - std::pair<iterator, bool> result = boost::asio::detail::partial_search( - start, end, delim.begin(), delim.end()); - if (result.first != end) - { - if (result.second) - { - // Full match. We're done. - ec = boost::system::error_code(); - return result.first - begin + delim.length(); - } - else - { - // Partial match. Next search needs to start from beginning of match. - next_search_start = result.first - begin; - } - } - else - { - // No match. Next search can start with the new data. - next_search_start = end - begin; - } - - // Check if buffer is full. - if (b.size() == b.max_size()) - { - ec = error::not_found; - return 0; - } - - // Need more data. - std::size_t bytes_available = - std::min<std::size_t>(512, b.max_size() - b.size()); - b.commit(s.read_some(b.prepare(bytes_available), ec)); - if (ec) - return 0; - } -} - -template <typename SyncReadStream, typename Allocator> -inline std::size_t read_until(SyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr) -{ - boost::system::error_code ec; - std::size_t bytes_transferred = read_until(s, b, expr, ec); - boost::asio::detail::throw_error(ec); - return bytes_transferred; -} - -template <typename SyncReadStream, typename Allocator> -std::size_t read_until(SyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr, - boost::system::error_code& ec) -{ - std::size_t next_search_start = 0; - for (;;) - { - // Determine the range of the data to be searched. - typedef typename boost::asio::basic_streambuf< - Allocator>::const_buffers_type const_buffers_type; - typedef boost::asio::buffers_iterator<const_buffers_type> iterator; - const_buffers_type buffers = b.data(); - iterator begin = iterator::begin(buffers); - iterator start = begin + next_search_start; - iterator end = iterator::end(buffers); - - // Look for a match. - boost::match_results<iterator> match_results; - if (boost::regex_search(start, end, match_results, expr, - boost::match_default | boost::match_partial)) - { - if (match_results[0].matched) - { - // Full match. We're done. - ec = boost::system::error_code(); - return match_results[0].second - begin; - } - else - { - // Partial match. Next search needs to start from beginning of match. - next_search_start = match_results[0].first - begin; - } - } - else - { - // No match. Next search can start with the new data. - next_search_start = end - begin; - } - - // Check if buffer is full. - if (b.size() == b.max_size()) - { - ec = error::not_found; - return 0; - } - - // Need more data. - std::size_t bytes_available = - std::min<std::size_t>(512, b.max_size() - b.size()); - b.commit(s.read_some(b.prepare(bytes_available), ec)); - if (ec) - return 0; - } -} - -template <typename SyncReadStream, typename Allocator, typename MatchCondition> -std::size_t read_until(SyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, - MatchCondition match_condition, boost::system::error_code& ec, - typename boost::enable_if<is_match_condition<MatchCondition> >::type*) -{ - std::size_t next_search_start = 0; - for (;;) - { - // Determine the range of the data to be searched. - typedef typename boost::asio::basic_streambuf< - Allocator>::const_buffers_type const_buffers_type; - typedef boost::asio::buffers_iterator<const_buffers_type> iterator; - const_buffers_type buffers = b.data(); - iterator begin = iterator::begin(buffers); - iterator start = begin + next_search_start; - iterator end = iterator::end(buffers); - - // Look for a match. - std::pair<iterator, bool> result = match_condition(start, end); - if (result.second) - { - // Full match. We're done. - ec = boost::system::error_code(); - return result.first - begin; - } - else if (result.first != end) - { - // Partial match. Next search needs to start from beginning of match. - next_search_start = result.first - begin; - } - else - { - // No match. Next search can start with the new data. - next_search_start = end - begin; - } - - // Check if buffer is full. - if (b.size() == b.max_size()) - { - ec = error::not_found; - return 0; - } - - // Need more data. - std::size_t bytes_available = - std::min<std::size_t>(512, b.max_size() - b.size()); - b.commit(s.read_some(b.prepare(bytes_available), ec)); - if (ec) - return 0; - } -} - -template <typename SyncReadStream, typename Allocator, typename MatchCondition> -inline std::size_t read_until(SyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, MatchCondition match_condition, - typename boost::enable_if<is_match_condition<MatchCondition> >::type*) -{ - boost::system::error_code ec; - std::size_t bytes_transferred = read_until(s, b, match_condition, ec); - boost::asio::detail::throw_error(ec); - return bytes_transferred; -} - -namespace detail -{ - template <typename AsyncReadStream, typename Allocator, typename ReadHandler> - class read_until_delim_handler - { - public: - read_until_delim_handler(AsyncReadStream& stream, - boost::asio::basic_streambuf<Allocator>& streambuf, char delim, - std::size_t next_search_start, ReadHandler handler) - : stream_(stream), - streambuf_(streambuf), - delim_(delim), - next_search_start_(next_search_start), - handler_(handler) - { - } - - void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) - { - // Check for errors. - if (ec) - { - std::size_t bytes = 0; - handler_(ec, bytes); - return; - } - - // Commit received data to streambuf's get area. - streambuf_.commit(bytes_transferred); - - // Determine the range of the data to be searched. - typedef typename boost::asio::basic_streambuf< - Allocator>::const_buffers_type const_buffers_type; - typedef boost::asio::buffers_iterator<const_buffers_type> iterator; - const_buffers_type buffers = streambuf_.data(); - iterator begin = iterator::begin(buffers); - iterator start = begin + next_search_start_; - iterator end = iterator::end(buffers); - - // Look for a match. - iterator iter = std::find(start, end, delim_); - if (iter != end) - { - // Found a match. We're done. - std::size_t bytes = iter - begin + 1; - handler_(ec, bytes); - return; - } - - // No match. Check if buffer is full. - if (streambuf_.size() == streambuf_.max_size()) - { - std::size_t bytes = 0; - boost::system::error_code ec(error::not_found); - handler_(ec, bytes); - return; - } - - // Next search can start with the new data. - next_search_start_ = end - begin; - - // Start a new asynchronous read operation to obtain more data. - std::size_t bytes_available = - std::min<std::size_t>(512, streambuf_.max_size() - streambuf_.size()); - stream_.async_read_some(streambuf_.prepare(bytes_available), *this); - } - - //private: - AsyncReadStream& stream_; - boost::asio::basic_streambuf<Allocator>& streambuf_; - char delim_; - std::size_t next_search_start_; - ReadHandler handler_; - }; - - template <typename AsyncReadStream, typename Allocator, typename ReadHandler> - inline void* asio_handler_allocate(std::size_t size, - read_until_delim_handler<AsyncReadStream, - Allocator, ReadHandler>* this_handler) - { - return boost_asio_handler_alloc_helpers::allocate( - size, this_handler->handler_); - } - - template <typename AsyncReadStream, typename Allocator, typename ReadHandler> - inline void asio_handler_deallocate(void* pointer, std::size_t size, - read_until_delim_handler<AsyncReadStream, - Allocator, ReadHandler>* this_handler) - { - boost_asio_handler_alloc_helpers::deallocate( - pointer, size, this_handler->handler_); - } - - template <typename Function, typename AsyncReadStream, typename Allocator, - typename ReadHandler> - inline void asio_handler_invoke(const Function& function, - read_until_delim_handler<AsyncReadStream, - Allocator, ReadHandler>* this_handler) - { - boost_asio_handler_invoke_helpers::invoke( - function, this_handler->handler_); - } -} // namespace detail - -template <typename AsyncReadStream, typename Allocator, typename ReadHandler> -void async_read_until(AsyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, char delim, ReadHandler handler) -{ - // Determine the range of the data to be searched. - typedef typename boost::asio::basic_streambuf< - Allocator>::const_buffers_type const_buffers_type; - typedef boost::asio::buffers_iterator<const_buffers_type> iterator; - const_buffers_type buffers = b.data(); - iterator begin = iterator::begin(buffers); - iterator end = iterator::end(buffers); - - // Look for a match. - iterator iter = std::find(begin, end, delim); - if (iter != end) - { - // Found a match. We're done. - boost::system::error_code ec; - std::size_t bytes = iter - begin + 1; - s.get_io_service().post(detail::bind_handler(handler, ec, bytes)); - return; - } - - // No match. Check if buffer is full. - if (b.size() == b.max_size()) - { - boost::system::error_code ec(error::not_found); - s.get_io_service().post(detail::bind_handler(handler, ec, 0)); - return; - } - - // Start a new asynchronous read operation to obtain more data. - std::size_t bytes_available = - std::min<std::size_t>(512, b.max_size() - b.size()); - s.async_read_some(b.prepare(bytes_available), - detail::read_until_delim_handler<AsyncReadStream, Allocator, ReadHandler>( - s, b, delim, end - begin, handler)); -} - -namespace detail -{ - template <typename AsyncReadStream, typename Allocator, typename ReadHandler> - class read_until_delim_string_handler - { - public: - read_until_delim_string_handler(AsyncReadStream& stream, - boost::asio::basic_streambuf<Allocator>& streambuf, - const std::string& delim, std::size_t next_search_start, - ReadHandler handler) - : stream_(stream), - streambuf_(streambuf), - delim_(delim), - next_search_start_(next_search_start), - handler_(handler) - { - } - - void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) - { - // Check for errors. - if (ec) - { - std::size_t bytes = 0; - handler_(ec, bytes); - return; - } - - // Commit received data to streambuf's get area. - streambuf_.commit(bytes_transferred); - - // Determine the range of the data to be searched. - typedef typename boost::asio::basic_streambuf< - Allocator>::const_buffers_type const_buffers_type; - typedef boost::asio::buffers_iterator<const_buffers_type> iterator; - const_buffers_type buffers = streambuf_.data(); - iterator begin = iterator::begin(buffers); - iterator start = begin + next_search_start_; - iterator end = iterator::end(buffers); - - // Look for a match. - std::pair<iterator, bool> result = boost::asio::detail::partial_search( - start, end, delim_.begin(), delim_.end()); - if (result.first != end) - { - if (result.second) - { - // Full match. We're done. - std::size_t bytes = result.first - begin + delim_.length(); - handler_(ec, bytes); - return; - } - else - { - // Partial match. Next search needs to start from beginning of match. - next_search_start_ = result.first - begin; - } - } - else - { - // No match. Next search can start with the new data. - next_search_start_ = end - begin; - } - - // Check if buffer is full. - if (streambuf_.size() == streambuf_.max_size()) - { - std::size_t bytes = 0; - boost::system::error_code ec2(error::not_found); - handler_(ec2, bytes); - return; - } - - // Start a new asynchronous read operation to obtain more data. - std::size_t bytes_available = - std::min<std::size_t>(512, streambuf_.max_size() - streambuf_.size()); - stream_.async_read_some(streambuf_.prepare(bytes_available), *this); - } - - //private: - AsyncReadStream& stream_; - boost::asio::basic_streambuf<Allocator>& streambuf_; - std::string delim_; - std::size_t next_search_start_; - ReadHandler handler_; - }; - - template <typename AsyncReadStream, typename Allocator, typename ReadHandler> - inline void* asio_handler_allocate(std::size_t size, - read_until_delim_string_handler<AsyncReadStream, - Allocator, ReadHandler>* this_handler) - { - return boost_asio_handler_alloc_helpers::allocate( - size, this_handler->handler_); - } - - template <typename AsyncReadStream, typename Allocator, typename ReadHandler> - inline void asio_handler_deallocate(void* pointer, std::size_t size, - read_until_delim_string_handler<AsyncReadStream, - Allocator, ReadHandler>* this_handler) - { - boost_asio_handler_alloc_helpers::deallocate( - pointer, size, this_handler->handler_); - } - - template <typename Function, typename AsyncReadStream, - typename Allocator, typename ReadHandler> - inline void asio_handler_invoke(const Function& function, - read_until_delim_string_handler<AsyncReadStream, - Allocator, ReadHandler>* this_handler) - { - boost_asio_handler_invoke_helpers::invoke( - function, this_handler->handler_); - } -} // namespace detail - -template <typename AsyncReadStream, typename Allocator, typename ReadHandler> -void async_read_until(AsyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, const std::string& delim, - ReadHandler handler) -{ - // Determine the range of the data to be searched. - typedef typename boost::asio::basic_streambuf< - Allocator>::const_buffers_type const_buffers_type; - typedef boost::asio::buffers_iterator<const_buffers_type> iterator; - const_buffers_type buffers = b.data(); - iterator begin = iterator::begin(buffers); - iterator end = iterator::end(buffers); - - // Look for a match. - std::size_t next_search_start; - std::pair<iterator, bool> result = boost::asio::detail::partial_search( - begin, end, delim.begin(), delim.end()); - if (result.first != end) - { - if (result.second) - { - // Full match. We're done. - boost::system::error_code ec; - std::size_t bytes = result.first - begin + delim.length(); - s.get_io_service().post(detail::bind_handler(handler, ec, bytes)); - return; - } - else - { - // Partial match. Next search needs to start from beginning of match. - next_search_start = result.first - begin; - } - } - else - { - // No match. Next search can start with the new data. - next_search_start = end - begin; - } - - // Check if buffer is full. - if (b.size() == b.max_size()) - { - boost::system::error_code ec(error::not_found); - s.get_io_service().post(detail::bind_handler(handler, ec, 0)); - return; - } - - // Start a new asynchronous read operation to obtain more data. - std::size_t bytes_available = - std::min<std::size_t>(512, b.max_size() - b.size()); - s.async_read_some(b.prepare(bytes_available), - detail::read_until_delim_string_handler< - AsyncReadStream, Allocator, ReadHandler>( - s, b, delim, next_search_start, handler)); -} - -namespace detail -{ - template <typename AsyncReadStream, typename Allocator, typename ReadHandler> - class read_until_expr_handler - { - public: - read_until_expr_handler(AsyncReadStream& stream, - boost::asio::basic_streambuf<Allocator>& streambuf, - const boost::regex& expr, std::size_t next_search_start, - ReadHandler handler) - : stream_(stream), - streambuf_(streambuf), - expr_(expr), - next_search_start_(next_search_start), - handler_(handler) - { - } - - void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) - { - // Check for errors. - if (ec) - { - std::size_t bytes = 0; - handler_(ec, bytes); - return; - } - - // Commit received data to streambuf's get area. - streambuf_.commit(bytes_transferred); - - // Determine the range of the data to be searched. - typedef typename boost::asio::basic_streambuf< - Allocator>::const_buffers_type const_buffers_type; - typedef boost::asio::buffers_iterator<const_buffers_type> iterator; - const_buffers_type buffers = streambuf_.data(); - iterator begin = iterator::begin(buffers); - iterator start = begin + next_search_start_; - iterator end = iterator::end(buffers); - - // Look for a match. - boost::match_results<iterator> match_results; - if (boost::regex_search(start, end, match_results, expr_, - boost::match_default | boost::match_partial)) - { - if (match_results[0].matched) - { - // Full match. We're done. - std::size_t bytes = match_results[0].second - begin; - handler_(ec, bytes); - return; - } - else - { - // Partial match. Next search needs to start from beginning of match. - next_search_start_ = match_results[0].first - begin; - } - } - else - { - // No match. Next search can start with the new data. - next_search_start_ = end - begin; - } - - // Check if buffer is full. - if (streambuf_.size() == streambuf_.max_size()) - { - std::size_t bytes = 0; - boost::system::error_code ec(error::not_found); - handler_(ec, bytes); - return; - } - - // Start a new asynchronous read operation to obtain more data. - std::size_t bytes_available = - std::min<std::size_t>(512, streambuf_.max_size() - streambuf_.size()); - stream_.async_read_some(streambuf_.prepare(bytes_available), *this); - } - - //private: - AsyncReadStream& stream_; - boost::asio::basic_streambuf<Allocator>& streambuf_; - boost::regex expr_; - std::size_t next_search_start_; - ReadHandler handler_; - }; - - template <typename AsyncReadStream, typename Allocator, typename ReadHandler> - inline void* asio_handler_allocate(std::size_t size, - read_until_expr_handler<AsyncReadStream, - Allocator, ReadHandler>* this_handler) - { - return boost_asio_handler_alloc_helpers::allocate( - size, this_handler->handler_); - } - - template <typename AsyncReadStream, typename Allocator, typename ReadHandler> - inline void asio_handler_deallocate(void* pointer, std::size_t size, - read_until_expr_handler<AsyncReadStream, - Allocator, ReadHandler>* this_handler) - { - boost_asio_handler_alloc_helpers::deallocate( - pointer, size, this_handler->handler_); - } - - template <typename Function, typename AsyncReadStream, typename Allocator, - typename ReadHandler> - inline void asio_handler_invoke(const Function& function, - read_until_expr_handler<AsyncReadStream, - Allocator, ReadHandler>* this_handler) - { - boost_asio_handler_invoke_helpers::invoke( - function, this_handler->handler_); - } -} // namespace detail - -template <typename AsyncReadStream, typename Allocator, typename ReadHandler> -void async_read_until(AsyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr, - ReadHandler handler) -{ - // Determine the range of the data to be searched. - typedef typename boost::asio::basic_streambuf< - Allocator>::const_buffers_type const_buffers_type; - typedef boost::asio::buffers_iterator<const_buffers_type> iterator; - const_buffers_type buffers = b.data(); - iterator begin = iterator::begin(buffers); - iterator end = iterator::end(buffers); - - // Look for a match. - std::size_t next_search_start; - boost::match_results<iterator> match_results; - if (boost::regex_search(begin, end, match_results, expr, - boost::match_default | boost::match_partial)) - { - if (match_results[0].matched) - { - // Full match. We're done. - boost::system::error_code ec; - std::size_t bytes = match_results[0].second - begin; - s.get_io_service().post(detail::bind_handler(handler, ec, bytes)); - return; - } - else - { - // Partial match. Next search needs to start from beginning of match. - next_search_start = match_results[0].first - begin; - } - } - else - { - // No match. Next search can start with the new data. - next_search_start = end - begin; - } - - // Check if buffer is full. - if (b.size() == b.max_size()) - { - boost::system::error_code ec(error::not_found); - s.get_io_service().post(detail::bind_handler(handler, ec, 0)); - return; - } - - // Start a new asynchronous read operation to obtain more data. - std::size_t bytes_available = - std::min<std::size_t>(512, b.max_size() - b.size()); - s.async_read_some(b.prepare(bytes_available), - detail::read_until_expr_handler<AsyncReadStream, Allocator, ReadHandler>( - s, b, expr, next_search_start, handler)); -} - -namespace detail -{ - template <typename AsyncReadStream, typename Allocator, - typename MatchCondition, typename ReadHandler> - class read_until_match_handler - { - public: - read_until_match_handler(AsyncReadStream& stream, - boost::asio::basic_streambuf<Allocator>& streambuf, - MatchCondition match_condition, std::size_t next_search_start, - ReadHandler handler) - : stream_(stream), - streambuf_(streambuf), - match_condition_(match_condition), - next_search_start_(next_search_start), - handler_(handler) - { - } - - void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) - { - // Check for errors. - if (ec) - { - std::size_t bytes = 0; - handler_(ec, bytes); - return; - } - - // Commit received data to streambuf's get area. - streambuf_.commit(bytes_transferred); - - // Determine the range of the data to be searched. - typedef typename boost::asio::basic_streambuf< - Allocator>::const_buffers_type const_buffers_type; - typedef boost::asio::buffers_iterator<const_buffers_type> iterator; - const_buffers_type buffers = streambuf_.data(); - iterator begin = iterator::begin(buffers); - iterator start = begin + next_search_start_; - iterator end = iterator::end(buffers); - - // Look for a match. - std::pair<iterator, bool> result = match_condition_(start, end); - if (result.second) - { - // Full match. We're done. - std::size_t bytes = result.first - begin; - handler_(ec, bytes); - return; - } - else if (result.first != end) - { - // Partial match. Next search needs to start from beginning of match. - next_search_start_ = result.first - begin; - } - else - { - // No match. Next search can start with the new data. - next_search_start_ = end - begin; - } - - // Check if buffer is full. - if (streambuf_.size() == streambuf_.max_size()) - { - std::size_t bytes = 0; - boost::system::error_code ec(error::not_found); - handler_(ec, bytes); - return; - } - - // Start a new asynchronous read operation to obtain more data. - std::size_t bytes_available = - std::min<std::size_t>(512, streambuf_.max_size() - streambuf_.size()); - stream_.async_read_some(streambuf_.prepare(bytes_available), *this); - } - - //private: - AsyncReadStream& stream_; - boost::asio::basic_streambuf<Allocator>& streambuf_; - MatchCondition match_condition_; - std::size_t next_search_start_; - ReadHandler handler_; - }; - - template <typename AsyncReadStream, typename Allocator, - typename MatchCondition, typename ReadHandler> - inline void* asio_handler_allocate(std::size_t size, - read_until_match_handler<AsyncReadStream, - Allocator, MatchCondition, ReadHandler>* this_handler) - { - return boost_asio_handler_alloc_helpers::allocate( - size, this_handler->handler_); - } - - template <typename AsyncReadStream, typename Allocator, - typename MatchCondition, typename ReadHandler> - inline void asio_handler_deallocate(void* pointer, std::size_t size, - read_until_match_handler<AsyncReadStream, - Allocator, MatchCondition, ReadHandler>* this_handler) - { - boost_asio_handler_alloc_helpers::deallocate( - pointer, size, this_handler->handler_); - } - - template <typename Function, typename AsyncReadStream, typename Allocator, - typename MatchCondition, typename ReadHandler> - inline void asio_handler_invoke(const Function& function, - read_until_match_handler<AsyncReadStream, - Allocator, MatchCondition, ReadHandler>* this_handler) - { - boost_asio_handler_invoke_helpers::invoke( - function, this_handler->handler_); - } -} // namespace detail - -template <typename AsyncReadStream, typename Allocator, - typename MatchCondition, typename ReadHandler> -void async_read_until(AsyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, - MatchCondition match_condition, ReadHandler handler, - typename boost::enable_if<is_match_condition<MatchCondition> >::type*) -{ - // Determine the range of the data to be searched. - typedef typename boost::asio::basic_streambuf< - Allocator>::const_buffers_type const_buffers_type; - typedef boost::asio::buffers_iterator<const_buffers_type> iterator; - const_buffers_type buffers = b.data(); - iterator begin = iterator::begin(buffers); - iterator end = iterator::end(buffers); - - // Look for a match. - std::size_t next_search_start; - std::pair<iterator, bool> result = match_condition(begin, end); - if (result.second) - { - // Full match. We're done. - boost::system::error_code ec; - std::size_t bytes = result.first - begin; - s.get_io_service().post(detail::bind_handler(handler, ec, bytes)); - return; - } - else if (result.first != end) - { - // Partial match. Next search needs to start from beginning of match. - next_search_start = result.first - begin; - } - else - { - // No match. Next search can start with the new data. - next_search_start = end - begin; - } - - // Check if buffer is full. - if (b.size() == b.max_size()) - { - boost::system::error_code ec(error::not_found); - s.get_io_service().post(detail::bind_handler(handler, ec, 0)); - return; - } - - // Start a new asynchronous read operation to obtain more data. - std::size_t bytes_available = - std::min<std::size_t>(512, b.max_size() - b.size()); - s.async_read_some(b.prepare(bytes_available), - detail::read_until_match_handler< - AsyncReadStream, Allocator, MatchCondition, ReadHandler>( - s, b, match_condition, next_search_start, handler)); -} - -} // namespace asio -} // namespace boost - -#include <boost/asio/detail/pop_options.hpp> - -#endif // BOOST_ASIO_READ_UNTIL_IPP diff --git a/3rdParty/Boost/src/boost/asio/impl/serial_port_base.hpp b/3rdParty/Boost/src/boost/asio/impl/serial_port_base.hpp new file mode 100644 index 0000000..2b291f3 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/impl/serial_port_base.hpp @@ -0,0 +1,61 @@ +// +// impl/serial_port_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.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) +// + +#ifndef BOOST_ASIO_IMPL_SERIAL_PORT_BASE_HPP +#define BOOST_ASIO_IMPL_SERIAL_PORT_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { + +inline serial_port_base::baud_rate::baud_rate(unsigned int rate) + : value_(rate) +{ +} + +inline unsigned int serial_port_base::baud_rate::value() const +{ + return value_; +} + +inline serial_port_base::flow_control::type +serial_port_base::flow_control::value() const +{ + return value_; +} + +inline serial_port_base::parity::type serial_port_base::parity::value() const +{ + return value_; +} + +inline serial_port_base::stop_bits::type +serial_port_base::stop_bits::value() const +{ + return value_; +} + +inline unsigned int serial_port_base::character_size::value() const +{ + return value_; +} + +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_IMPL_SERIAL_PORT_BASE_HPP diff --git a/3rdParty/Boost/src/boost/asio/impl/serial_port_base.ipp b/3rdParty/Boost/src/boost/asio/impl/serial_port_base.ipp index 2775a02..2bfe58a 100644 --- a/3rdParty/Boost/src/boost/asio/impl/serial_port_base.ipp +++ b/3rdParty/Boost/src/boost/asio/impl/serial_port_base.ipp @@ -1,6 +1,6 @@ // -// serial_port_base.ipp -// ~~~~~~~~~~~~~~~~~~~~ +// impl/serial_port_base.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) @@ -9,33 +9,36 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef BOOST_ASIO_SERIAL_PORT_BASE_IPP -#define BOOST_ASIO_SERIAL_PORT_BASE_IPP +#ifndef BOOST_ASIO_IMPL_SERIAL_PORT_BASE_IPP +#define BOOST_ASIO_IMPL_SERIAL_PORT_BASE_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> +#if defined(BOOST_ASIO_HAS_SERIAL_PORT) + +#include <stdexcept> #include <boost/throw_exception.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/serial_port_base.hpp> -namespace boost { -namespace asio { +#if defined(GENERATING_DOCUMENTATION) +# define BOOST_ASIO_OPTION_STORAGE implementation_defined +#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# define BOOST_ASIO_OPTION_STORAGE DCB +#else +# define BOOST_ASIO_OPTION_STORAGE termios +#endif -inline serial_port_base::baud_rate::baud_rate(unsigned int rate) - : value_(rate) -{ -} +#include <boost/asio/detail/push_options.hpp> -inline unsigned int serial_port_base::baud_rate::value() const -{ - return value_; -} +namespace boost { +namespace asio { -inline boost::system::error_code serial_port_base::baud_rate::store( +boost::system::error_code serial_port_base::baud_rate::store( BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const { #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -123,7 +126,7 @@ inline boost::system::error_code serial_port_base::baud_rate::store( return ec; } -inline boost::system::error_code serial_port_base::baud_rate::load( +boost::system::error_code serial_port_base::baud_rate::load( const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) { #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -205,7 +208,7 @@ inline boost::system::error_code serial_port_base::baud_rate::load( return ec; } -inline serial_port_base::flow_control::flow_control( +serial_port_base::flow_control::flow_control( serial_port_base::flow_control::type t) : value_(t) { @@ -216,13 +219,7 @@ inline serial_port_base::flow_control::flow_control( } } -inline serial_port_base::flow_control::type -serial_port_base::flow_control::value() const -{ - return value_; -} - -inline boost::system::error_code serial_port_base::flow_control::store( +boost::system::error_code serial_port_base::flow_control::store( BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const { #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -256,12 +253,16 @@ inline boost::system::error_code serial_port_base::flow_control::store( storage.c_iflag &= ~(IXOFF | IXON); # if defined(_BSD_SOURCE) storage.c_cflag &= ~CRTSCTS; +# elif defined(__QNXNTO__) + storage.c_cflag &= ~(IHFLOW | OHFLOW); # endif break; case software: storage.c_iflag |= IXOFF | IXON; # if defined(_BSD_SOURCE) storage.c_cflag &= ~CRTSCTS; +# elif defined(__QNXNTO__) + storage.c_cflag &= ~(IHFLOW | OHFLOW); # endif break; case hardware: @@ -269,6 +270,10 @@ inline boost::system::error_code serial_port_base::flow_control::store( storage.c_iflag &= ~(IXOFF | IXON); storage.c_cflag |= CRTSCTS; break; +# elif defined(__QNXNTO__) + storage.c_iflag &= ~(IXOFF | IXON); + storage.c_cflag |= (IHFLOW | OHFLOW); + break; # else ec = boost::asio::error::operation_not_supported; return ec; @@ -281,7 +286,7 @@ inline boost::system::error_code serial_port_base::flow_control::store( return ec; } -inline boost::system::error_code serial_port_base::flow_control::load( +boost::system::error_code serial_port_base::flow_control::load( const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) { #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -307,6 +312,11 @@ inline boost::system::error_code serial_port_base::flow_control::load( { value_ = hardware; } +# elif defined(__QNXNTO__) + else if (storage.c_cflag & IHFLOW && storage.c_cflag & OHFLOW) + { + value_ = hardware; + } # endif else { @@ -317,7 +327,7 @@ inline boost::system::error_code serial_port_base::flow_control::load( return ec; } -inline serial_port_base::parity::parity(serial_port_base::parity::type t) +serial_port_base::parity::parity(serial_port_base::parity::type t) : value_(t) { if (t != none && t != odd && t != even) @@ -327,12 +337,7 @@ inline serial_port_base::parity::parity(serial_port_base::parity::type t) } } -inline serial_port_base::parity::type serial_port_base::parity::value() const -{ - return value_; -} - -inline boost::system::error_code serial_port_base::parity::store( +boost::system::error_code serial_port_base::parity::store( BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const { #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -379,7 +384,7 @@ inline boost::system::error_code serial_port_base::parity::store( return ec; } -inline boost::system::error_code serial_port_base::parity::load( +boost::system::error_code serial_port_base::parity::load( const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) { #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -416,7 +421,7 @@ inline boost::system::error_code serial_port_base::parity::load( return ec; } -inline serial_port_base::stop_bits::stop_bits( +serial_port_base::stop_bits::stop_bits( serial_port_base::stop_bits::type t) : value_(t) { @@ -427,13 +432,7 @@ inline serial_port_base::stop_bits::stop_bits( } } -inline serial_port_base::stop_bits::type -serial_port_base::stop_bits::value() const -{ - return value_; -} - -inline boost::system::error_code serial_port_base::stop_bits::store( +boost::system::error_code serial_port_base::stop_bits::store( BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const { #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -469,7 +468,7 @@ inline boost::system::error_code serial_port_base::stop_bits::store( return ec; } -inline boost::system::error_code serial_port_base::stop_bits::load( +boost::system::error_code serial_port_base::stop_bits::load( const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) { #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -496,7 +495,7 @@ inline boost::system::error_code serial_port_base::stop_bits::load( return ec; } -inline serial_port_base::character_size::character_size(unsigned int t) +serial_port_base::character_size::character_size(unsigned int t) : value_(t) { if (t < 5 || t > 8) @@ -506,12 +505,7 @@ inline serial_port_base::character_size::character_size(unsigned int t) } } -inline unsigned int serial_port_base::character_size::value() const -{ - return value_; -} - -inline boost::system::error_code serial_port_base::character_size::store( +boost::system::error_code serial_port_base::character_size::store( BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const { #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -531,7 +525,7 @@ inline boost::system::error_code serial_port_base::character_size::store( return ec; } -inline boost::system::error_code serial_port_base::character_size::load( +boost::system::error_code serial_port_base::character_size::load( const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) { #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) @@ -556,4 +550,8 @@ inline boost::system::error_code serial_port_base::character_size::load( #include <boost/asio/detail/pop_options.hpp> -#endif // BOOST_ASIO_SERIAL_PORT_BASE_IPP +#undef BOOST_ASIO_OPTION_STORAGE + +#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT) + +#endif // BOOST_ASIO_IMPL_SERIAL_PORT_BASE_IPP diff --git a/3rdParty/Boost/src/boost/asio/impl/write.ipp b/3rdParty/Boost/src/boost/asio/impl/write.hpp index 28a5273..fa2982a 100644 --- a/3rdParty/Boost/src/boost/asio/impl/write.ipp +++ b/3rdParty/Boost/src/boost/asio/impl/write.hpp @@ -1,6 +1,6 @@ // -// write.ipp -// ~~~~~~~~~ +// impl/write.hpp +// ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -8,15 +8,13 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef BOOST_ASIO_WRITE_IPP -#define BOOST_ASIO_WRITE_IPP +#ifndef BOOST_ASIO_IMPL_WRITE_HPP +#define BOOST_ASIO_IMPL_WRITE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - #include <boost/asio/buffer.hpp> #include <boost/asio/completion_condition.hpp> #include <boost/asio/detail/base_from_completion_cond.hpp> @@ -26,6 +24,8 @@ #include <boost/asio/detail/handler_invoke_helpers.hpp> #include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { @@ -123,31 +123,30 @@ namespace detail stream_(stream), buffers_(buffers), total_transferred_(0), - handler_(handler), - start_(true) + handler_(handler) { } void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) + std::size_t bytes_transferred, int start = 0) { - switch (start_) + switch (start) { - case true: start_ = false; - buffers_.prepare(this->check(ec, total_transferred_)); + case 1: + buffers_.prepare(this->check_for_completion(ec, total_transferred_)); for (;;) { stream_.async_write_some(buffers_, *this); return; default: total_transferred_ += bytes_transferred; buffers_.consume(bytes_transferred); - buffers_.prepare(this->check(ec, total_transferred_)); + buffers_.prepare(this->check_for_completion(ec, total_transferred_)); if ((!ec && bytes_transferred == 0) || buffers_.begin() == buffers_.end()) break; } - handler_(ec, total_transferred_); + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); } } @@ -157,7 +156,6 @@ namespace detail const_buffer, ConstBufferSequence> buffers_; std::size_t total_transferred_; WriteHandler handler_; - bool start_; }; template <typename AsyncWriteStream, @@ -176,19 +174,18 @@ namespace detail stream_(stream), buffer_(buffers), total_transferred_(0), - handler_(handler), - start_(true) + handler_(handler) { } void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) + std::size_t bytes_transferred, int start = 0) { std::size_t n = 0; - switch (start_) + switch (start) { - case true: start_ = false; - n = this->check(ec, total_transferred_); + case 1: + n = this->check_for_completion(ec, total_transferred_); for (;;) { stream_.async_write_some(boost::asio::buffer( @@ -196,12 +193,12 @@ namespace detail return; default: total_transferred_ += bytes_transferred; if ((!ec && bytes_transferred == 0) - || (n = this->check(ec, total_transferred_)) == 0 + || (n = this->check_for_completion(ec, total_transferred_)) == 0 || total_transferred_ == boost::asio::buffer_size(buffer_)) break; } - handler_(ec, total_transferred_); + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); } } @@ -210,7 +207,6 @@ namespace detail boost::asio::mutable_buffer buffer_; std::size_t total_transferred_; WriteHandler handler_; - bool start_; }; template <typename AsyncWriteStream, @@ -229,19 +225,18 @@ namespace detail stream_(stream), buffer_(buffers), total_transferred_(0), - handler_(handler), - start_(true) + handler_(handler) { } void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) + std::size_t bytes_transferred, int start = 0) { std::size_t n = 0; - switch (start_) + switch (start) { - case true: start_ = false; - n = this->check(ec, total_transferred_); + case 1: + n = this->check_for_completion(ec, total_transferred_); for (;;) { stream_.async_write_some(boost::asio::buffer( @@ -249,12 +244,12 @@ namespace detail return; default: total_transferred_ += bytes_transferred; if ((!ec && bytes_transferred == 0) - || (n = this->check(ec, total_transferred_)) == 0 + || (n = this->check_for_completion(ec, total_transferred_)) == 0 || total_transferred_ == boost::asio::buffer_size(buffer_)) break; } - handler_(ec, total_transferred_); + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); } } @@ -263,7 +258,6 @@ namespace detail boost::asio::const_buffer buffer_; std::size_t total_transferred_; WriteHandler handler_; - bool start_; }; template <typename AsyncWriteStream, typename ConstBufferSequence, @@ -306,7 +300,7 @@ inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, detail::write_op<AsyncWriteStream, ConstBufferSequence, CompletionCondition, WriteHandler>( s, buffers, completion_condition, handler)( - boost::system::error_code(), 0); + boost::system::error_code(), 0, 1); } template <typename AsyncWriteStream, typename ConstBufferSequence, @@ -334,7 +328,7 @@ namespace detail } void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) + const std::size_t bytes_transferred) { streambuf_.consume(bytes_transferred); handler_(ec, bytes_transferred); @@ -401,4 +395,4 @@ inline void async_write(AsyncWriteStream& s, #include <boost/asio/detail/pop_options.hpp> -#endif // BOOST_ASIO_WRITE_IPP +#endif // BOOST_ASIO_IMPL_WRITE_HPP diff --git a/3rdParty/Boost/src/boost/asio/impl/write_at.ipp b/3rdParty/Boost/src/boost/asio/impl/write_at.hpp index 3d1a112..aad64ef 100644 --- a/3rdParty/Boost/src/boost/asio/impl/write_at.ipp +++ b/3rdParty/Boost/src/boost/asio/impl/write_at.hpp @@ -1,6 +1,6 @@ // -// write_at.ipp -// ~~~~~~~~~~~~ +// impl/write_at.hpp +// ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -8,23 +8,24 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef BOOST_ASIO_WRITE_AT_IPP -#define BOOST_ASIO_WRITE_AT_IPP +#ifndef BOOST_ASIO_IMPL_WRITE_AT_HPP +#define BOOST_ASIO_IMPL_WRITE_AT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - #include <boost/asio/buffer.hpp> #include <boost/asio/completion_condition.hpp> +#include <boost/asio/detail/base_from_completion_cond.hpp> #include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/consuming_buffers.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> #include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { @@ -119,55 +120,166 @@ namespace detail { template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> - class write_at_handler + class write_at_op + : detail::base_from_completion_cond<CompletionCondition> { public: - typedef boost::asio::detail::consuming_buffers< - const_buffer, ConstBufferSequence> buffers_type; - - write_at_handler(AsyncRandomAccessWriteDevice& stream, - boost::uint64_t offset, const buffers_type& buffers, + write_at_op(AsyncRandomAccessWriteDevice& device, + boost::uint64_t offset, const ConstBufferSequence& buffers, CompletionCondition completion_condition, WriteHandler handler) - : stream_(stream), + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + device_(device), + offset_(offset), buffers_(buffers), + total_transferred_(0), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + switch (start) + { + case 1: + buffers_.prepare(this->check_for_completion(ec, total_transferred_)); + for (;;) + { + device_.async_write_some_at( + offset_ + total_transferred_, buffers_, *this); + return; default: + total_transferred_ += bytes_transferred; + buffers_.consume(bytes_transferred); + buffers_.prepare(this->check_for_completion(ec, total_transferred_)); + if ((!ec && bytes_transferred == 0) + || buffers_.begin() == buffers_.end()) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); + } + } + + //private: + AsyncRandomAccessWriteDevice& device_; + boost::uint64_t offset_; + boost::asio::detail::consuming_buffers< + const_buffer, ConstBufferSequence> buffers_; + std::size_t total_transferred_; + WriteHandler handler_; + }; + + template <typename AsyncRandomAccessWriteDevice, + typename CompletionCondition, typename WriteHandler> + class write_at_op<AsyncRandomAccessWriteDevice, + boost::asio::mutable_buffers_1, CompletionCondition, WriteHandler> + : detail::base_from_completion_cond<CompletionCondition> + { + public: + write_at_op(AsyncRandomAccessWriteDevice& device, + boost::uint64_t offset, const boost::asio::mutable_buffers_1& buffers, + CompletionCondition completion_condition, + WriteHandler handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + device_(device), offset_(offset), + buffer_(buffers), total_transferred_(0), - completion_condition_(completion_condition), handler_(handler) { } void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) + std::size_t bytes_transferred, int start = 0) { - total_transferred_ += bytes_transferred; - buffers_.consume(bytes_transferred); - buffers_.prepare(detail::adapt_completion_condition_result( - completion_condition_(ec, total_transferred_))); - if (buffers_.begin() == buffers_.end()) + std::size_t n = 0; + switch (start) { - handler_(ec, total_transferred_); + case 1: + n = this->check_for_completion(ec, total_transferred_); + for (;;) + { + device_.async_write_some_at(offset_ + total_transferred_, + boost::asio::buffer(buffer_ + total_transferred_, n), *this); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check_for_completion(ec, total_transferred_)) == 0 + || total_transferred_ == boost::asio::buffer_size(buffer_)) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); } - else + } + + //private: + AsyncRandomAccessWriteDevice& device_; + boost::uint64_t offset_; + boost::asio::mutable_buffer buffer_; + std::size_t total_transferred_; + WriteHandler handler_; + }; + + template <typename AsyncRandomAccessWriteDevice, + typename CompletionCondition, typename WriteHandler> + class write_at_op<AsyncRandomAccessWriteDevice, boost::asio::const_buffers_1, + CompletionCondition, WriteHandler> + : detail::base_from_completion_cond<CompletionCondition> + { + public: + write_at_op(AsyncRandomAccessWriteDevice& device, + boost::uint64_t offset, const boost::asio::const_buffers_1& buffers, + CompletionCondition completion_condition, + WriteHandler handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + device_(device), + offset_(offset), + buffer_(buffers), + total_transferred_(0), + handler_(handler) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + std::size_t n = 0; + switch (start) { - stream_.async_write_some_at( - offset_ + total_transferred_, buffers_, *this); + case 1: + n = this->check_for_completion(ec, total_transferred_); + for (;;) + { + device_.async_write_some_at(offset_ + total_transferred_, + boost::asio::buffer(buffer_ + total_transferred_, n), *this); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check_for_completion(ec, total_transferred_)) == 0 + || total_transferred_ == boost::asio::buffer_size(buffer_)) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); } } //private: - AsyncRandomAccessWriteDevice& stream_; - buffers_type buffers_; + AsyncRandomAccessWriteDevice& device_; boost::uint64_t offset_; + boost::asio::const_buffer buffer_; std::size_t total_transferred_; - CompletionCondition completion_condition_; WriteHandler handler_; }; template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> inline void* asio_handler_allocate(std::size_t size, - write_at_handler<AsyncRandomAccessWriteDevice, ConstBufferSequence, + write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence, CompletionCondition, WriteHandler>* this_handler) { return boost_asio_handler_alloc_helpers::allocate( @@ -177,7 +289,7 @@ namespace detail template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> inline void asio_handler_deallocate(void* pointer, std::size_t size, - write_at_handler<AsyncRandomAccessWriteDevice, ConstBufferSequence, + write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence, CompletionCondition, WriteHandler>* this_handler) { boost_asio_handler_alloc_helpers::deallocate( @@ -188,7 +300,7 @@ namespace detail typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> inline void asio_handler_invoke(const Function& function, - write_at_handler<AsyncRandomAccessWriteDevice, ConstBufferSequence, + write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence, CompletionCondition, WriteHandler>* this_handler) { boost_asio_handler_invoke_helpers::invoke( @@ -202,24 +314,10 @@ inline void async_write_at(AsyncRandomAccessWriteDevice& d, boost::uint64_t offset, const ConstBufferSequence& buffers, CompletionCondition completion_condition, WriteHandler handler) { - boost::asio::detail::consuming_buffers< - const_buffer, ConstBufferSequence> tmp(buffers); - - boost::system::error_code ec; - std::size_t total_transferred = 0; - tmp.prepare(detail::adapt_completion_condition_result( - completion_condition(ec, total_transferred))); - if (tmp.begin() == tmp.end()) - { - d.get_io_service().post(detail::bind_handler( - handler, ec, total_transferred)); - return; - } - - d.async_write_some_at(offset, tmp, - detail::write_at_handler<AsyncRandomAccessWriteDevice, - ConstBufferSequence, CompletionCondition, WriteHandler>( - d, offset, tmp, completion_condition, handler)); + detail::write_at_op<AsyncRandomAccessWriteDevice, + ConstBufferSequence, CompletionCondition, WriteHandler>( + d, offset, buffers, completion_condition, handler)( + boost::system::error_code(), 0, 1); } template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, @@ -235,12 +333,12 @@ inline void async_write_at(AsyncRandomAccessWriteDevice& d, namespace detail { - template <typename AsyncRandomAccessWriteDevice, typename Allocator, - typename WriteHandler> - class write_at_streambuf_handler + template <typename AsyncRandomAccessWriteDevice, + typename Allocator, typename WriteHandler> + class write_at_streambuf_op { public: - write_at_streambuf_handler( + write_at_streambuf_op( boost::asio::basic_streambuf<Allocator>& streambuf, WriteHandler handler) : streambuf_(streambuf), @@ -249,7 +347,7 @@ namespace detail } void operator()(const boost::system::error_code& ec, - std::size_t bytes_transferred) + const std::size_t bytes_transferred) { streambuf_.consume(bytes_transferred); handler_(ec, bytes_transferred); @@ -263,7 +361,7 @@ namespace detail template <typename AsyncRandomAccessWriteDevice, typename Allocator, typename WriteHandler> inline void* asio_handler_allocate(std::size_t size, - write_at_streambuf_handler<AsyncRandomAccessWriteDevice, + write_at_streambuf_op<AsyncRandomAccessWriteDevice, Allocator, WriteHandler>* this_handler) { return boost_asio_handler_alloc_helpers::allocate( @@ -273,7 +371,7 @@ namespace detail template <typename AsyncRandomAccessWriteDevice, typename Allocator, typename WriteHandler> inline void asio_handler_deallocate(void* pointer, std::size_t size, - write_at_streambuf_handler<AsyncRandomAccessWriteDevice, + write_at_streambuf_op<AsyncRandomAccessWriteDevice, Allocator, WriteHandler>* this_handler) { boost_asio_handler_alloc_helpers::deallocate( @@ -283,7 +381,7 @@ namespace detail template <typename Function, typename AsyncRandomAccessWriteDevice, typename Allocator, typename WriteHandler> inline void asio_handler_invoke(const Function& function, - write_at_streambuf_handler<AsyncRandomAccessWriteDevice, + write_at_streambuf_op<AsyncRandomAccessWriteDevice, Allocator, WriteHandler>* this_handler) { boost_asio_handler_invoke_helpers::invoke( @@ -298,7 +396,7 @@ inline void async_write_at(AsyncRandomAccessWriteDevice& d, CompletionCondition completion_condition, WriteHandler handler) { async_write_at(d, offset, b.data(), completion_condition, - detail::write_at_streambuf_handler< + detail::write_at_streambuf_op< AsyncRandomAccessWriteDevice, Allocator, WriteHandler>(b, handler)); } @@ -318,4 +416,4 @@ inline void async_write_at(AsyncRandomAccessWriteDevice& d, #include <boost/asio/detail/pop_options.hpp> -#endif // BOOST_ASIO_WRITE_AT_IPP +#endif // BOOST_ASIO_IMPL_WRITE_AT_HPP diff --git a/3rdParty/Boost/src/boost/asio/io_service.hpp b/3rdParty/Boost/src/boost/asio/io_service.hpp index 3863e96..9350a84 100644 --- a/3rdParty/Boost/src/boost/asio/io_service.hpp +++ b/3rdParty/Boost/src/boost/asio/io_service.hpp @@ -15,25 +15,29 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> #include <stdexcept> #include <typeinfo> -#include <boost/config.hpp> -#include <boost/throw_exception.hpp> -#include <boost/system/error_code.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/detail/noncopyable.hpp> -#include <boost/asio/detail/reactor_fwd.hpp> #include <boost/asio/detail/service_registry_fwd.hpp> -#include <boost/asio/detail/signal_init.hpp> -#include <boost/asio/detail/task_io_service_fwd.hpp> -#include <boost/asio/detail/win_iocp_io_service_fwd.hpp> -#include <boost/asio/detail/winsock_init.hpp> #include <boost/asio/detail/wrapped_handler.hpp> +#include <boost/system/error_code.hpp> + +#if defined(BOOST_ASIO_HAS_IOCP) +# include <boost/asio/detail/win_iocp_io_service_fwd.hpp> +#else +# include <boost/asio/detail/task_io_service_fwd.hpp> +#endif + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# include <boost/asio/detail/winsock_init.hpp> +#elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \ + || defined(__osf__) +# include <boost/asio/detail/signal_init.hpp> +#endif + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -46,7 +50,7 @@ template <typename Service> bool has_service(io_service& ios); #if defined(BOOST_ASIO_HAS_IOCP) namespace detail { typedef win_iocp_io_service io_service_impl; } #else -namespace detail { typedef task_io_service<reactor> io_service_impl; } +namespace detail { typedef task_io_service io_service_impl; } #endif /// Provides core I/O functionality. @@ -197,7 +201,7 @@ public: class strand; /// Constructor. - io_service(); + BOOST_ASIO_DECL io_service(); /// Constructor. /** @@ -206,7 +210,7 @@ public: * @param concurrency_hint A suggestion to the implementation on how many * threads it should allow to run simultaneously. */ - explicit io_service(std::size_t concurrency_hint); + BOOST_ASIO_DECL explicit io_service(std::size_t concurrency_hint); /// Destructor. /** @@ -240,7 +244,7 @@ public: * destructor defined above destroys all handlers, causing all @c shared_ptr * references to all connection objects to be destroyed. */ - ~io_service(); + BOOST_ASIO_DECL ~io_service(); /// Run the io_service object's event processing loop. /** @@ -266,7 +270,7 @@ public: * The poll() function may also be used to dispatch ready handlers, but * without blocking. */ - std::size_t run(); + BOOST_ASIO_DECL std::size_t run(); /// Run the io_service object's event processing loop. /** @@ -292,7 +296,7 @@ public: * The poll() function may also be used to dispatch ready handlers, but * without blocking. */ - std::size_t run(boost::system::error_code& ec); + BOOST_ASIO_DECL std::size_t run(boost::system::error_code& ec); /// Run the io_service object's event processing loop to execute at most one /// handler. @@ -304,7 +308,7 @@ public: * * @throws boost::system::system_error Thrown on failure. */ - std::size_t run_one(); + BOOST_ASIO_DECL std::size_t run_one(); /// Run the io_service object's event processing loop to execute at most one /// handler. @@ -316,7 +320,7 @@ public: * * @return The number of handlers that were executed. */ - std::size_t run_one(boost::system::error_code& ec); + BOOST_ASIO_DECL std::size_t run_one(boost::system::error_code& ec); /// Run the io_service object's event processing loop to execute ready /// handlers. @@ -328,7 +332,7 @@ public: * * @throws boost::system::system_error Thrown on failure. */ - std::size_t poll(); + BOOST_ASIO_DECL std::size_t poll(); /// Run the io_service object's event processing loop to execute ready /// handlers. @@ -340,7 +344,7 @@ public: * * @return The number of handlers that were executed. */ - std::size_t poll(boost::system::error_code& ec); + BOOST_ASIO_DECL std::size_t poll(boost::system::error_code& ec); /// Run the io_service object's event processing loop to execute one ready /// handler. @@ -352,7 +356,7 @@ public: * * @throws boost::system::system_error Thrown on failure. */ - std::size_t poll_one(); + BOOST_ASIO_DECL std::size_t poll_one(); /// Run the io_service object's event processing loop to execute one ready /// handler. @@ -364,7 +368,7 @@ public: * * @return The number of handlers that were executed. */ - std::size_t poll_one(boost::system::error_code& ec); + BOOST_ASIO_DECL std::size_t poll_one(boost::system::error_code& ec); /// Stop the io_service object's event processing loop. /** @@ -373,7 +377,7 @@ public: * return as soon as possible. Subsequent calls to run(), run_one(), poll() * or poll_one() will return immediately until reset() is called. */ - void stop(); + BOOST_ASIO_DECL void stop(); /// Reset the io_service in preparation for a subsequent run() invocation. /** @@ -386,7 +390,7 @@ public: * This function must not be called while there are any unfinished calls to * the run(), run_one(), poll() or poll_one() functions. */ - void reset(); + BOOST_ASIO_DECL void reset(); /// Request the io_service to invoke the given handler. /** @@ -606,10 +610,10 @@ protected: /** * @param owner The io_service object that owns the service. */ - service(boost::asio::io_service& owner); + BOOST_ASIO_DECL service(boost::asio::io_service& owner); /// Destructor. - virtual ~service(); + BOOST_ASIO_DECL virtual ~service(); private: /// Destroy all user-defined handler objects owned by the service. @@ -632,10 +636,7 @@ class service_already_exists : public std::logic_error { public: - service_already_exists() - : std::logic_error("Service already exists.") - { - } + BOOST_ASIO_DECL service_already_exists(); }; /// Exception thrown when trying to add a service object to an io_service where @@ -644,17 +645,45 @@ class invalid_service_owner : public std::logic_error { public: - invalid_service_owner() - : std::logic_error("Invalid service owner.") + BOOST_ASIO_DECL invalid_service_owner(); +}; + +namespace detail { + +// Special derived service id type to keep classes header-file only. +template <typename Type> +class service_id + : public boost::asio::io_service::id +{ +}; + +// Special service base class to keep classes header-file only. +template <typename Type> +class service_base + : public boost::asio::io_service::service +{ +public: + static boost::asio::detail::service_id<Type> id; + + // Constructor. + service_base(boost::asio::io_service& io_service) + : boost::asio::io_service::service(io_service) { } }; +template <typename Type> +boost::asio::detail::service_id<Type> service_base<Type>::id; + +} // namespace detail } // namespace asio } // namespace boost -#include <boost/asio/impl/io_service.ipp> - #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/impl/io_service.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/impl/io_service.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + #endif // BOOST_ASIO_IO_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/ip/address.hpp b/3rdParty/Boost/src/boost/asio/ip/address.hpp index 16113f0..8cc3a4b 100644 --- a/3rdParty/Boost/src/boost/asio/ip/address.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/address.hpp @@ -1,6 +1,6 @@ // -// address.hpp -// ~~~~~~~~~~~ +// ip/address.hpp +// ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,21 +15,17 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> +#include <string> +#include <boost/system/error_code.hpp> +#include <boost/asio/ip/address_v4.hpp> +#include <boost/asio/ip/address_v6.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> #if !defined(BOOST_NO_IOSTREAM) # include <iosfwd> #endif // !defined(BOOST_NO_IOSTREAM) -#include <string> -#include <boost/throw_exception.hpp> -#include <boost/asio/detail/pop_options.hpp> -#include <boost/asio/error.hpp> -#include <boost/asio/ip/address_v4.hpp> -#include <boost/asio/ip/address_v6.hpp> -#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -48,63 +44,27 @@ class address { public: /// Default constructor. - address() - : type_(ipv4), - ipv4_address_(), - ipv6_address_() - { - } + BOOST_ASIO_DECL address(); /// Construct an address from an IPv4 address. - address(const boost::asio::ip::address_v4& ipv4_address) - : type_(ipv4), - ipv4_address_(ipv4_address), - ipv6_address_() - { - } + BOOST_ASIO_DECL address(const boost::asio::ip::address_v4& ipv4_address); /// Construct an address from an IPv6 address. - address(const boost::asio::ip::address_v6& ipv6_address) - : type_(ipv6), - ipv4_address_(), - ipv6_address_(ipv6_address) - { - } + BOOST_ASIO_DECL address(const boost::asio::ip::address_v6& ipv6_address); /// Copy constructor. - address(const address& other) - : type_(other.type_), - ipv4_address_(other.ipv4_address_), - ipv6_address_(other.ipv6_address_) - { - } + BOOST_ASIO_DECL address(const address& other); /// Assign from another address. - address& operator=(const address& other) - { - type_ = other.type_; - ipv4_address_ = other.ipv4_address_; - ipv6_address_ = other.ipv6_address_; - return *this; - } + BOOST_ASIO_DECL address& operator=(const address& other); /// Assign from an IPv4 address. - address& operator=(const boost::asio::ip::address_v4& ipv4_address) - { - type_ = ipv4; - ipv4_address_ = ipv4_address; - ipv6_address_ = boost::asio::ip::address_v6(); - return *this; - } + BOOST_ASIO_DECL address& operator=( + const boost::asio::ip::address_v4& ipv4_address); /// Assign from an IPv6 address. - address& operator=(const boost::asio::ip::address_v6& ipv6_address) - { - type_ = ipv6; - ipv4_address_ = boost::asio::ip::address_v4(); - ipv6_address_ = ipv6_address; - return *this; - } + BOOST_ASIO_DECL address& operator=( + const boost::asio::ip::address_v6& ipv6_address); /// Get whether the address is an IP version 4 address. bool is_v4() const @@ -119,127 +79,63 @@ public: } /// Get the address as an IP version 4 address. - boost::asio::ip::address_v4 to_v4() const - { - if (type_ != ipv4) - { - boost::system::system_error e( - boost::asio::error::address_family_not_supported); - boost::throw_exception(e); - } - return ipv4_address_; - } + BOOST_ASIO_DECL boost::asio::ip::address_v4 to_v4() const; /// Get the address as an IP version 6 address. - boost::asio::ip::address_v6 to_v6() const - { - if (type_ != ipv6) - { - boost::system::system_error e( - boost::asio::error::address_family_not_supported); - boost::throw_exception(e); - } - return ipv6_address_; - } + BOOST_ASIO_DECL boost::asio::ip::address_v6 to_v6() const; /// Get the address as a string in dotted decimal format. - std::string to_string() const - { - if (type_ == ipv6) - return ipv6_address_.to_string(); - return ipv4_address_.to_string(); - } + BOOST_ASIO_DECL std::string to_string() const; /// Get the address as a string in dotted decimal format. - std::string to_string(boost::system::error_code& ec) const - { - if (type_ == ipv6) - return ipv6_address_.to_string(ec); - return ipv4_address_.to_string(ec); - } + BOOST_ASIO_DECL std::string to_string(boost::system::error_code& ec) const; /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation. - static address from_string(const char* str) - { - boost::system::error_code ec; - address addr = from_string(str, ec); - boost::asio::detail::throw_error(ec); - return addr; - } + BOOST_ASIO_DECL static address from_string(const char* str); /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation. - static address from_string(const char* str, boost::system::error_code& ec) - { - boost::asio::ip::address_v6 ipv6_address = - boost::asio::ip::address_v6::from_string(str, ec); - if (!ec) - { - address tmp; - tmp.type_ = ipv6; - tmp.ipv6_address_ = ipv6_address; - return tmp; - } - - boost::asio::ip::address_v4 ipv4_address = - boost::asio::ip::address_v4::from_string(str, ec); - if (!ec) - { - address tmp; - tmp.type_ = ipv4; - tmp.ipv4_address_ = ipv4_address; - return tmp; - } - - return address(); - } + BOOST_ASIO_DECL static address from_string( + const char* str, boost::system::error_code& ec); /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation. - static address from_string(const std::string& str) - { - return from_string(str.c_str()); - } + BOOST_ASIO_DECL static address from_string(const std::string& str); /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation. - static address from_string(const std::string& str, - boost::system::error_code& ec) + BOOST_ASIO_DECL static address from_string( + const std::string& str, boost::system::error_code& ec); + + /// Compare two addresses for equality. + BOOST_ASIO_DECL friend bool operator==(const address& a1, const address& a2); + + /// Compare two addresses for inequality. + friend bool operator!=(const address& a1, const address& a2) { - return from_string(str.c_str(), ec); + return !(a1 == a2); } - /// Compare two addresses for equality. - friend bool operator==(const address& a1, const address& a2) + /// Compare addresses for ordering. + BOOST_ASIO_DECL friend bool operator<(const address& a1, const address& a2); + + /// Compare addresses for ordering. + friend bool operator>(const address& a1, const address& a2) { - if (a1.type_ != a2.type_) - return false; - if (a1.type_ == ipv6) - return a1.ipv6_address_ == a2.ipv6_address_; - return a1.ipv4_address_ == a2.ipv4_address_; + return a2 < a1; } - /// Compare two addresses for inequality. - friend bool operator!=(const address& a1, const address& a2) + /// Compare addresses for ordering. + friend bool operator<=(const address& a1, const address& a2) { - if (a1.type_ != a2.type_) - return true; - if (a1.type_ == ipv6) - return a1.ipv6_address_ != a2.ipv6_address_; - return a1.ipv4_address_ != a2.ipv4_address_; + return !(a2 < a1); } /// Compare addresses for ordering. - friend bool operator<(const address& a1, const address& a2) + friend bool operator>=(const address& a1, const address& a2) { - if (a1.type_ < a2.type_) - return true; - if (a1.type_ > a2.type_) - return false; - if (a1.type_ == ipv6) - return a1.ipv6_address_ < a2.ipv6_address_; - return a1.ipv4_address_ < a2.ipv4_address_; + return !(a1 < a2); } private: @@ -269,11 +165,7 @@ private: */ template <typename Elem, typename Traits> std::basic_ostream<Elem, Traits>& operator<<( - std::basic_ostream<Elem, Traits>& os, const address& addr) -{ - os << addr.to_string(); - return os; -} + std::basic_ostream<Elem, Traits>& os, const address& addr); #endif // !defined(BOOST_NO_IOSTREAM) @@ -283,4 +175,9 @@ std::basic_ostream<Elem, Traits>& operator<<( #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/ip/impl/address.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/ip/impl/address.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + #endif // BOOST_ASIO_IP_ADDRESS_HPP diff --git a/3rdParty/Boost/src/boost/asio/ip/address_v4.hpp b/3rdParty/Boost/src/boost/asio/ip/address_v4.hpp index 47d36b5..21c1a7f 100644 --- a/3rdParty/Boost/src/boost/asio/ip/address_v4.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/address_v4.hpp @@ -1,6 +1,6 @@ // -// address_v4.hpp -// ~~~~~~~~~~~~~~ +// ip/address_v4.hpp +// ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,24 +15,18 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> +#include <string> +#include <boost/array.hpp> +#include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/winsock_init.hpp> +#include <boost/system/error_code.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> #if !defined(BOOST_NO_IOSTREAM) # include <iosfwd> #endif // !defined(BOOST_NO_IOSTREAM) -#include <climits> -#include <string> -#include <stdexcept> -#include <boost/array.hpp> -#include <boost/throw_exception.hpp> -#include <boost/asio/detail/pop_options.hpp> -#include <boost/asio/error.hpp> -#include <boost/asio/detail/socket_ops.hpp> -#include <boost/asio/detail/socket_types.hpp> -#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -60,34 +54,10 @@ public: } /// Construct an address from raw bytes. - explicit address_v4(const bytes_type& bytes) - { -#if UCHAR_MAX > 0xFF - if (bytes[0] > 0xFF || bytes[1] > 0xFF - || bytes[2] > 0xFF || bytes[3] > 0xFF) - { - std::out_of_range ex("address_v4 from bytes_type"); - boost::throw_exception(ex); - } -#endif // UCHAR_MAX > 0xFF - - using namespace std; // For memcpy. - memcpy(&addr_.s_addr, bytes.elems, 4); - } + BOOST_ASIO_DECL explicit address_v4(const bytes_type& bytes); /// Construct an address from a unsigned long in host byte order. - explicit address_v4(unsigned long addr) - { -#if ULONG_MAX > 0xFFFFFFFF - if (addr > 0xFFFFFFFF) - { - std::out_of_range ex("address_v4 from unsigned long"); - boost::throw_exception(ex); - } -#endif // ULONG_MAX > 0xFFFFFFFF - - addr_.s_addr = boost::asio::detail::socket_ops::host_to_network_long(addr); - } + BOOST_ASIO_DECL explicit address_v4(unsigned long addr); /// Copy constructor. address_v4(const address_v4& other) @@ -103,96 +73,42 @@ public: } /// Get the address in bytes, in network byte order. - bytes_type to_bytes() const - { - using namespace std; // For memcpy. - bytes_type bytes; - memcpy(bytes.elems, &addr_.s_addr, 4); - return bytes; - } + BOOST_ASIO_DECL bytes_type to_bytes() const; /// Get the address as an unsigned long in host byte order - unsigned long to_ulong() const - { - return boost::asio::detail::socket_ops::network_to_host_long(addr_.s_addr); - } + BOOST_ASIO_DECL unsigned long to_ulong() const; /// Get the address as a string in dotted decimal format. - std::string to_string() const - { - boost::system::error_code ec; - std::string addr = to_string(ec); - boost::asio::detail::throw_error(ec); - return addr; - } + BOOST_ASIO_DECL std::string to_string() const; /// Get the address as a string in dotted decimal format. - std::string to_string(boost::system::error_code& ec) const - { - char addr_str[boost::asio::detail::max_addr_v4_str_len]; - const char* addr = - boost::asio::detail::socket_ops::inet_ntop(AF_INET, &addr_, addr_str, - boost::asio::detail::max_addr_v4_str_len, 0, ec); - if (addr == 0) - return std::string(); - return addr; - } + BOOST_ASIO_DECL std::string to_string(boost::system::error_code& ec) const; /// Create an address from an IP address string in dotted decimal form. - static address_v4 from_string(const char* str) - { - boost::system::error_code ec; - address_v4 addr = from_string(str, ec); - boost::asio::detail::throw_error(ec); - return addr; - } + BOOST_ASIO_DECL static address_v4 from_string(const char* str); /// Create an address from an IP address string in dotted decimal form. - static address_v4 from_string(const char* str, boost::system::error_code& ec) - { - address_v4 tmp; - if (boost::asio::detail::socket_ops::inet_pton( - AF_INET, str, &tmp.addr_, 0, ec) <= 0) - return address_v4(); - return tmp; - } + BOOST_ASIO_DECL static address_v4 from_string( + const char* str, boost::system::error_code& ec); /// Create an address from an IP address string in dotted decimal form. - static address_v4 from_string(const std::string& str) - { - return from_string(str.c_str()); - } + BOOST_ASIO_DECL static address_v4 from_string(const std::string& str); /// Create an address from an IP address string in dotted decimal form. - static address_v4 from_string(const std::string& str, - boost::system::error_code& ec) - { - return from_string(str.c_str(), ec); - } + BOOST_ASIO_DECL static address_v4 from_string( + const std::string& str, boost::system::error_code& ec); /// Determine whether the address is a class A address. - bool is_class_a() const - { - return IN_CLASSA(to_ulong()); - } + BOOST_ASIO_DECL bool is_class_a() const; /// Determine whether the address is a class B address. - bool is_class_b() const - { - return IN_CLASSB(to_ulong()); - } + BOOST_ASIO_DECL bool is_class_b() const; /// Determine whether the address is a class C address. - bool is_class_c() const - { - return IN_CLASSC(to_ulong()); - } + BOOST_ASIO_DECL bool is_class_c() const; /// Determine whether the address is a multicast address. - bool is_multicast() const - { - return IN_MULTICAST(to_ulong()); - } + BOOST_ASIO_DECL bool is_multicast() const; /// Compare two addresses for equality. friend bool operator==(const address_v4& a1, const address_v4& a2) @@ -250,23 +166,12 @@ public: /// Obtain an address object that represents the broadcast address that /// corresponds to the specified address and netmask. - static address_v4 broadcast(const address_v4& addr, const address_v4& mask) - { - return address_v4(addr.to_ulong() | ~mask.to_ulong()); - } + BOOST_ASIO_DECL static address_v4 broadcast( + const address_v4& addr, const address_v4& mask); /// Obtain the netmask that corresponds to the address, based on its address /// class. - static address_v4 netmask(const address_v4& addr) - { - if (addr.is_class_a()) - return address_v4(0xFF000000); - if (addr.is_class_b()) - return address_v4(0xFFFF0000); - if (addr.is_class_c()) - return address_v4(0xFFFFFF00); - return address_v4(0xFFFFFFFF); - } + BOOST_ASIO_DECL static address_v4 netmask(const address_v4& addr); private: // The underlying IPv4 address. @@ -289,22 +194,7 @@ private: */ template <typename Elem, typename Traits> std::basic_ostream<Elem, Traits>& operator<<( - std::basic_ostream<Elem, Traits>& os, const address_v4& addr) -{ - boost::system::error_code ec; - std::string s = addr.to_string(ec); - if (ec) - { - if (os.exceptions() & std::ios::failbit) - boost::asio::detail::throw_error(ec); - else - os.setstate(std::ios_base::failbit); - } - else - for (std::string::iterator i = s.begin(); i != s.end(); ++i) - os << os.widen(*i); - return os; -} + std::basic_ostream<Elem, Traits>& os, const address_v4& addr); #endif // !defined(BOOST_NO_IOSTREAM) @@ -314,4 +204,9 @@ std::basic_ostream<Elem, Traits>& operator<<( #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/ip/impl/address_v4.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/ip/impl/address_v4.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + #endif // BOOST_ASIO_IP_ADDRESS_V4_HPP diff --git a/3rdParty/Boost/src/boost/asio/ip/address_v6.hpp b/3rdParty/Boost/src/boost/asio/ip/address_v6.hpp index 5685f08..7165eac 100644 --- a/3rdParty/Boost/src/boost/asio/ip/address_v6.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/address_v6.hpp @@ -1,6 +1,6 @@ // -// address_v6.hpp -// ~~~~~~~~~~~~~~ +// ip/address_v6.hpp +// ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,26 +15,19 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> +#include <string> +#include <boost/array.hpp> +#include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/winsock_init.hpp> +#include <boost/system/error_code.hpp> +#include <boost/asio/ip/address_v4.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> #if !defined(BOOST_NO_IOSTREAM) # include <iosfwd> #endif // !defined(BOOST_NO_IOSTREAM) -#include <cstring> -#include <string> -#include <stdexcept> -#include <typeinfo> -#include <boost/array.hpp> -#include <boost/throw_exception.hpp> -#include <boost/asio/detail/pop_options.hpp> -#include <boost/asio/error.hpp> -#include <boost/asio/detail/socket_ops.hpp> -#include <boost/asio/detail/socket_types.hpp> -#include <boost/asio/detail/throw_error.hpp> -#include <boost/asio/ip/address_v4.hpp> +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -56,46 +49,17 @@ public: typedef boost::array<unsigned char, 16> bytes_type; /// Default constructor. - address_v6() - : scope_id_(0) - { - boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; - addr_ = tmp_addr; - } + BOOST_ASIO_DECL address_v6(); /// Construct an address from raw bytes and scope ID. - explicit address_v6(const bytes_type& bytes, unsigned long scope_id = 0) - : scope_id_(scope_id) - { -#if UCHAR_MAX > 0xFF - for (std::size_t i = 0; i < bytes.size(); ++i) - { - if (bytes[i] > 0xFF) - { - std::out_of_range ex("address_v6 from bytes_type"); - boost::throw_exception(ex); - } - } -#endif // UCHAR_MAX > 0xFF - - using namespace std; // For memcpy. - memcpy(addr_.s6_addr, bytes.elems, 16); - } + BOOST_ASIO_DECL explicit address_v6(const bytes_type& bytes, + unsigned long scope_id = 0); /// Copy constructor. - address_v6(const address_v6& other) - : addr_(other.addr_), - scope_id_(other.scope_id_) - { - } + BOOST_ASIO_DECL address_v6(const address_v6& other); /// Assign from another address. - address_v6& operator=(const address_v6& other) - { - addr_ = other.addr_; - scope_id_ = other.scope_id_; - return *this; - } + BOOST_ASIO_DECL address_v6& operator=(const address_v6& other); /// The scope ID of the address. /** @@ -116,217 +80,80 @@ public: } /// Get the address in bytes, in network byte order. - bytes_type to_bytes() const - { - using namespace std; // For memcpy. - bytes_type bytes; - memcpy(bytes.elems, addr_.s6_addr, 16); - return bytes; - } + BOOST_ASIO_DECL bytes_type to_bytes() const; /// Get the address as a string. - std::string to_string() const - { - boost::system::error_code ec; - std::string addr = to_string(ec); - boost::asio::detail::throw_error(ec); - return addr; - } + BOOST_ASIO_DECL std::string to_string() const; /// Get the address as a string. - std::string to_string(boost::system::error_code& ec) const - { - char addr_str[boost::asio::detail::max_addr_v6_str_len]; - const char* addr = - boost::asio::detail::socket_ops::inet_ntop(AF_INET6, &addr_, addr_str, - boost::asio::detail::max_addr_v6_str_len, scope_id_, ec); - if (addr == 0) - return std::string(); - return addr; - } + BOOST_ASIO_DECL std::string to_string(boost::system::error_code& ec) const; /// Create an address from an IP address string. - static address_v6 from_string(const char* str) - { - boost::system::error_code ec; - address_v6 addr = from_string(str, ec); - boost::asio::detail::throw_error(ec); - return addr; - } + BOOST_ASIO_DECL static address_v6 from_string(const char* str); /// Create an address from an IP address string. - static address_v6 from_string(const char* str, boost::system::error_code& ec) - { - address_v6 tmp; - if (boost::asio::detail::socket_ops::inet_pton( - AF_INET6, str, &tmp.addr_, &tmp.scope_id_, ec) <= 0) - return address_v6(); - return tmp; - } + BOOST_ASIO_DECL static address_v6 from_string( + const char* str, boost::system::error_code& ec); /// Create an address from an IP address string. - static address_v6 from_string(const std::string& str) - { - return from_string(str.c_str()); - } + BOOST_ASIO_DECL static address_v6 from_string(const std::string& str); /// Create an address from an IP address string. - static address_v6 from_string(const std::string& str, - boost::system::error_code& ec) - { - return from_string(str.c_str(), ec); - } + BOOST_ASIO_DECL static address_v6 from_string( + const std::string& str, boost::system::error_code& ec); /// Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address. - address_v4 to_v4() const - { - if (!is_v4_mapped() && !is_v4_compatible()) - { - std::bad_cast ex; - boost::throw_exception(ex); - } - - address_v4::bytes_type v4_bytes = { { addr_.s6_addr[12], - addr_.s6_addr[13], addr_.s6_addr[14], addr_.s6_addr[15] } }; - return address_v4(v4_bytes); - } + BOOST_ASIO_DECL address_v4 to_v4() const; /// Determine whether the address is a loopback address. - bool is_loopback() const - { -#if defined(__BORLANDC__) - return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) - && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) - && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) - && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) - && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) - && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) - && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0) - && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1)); -#else - using namespace boost::asio::detail; - return IN6_IS_ADDR_LOOPBACK(&addr_) != 0; -#endif - } + BOOST_ASIO_DECL bool is_loopback() const; /// Determine whether the address is unspecified. - bool is_unspecified() const - { -#if defined(__BORLANDC__) - return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) - && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) - && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) - && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) - && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) - && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) - && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0) - && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0)); -#else - using namespace boost::asio::detail; - return IN6_IS_ADDR_UNSPECIFIED(&addr_) != 0; -#endif - } + BOOST_ASIO_DECL bool is_unspecified() const; /// Determine whether the address is link local. - bool is_link_local() const - { - using namespace boost::asio::detail; - return IN6_IS_ADDR_LINKLOCAL(&addr_) != 0; - } + BOOST_ASIO_DECL bool is_link_local() const; /// Determine whether the address is site local. - bool is_site_local() const - { - using namespace boost::asio::detail; - return IN6_IS_ADDR_SITELOCAL(&addr_) != 0; - } + BOOST_ASIO_DECL bool is_site_local() const; /// Determine whether the address is a mapped IPv4 address. - bool is_v4_mapped() const - { - using namespace boost::asio::detail; - return IN6_IS_ADDR_V4MAPPED(&addr_) != 0; - } + BOOST_ASIO_DECL bool is_v4_mapped() const; /// Determine whether the address is an IPv4-compatible address. - bool is_v4_compatible() const - { - using namespace boost::asio::detail; - return IN6_IS_ADDR_V4COMPAT(&addr_) != 0; - } + BOOST_ASIO_DECL bool is_v4_compatible() const; /// Determine whether the address is a multicast address. - bool is_multicast() const - { - using namespace boost::asio::detail; - return IN6_IS_ADDR_MULTICAST(&addr_) != 0; - } + BOOST_ASIO_DECL bool is_multicast() const; /// Determine whether the address is a global multicast address. - bool is_multicast_global() const - { - using namespace boost::asio::detail; - return IN6_IS_ADDR_MC_GLOBAL(&addr_) != 0; - } + BOOST_ASIO_DECL bool is_multicast_global() const; /// Determine whether the address is a link-local multicast address. - bool is_multicast_link_local() const - { - using namespace boost::asio::detail; - return IN6_IS_ADDR_MC_LINKLOCAL(&addr_) != 0; - } + BOOST_ASIO_DECL bool is_multicast_link_local() const; /// Determine whether the address is a node-local multicast address. - bool is_multicast_node_local() const - { - using namespace boost::asio::detail; - return IN6_IS_ADDR_MC_NODELOCAL(&addr_) != 0; - } + BOOST_ASIO_DECL bool is_multicast_node_local() const; /// Determine whether the address is a org-local multicast address. - bool is_multicast_org_local() const - { - using namespace boost::asio::detail; - return IN6_IS_ADDR_MC_ORGLOCAL(&addr_) != 0; - } + BOOST_ASIO_DECL bool is_multicast_org_local() const; /// Determine whether the address is a site-local multicast address. - bool is_multicast_site_local() const - { - using namespace boost::asio::detail; - return IN6_IS_ADDR_MC_SITELOCAL(&addr_) != 0; - } + BOOST_ASIO_DECL bool is_multicast_site_local() const; /// Compare two addresses for equality. - friend bool operator==(const address_v6& a1, const address_v6& a2) - { - using namespace std; // For memcmp. - return memcmp(&a1.addr_, &a2.addr_, - sizeof(boost::asio::detail::in6_addr_type)) == 0 - && a1.scope_id_ == a2.scope_id_; - } + BOOST_ASIO_DECL friend bool operator==( + const address_v6& a1, const address_v6& a2); /// Compare two addresses for inequality. friend bool operator!=(const address_v6& a1, const address_v6& a2) { - using namespace std; // For memcmp. - return memcmp(&a1.addr_, &a2.addr_, - sizeof(boost::asio::detail::in6_addr_type)) != 0 - || a1.scope_id_ != a2.scope_id_; + return !(a1 == a2); } /// Compare addresses for ordering. - friend bool operator<(const address_v6& a1, const address_v6& a2) - { - using namespace std; // For memcmp. - int memcmp_result = memcmp(&a1.addr_, &a2.addr_, - sizeof(boost::asio::detail::in6_addr_type)); - if (memcmp_result < 0) - return true; - if (memcmp_result > 0) - return false; - return a1.scope_id_ < a2.scope_id_; - } + BOOST_ASIO_DECL friend bool operator<( + const address_v6& a1, const address_v6& a2); /// Compare addresses for ordering. friend bool operator>(const address_v6& a1, const address_v6& a2) @@ -353,31 +180,13 @@ public: } /// Obtain an address object that represents the loopback address. - static address_v6 loopback() - { - address_v6 tmp; - boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_LOOPBACK_INIT; - tmp.addr_ = tmp_addr; - return tmp; - } + BOOST_ASIO_DECL static address_v6 loopback(); /// Create an IPv4-mapped IPv6 address. - static address_v6 v4_mapped(const address_v4& addr) - { - address_v4::bytes_type v4_bytes = addr.to_bytes(); - bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, - v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; - return address_v6(v6_bytes); - } + BOOST_ASIO_DECL static address_v6 v4_mapped(const address_v4& addr); /// Create an IPv4-compatible IPv6 address. - static address_v6 v4_compatible(const address_v4& addr) - { - address_v4::bytes_type v4_bytes = addr.to_bytes(); - bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; - return address_v6(v6_bytes); - } + BOOST_ASIO_DECL static address_v6 v4_compatible(const address_v4& addr); private: // The underlying IPv6 address. @@ -403,22 +212,7 @@ private: */ template <typename Elem, typename Traits> std::basic_ostream<Elem, Traits>& operator<<( - std::basic_ostream<Elem, Traits>& os, const address_v6& addr) -{ - boost::system::error_code ec; - std::string s = addr.to_string(ec); - if (ec) - { - if (os.exceptions() & std::ios::failbit) - boost::asio::detail::throw_error(ec); - else - os.setstate(std::ios_base::failbit); - } - else - for (std::string::iterator i = s.begin(); i != s.end(); ++i) - os << os.widen(*i); - return os; -} + std::basic_ostream<Elem, Traits>& os, const address_v6& addr); #endif // !defined(BOOST_NO_IOSTREAM) @@ -428,4 +222,9 @@ std::basic_ostream<Elem, Traits>& operator<<( #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/ip/impl/address_v6.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/ip/impl/address_v6.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + #endif // BOOST_ASIO_IP_ADDRESS_V6_HPP diff --git a/3rdParty/Boost/src/boost/asio/ip/basic_endpoint.hpp b/3rdParty/Boost/src/boost/asio/ip/basic_endpoint.hpp index f191a4c..10459c4 100644 --- a/3rdParty/Boost/src/boost/asio/ip/basic_endpoint.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/basic_endpoint.hpp @@ -1,6 +1,6 @@ // -// basic_endpoint.hpp -// ~~~~~~~~~~~~~~~~~~ +// ip/basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,25 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> +#include <boost/asio/ip/address.hpp> +#include <boost/asio/ip/detail/endpoint.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/throw_exception.hpp> -#include <boost/detail/workaround.hpp> -#include <cstring> #if !defined(BOOST_NO_IOSTREAM) -# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) -# include <ostream> -# endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) -# include <sstream> +# include <iosfwd> #endif // !defined(BOOST_NO_IOSTREAM) -#include <boost/asio/detail/pop_options.hpp> -#include <boost/asio/error.hpp> -#include <boost/asio/ip/address.hpp> -#include <boost/asio/detail/socket_ops.hpp> -#include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -68,11 +58,8 @@ public: /// Default constructor. basic_endpoint() - : data_() + : impl_() { - data_.v4.sin_family = AF_INET; - data_.v4.sin_port = 0; - data_.v4.sin_addr.s_addr = INADDR_ANY; } /// Construct an endpoint using a port number, specified in the host's byte @@ -92,74 +79,35 @@ public: * @endcode */ basic_endpoint(const InternetProtocol& protocol, unsigned short port_num) - : data_() + : impl_(protocol.family(), port_num) { - using namespace std; // For memcpy. - if (protocol.family() == PF_INET) - { - data_.v4.sin_family = AF_INET; - data_.v4.sin_port = - boost::asio::detail::socket_ops::host_to_network_short(port_num); - data_.v4.sin_addr.s_addr = INADDR_ANY; - } - else - { - data_.v6.sin6_family = AF_INET6; - data_.v6.sin6_port = - boost::asio::detail::socket_ops::host_to_network_short(port_num); - data_.v6.sin6_flowinfo = 0; - boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; - data_.v6.sin6_addr = tmp_addr; - data_.v6.sin6_scope_id = 0; - } } /// Construct an endpoint using a port number and an IP address. This /// constructor may be used for accepting connections on a specific interface /// or for making a connection to a remote endpoint. basic_endpoint(const boost::asio::ip::address& addr, unsigned short port_num) - : data_() + : impl_(addr, port_num) { - using namespace std; // For memcpy. - if (addr.is_v4()) - { - data_.v4.sin_family = AF_INET; - data_.v4.sin_port = - boost::asio::detail::socket_ops::host_to_network_short(port_num); - data_.v4.sin_addr.s_addr = - boost::asio::detail::socket_ops::host_to_network_long( - addr.to_v4().to_ulong()); - } - else - { - data_.v6.sin6_family = AF_INET6; - data_.v6.sin6_port = - boost::asio::detail::socket_ops::host_to_network_short(port_num); - data_.v6.sin6_flowinfo = 0; - boost::asio::ip::address_v6 v6_addr = addr.to_v6(); - boost::asio::ip::address_v6::bytes_type bytes = v6_addr.to_bytes(); - memcpy(data_.v6.sin6_addr.s6_addr, bytes.elems, 16); - data_.v6.sin6_scope_id = v6_addr.scope_id(); - } } /// Copy constructor. basic_endpoint(const basic_endpoint& other) - : data_(other.data_) + : impl_(other.impl_) { } /// Assign from another endpoint. basic_endpoint& operator=(const basic_endpoint& other) { - data_ = other.data_; + impl_ = other.impl_; return *this; } /// The protocol associated with the endpoint. protocol_type protocol() const { - if (is_v4()) + if (impl_.is_v4()) return InternetProtocol::v4(); return InternetProtocol::v6(); } @@ -167,137 +115,104 @@ public: /// Get the underlying endpoint in the native type. data_type* data() { - return &data_.base; + return impl_.data(); } /// Get the underlying endpoint in the native type. const data_type* data() const { - return &data_.base; + return impl_.data(); } /// Get the underlying size of the endpoint in the native type. std::size_t size() const { - if (is_v4()) - return sizeof(boost::asio::detail::sockaddr_in4_type); - else - return sizeof(boost::asio::detail::sockaddr_in6_type); + return impl_.size(); } /// Set the underlying size of the endpoint in the native type. void resize(std::size_t size) { - if (size > sizeof(boost::asio::detail::sockaddr_storage_type)) - { - boost::system::system_error e(boost::asio::error::invalid_argument); - boost::throw_exception(e); - } + impl_.resize(size); } /// Get the capacity of the endpoint in the native type. std::size_t capacity() const { - return sizeof(boost::asio::detail::sockaddr_storage_type); + return impl_.capacity(); } /// Get the port associated with the endpoint. The port number is always in /// the host's byte order. unsigned short port() const { - if (is_v4()) - { - return boost::asio::detail::socket_ops::network_to_host_short( - data_.v4.sin_port); - } - else - { - return boost::asio::detail::socket_ops::network_to_host_short( - data_.v6.sin6_port); - } + return impl_.port(); } /// Set the port associated with the endpoint. The port number is always in /// the host's byte order. void port(unsigned short port_num) { - if (is_v4()) - { - data_.v4.sin_port - = boost::asio::detail::socket_ops::host_to_network_short(port_num); - } - else - { - data_.v6.sin6_port - = boost::asio::detail::socket_ops::host_to_network_short(port_num); - } + impl_.port(port_num); } /// Get the IP address associated with the endpoint. boost::asio::ip::address address() const { - using namespace std; // For memcpy. - if (is_v4()) - { - return boost::asio::ip::address_v4( - boost::asio::detail::socket_ops::network_to_host_long( - data_.v4.sin_addr.s_addr)); - } - else - { - boost::asio::ip::address_v6::bytes_type bytes; - memcpy(bytes.elems, data_.v6.sin6_addr.s6_addr, 16); - return boost::asio::ip::address_v6(bytes, data_.v6.sin6_scope_id); - } + return impl_.address(); } /// Set the IP address associated with the endpoint. void address(const boost::asio::ip::address& addr) { - basic_endpoint<InternetProtocol> tmp_endpoint(addr, port()); - data_ = tmp_endpoint.data_; + impl_.address(addr); } /// Compare two endpoints for equality. friend bool operator==(const basic_endpoint<InternetProtocol>& e1, const basic_endpoint<InternetProtocol>& e2) { - return e1.address() == e2.address() && e1.port() == e2.port(); + return e1.impl_ == e2.impl_; } /// Compare two endpoints for inequality. friend bool operator!=(const basic_endpoint<InternetProtocol>& e1, const basic_endpoint<InternetProtocol>& e2) { - return e1.address() != e2.address() || e1.port() != e2.port(); + return !(e1 == e2); } /// Compare endpoints for ordering. friend bool operator<(const basic_endpoint<InternetProtocol>& e1, const basic_endpoint<InternetProtocol>& e2) { - if (e1.address() < e2.address()) - return true; - if (e1.address() != e2.address()) - return false; - return e1.port() < e2.port(); + return e1.impl_ < e2.impl_; } -private: - // Helper function to determine whether the endpoint is IPv4. - bool is_v4() const + /// Compare endpoints for ordering. + friend bool operator>(const basic_endpoint<InternetProtocol>& e1, + const basic_endpoint<InternetProtocol>& e2) + { + return e2.impl_ < e1.impl_; + } + + /// Compare endpoints for ordering. + friend bool operator<=(const basic_endpoint<InternetProtocol>& e1, + const basic_endpoint<InternetProtocol>& e2) { - return data_.base.sa_family == AF_INET; + return !(e2 < e1); } - // The underlying IP socket address. - union data_union + /// Compare endpoints for ordering. + friend bool operator>=(const basic_endpoint<InternetProtocol>& e1, + const basic_endpoint<InternetProtocol>& e2) { - boost::asio::detail::socket_addr_type base; - boost::asio::detail::sockaddr_storage_type storage; - boost::asio::detail::sockaddr_in4_type v4; - boost::asio::detail::sockaddr_in6_type v6; - } data_; + return !(e1 < e2); + } + +private: + // The underlying IP endpoint. + boost::asio::ip::detail::endpoint impl_; }; #if !defined(BOOST_NO_IOSTREAM) @@ -314,64 +229,10 @@ private: * * @relates boost::asio::ip::basic_endpoint */ -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) -template <typename InternetProtocol> -std::ostream& operator<<(std::ostream& os, - const basic_endpoint<InternetProtocol>& endpoint) -{ - const address& addr = endpoint.address(); - boost::system::error_code ec; - std::string a = addr.to_string(ec); - if (ec) - { - if (os.exceptions() & std::ios::failbit) - boost::asio::detail::throw_error(ec); - else - os.setstate(std::ios_base::failbit); - } - else - { - std::ostringstream tmp_os; - tmp_os.imbue(std::locale::classic()); - if (addr.is_v4()) - tmp_os << a; - else - tmp_os << '[' << a << ']'; - tmp_os << ':' << endpoint.port(); - os << tmp_os.str(); - } - return os; -} -#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) template <typename Elem, typename Traits, typename InternetProtocol> std::basic_ostream<Elem, Traits>& operator<<( std::basic_ostream<Elem, Traits>& os, - const basic_endpoint<InternetProtocol>& endpoint) -{ - const address& addr = endpoint.address(); - boost::system::error_code ec; - std::string a = addr.to_string(ec); - if (ec) - { - if (os.exceptions() & std::ios::failbit) - boost::asio::detail::throw_error(ec); - else - os.setstate(std::ios_base::failbit); - } - else - { - std::ostringstream tmp_os; - tmp_os.imbue(std::locale::classic()); - if (addr.is_v4()) - tmp_os << a; - else - tmp_os << '[' << a << ']'; - tmp_os << ':' << endpoint.port(); - os << tmp_os.str(); - } - return os; -} -#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + const basic_endpoint<InternetProtocol>& endpoint); #endif // !defined(BOOST_NO_IOSTREAM) @@ -381,4 +242,6 @@ std::basic_ostream<Elem, Traits>& operator<<( #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/ip/impl/basic_endpoint.hpp> + #endif // BOOST_ASIO_IP_BASIC_ENDPOINT_HPP diff --git a/3rdParty/Boost/src/boost/asio/ip/basic_resolver.hpp b/3rdParty/Boost/src/boost/asio/ip/basic_resolver.hpp index 0660ce5..21b83da 100644 --- a/3rdParty/Boost/src/boost/asio/ip/basic_resolver.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/basic_resolver.hpp @@ -1,6 +1,6 @@ // -// basic_resolver.hpp -// ~~~~~~~~~~~~~~~~~~ +// ip/basic_resolver.hpp +// ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,14 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/basic_io_object.hpp> +#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> #include <boost/asio/ip/basic_resolver_iterator.hpp> #include <boost/asio/ip/basic_resolver_query.hpp> #include <boost/asio/ip/resolver_service.hpp> -#include <boost/asio/detail/throw_error.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/ip/basic_resolver_entry.hpp b/3rdParty/Boost/src/boost/asio/ip/basic_resolver_entry.hpp index f2ac595..84589b5 100644 --- a/3rdParty/Boost/src/boost/asio/ip/basic_resolver_entry.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/basic_resolver_entry.hpp @@ -1,6 +1,6 @@ // -// basic_resolver_entry.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~ +// ip/basic_resolver_entry.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,11 +15,10 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> +#include <string> #include <boost/asio/detail/push_options.hpp> -#include <string> -#include <boost/asio/detail/pop_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/ip/basic_resolver_iterator.hpp b/3rdParty/Boost/src/boost/asio/ip/basic_resolver_iterator.hpp index 5f4937b..de42699 100644 --- a/3rdParty/Boost/src/boost/asio/ip/basic_resolver_iterator.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/basic_resolver_iterator.hpp @@ -1,6 +1,6 @@ // -// basic_resolver_iterator.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// ip/basic_resolver_iterator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,20 +15,18 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/iterator.hpp> -#include <boost/shared_ptr.hpp> #include <cstring> #include <string> #include <vector> -#include <boost/asio/detail/pop_options.hpp> - +#include <boost/asio/detail/shared_ptr.hpp> #include <boost/asio/detail/socket_ops.hpp> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/ip/basic_resolver_entry.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace ip { @@ -177,7 +175,7 @@ private: } typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type; - boost::shared_ptr<values_type> values_; + boost::asio::detail::shared_ptr<values_type> values_; std::size_t index_; }; diff --git a/3rdParty/Boost/src/boost/asio/ip/basic_resolver_query.hpp b/3rdParty/Boost/src/boost/asio/ip/basic_resolver_query.hpp index 75d3c47..38cba01 100644 --- a/3rdParty/Boost/src/boost/asio/ip/basic_resolver_query.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/basic_resolver_query.hpp @@ -1,6 +1,6 @@ // -// basic_resolver_query.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~ +// ip/basic_resolver_query.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> +#include <boost/asio/detail/config.hpp> #include <string> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/detail/socket_ops.hpp> #include <boost/asio/ip/resolver_query_base.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace ip { diff --git a/3rdParty/Boost/src/boost/asio/ip/detail/endpoint.hpp b/3rdParty/Boost/src/boost/asio/ip/detail/endpoint.hpp new file mode 100644 index 0000000..9823e72 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/ip/detail/endpoint.hpp @@ -0,0 +1,142 @@ +// +// ip/detail/endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_IP_DETAIL_ENDPOINT_HPP +#define BOOST_ASIO_IP_DETAIL_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <string> +#include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/winsock_init.hpp> +#include <boost/system/error_code.hpp> +#include <boost/asio/ip/address.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace ip { +namespace detail { + +// Helper class for implementating an IP endpoint. +class endpoint +{ +public: + // Default constructor. + BOOST_ASIO_DECL endpoint(); + + // Construct an endpoint using a family and port number. + BOOST_ASIO_DECL endpoint(int family, unsigned short port_num); + + // Construct an endpoint using an address and port number. + BOOST_ASIO_DECL endpoint(const boost::asio::ip::address& addr, + unsigned short port_num); + + // Copy constructor. + endpoint(const endpoint& other) + : data_(other.data_) + { + } + + // Assign from another endpoint. + endpoint& operator=(const endpoint& other) + { + data_ = other.data_; + return *this; + } + + // Get the underlying endpoint in the native type. + boost::asio::detail::socket_addr_type* data() + { + return &data_.base; + } + + // Get the underlying endpoint in the native type. + const boost::asio::detail::socket_addr_type* data() const + { + return &data_.base; + } + + // Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + if (is_v4()) + return sizeof(boost::asio::detail::sockaddr_in4_type); + else + return sizeof(boost::asio::detail::sockaddr_in6_type); + } + + // Set the underlying size of the endpoint in the native type. + BOOST_ASIO_DECL void resize(std::size_t size); + + // Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return sizeof(boost::asio::detail::sockaddr_storage_type); + } + + // Get the port associated with the endpoint. + BOOST_ASIO_DECL unsigned short port() const; + + // Set the port associated with the endpoint. + BOOST_ASIO_DECL void port(unsigned short port_num); + + // Get the IP address associated with the endpoint. + BOOST_ASIO_DECL boost::asio::ip::address address() const; + + // Set the IP address associated with the endpoint. + BOOST_ASIO_DECL void address(const boost::asio::ip::address& addr); + + // Compare two endpoints for equality. + BOOST_ASIO_DECL friend bool operator==( + const endpoint& e1, const endpoint& e2); + + // Compare endpoints for ordering. + BOOST_ASIO_DECL friend bool operator<( + const endpoint& e1, const endpoint& e2); + + // Determine whether the endpoint is IPv4. + bool is_v4() const + { + return data_.base.sa_family == AF_INET; + } + +#if !defined(BOOST_NO_IOSTREAM) + // Convert to a string. + BOOST_ASIO_DECL std::string to_string(boost::system::error_code& ec) const; +#endif // !defined(BOOST_NO_IOSTREAM) + +private: + // The underlying IP socket address. + union data_union + { + boost::asio::detail::socket_addr_type base; + boost::asio::detail::sockaddr_storage_type storage; + boost::asio::detail::sockaddr_in4_type v4; + boost::asio::detail::sockaddr_in6_type v6; + } data_; +}; + +} // namespace detail +} // namespace ip +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/ip/detail/impl/endpoint.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // BOOST_ASIO_IP_DETAIL_ENDPOINT_HPP diff --git a/3rdParty/Boost/src/boost/asio/ip/detail/impl/endpoint.ipp b/3rdParty/Boost/src/boost/asio/ip/detail/impl/endpoint.ipp new file mode 100644 index 0000000..4a6e395 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/ip/detail/impl/endpoint.ipp @@ -0,0 +1,193 @@ +// +// ip/detail/impl/endpoint.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP +#define BOOST_ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <cstring> +#if !defined(BOOST_NO_IOSTREAM) +# include <sstream> +#endif // !defined(BOOST_NO_IOSTREAM) +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/ip/detail/endpoint.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace ip { +namespace detail { + +endpoint::endpoint() + : data_() +{ + data_.v4.sin_family = AF_INET; + data_.v4.sin_port = 0; + data_.v4.sin_addr.s_addr = INADDR_ANY; +} + +endpoint::endpoint(int family, unsigned short port_num) + : data_() +{ + using namespace std; // For memcpy. + if (family == PF_INET) + { + data_.v4.sin_family = AF_INET; + data_.v4.sin_port = + boost::asio::detail::socket_ops::host_to_network_short(port_num); + data_.v4.sin_addr.s_addr = INADDR_ANY; + } + else + { + data_.v6.sin6_family = AF_INET6; + data_.v6.sin6_port = + boost::asio::detail::socket_ops::host_to_network_short(port_num); + data_.v6.sin6_flowinfo = 0; + boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; + data_.v6.sin6_addr = tmp_addr; + data_.v6.sin6_scope_id = 0; + } +} + +endpoint::endpoint(const boost::asio::ip::address& addr, + unsigned short port_num) + : data_() +{ + using namespace std; // For memcpy. + if (addr.is_v4()) + { + data_.v4.sin_family = AF_INET; + data_.v4.sin_port = + boost::asio::detail::socket_ops::host_to_network_short(port_num); + data_.v4.sin_addr.s_addr = + boost::asio::detail::socket_ops::host_to_network_long( + addr.to_v4().to_ulong()); + } + else + { + data_.v6.sin6_family = AF_INET6; + data_.v6.sin6_port = + boost::asio::detail::socket_ops::host_to_network_short(port_num); + data_.v6.sin6_flowinfo = 0; + boost::asio::ip::address_v6 v6_addr = addr.to_v6(); + boost::asio::ip::address_v6::bytes_type bytes = v6_addr.to_bytes(); + memcpy(data_.v6.sin6_addr.s6_addr, bytes.elems, 16); + data_.v6.sin6_scope_id = v6_addr.scope_id(); + } +} + +void endpoint::resize(std::size_t size) +{ + if (size > sizeof(boost::asio::detail::sockaddr_storage_type)) + { + boost::system::error_code ec(boost::asio::error::invalid_argument); + boost::asio::detail::throw_error(ec); + } +} + +unsigned short endpoint::port() const +{ + if (is_v4()) + { + return boost::asio::detail::socket_ops::network_to_host_short( + data_.v4.sin_port); + } + else + { + return boost::asio::detail::socket_ops::network_to_host_short( + data_.v6.sin6_port); + } +} + +void endpoint::port(unsigned short port_num) +{ + if (is_v4()) + { + data_.v4.sin_port + = boost::asio::detail::socket_ops::host_to_network_short(port_num); + } + else + { + data_.v6.sin6_port + = boost::asio::detail::socket_ops::host_to_network_short(port_num); + } +} + +boost::asio::ip::address endpoint::address() const +{ + using namespace std; // For memcpy. + if (is_v4()) + { + return boost::asio::ip::address_v4( + boost::asio::detail::socket_ops::network_to_host_long( + data_.v4.sin_addr.s_addr)); + } + else + { + boost::asio::ip::address_v6::bytes_type bytes; + memcpy(bytes.elems, data_.v6.sin6_addr.s6_addr, 16); + return boost::asio::ip::address_v6(bytes, data_.v6.sin6_scope_id); + } +} + +void endpoint::address(const boost::asio::ip::address& addr) +{ + endpoint tmp_endpoint(addr, port()); + data_ = tmp_endpoint.data_; +} + +bool operator==(const endpoint& e1, const endpoint& e2) +{ + return e1.address() == e2.address() && e1.port() == e2.port(); +} + +bool operator<(const endpoint& e1, const endpoint& e2) +{ + if (e1.address() < e2.address()) + return true; + if (e1.address() != e2.address()) + return false; + return e1.port() < e2.port(); +} + +#if !defined(BOOST_NO_IOSTREAM) +std::string endpoint::to_string(boost::system::error_code& ec) const +{ + std::string a = address().to_string(ec); + if (ec) + return std::string(); + + std::ostringstream tmp_os; + tmp_os.imbue(std::locale::classic()); + if (is_v4()) + tmp_os << a; + else + tmp_os << '[' << a << ']'; + tmp_os << ':' << port(); + + return tmp_os.str(); +} +#endif // !defined(BOOST_NO_IOSTREAM) + +} // namespace detail +} // namespace ip +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP diff --git a/3rdParty/Boost/src/boost/asio/ip/detail/socket_option.hpp b/3rdParty/Boost/src/boost/asio/ip/detail/socket_option.hpp index 0c26864..59ce6c3 100644 --- a/3rdParty/Boost/src/boost/asio/ip/detail/socket_option.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/detail/socket_option.hpp @@ -1,6 +1,6 @@ // -// socket_option.hpp -// ~~~~~~~~~~~~~~~~~ +// detail/socket_option.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,18 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> #include <cstring> -#include <boost/config.hpp> #include <boost/throw_exception.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/ip/address.hpp> #include <boost/asio/detail/socket_ops.hpp> #include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/ip/address.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/ip/host_name.hpp b/3rdParty/Boost/src/boost/asio/ip/host_name.hpp index fee245b..f40a9df 100644 --- a/3rdParty/Boost/src/boost/asio/ip/host_name.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/host_name.hpp @@ -1,6 +1,6 @@ // -// host_name.hpp -// ~~~~~~~~~~~~~ +// ip/host_name.hpp +// ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,45 +15,21 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <string> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/system/error_code.hpp> -#include <boost/asio/error.hpp> -#include <boost/asio/detail/socket_ops.hpp> -#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace ip { /// Get the current host name. -std::string host_name(); +BOOST_ASIO_DECL std::string host_name(); /// Get the current host name. -std::string host_name(boost::system::error_code& ec); - -inline std::string host_name() -{ - char name[1024]; - boost::system::error_code ec; - if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) - { - boost::asio::detail::throw_error(ec); - return std::string(); - } - return std::string(name); -} - -inline std::string host_name(boost::system::error_code& ec) -{ - char name[1024]; - if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) - return std::string(); - return std::string(name); -} +BOOST_ASIO_DECL std::string host_name(boost::system::error_code& ec); } // namespace ip } // namespace asio @@ -61,4 +37,8 @@ inline std::string host_name(boost::system::error_code& ec) #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/ip/impl/host_name.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + #endif // BOOST_ASIO_IP_HOST_NAME_HPP diff --git a/3rdParty/Boost/src/boost/asio/ip/icmp.hpp b/3rdParty/Boost/src/boost/asio/ip/icmp.hpp index 5d2fcab..ca5d434 100644 --- a/3rdParty/Boost/src/boost/asio/ip/icmp.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/icmp.hpp @@ -1,6 +1,6 @@ // -// icmp.hpp -// ~~~~~~~~ +// ip/icmp.hpp +// ~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,14 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> +#include <boost/asio/detail/socket_types.hpp> #include <boost/asio/basic_raw_socket.hpp> #include <boost/asio/ip/basic_endpoint.hpp> #include <boost/asio/ip/basic_resolver.hpp> #include <boost/asio/ip/basic_resolver_iterator.hpp> #include <boost/asio/ip/basic_resolver_query.hpp> -#include <boost/asio/detail/socket_types.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/ip/impl/address.hpp b/3rdParty/Boost/src/boost/asio/ip/impl/address.hpp new file mode 100644 index 0000000..c19d25d --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/ip/impl/address.hpp @@ -0,0 +1,55 @@ +// +// ip/impl/address.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_IP_IMPL_ADDRESS_HPP +#define BOOST_ASIO_IP_IMPL_ADDRESS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(BOOST_NO_IOSTREAM) + +#include <boost/asio/detail/throw_error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace ip { + +template <typename Elem, typename Traits> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, const address& addr) +{ + boost::system::error_code ec; + std::string s = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::basic_ostream<Elem, Traits>::failbit) + boost::asio::detail::throw_error(ec); + else + os.setstate(std::basic_ostream<Elem, Traits>::failbit); + } + else + for (std::string::iterator i = s.begin(); i != s.end(); ++i) + os << os.widen(*i); + return os; +} + +} // namespace ip +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // !defined(BOOST_NO_IOSTREAM) + +#endif // BOOST_ASIO_IP_IMPL_ADDRESS_HPP diff --git a/3rdParty/Boost/src/boost/asio/ip/impl/address.ipp b/3rdParty/Boost/src/boost/asio/ip/impl/address.ipp new file mode 100644 index 0000000..70513b7 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/ip/impl/address.ipp @@ -0,0 +1,188 @@ +// +// ip/impl/address.ipp +// ~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_IP_IMPL_ADDRESS_IPP +#define BOOST_ASIO_IP_IMPL_ADDRESS_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <typeinfo> +#include <boost/throw_exception.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/ip/address.hpp> +#include <boost/system/system_error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace ip { + +address::address() + : type_(ipv4), + ipv4_address_(), + ipv6_address_() +{ +} + +address::address(const boost::asio::ip::address_v4& ipv4_address) + : type_(ipv4), + ipv4_address_(ipv4_address), + ipv6_address_() +{ +} + +address::address(const boost::asio::ip::address_v6& ipv6_address) + : type_(ipv6), + ipv4_address_(), + ipv6_address_(ipv6_address) +{ +} + +address::address(const address& other) + : type_(other.type_), + ipv4_address_(other.ipv4_address_), + ipv6_address_(other.ipv6_address_) +{ +} + +address& address::operator=(const address& other) +{ + type_ = other.type_; + ipv4_address_ = other.ipv4_address_; + ipv6_address_ = other.ipv6_address_; + return *this; +} + +address& address::operator=(const boost::asio::ip::address_v4& ipv4_address) +{ + type_ = ipv4; + ipv4_address_ = ipv4_address; + ipv6_address_ = boost::asio::ip::address_v6(); + return *this; +} + +address& address::operator=(const boost::asio::ip::address_v6& ipv6_address) +{ + type_ = ipv6; + ipv4_address_ = boost::asio::ip::address_v4(); + ipv6_address_ = ipv6_address; + return *this; +} + +boost::asio::ip::address_v4 address::to_v4() const +{ + if (type_ != ipv4) + { + std::bad_cast ex; + boost::throw_exception(ex); + } + return ipv4_address_; +} + +boost::asio::ip::address_v6 address::to_v6() const +{ + if (type_ != ipv6) + { + std::bad_cast ex; + boost::throw_exception(ex); + } + return ipv6_address_; +} + +std::string address::to_string() const +{ + if (type_ == ipv6) + return ipv6_address_.to_string(); + return ipv4_address_.to_string(); +} + +std::string address::to_string(boost::system::error_code& ec) const +{ + if (type_ == ipv6) + return ipv6_address_.to_string(ec); + return ipv4_address_.to_string(ec); +} + +address address::from_string(const char* str) +{ + boost::system::error_code ec; + address addr = from_string(str, ec); + boost::asio::detail::throw_error(ec); + return addr; +} + +address address::from_string(const char* str, boost::system::error_code& ec) +{ + boost::asio::ip::address_v6 ipv6_address = + boost::asio::ip::address_v6::from_string(str, ec); + if (!ec) + { + address tmp; + tmp.type_ = ipv6; + tmp.ipv6_address_ = ipv6_address; + return tmp; + } + + boost::asio::ip::address_v4 ipv4_address = + boost::asio::ip::address_v4::from_string(str, ec); + if (!ec) + { + address tmp; + tmp.type_ = ipv4; + tmp.ipv4_address_ = ipv4_address; + return tmp; + } + + return address(); +} + +address address::from_string(const std::string& str) +{ + return from_string(str.c_str()); +} + +address address::from_string(const std::string& str, + boost::system::error_code& ec) +{ + return from_string(str.c_str(), ec); +} + +bool operator==(const address& a1, const address& a2) +{ + if (a1.type_ != a2.type_) + return false; + if (a1.type_ == address::ipv6) + return a1.ipv6_address_ == a2.ipv6_address_; + return a1.ipv4_address_ == a2.ipv4_address_; +} + +bool operator<(const address& a1, const address& a2) +{ + if (a1.type_ < a2.type_) + return true; + if (a1.type_ > a2.type_) + return false; + if (a1.type_ == address::ipv6) + return a1.ipv6_address_ < a2.ipv6_address_; + return a1.ipv4_address_ < a2.ipv4_address_; +} + +} // namespace ip +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_IP_IMPL_ADDRESS_IPP diff --git a/3rdParty/Boost/src/boost/asio/ip/impl/address_v4.hpp b/3rdParty/Boost/src/boost/asio/ip/impl/address_v4.hpp new file mode 100644 index 0000000..7e798e8 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/ip/impl/address_v4.hpp @@ -0,0 +1,55 @@ +// +// ip/impl/address_v4.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_IP_IMPL_ADDRESS_V4_HPP +#define BOOST_ASIO_IP_IMPL_ADDRESS_V4_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(BOOST_NO_IOSTREAM) + +#include <boost/asio/detail/throw_error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace ip { + +template <typename Elem, typename Traits> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, const address_v4& addr) +{ + boost::system::error_code ec; + std::string s = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::basic_ostream<Elem, Traits>::failbit) + boost::asio::detail::throw_error(ec); + else + os.setstate(std::basic_ostream<Elem, Traits>::failbit); + } + else + for (std::string::iterator i = s.begin(); i != s.end(); ++i) + os << os.widen(*i); + return os; +} + +} // namespace ip +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // !defined(BOOST_NO_IOSTREAM) + +#endif // BOOST_ASIO_IP_IMPL_ADDRESS_V4_HPP diff --git a/3rdParty/Boost/src/boost/asio/ip/impl/address_v4.ipp b/3rdParty/Boost/src/boost/asio/ip/impl/address_v4.ipp new file mode 100644 index 0000000..3cdcbf1 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/ip/impl/address_v4.ipp @@ -0,0 +1,164 @@ +// +// ip/impl/address_v4.ipp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_IP_IMPL_ADDRESS_V4_IPP +#define BOOST_ASIO_IP_IMPL_ADDRESS_V4_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <climits> +#include <stdexcept> +#include <boost/throw_exception.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/ip/address_v4.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace ip { + +address_v4::address_v4(const address_v4::bytes_type& bytes) +{ +#if UCHAR_MAX > 0xFF + if (bytes[0] > 0xFF || bytes[1] > 0xFF + || bytes[2] > 0xFF || bytes[3] > 0xFF) + { + std::out_of_range ex("address_v4 from bytes_type"); + boost::throw_exception(ex); + } +#endif // UCHAR_MAX > 0xFF + + using namespace std; // For memcpy. + memcpy(&addr_.s_addr, bytes.elems, 4); +} + +address_v4::address_v4(unsigned long addr) +{ +#if ULONG_MAX > 0xFFFFFFFF + if (addr > 0xFFFFFFFF) + { + std::out_of_range ex("address_v4 from unsigned long"); + boost::throw_exception(ex); + } +#endif // ULONG_MAX > 0xFFFFFFFF + + addr_.s_addr = boost::asio::detail::socket_ops::host_to_network_long(addr); +} + +address_v4::bytes_type address_v4::to_bytes() const +{ + using namespace std; // For memcpy. + bytes_type bytes; + memcpy(bytes.elems, &addr_.s_addr, 4); + return bytes; +} + +unsigned long address_v4::to_ulong() const +{ + return boost::asio::detail::socket_ops::network_to_host_long(addr_.s_addr); +} + +std::string address_v4::to_string() const +{ + boost::system::error_code ec; + std::string addr = to_string(ec); + boost::asio::detail::throw_error(ec); + return addr; +} + +std::string address_v4::to_string(boost::system::error_code& ec) const +{ + char addr_str[boost::asio::detail::max_addr_v4_str_len]; + const char* addr = + boost::asio::detail::socket_ops::inet_ntop(AF_INET, &addr_, addr_str, + boost::asio::detail::max_addr_v4_str_len, 0, ec); + if (addr == 0) + return std::string(); + return addr; +} + +address_v4 address_v4::from_string(const char* str) +{ + boost::system::error_code ec; + address_v4 addr = from_string(str, ec); + boost::asio::detail::throw_error(ec); + return addr; +} + +address_v4 address_v4::from_string( + const char* str, boost::system::error_code& ec) +{ + address_v4 tmp; + if (boost::asio::detail::socket_ops::inet_pton( + AF_INET, str, &tmp.addr_, 0, ec) <= 0) + return address_v4(); + return tmp; +} + +address_v4 address_v4::from_string(const std::string& str) +{ + return from_string(str.c_str()); +} + +address_v4 address_v4::from_string( + const std::string& str, boost::system::error_code& ec) +{ + return from_string(str.c_str(), ec); +} + +bool address_v4::is_class_a() const +{ + return IN_CLASSA(to_ulong()); +} + +bool address_v4::is_class_b() const +{ + return IN_CLASSB(to_ulong()); +} + +bool address_v4::is_class_c() const +{ + return IN_CLASSC(to_ulong()); +} + +bool address_v4::is_multicast() const +{ + return IN_MULTICAST(to_ulong()); +} + +address_v4 address_v4::broadcast(const address_v4& addr, const address_v4& mask) +{ + return address_v4(addr.to_ulong() | ~mask.to_ulong()); +} + +address_v4 address_v4::netmask(const address_v4& addr) +{ + if (addr.is_class_a()) + return address_v4(0xFF000000); + if (addr.is_class_b()) + return address_v4(0xFFFF0000); + if (addr.is_class_c()) + return address_v4(0xFFFFFF00); + return address_v4(0xFFFFFFFF); +} + +} // namespace ip +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_IP_IMPL_ADDRESS_V4_IPP diff --git a/3rdParty/Boost/src/boost/asio/ip/impl/address_v6.hpp b/3rdParty/Boost/src/boost/asio/ip/impl/address_v6.hpp new file mode 100644 index 0000000..8b39e3e --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/ip/impl/address_v6.hpp @@ -0,0 +1,55 @@ +// +// ip/impl/address_v6.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_IP_IMPL_ADDRESS_V6_HPP +#define BOOST_ASIO_IP_IMPL_ADDRESS_V6_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(BOOST_NO_IOSTREAM) + +#include <boost/asio/detail/throw_error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace ip { + +template <typename Elem, typename Traits> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, const address_v6& addr) +{ + boost::system::error_code ec; + std::string s = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::basic_ostream<Elem, Traits>::failbit) + boost::asio::detail::throw_error(ec); + else + os.setstate(std::basic_ostream<Elem, Traits>::failbit); + } + else + for (std::string::iterator i = s.begin(); i != s.end(); ++i) + os << os.widen(*i); + return os; +} + +} // namespace ip +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // !defined(BOOST_NO_IOSTREAM) + +#endif // BOOST_ASIO_IP_IMPL_ADDRESS_V6_HPP diff --git a/3rdParty/Boost/src/boost/asio/ip/impl/address_v6.ipp b/3rdParty/Boost/src/boost/asio/ip/impl/address_v6.ipp new file mode 100644 index 0000000..a06dfe5 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/ip/impl/address_v6.ipp @@ -0,0 +1,286 @@ +// +// ip/impl/address_v6.ipp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP +#define BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <cstring> +#include <stdexcept> +#include <typeinfo> +#include <boost/throw_exception.hpp> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/ip/address_v6.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace ip { + +address_v6::address_v6() + : scope_id_(0) +{ + boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; + addr_ = tmp_addr; +} + +address_v6::address_v6(const address_v6::bytes_type& bytes, + unsigned long scope_id) + : scope_id_(scope_id) +{ +#if UCHAR_MAX > 0xFF + for (std::size_t i = 0; i < bytes.size(); ++i) + { + if (bytes[i] > 0xFF) + { + std::out_of_range ex("address_v6 from bytes_type"); + boost::throw_exception(ex); + } + } +#endif // UCHAR_MAX > 0xFF + + using namespace std; // For memcpy. + memcpy(addr_.s6_addr, bytes.elems, 16); +} + +address_v6::address_v6(const address_v6& other) + : addr_(other.addr_), + scope_id_(other.scope_id_) +{ +} + +address_v6& address_v6::operator=(const address_v6& other) +{ + addr_ = other.addr_; + scope_id_ = other.scope_id_; + return *this; +} + +address_v6::bytes_type address_v6::to_bytes() const +{ + using namespace std; // For memcpy. + bytes_type bytes; + memcpy(bytes.elems, addr_.s6_addr, 16); + return bytes; +} + +std::string address_v6::to_string() const +{ + boost::system::error_code ec; + std::string addr = to_string(ec); + boost::asio::detail::throw_error(ec); + return addr; +} + +std::string address_v6::to_string(boost::system::error_code& ec) const +{ + char addr_str[boost::asio::detail::max_addr_v6_str_len]; + const char* addr = + boost::asio::detail::socket_ops::inet_ntop(AF_INET6, &addr_, addr_str, + boost::asio::detail::max_addr_v6_str_len, scope_id_, ec); + if (addr == 0) + return std::string(); + return addr; +} + +address_v6 address_v6::from_string(const char* str) +{ + boost::system::error_code ec; + address_v6 addr = from_string(str, ec); + boost::asio::detail::throw_error(ec); + return addr; +} + +address_v6 address_v6::from_string( + const char* str, boost::system::error_code& ec) +{ + address_v6 tmp; + if (boost::asio::detail::socket_ops::inet_pton( + AF_INET6, str, &tmp.addr_, &tmp.scope_id_, ec) <= 0) + return address_v6(); + return tmp; +} + +address_v6 address_v6::from_string(const std::string& str) +{ + return from_string(str.c_str()); +} + +address_v6 address_v6::from_string( + const std::string& str, boost::system::error_code& ec) +{ + return from_string(str.c_str(), ec); +} + +address_v4 address_v6::to_v4() const +{ + if (!is_v4_mapped() && !is_v4_compatible()) + { + std::bad_cast ex; + boost::throw_exception(ex); + } + + address_v4::bytes_type v4_bytes = { { addr_.s6_addr[12], + addr_.s6_addr[13], addr_.s6_addr[14], addr_.s6_addr[15] } }; + return address_v4(v4_bytes); +} + +bool address_v6::is_loopback() const +{ +#if defined(__BORLANDC__) + return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) + && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) + && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) + && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) + && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) + && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) + && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0) + && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1)); +#else + using namespace boost::asio::detail; + return IN6_IS_ADDR_LOOPBACK(&addr_) != 0; +#endif +} + +bool address_v6::is_unspecified() const +{ +#if defined(__BORLANDC__) + return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) + && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) + && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) + && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) + && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) + && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) + && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0) + && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0)); +#else + using namespace boost::asio::detail; + return IN6_IS_ADDR_UNSPECIFIED(&addr_) != 0; +#endif +} + +bool address_v6::is_link_local() const +{ + using namespace boost::asio::detail; + return IN6_IS_ADDR_LINKLOCAL(&addr_) != 0; +} + +bool address_v6::is_site_local() const +{ + using namespace boost::asio::detail; + return IN6_IS_ADDR_SITELOCAL(&addr_) != 0; +} + +bool address_v6::is_v4_mapped() const +{ + using namespace boost::asio::detail; + return IN6_IS_ADDR_V4MAPPED(&addr_) != 0; +} + +bool address_v6::is_v4_compatible() const +{ + using namespace boost::asio::detail; + return IN6_IS_ADDR_V4COMPAT(&addr_) != 0; +} + +bool address_v6::is_multicast() const +{ + using namespace boost::asio::detail; + return IN6_IS_ADDR_MULTICAST(&addr_) != 0; +} + +bool address_v6::is_multicast_global() const +{ + using namespace boost::asio::detail; + return IN6_IS_ADDR_MC_GLOBAL(&addr_) != 0; +} + +bool address_v6::is_multicast_link_local() const +{ + using namespace boost::asio::detail; + return IN6_IS_ADDR_MC_LINKLOCAL(&addr_) != 0; +} + +bool address_v6::is_multicast_node_local() const +{ + using namespace boost::asio::detail; + return IN6_IS_ADDR_MC_NODELOCAL(&addr_) != 0; +} + +bool address_v6::is_multicast_org_local() const +{ + using namespace boost::asio::detail; + return IN6_IS_ADDR_MC_ORGLOCAL(&addr_) != 0; +} + +bool address_v6::is_multicast_site_local() const +{ + using namespace boost::asio::detail; + return IN6_IS_ADDR_MC_SITELOCAL(&addr_) != 0; +} + +bool operator==(const address_v6& a1, const address_v6& a2) +{ + using namespace std; // For memcmp. + return memcmp(&a1.addr_, &a2.addr_, + sizeof(boost::asio::detail::in6_addr_type)) == 0 + && a1.scope_id_ == a2.scope_id_; +} + +bool operator<(const address_v6& a1, const address_v6& a2) +{ + using namespace std; // For memcmp. + int memcmp_result = memcmp(&a1.addr_, &a2.addr_, + sizeof(boost::asio::detail::in6_addr_type)); + if (memcmp_result < 0) + return true; + if (memcmp_result > 0) + return false; + return a1.scope_id_ < a2.scope_id_; +} + +address_v6 address_v6::loopback() +{ + address_v6 tmp; + boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_LOOPBACK_INIT; + tmp.addr_ = tmp_addr; + return tmp; +} + +address_v6 address_v6::v4_mapped(const address_v4& addr) +{ + address_v4::bytes_type v4_bytes = addr.to_bytes(); + bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, + v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; + return address_v6(v6_bytes); +} + +address_v6 address_v6::v4_compatible(const address_v4& addr) +{ + address_v4::bytes_type v4_bytes = addr.to_bytes(); + bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; + return address_v6(v6_bytes); +} + +} // namespace ip +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP diff --git a/3rdParty/Boost/src/boost/asio/ip/impl/basic_endpoint.hpp b/3rdParty/Boost/src/boost/asio/ip/impl/basic_endpoint.hpp new file mode 100644 index 0000000..474c193 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/ip/impl/basic_endpoint.hpp @@ -0,0 +1,57 @@ +// +// ip/impl/basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_IP_IMPL_BASIC_ENDPOINT_HPP +#define BOOST_ASIO_IP_IMPL_BASIC_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(BOOST_NO_IOSTREAM) + +#include <boost/asio/detail/throw_error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace ip { + +template <typename Elem, typename Traits, typename InternetProtocol> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, + const basic_endpoint<InternetProtocol>& endpoint) +{ + boost::asio::ip::detail::endpoint tmp_ep(endpoint.address(), endpoint.port()); + boost::system::error_code ec; + std::string s = tmp_ep.to_string(ec); + if (ec) + { + if (os.exceptions() & std::basic_ostream<Elem, Traits>::failbit) + boost::asio::detail::throw_error(ec); + else + os.setstate(std::basic_ostream<Elem, Traits>::failbit); + } + else + for (std::string::iterator i = s.begin(); i != s.end(); ++i) + os << os.widen(*i); + return os; +} + +} // namespace ip +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // !defined(BOOST_NO_IOSTREAM) + +#endif // BOOST_ASIO_IP_IMPL_BASIC_ENDPOINT_HPP diff --git a/3rdParty/Boost/src/boost/asio/ip/impl/host_name.ipp b/3rdParty/Boost/src/boost/asio/ip/impl/host_name.ipp new file mode 100644 index 0000000..a5ba582 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/ip/impl/host_name.ipp @@ -0,0 +1,56 @@ +// +// ip/impl/host_name.ipp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_IP_IMPL_HOST_NAME_IPP +#define BOOST_ASIO_IP_IMPL_HOST_NAME_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/detail/winsock_init.hpp> +#include <boost/asio/ip/host_name.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace ip { + +std::string host_name() +{ + char name[1024]; + boost::system::error_code ec; + if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) + { + boost::asio::detail::throw_error(ec); + return std::string(); + } + return std::string(name); +} + +std::string host_name(boost::system::error_code& ec) +{ + char name[1024]; + if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) + return std::string(); + return std::string(name); +} + +} // namespace ip +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_IP_IMPL_HOST_NAME_IPP diff --git a/3rdParty/Boost/src/boost/asio/ip/multicast.hpp b/3rdParty/Boost/src/boost/asio/ip/multicast.hpp index 3aab7f0..e4d9f88 100644 --- a/3rdParty/Boost/src/boost/asio/ip/multicast.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/multicast.hpp @@ -1,6 +1,6 @@ // -// multicast.hpp -// ~~~~~~~~~~~~~ +// ip/multicast.hpp +// ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,15 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/ip/detail/socket_option.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace ip { diff --git a/3rdParty/Boost/src/boost/asio/ip/resolver_query_base.hpp b/3rdParty/Boost/src/boost/asio/ip/resolver_query_base.hpp index 7fe1650..0173e11 100644 --- a/3rdParty/Boost/src/boost/asio/ip/resolver_query_base.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/resolver_query_base.hpp @@ -1,6 +1,6 @@ // -// resolver_query_base.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~ +// ip/resolver_query_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,15 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/detail/workaround.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace ip { diff --git a/3rdParty/Boost/src/boost/asio/ip/resolver_service.hpp b/3rdParty/Boost/src/boost/asio/ip/resolver_service.hpp index ba59f6d..b13e0ad 100644 --- a/3rdParty/Boost/src/boost/asio/ip/resolver_service.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/resolver_service.hpp @@ -1,6 +1,6 @@ // -// resolver_service.hpp -// ~~~~~~~~~~~~~~~~~~~~ +// ip/resolver_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,14 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/error.hpp> +#include <boost/asio/detail/config.hpp> +#include <boost/system/error_code.hpp> +#include <boost/asio/detail/resolver_service.hpp> #include <boost/asio/io_service.hpp> #include <boost/asio/ip/basic_resolver_iterator.hpp> #include <boost/asio/ip/basic_resolver_query.hpp> -#include <boost/asio/detail/resolver_service.hpp> -#include <boost/asio/detail/service_base.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -73,13 +73,14 @@ public: explicit resolver_service(boost::asio::io_service& io_service) : boost::asio::detail::service_base< resolver_service<InternetProtocol> >(io_service), - service_impl_(boost::asio::use_service<service_impl_type>(io_service)) + service_impl_(io_service) { } /// Destroy all user-defined handler objects owned by the service. void shutdown_service() { + service_impl_.shutdown_service(); } /// Construct a new resolver implementation. @@ -131,8 +132,8 @@ public: } private: - // The service that provides the platform-specific implementation. - service_impl_type& service_impl_; + // The platform-specific implementation. + service_impl_type service_impl_; }; } // namespace ip diff --git a/3rdParty/Boost/src/boost/asio/ip/tcp.hpp b/3rdParty/Boost/src/boost/asio/ip/tcp.hpp index 541c95c..2026148 100644 --- a/3rdParty/Boost/src/boost/asio/ip/tcp.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/tcp.hpp @@ -1,6 +1,6 @@ // -// tcp.hpp -// ~~~~~~~ +// ip/tcp.hpp +// ~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,17 +15,18 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/basic_socket_acceptor.hpp> #include <boost/asio/basic_socket_iostream.hpp> #include <boost/asio/basic_stream_socket.hpp> +#include <boost/asio/detail/socket_option.hpp> +#include <boost/asio/detail/socket_types.hpp> #include <boost/asio/ip/basic_endpoint.hpp> #include <boost/asio/ip/basic_resolver.hpp> #include <boost/asio/ip/basic_resolver_iterator.hpp> #include <boost/asio/ip/basic_resolver_query.hpp> -#include <boost/asio/detail/socket_option.hpp> -#include <boost/asio/detail/socket_types.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/ip/udp.hpp b/3rdParty/Boost/src/boost/asio/ip/udp.hpp index e592e06..4d78692 100644 --- a/3rdParty/Boost/src/boost/asio/ip/udp.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/udp.hpp @@ -1,6 +1,6 @@ // -// udp.hpp -// ~~~~~~~ +// ip/udp.hpp +// ~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,14 +15,15 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/basic_datagram_socket.hpp> +#include <boost/asio/detail/socket_types.hpp> #include <boost/asio/ip/basic_endpoint.hpp> #include <boost/asio/ip/basic_resolver.hpp> #include <boost/asio/ip/basic_resolver_iterator.hpp> #include <boost/asio/ip/basic_resolver_query.hpp> -#include <boost/asio/detail/socket_types.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/ip/unicast.hpp b/3rdParty/Boost/src/boost/asio/ip/unicast.hpp index c97e6fd..1f331de 100644 --- a/3rdParty/Boost/src/boost/asio/ip/unicast.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/unicast.hpp @@ -1,6 +1,6 @@ // -// unicast.hpp -// ~~~~~~~~~~~ +// ip/unicast.hpp +// ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,15 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/ip/detail/socket_option.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace ip { diff --git a/3rdParty/Boost/src/boost/asio/ip/v6_only.hpp b/3rdParty/Boost/src/boost/asio/ip/v6_only.hpp index 9adcbff..e9aab31 100644 --- a/3rdParty/Boost/src/boost/asio/ip/v6_only.hpp +++ b/3rdParty/Boost/src/boost/asio/ip/v6_only.hpp @@ -1,6 +1,6 @@ // -// v6_only.hpp -// ~~~~~~~~~~~ +// ip/v6_only.hpp +// ~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,10 +15,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/socket_option.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace ip { diff --git a/3rdParty/Boost/src/boost/asio/is_read_buffered.hpp b/3rdParty/Boost/src/boost/asio/is_read_buffered.hpp index f0989a2..e429e6d 100644 --- a/3rdParty/Boost/src/boost/asio/is_read_buffered.hpp +++ b/3rdParty/Boost/src/boost/asio/is_read_buffered.hpp @@ -15,15 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/buffered_read_stream_fwd.hpp> #include <boost/asio/buffered_stream_fwd.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/is_write_buffered.hpp b/3rdParty/Boost/src/boost/asio/is_write_buffered.hpp index bcdf77d..fff68d6 100644 --- a/3rdParty/Boost/src/boost/asio/is_write_buffered.hpp +++ b/3rdParty/Boost/src/boost/asio/is_write_buffered.hpp @@ -15,15 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/buffered_stream_fwd.hpp> #include <boost/asio/buffered_write_stream_fwd.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/local/basic_endpoint.hpp b/3rdParty/Boost/src/boost/asio/local/basic_endpoint.hpp index 1e4057f..2cd93f6 100644 --- a/3rdParty/Boost/src/boost/asio/local/basic_endpoint.hpp +++ b/3rdParty/Boost/src/boost/asio/local/basic_endpoint.hpp @@ -1,6 +1,6 @@ // -// basic_endpoint.hpp -// ~~~~~~~~~~~~~~~~~~ +// local/basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Derived from a public domain implementation written by Daniel Casimiro. @@ -16,30 +16,18 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/throw_exception.hpp> -#include <cstddef> -#include <cstring> -#include <ostream> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> -#include <boost/asio/detail/socket_ops.hpp> -#include <boost/asio/detail/socket_types.hpp> -#include <boost/asio/detail/throw_error.hpp> - -#if !defined(BOOST_ASIO_DISABLE_LOCAL_SOCKETS) -# if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) -# define BOOST_ASIO_HAS_LOCAL_SOCKETS 1 -# endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) -#endif // !defined(BOOST_ASIO_DISABLE_LOCAL_SOCKETS) +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/local/detail/endpoint.hpp> + +#if !defined(BOOST_NO_IOSTREAM) +# include <iosfwd> +#endif // !defined(BOOST_NO_IOSTREAM) + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -75,34 +63,30 @@ public: /// Default constructor. basic_endpoint() { - init("", 0); } /// Construct an endpoint using the specified path name. basic_endpoint(const char* path) + : impl_(path) { - using namespace std; // For strlen. - init(path, strlen(path)); } /// Construct an endpoint using the specified path name. basic_endpoint(const std::string& path) + : impl_(path) { - init(path.data(), path.length()); } /// Copy constructor. basic_endpoint(const basic_endpoint& other) - : data_(other.data_), - path_length_(other.path_length_) + : impl_(other.impl_) { } /// Assign from another endpoint. basic_endpoint& operator=(const basic_endpoint& other) { - data_ = other.data_; - path_length_ = other.path_length_; + impl_ = other.impl_; return *this; } @@ -115,123 +99,96 @@ public: /// Get the underlying endpoint in the native type. data_type* data() { - return &data_.base; + return impl_.data(); } /// Get the underlying endpoint in the native type. const data_type* data() const { - return &data_.base; + return impl_.data(); } /// Get the underlying size of the endpoint in the native type. std::size_t size() const { - return path_length_ - + offsetof(boost::asio::detail::sockaddr_un_type, sun_path); + return impl_.size(); } /// Set the underlying size of the endpoint in the native type. void resize(std::size_t size) { - if (size > sizeof(boost::asio::detail::sockaddr_un_type)) - { - boost::system::system_error e(boost::asio::error::invalid_argument); - boost::throw_exception(e); - } - else if (size == 0) - { - path_length_ = 0; - } - else - { - path_length_ = size - - offsetof(boost::asio::detail::sockaddr_un_type, sun_path); - - // The path returned by the operating system may be NUL-terminated. - if (path_length_ > 0 && data_.local.sun_path[path_length_ - 1] == 0) - --path_length_; - } + impl_.resize(size); } /// Get the capacity of the endpoint in the native type. std::size_t capacity() const { - return sizeof(boost::asio::detail::sockaddr_un_type); + return impl_.capacity(); } /// Get the path associated with the endpoint. std::string path() const { - return std::string(data_.local.sun_path, path_length_); + return impl_.path(); } /// Set the path associated with the endpoint. void path(const char* p) { - using namespace std; // For strlen. - init(p, strlen(p)); + impl_.path(p); } /// Set the path associated with the endpoint. void path(const std::string& p) { - init(p.data(), p.length()); + impl_.path(p); } /// Compare two endpoints for equality. friend bool operator==(const basic_endpoint<Protocol>& e1, const basic_endpoint<Protocol>& e2) { - return e1.path() == e2.path(); + return e1.impl_ == e2.impl_; } /// Compare two endpoints for inequality. friend bool operator!=(const basic_endpoint<Protocol>& e1, const basic_endpoint<Protocol>& e2) { - return e1.path() != e2.path(); + return !(e1.impl_ == e2.impl_); } /// Compare endpoints for ordering. friend bool operator<(const basic_endpoint<Protocol>& e1, const basic_endpoint<Protocol>& e2) { - return e1.path() < e2.path(); + return e1.impl_ < e2.impl_; } -private: - // The underlying UNIX socket address. - union data_union + /// Compare endpoints for ordering. + friend bool operator>(const basic_endpoint<Protocol>& e1, + const basic_endpoint<Protocol>& e2) { - boost::asio::detail::socket_addr_type base; - boost::asio::detail::sockaddr_un_type local; - } data_; + return e2.impl_ < e1.impl_; + } - // The length of the path associated with the endpoint. - std::size_t path_length_; + /// Compare endpoints for ordering. + friend bool operator<=(const basic_endpoint<Protocol>& e1, + const basic_endpoint<Protocol>& e2) + { + return !(e2 < e1); + } - // Initialise with a specified path. - void init(const char* path, std::size_t path_length) + /// Compare endpoints for ordering. + friend bool operator>=(const basic_endpoint<Protocol>& e1, + const basic_endpoint<Protocol>& e2) { - if (path_length > sizeof(data_.local.sun_path) - 1) - { - // The buffer is not large enough to store this address. - boost::system::error_code ec(boost::asio::error::name_too_long); - boost::asio::detail::throw_error(ec); - } - - using namespace std; // For memcpy. - data_.local = boost::asio::detail::sockaddr_un_type(); - data_.local.sun_family = AF_UNIX; - memcpy(data_.local.sun_path, path, path_length); - path_length_ = path_length; - - // NUL-terminate normal path names. Names that start with a NUL are in the - // UNIX domain protocol's "abstract namespace" and are not NUL-terminated. - if (path_length > 0 && data_.local.sun_path[0] == 0) - data_.local.sun_path[path_length] = 0; + return !(e1 < e2); } + +private: + // The underlying UNIX domain endpoint. + boost::asio::local::detail::endpoint impl_; }; /// Output an endpoint as a string. @@ -259,9 +216,9 @@ std::basic_ostream<Elem, Traits>& operator<<( } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_LOCAL_BASIC_ENDPOINT_HPP diff --git a/3rdParty/Boost/src/boost/asio/local/connect_pair.hpp b/3rdParty/Boost/src/boost/asio/local/connect_pair.hpp index 697a0d2..cb08777 100644 --- a/3rdParty/Boost/src/boost/asio/local/connect_pair.hpp +++ b/3rdParty/Boost/src/boost/asio/local/connect_pair.hpp @@ -1,6 +1,6 @@ // -// connect_pair.hpp -// ~~~~~~~~~~~~~~~~ +// local/connect_pair.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,18 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) #include <boost/asio/basic_socket.hpp> -#include <boost/asio/error.hpp> -#include <boost/asio/local/basic_endpoint.hpp> #include <boost/asio/detail/socket_ops.hpp> #include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/local/basic_endpoint.hpp> -#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ - || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -74,8 +76,9 @@ inline boost::system::error_code connect_pair( if (socket1.assign(protocol, sv[0], ec)) { boost::system::error_code temp_ec; - boost::asio::detail::socket_ops::close(sv[0], temp_ec); - boost::asio::detail::socket_ops::close(sv[1], temp_ec); + boost::asio::detail::socket_ops::state_type state[2] = { 0, 0 }; + boost::asio::detail::socket_ops::close(sv[0], state[0], true, temp_ec); + boost::asio::detail::socket_ops::close(sv[1], state[1], true, temp_ec); return ec; } @@ -83,7 +86,8 @@ inline boost::system::error_code connect_pair( { boost::system::error_code temp_ec; socket1.close(temp_ec); - boost::asio::detail::socket_ops::close(sv[1], temp_ec); + boost::asio::detail::socket_ops::state_type state = 0; + boost::asio::detail::socket_ops::close(sv[1], state, true, temp_ec); return ec; } @@ -94,9 +98,9 @@ inline boost::system::error_code connect_pair( } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_LOCAL_CONNECT_PAIR_HPP diff --git a/3rdParty/Boost/src/boost/asio/local/datagram_protocol.hpp b/3rdParty/Boost/src/boost/asio/local/datagram_protocol.hpp index 1441ee6..2d78773 100644 --- a/3rdParty/Boost/src/boost/asio/local/datagram_protocol.hpp +++ b/3rdParty/Boost/src/boost/asio/local/datagram_protocol.hpp @@ -1,6 +1,6 @@ // -// datagram_protocol.hpp -// ~~~~~~~~~~~~~~~~~~~~~ +// local/datagram_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,14 +15,16 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) #include <boost/asio/basic_datagram_socket.hpp> -#include <boost/asio/local/basic_endpoint.hpp> #include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/local/basic_endpoint.hpp> -#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ - || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -72,9 +74,9 @@ public: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP diff --git a/3rdParty/Boost/src/boost/asio/local/detail/endpoint.hpp b/3rdParty/Boost/src/boost/asio/local/detail/endpoint.hpp new file mode 100644 index 0000000..5fb7297 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/local/detail/endpoint.hpp @@ -0,0 +1,135 @@ +// +// local/detail/endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Derived from a public domain implementation written by Daniel Casimiro. +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_LOCAL_DETAIL_ENDPOINT_HPP +#define BOOST_ASIO_LOCAL_DETAIL_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) + +#include <cstddef> +#include <string> +#include <boost/asio/detail/socket_types.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace local { +namespace detail { + +// Helper class for implementing a UNIX domain endpoint. +class endpoint +{ +public: + // Default constructor. + BOOST_ASIO_DECL endpoint(); + + // Construct an endpoint using the specified path name. + BOOST_ASIO_DECL endpoint(const char* path); + + // Construct an endpoint using the specified path name. + BOOST_ASIO_DECL endpoint(const std::string& path); + + // Copy constructor. + endpoint(const endpoint& other) + : data_(other.data_), + path_length_(other.path_length_) + { + } + + // Assign from another endpoint. + endpoint& operator=(const endpoint& other) + { + data_ = other.data_; + path_length_ = other.path_length_; + return *this; + } + + // Get the underlying endpoint in the native type. + boost::asio::detail::socket_addr_type* data() + { + return &data_.base; + } + + // Get the underlying endpoint in the native type. + const boost::asio::detail::socket_addr_type* data() const + { + return &data_.base; + } + + // Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + return path_length_ + + offsetof(boost::asio::detail::sockaddr_un_type, sun_path); + } + + // Set the underlying size of the endpoint in the native type. + BOOST_ASIO_DECL void resize(std::size_t size); + + // Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return sizeof(boost::asio::detail::sockaddr_un_type); + } + + // Get the path associated with the endpoint. + BOOST_ASIO_DECL std::string path() const; + + // Set the path associated with the endpoint. + BOOST_ASIO_DECL void path(const char* p); + + // Set the path associated with the endpoint. + BOOST_ASIO_DECL void path(const std::string& p); + + // Compare two endpoints for equality. + BOOST_ASIO_DECL friend bool operator==( + const endpoint& e1, const endpoint& e2); + + // Compare endpoints for ordering. + BOOST_ASIO_DECL friend bool operator<( + const endpoint& e1, const endpoint& e2); + +private: + // The underlying UNIX socket address. + union data_union + { + boost::asio::detail::socket_addr_type base; + boost::asio::detail::sockaddr_un_type local; + } data_; + + // The length of the path associated with the endpoint. + std::size_t path_length_; + + // Initialise with a specified path. + BOOST_ASIO_DECL void init(const char* path, std::size_t path_length); +}; + +} // namespace detail +} // namespace local +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/local/detail/impl/endpoint.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) + +#endif // BOOST_ASIO_LOCAL_DETAIL_ENDPOINT_HPP diff --git a/3rdParty/Boost/src/boost/asio/local/detail/impl/endpoint.ipp b/3rdParty/Boost/src/boost/asio/local/detail/impl/endpoint.ipp new file mode 100644 index 0000000..ffbc44e --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/local/detail/impl/endpoint.ipp @@ -0,0 +1,130 @@ +// +// local/detail/impl/endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Derived from a public domain implementation written by Daniel Casimiro. +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP +#define BOOST_ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) + +#include <cstring> +#include <boost/asio/detail/socket_ops.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> +#include <boost/asio/local/detail/endpoint.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace local { +namespace detail { + +endpoint::endpoint() +{ + init("", 0); +} + +endpoint::endpoint(const char* path) +{ + using namespace std; // For strlen. + init(path, strlen(path)); +} + +endpoint::endpoint(const std::string& path) +{ + init(path.data(), path.length()); +} + +void endpoint::resize(std::size_t size) +{ + if (size > sizeof(boost::asio::detail::sockaddr_un_type)) + { + boost::system::error_code ec(boost::asio::error::invalid_argument); + boost::asio::detail::throw_error(ec); + } + else if (size == 0) + { + path_length_ = 0; + } + else + { + path_length_ = size + - offsetof(boost::asio::detail::sockaddr_un_type, sun_path); + + // The path returned by the operating system may be NUL-terminated. + if (path_length_ > 0 && data_.local.sun_path[path_length_ - 1] == 0) + --path_length_; + } +} + +std::string endpoint::path() const +{ + return std::string(data_.local.sun_path, path_length_); +} + +void endpoint::path(const char* p) +{ + using namespace std; // For strlen. + init(p, strlen(p)); +} + +void endpoint::path(const std::string& p) +{ + init(p.data(), p.length()); +} + +bool operator==(const endpoint& e1, const endpoint& e2) +{ + return e1.path() == e2.path(); +} + +bool operator<(const endpoint& e1, const endpoint& e2) +{ + return e1.path() < e2.path(); +} + +void endpoint::init(const char* path, std::size_t path_length) +{ + if (path_length > sizeof(data_.local.sun_path) - 1) + { + // The buffer is not large enough to store this address. + boost::system::error_code ec(boost::asio::error::name_too_long); + boost::asio::detail::throw_error(ec); + } + + using namespace std; // For memcpy. + data_.local = boost::asio::detail::sockaddr_un_type(); + data_.local.sun_family = AF_UNIX; + memcpy(data_.local.sun_path, path, path_length); + path_length_ = path_length; + + // NUL-terminate normal path names. Names that start with a NUL are in the + // UNIX domain protocol's "abstract namespace" and are not NUL-terminated. + if (path_length > 0 && data_.local.sun_path[0] == 0) + data_.local.sun_path[path_length] = 0; +} + +} // namespace detail +} // namespace local +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) + +#endif // BOOST_ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP diff --git a/3rdParty/Boost/src/boost/asio/local/stream_protocol.hpp b/3rdParty/Boost/src/boost/asio/local/stream_protocol.hpp index f341a8b..723c348 100644 --- a/3rdParty/Boost/src/boost/asio/local/stream_protocol.hpp +++ b/3rdParty/Boost/src/boost/asio/local/stream_protocol.hpp @@ -1,6 +1,6 @@ // -// stream_protocol.hpp -// ~~~~~~~~~~~~~~~~~~~ +// local/stream_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,18 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) #include <boost/asio/basic_socket_acceptor.hpp> #include <boost/asio/basic_socket_iostream.hpp> #include <boost/asio/basic_stream_socket.hpp> -#include <boost/asio/local/basic_endpoint.hpp> #include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/local/basic_endpoint.hpp> -#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ - || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -82,9 +84,9 @@ public: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_HPP diff --git a/3rdParty/Boost/src/boost/asio/placeholders.hpp b/3rdParty/Boost/src/boost/asio/placeholders.hpp index 55b6fd7..2940eda 100644 --- a/3rdParty/Boost/src/boost/asio/placeholders.hpp +++ b/3rdParty/Boost/src/boost/asio/placeholders.hpp @@ -15,12 +15,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/bind/arg.hpp> #include <boost/detail/workaround.hpp> -#include <boost/asio/detail/pop_options.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/posix/basic_descriptor.hpp b/3rdParty/Boost/src/boost/asio/posix/basic_descriptor.hpp index ff9cb87..56ec9d8 100644 --- a/3rdParty/Boost/src/boost/asio/posix/basic_descriptor.hpp +++ b/3rdParty/Boost/src/boost/asio/posix/basic_descriptor.hpp @@ -1,6 +1,6 @@ // -// basic_descriptor.hpp -// ~~~~~~~~~~~~~~~~~~~~ +// posix/basic_descriptor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,17 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ + || defined(GENERATING_DOCUMENTATION) #include <boost/asio/basic_io_object.hpp> +#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> #include <boost/asio/posix/descriptor_base.hpp> -#include <boost/asio/detail/throw_error.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -293,4 +294,7 @@ protected: #include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) + // || defined(GENERATING_DOCUMENTATION) + #endif // BOOST_ASIO_POSIX_BASIC_DESCRIPTOR_HPP diff --git a/3rdParty/Boost/src/boost/asio/posix/basic_stream_descriptor.hpp b/3rdParty/Boost/src/boost/asio/posix/basic_stream_descriptor.hpp index d83a7f7..0f70604 100644 --- a/3rdParty/Boost/src/boost/asio/posix/basic_stream_descriptor.hpp +++ b/3rdParty/Boost/src/boost/asio/posix/basic_stream_descriptor.hpp @@ -1,6 +1,6 @@ // -// basic_stream_descriptor.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// posix/basic_stream_descriptor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,20 +15,18 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ + || defined(GENERATING_DOCUMENTATION) +#include <cstddef> +#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> #include <boost/asio/posix/basic_descriptor.hpp> #include <boost/asio/posix/stream_descriptor_service.hpp> -#include <boost/asio/detail/throw_error.hpp> -#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ - || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -298,9 +296,9 @@ public: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP diff --git a/3rdParty/Boost/src/boost/asio/posix/descriptor_base.hpp b/3rdParty/Boost/src/boost/asio/posix/descriptor_base.hpp index ca93f4d..70bac63 100644 --- a/3rdParty/Boost/src/boost/asio/posix/descriptor_base.hpp +++ b/3rdParty/Boost/src/boost/asio/posix/descriptor_base.hpp @@ -1,6 +1,6 @@ // -// descriptor_base.hpp -// ~~~~~~~~~~~~~~~~~~~ +// posix/descriptor_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,16 +15,16 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/detail/workaround.hpp> -#include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ + || defined(GENERATING_DOCUMENTATION) #include <boost/asio/detail/io_control.hpp> #include <boost/asio/detail/socket_option.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace posix { @@ -92,4 +92,7 @@ protected: #include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) + // || defined(GENERATING_DOCUMENTATION) + #endif // BOOST_ASIO_POSIX_DESCRIPTOR_BASE_HPP diff --git a/3rdParty/Boost/src/boost/asio/posix/stream_descriptor.hpp b/3rdParty/Boost/src/boost/asio/posix/stream_descriptor.hpp index 3b01618..30b7e37 100644 --- a/3rdParty/Boost/src/boost/asio/posix/stream_descriptor.hpp +++ b/3rdParty/Boost/src/boost/asio/posix/stream_descriptor.hpp @@ -1,6 +1,6 @@ // -// stream_descriptor.hpp -// ~~~~~~~~~~~~~~~~~~~~~ +// posix/stream_descriptor.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,13 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/posix/basic_stream_descriptor.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/posix/basic_stream_descriptor.hpp> + namespace boost { namespace asio { namespace posix { @@ -36,6 +36,4 @@ typedef basic_stream_descriptor<> stream_descriptor; #endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_POSIX_STREAM_DESCRIPTOR_HPP diff --git a/3rdParty/Boost/src/boost/asio/posix/stream_descriptor_service.hpp b/3rdParty/Boost/src/boost/asio/posix/stream_descriptor_service.hpp index 89b9ef4..c2034da 100644 --- a/3rdParty/Boost/src/boost/asio/posix/stream_descriptor_service.hpp +++ b/3rdParty/Boost/src/boost/asio/posix/stream_descriptor_service.hpp @@ -1,6 +1,6 @@ // -// stream_descriptor_service.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// posix/stream_descriptor_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,28 +15,18 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/error.hpp> -#include <boost/asio/io_service.hpp> -#include <boost/asio/detail/service_base.hpp> - -#if !defined(BOOST_ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR) -# if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) -# define BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR 1 -# endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) -#endif // !defined(BOOST_ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR) +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ || defined(GENERATING_DOCUMENTATION) +#include <cstddef> +#include <boost/asio/error.hpp> +#include <boost/asio/io_service.hpp> #include <boost/asio/detail/reactive_descriptor_service.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { namespace posix { @@ -181,9 +171,9 @@ private: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_POSIX_STREAM_DESCRIPTOR_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/raw_socket_service.hpp b/3rdParty/Boost/src/boost/asio/raw_socket_service.hpp index 23427d7..0db83b6 100644 --- a/3rdParty/Boost/src/boost/asio/raw_socket_service.hpp +++ b/3rdParty/Boost/src/boost/asio/raw_socket_service.hpp @@ -15,16 +15,10 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> -#include <boost/asio/detail/service_base.hpp> #if defined(BOOST_ASIO_HAS_IOCP) # include <boost/asio/detail/win_iocp_socket_service.hpp> @@ -32,6 +26,8 @@ # include <boost/asio/detail/reactive_socket_service.hpp> #endif +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/read.hpp b/3rdParty/Boost/src/boost/asio/read.hpp index 40ccc00..d2339d5 100644 --- a/3rdParty/Boost/src/boost/asio/read.hpp +++ b/3rdParty/Boost/src/boost/asio/read.hpp @@ -15,16 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/basic_streambuf.hpp> +#include <boost/asio/basic_streambuf_fwd.hpp> #include <boost/asio/error.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { @@ -538,8 +535,8 @@ void async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b, } // namespace asio } // namespace boost -#include <boost/asio/impl/read.ipp> - #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/impl/read.hpp> + #endif // BOOST_ASIO_READ_HPP diff --git a/3rdParty/Boost/src/boost/asio/read_at.hpp b/3rdParty/Boost/src/boost/asio/read_at.hpp index 133f143..27bad65 100644 --- a/3rdParty/Boost/src/boost/asio/read_at.hpp +++ b/3rdParty/Boost/src/boost/asio/read_at.hpp @@ -15,17 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> #include <boost/cstdint.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/basic_streambuf.hpp> +#include <boost/asio/basic_streambuf_fwd.hpp> #include <boost/asio/error.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { @@ -571,8 +568,8 @@ void async_read_at(AsyncRandomAccessReadDevice& d, } // namespace asio } // namespace boost -#include <boost/asio/impl/read_at.ipp> - #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/impl/read_at.hpp> + #endif // BOOST_ASIO_READ_AT_HPP diff --git a/3rdParty/Boost/src/boost/asio/read_until.hpp b/3rdParty/Boost/src/boost/asio/read_until.hpp index ec6cb42..aa9d2ba 100644 --- a/3rdParty/Boost/src/boost/asio/read_until.hpp +++ b/3rdParty/Boost/src/boost/asio/read_until.hpp @@ -15,27 +15,22 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_NO_IOSTREAM) -#include <boost/asio/detail/push_options.hpp> #include <cstddef> -#include <boost/regex.hpp> #include <boost/type_traits/is_function.hpp> #include <boost/type_traits/remove_pointer.hpp> #include <boost/utility/enable_if.hpp> #include <boost/detail/workaround.hpp> #include <string> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/basic_streambuf.hpp> +#include <boost/asio/detail/regex_fwd.hpp> #include <boost/asio/error.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { @@ -916,10 +911,10 @@ void async_read_until(AsyncReadStream& s, } // namespace asio } // namespace boost -#include <boost/asio/impl/read_until.ipp> +#include <boost/asio/detail/pop_options.hpp> + +#include <boost/asio/impl/read_until.hpp> #endif // !defined(BOOST_NO_IOSTREAM) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_READ_UNTIL_HPP diff --git a/3rdParty/Boost/src/boost/asio/serial_port.hpp b/3rdParty/Boost/src/boost/asio/serial_port.hpp index 00546e8..9775739 100644 --- a/3rdParty/Boost/src/boost/asio/serial_port.hpp +++ b/3rdParty/Boost/src/boost/asio/serial_port.hpp @@ -16,13 +16,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/basic_serial_port.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_SERIAL_PORT) \ || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/basic_serial_port.hpp> + namespace boost { namespace asio { @@ -35,6 +35,4 @@ typedef basic_serial_port<> serial_port; #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_SERIAL_PORT_HPP diff --git a/3rdParty/Boost/src/boost/asio/serial_port_base.hpp b/3rdParty/Boost/src/boost/asio/serial_port_base.hpp index 5f96639..a050df2 100644 --- a/3rdParty/Boost/src/boost/asio/serial_port_base.hpp +++ b/3rdParty/Boost/src/boost/asio/serial_port_base.hpp @@ -16,32 +16,18 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <stdexcept> -#include <boost/config.hpp> -#include <boost/detail/workaround.hpp> -#include <boost/system/error_code.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#if !defined(BOOST_ASIO_DISABLE_SERIAL_PORT) -# if defined(BOOST_ASIO_HAS_IOCP) \ - || !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) -# define BOOST_ASIO_HAS_SERIAL_PORT 1 -# endif // defined(BOOST_ASIO_HAS_IOCP) -#endif // !defined(BOOST_ASIO_DISABLE_STREAM_HANDLE) +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_SERIAL_PORT) \ || defined(GENERATING_DOCUMENTATION) #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) -# include <boost/asio/detail/push_options.hpp> # include <termios.h> -# include <boost/asio/detail/pop_options.hpp> #endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#include <boost/detail/workaround.hpp> #include <boost/asio/detail/socket_types.hpp> +#include <boost/system/error_code.hpp> #if defined(GENERATING_DOCUMENTATION) # define BOOST_ASIO_OPTION_STORAGE implementation_defined @@ -51,6 +37,8 @@ # define BOOST_ASIO_OPTION_STORAGE termios #endif +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { @@ -68,9 +56,11 @@ public: public: explicit baud_rate(unsigned int rate = 0); unsigned int value() const; - boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage, + BOOST_ASIO_DECL boost::system::error_code store( + BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const; - boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage, + BOOST_ASIO_DECL boost::system::error_code load( + const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec); private: unsigned int value_; @@ -84,11 +74,13 @@ public: { public: enum type { none, software, hardware }; - explicit flow_control(type t = none); + BOOST_ASIO_DECL explicit flow_control(type t = none); type value() const; - boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage, + BOOST_ASIO_DECL boost::system::error_code store( + BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const; - boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage, + BOOST_ASIO_DECL boost::system::error_code load( + const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec); private: type value_; @@ -102,11 +94,13 @@ public: { public: enum type { none, odd, even }; - explicit parity(type t = none); + BOOST_ASIO_DECL explicit parity(type t = none); type value() const; - boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage, + BOOST_ASIO_DECL boost::system::error_code store( + BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const; - boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage, + BOOST_ASIO_DECL boost::system::error_code load( + const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec); private: type value_; @@ -120,11 +114,13 @@ public: { public: enum type { one, onepointfive, two }; - explicit stop_bits(type t = one); + BOOST_ASIO_DECL explicit stop_bits(type t = one); type value() const; - boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage, + BOOST_ASIO_DECL boost::system::error_code store( + BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const; - boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage, + BOOST_ASIO_DECL boost::system::error_code load( + const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec); private: type value_; @@ -137,11 +133,13 @@ public: class character_size { public: - explicit character_size(unsigned int t = 8); + BOOST_ASIO_DECL explicit character_size(unsigned int t = 8); unsigned int value() const; - boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage, + BOOST_ASIO_DECL boost::system::error_code store( + BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const; - boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage, + BOOST_ASIO_DECL boost::system::error_code load( + const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec); private: unsigned int value_; @@ -163,13 +161,16 @@ private: } // namespace asio } // namespace boost -#include <boost/asio/impl/serial_port_base.ipp> +#include <boost/asio/detail/pop_options.hpp> #undef BOOST_ASIO_OPTION_STORAGE +#include <boost/asio/impl/serial_port_base.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/impl/serial_port_base.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_SERIAL_PORT_BASE_HPP diff --git a/3rdParty/Boost/src/boost/asio/serial_port_service.hpp b/3rdParty/Boost/src/boost/asio/serial_port_service.hpp index f1a2344..b1c8301 100644 --- a/3rdParty/Boost/src/boost/asio/serial_port_service.hpp +++ b/3rdParty/Boost/src/boost/asio/serial_port_service.hpp @@ -15,23 +15,20 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \ + || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/push_options.hpp> #include <cstddef> -#include <boost/config.hpp> #include <string> -#include <boost/asio/detail/pop_options.hpp> - +#include <boost/asio/detail/reactive_serial_port_service.hpp> +#include <boost/asio/detail/win_iocp_serial_port_service.hpp> #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> #include <boost/asio/serial_port_base.hpp> -#include <boost/asio/detail/service_base.hpp> -#include <boost/asio/detail/reactive_serial_port_service.hpp> -#include <boost/asio/detail/win_iocp_serial_port_service.hpp> -#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \ - || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -201,9 +198,9 @@ private: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_SERIAL_PORT_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/socket_acceptor_service.hpp b/3rdParty/Boost/src/boost/asio/socket_acceptor_service.hpp index 184580f..3f7436b 100644 --- a/3rdParty/Boost/src/boost/asio/socket_acceptor_service.hpp +++ b/3rdParty/Boost/src/boost/asio/socket_acceptor_service.hpp @@ -15,12 +15,10 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - +#include <boost/asio/detail/config.hpp> #include <boost/asio/basic_socket.hpp> #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> -#include <boost/asio/detail/service_base.hpp> #if defined(BOOST_ASIO_HAS_IOCP) # include <boost/asio/detail/win_iocp_socket_service.hpp> @@ -28,6 +26,8 @@ # include <boost/asio/detail/reactive_socket_service.hpp> #endif +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/socket_base.hpp b/3rdParty/Boost/src/boost/asio/socket_base.hpp index 75015bf..083ffb6 100644 --- a/3rdParty/Boost/src/boost/asio/socket_base.hpp +++ b/3rdParty/Boost/src/boost/asio/socket_base.hpp @@ -15,17 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/detail/workaround.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/detail/io_control.hpp> #include <boost/asio/detail/socket_option.hpp> #include <boost/asio/detail/socket_types.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/strand.hpp b/3rdParty/Boost/src/boost/asio/strand.hpp index a64d486..e085030 100644 --- a/3rdParty/Boost/src/boost/asio/strand.hpp +++ b/3rdParty/Boost/src/boost/asio/strand.hpp @@ -15,11 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/io_service.hpp> +#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/strand_service.hpp> #include <boost/asio/detail/wrapped_handler.hpp> +#include <boost/asio/io_service.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/stream_socket_service.hpp b/3rdParty/Boost/src/boost/asio/stream_socket_service.hpp index 15aa683..101eacb 100644 --- a/3rdParty/Boost/src/boost/asio/stream_socket_service.hpp +++ b/3rdParty/Boost/src/boost/asio/stream_socket_service.hpp @@ -15,16 +15,10 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> -#include <boost/asio/detail/service_base.hpp> #if defined(BOOST_ASIO_HAS_IOCP) # include <boost/asio/detail/win_iocp_socket_service.hpp> @@ -32,6 +26,8 @@ # include <boost/asio/detail/reactive_socket_service.hpp> #endif +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/streambuf.hpp b/3rdParty/Boost/src/boost/asio/streambuf.hpp index c112e64..30196ad 100644 --- a/3rdParty/Boost/src/boost/asio/streambuf.hpp +++ b/3rdParty/Boost/src/boost/asio/streambuf.hpp @@ -15,12 +15,12 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/basic_streambuf.hpp> +#include <boost/asio/detail/config.hpp> #if !defined(BOOST_NO_IOSTREAM) +#include <boost/asio/basic_streambuf.hpp> + namespace boost { namespace asio { @@ -32,6 +32,4 @@ typedef basic_streambuf<> streambuf; #endif // !defined(BOOST_NO_IOSTREAM) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_STREAMBUF_HPP diff --git a/3rdParty/Boost/src/boost/asio/time_traits.hpp b/3rdParty/Boost/src/boost/asio/time_traits.hpp index e0f40ca..9043d7d 100644 --- a/3rdParty/Boost/src/boost/asio/time_traits.hpp +++ b/3rdParty/Boost/src/boost/asio/time_traits.hpp @@ -15,14 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - #include <boost/asio/detail/socket_types.hpp> // Must come before posix_time. #include <boost/asio/detail/push_options.hpp> #include <boost/date_time/posix_time/posix_time_types.hpp> #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { diff --git a/3rdParty/Boost/src/boost/asio/version.hpp b/3rdParty/Boost/src/boost/asio/version.hpp index 0172f73..20858bf 100644 --- a/3rdParty/Boost/src/boost/asio/version.hpp +++ b/3rdParty/Boost/src/boost/asio/version.hpp @@ -18,6 +18,6 @@ // BOOST_ASIO_VERSION % 100 is the sub-minor version // BOOST_ASIO_VERSION / 100 % 1000 is the minor version // BOOST_ASIO_VERSION / 100000 is the major version -#define BOOST_ASIO_VERSION 100405 // 1.4.5 +#define BOOST_ASIO_VERSION 100407 // 1.4.7 #endif // BOOST_ASIO_VERSION_HPP diff --git a/3rdParty/Boost/src/boost/asio/windows/basic_handle.hpp b/3rdParty/Boost/src/boost/asio/windows/basic_handle.hpp index 7bbdb0d..58bb54d 100644 --- a/3rdParty/Boost/src/boost/asio/windows/basic_handle.hpp +++ b/3rdParty/Boost/src/boost/asio/windows/basic_handle.hpp @@ -1,6 +1,6 @@ // -// basic_handle.hpp -// ~~~~~~~~~~~~~~~~ +// windows/basic_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,15 +15,17 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) #include <boost/asio/basic_io_object.hpp> -#include <boost/asio/error.hpp> #include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -224,4 +226,8 @@ protected: #include <boost/asio/detail/pop_options.hpp> +#endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + #endif // BOOST_ASIO_WINDOWS_BASIC_HANDLE_HPP diff --git a/3rdParty/Boost/src/boost/asio/windows/basic_random_access_handle.hpp b/3rdParty/Boost/src/boost/asio/windows/basic_random_access_handle.hpp index 06239df..5c403d0 100644 --- a/3rdParty/Boost/src/boost/asio/windows/basic_random_access_handle.hpp +++ b/3rdParty/Boost/src/boost/asio/windows/basic_random_access_handle.hpp @@ -1,6 +1,6 @@ // -// basic_random_access_handle.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// windows/basic_random_access_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,20 +15,18 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) +#include <cstddef> +#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> #include <boost/asio/windows/basic_handle.hpp> #include <boost/asio/windows/random_access_handle_service.hpp> -#include <boost/asio/detail/throw_error.hpp> -#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ - || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -314,9 +312,9 @@ public: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP diff --git a/3rdParty/Boost/src/boost/asio/windows/basic_stream_handle.hpp b/3rdParty/Boost/src/boost/asio/windows/basic_stream_handle.hpp index 329cc6f..340e402 100644 --- a/3rdParty/Boost/src/boost/asio/windows/basic_stream_handle.hpp +++ b/3rdParty/Boost/src/boost/asio/windows/basic_stream_handle.hpp @@ -1,6 +1,6 @@ // -// basic_stream_handle.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~ +// windows/basic_stream_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,20 +15,18 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) +#include <cstddef> #include <boost/asio/error.hpp> #include <boost/asio/windows/basic_handle.hpp> #include <boost/asio/windows/stream_handle_service.hpp> #include <boost/asio/detail/throw_error.hpp> -#if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \ - || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -296,9 +294,9 @@ public: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP diff --git a/3rdParty/Boost/src/boost/asio/windows/overlapped_ptr.hpp b/3rdParty/Boost/src/boost/asio/windows/overlapped_ptr.hpp index 5880272..24a199f 100644 --- a/3rdParty/Boost/src/boost/asio/windows/overlapped_ptr.hpp +++ b/3rdParty/Boost/src/boost/asio/windows/overlapped_ptr.hpp @@ -1,6 +1,6 @@ // -// overlapped_ptr.hpp -// ~~~~~~~~~~~~~~~~~~ +// windows/overlapped_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,20 +15,16 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR) \ + || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/io_service.hpp> #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/win_iocp_overlapped_ptr.hpp> +#include <boost/asio/io_service.hpp> -#if !defined(BOOST_ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR) -# if defined(BOOST_ASIO_HAS_IOCP) -# define BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1 -# endif // defined(BOOST_ASIO_HAS_IOCP) -#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR) - -#if defined(BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR) \ - || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -112,9 +108,9 @@ private: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_WINDOWS_OVERLAPPED_PTR_HPP diff --git a/3rdParty/Boost/src/boost/asio/windows/random_access_handle.hpp b/3rdParty/Boost/src/boost/asio/windows/random_access_handle.hpp index 7707aac..03d7055 100644 --- a/3rdParty/Boost/src/boost/asio/windows/random_access_handle.hpp +++ b/3rdParty/Boost/src/boost/asio/windows/random_access_handle.hpp @@ -1,6 +1,6 @@ // -// random_access_handle.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~ +// windows/random_access_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,13 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/windows/basic_random_access_handle.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/windows/basic_random_access_handle.hpp> + namespace boost { namespace asio { namespace windows { @@ -36,6 +36,4 @@ typedef basic_random_access_handle<> random_access_handle; #endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP diff --git a/3rdParty/Boost/src/boost/asio/windows/random_access_handle_service.hpp b/3rdParty/Boost/src/boost/asio/windows/random_access_handle_service.hpp index 1dcbee4..e5a2e11 100644 --- a/3rdParty/Boost/src/boost/asio/windows/random_access_handle_service.hpp +++ b/3rdParty/Boost/src/boost/asio/windows/random_access_handle_service.hpp @@ -1,6 +1,6 @@ // -// random_access_handle_service.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// windows/random_access_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,27 +15,19 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/push_options.hpp> #include <cstddef> #include <boost/config.hpp> #include <boost/cstdint.hpp> -#include <boost/asio/detail/pop_options.hpp> - +#include <boost/asio/detail/win_iocp_handle_service.hpp> #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> -#include <boost/asio/detail/service_base.hpp> -#include <boost/asio/detail/win_iocp_handle_service.hpp> -#if !defined(BOOST_ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE) -# if defined(BOOST_ASIO_HAS_IOCP) -# define BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE 1 -# endif // defined(BOOST_ASIO_HAS_IOCP) -#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE) - -#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ - || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -174,9 +166,9 @@ private: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/windows/stream_handle.hpp b/3rdParty/Boost/src/boost/asio/windows/stream_handle.hpp index 8e9e467..ca2a56c 100644 --- a/3rdParty/Boost/src/boost/asio/windows/stream_handle.hpp +++ b/3rdParty/Boost/src/boost/asio/windows/stream_handle.hpp @@ -1,6 +1,6 @@ // -// stream_handle.hpp -// ~~~~~~~~~~~~~~~~~~ +// windows/stream_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,13 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/windows/basic_stream_handle.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \ || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/windows/basic_stream_handle.hpp> + namespace boost { namespace asio { namespace windows { @@ -36,6 +36,4 @@ typedef basic_stream_handle<> stream_handle; #endif // defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_WINDOWS_STREAM_HANDLE_HPP diff --git a/3rdParty/Boost/src/boost/asio/windows/stream_handle_service.hpp b/3rdParty/Boost/src/boost/asio/windows/stream_handle_service.hpp index cc6c6e8..e534646 100644 --- a/3rdParty/Boost/src/boost/asio/windows/stream_handle_service.hpp +++ b/3rdParty/Boost/src/boost/asio/windows/stream_handle_service.hpp @@ -1,6 +1,6 @@ // -// stream_handle_service.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// windows/stream_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,26 +15,17 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) +#include <cstddef> +#include <boost/asio/detail/win_iocp_handle_service.hpp> #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> -#include <boost/asio/detail/service_base.hpp> -#include <boost/asio/detail/win_iocp_handle_service.hpp> -#if !defined(BOOST_ASIO_DISABLE_WINDOWS_STREAM_HANDLE) -# if defined(BOOST_ASIO_HAS_IOCP) -# define BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE 1 -# endif // defined(BOOST_ASIO_HAS_IOCP) -#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_STREAM_HANDLE) - -#if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \ - || defined(GENERATING_DOCUMENTATION) +#include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { @@ -172,9 +163,9 @@ private: } // namespace asio } // namespace boost +#include <boost/asio/detail/pop_options.hpp> + #endif // defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) // || defined(GENERATING_DOCUMENTATION) -#include <boost/asio/detail/pop_options.hpp> - #endif // BOOST_ASIO_WINDOWS_STREAM_HANDLE_SERVICE_HPP diff --git a/3rdParty/Boost/src/boost/asio/write.hpp b/3rdParty/Boost/src/boost/asio/write.hpp index 2a95735..0ec0879 100644 --- a/3rdParty/Boost/src/boost/asio/write.hpp +++ b/3rdParty/Boost/src/boost/asio/write.hpp @@ -15,16 +15,13 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/basic_streambuf.hpp> +#include <boost/asio/basic_streambuf_fwd.hpp> #include <boost/asio/error.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { @@ -535,8 +532,8 @@ void async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b, } // namespace asio } // namespace boost -#include <boost/asio/impl/write.ipp> - #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/impl/write.hpp> + #endif // BOOST_ASIO_WRITE_HPP diff --git a/3rdParty/Boost/src/boost/asio/write_at.hpp b/3rdParty/Boost/src/boost/asio/write_at.hpp index 74f080a..a078a70 100644 --- a/3rdParty/Boost/src/boost/asio/write_at.hpp +++ b/3rdParty/Boost/src/boost/asio/write_at.hpp @@ -15,17 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> +#include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/config.hpp> #include <boost/cstdint.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#include <boost/asio/basic_streambuf.hpp> +#include <boost/asio/basic_streambuf_fwd.hpp> #include <boost/asio/error.hpp> +#include <boost/asio/detail/push_options.hpp> + namespace boost { namespace asio { @@ -558,8 +555,8 @@ void async_write_at(AsyncRandomAccessWriteDevice& d, boost::uint64_t offset, } // namespace asio } // namespace boost -#include <boost/asio/impl/write_at.ipp> - #include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/impl/write_at.hpp> + #endif // BOOST_ASIO_WRITE_AT_HPP diff --git a/3rdParty/Boost/src/boost/bind/placeholders.hpp b/3rdParty/Boost/src/boost/bind/placeholders.hpp index 37d01db..3b098b1 100644 --- a/3rdParty/Boost/src/boost/bind/placeholders.hpp +++ b/3rdParty/Boost/src/boost/bind/placeholders.hpp @@ -25,7 +25,7 @@ namespace { -#if defined(__BORLANDC__) || defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 400) +#if defined(__BORLANDC__) || defined(__GNUC__) && (__GNUC__ < 4) static inline boost::arg<1> _1() { return boost::arg<1>(); } static inline boost::arg<2> _2() { return boost::arg<2>(); } @@ -38,7 +38,7 @@ static inline boost::arg<8> _8() { return boost::arg<8>(); } static inline boost::arg<9> _9() { return boost::arg<9>(); } #elif defined(BOOST_MSVC) || (defined(__DECCXX_VER) && __DECCXX_VER <= 60590031) || defined(__MWERKS__) || \ - defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ == 400) + defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ < 2) static boost::arg<1> _1; static boost::arg<2> _2; diff --git a/3rdParty/Boost/src/boost/concept/detail/backward_compatibility.hpp b/3rdParty/Boost/src/boost/concept/detail/backward_compatibility.hpp new file mode 100644 index 0000000..88d5921 --- /dev/null +++ b/3rdParty/Boost/src/boost/concept/detail/backward_compatibility.hpp @@ -0,0 +1,16 @@ +// Copyright David Abrahams 2009. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP +# define BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP + +namespace boost +{ + namespace concepts {} + +# if !defined(BOOST_NO_CONCEPTS) && !defined(BOOST_CONCEPT_NO_BACKWARD_KEYWORD) + namespace concept = concepts; +# endif +} // namespace boost::concept + +#endif // BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP diff --git a/3rdParty/Boost/src/boost/concept/detail/borland.hpp b/3rdParty/Boost/src/boost/concept/detail/borland.hpp index 59fec55..300d5d4 100644 --- a/3rdParty/Boost/src/boost/concept/detail/borland.hpp +++ b/3rdParty/Boost/src/boost/concept/detail/borland.hpp @@ -5,8 +5,9 @@ # define BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP # include <boost/preprocessor/cat.hpp> +# include <boost/concept/detail/backward_compatibility.hpp> -namespace boost { namespace concept { +namespace boost { namespace concepts { template <class ModelFnPtr> struct require; @@ -21,7 +22,7 @@ struct require<void(*)(Model)> enum \ { \ BOOST_PP_CAT(boost_concept_check,__LINE__) = \ - boost::concept::require<ModelFnPtr>::instantiate \ + boost::concepts::require<ModelFnPtr>::instantiate \ } }} // namespace boost::concept diff --git a/3rdParty/Boost/src/boost/concept/detail/general.hpp b/3rdParty/Boost/src/boost/concept/detail/general.hpp index f36f9c4..e3014c1 100644 --- a/3rdParty/Boost/src/boost/concept/detail/general.hpp +++ b/3rdParty/Boost/src/boost/concept/detail/general.hpp @@ -5,6 +5,7 @@ # define BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP # include <boost/preprocessor/cat.hpp> +# include <boost/concept/detail/backward_compatibility.hpp> # ifdef BOOST_OLD_CONCEPT_SUPPORT # include <boost/concept/detail/has_constraints.hpp> @@ -13,7 +14,7 @@ // This implementation works on Comeau and GCC, all the way back to // 2.95 -namespace boost { namespace concept { +namespace boost { namespace concepts { template <class ModelFn> struct requirement_; @@ -29,6 +30,14 @@ struct requirement static void failed() { ((Model*)0)->~Model(); } }; +struct failed {}; + +template <class Model> +struct requirement<failed ************ Model::************> +{ + static void failed() { ((Model*)0)->~Model(); } +}; + # ifdef BOOST_OLD_CONCEPT_SUPPORT template <class Model> @@ -40,9 +49,9 @@ struct constraint template <class Model> struct requirement_<void(*)(Model)> : mpl::if_< - concept::not_satisfied<Model> + concepts::not_satisfied<Model> , constraint<Model> - , requirement<Model> + , requirement<failed ************ Model::************> >::type {}; @@ -51,14 +60,14 @@ struct requirement_<void(*)(Model)> // For GCC-2.x, these can't have exactly the same name template <class Model> struct requirement_<void(*)(Model)> - : requirement<Model> + : requirement<failed ************ Model::************> {}; # endif # define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ - typedef ::boost::concept::detail::instantiate< \ - &::boost::concept::requirement_<ModelFnPtr>::failed> \ + typedef ::boost::concepts::detail::instantiate< \ + &::boost::concepts::requirement_<ModelFnPtr>::failed> \ BOOST_PP_CAT(boost_concept_check,__LINE__) }} diff --git a/3rdParty/Boost/src/boost/concept/detail/has_constraints.hpp b/3rdParty/Boost/src/boost/concept/detail/has_constraints.hpp index 9191181..a309db3 100644 --- a/3rdParty/Boost/src/boost/concept/detail/has_constraints.hpp +++ b/3rdParty/Boost/src/boost/concept/detail/has_constraints.hpp @@ -6,7 +6,9 @@ # include <boost/mpl/bool.hpp> # include <boost/detail/workaround.hpp> -namespace boost { namespace concept { +# include <boost/concept/detail/backward_compatibility.hpp> + +namespace boost { namespace concepts { namespace detail { @@ -43,6 +45,6 @@ struct not_satisfied typedef mpl::bool_<value> type; }; -}} // namespace boost::concept::detail +}} // namespace boost::concepts::detail #endif // BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP diff --git a/3rdParty/Boost/src/boost/concept/detail/msvc.hpp b/3rdParty/Boost/src/boost/concept/detail/msvc.hpp index 3aadb79..9fbd250 100644 --- a/3rdParty/Boost/src/boost/concept/detail/msvc.hpp +++ b/3rdParty/Boost/src/boost/concept/detail/msvc.hpp @@ -5,6 +5,7 @@ # define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP # include <boost/preprocessor/cat.hpp> +# include <boost/concept/detail/backward_compatibility.hpp> # ifdef BOOST_OLD_CONCEPT_SUPPORT # include <boost/concept/detail/has_constraints.hpp> @@ -12,7 +13,8 @@ # endif -namespace boost { namespace concept { +namespace boost { namespace concepts { + template <class Model> struct check @@ -22,7 +24,19 @@ struct check x->~Model(); } }; - + +# ifndef BOOST_NO_PARTIAL_SPECIALIZATION +struct failed {}; +template <class Model> +struct check<failed ************ Model::************> +{ + virtual void failed(Model* x) + { + x->~Model(); + } +}; +# endif + # ifdef BOOST_OLD_CONCEPT_SUPPORT namespace detail @@ -38,7 +52,11 @@ struct require : mpl::if_c< not_satisfied<Model>::value , detail::constraint +# ifndef BOOST_NO_PARTIAL_SPECIALIZATION , check<Model> +# else + , check<failed ************ Model::************> +# endif >::type {}; @@ -46,7 +64,11 @@ struct require template <class Model> struct require - : check<Model> +# ifndef BOOST_NO_PARTIAL_SPECIALIZATION + : check<Model> +# else + : check<failed ************ Model::************> +# endif {}; # endif @@ -70,7 +92,7 @@ struct require<void(*)(Model)> enum \ { \ BOOST_PP_CAT(boost_concept_check,__LINE__) = \ - sizeof(::boost::concept::require<ModelFnPtr>) \ + sizeof(::boost::concepts::require<ModelFnPtr>) \ } # else // Not vc-7.1 @@ -83,7 +105,7 @@ require_(void(*)(Model)); enum \ { \ BOOST_PP_CAT(boost_concept_check,__LINE__) = \ - sizeof(::boost::concept::require_((ModelFnPtr)0)) \ + sizeof(::boost::concepts::require_((ModelFnPtr)0)) \ } # endif diff --git a/3rdParty/Boost/src/boost/concept/usage.hpp b/3rdParty/Boost/src/boost/concept/usage.hpp index 9af8ca3..21547c3 100644 --- a/3rdParty/Boost/src/boost/concept/usage.hpp +++ b/3rdParty/Boost/src/boost/concept/usage.hpp @@ -6,8 +6,9 @@ # include <boost/concept/assert.hpp> # include <boost/detail/workaround.hpp> +# include <boost/concept/detail/backward_compatibility.hpp> -namespace boost { namespace concept { +namespace boost { namespace concepts { # if BOOST_WORKAROUND(__GNUC__, == 2) @@ -25,19 +26,19 @@ struct usage_requirements # define BOOST_CONCEPT_USAGE(model) \ model(); /* at least 2.96 and 3.4.3 both need this :( */ \ - BOOST_CONCEPT_ASSERT((boost::concept::usage_requirements<model>)); \ + BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements<model>)); \ ~model() # else # define BOOST_CONCEPT_USAGE(model) \ - BOOST_CONCEPT_ASSERT((boost::concept::usage_requirements<model>)); \ + BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements<model>)); \ ~model() # endif # endif -}} // namespace boost::concept +}} // namespace boost::concepts #endif // BOOST_CONCEPT_USAGE_DWA2006919_HPP diff --git a/3rdParty/Boost/src/boost/concept_check.hpp b/3rdParty/Boost/src/boost/concept_check.hpp index 7ee3036..58bd8b2 100644 --- a/3rdParty/Boost/src/boost/concept_check.hpp +++ b/3rdParty/Boost/src/boost/concept_check.hpp @@ -1,5 +1,7 @@ // // (C) Copyright Jeremy Siek 2000. +// Copyright 2002 The Trustees of Indiana University. +// // 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) @@ -999,6 +1001,42 @@ namespace boost // HashedAssociativeContainer + BOOST_concept(Collection,(C)) + { + BOOST_CONCEPT_USAGE(Collection) + { + boost::function_requires<boost::InputIteratorConcept<iterator> >(); + boost::function_requires<boost::InputIteratorConcept<const_iterator> >(); + boost::function_requires<boost::CopyConstructibleConcept<value_type> >(); + const_constraints(c); + i = c.begin(); + i = c.end(); + c.swap(c); + } + + void const_constraints(const C& c) { + ci = c.begin(); + ci = c.end(); + n = c.size(); + b = c.empty(); + } + + private: + typedef typename C::value_type value_type; + typedef typename C::iterator iterator; + typedef typename C::const_iterator const_iterator; + typedef typename C::reference reference; + typedef typename C::const_reference const_reference; + // typedef typename C::pointer pointer; + typedef typename C::difference_type difference_type; + typedef typename C::size_type size_type; + + C c; + bool b; + iterator i; + const_iterator ci; + size_type n; + }; } // namespace boost # include <boost/concept/detail/concept_undef.hpp> diff --git a/3rdParty/Boost/src/boost/config/abi/borland_prefix.hpp b/3rdParty/Boost/src/boost/config/abi/borland_prefix.hpp index 49f4249..3a0e5ae 100644 --- a/3rdParty/Boost/src/boost/config/abi/borland_prefix.hpp +++ b/3rdParty/Boost/src/boost/config/abi/borland_prefix.hpp @@ -21,7 +21,7 @@ // 8026 - functions taking class by value arguments are not expanded inline #pragma nopushoptwarn -# pragma option push -Vx -Ve -a8 -b -pc -Vmv -VC- -Vl- -w-8027 -w-8026 +# pragma option push -a8 -Vx- -Ve- -b- -pc -Vmv -VC- -Vl- -w-8027 -w-8026 diff --git a/3rdParty/Boost/src/boost/config/auto_link.hpp b/3rdParty/Boost/src/boost/config/auto_link.hpp index f2eb583..e562caf 100644 --- a/3rdParty/Boost/src/boost/config/auto_link.hpp +++ b/3rdParty/Boost/src/boost/config/auto_link.hpp @@ -25,6 +25,9 @@ BOOST_LIB_DIAGNOSTIC: Optional: when set the header will print out the name of the library selected (useful for debugging). BOOST_AUTO_LINK_NOMANGLE: Specifies that we should link to BOOST_LIB_NAME.lib, rather than a mangled-name version. +BOOST_AUTO_LINK_TAGGED: Specifies that we link to libraries built with the --layout=tagged option. + This is essentially the same as the default name-mangled version, but without + the compiler name and version, or the Boost version. Just the build options. These macros will be undef'ed at the end of the header, further this header has no include guards - so be sure to include it only once from your library! @@ -60,6 +63,8 @@ BOOST_LIB_RT_OPT: A suffix that indicates the runtime library used, a hiphen: s static runtime (dynamic if not present). + g debug/diagnostic runtime (release if not present). + y Python debug/diagnostic runtime (release if not present). d debug build (release if not present). g debug/diagnostic runtime (release if not present). p STLPort Build. @@ -183,8 +188,16 @@ BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. # if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) -# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydp" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) # define BOOST_LIB_RT_OPT "-gdp" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydp" +# pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" # elif defined(_DEBUG) # define BOOST_LIB_RT_OPT "-gdp" # pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") @@ -195,8 +208,16 @@ BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. # elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydpn" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) # define BOOST_LIB_RT_OPT "-gdpn" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydpn" +# pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" # elif defined(_DEBUG) # define BOOST_LIB_RT_OPT "-gdpn" # pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") @@ -207,7 +228,9 @@ BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. # else -# if defined(_DEBUG) +# if defined(_DEBUG) && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gyd" +# elif defined(_DEBUG) # define BOOST_LIB_RT_OPT "-gd" # else # define BOOST_LIB_RT_OPT @@ -219,8 +242,16 @@ BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. # if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) -# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydp" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) # define BOOST_LIB_RT_OPT "-sgdp" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydp" +# pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" # elif defined(_DEBUG) # define BOOST_LIB_RT_OPT "-sgdp" # pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") @@ -231,8 +262,16 @@ BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. # elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydpn" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) # define BOOST_LIB_RT_OPT "-sgdpn" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydpn" +# pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" # elif defined(_DEBUG) # define BOOST_LIB_RT_OPT "-sgdpn" # pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") @@ -243,7 +282,10 @@ BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. # else -# if defined(_DEBUG) +# if defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgyd" +# elif defined(_DEBUG) # define BOOST_LIB_RT_OPT "-sgd" # else # define BOOST_LIB_RT_OPT "-s" @@ -270,16 +312,26 @@ BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. # ifdef _RTLDLL -# ifdef BOOST_BORLAND_DEBUG +# if defined(BOOST_BORLAND_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-yd" +# elif defined(BOOST_BORLAND_DEBUG) # define BOOST_LIB_RT_OPT "-d" +# elif defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT -y # else # define BOOST_LIB_RT_OPT # endif # else -# ifdef BOOST_BORLAND_DEBUG +# if defined(BOOST_BORLAND_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-syd" +# elif defined(BOOST_BORLAND_DEBUG) # define BOOST_LIB_RT_OPT "-sd" +# elif defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sy" # else # define BOOST_LIB_RT_OPT "-s" # endif @@ -309,16 +361,21 @@ BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. && defined(BOOST_LIB_RT_OPT) \ && defined(BOOST_LIB_VERSION) -#ifndef BOOST_AUTO_LINK_NOMANGLE -# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib") +#ifdef BOOST_AUTO_LINK_TAGGED +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT ".lib") # ifdef BOOST_LIB_DIAGNOSTIC # pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib") # endif -#else +#elif defined(BOOST_AUTO_LINK_NOMANGLE) # pragma comment(lib, BOOST_STRINGIZE(BOOST_LIB_NAME) ".lib") # ifdef BOOST_LIB_DIAGNOSTIC # pragma message ("Linking to lib file: " BOOST_STRINGIZE(BOOST_LIB_NAME) ".lib") # endif +#else +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib") +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib") +# endif #endif #else @@ -361,13 +418,3 @@ BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. # undef BOOST_AUTO_LINK_NOMANGLE #endif - - - - - - - - - - diff --git a/3rdParty/Boost/src/boost/config/compiler/borland.hpp b/3rdParty/Boost/src/boost/config/compiler/borland.hpp index 6a7b988..a989fd6 100644 --- a/3rdParty/Boost/src/boost/config/compiler/borland.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/borland.hpp @@ -46,6 +46,8 @@ // Borland C++Builder 5, command-line compiler 5.5: # define BOOST_NO_OPERATORS_IN_NAMESPACE # endif +// Variadic macros do not exist for C++ Builder versions 5 and below +#define BOOST_NO_VARIADIC_MACROS # endif // Version 5.51 and below: @@ -218,7 +220,7 @@ // // check for exception handling support: // -#if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) +#if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif // @@ -230,8 +232,9 @@ // // all versions support __declspec: // -#ifndef __STRICT_ANSI__ -# define BOOST_HAS_DECLSPEC +#if defined(__STRICT_ANSI__) +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT #endif // // ABI fixing headers: @@ -261,6 +264,13 @@ # define BOOST_NO_VOID_RETURNS #endif +// Borland did not implement value-initialization completely, as I reported +// in 2007, Borland Report 51854, "Value-initialization: POD struct should be +// zero-initialized", http://qc.embarcadero.com/wc/qcmain.aspx?d=51854 +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +// (Niels Dekker, LKEB, April 2010) +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION + #define BOOST_COMPILER "Borland C++ version " BOOST_STRINGIZE(__BORLANDC__) diff --git a/3rdParty/Boost/src/boost/config/compiler/clang.hpp b/3rdParty/Boost/src/boost/config/compiler/clang.hpp new file mode 100644 index 0000000..2ce6773 --- /dev/null +++ b/3rdParty/Boost/src/boost/config/compiler/clang.hpp @@ -0,0 +1,63 @@ +// (C) Copyright Douglas Gregor 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 for most recent version. + +// Clang compiler setup. + +#if __has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS) +#else +# define BOOST_NO_EXCEPTIONS +#endif + +#if __has_feature(cxx_rtti) +#else +# define BOOST_NO_RTTI +#endif + +#if defined(__int64) +# define BOOST_HAS_MS_INT64 +#endif + +#define BOOST_HAS_NRVO + +// NOTE: Clang's C++0x support is not worth detecting. However, it +// supports both extern templates and "long long" even in C++98/03 +// mode. +#define BOOST_NO_AUTO_DECLARATIONS +#define BOOST_NO_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CHAR16_T +#define BOOST_NO_CHAR32_T +#define BOOST_NO_CONCEPTS +#define BOOST_NO_CONSTEXPR +#define BOOST_NO_DECLTYPE +#define BOOST_NO_DEFAULTED_FUNCTIONS +#define BOOST_NO_DELETED_FUNCTIONS +#define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_INITIALIZER_LISTS +#define BOOST_NO_LAMBDAS +#define BOOST_NO_NULLPTR +#define BOOST_NO_RAW_LITERALS +#define BOOST_NO_RVALUE_REFERENCES +#define BOOST_NO_SCOPED_ENUMS +#define BOOST_NO_STATIC_ASSERT +#define BOOST_NO_TEMPLATE_ALIASES +#define BOOST_NO_UNICODE_LITERALS +#define BOOST_NO_VARIADIC_TEMPLATES +#define BOOST_NO_VARIADIC_MACROS + +// HACK: Clang does support extern templates, but Boost's test for +// them is wrong. +#define BOOST_NO_EXTERN_TEMPLATE + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "Clang version " __clang_version__ +#endif + +// Macro used to identify the Clang compiler. +#define BOOST_CLANG 1 + diff --git a/3rdParty/Boost/src/boost/config/compiler/codegear.hpp b/3rdParty/Boost/src/boost/config/compiler/codegear.hpp index 698624e..f6dc4c0 100644 --- a/3rdParty/Boost/src/boost/config/compiler/codegear.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/codegear.hpp @@ -19,8 +19,8 @@ #endif // // versions check: -// last known and checked version is 0x620 -#if (__CODEGEARC__ > 0x620) +// last known and checked version is 0x621 +#if (__CODEGEARC__ > 0x621) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # else @@ -41,7 +41,7 @@ #endif // CodeGear C++ Builder 2010 -#if (__CODEGEARC__ <= 0x620) +#if (__CODEGEARC__ <= 0x621) # define BOOST_NO_TYPENAME_WITH_CTOR // Cannot use typename keyword when making temporaries of a dependant type # define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL # define BOOST_NO_MEMBER_TEMPLATE_FRIENDS @@ -51,6 +51,15 @@ // Temporary hack, until specific MPL preprocessed headers are generated # define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +// CodeGear has not yet completely implemented value-initialization, for +// example for array types, as I reported in 2010: Embarcadero Report 83751, +// "Value-initialization: arrays should have each element value-initialized", +// http://qc.embarcadero.com/wc/qcmain.aspx?d=83751 +// Last checked version: Embarcadero C++ 6.21 +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +// (Niels Dekker, LKEB, April 2010) +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION + # ifdef NDEBUG // fix broken <cstring> so that Boost.test works: # include <cstring> @@ -66,6 +75,11 @@ // // C++0x macros: // +#if (__CODEGEARC__ <= 0x620) +#define BOOST_NO_STATIC_ASSERT +#else +#define BOOST_HAS_STATIC_ASSERT +#endif #define BOOST_HAS_CHAR16_T #define BOOST_HAS_CHAR32_T #define BOOST_HAS_LONG_LONG @@ -91,7 +105,6 @@ #define BOOST_NO_RAW_LITERALS #define BOOST_NO_RVALUE_REFERENCES #define BOOST_NO_SFINAE_EXPR -#define BOOST_NO_STATIC_ASSERT #define BOOST_NO_TEMPLATE_ALIASES #define BOOST_NO_UNICODE_LITERALS #define BOOST_NO_VARIADIC_TEMPLATES @@ -122,7 +135,7 @@ // // check for exception handling support: // -#if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) +#if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif // @@ -134,8 +147,9 @@ // // all versions support __declspec: // -#if !defined(__STRICT_ANSI__) -# define BOOST_HAS_DECLSPEC +#if defined(__STRICT_ANSI__) +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT #endif // // ABI fixing headers: diff --git a/3rdParty/Boost/src/boost/config/compiler/common_edg.hpp b/3rdParty/Boost/src/boost/config/compiler/common_edg.hpp index 9dc4cef..682c73a 100644 --- a/3rdParty/Boost/src/boost/config/compiler/common_edg.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/common_edg.hpp @@ -44,7 +44,7 @@ #endif // See also kai.hpp which checks a Kai-specific symbol for EH -# if !defined(__KCC) && !defined(__EXCEPTIONS) +# if !defined(__KCC) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS # endif @@ -59,6 +59,9 @@ // // See above for BOOST_NO_LONG_LONG // +#if (__EDG_VERSION__ < 310) +# define BOOST_NO_EXTERN_TEMPLATE +#endif #if (__EDG_VERSION__ <= 310) || !defined(BOOST_STRICT_CONFIG) // No support for initializer lists # define BOOST_NO_INITIALIZER_LISTS @@ -74,7 +77,6 @@ #define BOOST_NO_DEFAULTED_FUNCTIONS #define BOOST_NO_DELETED_FUNCTIONS #define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS -#define BOOST_NO_EXTERN_TEMPLATE #define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS #define BOOST_NO_LAMBDAS #define BOOST_NO_NULLPTR @@ -86,12 +88,10 @@ #define BOOST_NO_TEMPLATE_ALIASES #define BOOST_NO_UNICODE_LITERALS #define BOOST_NO_VARIADIC_TEMPLATES +#define BOOST_NO_VARIADIC_MACROS #ifdef c_plusplus // EDG has "long long" in non-strict mode // However, some libraries have insufficient "long long" support // #define BOOST_HAS_LONG_LONG #endif - - - diff --git a/3rdParty/Boost/src/boost/config/compiler/digitalmars.hpp b/3rdParty/Boost/src/boost/config/compiler/digitalmars.hpp index a01b4c2..31c11bf 100644 --- a/3rdParty/Boost/src/boost/config/compiler/digitalmars.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/digitalmars.hpp @@ -51,7 +51,7 @@ // check for exception handling support: -#ifndef _CPPUNWIND +#if !defined(_CPPUNWIND) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif @@ -80,6 +80,9 @@ #define BOOST_NO_TEMPLATE_ALIASES #define BOOST_NO_UNICODE_LITERALS #define BOOST_NO_VARIADIC_TEMPLATES +#if (__DMC__ < 0x812) +#define BOOST_NO_VARIADIC_MACROS +#endif #if __DMC__ < 0x800 #error "Compiler not supported or configured - please reconfigure" diff --git a/3rdParty/Boost/src/boost/config/compiler/gcc.hpp b/3rdParty/Boost/src/boost/config/compiler/gcc.hpp index fe2c52e..eeaf998 100644 --- a/3rdParty/Boost/src/boost/config/compiler/gcc.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/gcc.hpp @@ -42,6 +42,9 @@ # define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE # define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL # define BOOST_NO_IS_ABSTRACT +# define BOOST_NO_EXTERN_TEMPLATE +// Variadic macros do not exist for gcc versions before 3.0 +# define BOOST_NO_VARIADIC_MACROS #elif __GNUC__ == 3 # if defined (__PATHSCALE__) # define BOOST_NO_TWO_PHASE_NAME_LOOKUP @@ -58,6 +61,7 @@ # if __GNUC_MINOR__ < 4 # define BOOST_NO_IS_ABSTRACT # endif +# define BOOST_NO_EXTERN_TEMPLATE #endif #if __GNUC__ < 4 // @@ -69,7 +73,19 @@ # endif #endif -#ifndef __EXCEPTIONS +#if __GNUC__ < 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 ) +// Previous versions of GCC did not completely implement value-initialization: +// 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 (fixed for GCC 4.4) +// GCC Bug 33916, "Default constructor fails to initialize array members", +// reported by Michael Elizabeth Chastain in 2007, +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 (fixed for GCC 4.2.4) +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#endif + +#if !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif @@ -94,20 +110,45 @@ #if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 1 ) #define BOOST_HAS_NRVO #endif + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if __GNUC__ >= 4 +# if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(__CYGWIN__) + // All Win32 development environments, including 64-bit Windows and MinGW, define + // _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment, + // so does not define _WIN32 or its variants. +# define BOOST_HAS_DECLSPEC +# define BOOST_SYMBOL_EXPORT __attribute__((dllexport)) +# define BOOST_SYMBOL_IMPORT __attribute__((dllimport)) +# else +# define BOOST_SYMBOL_EXPORT __attribute__((visibility("default"))) +# define BOOST_SYMBOL_IMPORT +# endif +# define BOOST_SYMBOL_VISIBLE __attribute__((visibility("default"))) +#else +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT +#endif + // // RTTI and typeinfo detection is possible post gcc-4.3: // #if __GNUC__ * 100 + __GNUC_MINOR__ >= 403 # ifndef __GXX_RTTI -# define BOOST_NO_TYPEID -# define BOOST_NO_RTTI +# ifndef BOOST_NO_TYPEID +# define BOOST_NO_TYPEID +# endif +# ifndef BOOST_NO_RTTI +# define BOOST_NO_RTTI +# endif # endif #endif // C++0x features not implemented in any GCC version // #define BOOST_NO_CONSTEXPR -#define BOOST_NO_EXTERN_TEMPLATE #define BOOST_NO_NULLPTR #define BOOST_NO_TEMPLATE_ALIASES diff --git a/3rdParty/Boost/src/boost/config/compiler/gcc_xml.hpp b/3rdParty/Boost/src/boost/config/compiler/gcc_xml.hpp index 5dd67c7..a456463 100644 --- a/3rdParty/Boost/src/boost/config/compiler/gcc_xml.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/gcc_xml.hpp @@ -25,6 +25,32 @@ // #define BOOST_HAS_LONG_LONG +// C++0x features: +// +# define BOOST_NO_CONSTEXPR +# define BOOST_NO_NULLPTR +# define BOOST_NO_TEMPLATE_ALIASES +# define BOOST_NO_DECLTYPE +# define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_RVALUE_REFERENCES +# define BOOST_NO_STATIC_ASSERT +# define BOOST_NO_VARIADIC_TEMPLATES +# define BOOST_NO_VARIADIC_MACROS +# define BOOST_NO_AUTO_DECLARATIONS +# define BOOST_NO_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CHAR16_T +# define BOOST_NO_CHAR32_T +# define BOOST_NO_DEFAULTED_FUNCTIONS +# define BOOST_NO_DELETED_FUNCTIONS +# define BOOST_NO_INITIALIZER_LISTS +# define BOOST_NO_SCOPED_ENUMS +# define BOOST_NO_SFINAE_EXPR +# define BOOST_NO_SCOPED_ENUMS +# define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_LAMBDAS +# define BOOST_NO_RAW_LITERALS +# define BOOST_NO_UNICODE_LITERALS + #define BOOST_COMPILER "GCC-XML C++ version " __GCCXML__ diff --git a/3rdParty/Boost/src/boost/config/compiler/hp_acc.hpp b/3rdParty/Boost/src/boost/config/compiler/hp_acc.hpp index 98e7772..d0b672e 100644 --- a/3rdParty/Boost/src/boost/config/compiler/hp_acc.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/hp_acc.hpp @@ -115,6 +115,16 @@ #define BOOST_NO_TEMPLATE_ALIASES #define BOOST_NO_UNICODE_LITERALS #define BOOST_NO_VARIADIC_TEMPLATES + +/* + See https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443331 and + https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443436 +*/ + +#if (__HP_aCC < 62500) || !defined(HP_CXX0x_SOURCE) + #define BOOST_NO_VARIADIC_MACROS +#endif + #endif // diff --git a/3rdParty/Boost/src/boost/config/compiler/intel.hpp b/3rdParty/Boost/src/boost/config/compiler/intel.hpp index 531242e..e7bc95b 100644 --- a/3rdParty/Boost/src/boost/config/compiler/intel.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/intel.hpp @@ -158,6 +158,29 @@ template<> struct assert_intrinsic_wchar_t<unsigned short> {}; #endif // +// An attempt to value-initialize a pointer-to-member may trigger an +// internal error on Intel <= 11.1 (last checked version), as was +// reported by John Maddock, Intel support issue 589832, May 2010. +// Moreover, according to test results from Huang-Vista-x86_32_intel, +// intel-vc9-win-11.1 may leave a non-POD array uninitialized, in some +// cases when it should be value-initialized. +// (Niels Dekker, LKEB, May 2010) +#if defined(__INTEL_COMPILER) +# if __INTEL_COMPILER <= 1110 +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +# endif +#endif + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +# define BOOST_SYMBOL_EXPORT __attribute__((visibility("default"))) +# define BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_VISIBLE __attribute__((visibility("default"))) +#endif + +// // last known and checked version: #if (BOOST_INTEL_CXX_VERSION > 1110) # if defined(BOOST_ASSERT_CONFIG) diff --git a/3rdParty/Boost/src/boost/config/compiler/kai.hpp b/3rdParty/Boost/src/boost/config/compiler/kai.hpp index ea06f9f..2337e6a 100644 --- a/3rdParty/Boost/src/boost/config/compiler/kai.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/kai.hpp @@ -17,7 +17,7 @@ # endif // see also common_edg.hpp which needs a special check for __KCC -# if !defined(_EXCEPTIONS) +# if !defined(_EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS # endif diff --git a/3rdParty/Boost/src/boost/config/compiler/metrowerks.hpp b/3rdParty/Boost/src/boost/config/compiler/metrowerks.hpp index aeba7f8..21083b7 100644 --- a/3rdParty/Boost/src/boost/config/compiler/metrowerks.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/metrowerks.hpp @@ -48,7 +48,7 @@ # define BOOST_NO_INTRINSIC_WCHAR_T #endif -#if !__option(exceptions) +#if !__option(exceptions) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif @@ -114,6 +114,7 @@ #define BOOST_NO_TEMPLATE_ALIASES #define BOOST_NO_UNICODE_LITERALS #define BOOST_NO_VARIADIC_TEMPLATES +#define BOOST_NO_VARIADIC_MACROS #define BOOST_COMPILER "Metrowerks CodeWarrior C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) diff --git a/3rdParty/Boost/src/boost/config/compiler/mpw.hpp b/3rdParty/Boost/src/boost/config/compiler/mpw.hpp index 4db14dd..ae12f80 100644 --- a/3rdParty/Boost/src/boost/config/compiler/mpw.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/mpw.hpp @@ -63,6 +63,7 @@ #define BOOST_NO_TEMPLATE_ALIASES #define BOOST_NO_UNICODE_LITERALS #define BOOST_NO_VARIADIC_TEMPLATES +#define BOOST_NO_VARIADIC_MACROS // // versions check: diff --git a/3rdParty/Boost/src/boost/config/compiler/nvcc.hpp b/3rdParty/Boost/src/boost/config/compiler/nvcc.hpp index 7d831af..eaecf37 100644 --- a/3rdParty/Boost/src/boost/config/compiler/nvcc.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/nvcc.hpp @@ -37,6 +37,7 @@ #define BOOST_HAS_DIRENT_H #define BOOST_HAS_CLOCK_GETTIME #define BOOST_NO_VARIADIC_TEMPLATES +#define BOOST_NO_VARIADIC_MACROS #define BOOST_NO_UNICODE_LITERALS #define BOOST_NO_TEMPLATE_ALIASES #define BOOST_NO_STD_UNORDERED @@ -66,6 +67,7 @@ #define BOOST_NO_0X_HDR_TYPE_TRAITS #define BOOST_NO_0X_HDR_TUPLE #define BOOST_NO_0X_HDR_THREAD +#define BOOST_NO_0X_HDR_TYPEINDEX #define BOOST_NO_0X_HDR_SYSTEM_ERROR #define BOOST_NO_0X_HDR_REGEX #define BOOST_NO_0X_HDR_RATIO diff --git a/3rdParty/Boost/src/boost/config/compiler/pgi.hpp b/3rdParty/Boost/src/boost/config/compiler/pgi.hpp index 1c7c84b..fb3a6c0 100644 --- a/3rdParty/Boost/src/boost/config/compiler/pgi.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/pgi.hpp @@ -70,6 +70,7 @@ #define BOOST_NO_TEMPLATE_ALIASES #define BOOST_NO_UNICODE_LITERALS #define BOOST_NO_VARIADIC_TEMPLATES +#define BOOST_NO_VARIADIC_MACROS // // version check: diff --git a/3rdParty/Boost/src/boost/config/compiler/sunpro_cc.hpp b/3rdParty/Boost/src/boost/config/compiler/sunpro_cc.hpp index f518488..85fa462 100644 --- a/3rdParty/Boost/src/boost/config/compiler/sunpro_cc.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/sunpro_cc.hpp @@ -69,6 +69,25 @@ # define BOOST_NO_IS_ABSTRACT # endif +# if (__SUNPRO_CC <= 0x5100) + // Sun 5.10 may not correctly value-initialize objects of + // some user defined types, as was reported in April 2010 + // (CR 6947016), and confirmed by Steve Clamage. + // (Niels Dekker, LKEB, May 2010). +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +# endif + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if __SUNPRO_CC > 0x500 +# define BOOST_SYMBOL_EXPORT __global +# define BOOST_SYMBOL_IMPORT __global +# define BOOST_SYMBOL_VISIBLE __global +#endif + + + // // Issues that effect all known versions: // @@ -78,12 +97,7 @@ // // C++0x features // - -#if(__SUNPRO_CC >= 0x590) # define BOOST_HAS_LONG_LONG -#else -# define BOOST_NO_LONG_LONG -#endif #define BOOST_NO_AUTO_DECLARATIONS #define BOOST_NO_AUTO_MULTIDECLARATIONS @@ -108,6 +122,7 @@ #define BOOST_NO_TEMPLATE_ALIASES #define BOOST_NO_UNICODE_LITERALS #define BOOST_NO_VARIADIC_TEMPLATES +#define BOOST_NO_VARIADIC_MACROS // // Version diff --git a/3rdParty/Boost/src/boost/config/compiler/vacpp.hpp b/3rdParty/Boost/src/boost/config/compiler/vacpp.hpp index 01956d3..5ae9c28 100644 --- a/3rdParty/Boost/src/boost/config/compiler/vacpp.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/vacpp.hpp @@ -30,6 +30,14 @@ # define BOOST_NO_INITIALIZER_LISTS #endif +#if (__IBMCPP__ <= 1110) +// XL C++ V11.1 and earlier versions may not always value-initialize +// a temporary object T(), when T is a non-POD aggregate class type. +// Michael Wong (IBM Canada Ltd) has confirmed this issue and gave it +// high priority. -- Niels Dekker (LKEB), May 2010. +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#endif + // // On AIX thread support seems to be indicated by _THREAD_SAFE: // @@ -83,6 +91,7 @@ #define BOOST_NO_TEMPLATE_ALIASES #define BOOST_NO_UNICODE_LITERALS #define BOOST_NO_VARIADIC_TEMPLATES +#define BOOST_NO_VARIADIC_MACROS diff --git a/3rdParty/Boost/src/boost/config/compiler/visualc.hpp b/3rdParty/Boost/src/boost/config/compiler/visualc.hpp index f8cc109..6755287 100644 --- a/3rdParty/Boost/src/boost/config/compiler/visualc.hpp +++ b/3rdParty/Boost/src/boost/config/compiler/visualc.hpp @@ -79,6 +79,10 @@ // although a conforming signature for swprint exists in VC7.1 // it appears not to actually work: # define BOOST_NO_SWPRINTF +// Our extern template tests also fail for this compiler: +# define BOOST_NO_EXTERN_TEMPLATE +// Variadic macros do not exist for VC7.1 and lower +# define BOOST_NO_VARIADIC_MACROS #endif #if defined(UNDER_CE) @@ -99,6 +103,24 @@ # define BOOST_NO_ADL_BARRIER #endif + +#if (_MSC_VER <= 1600) +// MSVC (including the latest checked version) has not yet completely +// implemented value-initialization, as is reported: +// "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 +// "Presence of copy constructor breaks member class initialization", +// reported in 2009 by Alex Vakulenko: +// https://connect.microsoft.com/VisualStudio/feedback/details/499606 +// "Value-initialization in new-expression", reported in 2005 by +// Pavel Kuznetsov (MetaCommunications Engineering): +// https://connect.microsoft.com/VisualStudio/feedback/details/100744 +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +// (Niels Dekker, LKEB, May 2010) +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#endif + #if _MSC_VER <= 1500 || !defined(BOOST_STRICT_CONFIG) // 1500 == VC++ 9.0 # define BOOST_NO_INITIALIZER_LISTS #endif @@ -115,7 +137,7 @@ // // check for exception handling support: -#ifndef _CPPUNWIND +#if !defined(_CPPUNWIND) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif @@ -145,11 +167,6 @@ #endif // -// all versions support __declspec: -// -#define BOOST_HAS_DECLSPEC - -// // C++0x features // // See above for BOOST_NO_LONG_LONG @@ -159,11 +176,14 @@ #if _MSC_VER < 1600 #define BOOST_NO_AUTO_DECLARATIONS #define BOOST_NO_AUTO_MULTIDECLARATIONS -#define BOOST_NO_DECLTYPE #define BOOST_NO_LAMBDAS #define BOOST_NO_RVALUE_REFERENCES #define BOOST_NO_STATIC_ASSERT +#define BOOST_NO_NULLPTR #endif // _MSC_VER < 1600 +#if _MSC_VER >= 1600 +#define BOOST_HAS_STDINT_H +#endif // C++0x features not supported by any versions #define BOOST_NO_CHAR16_T @@ -171,19 +191,17 @@ #define BOOST_NO_CONCEPTS #define BOOST_NO_CONSTEXPR #define BOOST_NO_DEFAULTED_FUNCTIONS +#define BOOST_NO_DECLTYPE #define BOOST_NO_DELETED_FUNCTIONS #define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS -#define BOOST_NO_EXTERN_TEMPLATE #define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS #define BOOST_NO_INITIALIZER_LISTS -#define BOOST_NO_NULLPTR #define BOOST_NO_RAW_LITERALS #define BOOST_NO_SCOPED_ENUMS #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_TEMPLATE_ALIASES #define BOOST_NO_UNICODE_LITERALS #define BOOST_NO_VARIADIC_TEMPLATES - // // prefix and suffix headers: // diff --git a/3rdParty/Boost/src/boost/config/platform/bsd.hpp b/3rdParty/Boost/src/boost/config/platform/bsd.hpp index f02b0e2..a014297 100644 --- a/3rdParty/Boost/src/boost/config/platform/bsd.hpp +++ b/3rdParty/Boost/src/boost/config/platform/bsd.hpp @@ -56,7 +56,7 @@ #endif #if !((defined(__FreeBSD__) && (__FreeBSD__ >= 5)) \ - || (__NetBSD_GCC__ >= 2095003) || defined(__DragonFly__)) + || (defined(__NetBSD_GCC__) && (__NetBSD_GCC__ >= 2095003)) || defined(__DragonFly__)) # define BOOST_NO_CWCHAR #endif // diff --git a/3rdParty/Boost/src/boost/config/platform/cygwin.hpp b/3rdParty/Boost/src/boost/config/platform/cygwin.hpp index 41fcaa1..8e1bcb0 100644 --- a/3rdParty/Boost/src/boost/config/platform/cygwin.hpp +++ b/3rdParty/Boost/src/boost/config/platform/cygwin.hpp @@ -8,9 +8,6 @@ // cygwin specific config options: #define BOOST_PLATFORM "Cygwin" -#define BOOST_NO_CWCTYPE -#define BOOST_NO_CWCHAR -#define BOOST_NO_SWPRINTF #define BOOST_HAS_DIRENT_H #define BOOST_HAS_LOG1P #define BOOST_HAS_EXPM1 @@ -44,6 +41,13 @@ // boilerplate code: #include <boost/config/posix_features.hpp> + +// +// Cygwin lies about XSI conformance, there is no nl_types.h: +// +#ifdef BOOST_HAS_NL_TYPES_H +# undef BOOST_HAS_NL_TYPES_H +#endif diff --git a/3rdParty/Boost/src/boost/config/platform/vms.hpp b/3rdParty/Boost/src/boost/config/platform/vms.hpp new file mode 100644 index 0000000..f70efcf --- /dev/null +++ b/3rdParty/Boost/src/boost/config/platform/vms.hpp @@ -0,0 +1,25 @@ +// (C) Copyright Artyom Beilis 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) + +#ifndef BOOST_CONFIG_PLATFORM_VMS_HPP +#define BOOST_CONFIG_PLATFORM_VMS_HPP + +#define BOOST_PLATFORM "OpenVMS" + +#undef BOOST_HAS_STDINT_H +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_NL_TYPES_H +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#define BOOST_HAS_LOG1P +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_THREADS +#undef BOOST_HAS_SCHED_YIELD + +#endif diff --git a/3rdParty/Boost/src/boost/config/platform/win32.hpp b/3rdParty/Boost/src/boost/config/platform/win32.hpp index 9344818..f59c4ea 100644 --- a/3rdParty/Boost/src/boost/config/platform/win32.hpp +++ b/3rdParty/Boost/src/boost/config/platform/win32.hpp @@ -21,10 +21,17 @@ # define BOOST_NO_SWPRINTF #endif -#if !defined(__GNUC__) && !defined(BOOST_HAS_DECLSPEC) +// Default defines for BOOST_SYMBOL_EXPORT and BOOST_SYMBOL_IMPORT +// If a compiler doesn't support __declspec(dllexport)/__declspec(dllimport), +// its boost/config/compiler/ file must define BOOST_SYMBOL_EXPORT and +// BOOST_SYMBOL_IMPORT +#ifndef BOOST_SYMBOL_EXPORT # define BOOST_HAS_DECLSPEC +# define BOOST_SYMBOL_EXPORT __declspec(dllexport) +# define BOOST_SYMBOL_IMPORT __declspec(dllimport) #endif + #if defined(__MINGW32__) && ((__MINGW32_MAJOR_VERSION > 2) || ((__MINGW32_MAJOR_VERSION == 2) && (__MINGW32_MINOR_VERSION >= 0))) # define BOOST_HAS_STDINT_H # define __STDC_LIMIT_MACROS diff --git a/3rdParty/Boost/src/boost/config/select_compiler_config.hpp b/3rdParty/Boost/src/boost/config/select_compiler_config.hpp index 792963e..f9b086a 100644 --- a/3rdParty/Boost/src/boost/config/select_compiler_config.hpp +++ b/3rdParty/Boost/src/boost/config/select_compiler_config.hpp @@ -15,6 +15,7 @@ // compilers we support: # define BOOST_CXX_GCCXML 0 +# define BOOST_CXX_CLANG 0 # define BOOST_CXX_COMO 0 # define BOOST_CXX_DMC 0 # define BOOST_CXX_INTEL 0 @@ -49,6 +50,10 @@ // Comeau C++ # define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp" +#elif defined __clang__ +// Clang C++ emulates GCC, so it has to appear early. +# define BOOST_COMPILER_CONFIG "boost/config/compiler/clang.hpp" + #elif defined __DMC__ // Digital Mars C++ # define BOOST_COMPILER_CONFIG "boost/config/compiler/digitalmars.hpp" diff --git a/3rdParty/Boost/src/boost/config/select_platform_config.hpp b/3rdParty/Boost/src/boost/config/select_platform_config.hpp index 8606e12..bc1ffaf 100644 --- a/3rdParty/Boost/src/boost/config/select_platform_config.hpp +++ b/3rdParty/Boost/src/boost/config/select_platform_config.hpp @@ -69,6 +69,9 @@ // Symbian: # define BOOST_PLATFORM_CONFIG "boost/config/platform/symbian.hpp" +#elif defined(__VMS) +// VMS: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/vms.hpp" #else # if defined(unix) \ diff --git a/3rdParty/Boost/src/boost/config/stdlib/dinkumware.hpp b/3rdParty/Boost/src/boost/config/stdlib/dinkumware.hpp index ab77059..e33fef1 100644 --- a/3rdParty/Boost/src/boost/config/stdlib/dinkumware.hpp +++ b/3rdParty/Boost/src/boost/config/stdlib/dinkumware.hpp @@ -86,6 +86,11 @@ # define BOOST_NO_STD_LOCALE #endif +#include <typeinfo> +#if !_HAS_EXCEPTIONS +# define BOOST_NO_STD_TYPEINFO +#endif + // C++0x headers implemented in 520 (as shipped by Microsoft) // #if !defined(_CPPLIB_VER) || _CPPLIB_VER < 520 @@ -100,6 +105,12 @@ # define BOOST_NO_STD_UNORDERED // deprecated; see following # define BOOST_NO_0X_HDR_UNORDERED_MAP # define BOOST_NO_0X_HDR_UNORDERED_SET +# define BOOST_NO_0X_HDR_TUPLE +# define BOOST_NO_0X_HDR_TYPEINDEX +#endif + +#if !defined(_HAS_TR1_IMPORTS) && !defined(BOOST_NO_0X_HDR_TUPLE) +# define BOOST_NO_0X_HDR_TUPLE #endif // C++0x headers not yet implemented @@ -114,7 +125,7 @@ # define BOOST_NO_0X_HDR_MUTEX # define BOOST_NO_0X_HDR_RATIO # define BOOST_NO_0X_HDR_THREAD -# define BOOST_NO_0X_HDR_TUPLE +# define BOOST_NO_NUMERIC_LIMITS_LOWEST #ifdef _CPPLIB_VER # define BOOST_DINKUMWARE_STDLIB _CPPLIB_VER diff --git a/3rdParty/Boost/src/boost/config/stdlib/libcomo.hpp b/3rdParty/Boost/src/boost/config/stdlib/libcomo.hpp index 06731e3..16a842a 100644 --- a/3rdParty/Boost/src/boost/config/stdlib/libcomo.hpp +++ b/3rdParty/Boost/src/boost/config/stdlib/libcomo.hpp @@ -54,9 +54,11 @@ # define BOOST_NO_0X_HDR_THREAD # define BOOST_NO_0X_HDR_TUPLE # define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_0X_HDR_TYPEINDEX # define BOOST_NO_STD_UNORDERED // deprecated; see following # define BOOST_NO_0X_HDR_UNORDERED_MAP # define BOOST_NO_0X_HDR_UNORDERED_SET +# define BOOST_NO_NUMERIC_LIMITS_LOWEST // // Intrinsic type_traits support. diff --git a/3rdParty/Boost/src/boost/config/stdlib/libstdcpp3.hpp b/3rdParty/Boost/src/boost/config/stdlib/libstdcpp3.hpp index 6a57319..01dd490 100644 --- a/3rdParty/Boost/src/boost/config/stdlib/libstdcpp3.hpp +++ b/3rdParty/Boost/src/boost/config/stdlib/libstdcpp3.hpp @@ -115,6 +115,12 @@ # define BOOST_NO_0X_HDR_THREAD #endif +// C++0x features in GCC 4.5.0 and later +// +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_NO_NUMERIC_LIMITS_LOWEST +#endif + // C++0x headers not yet implemented // # define BOOST_NO_0X_HDR_CODECVT @@ -123,5 +129,6 @@ # define BOOST_NO_0X_HDR_FUTURE # define BOOST_NO_0X_HDR_ITERATOR_CONCEPTS # define BOOST_NO_0X_HDR_MEMORY_CONCEPTS +# define BOOST_NO_0X_HDR_TYPEINDEX // --- end --- diff --git a/3rdParty/Boost/src/boost/config/stdlib/modena.hpp b/3rdParty/Boost/src/boost/config/stdlib/modena.hpp index 7bd50ce..147060d 100644 --- a/3rdParty/Boost/src/boost/config/stdlib/modena.hpp +++ b/3rdParty/Boost/src/boost/config/stdlib/modena.hpp @@ -43,9 +43,11 @@ # define BOOST_NO_0X_HDR_THREAD # define BOOST_NO_0X_HDR_TUPLE # define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_0X_HDR_TYPEINDEX # define BOOST_NO_STD_UNORDERED // deprecated; see following # define BOOST_NO_0X_HDR_UNORDERED_MAP # define BOOST_NO_0X_HDR_UNORDERED_SET +# define BOOST_NO_NUMERIC_LIMITS_LOWEST #define BOOST_STDLIB "Modena C++ standard library" diff --git a/3rdParty/Boost/src/boost/config/stdlib/msl.hpp b/3rdParty/Boost/src/boost/config/stdlib/msl.hpp index 6bcd232..8185e35 100644 --- a/3rdParty/Boost/src/boost/config/stdlib/msl.hpp +++ b/3rdParty/Boost/src/boost/config/stdlib/msl.hpp @@ -67,9 +67,11 @@ # define BOOST_NO_0X_HDR_THREAD # define BOOST_NO_0X_HDR_TUPLE # define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_0X_HDR_TYPEINDEX # define BOOST_NO_STD_UNORDERED // deprecated; see following # define BOOST_NO_0X_HDR_UNORDERED_MAP # define BOOST_NO_0X_HDR_UNORDERED_SET +# define BOOST_NO_NUMERIC_LIMITS_LOWEST #define BOOST_STDLIB "Metrowerks Standard Library version " BOOST_STRINGIZE(__MSL_CPP__) diff --git a/3rdParty/Boost/src/boost/config/stdlib/roguewave.hpp b/3rdParty/Boost/src/boost/config/stdlib/roguewave.hpp index cba2f54..dcd0af8 100644 --- a/3rdParty/Boost/src/boost/config/stdlib/roguewave.hpp +++ b/3rdParty/Boost/src/boost/config/stdlib/roguewave.hpp @@ -173,7 +173,9 @@ # define BOOST_NO_0X_HDR_THREAD # define BOOST_NO_0X_HDR_TUPLE # define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_0X_HDR_TYPEINDEX # define BOOST_NO_STD_UNORDERED // deprecated; see following # define BOOST_NO_0X_HDR_UNORDERED_MAP # define BOOST_NO_0X_HDR_UNORDERED_SET +# define BOOST_NO_NUMERIC_LIMITS_LOWEST diff --git a/3rdParty/Boost/src/boost/config/stdlib/sgi.hpp b/3rdParty/Boost/src/boost/config/stdlib/sgi.hpp index c505008..4d42647 100644 --- a/3rdParty/Boost/src/boost/config/stdlib/sgi.hpp +++ b/3rdParty/Boost/src/boost/config/stdlib/sgi.hpp @@ -126,9 +126,11 @@ # define BOOST_NO_0X_HDR_THREAD # define BOOST_NO_0X_HDR_TUPLE # define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_0X_HDR_TYPEINDEX # define BOOST_NO_STD_UNORDERED // deprecated; see following # define BOOST_NO_0X_HDR_UNORDERED_MAP # define BOOST_NO_0X_HDR_UNORDERED_SET +# define BOOST_NO_NUMERIC_LIMITS_LOWEST #define BOOST_STDLIB "SGI standard library" diff --git a/3rdParty/Boost/src/boost/config/stdlib/stlport.hpp b/3rdParty/Boost/src/boost/config/stdlib/stlport.hpp index 3dfd529..0e1c9b2 100644 --- a/3rdParty/Boost/src/boost/config/stdlib/stlport.hpp +++ b/3rdParty/Boost/src/boost/config/stdlib/stlport.hpp @@ -221,9 +221,11 @@ namespace boost { using std::min; using std::max; } # define BOOST_NO_0X_HDR_THREAD # define BOOST_NO_0X_HDR_TUPLE # define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_0X_HDR_TYPEINDEX # define BOOST_NO_STD_UNORDERED // deprecated; see following # define BOOST_NO_0X_HDR_UNORDERED_MAP # define BOOST_NO_0X_HDR_UNORDERED_SET +# define BOOST_NO_NUMERIC_LIMITS_LOWEST #define BOOST_STDLIB "STLPort standard library version " BOOST_STRINGIZE(__SGI_STL_PORT) diff --git a/3rdParty/Boost/src/boost/config/stdlib/vacpp.hpp b/3rdParty/Boost/src/boost/config/stdlib/vacpp.hpp index c8d6d5a..0fc092f 100644 --- a/3rdParty/Boost/src/boost/config/stdlib/vacpp.hpp +++ b/3rdParty/Boost/src/boost/config/stdlib/vacpp.hpp @@ -33,9 +33,11 @@ # define BOOST_NO_0X_HDR_THREAD # define BOOST_NO_0X_HDR_TUPLE # define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_0X_HDR_TYPEINDEX # define BOOST_NO_STD_UNORDERED // deprecated; see following # define BOOST_NO_0X_HDR_UNORDERED_MAP # define BOOST_NO_0X_HDR_UNORDERED_SET +# define BOOST_NO_NUMERIC_LIMITS_LOWEST #define BOOST_STDLIB "Visual Age default standard library" diff --git a/3rdParty/Boost/src/boost/config/suffix.hpp b/3rdParty/Boost/src/boost/config/suffix.hpp index 9e4d078..722758f 100644 --- a/3rdParty/Boost/src/boost/config/suffix.hpp +++ b/3rdParty/Boost/src/boost/config/suffix.hpp @@ -25,6 +25,27 @@ #ifndef BOOST_CONFIG_SUFFIX_HPP #define BOOST_CONFIG_SUFFIX_HPP +#if defined(__GNUC__) && (__GNUC__ >= 4) +// +// Some GCC-4.x versions issue warnings even when __extension__ is used, +// so use this as a workaround: +// +#pragma GCC system_header +#endif + +// +// ensure that visibility macros are always defined, thus symplifying use +// +#ifndef BOOST_SYMBOL_EXPORT +# define BOOST_SYMBOL_EXPORT +#endif +#ifndef BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_IMPORT +#endif +#ifndef BOOST_SYMBOL_VISIBLE +# define BOOST_SYMBOL_VISIBLE +#endif + // // look for long long by looking for the appropriate macros in <limits.h>. // Note that we use limits.h rather than climits for maximal portability, @@ -83,6 +104,13 @@ #endif // +// Normalize BOOST_NO_STATIC_ASSERT and (depricated) BOOST_HAS_STATIC_ASSERT: +// +#if !defined(BOOST_NO_STATIC_ASSERT) && !defined(BOOST_HAS_STATIC_ASSERT) +# define BOOST_HAS_STATIC_ASSERT +#endif + +// // if there is no __int64 then there is no specialisation // for numeric_limits<__int64> either: // @@ -314,6 +342,13 @@ # define BOOST_NO_INITIALIZER_LISTS #endif +// +// Set BOOST_HAS_RVALUE_REFS when BOOST_NO_RVALUE_REFERENCES is not defined +// +#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_HAS_RVALUE_REFS) +#define BOOST_HAS_RVALUE_REFS +#endif + // BOOST_HAS_ABI_HEADERS // This macro gets set if we have headers that fix the ABI, // and prevent ODR violations when linking to external libraries: @@ -554,6 +589,12 @@ namespace boost{ #endif // defined BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +// When BOOST_NO_STD_TYPEINFO is defined, we can just import +// the global definition into std namespace: +#ifdef BOOST_NO_STD_TYPEINFO +#include <typeinfo> +namespace std{ using ::typeinfo; } +#endif // ---------------------------------------------------------------------------// diff --git a/3rdParty/Boost/src/boost/cstdint.hpp b/3rdParty/Boost/src/boost/cstdint.hpp index 47e6a16..ea84b65 100644 --- a/3rdParty/Boost/src/boost/cstdint.hpp +++ b/3rdParty/Boost/src/boost/cstdint.hpp @@ -137,7 +137,7 @@ namespace boost } // namespace boost -#elif defined(__FreeBSD__) && (__FreeBSD__ <= 4) || defined(__osf__) +#elif defined(__FreeBSD__) && (__FreeBSD__ <= 4) || defined(__osf__) || defined(__VMS) // FreeBSD and Tru64 have an <inttypes.h> that contains much of what we need. # include <inttypes.h> @@ -256,20 +256,27 @@ namespace boost // 32-bit types -----------------------------------------------------------// -# if ULONG_MAX == 0xffffffff - typedef long int32_t; - typedef long int_least32_t; - typedef long int_fast32_t; - typedef unsigned long uint32_t; - typedef unsigned long uint_least32_t; - typedef unsigned long uint_fast32_t; -# elif UINT_MAX == 0xffffffff +# if UINT_MAX == 0xffffffff typedef int int32_t; typedef int int_least32_t; typedef int int_fast32_t; typedef unsigned int uint32_t; typedef unsigned int uint_least32_t; typedef unsigned int uint_fast32_t; +# elif (USHRT_MAX == 0xffffffff) + typedef short int32_t; + typedef short int_least32_t; + typedef short int_fast32_t; + typedef unsigned short uint32_t; + typedef unsigned short uint_least32_t; + typedef unsigned short uint_fast32_t; +# elif ULONG_MAX == 0xffffffff + typedef long int32_t; + typedef long int_least32_t; + typedef long int_fast32_t; + typedef unsigned long uint32_t; + typedef unsigned long uint_least32_t; + typedef unsigned long uint_fast32_t; # elif (UINT_MAX == 0xffffffffffffffff) && defined(__MTA__) // Integers are 64 bits on the MTA / XMT typedef __int32 int32_t; @@ -366,58 +373,87 @@ INT#_C macros if they're not already defined (John Maddock). ******************************************************/ -#if !defined(BOOST__STDC_CONSTANT_MACROS_DEFINED) && !defined(INT8_C) +#if !defined(BOOST__STDC_CONSTANT_MACROS_DEFINED) && \ + (!defined(INT8_C) || !defined(INT16_C) || !defined(INT32_C) || !defined(INT64_C)) +// +// For the following code we get several warnings along the lines of: +// +// boost/cstdint.hpp:428:35: error: use of C99 long long integer constant +// +// So we declare this a system header to suppress these warnings. +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +#pragma GCC system_header +#endif + #include <limits.h> # define BOOST__STDC_CONSTANT_MACROS_DEFINED # if defined(BOOST_HAS_MS_INT64) // // Borland/Intel/Microsoft compilers have width specific suffixes: // +#ifndef INT8_C # define INT8_C(value) value##i8 +#endif +#ifndef INT16_C # define INT16_C(value) value##i16 +#endif +#ifndef INT32_C # define INT32_C(value) value##i32 +#endif +#ifndef INT64_C # define INT64_C(value) value##i64 +#endif # ifdef __BORLANDC__ // Borland bug: appending ui8 makes the type a signed char # define UINT8_C(value) static_cast<unsigned char>(value##u) # else # define UINT8_C(value) value##ui8 # endif +#ifndef UINT16_C # define UINT16_C(value) value##ui16 +#endif +#ifndef UINT32_C # define UINT32_C(value) value##ui32 +#endif +#ifndef UINT64_C # define UINT64_C(value) value##ui64 +#endif +#ifndef INTMAX_C # define INTMAX_C(value) value##i64 # define UINTMAX_C(value) value##ui64 +#endif # else // do it the old fashioned way: // 8-bit types ------------------------------------------------------------// -# if UCHAR_MAX == 0xff +# if (UCHAR_MAX == 0xff) && !defined(INT8_C) # define INT8_C(value) static_cast<boost::int8_t>(value) # define UINT8_C(value) static_cast<boost::uint8_t>(value##u) # endif // 16-bit types -----------------------------------------------------------// -# if USHRT_MAX == 0xffff +# if (USHRT_MAX == 0xffff) && !defined(INT16_C) # define INT16_C(value) static_cast<boost::int16_t>(value) # define UINT16_C(value) static_cast<boost::uint16_t>(value##u) # endif // 32-bit types -----------------------------------------------------------// - -# if UINT_MAX == 0xffffffff +#ifndef INT32_C +# if (UINT_MAX == 0xffffffff) # define INT32_C(value) value # define UINT32_C(value) value##u # elif ULONG_MAX == 0xffffffff # define INT32_C(value) value##L # define UINT32_C(value) value##uL # endif +#endif // 64-bit types + intmax_t and uintmax_t ----------------------------------// - +#ifndef INT64_C # if defined(BOOST_HAS_LONG_LONG) && \ (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX) || defined(_LLONG_MAX)) @@ -462,7 +498,7 @@ INT#_C macros if they're not already defined (John Maddock). # define INTMAX_C(value) INT64_C(value) # define UINTMAX_C(value) UINT64_C(value) # endif - +#endif # endif // Borland/Microsoft specific width suffixes #endif // INT#_C macros. diff --git a/3rdParty/Boost/src/boost/date_time/gregorian/conversion.hpp b/3rdParty/Boost/src/boost/date_time/gregorian/conversion.hpp index 6d4b606..c505bdd 100644 --- a/3rdParty/Boost/src/boost/date_time/gregorian/conversion.hpp +++ b/3rdParty/Boost/src/boost/date_time/gregorian/conversion.hpp @@ -6,16 +6,16 @@ * Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland, Bart Garst - * $Date: 2009-06-06 07:27:35 -0400 (Sat, 06 Jun 2009) $ + * $Date: 2010-06-09 14:10:13 -0400 (Wed, 09 Jun 2010) $ */ +#include <cstring> #include <string> #include <stdexcept> #include <boost/throw_exception.hpp> #include <boost/date_time/c_time.hpp> #include <boost/date_time/special_defs.hpp> #include <boost/date_time/gregorian/gregorian_types.hpp> -#include <cstring> namespace boost { @@ -43,7 +43,7 @@ namespace gregorian { } std::tm datetm; - memset(&datetm, 0, sizeof(std::tm)); + std::memset(&datetm, 0, sizeof(datetm)); boost::gregorian::date::ymd_type ymd = d.year_month_day(); datetm.tm_year = ymd.year - 1900; datetm.tm_mon = ymd.month - 1; diff --git a/3rdParty/Boost/src/boost/date_time/microsec_time_clock.hpp b/3rdParty/Boost/src/boost/date_time/microsec_time_clock.hpp index e6f3b8e..9396579 100644 --- a/3rdParty/Boost/src/boost/date_time/microsec_time_clock.hpp +++ b/3rdParty/Boost/src/boost/date_time/microsec_time_clock.hpp @@ -6,7 +6,7 @@ * Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland, Bart Garst - * $Date: 2009-06-04 07:36:43 -0400 (Thu, 04 Jun 2009) $ + * $Date: 2010-05-10 05:15:48 -0400 (Mon, 10 May 2010) $ */ @@ -98,9 +98,9 @@ namespace date_time { std::tm curr; std::tm* curr_ptr = converter(&t, &curr); - date_type d(curr_ptr->tm_year + 1900, - curr_ptr->tm_mon + 1, - curr_ptr->tm_mday); + date_type d(static_cast< typename date_type::year_type::value_type >(curr_ptr->tm_year + 1900), + static_cast< typename date_type::month_type::value_type >(curr_ptr->tm_mon + 1), + static_cast< typename date_type::day_type::value_type >(curr_ptr->tm_mday)); //The following line will adjust the fractional second tick in terms //of the current time system. For example, if the time system @@ -108,9 +108,9 @@ namespace date_time { //and all the fractional seconds return 0. int adjust = static_cast< int >(resolution_traits_type::res_adjust() / 1000000); - time_duration_type td(curr_ptr->tm_hour, - curr_ptr->tm_min, - curr_ptr->tm_sec, + time_duration_type td(static_cast< typename time_duration_type::hour_type >(curr_ptr->tm_hour), + static_cast< typename time_duration_type::min_type >(curr_ptr->tm_min), + static_cast< typename time_duration_type::sec_type >(curr_ptr->tm_sec), sub_sec * adjust); return time_type(d,td); diff --git a/3rdParty/Boost/src/boost/date_time/posix_time/conversion.hpp b/3rdParty/Boost/src/boost/date_time/posix_time/conversion.hpp index a7b1a80..3fb21d7 100644 --- a/3rdParty/Boost/src/boost/date_time/posix_time/conversion.hpp +++ b/3rdParty/Boost/src/boost/date_time/posix_time/conversion.hpp @@ -6,16 +6,16 @@ * Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland, Bart Garst - * $Date: 2010-01-10 14:17:23 -0500 (Sun, 10 Jan 2010) $ + * $Date: 2010-06-09 14:10:13 -0400 (Wed, 09 Jun 2010) $ */ +#include <cstring> #include <boost/date_time/posix_time/ptime.hpp> #include <boost/date_time/posix_time/posix_time_duration.hpp> #include <boost/date_time/filetime_functions.hpp> #include <boost/date_time/c_time.hpp> #include <boost/date_time/time_resolution_traits.hpp> // absolute_value #include <boost/date_time/gregorian/conversion.hpp> -#include <cstring> namespace boost { @@ -45,7 +45,7 @@ namespace posix_time { inline std::tm to_tm(const boost::posix_time::time_duration& td) { std::tm timetm; - memset(&timetm, 0, sizeof(std::tm)); + std::memset(&timetm, 0, sizeof(timetm)); timetm.tm_hour = date_time::absolute_value(td.hours()); timetm.tm_min = date_time::absolute_value(td.minutes()); timetm.tm_sec = date_time::absolute_value(td.seconds()); diff --git a/3rdParty/Boost/src/boost/date_time/time_facet.hpp b/3rdParty/Boost/src/boost/date_time/time_facet.hpp index 3f27f77..a456db9 100644 --- a/3rdParty/Boost/src/boost/date_time/time_facet.hpp +++ b/3rdParty/Boost/src/boost/date_time/time_facet.hpp @@ -7,7 +7,7 @@ * Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Martin Andrian, Jeff Garland, Bart Garst - * $Date: 2010-01-10 14:17:23 -0500 (Sun, 10 Jan 2010) $ + * $Date: 2010-06-09 12:39:31 -0400 (Wed, 09 Jun 2010) $ */ #include <cctype> @@ -21,6 +21,7 @@ #include <boost/assert.hpp> #include <boost/lexical_cast.hpp> #include <boost/throw_exception.hpp> +#include <boost/range/as_literal.hpp> #include <boost/algorithm/string/erase.hpp> #include <boost/algorithm/string/replace.hpp> #include <boost/date_time/compiler_config.hpp> @@ -42,6 +43,10 @@ namespace date_time { static const char_type seconds_format[3]; // S static const char_type hours_format[3]; // H static const char_type unrestricted_hours_format[3]; // O + static const char_type full_24_hour_time_format[3]; // T + static const char_type full_24_hour_time_expanded_format[9]; // HH:MM:SS + static const char_type short_24_hour_time_format[3]; // R + static const char_type short_24_hour_time_expanded_format[6]; // HH:MM static const char_type standard_format[9]; // x X static const char_type zone_abbrev_format[3]; // z static const char_type zone_name_format[3]; // Z @@ -73,8 +78,7 @@ namespace date_time { template <class CharT> const typename time_formats<CharT>::char_type - time_formats<CharT>::seconds_with_fractional_seconds_format[3] = - {'%','s'}; + time_formats<CharT>::seconds_with_fractional_seconds_format[3] = {'%','s'}; template <class CharT> const typename time_formats<CharT>::char_type @@ -90,6 +94,24 @@ namespace date_time { template <class CharT> const typename time_formats<CharT>::char_type + time_formats<CharT>::full_24_hour_time_format[3] = {'%','T'}; + + template <class CharT> + const typename time_formats<CharT>::char_type + time_formats<CharT>::full_24_hour_time_expanded_format[9] = + {'%','H',':','%','M',':','%','S'}; + + template <class CharT> + const typename time_formats<CharT>::char_type + time_formats<CharT>::short_24_hour_time_format[3] = {'%','R'}; + + template <class CharT> + const typename time_formats<CharT>::char_type + time_formats<CharT>::short_24_hour_time_expanded_format[6] = + {'%','H',':','%','M'}; + + template <class CharT> + const typename time_formats<CharT>::char_type //time_formats<CharT>::standard_format[5] = {'%','c',' ','%','z'}; time_formats<CharT>::standard_format[9] = {'%','x',' ','%','X',' ','%','z'}; @@ -180,6 +202,7 @@ namespace date_time { class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > > class time_facet : public boost::date_time::date_facet<typename time_type::date_type , CharT, OutItrT> { + typedef time_formats< CharT > formats_type; public: typedef typename time_type::date_type date_type; typedef typename time_type::time_duration_type time_duration_type; @@ -266,6 +289,14 @@ namespace date_time { } string_type format(this->m_format); + // %T and %R have to be replaced here since they are not standard + boost::algorithm::replace_all(format, + boost::as_literal(formats_type::full_24_hour_time_format), + boost::as_literal(formats_type::full_24_hour_time_expanded_format)); + boost::algorithm::replace_all(format, + boost::as_literal(formats_type::short_24_hour_time_format), + boost::as_literal(formats_type::short_24_hour_time_expanded_format)); + string_type frac_str; if (format.find(seconds_with_fractional_seconds_format) != string_type::npos) { // replace %s with %S.nnn @@ -366,7 +397,7 @@ namespace date_time { } if (format.find(fractional_seconds_format) != string_type::npos) { // replace %f with nnnnnnn - if (!frac_str.size()) { + if (frac_str.empty()) { frac_str = fractional_seconds_as_string(a_time.time_of_day(), false); } boost::algorithm::replace_all(format, @@ -428,6 +459,14 @@ namespace date_time { positive_sign); } + // %T and %R have to be replaced here since they are not standard + boost::algorithm::replace_all(format, + boost::as_literal(formats_type::full_24_hour_time_format), + boost::as_literal(formats_type::full_24_hour_time_expanded_format)); + boost::algorithm::replace_all(format, + boost::as_literal(formats_type::short_24_hour_time_format), + boost::as_literal(formats_type::short_24_hour_time_expanded_format)); + /* * It is possible for a time duration to span more then 24 hours. * Standard time_put::put is obliged to behave the same as strftime diff --git a/3rdParty/Boost/src/boost/detail/endian.hpp b/3rdParty/Boost/src/boost/detail/endian.hpp index 36ddb7e..5f9b90e 100644 --- a/3rdParty/Boost/src/boost/detail/endian.hpp +++ b/3rdParty/Boost/src/boost/detail/endian.hpp @@ -1,5 +1,6 @@ // Copyright 2005 Caleb Epstein // Copyright 2006 John Maddock +// Copyright 2010 Rene Rivera // Distributed under the Boost Software License, Version 1.0. (See accompany- // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -42,10 +43,12 @@ # error Unknown machine endianness detected. # endif # define BOOST_BYTE_ORDER __BYTE_ORDER -#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) +#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) || \ + defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) # define BOOST_BIG_ENDIAN # define BOOST_BYTE_ORDER 4321 -#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) || \ + defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) # define BOOST_LITTLE_ENDIAN # define BOOST_BYTE_ORDER 1234 #elif defined(__sparc) || defined(__sparc__) \ diff --git a/3rdParty/Boost/src/boost/detail/sp_typeinfo.hpp b/3rdParty/Boost/src/boost/detail/sp_typeinfo.hpp index 636fe27..43fae78 100644 --- a/3rdParty/Boost/src/boost/detail/sp_typeinfo.hpp +++ b/3rdParty/Boost/src/boost/detail/sp_typeinfo.hpp @@ -74,7 +74,13 @@ template<class T> struct sp_typeid_ } }; -template<class T> sp_typeinfo sp_typeid_< T >::ti_( sp_typeid_< T >::name() ); +#if defined(__SUNPRO_CC) +// see #4199, the Sun Studio compiler gets confused about static initialization +// constructor arguments. But an assignment works just fine. +template<class T> sp_typeinfo sp_typeid_< T >::ti_ = sp_typeid_< T >::name(); +#else +template<class T> sp_typeinfo sp_typeid_< T >::ti_(sp_typeid_< T >::name()); +#endif template<class T> struct sp_typeid_< T & >: sp_typeid_< T > { diff --git a/3rdParty/Boost/src/boost/detail/workaround.hpp b/3rdParty/Boost/src/boost/detail/workaround.hpp index b6b6412..40b3423 100644 --- a/3rdParty/Boost/src/boost/detail/workaround.hpp +++ b/3rdParty/Boost/src/boost/detail/workaround.hpp @@ -65,6 +65,11 @@ #else #define BOOST_MSVC_WORKAROUND_GUARD 0 #endif +#ifndef BOOST_MSVC_FULL_VER +#define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 1 +#else +#define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 0 +#endif #ifndef __GNUC__ #define __GNUC___WORKAROUND_GUARD 1 #else diff --git a/3rdParty/Boost/src/boost/exception/detail/exception_ptr.hpp b/3rdParty/Boost/src/boost/exception/detail/exception_ptr.hpp index 59686e9..0510fe2 100644 --- a/3rdParty/Boost/src/boost/exception/detail/exception_ptr.hpp +++ b/3rdParty/Boost/src/boost/exception/detail/exception_ptr.hpp @@ -73,12 +73,14 @@ boost exception_ptr get_bad_alloc() { - static exception_ptr e = boost::copy_exception( - bad_alloc_() << - throw_function("boost::current_exception()") << + bad_alloc_ ba; + exception_detail::clone_impl<bad_alloc_> c(ba); + c << + throw_function(BOOST_CURRENT_FUNCTION) << throw_file(__FILE__) << - throw_line(__LINE__) ); - return e; + throw_line(__LINE__); + static exception_ptr ep(new exception_detail::clone_impl<bad_alloc_>(c)); + return ep; } template <int Dummy> diff --git a/3rdParty/Boost/src/boost/exception/exception.hpp b/3rdParty/Boost/src/boost/exception/exception.hpp index fd516dd..adaac68 100644 --- a/3rdParty/Boost/src/boost/exception/exception.hpp +++ b/3rdParty/Boost/src/boost/exception/exception.hpp @@ -75,8 +75,8 @@ boost void release() { - if( px_ ) - px_->release(); + if( px_ && px_->release() ) + px_=0; } }; } @@ -134,7 +134,7 @@ boost class exception; - template <class> + template <class T> class shared_ptr; namespace @@ -150,7 +150,7 @@ boost virtual shared_ptr<error_info_base> get( type_info_ const & ) const = 0; virtual void set( shared_ptr<error_info_base> const &, type_info_ const & ) = 0; virtual void add_ref() const = 0; - virtual void release() const = 0; + virtual bool release() const = 0; virtual refcount_ptr<exception_detail::error_info_container> clone() const = 0; protected: diff --git a/3rdParty/Boost/src/boost/exception/info.hpp b/3rdParty/Boost/src/boost/exception/info.hpp index 7aeeee5..c918dbd 100644 --- a/3rdParty/Boost/src/boost/exception/info.hpp +++ b/3rdParty/Boost/src/boost/exception/info.hpp @@ -114,8 +114,8 @@ boost tmp << header; for( error_info_map::const_iterator i=info_.begin(),end=info_.end(); i!=end; ++i ) { - shared_ptr<error_info_base const> const & x = i->second; - tmp << '[' << x->tag_typeid_name() << "] = " << x->value_as_string() << '\n'; + error_info_base const & x = *i->second; + tmp << '[' << x.tag_typeid_name() << "] = " << x.value_as_string() << '\n'; } tmp.str().swap(diagnostic_info_str_); } @@ -140,11 +140,16 @@ boost ++count_; } - void + bool release() const { - if( !--count_ ) + if( --count_ ) + return false; + else + { delete this; + return true; + } } refcount_ptr<error_info_container> diff --git a/3rdParty/Boost/src/boost/filesystem.hpp b/3rdParty/Boost/src/boost/filesystem.hpp index aa65b21..f8b9353 100644 --- a/3rdParty/Boost/src/boost/filesystem.hpp +++ b/3rdParty/Boost/src/boost/filesystem.hpp @@ -1,20 +1,38 @@ -// boost/filesystem/filesystem.hpp -----------------------------------------// +// boost/filesystem.hpp --------------------------------------------------------------// -// Copyright Beman Dawes 2005 +// Copyright Beman Dawes 2010 -// 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) +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt -// See library home page at http://www.boost.org/libs/filesystem +// Library home page: http://www.boost.org/libs/filesystem -//----------------------------------------------------------------------------// +//--------------------------------------------------------------------------------------// #ifndef BOOST_FILESYSTEM_FILESYSTEM_HPP #define BOOST_FILESYSTEM_FILESYSTEM_HPP -#include <boost/filesystem/operations.hpp> // includes path.hpp -#include <boost/filesystem/convenience.hpp> +# if defined(BOOST_FILESYSTEM_VERSION) \ + && BOOST_FILESYSTEM_VERSION != 2 && BOOST_FILESYSTEM_VERSION != 3 +# error BOOST_FILESYSTEM_VERSION defined, but not as 2 or 3 +# endif -#endif +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 2 +# endif +#if BOOST_FILESYSTEM_VERSION == 2 +# include <boost/filesystem/v2/config.hpp> +# include <boost/filesystem/v2/path.hpp> +# include <boost/filesystem/v2/operations.hpp> +# include <boost/filesystem/v2/convenience.hpp> + +# else +# include <boost/filesystem/v3/config.hpp> +# include <boost/filesystem/v3/path.hpp> +# include <boost/filesystem/v3/operations.hpp> +# include <boost/filesystem/v3/convenience.hpp> + +# endif + +#endif // BOOST_FILESYSTEM_FILESYSTEM_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/config.hpp b/3rdParty/Boost/src/boost/filesystem/config.hpp index 29a0494..9d12bce 100644 --- a/3rdParty/Boost/src/boost/filesystem/config.hpp +++ b/3rdParty/Boost/src/boost/filesystem/config.hpp @@ -1,113 +1,32 @@ -// boost/filesystem/config.hpp ---------------------------------------------// +// boost/filesystem/config.hpp -------------------------------------------------------// -// Copyright Beman Dawes 2003 +// Copyright Beman Dawes 2010 -// 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) +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt -// See library home page at http://www.boost.org/libs/filesystem +// Library home page: http://www.boost.org/libs/filesystem -//----------------------------------------------------------------------------// +//--------------------------------------------------------------------------------------// -#ifndef BOOST_FILESYSTEM_CONFIG_HPP -#define BOOST_FILESYSTEM_CONFIG_HPP +#ifndef BOOST_FILESYSTEM_CONFIGX_HPP +#define BOOST_FILESYSTEM_CONFIGX_HPP -#define BOOST_FILESYSTEM_I18N // aid users wishing to compile several versions - -// ability to change namespace aids path_table.cpp ------------------------// -#ifndef BOOST_FILESYSTEM_NAMESPACE -# define BOOST_FILESYSTEM_NAMESPACE filesystem -#endif - -// This header implements separate compilation features as described in -// http://www.boost.org/more/separate_compilation.html - -#include <boost/config.hpp> -#include <boost/detail/workaround.hpp> - -// determine platform ------------------------------------------------------// - -// BOOST_CYGWIN_PATH implies BOOST_WINDOWS_PATH and BOOST_POSIX_API - -# if defined(BOOST_CYGWIN_PATH) -# if defined(BOOST_POSIX_PATH) -# error BOOST_POSIX_PATH is invalid when BOOST_CYGWIN_PATH is defined -# endif -# if defined(BOOST_WINDOWS_API) -# error BOOST_WINDOWS_API is invalid when BOOST_CYGWIN_PATH is defined -# endif -# define BOOST_WINDOWS_PATH -# define BOOST_POSIX_API +# if defined(BOOST_FILESYSTEM_VERSION) \ + && BOOST_FILESYSTEM_VERSION != 2 && BOOST_FILESYSTEM_VERSION != 3 +# error BOOST_FILESYSTEM_VERSION defined, but not as 2 or 3 # endif -// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use - -# if defined( BOOST_WINDOWS_API ) && defined( BOOST_POSIX_API ) -# error both BOOST_WINDOWS_API and BOOST_POSIX_API are defined -# elif !defined( BOOST_WINDOWS_API ) && !defined( BOOST_POSIX_API ) -# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) -# define BOOST_WINDOWS_API -# else -# define BOOST_POSIX_API -# endif +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 2 # endif -// BOOST_WINDOWS_PATH enables Windows path syntax recognition +#if BOOST_FILESYSTEM_VERSION == 2 +# include <boost/filesystem/v2/config.hpp> -# if !defined(BOOST_POSIX_PATH) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)) -# define BOOST_WINDOWS_PATH -# endif - -// narrow support only for badly broken compilers or libraries -------------// +# else +# include <boost/filesystem/v3/config.hpp> -# if defined(BOOST_NO_STD_WSTRING) || defined(BOOST_NO_SFINAE) || defined(BOOST_NO_STD_LOCALE) || BOOST_WORKAROUND(__BORLANDC__, <0x610) -# define BOOST_FILESYSTEM_NARROW_ONLY # endif -// enable dynamic linking on Windows ---------------------------------------// - -# if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK)) && BOOST_WORKAROUND(__BORLANDC__, <0x610) && defined(__WIN32__) -# error Dynamic linking Boost.Filesystem does not work for Borland; use static linking instead -# endif - -#ifdef BOOST_HAS_DECLSPEC // defined in config system -// we need to import/export our code only if the user has specifically -// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost -// libraries to be dynamically linked, or BOOST_FILESYSTEM_DYN_LINK -// if they want just this one to be dynamically liked: -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) -// export if this is our own source, otherwise import: -#ifdef BOOST_FILESYSTEM_SOURCE -# define BOOST_FILESYSTEM_DECL __declspec(dllexport) -#else -# define BOOST_FILESYSTEM_DECL __declspec(dllimport) -#endif // BOOST_FILESYSTEM_SOURCE -#endif // DYN_LINK -#endif // BOOST_HAS_DECLSPEC -// -// if BOOST_FILESYSTEM_DECL isn't defined yet define it now: -#ifndef BOOST_FILESYSTEM_DECL -#define BOOST_FILESYSTEM_DECL -#endif - -// enable automatic library variant selection ------------------------------// - -#if !defined(BOOST_FILESYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_FILESYSTEM_NO_LIB) -// -// Set the name of our library, this will get undef'ed by auto_link.hpp -// once it's done with it: -// -#define BOOST_LIB_NAME boost_filesystem -// -// If we're importing code from a dll, then tell auto_link.hpp about it: -// -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) -# define BOOST_DYN_LINK -#endif -// -// And include the header that does the work: -// -#include <boost/config/auto_link.hpp> -#endif // auto-linking disabled - -#endif // BOOST_FILESYSTEM_CONFIG_HPP +#endif // BOOST_FILESYSTEM_CONFIGX_HPP diff --git a/3rdParty/Boost/src/libs/filesystem/src/utf8_codecvt_facet.hpp b/3rdParty/Boost/src/boost/filesystem/detail/utf8_codecvt_facet.hpp index 3b78fb1..3b78fb1 100644 --- a/3rdParty/Boost/src/libs/filesystem/src/utf8_codecvt_facet.hpp +++ b/3rdParty/Boost/src/boost/filesystem/detail/utf8_codecvt_facet.hpp diff --git a/3rdParty/Boost/src/boost/filesystem/exception.hpp b/3rdParty/Boost/src/boost/filesystem/exception.hpp index edea663..cced257 100644 --- a/3rdParty/Boost/src/boost/filesystem/exception.hpp +++ b/3rdParty/Boost/src/boost/filesystem/exception.hpp @@ -1,9 +1,32 @@ -// boost/filesystem/exception.hpp -------------------------------------------// +// boost/filesystem/exception.hpp ----------------------------------------------------// -// Copyright Beman Dawes 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) +// Copyright Beman Dawes 2010 -// This header is no long used. The contents have been moved to path.hpp. -// It is provided so that user code #includes do not have to be changed. +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_EXCEPTIONX_HPP +#define BOOST_FILESYSTEM_EXCEPTIONX_HPP + +# if defined(BOOST_FILESYSTEM_VERSION) \ + && BOOST_FILESYSTEM_VERSION != 2 && BOOST_FILESYSTEM_VERSION != 3 +# error BOOST_FILESYSTEM_VERSION defined, but not as 2 or 3 +# endif + +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 2 +# endif + +#if BOOST_FILESYSTEM_VERSION == 2 +# include <boost/filesystem/v2/exception.hpp> + +# else +# include <boost/filesystem/v3/exception.hpp> + +# endif + +#endif // BOOST_FILESYSTEM_EXCEPTIONX_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/fstream.hpp b/3rdParty/Boost/src/boost/filesystem/fstream.hpp index bdba8f0..ae44cd9 100644 --- a/3rdParty/Boost/src/boost/filesystem/fstream.hpp +++ b/3rdParty/Boost/src/boost/filesystem/fstream.hpp @@ -1,584 +1,32 @@ -// boost/filesystem/fstream.hpp --------------------------------------------// +// boost/filesystem/fstream.hpp ------------------------------------------------------// -// Copyright Beman Dawes 2002. -// 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) +// Copyright Beman Dawes 2010 -// See library home page at http://www.boost.org/libs/filesystem +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt -//----------------------------------------------------------------------------// +// Library home page: http://www.boost.org/libs/filesystem -#ifndef BOOST_FILESYSTEM_FSTREAM_HPP -#define BOOST_FILESYSTEM_FSTREAM_HPP +//--------------------------------------------------------------------------------------// -#include <boost/filesystem/operations.hpp> // for 8.3 hack (see below) -#include <boost/utility/enable_if.hpp> -#include <boost/detail/workaround.hpp> +#ifndef BOOST_FILESYSTEM_FSTREAMX_HPP +#define BOOST_FILESYSTEM_FSTREAMX_HPP -#include <iosfwd> -#include <fstream> - -#include <boost/config/abi_prefix.hpp> // must be the last #include - -// NOTE: fstream.hpp for Boost 1.32.0 and earlier supplied workarounds for -// various compiler problems. They have been removed to ease development of the -// basic i18n functionality. Once the new interface is stable, the workarounds -// will be reinstated for any compilers that otherwise can support the rest of -// the library after internationalization. - -namespace boost -{ - namespace filesystem - { - namespace detail - { -# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY) -# if !defined(BOOST_DINKUMWARE_STDLIB) || BOOST_DINKUMWARE_STDLIB < 405 - // The 8.3 hack: - // C++98 does not supply a wchar_t open, so try to get an equivalent - // narrow char name based on the short, so-called 8.3, name. - // Not needed for Dinkumware 405 and later as they do supply wchar_t open. - BOOST_FILESYSTEM_DECL bool create_file_api( const std::wstring & ph, - std::ios_base::openmode mode ); // true if succeeds - BOOST_FILESYSTEM_DECL std::string narrow_path_api( - const std::wstring & ph ); // return is empty if fails - - inline std::string path_proxy( const std::wstring & file_ph, - std::ios_base::openmode mode ) - // Return a non-existant path if cannot supply narrow short path. - // An empty path doesn't work because some Dinkumware versions - // assert the path is non-empty. - { - std::string narrow_ph; - bool created_file( false ); - if ( !exists( file_ph ) - && (mode & std::ios_base::out) != 0 - && create_file_api( file_ph, mode ) ) - { - created_file = true; - } - narrow_ph = narrow_path_api( file_ph ); - if ( narrow_ph.empty() ) - { - if ( created_file ) remove_api( file_ph ); - narrow_ph = "\x01"; - } - return narrow_ph; - } -# else - // Dinkumware 405 and later does supply wchar_t functions - inline const std::wstring & path_proxy( const std::wstring & file_ph, - std::ios_base::openmode ) - { return file_ph; } -# endif -# endif - - inline const std::string & path_proxy( const std::string & file_ph, - std::ios_base::openmode ) - { return file_ph; } - - } // namespace detail - - template < class charT, class traits = std::char_traits<charT> > - class basic_filebuf : public std::basic_filebuf<charT,traits> - { - private: // disallow copying - basic_filebuf( const basic_filebuf & ); - const basic_filebuf & operator=( const basic_filebuf & ); - public: - basic_filebuf() {} - virtual ~basic_filebuf() {} - -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - template<class Path> - typename boost::enable_if<is_basic_path<Path>, - basic_filebuf<charT,traits> *>::type - open( const Path & file_ph, std::ios_base::openmode mode ); - - basic_filebuf<charT,traits> * - open( const wpath & file_ph, std::ios_base::openmode mode ); -# endif - -# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this - basic_filebuf<charT,traits> * - open( const path & file_ph, std::ios_base::openmode mode ); -# endif - }; - - template < class charT, class traits = std::char_traits<charT> > - class basic_ifstream : public std::basic_ifstream<charT,traits> - { - private: // disallow copying - basic_ifstream( const basic_ifstream & ); - const basic_ifstream & operator=( const basic_ifstream & ); - public: - basic_ifstream() {} - - // use two signatures, rather than one signature with default second - // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) - -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - template<class Path> - explicit basic_ifstream( const Path & file_ph, - typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); - - template<class Path> - basic_ifstream( const Path & file_ph, std::ios_base::openmode mode, - typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); - - template<class Path> - typename boost::enable_if<is_basic_path<Path>, void>::type - open( const Path & file_ph ); - - template<class Path> - typename boost::enable_if<is_basic_path<Path>, void>::type - open( const Path & file_ph, std::ios_base::openmode mode ); - - explicit basic_ifstream( const wpath & file_ph ); - basic_ifstream( const wpath & file_ph, std::ios_base::openmode mode ); - void open( const wpath & file_ph ); - void open( const wpath & file_ph, std::ios_base::openmode mode ); -# endif - - explicit basic_ifstream( const path & file_ph ); - basic_ifstream( const path & file_ph, std::ios_base::openmode mode ); -# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this - void open( const path & file_ph ); - void open( const path & file_ph, std::ios_base::openmode mode ); -# endif - virtual ~basic_ifstream() {} - }; - - template < class charT, class traits = std::char_traits<charT> > - class basic_ofstream : public std::basic_ofstream<charT,traits> - { - private: // disallow copying - basic_ofstream( const basic_ofstream & ); - const basic_ofstream & operator=( const basic_ofstream & ); - public: - basic_ofstream() {} - - // use two signatures, rather than one signature with default second - // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) - -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - - template<class Path> - explicit basic_ofstream( const Path & file_ph, - typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); - explicit basic_ofstream( const wpath & file_ph ); - - template<class Path> - basic_ofstream( const Path & file_ph, std::ios_base::openmode mode, - typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); - basic_ofstream( const wpath & file_ph, std::ios_base::openmode mode ); - - template<class Path> - typename boost::enable_if<is_basic_path<Path>, void>::type - open( const Path & file_ph ); - void open( const wpath & file_ph ); - - template<class Path> - typename boost::enable_if<is_basic_path<Path>, void>::type - open( const Path & file_ph, std::ios_base::openmode mode ); - void open( const wpath & file_ph, std::ios_base::openmode mode ); - -# endif - - explicit basic_ofstream( const path & file_ph ); - basic_ofstream( const path & file_ph, std::ios_base::openmode mode ); -# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this - void open( const path & file_ph ); - void open( const path & file_ph, std::ios_base::openmode mode ); -# endif - virtual ~basic_ofstream() {} - }; - - template < class charT, class traits = std::char_traits<charT> > - class basic_fstream : public std::basic_fstream<charT,traits> - { - private: // disallow copying - basic_fstream( const basic_fstream & ); - const basic_fstream & operator=( const basic_fstream & ); - public: - basic_fstream() {} - - // use two signatures, rather than one signature with default second - // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) - -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - - template<class Path> - explicit basic_fstream( const Path & file_ph, - typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); - explicit basic_fstream( const wpath & file_ph ); - - template<class Path> - basic_fstream( const Path & file_ph, std::ios_base::openmode mode, - typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); - basic_fstream( const wpath & file_ph, std::ios_base::openmode mode ); - - template<class Path> - typename boost::enable_if<is_basic_path<Path>, void>::type - open( const Path & file_ph ); - void open( const wpath & file_ph ); - - template<class Path> - typename boost::enable_if<is_basic_path<Path>, void>::type - open( const Path & file_ph, std::ios_base::openmode mode ); - void open( const wpath & file_ph, std::ios_base::openmode mode ); - -# endif - - explicit basic_fstream( const path & file_ph ); - basic_fstream( const path & file_ph, std::ios_base::openmode mode ); -# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this - void open( const path & file_ph ); - void open( const path & file_ph, std::ios_base::openmode mode ); -# endif - virtual ~basic_fstream() {} - - }; - - typedef basic_filebuf<char> filebuf; - typedef basic_ifstream<char> ifstream; - typedef basic_ofstream<char> ofstream; - typedef basic_fstream<char> fstream; - -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - typedef basic_filebuf<wchar_t> wfilebuf; - typedef basic_ifstream<wchar_t> wifstream; - typedef basic_fstream<wchar_t> wfstream; - typedef basic_ofstream<wchar_t> wofstream; +# if defined(BOOST_FILESYSTEM_VERSION) \ + && BOOST_FILESYSTEM_VERSION != 2 && BOOST_FILESYSTEM_VERSION != 3 +# error BOOST_FILESYSTEM_VERSION defined, but not as 2 or 3 # endif - -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - -// basic_filebuf definitions -----------------------------------------------// - - template <class charT, class traits> - template<class Path> - typename boost::enable_if<is_basic_path<Path>, - basic_filebuf<charT,traits> *>::type - basic_filebuf<charT,traits>::open( const Path & file_ph, - std::ios_base::openmode mode ) - { - return (std::basic_filebuf<charT,traits>::open( detail::path_proxy( - file_ph.external_file_string(), mode ).c_str(), mode ) - == 0) ? 0 : this; - } - - template <class charT, class traits> - basic_filebuf<charT,traits> * - basic_filebuf<charT, traits>::open( const wpath & file_ph, - std::ios_base::openmode mode ) - { - return this->BOOST_NESTED_TEMPLATE open<wpath>( file_ph, mode ); - } - -// basic_ifstream definitions ----------------------------------------------// - - template <class charT, class traits> template<class Path> - basic_ifstream<charT,traits>::basic_ifstream(const Path & file_ph, - typename boost::enable_if<is_basic_path<Path> >::type* ) - : std::basic_ifstream<charT,traits>( - detail::path_proxy( file_ph.external_file_string(), - std::ios_base::in ).c_str(), std::ios_base::in ) {} - - template <class charT, class traits> - basic_ifstream<charT,traits>::basic_ifstream( const wpath & file_ph ) - : std::basic_ifstream<charT,traits>( - detail::path_proxy( file_ph.external_file_string(), - std::ios_base::in ).c_str(), std::ios_base::in ) {} - - template <class charT, class traits> template<class Path> - basic_ifstream<charT,traits>::basic_ifstream( const Path & file_ph, - std::ios_base::openmode mode, - typename boost::enable_if<is_basic_path<Path> >::type* ) - : std::basic_ifstream<charT,traits>( - detail::path_proxy( file_ph.external_file_string(), - mode ).c_str(), mode | std::ios_base::in ) {} - - template <class charT, class traits> - basic_ifstream<charT,traits>::basic_ifstream( const wpath & file_ph, - std::ios_base::openmode mode ) - : std::basic_ifstream<charT,traits>( - detail::path_proxy( file_ph.external_file_string(), - mode ).c_str(), mode | std::ios_base::in ) {} - - template <class charT, class traits> template<class Path> - typename boost::enable_if<is_basic_path<Path>, void>::type - basic_ifstream<charT,traits>::open( const Path & file_ph ) - { - std::basic_ifstream<charT,traits>::open( - detail::path_proxy( file_ph.external_file_string(), - std::ios_base::in ).c_str(), std::ios_base::in ); - } - - template <class charT, class traits> - void basic_ifstream<charT,traits>::open( const wpath & file_ph ) - { - std::basic_ifstream<charT,traits>::open( - detail::path_proxy( file_ph.external_file_string(), - std::ios_base::in ).c_str(), std::ios_base::in ); - } - - template <class charT, class traits> template<class Path> - typename boost::enable_if<is_basic_path<Path>, void>::type - basic_ifstream<charT,traits>::open( const Path & file_ph, - std::ios_base::openmode mode ) - { - std::basic_ifstream<charT,traits>::open( - detail::path_proxy( file_ph.external_file_string(), - mode ).c_str(), mode | std::ios_base::in ); - } - - template <class charT, class traits> - void basic_ifstream<charT,traits>::open( const wpath & file_ph, - std::ios_base::openmode mode ) - { - std::basic_ifstream<charT,traits>::open( - detail::path_proxy( file_ph.external_file_string(), - mode ).c_str(), mode | std::ios_base::in ); - } - -// basic_ofstream definitions ----------------------------------------------// - - template <class charT, class traits> template<class Path> - basic_ofstream<charT,traits>::basic_ofstream(const Path & file_ph, - typename boost::enable_if<is_basic_path<Path> >::type* ) - : std::basic_ofstream<charT,traits>( - detail::path_proxy( file_ph.external_file_string(), - std::ios_base::out ).c_str(), std::ios_base::out ) {} - - template <class charT, class traits> - basic_ofstream<charT,traits>::basic_ofstream( const wpath & file_ph ) - : std::basic_ofstream<charT,traits>( - detail::path_proxy( file_ph.external_file_string(), - std::ios_base::out ).c_str(), std::ios_base::out ) {} - - template <class charT, class traits> template<class Path> - basic_ofstream<charT,traits>::basic_ofstream( const Path & file_ph, - std::ios_base::openmode mode, - typename boost::enable_if<is_basic_path<Path> >::type* ) - : std::basic_ofstream<charT,traits>( - detail::path_proxy( file_ph.external_file_string(), - mode ).c_str(), mode | std::ios_base::out ) {} - - template <class charT, class traits> - basic_ofstream<charT,traits>::basic_ofstream( const wpath & file_ph, - std::ios_base::openmode mode ) - : std::basic_ofstream<charT,traits>( - detail::path_proxy( file_ph.external_file_string(), - mode ).c_str(), mode | std::ios_base::out ) {} - - template <class charT, class traits> template<class Path> - typename boost::enable_if<is_basic_path<Path>, void>::type - basic_ofstream<charT,traits>::open( const Path & file_ph ) - { - std::basic_ofstream<charT,traits>::open( - detail::path_proxy( file_ph.external_file_string(), - std::ios_base::out ).c_str(), std::ios_base::out ); - } - - template <class charT, class traits> - void basic_ofstream<charT,traits>::open( const wpath & file_ph ) - { - std::basic_ofstream<charT,traits>::open( - detail::path_proxy( file_ph.external_file_string(), - std::ios_base::out ).c_str(), std::ios_base::out ); - } - - template <class charT, class traits> template<class Path> - typename boost::enable_if<is_basic_path<Path>, void>::type - basic_ofstream<charT,traits>::open( const Path & file_ph, - std::ios_base::openmode mode ) - { - std::basic_ofstream<charT,traits>::open( - detail::path_proxy( file_ph.external_file_string(), - mode ).c_str(), mode | std::ios_base::out ); - } - - template <class charT, class traits> - void basic_ofstream<charT,traits>::open( const wpath & file_ph, - std::ios_base::openmode mode ) - { - std::basic_ofstream<charT,traits>::open( - detail::path_proxy( file_ph.external_file_string(), - mode ).c_str(), mode | std::ios_base::out ); - } - -// basic_fstream definitions -----------------------------------------------// - - template <class charT, class traits> template<class Path> - basic_fstream<charT,traits>::basic_fstream(const Path & file_ph, - typename boost::enable_if<is_basic_path<Path> >::type* ) - : std::basic_fstream<charT,traits>( - detail::path_proxy( file_ph.external_file_string(), - std::ios_base::in|std::ios_base::out ).c_str(), - std::ios_base::in|std::ios_base::out ) {} - - template <class charT, class traits> - basic_fstream<charT,traits>::basic_fstream( const wpath & file_ph ) - : std::basic_fstream<charT,traits>( - detail::path_proxy( file_ph.external_file_string(), - std::ios_base::in|std::ios_base::out ).c_str(), - std::ios_base::in|std::ios_base::out ) {} - - template <class charT, class traits> template<class Path> - basic_fstream<charT,traits>::basic_fstream( const Path & file_ph, - std::ios_base::openmode mode, - typename boost::enable_if<is_basic_path<Path> >::type* ) - : std::basic_fstream<charT,traits>( - detail::path_proxy( file_ph.external_file_string(), - mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ) {} - - template <class charT, class traits> - basic_fstream<charT,traits>::basic_fstream( const wpath & file_ph, - std::ios_base::openmode mode ) - : std::basic_fstream<charT,traits>( - detail::path_proxy( file_ph.external_file_string(), - mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ) {} - - template <class charT, class traits> template<class Path> - typename boost::enable_if<is_basic_path<Path>, void>::type - basic_fstream<charT,traits>::open( const Path & file_ph ) - { - std::basic_fstream<charT,traits>::open( - detail::path_proxy( file_ph.external_file_string(), - std::ios_base::in|std::ios_base::out ).c_str(), - std::ios_base::in|std::ios_base::out ); - } - - template <class charT, class traits> - void basic_fstream<charT,traits>::open( const wpath & file_ph ) - { - std::basic_fstream<charT,traits>::open( - detail::path_proxy( file_ph.external_file_string(), - std::ios_base::in|std::ios_base::out ).c_str(), - std::ios_base::in|std::ios_base::out ); - } - - template <class charT, class traits> template<class Path> - typename boost::enable_if<is_basic_path<Path>, void>::type - basic_fstream<charT,traits>::open( const Path & file_ph, - std::ios_base::openmode mode ) - { - std::basic_fstream<charT,traits>::open( - detail::path_proxy( file_ph.external_file_string(), - mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ); - } - - template <class charT, class traits> - void basic_fstream<charT,traits>::open( const wpath & file_ph, - std::ios_base::openmode mode ) - { - std::basic_fstream<charT,traits>::open( - detail::path_proxy( file_ph.external_file_string(), - mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ); - } +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 2 # endif -# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this - template <class charT, class traits> - basic_filebuf<charT,traits> * - basic_filebuf<charT, traits>::open( const path & file_ph, - std::ios_base::openmode mode ) - { - return std::basic_filebuf<charT,traits>::open( - file_ph.file_string().c_str(), mode ) == 0 ? 0 : this; - } -# endif +#if BOOST_FILESYSTEM_VERSION == 2 +# include <boost/filesystem/v2/fstream.hpp> - template <class charT, class traits> - basic_ifstream<charT,traits>::basic_ifstream( const path & file_ph ) - : std::basic_ifstream<charT,traits>( - file_ph.file_string().c_str(), std::ios_base::in ) {} +# else +# include <boost/filesystem/v3/fstream.hpp> - template <class charT, class traits> - basic_ifstream<charT,traits>::basic_ifstream( const path & file_ph, - std::ios_base::openmode mode ) - : std::basic_ifstream<charT,traits>( - file_ph.file_string().c_str(), mode ) {} - -# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this - template <class charT, class traits> - void basic_ifstream<charT,traits>::open( const path & file_ph ) - { - std::basic_ifstream<charT,traits>::open( - file_ph.file_string().c_str(), std::ios_base::in ); - } - - template <class charT, class traits> - void basic_ifstream<charT,traits>::open( const path & file_ph, - std::ios_base::openmode mode ) - { - std::basic_ifstream<charT,traits>::open( - file_ph.file_string().c_str(), mode ); - } -# endif - - template <class charT, class traits> - basic_ofstream<charT,traits>::basic_ofstream( const path & file_ph ) - : std::basic_ofstream<charT,traits>( - file_ph.file_string().c_str(), std::ios_base::out ) {} - - template <class charT, class traits> - basic_ofstream<charT,traits>::basic_ofstream( const path & file_ph, - std::ios_base::openmode mode ) - : std::basic_ofstream<charT,traits>( - file_ph.file_string().c_str(), mode ) {} - -# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this - template <class charT, class traits> - void basic_ofstream<charT,traits>::open( const path & file_ph ) - { - std::basic_ofstream<charT,traits>::open( - file_ph.file_string().c_str(), std::ios_base::out ); - } - - template <class charT, class traits> - void basic_ofstream<charT,traits>::open( const path & file_ph, - std::ios_base::openmode mode ) - { - std::basic_ofstream<charT,traits>::open( - file_ph.file_string().c_str(), mode ); - } -# endif - - template <class charT, class traits> - basic_fstream<charT,traits>::basic_fstream( const path & file_ph ) - : std::basic_fstream<charT,traits>( - file_ph.file_string().c_str(), - std::ios_base::in|std::ios_base::out ) {} - - - template <class charT, class traits> - basic_fstream<charT,traits>::basic_fstream( const path & file_ph, - std::ios_base::openmode mode ) - : std::basic_fstream<charT,traits>( - file_ph.file_string().c_str(), mode ) {} - -# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this - template <class charT, class traits> - void basic_fstream<charT,traits>::open( const path & file_ph ) - { - std::basic_fstream<charT,traits>::open( - file_ph.file_string().c_str(), std::ios_base::in|std::ios_base::out ); - } - - template <class charT, class traits> - void basic_fstream<charT,traits>::open( const path & file_ph, - std::ios_base::openmode mode ) - { - std::basic_fstream<charT,traits>::open( - file_ph.file_string().c_str(), mode ); - } -# endif - } // namespace filesystem -} // namespace boost +# endif -#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas -#endif // BOOST_FILESYSTEM_FSTREAM_HPP +#endif // BOOST_FILESYSTEM_FSTREAMX_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/operations.hpp b/3rdParty/Boost/src/boost/filesystem/operations.hpp index 4d52ab7..7dc94e9 100644 --- a/3rdParty/Boost/src/boost/filesystem/operations.hpp +++ b/3rdParty/Boost/src/boost/filesystem/operations.hpp @@ -1,1179 +1,32 @@ -// boost/filesystem/operations.hpp -----------------------------------------// +// boost/filesystem/operations.hpp ---------------------------------------------------// -// Copyright 2002-2005 Beman Dawes -// Copyright 2002 Jan Langer -// Copyright 2001 Dietmar Kuehl -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// Copyright Beman Dawes 2010 -// See library home page at http://www.boost.org/libs/filesystem +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt -//----------------------------------------------------------------------------// +// Library home page: http://www.boost.org/libs/filesystem -#ifndef BOOST_FILESYSTEM_OPERATIONS_HPP -#define BOOST_FILESYSTEM_OPERATIONS_HPP +//--------------------------------------------------------------------------------------// -#include <boost/filesystem/path.hpp> -#include <boost/detail/scoped_enum_emulation.hpp> +#ifndef BOOST_FILESYSTEM_OPERATIONSX_HPP +#define BOOST_FILESYSTEM_OPERATIONSX_HPP -#include <boost/shared_ptr.hpp> -#include <boost/utility/enable_if.hpp> -#include <boost/type_traits/is_same.hpp> -#include <boost/iterator.hpp> -#include <boost/cstdint.hpp> -#include <boost/assert.hpp> - -#include <string> -#include <utility> // for pair -#include <ctime> - -#ifdef BOOST_WINDOWS_API -# include <fstream> -# if !defined(_WIN32_WINNT) || _WIN32_WINNT >= 0x0500 -# define BOOST_FS_HARD_LINK // Default for Windows 2K or later -# endif -#endif - -#include <boost/config/abi_prefix.hpp> // must be the last #include - -# ifdef BOOST_NO_STDC_NAMESPACE - namespace std { using ::time_t; } +# if defined(BOOST_FILESYSTEM_VERSION) \ + && BOOST_FILESYSTEM_VERSION != 2 && BOOST_FILESYSTEM_VERSION != 3 +# error BOOST_FILESYSTEM_VERSION defined, but not as 2 or 3 # endif -//----------------------------------------------------------------------------// - -namespace boost -{ - namespace filesystem - { - -// typedef boost::filesystem::path Path; needs to be in namespace boost::filesystem -# ifndef BOOST_FILESYSTEM_NARROW_ONLY -# define BOOST_FS_FUNC(BOOST_FS_TYPE) \ - template<class Path> typename boost::enable_if<is_basic_path<Path>, \ - BOOST_FS_TYPE>::type -# define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) \ - template<class Path> inline typename boost::enable_if<is_basic_path<Path>, \ - BOOST_FS_TYPE>::type -# define BOOST_FS_TYPENAME typename -# else -# define BOOST_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE -# define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE - typedef boost::filesystem::path Path; -# define BOOST_FS_TYPENAME +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 2 # endif - template<class Path> class basic_directory_iterator; - - // BOOST_FILESYSTEM_NARROW_ONLY needs this: - typedef basic_directory_iterator<path> directory_iterator; - - template<class Path> class basic_directory_entry; - - enum file_type - { - status_unknown, - file_not_found, - regular_file, - directory_file, - // the following will never be reported by some operating or file systems - symlink_file, - block_file, - character_file, - fifo_file, - socket_file, - type_unknown // file does exist, but isn't one of the above types or - // we don't have strong enough permission to find its type - }; - - class file_status - { - public: - explicit file_status( file_type v = status_unknown ) : m_value(v) {} - - void type( file_type v ) { m_value = v; } - file_type type() const { return m_value; } - - private: - // the internal representation is unspecified so that additional state - // information such as permissions can be added in the future; this - // implementation just uses status_type as the internal representation - - file_type m_value; - }; - - inline bool status_known( file_status f ) { return f.type() != status_unknown; } - inline bool exists( file_status f ) { return f.type() != status_unknown && f.type() != file_not_found; } - inline bool is_regular_file(file_status f){ return f.type() == regular_file; } - inline bool is_directory( file_status f ) { return f.type() == directory_file; } - inline bool is_symlink( file_status f ) { return f.type() == symlink_file; } - inline bool is_other( file_status f ) { return exists(f) && !is_regular_file(f) && !is_directory(f) && !is_symlink(f); } - -# ifndef BOOST_FILESYSTEM_NO_DEPRECATED - inline bool is_regular( file_status f ) { return f.type() == regular_file; } -# endif - - struct space_info - { - // all values are byte counts - boost::uintmax_t capacity; - boost::uintmax_t free; // <= capacity - boost::uintmax_t available; // <= free - }; - - namespace detail - { - typedef std::pair< system::error_code, bool > - query_pair; - - typedef std::pair< system::error_code, boost::uintmax_t > - uintmax_pair; - - typedef std::pair< system::error_code, std::time_t > - time_pair; +#if BOOST_FILESYSTEM_VERSION == 2 +# include <boost/filesystem/v2/operations.hpp> - typedef std::pair< system::error_code, space_info > - space_pair; - - template< class Path > - struct directory_pair - { - typedef std::pair< system::error_code, - typename Path::external_string_type > type; - }; - -# ifndef BOOST_FILESYSTEM_NO_DEPRECATED - BOOST_FILESYSTEM_DECL bool - symbolic_link_exists_api( const std::string & ); // deprecated -# endif - - BOOST_FILESYSTEM_DECL file_status - status_api( const std::string & ph, system::error_code & ec ); -# ifndef BOOST_WINDOWS_API - BOOST_FILESYSTEM_DECL file_status - symlink_status_api( const std::string & ph, system::error_code & ec ); -# endif - BOOST_FILESYSTEM_DECL query_pair - is_empty_api( const std::string & ph ); - BOOST_FILESYSTEM_DECL query_pair - equivalent_api( const std::string & ph1, const std::string & ph2 ); - BOOST_FILESYSTEM_DECL uintmax_pair - file_size_api( const std::string & ph ); - BOOST_FILESYSTEM_DECL space_pair - space_api( const std::string & ph ); - BOOST_FILESYSTEM_DECL time_pair - last_write_time_api( const std::string & ph ); - BOOST_FILESYSTEM_DECL system::error_code - last_write_time_api( const std::string & ph, std::time_t new_value ); - BOOST_FILESYSTEM_DECL system::error_code - get_current_path_api( std::string & ph ); - BOOST_FILESYSTEM_DECL system::error_code - set_current_path_api( const std::string & ph ); - BOOST_FILESYSTEM_DECL query_pair - create_directory_api( const std::string & ph ); - BOOST_FILESYSTEM_DECL system::error_code - create_hard_link_api( const std::string & to_ph, - const std::string & from_ph ); - BOOST_FILESYSTEM_DECL system::error_code - create_symlink_api( const std::string & to_ph, - const std::string & from_ph ); - BOOST_FILESYSTEM_DECL system::error_code - remove_api( const std::string & ph ); - BOOST_FILESYSTEM_DECL system::error_code - rename_api( const std::string & from, const std::string & to ); - BOOST_FILESYSTEM_DECL system::error_code - copy_file_api( const std::string & from, const std::string & to, bool fail_if_exists ); - -# if defined(BOOST_WINDOWS_API) - - BOOST_FILESYSTEM_DECL system::error_code - get_full_path_name_api( const std::string & ph, std::string & target ); - -# if !defined(BOOST_FILESYSTEM_NARROW_ONLY) - - BOOST_FILESYSTEM_DECL boost::filesystem::file_status - status_api( const std::wstring & ph, system::error_code & ec ); - BOOST_FILESYSTEM_DECL query_pair - is_empty_api( const std::wstring & ph ); - BOOST_FILESYSTEM_DECL query_pair - equivalent_api( const std::wstring & ph1, const std::wstring & ph2 ); - BOOST_FILESYSTEM_DECL uintmax_pair - file_size_api( const std::wstring & ph ); - BOOST_FILESYSTEM_DECL space_pair - space_api( const std::wstring & ph ); - BOOST_FILESYSTEM_DECL system::error_code - get_full_path_name_api( const std::wstring & ph, std::wstring & target ); - BOOST_FILESYSTEM_DECL time_pair - last_write_time_api( const std::wstring & ph ); - BOOST_FILESYSTEM_DECL system::error_code - last_write_time_api( const std::wstring & ph, std::time_t new_value ); - BOOST_FILESYSTEM_DECL system::error_code - get_current_path_api( std::wstring & ph ); - BOOST_FILESYSTEM_DECL system::error_code - set_current_path_api( const std::wstring & ph ); - BOOST_FILESYSTEM_DECL query_pair - create_directory_api( const std::wstring & ph ); -# ifdef BOOST_FS_HARD_LINK - BOOST_FILESYSTEM_DECL system::error_code - create_hard_link_api( const std::wstring & existing_ph, - const std::wstring & new_ph ); -# endif - BOOST_FILESYSTEM_DECL system::error_code - create_symlink_api( const std::wstring & to_ph, - const std::wstring & from_ph ); - BOOST_FILESYSTEM_DECL system::error_code - remove_api( const std::wstring & ph ); - BOOST_FILESYSTEM_DECL system::error_code - rename_api( const std::wstring & from, const std::wstring & to ); - BOOST_FILESYSTEM_DECL system::error_code - copy_file_api( const std::wstring & from, const std::wstring & to, bool fail_if_exists ); - -# endif -# endif - - template<class Path> - bool remove_aux( const Path & ph, file_status f ); - - template<class Path> - unsigned long remove_all_aux( const Path & ph, file_status f ); - - } // namespace detail - -// operations functions ----------------------------------------------------// - - // The non-template overloads enable automatic conversion from std and - // C-style strings. See basic_path constructors. The enable_if for the - // templates implements the famous "do-the-right-thing" rule. - -// query functions ---------------------------------------------------------// - - BOOST_INLINE_FS_FUNC(file_status) - status( const Path & ph, system::error_code & ec ) - { return detail::status_api( ph.external_file_string(), ec ); } - - BOOST_FS_FUNC(file_status) - status( const Path & ph ) - { - system::error_code ec; - file_status result( detail::status_api( ph.external_file_string(), ec ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::status", ph, ec ) ); - return result; - } - - BOOST_INLINE_FS_FUNC(file_status) - symlink_status( const Path & ph, system::error_code & ec ) -# ifdef BOOST_WINDOWS_API - { return detail::status_api( ph.external_file_string(), ec ); } -# else - { return detail::symlink_status_api( ph.external_file_string(), ec ); } -# endif - - BOOST_FS_FUNC(file_status) - symlink_status( const Path & ph ) - { - system::error_code ec; - file_status result( symlink_status( ph, ec ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::symlink_status", ph, ec ) ); - return result; - } - -# ifndef BOOST_FILESYSTEM_NO_DEPRECATED - inline bool symbolic_link_exists( const path & ph ) - { return is_symlink( symlink_status(ph) ); } -# endif - - BOOST_FS_FUNC(bool) exists( const Path & ph ) - { - system::error_code ec; - file_status result( detail::status_api( ph.external_file_string(), ec ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::exists", ph, ec ) ); - return exists( result ); - } - - BOOST_FS_FUNC(bool) is_directory( const Path & ph ) - { - system::error_code ec; - file_status result( detail::status_api( ph.external_file_string(), ec ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::is_directory", ph, ec ) ); - return is_directory( result ); - } - - BOOST_FS_FUNC(bool) is_regular_file( const Path & ph ) - { - system::error_code ec; - file_status result( detail::status_api( ph.external_file_string(), ec ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::is_regular_file", ph, ec ) ); - return is_regular_file( result ); - } - -# ifndef BOOST_FILESYSTEM_NO_DEPRECATED - BOOST_FS_FUNC(bool) is_regular( const Path & ph ) - { - system::error_code ec; - file_status result( detail::status_api( ph.external_file_string(), ec ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::is_regular", ph, ec ) ); - return is_regular( result ); - } -# endif - - BOOST_FS_FUNC(bool) is_other( const Path & ph ) - { - system::error_code ec; - file_status result( detail::status_api( ph.external_file_string(), ec ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::is_other", ph, ec ) ); - return is_other( result ); - } - - BOOST_FS_FUNC(bool) is_symlink( -# ifdef BOOST_WINDOWS_API - const Path & ) - { - return false; -# else - const Path & ph) - { - system::error_code ec; - file_status result( detail::symlink_status_api( ph.external_file_string(), ec ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::is_symlink", ph, ec ) ); - return is_symlink( result ); -# endif - } - - // VC++ 7.0 and earlier has a serious namespace bug that causes a clash - // between boost::filesystem::is_empty and the unrelated type trait - // boost::is_empty. - -# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 - BOOST_FS_FUNC(bool) is_empty( const Path & ph ) # else - BOOST_FS_FUNC(bool) _is_empty( const Path & ph ) -# endif - { - detail::query_pair result( - detail::is_empty_api( ph.external_file_string() ) ); - if ( result.first ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::is_empty", ph, result.first ) ); - return result.second; - } - - BOOST_FS_FUNC(bool) equivalent( const Path & ph1, const Path & ph2 ) - { - detail::query_pair result( detail::equivalent_api( - ph1.external_file_string(), ph2.external_file_string() ) ); - if ( result.first ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::equivalent", ph1, ph2, result.first ) ); - return result.second; - } - - BOOST_FS_FUNC(boost::uintmax_t) file_size( const Path & ph ) - { - detail::uintmax_pair result - ( detail::file_size_api( ph.external_file_string() ) ); - if ( result.first ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::file_size", ph, result.first ) ); - return result.second; - } - - BOOST_FS_FUNC(space_info) space( const Path & ph ) - { - detail::space_pair result - ( detail::space_api( ph.external_file_string() ) ); - if ( result.first ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::space", ph, result.first ) ); - return result.second; - } - - BOOST_FS_FUNC(std::time_t) last_write_time( const Path & ph ) - { - detail::time_pair result - ( detail::last_write_time_api( ph.external_file_string() ) ); - if ( result.first ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::last_write_time", ph, result.first ) ); - return result.second; - } - - -// operations --------------------------------------------------------------// - - BOOST_FS_FUNC(bool) create_directory( const Path & dir_ph ) - { - detail::query_pair result( - detail::create_directory_api( dir_ph.external_directory_string() ) ); - if ( result.first ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::create_directory", - dir_ph, result.first ) ); - return result.second; - } - -#if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK) - BOOST_FS_FUNC(void) - create_hard_link( const Path & to_ph, const Path & from_ph ) - { - system::error_code ec( - detail::create_hard_link_api( - to_ph.external_file_string(), - from_ph.external_file_string() ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::create_hard_link", - to_ph, from_ph, ec ) ); - } - - BOOST_FS_FUNC(system::error_code) - create_hard_link( const Path & to_ph, const Path & from_ph, - system::error_code & ec ) - { - ec = detail::create_hard_link_api( - to_ph.external_file_string(), - from_ph.external_file_string() ); - return ec; - } -#endif - - BOOST_FS_FUNC(void) - create_symlink( const Path & to_ph, const Path & from_ph ) - { - system::error_code ec( - detail::create_symlink_api( - to_ph.external_file_string(), - from_ph.external_file_string() ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::create_symlink", - to_ph, from_ph, ec ) ); - } +# include <boost/filesystem/v3/operations.hpp> - BOOST_FS_FUNC(system::error_code) - create_symlink( const Path & to_ph, const Path & from_ph, - system::error_code & ec ) - { - ec = detail::create_symlink_api( - to_ph.external_file_string(), - from_ph.external_file_string() ); - return ec; - } - - BOOST_FS_FUNC(bool) remove( const Path & ph ) - { - system::error_code ec; - file_status f = symlink_status( ph, ec ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::remove", ph, ec ) ); - return detail::remove_aux( ph, f ); - } - - BOOST_FS_FUNC(unsigned long) remove_all( const Path & ph ) - { - system::error_code ec; - file_status f = symlink_status( ph, ec ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::remove_all", ph, ec ) ); - return exists( f ) ? detail::remove_all_aux( ph, f ) : 0; - } - - BOOST_FS_FUNC(void) rename( const Path & from_path, const Path & to_path ) - { - system::error_code ec( detail::rename_api( - from_path.external_directory_string(), - to_path.external_directory_string() ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::rename", - from_path, to_path, ec ) ); - } - - BOOST_SCOPED_ENUM_START(copy_option) - { fail_if_exists, overwrite_if_exists }; - BOOST_SCOPED_ENUM_END - - BOOST_FS_FUNC(void) copy_file( const Path & from_path, const Path & to_path, - BOOST_SCOPED_ENUM(copy_option) option = copy_option::fail_if_exists ) - { - system::error_code ec( detail::copy_file_api( - from_path.external_directory_string(), - to_path.external_directory_string(), option == copy_option::fail_if_exists ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::copy_file", - from_path, to_path, ec ) ); - } - - template< class Path > - Path current_path() - { - typename Path::external_string_type ph; - system::error_code ec( detail::get_current_path_api( ph ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::current_path", ec ) ); - return Path( Path::traits_type::to_internal( ph ) ); - } - - BOOST_FS_FUNC(void) current_path( const Path & ph ) - { - system::error_code ec( detail::set_current_path_api( - ph.external_directory_string() ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::current_path", ph, ec ) ); - } - - template< class Path > - const Path & initial_path() - { - static Path init_path; - if ( init_path.empty() ) init_path = current_path<Path>(); - return init_path; - } - -# ifndef BOOST_FILESYSTEM_NO_DEPRECATED - // legacy support - inline path current_path() // overload supports pre-i18n apps - { return current_path<boost::filesystem::path>(); } - inline const path & initial_path() // overload supports pre-i18n apps - { return initial_path<boost::filesystem::path>(); } -# endif - - BOOST_FS_FUNC(Path) system_complete( const Path & ph ) - { -# ifdef BOOST_WINDOWS_API - if ( ph.empty() ) return ph; - BOOST_FS_TYPENAME Path::external_string_type sys_ph; - system::error_code ec( detail::get_full_path_name_api( ph.external_file_string(), - sys_ph ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::system_complete", ph, ec ) ); - return Path( Path::traits_type::to_internal( sys_ph ) ); -# else - return (ph.empty() || ph.is_complete()) - ? ph : current_path<Path>() / ph; # endif - } - - BOOST_FS_FUNC(Path) - complete( const Path & ph, - const Path & base/* = initial_path<Path>() */) - { - BOOST_ASSERT( base.is_complete() - && (ph.is_complete() || !ph.has_root_name()) - && "boost::filesystem::complete() precondition not met" ); -# ifdef BOOST_WINDOWS_PATH - if (ph.empty() || ph.is_complete()) return ph; - if ( !ph.has_root_name() ) - return ph.has_root_directory() - ? Path( base.root_name() ) / ph - : base / ph; - return base / ph; -# else - return (ph.empty() || ph.is_complete()) ? ph : base / ph; -# endif - } - - // VC++ 7.1 had trouble with default arguments, so separate one argument - // signatures are provided as workarounds; the effect is the same. - BOOST_FS_FUNC(Path) complete( const Path & ph ) - { return complete( ph, initial_path<Path>() ); } - - BOOST_FS_FUNC(void) - last_write_time( const Path & ph, const std::time_t new_time ) - { - system::error_code ec( detail::last_write_time_api( ph.external_file_string(), - new_time ) ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::last_write_time", ph, ec ) ); - } - -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - - // "do-the-right-thing" overloads ---------------------------------------// - - inline file_status status( const path & ph ) - { return status<path>( ph ); } - inline file_status status( const wpath & ph ) - { return status<wpath>( ph ); } - - inline file_status status( const path & ph, system::error_code & ec ) - { return status<path>( ph, ec ); } - inline file_status status( const wpath & ph, system::error_code & ec ) - { return status<wpath>( ph, ec ); } - - inline file_status symlink_status( const path & ph ) - { return symlink_status<path>( ph ); } - inline file_status symlink_status( const wpath & ph ) - { return symlink_status<wpath>( ph ); } - - inline file_status symlink_status( const path & ph, system::error_code & ec ) - { return symlink_status<path>( ph, ec ); } - inline file_status symlink_status( const wpath & ph, system::error_code & ec ) - { return symlink_status<wpath>( ph, ec ); } - - inline bool exists( const path & ph ) { return exists<path>( ph ); } - inline bool exists( const wpath & ph ) { return exists<wpath>( ph ); } - - inline bool is_directory( const path & ph ) - { return is_directory<path>( ph ); } - inline bool is_directory( const wpath & ph ) - { return is_directory<wpath>( ph ); } - - inline bool is_regular_file( const path & ph ) - { return is_regular_file<path>( ph ); } - inline bool is_regular_file( const wpath & ph ) - { return is_regular_file<wpath>( ph ); } - -# ifndef BOOST_FILESYSTEM_NO_DEPRECATED - inline bool is_regular( const path & ph ) - { return is_regular<path>( ph ); } - inline bool is_regular( const wpath & ph ) - { return is_regular<wpath>( ph ); } -# endif - - inline bool is_other( const path & ph ) - { return is_other<path>( ph ); } - inline bool is_other( const wpath & ph ) - { return is_other<wpath>( ph ); } - - inline bool is_symlink( const path & ph ) - { return is_symlink<path>( ph ); } - inline bool is_symlink( const wpath & ph ) - { return is_symlink<wpath>( ph ); } - - inline bool is_empty( const path & ph ) - { return boost::filesystem::is_empty<path>( ph ); } - inline bool is_empty( const wpath & ph ) - { return boost::filesystem::is_empty<wpath>( ph ); } - - inline bool equivalent( const path & ph1, const path & ph2 ) - { return equivalent<path>( ph1, ph2 ); } - inline bool equivalent( const wpath & ph1, const wpath & ph2 ) - { return equivalent<wpath>( ph1, ph2 ); } - - inline boost::uintmax_t file_size( const path & ph ) - { return file_size<path>( ph ); } - inline boost::uintmax_t file_size( const wpath & ph ) - { return file_size<wpath>( ph ); } - - inline space_info space( const path & ph ) - { return space<path>( ph ); } - inline space_info space( const wpath & ph ) - { return space<wpath>( ph ); } - - inline std::time_t last_write_time( const path & ph ) - { return last_write_time<path>( ph ); } - inline std::time_t last_write_time( const wpath & ph ) - { return last_write_time<wpath>( ph ); } - - inline bool create_directory( const path & dir_ph ) - { return create_directory<path>( dir_ph ); } - inline bool create_directory( const wpath & dir_ph ) - { return create_directory<wpath>( dir_ph ); } - -#if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK) - inline void create_hard_link( const path & to_ph, - const path & from_ph ) - { return create_hard_link<path>( to_ph, from_ph ); } - inline void create_hard_link( const wpath & to_ph, - const wpath & from_ph ) - { return create_hard_link<wpath>( to_ph, from_ph ); } - - inline system::error_code create_hard_link( const path & to_ph, - const path & from_ph, system::error_code & ec ) - { return create_hard_link<path>( to_ph, from_ph, ec ); } - inline system::error_code create_hard_link( const wpath & to_ph, - const wpath & from_ph, system::error_code & ec ) - { return create_hard_link<wpath>( to_ph, from_ph, ec ); } -#endif - - inline void create_symlink( const path & to_ph, - const path & from_ph ) - { return create_symlink<path>( to_ph, from_ph ); } - inline void create_symlink( const wpath & to_ph, - const wpath & from_ph ) - { return create_symlink<wpath>( to_ph, from_ph ); } - - inline system::error_code create_symlink( const path & to_ph, - const path & from_ph, system::error_code & ec ) - { return create_symlink<path>( to_ph, from_ph, ec ); } - inline system::error_code create_symlink( const wpath & to_ph, - const wpath & from_ph, system::error_code & ec ) - { return create_symlink<wpath>( to_ph, from_ph, ec ); } - - inline bool remove( const path & ph ) - { return remove<path>( ph ); } - inline bool remove( const wpath & ph ) - { return remove<wpath>( ph ); } - - inline unsigned long remove_all( const path & ph ) - { return remove_all<path>( ph ); } - inline unsigned long remove_all( const wpath & ph ) - { return remove_all<wpath>( ph ); } - - inline void rename( const path & from_path, const path & to_path ) - { return rename<path>( from_path, to_path ); } - inline void rename( const wpath & from_path, const wpath & to_path ) - { return rename<wpath>( from_path, to_path ); } - - inline void copy_file( const path & from_path, const path & to_path ) - { return copy_file<path>( from_path, to_path ); } - inline void copy_file( const wpath & from_path, const wpath & to_path ) - { return copy_file<wpath>( from_path, to_path ); } - - inline path system_complete( const path & ph ) - { return system_complete<path>( ph ); } - inline wpath system_complete( const wpath & ph ) - { return system_complete<wpath>( ph ); } - - inline path complete( const path & ph, - const path & base/* = initial_path<path>()*/ ) - { return complete<path>( ph, base ); } - inline wpath complete( const wpath & ph, - const wpath & base/* = initial_path<wpath>()*/ ) - { return complete<wpath>( ph, base ); } - - inline path complete( const path & ph ) - { return complete<path>( ph, initial_path<path>() ); } - inline wpath complete( const wpath & ph ) - { return complete<wpath>( ph, initial_path<wpath>() ); } - - inline void last_write_time( const path & ph, const std::time_t new_time ) - { last_write_time<path>( ph, new_time ); } - inline void last_write_time( const wpath & ph, const std::time_t new_time ) - { last_write_time<wpath>( ph, new_time ); } - - inline void current_path( const path & ph ) - { current_path<path>( ph ); } - inline void current_path( const wpath & ph ) - { current_path<wpath>( ph ); } - -# endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY - - namespace detail - { - template<class Path> - bool remove_aux( const Path & ph, file_status f ) - { - if ( exists( f ) ) - { - system::error_code ec = remove_api( ph.external_file_string() ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::remove", ph, ec ) ); - return true; - } - return false; - } - - template<class Path> - unsigned long remove_all_aux( const Path & ph, file_status f ) - { - static const boost::filesystem::basic_directory_iterator<Path> end_itr; - unsigned long count = 1; - if ( !boost::filesystem::is_symlink( f ) // don't recurse symbolic links - && boost::filesystem::is_directory( f ) ) - { - for ( boost::filesystem::basic_directory_iterator<Path> itr( ph ); - itr != end_itr; ++itr ) - { - boost::system::error_code ec; - boost::filesystem::file_status fn = boost::filesystem::symlink_status( itr->path(), ec ); - if ( ec ) - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem:remove_all", ph, ec ) ); - count += remove_all_aux( itr->path(), fn ); - } - } - remove_aux( ph, f ); - return count; - } - -// test helper -------------------------------------------------------------// - - // not part of the documented interface because false positives are possible; - // there is no law that says that an OS that has large stat.st_size - // actually supports large file sizes. - BOOST_FILESYSTEM_DECL bool possible_large_file_size_support(); - -// directory_iterator helpers ----------------------------------------------// - -// forwarding functions avoid need for BOOST_FILESYSTEM_DECL for class -// basic_directory_iterator, and so avoid iterator_facade DLL template -// problems. They also overload to the proper external path character type. - - BOOST_FILESYSTEM_DECL system::error_code - dir_itr_first( void *& handle, -#if defined(BOOST_POSIX_API) - void *& buffer, -#endif - const std::string & dir_path, - std::string & target, file_status & fs, file_status & symlink_fs ); - // eof: return==0 && handle==0 - - BOOST_FILESYSTEM_DECL system::error_code - dir_itr_increment( void *& handle, -#if defined(BOOST_POSIX_API) - void *& buffer, -#endif - std::string & target, file_status & fs, file_status & symlink_fs ); - // eof: return==0 && handle==0 - - BOOST_FILESYSTEM_DECL system::error_code - dir_itr_close( void *& handle -#if defined(BOOST_POSIX_API) - , void *& buffer -#endif - ); - // Effects: none if handle==0, otherwise close handle, set handle=0 - -# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY) - BOOST_FILESYSTEM_DECL system::error_code - dir_itr_first( void *& handle, const std::wstring & ph, - std::wstring & target, file_status & fs, file_status & symlink_fs ); - BOOST_FILESYSTEM_DECL system::error_code - dir_itr_increment( void *& handle, std::wstring & target, - file_status & fs, file_status & symlink_fs ); -# endif - - template< class Path > - class dir_itr_imp - { - public: - basic_directory_entry<Path> m_directory_entry; - void * m_handle; -# ifdef BOOST_POSIX_API - void * m_buffer; // see dir_itr_increment implementation -# endif - dir_itr_imp() : m_handle(0) -# ifdef BOOST_POSIX_API - , m_buffer(0) -# endif - {} - - ~dir_itr_imp() { dir_itr_close( m_handle -#if defined(BOOST_POSIX_API) - , m_buffer -#endif - ); } - }; - - BOOST_FILESYSTEM_DECL system::error_code not_found_error(); - - } // namespace detail - -// basic_directory_iterator ------------------------------------------------// - - template< class Path > - class basic_directory_iterator - : public boost::iterator_facade< - basic_directory_iterator<Path>, - basic_directory_entry<Path>, - boost::single_pass_traversal_tag > - { - public: - typedef Path path_type; - - basic_directory_iterator(){} // creates the "end" iterator - - explicit basic_directory_iterator( const Path & dir_path ); - basic_directory_iterator( const Path & dir_path, system::error_code & ec ); - - private: - - // shared_ptr provides shallow-copy semantics required for InputIterators. - // m_imp.get()==0 indicates the end iterator. - boost::shared_ptr< detail::dir_itr_imp< Path > > m_imp; - - friend class boost::iterator_core_access; - - typename boost::iterator_facade< - basic_directory_iterator<Path>, - basic_directory_entry<Path>, - boost::single_pass_traversal_tag >::reference dereference() const - { - BOOST_ASSERT( m_imp.get() && "attempt to dereference end iterator" ); - return m_imp->m_directory_entry; - } - - void increment(); - - bool equal( const basic_directory_iterator & rhs ) const - { return m_imp == rhs.m_imp; } - - system::error_code m_init( const Path & dir_path ); - }; - - typedef basic_directory_iterator< path > directory_iterator; -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - typedef basic_directory_iterator< wpath > wdirectory_iterator; -# endif - - // basic_directory_iterator implementation ---------------------------// - - template<class Path> - system::error_code basic_directory_iterator<Path>::m_init( - const Path & dir_path ) - { - if ( dir_path.empty() ) - { - m_imp.reset(); - return detail::not_found_error(); - } - typename Path::external_string_type name; - file_status fs, symlink_fs; - system::error_code ec( detail::dir_itr_first( m_imp->m_handle, -#if defined(BOOST_POSIX_API) - m_imp->m_buffer, -#endif - dir_path.external_directory_string(), - name, fs, symlink_fs ) ); - - if ( ec ) - { - m_imp.reset(); - return ec; - } - - if ( m_imp->m_handle == 0 ) m_imp.reset(); // eof, so make end iterator - else // not eof - { - m_imp->m_directory_entry.assign( dir_path - / Path::traits_type::to_internal( name ), fs, symlink_fs ); - if ( name[0] == dot<Path>::value // dot or dot-dot - && (name.size() == 1 - || (name[1] == dot<Path>::value - && name.size() == 2)) ) - { increment(); } - } - return boost::system::error_code(); - } - - template<class Path> - basic_directory_iterator<Path>::basic_directory_iterator( - const Path & dir_path ) - : m_imp( new detail::dir_itr_imp<Path> ) - { - system::error_code ec( m_init(dir_path) ); - if ( ec ) - { - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::basic_directory_iterator constructor", - dir_path, ec ) ); - } - } - - template<class Path> - basic_directory_iterator<Path>::basic_directory_iterator( - const Path & dir_path, system::error_code & ec ) - : m_imp( new detail::dir_itr_imp<Path> ) - { - ec = m_init(dir_path); - } - - template<class Path> - void basic_directory_iterator<Path>::increment() - { - BOOST_ASSERT( m_imp.get() && "attempt to increment end iterator" ); - BOOST_ASSERT( m_imp->m_handle != 0 && "internal program error" ); - - typename Path::external_string_type name; - file_status fs, symlink_fs; - system::error_code ec; - - for (;;) - { - ec = detail::dir_itr_increment( m_imp->m_handle, -#if defined(BOOST_POSIX_API) - m_imp->m_buffer, -#endif - name, fs, symlink_fs ); - if ( ec ) - { - boost::throw_exception( basic_filesystem_error<Path>( - "boost::filesystem::basic_directory_iterator increment", - m_imp->m_directory_entry.path().parent_path(), ec ) ); - } - if ( m_imp->m_handle == 0 ) { m_imp.reset(); return; } // eof, make end - if ( !(name[0] == dot<Path>::value // !(dot or dot-dot) - && (name.size() == 1 - || (name[1] == dot<Path>::value - && name.size() == 2))) ) - { - m_imp->m_directory_entry.replace_filename( - Path::traits_type::to_internal( name ), fs, symlink_fs ); - return; - } - } - } - - // basic_directory_entry -----------------------------------------------// - - template<class Path> - class basic_directory_entry - { - public: - typedef Path path_type; - typedef typename Path::string_type string_type; - - // compiler generated copy-ctor, copy assignment, and destructor apply - - basic_directory_entry() {} - explicit basic_directory_entry( const path_type & p, - file_status st = file_status(), file_status symlink_st=file_status() ) - : m_path(p), m_status(st), m_symlink_status(symlink_st) - {} - - void assign( const path_type & p, - file_status st, file_status symlink_st ) - { m_path = p; m_status = st; m_symlink_status = symlink_st; } - - void replace_filename( const string_type & s, - file_status st, file_status symlink_st ) - { - m_path.remove_filename(); - m_path /= s; - m_status = st; - m_symlink_status = symlink_st; - } - -# ifndef BOOST_FILESYSTEM_NO_DEPRECATED - void replace_leaf( const string_type & s, - file_status st, file_status symlink_st ) - { replace_filename( s, st, symlink_st ); } -# endif - - const Path & path() const { return m_path; } - file_status status() const; - file_status status( system::error_code & ec ) const; - file_status symlink_status() const; - file_status symlink_status( system::error_code & ec ) const; - - // conversion simplifies the most common use of basic_directory_entry - operator const path_type &() const { return m_path; } - -# ifndef BOOST_FILESYSTEM_NO_DEPRECATED - // deprecated functions preserve common use cases in legacy code - typename Path::string_type filename() const - { - return path().filename(); - } - typename Path::string_type leaf() const - { - return path().filename(); - } - typename Path::string_type string() const - { - return path().string(); - } -# endif - - private: - path_type m_path; - mutable file_status m_status; // stat()-like - mutable file_status m_symlink_status; // lstat()-like - // note: m_symlink_status is not used by Windows implementation - - }; // basic_directory_status - - typedef basic_directory_entry<path> directory_entry; -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - typedef basic_directory_entry<wpath> wdirectory_entry; -# endif - - // basic_directory_entry implementation --------------------------------// - - template<class Path> - file_status - basic_directory_entry<Path>::status() const - { - if ( !status_known( m_status ) ) - { -# ifndef BOOST_WINDOWS_API - if ( status_known( m_symlink_status ) - && !is_symlink( m_symlink_status ) ) - { m_status = m_symlink_status; } - else { m_status = boost::filesystem::status( m_path ); } -# else - m_status = boost::filesystem::status( m_path ); -# endif - } - return m_status; - } - - template<class Path> - file_status - basic_directory_entry<Path>::status( system::error_code & ec ) const - { - if ( !status_known( m_status ) ) - { -# ifndef BOOST_WINDOWS_API - if ( status_known( m_symlink_status ) - && !is_symlink( m_symlink_status ) ) - { ec = boost::system::error_code();; m_status = m_symlink_status; } - else { m_status = boost::filesystem::status( m_path, ec ); } -# else - m_status = boost::filesystem::status( m_path, ec ); -# endif - } - else ec = boost::system::error_code();; - return m_status; - } - - template<class Path> - file_status - basic_directory_entry<Path>::symlink_status() const - { -# ifndef BOOST_WINDOWS_API - if ( !status_known( m_symlink_status ) ) - { m_symlink_status = boost::filesystem::symlink_status( m_path ); } - return m_symlink_status; -# else - return status(); -# endif - } - - template<class Path> - file_status - basic_directory_entry<Path>::symlink_status( system::error_code & ec ) const - { -# ifndef BOOST_WINDOWS_API - if ( !status_known( m_symlink_status ) ) - { m_symlink_status = boost::filesystem::symlink_status( m_path, ec ); } - else ec = boost::system::error_code();; - return m_symlink_status; -# else - return status( ec ); -# endif - } - } // namespace filesystem -} // namespace boost - -#undef BOOST_FS_FUNC - -#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas -#endif // BOOST_FILESYSTEM_OPERATIONS_HPP +#endif // BOOST_FILESYSTEM_OPERATIONSX_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/path.hpp b/3rdParty/Boost/src/boost/filesystem/path.hpp index 8f5eaa0..bf12174 100644 --- a/3rdParty/Boost/src/boost/filesystem/path.hpp +++ b/3rdParty/Boost/src/boost/filesystem/path.hpp @@ -1,1531 +1,32 @@ -// boost/filesystem/path.hpp -----------------------------------------------// +// boost/filesystem/path.hpp ---------------------------------------------------------// -// Copyright Beman Dawes 2002-2005 -// Copyright Vladimir Prus 2002 +// Copyright Beman Dawes 2010 -// 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) +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt -// See library home page at http://www.boost.org/libs/filesystem +// Library home page: http://www.boost.org/libs/filesystem -// basic_path's stem(), extension(), and replace_extension() are based on -// basename(), extension(), and change_extension() from the original -// filesystem/convenience.hpp header by Vladimir Prus. +//--------------------------------------------------------------------------------------// -//----------------------------------------------------------------------------// +#ifndef BOOST_FILESYSTEM_PATHX_HPP +#define BOOST_FILESYSTEM_PATHX_HPP -#ifndef BOOST_FILESYSTEM_PATH_HPP -#define BOOST_FILESYSTEM_PATH_HPP - -#include <boost/filesystem/config.hpp> -#include <boost/system/system_error.hpp> -#include <boost/iterator/iterator_facade.hpp> -#include <boost/throw_exception.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/type_traits/is_same.hpp> -#include <boost/static_assert.hpp> - -#include <string> -#include <algorithm> // for lexicographical_compare -#include <iosfwd> // needed by basic_path inserter and extractor -#include <stdexcept> -#include <cassert> - -# ifndef BOOST_FILESYSTEM_NARROW_ONLY -# include <locale> -# endif - -#include <boost/config/abi_prefix.hpp> // must be the last #include - -//----------------------------------------------------------------------------// - -namespace boost -{ - namespace BOOST_FILESYSTEM_NAMESPACE - { - template<class String, class Traits> class basic_path; - - struct path_traits; - typedef basic_path< std::string, path_traits > path; - - struct path_traits - { - typedef std::string internal_string_type; - typedef std::string external_string_type; - static external_string_type to_external( const path &, - const internal_string_type & src ) { return src; } - static internal_string_type to_internal( - const external_string_type & src ) { return src; } - }; - -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - - struct BOOST_FILESYSTEM_DECL wpath_traits; - - typedef basic_path< std::wstring, wpath_traits > wpath; - - struct BOOST_FILESYSTEM_DECL wpath_traits - { - typedef std::wstring internal_string_type; -# ifdef BOOST_WINDOWS_API - typedef std::wstring external_string_type; - static external_string_type to_external( const wpath &, - const internal_string_type & src ) { return src; } - static internal_string_type to_internal( - const external_string_type & src ) { return src; } -# else - typedef std::string external_string_type; - static external_string_type to_external( const wpath & ph, - const internal_string_type & src ); - static internal_string_type to_internal( - const external_string_type & src ); -# endif - static void imbue( const std::locale & loc ); - static bool imbue( const std::locale & loc, const std::nothrow_t & ); - }; - -# endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY - - // path traits ---------------------------------------------------------// - - template<class Path> struct is_basic_path - { BOOST_STATIC_CONSTANT( bool, value = false ); }; - template<> struct is_basic_path<path> - { BOOST_STATIC_CONSTANT( bool, value = true ); }; -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - template<> struct is_basic_path<wpath> - { BOOST_STATIC_CONSTANT( bool, value = true ); }; -# endif - - // These only have to be specialized if Path::string_type::value_type - // is not convertible from char, although specializations may eliminate - // compiler warnings. See ticket 2543. - template<class Path> struct slash - { BOOST_STATIC_CONSTANT( char, value = '/' ); }; - - template<class Path> struct dot - { BOOST_STATIC_CONSTANT( char, value = '.' ); }; - - template<class Path> struct colon - { BOOST_STATIC_CONSTANT( char, value = ':' ); }; - -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - template<> struct slash<wpath> - { BOOST_STATIC_CONSTANT( wchar_t, value = L'/' ); }; - template<> struct dot<wpath> - { BOOST_STATIC_CONSTANT( wchar_t, value = L'.' ); }; - template<> struct colon<wpath> - { BOOST_STATIC_CONSTANT( wchar_t, value = L':' ); }; -# endif - -# ifdef BOOST_WINDOWS_PATH - template<class Path> struct path_alt_separator - { BOOST_STATIC_CONSTANT( char, value = '\\' ); }; -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - template<> struct path_alt_separator<wpath> - { BOOST_STATIC_CONSTANT( wchar_t, value = L'\\' ); }; -# endif -# endif - - // workaround for VC++ 7.0 and earlier issues with nested classes - namespace detail - { - template<class Path> - class iterator_helper - { - public: - typedef typename Path::iterator iterator; - static void do_increment( iterator & ph ); - static void do_decrement( iterator & ph ); - }; - } - - // basic_path ----------------------------------------------------------// - - template<class String, class Traits> - class basic_path - { - // invariant: m_path valid according to the portable generic path grammar - - // validate template arguments -// TODO: get these working -// BOOST_STATIC_ASSERT( ::boost::is_same<String,typename Traits::internal_string_type>::value ); -// BOOST_STATIC_ASSERT( ::boost::is_same<typename Traits::external_string_type,std::string>::value || ::boost::is_same<typename Traits::external_string_type,std::wstring>::value ); - - public: - // compiler generates copy constructor and copy assignment - - typedef basic_path<String, Traits> path_type; - typedef String string_type; - typedef typename String::value_type value_type; - typedef Traits traits_type; - typedef typename Traits::external_string_type external_string_type; - - // constructors/destructor - basic_path() {} - basic_path( const string_type & s ) { operator/=( s ); } - basic_path( const value_type * s ) { operator/=( s ); } -# ifndef BOOST_NO_MEMBER_TEMPLATES - template <class InputIterator> - basic_path( InputIterator first, InputIterator last ) - { append( first, last ); } -# endif - ~basic_path() {} - - // assignments - basic_path & operator=( const string_type & s ) - { -# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310) - m_path.clear(); -# else - m_path.erase( m_path.begin(), m_path.end() ); -# endif - operator/=( s ); - return *this; - } - basic_path & operator=( const value_type * s ) - { -# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310) - m_path.clear(); -# else - m_path.erase( m_path.begin(), m_path.end() ); -# endif - operator/=( s ); - return *this; - } -# ifndef BOOST_NO_MEMBER_TEMPLATES - template <class InputIterator> - basic_path & assign( InputIterator first, InputIterator last ) - { m_path.clear(); append( first, last ); return *this; } -# endif - - // modifiers - basic_path & operator/=( const basic_path & rhs ) { return operator /=( rhs.string().c_str() ); } - basic_path & operator/=( const string_type & rhs ) { return operator /=( rhs.c_str() ); } - basic_path & operator/=( const value_type * s ); -# ifndef BOOST_NO_MEMBER_TEMPLATES - template <class InputIterator> - basic_path & append( InputIterator first, InputIterator last ); -# endif - - void clear() - { -# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310) - m_path.clear(); -# else - m_path.erase( m_path.begin(), m_path.end() ); -# endif - } - - void swap( basic_path & rhs ) - { - m_path.swap( rhs.m_path ); -# ifdef BOOST_CYGWIN_PATH - std::swap( m_cygwin_root, rhs.m_cygwin_root ); -# endif - } - - basic_path & remove_filename(); - basic_path & replace_extension( const string_type & new_extension = string_type() ); - -# ifndef BOOST_FILESYSTEM_NO_DEPRECATED - basic_path & remove_leaf() { return remove_filename(); } -# endif - - // observers - const string_type & string() const { return m_path; } - const string_type file_string() const; - const string_type directory_string() const { return file_string(); } - - const external_string_type external_file_string() const { return Traits::to_external( *this, file_string() ); } - const external_string_type external_directory_string() const { return Traits::to_external( *this, directory_string() ); } - - basic_path root_path() const; - string_type root_name() const; - string_type root_directory() const; - basic_path relative_path() const; - basic_path parent_path() const; - string_type filename() const; - string_type stem() const; - string_type extension() const; - -# ifndef BOOST_FILESYSTEM_NO_DEPRECATED - string_type leaf() const { return filename(); } - basic_path branch_path() const { return parent_path(); } - bool has_leaf() const { return !m_path.empty(); } - bool has_branch_path() const { return !parent_path().empty(); } -# endif - - bool empty() const { return m_path.empty(); } // name consistent with std containers - bool is_complete() const; - bool has_root_path() const; - bool has_root_name() const; - bool has_root_directory() const; - bool has_relative_path() const { return !relative_path().empty(); } - bool has_filename() const { return !m_path.empty(); } - bool has_parent_path() const { return !parent_path().empty(); } - - // iterators - class iterator : public boost::iterator_facade< - iterator, - string_type const, - boost::bidirectional_traversal_tag > - { - private: - friend class boost::iterator_core_access; - friend class boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits>; - - const string_type & dereference() const - { return m_name; } - bool equal( const iterator & rhs ) const - { return m_path_ptr == rhs.m_path_ptr && m_pos == rhs.m_pos; } - - friend class boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>; - - void increment() - { - boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>::do_increment( - *this ); - } - void decrement() - { - boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>::do_decrement( - *this ); - } - - string_type m_name; // current element - const basic_path * m_path_ptr; // path being iterated over - typename string_type::size_type m_pos; // position of name in - // path_ptr->string(). The - // end() iterator is indicated by - // pos == path_ptr->m_path.size() - }; // iterator - - typedef iterator const_iterator; - - iterator begin() const; - iterator end() const; - - private: - // Note: This is an implementation for POSIX and Windows, where there - // are only minor differences between generic and native path grammars. - // Private members might be quite different in other implementations, - // particularly where there were wide differences between portable and - // native path formats, or between file_string() and - // directory_string() formats, or simply that the implementation - // was willing expend additional memory to achieve greater speed for - // some operations at the expense of other operations. - - string_type m_path; // invariant: portable path grammar - // on Windows, backslashes converted to slashes - -# ifdef BOOST_CYGWIN_PATH - bool m_cygwin_root; // if present, m_path[0] was slash. note: initialization - // done by append -# endif - - void m_append_separator_if_needed(); - void m_append( value_type value ); // converts Windows alt_separator - - // Was qualified; como433beta8 reports: - // warning #427-D: qualified name is not allowed in member declaration - friend class iterator; - friend class boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>; - - // Deprecated features ease transition for existing code. Don't use these - // in new code. -# ifndef BOOST_FILESYSTEM_NO_DEPRECATED - public: - typedef bool (*name_check)( const std::string & name ); - basic_path( const string_type & str, name_check ) { operator/=( str ); } - basic_path( const typename string_type::value_type * s, name_check ) - { operator/=( s );} - string_type native_file_string() const { return file_string(); } - string_type native_directory_string() const { return directory_string(); } - static bool default_name_check_writable() { return false; } - static void default_name_check( name_check ) {} - static name_check default_name_check() { return 0; } - basic_path & canonize(); - basic_path & normalize(); +# if defined(BOOST_FILESYSTEM_VERSION) \ + && BOOST_FILESYSTEM_VERSION != 2 && BOOST_FILESYSTEM_VERSION != 3 +# error BOOST_FILESYSTEM_VERSION defined, but not as 2 or 3 # endif - }; - // basic_path non-member functions ---------------------------------------// - - template< class String, class Traits > - inline void swap( basic_path<String, Traits> & lhs, - basic_path<String, Traits> & rhs ) { lhs.swap( rhs ); } - - template< class String, class Traits > - bool operator<( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) - { - return std::lexicographical_compare( - lhs.begin(), lhs.end(), rhs.begin(), rhs.end() ); - } - - template< class String, class Traits > - bool operator<( const typename basic_path<String, Traits>::string_type::value_type * lhs, - const basic_path<String, Traits> & rhs ) - { - basic_path<String, Traits> tmp( lhs ); - return std::lexicographical_compare( - tmp.begin(), tmp.end(), rhs.begin(), rhs.end() ); - } - - template< class String, class Traits > - bool operator<( const typename basic_path<String, Traits>::string_type & lhs, - const basic_path<String, Traits> & rhs ) - { - basic_path<String, Traits> tmp( lhs ); - return std::lexicographical_compare( - tmp.begin(), tmp.end(), rhs.begin(), rhs.end() ); - } - - template< class String, class Traits > - bool operator<( const basic_path<String, Traits> & lhs, - const typename basic_path<String, Traits>::string_type::value_type * rhs ) - { - basic_path<String, Traits> tmp( rhs ); - return std::lexicographical_compare( - lhs.begin(), lhs.end(), tmp.begin(), tmp.end() ); - } - - template< class String, class Traits > - bool operator<( const basic_path<String, Traits> & lhs, - const typename basic_path<String, Traits>::string_type & rhs ) - { - basic_path<String, Traits> tmp( rhs ); - return std::lexicographical_compare( - lhs.begin(), lhs.end(), tmp.begin(), tmp.end() ); - } - - // operator == uses hand-written compare rather than !(lhs < rhs) && !(rhs < lhs) - // because the result is the same yet the direct compare is much more efficient - // than lexicographical_compare, which would also be called twice. - - template< class String, class Traits > - inline bool operator==( const basic_path<String, Traits> & lhs, - const typename basic_path<String, Traits>::string_type::value_type * rhs ) - { - typedef typename - boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> path_type; - const typename path_type::string_type::value_type * l (lhs.string().c_str()); - while ( (*l == *rhs -# ifdef BOOST_WINDOWS_PATH - || (*l == path_alt_separator<path_type>::value && *rhs == slash<path_type>::value) - || (*l == slash<path_type>::value && *rhs == path_alt_separator<path_type>::value) -# endif - ) && *l ) { ++l; ++rhs; } - return *l == *rhs -# ifdef BOOST_WINDOWS_PATH - || (*l == path_alt_separator<path_type>::value && *rhs == slash<path_type>::value) - || (*l == slash<path_type>::value && *rhs == path_alt_separator<path_type>::value) -# endif - ; - } - - template< class String, class Traits > - inline bool operator==( const basic_path<String, Traits> & lhs, - const basic_path<String, Traits> & rhs ) - { - return lhs == rhs.string().c_str(); - } - - template< class String, class Traits > - inline bool operator==( const typename basic_path<String, Traits>::string_type::value_type * lhs, - const basic_path<String, Traits> & rhs ) - { - return rhs == lhs; - } - - template< class String, class Traits > - inline bool operator==( const typename basic_path<String, Traits>::string_type & lhs, - const basic_path<String, Traits> & rhs ) - { - return rhs == lhs.c_str(); - } - - template< class String, class Traits > - inline bool operator==( const basic_path<String, Traits> & lhs, - const typename basic_path<String, Traits>::string_type & rhs ) - { - return lhs == rhs.c_str(); - } - - template< class String, class Traits > - inline bool operator!=( const basic_path<String, Traits> & lhs, - const basic_path<String, Traits> & rhs ) - { return !(lhs == rhs); } - - template< class String, class Traits > - inline bool operator!=( const typename basic_path<String, - Traits>::string_type::value_type * lhs, - const basic_path<String, Traits> & rhs ) - { return !(lhs == rhs); } - - template< class String, class Traits > - inline bool operator!=( const typename basic_path<String, Traits>::string_type & lhs, - const basic_path<String, Traits> & rhs ) - { return !(lhs == rhs); } - - template< class String, class Traits > - inline bool operator!=( const basic_path<String, Traits> & lhs, - const typename basic_path<String, Traits>::string_type::value_type * rhs ) - { return !(lhs == rhs); } - - template< class String, class Traits > - inline bool operator!=( const basic_path<String, Traits> & lhs, - const typename basic_path<String, Traits>::string_type & rhs ) - { return !(lhs == rhs); } - - template< class String, class Traits > - inline bool operator>( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return rhs < lhs; } - - template< class String, class Traits > - inline bool operator>( const typename basic_path<String, Traits>::string_type::value_type * lhs, - const basic_path<String, Traits> & rhs ) { return rhs < basic_path<String, Traits>(lhs); } - - template< class String, class Traits > - inline bool operator>( const typename basic_path<String, Traits>::string_type & lhs, - const basic_path<String, Traits> & rhs ) { return rhs < basic_path<String, Traits>(lhs); } - - template< class String, class Traits > - inline bool operator>( const basic_path<String, Traits> & lhs, - const typename basic_path<String, Traits>::string_type::value_type * rhs ) - { return basic_path<String, Traits>(rhs) < lhs; } - - template< class String, class Traits > - inline bool operator>( const basic_path<String, Traits> & lhs, - const typename basic_path<String, Traits>::string_type & rhs ) - { return basic_path<String, Traits>(rhs) < lhs; } - - template< class String, class Traits > - inline bool operator<=( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return !(rhs < lhs); } - - template< class String, class Traits > - inline bool operator<=( const typename basic_path<String, Traits>::string_type::value_type * lhs, - const basic_path<String, Traits> & rhs ) { return !(rhs < basic_path<String, Traits>(lhs)); } - - template< class String, class Traits > - inline bool operator<=( const typename basic_path<String, Traits>::string_type & lhs, - const basic_path<String, Traits> & rhs ) { return !(rhs < basic_path<String, Traits>(lhs)); } - - template< class String, class Traits > - inline bool operator<=( const basic_path<String, Traits> & lhs, - const typename basic_path<String, Traits>::string_type::value_type * rhs ) - { return !(basic_path<String, Traits>(rhs) < lhs); } - - template< class String, class Traits > - inline bool operator<=( const basic_path<String, Traits> & lhs, - const typename basic_path<String, Traits>::string_type & rhs ) - { return !(basic_path<String, Traits>(rhs) < lhs); } - - template< class String, class Traits > - inline bool operator>=( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return !(lhs < rhs); } - - template< class String, class Traits > - inline bool operator>=( const typename basic_path<String, Traits>::string_type::value_type * lhs, - const basic_path<String, Traits> & rhs ) { return !(lhs < basic_path<String, Traits>(rhs)); } - - template< class String, class Traits > - inline bool operator>=( const typename basic_path<String, Traits>::string_type & lhs, - const basic_path<String, Traits> & rhs ) { return !(lhs < basic_path<String, Traits>(rhs)); } - - template< class String, class Traits > - inline bool operator>=( const basic_path<String, Traits> & lhs, - const typename basic_path<String, Traits>::string_type::value_type * rhs ) - { return !(basic_path<String, Traits>(lhs) < rhs); } - - template< class String, class Traits > - inline bool operator>=( const basic_path<String, Traits> & lhs, - const typename basic_path<String, Traits>::string_type & rhs ) - { return !(basic_path<String, Traits>(lhs) < rhs); } - - // operator / - - template< class String, class Traits > - inline basic_path<String, Traits> operator/( - const basic_path<String, Traits> & lhs, - const basic_path<String, Traits> & rhs ) - { return basic_path<String, Traits>( lhs ) /= rhs; } - - template< class String, class Traits > - inline basic_path<String, Traits> operator/( - const basic_path<String, Traits> & lhs, - const typename String::value_type * rhs ) - { return basic_path<String, Traits>( lhs ) /= - basic_path<String, Traits>( rhs ); } - - template< class String, class Traits > - inline basic_path<String, Traits> operator/( - const basic_path<String, Traits> & lhs, const String & rhs ) - { return basic_path<String, Traits>( lhs ) /= - basic_path<String, Traits>( rhs ); } - - template< class String, class Traits > - inline basic_path<String, Traits> operator/( - const typename String::value_type * lhs, - const basic_path<String, Traits> & rhs ) - { return basic_path<String, Traits>( lhs ) /= rhs; } - - template< class String, class Traits > - inline basic_path<String, Traits> operator/( - const String & lhs, const basic_path<String, Traits> & rhs ) - { return basic_path<String, Traits>( lhs ) /= rhs; } - - // inserters and extractors --------------------------------------------// - -// bypass VC++ 7.0 and earlier, and broken Borland compilers -# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && !BOOST_WORKAROUND(__BORLANDC__, < 0x610) - template< class Path > - std::basic_ostream< typename Path::string_type::value_type, - typename Path::string_type::traits_type > & - operator<< - ( std::basic_ostream< typename Path::string_type::value_type, - typename Path::string_type::traits_type >& os, const Path & ph ) - { - os << ph.string(); - return os; - } - - template< class Path > - std::basic_istream< typename Path::string_type::value_type, - typename Path::string_type::traits_type > & - operator>> - ( std::basic_istream< typename Path::string_type::value_type, - typename Path::string_type::traits_type >& is, Path & ph ) - { - typename Path::string_type str; - is >> str; - ph = str; - return is; - } -# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) - template< class String, class Traits > - std::basic_ostream< BOOST_DEDUCED_TYPENAME String::value_type, - BOOST_DEDUCED_TYPENAME String::traits_type > & - operator<< - ( std::basic_ostream< BOOST_DEDUCED_TYPENAME String::value_type, - BOOST_DEDUCED_TYPENAME String::traits_type >& os, - const basic_path< String, Traits > & ph ) - { - os << ph.string(); - return os; - } - - template< class String, class Traits > - std::basic_istream< BOOST_DEDUCED_TYPENAME String::value_type, - BOOST_DEDUCED_TYPENAME String::traits_type > & - operator>> - ( std::basic_istream< BOOST_DEDUCED_TYPENAME String::value_type, - BOOST_DEDUCED_TYPENAME String::traits_type> & is, - basic_path< String, Traits > & ph ) - { - String str; - is >> str; - ph = str; - return is; - } -# endif - - // basic_filesystem_error helpers --------------------------------------// - - // Originally choice of implementation was done via specialization of - // basic_filesystem_error::what(). Several compilers (GCC, aCC, etc.) - // couldn't handle that, so the choice is now accomplished by overloading. - - namespace detail - { - // BOOST_FILESYSTEM_DECL version works for VC++ but not GCC. Go figure! - inline - const char * what( const char * sys_err_what, - const path & path1_arg, const path & path2_arg, std::string & target ) - { - try - { - if ( target.empty() ) - { - target = sys_err_what; - if ( !path1_arg.empty() ) - { - target += ": \""; - target += path1_arg.file_string(); - target += "\""; - } - if ( !path2_arg.empty() ) - { - target += ", \""; - target += path2_arg.file_string(); - target += "\""; - } - } - return target.c_str(); - } - catch (...) - { - return sys_err_what; - } - } - - template<class Path> - const char * what( const char * sys_err_what, - const Path & /*path1_arg*/, const Path & /*path2_arg*/, std::string & /*target*/ ) - { - return sys_err_what; - } - } - - // basic_filesystem_error ----------------------------------------------// - - template<class Path> - class basic_filesystem_error : public system::system_error - { - // see http://www.boost.org/more/error_handling.html for design rationale - public: - // compiler generates copy constructor and copy assignment - - typedef Path path_type; - - basic_filesystem_error( const std::string & what_arg, - system::error_code ec ); - - basic_filesystem_error( const std::string & what_arg, - const path_type & path1_arg, system::error_code ec ); - - basic_filesystem_error( const std::string & what_arg, const path_type & path1_arg, - const path_type & path2_arg, system::error_code ec ); - - ~basic_filesystem_error() throw() {} - - const path_type & path1() const - { - static const path_type empty_path; - return m_imp_ptr.get() ? m_imp_ptr->m_path1 : empty_path ; - } - const path_type & path2() const - { - static const path_type empty_path; - return m_imp_ptr.get() ? m_imp_ptr->m_path2 : empty_path ; - } - - const char * what() const throw() - { - if ( !m_imp_ptr.get() ) - return system::system_error::what(); - return detail::what( system::system_error::what(), m_imp_ptr->m_path1, - m_imp_ptr->m_path2, m_imp_ptr->m_what ); - } - - private: - struct m_imp - { - path_type m_path1; // may be empty() - path_type m_path2; // may be empty() - std::string m_what; // not built until needed - }; - boost::shared_ptr<m_imp> m_imp_ptr; - }; - - typedef basic_filesystem_error<path> filesystem_error; - -# ifndef BOOST_FILESYSTEM_NARROW_ONLY - typedef basic_filesystem_error<wpath> wfilesystem_error; +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 2 # endif - // path::name_checks -----------------------------------------------------// - - BOOST_FILESYSTEM_DECL bool portable_posix_name( const std::string & name ); - BOOST_FILESYSTEM_DECL bool windows_name( const std::string & name ); - BOOST_FILESYSTEM_DECL bool portable_name( const std::string & name ); - BOOST_FILESYSTEM_DECL bool portable_directory_name( const std::string & name ); - BOOST_FILESYSTEM_DECL bool portable_file_name( const std::string & name ); - BOOST_FILESYSTEM_DECL bool native( const std::string & name ); - inline bool no_check( const std::string & ) - { return true; } - -// implementation -----------------------------------------------------------// +#if BOOST_FILESYSTEM_VERSION == 2 +# include <boost/filesystem/v2/path.hpp> - namespace detail - { - - // is_separator helper ------------------------------------------------// - - template<class Path> - inline bool is_separator( typename Path::string_type::value_type c ) - { - return c == slash<Path>::value -# ifdef BOOST_WINDOWS_PATH - || c == path_alt_separator<Path>::value -# endif - ; - } - - // filename_pos helper ----------------------------------------------------// - - template<class String, class Traits> - typename String::size_type filename_pos( - const String & str, // precondition: portable generic path grammar - typename String::size_type end_pos ) // end_pos is past-the-end position - // return 0 if str itself is filename (or empty) - { - typedef typename - boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> path_type; - - // case: "//" - if ( end_pos == 2 - && str[0] == slash<path_type>::value - && str[1] == slash<path_type>::value ) return 0; - - // case: ends in "/" - if ( end_pos && str[end_pos-1] == slash<path_type>::value ) - return end_pos-1; - - // set pos to start of last element - typename String::size_type pos( - str.find_last_of( slash<path_type>::value, end_pos-1 ) ); -# ifdef BOOST_WINDOWS_PATH - if ( pos == String::npos ) - pos = str.find_last_of( path_alt_separator<path_type>::value, end_pos-1 ); - if ( pos == String::npos ) - pos = str.find_last_of( colon<path_type>::value, end_pos-2 ); -# endif - - return ( pos == String::npos // path itself must be a filename (or empty) - || (pos == 1 && str[0] == slash<path_type>::value) ) // or net - ? 0 // so filename is entire string - : pos + 1; // or starts after delimiter - } - - // first_element helper -----------------------------------------------// - // sets pos and len of first element, excluding extra separators - // if src.empty(), sets pos,len, to 0,0. - - template<class String, class Traits> - void first_element( - const String & src, // precondition: portable generic path grammar - typename String::size_type & element_pos, - typename String::size_type & element_size, -# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1310 ) // VC++ 7.1 - typename String::size_type size = String::npos -# else - typename String::size_type size = -1 -# endif - ) - { - if ( size == String::npos ) size = src.size(); - element_pos = 0; - element_size = 0; - if ( src.empty() ) return; - - typedef typename boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> path_type; - - typename String::size_type cur(0); - - // deal with // [network] - if ( size >= 2 && src[0] == slash<path_type>::value - && src[1] == slash<path_type>::value - && (size == 2 - || src[2] != slash<path_type>::value) ) - { - cur += 2; - element_size += 2; - } - - // leading (not non-network) separator - else if ( src[0] == slash<path_type>::value ) - { - ++element_size; - // bypass extra leading separators - while ( cur+1 < size - && src[cur+1] == slash<path_type>::value ) - { - ++cur; - ++element_pos; - } - return; - } - - // at this point, we have either a plain name, a network name, - // or (on Windows only) a device name - - // find the end - while ( cur < size -# ifdef BOOST_WINDOWS_PATH - && src[cur] != colon<path_type>::value -# endif - && src[cur] != slash<path_type>::value ) - { - ++cur; - ++element_size; - } - -# ifdef BOOST_WINDOWS_PATH - if ( cur == size ) return; - // include device delimiter - if ( src[cur] == colon<path_type>::value ) - { ++element_size; } -# endif - - return; - } - - // root_directory_start helper ----------------------------------------// - - template<class String, class Traits> - typename String::size_type root_directory_start( - const String & s, // precondition: portable generic path grammar - typename String::size_type size ) - // return npos if no root_directory found - { - typedef typename boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> path_type; - -# ifdef BOOST_WINDOWS_PATH - // case "c:/" - if ( size > 2 - && s[1] == colon<path_type>::value - && s[2] == slash<path_type>::value ) return 2; -# endif - - // case "//" - if ( size == 2 - && s[0] == slash<path_type>::value - && s[1] == slash<path_type>::value ) return String::npos; - - // case "//net {/}" - if ( size > 3 - && s[0] == slash<path_type>::value - && s[1] == slash<path_type>::value - && s[2] != slash<path_type>::value ) - { - typename String::size_type pos( - s.find( slash<path_type>::value, 2 ) ); - return pos < size ? pos : String::npos; - } - - // case "/" - if ( size > 0 && s[0] == slash<path_type>::value ) return 0; - - return String::npos; - } - - // is_non_root_slash helper -------------------------------------------// - - template<class String, class Traits> - bool is_non_root_slash( const String & str, - typename String::size_type pos ) // pos is position of the slash - { - typedef typename - boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> - path_type; - - assert( !str.empty() && str[pos] == slash<path_type>::value - && "precondition violation" ); - - // subsequent logic expects pos to be for leftmost slash of a set - while ( pos > 0 && str[pos-1] == slash<path_type>::value ) - --pos; - - return pos != 0 - && (pos <= 2 || str[1] != slash<path_type>::value - || str.find( slash<path_type>::value, 2 ) != pos) -# ifdef BOOST_WINDOWS_PATH - && (pos !=2 || str[1] != colon<path_type>::value) -# endif - ; - } - } // namespace detail - - // decomposition functions ----------------------------------------------// - - template<class String, class Traits> - String basic_path<String, Traits>::filename() const - { - typename String::size_type end_pos( - detail::filename_pos<String, Traits>( m_path, m_path.size() ) ); - return (m_path.size() - && end_pos - && m_path[end_pos] == slash<path_type>::value - && detail::is_non_root_slash< String, Traits >(m_path, end_pos)) - ? String( 1, dot<path_type>::value ) - : m_path.substr( end_pos ); - } - - template<class String, class Traits> - String basic_path<String, Traits>::stem() const - { - string_type name = filename(); - typename string_type::size_type n = name.rfind(dot<path_type>::value); - return name.substr(0, n); - } - - template<class String, class Traits> - String basic_path<String, Traits>::extension() const - { - string_type name = filename(); - typename string_type::size_type n = name.rfind(dot<path_type>::value); - if (n != string_type::npos) - return name.substr(n); - else - return string_type(); - } - - template<class String, class Traits> - basic_path<String, Traits> basic_path<String, Traits>::parent_path() const - { - typename String::size_type end_pos( - detail::filename_pos<String, Traits>( m_path, m_path.size() ) ); - - bool filename_was_separator( m_path.size() - && m_path[end_pos] == slash<path_type>::value ); - - // skip separators unless root directory - typename string_type::size_type root_dir_pos( detail::root_directory_start - <string_type, traits_type>( m_path, end_pos ) ); - for ( ; - end_pos > 0 - && (end_pos-1) != root_dir_pos - && m_path[end_pos-1] == slash<path_type>::value - ; - --end_pos ) {} - - return (end_pos == 1 && root_dir_pos == 0 && filename_was_separator) - ? path_type() - : path_type( m_path.substr( 0, end_pos ) ); - } - - template<class String, class Traits> - basic_path<String, Traits> basic_path<String, Traits>::relative_path() const - { - iterator itr( begin() ); - for ( ; itr.m_pos != m_path.size() - && (itr.m_name[0] == slash<path_type>::value -# ifdef BOOST_WINDOWS_PATH - || itr.m_name[itr.m_name.size()-1] - == colon<path_type>::value -# endif - ); ++itr ) {} - - return basic_path<String, Traits>( m_path.substr( itr.m_pos ) ); - } - - template<class String, class Traits> - String basic_path<String, Traits>::root_name() const - { - iterator itr( begin() ); - - return ( itr.m_pos != m_path.size() - && ( - ( itr.m_name.size() > 1 - && itr.m_name[0] == slash<path_type>::value - && itr.m_name[1] == slash<path_type>::value - ) -# ifdef BOOST_WINDOWS_PATH - || itr.m_name[itr.m_name.size()-1] - == colon<path_type>::value -# endif - ) ) - ? *itr - : String(); - } - - template<class String, class Traits> - String basic_path<String, Traits>::root_directory() const - { - typename string_type::size_type start( - detail::root_directory_start<String, Traits>( m_path, m_path.size() ) ); - - return start == string_type::npos - ? string_type() - : m_path.substr( start, 1 ); - } - - template<class String, class Traits> - basic_path<String, Traits> basic_path<String, Traits>::root_path() const - { - // even on POSIX, root_name() is non-empty() on network paths - return basic_path<String, Traits>( root_name() ) /= root_directory(); - } - - // path query functions -------------------------------------------------// - - template<class String, class Traits> - inline bool basic_path<String, Traits>::is_complete() const - { -# ifdef BOOST_WINDOWS_PATH - return has_root_name() && has_root_directory(); -# else - return has_root_directory(); -# endif - } - - template<class String, class Traits> - inline bool basic_path<String, Traits>::has_root_path() const - { - return !root_path().empty(); - } - - template<class String, class Traits> - inline bool basic_path<String, Traits>::has_root_name() const - { - return !root_name().empty(); - } - - template<class String, class Traits> - inline bool basic_path<String, Traits>::has_root_directory() const - { - return !root_directory().empty(); - } - - // append ---------------------------------------------------------------// - - template<class String, class Traits> - void basic_path<String, Traits>::m_append_separator_if_needed() - // requires: !empty() - { - if ( -# ifdef BOOST_WINDOWS_PATH - *(m_path.end()-1) != colon<path_type>::value && -# endif - *(m_path.end()-1) != slash<path_type>::value ) - { - m_path += slash<path_type>::value; - } - } - - template<class String, class Traits> - void basic_path<String, Traits>::m_append( value_type value ) - { -# ifdef BOOST_CYGWIN_PATH - if ( m_path.empty() ) m_cygwin_root = (value == slash<path_type>::value); -# endif - -# ifdef BOOST_WINDOWS_PATH - // for BOOST_WINDOWS_PATH, convert alt_separator ('\') to separator ('/') - m_path += ( value == path_alt_separator<path_type>::value - ? slash<path_type>::value - : value ); -# else - m_path += value; -# endif - } - - // except that it wouldn't work for BOOST_NO_MEMBER_TEMPLATES compilers, - // the append() member template could replace this code. - template<class String, class Traits> - basic_path<String, Traits> & basic_path<String, Traits>::operator /= - ( const value_type * next_p ) - { - // ignore escape sequence on POSIX or Windows - if ( *next_p == slash<path_type>::value - && *(next_p+1) == slash<path_type>::value - && *(next_p+2) == colon<path_type>::value ) next_p += 3; - - // append slash<path_type>::value if needed - if ( !empty() && *next_p != 0 - && !detail::is_separator<path_type>( *next_p ) ) - { m_append_separator_if_needed(); } - - for ( ; *next_p != 0; ++next_p ) m_append( *next_p ); - return *this; - } - -# ifndef BOOST_NO_MEMBER_TEMPLATES - template<class String, class Traits> template <class InputIterator> - basic_path<String, Traits> & basic_path<String, Traits>::append( - InputIterator first, InputIterator last ) - { - // append slash<path_type>::value if needed - if ( !empty() && first != last - && !detail::is_separator<path_type>( *first ) ) - { m_append_separator_if_needed(); } - - // song-and-dance to avoid violating InputIterator requirements - // (which prohibit lookahead) in detecting a possible escape sequence - // (escape sequences are simply ignored on POSIX and Windows) - bool was_escape_sequence(true); - std::size_t append_count(0); - typename String::size_type initial_pos( m_path.size() ); - - for ( ; first != last && *first; ++first ) - { - if ( append_count == 0 && *first != slash<path_type>::value ) - was_escape_sequence = false; - if ( append_count == 1 && *first != slash<path_type>::value ) - was_escape_sequence = false; - if ( append_count == 2 && *first != colon<path_type>::value ) - was_escape_sequence = false; - m_append( *first ); - ++append_count; - } - - // erase escape sequence if any - if ( was_escape_sequence && append_count >= 3 ) - m_path.erase( initial_pos, 3 ); - - return *this; - } -# endif - -# ifndef BOOST_FILESYSTEM_NO_DEPRECATED - - // canonize ------------------------------------------------------------// - - template<class String, class Traits> - basic_path<String, Traits> & basic_path<String, Traits>::canonize() - { - static const typename string_type::value_type dot_str[] - = { dot<path_type>::value, 0 }; - - if ( m_path.empty() ) return *this; - - path_type temp; - - for ( iterator itr( begin() ); itr != end(); ++itr ) - { - temp /= *itr; - }; - - if ( temp.empty() ) temp /= dot_str; - m_path = temp.m_path; - return *this; - } - - // normalize ------------------------------------------------------------// - - template<class String, class Traits> - basic_path<String, Traits> & basic_path<String, Traits>::normalize() - { - static const typename string_type::value_type dot_str[] - = { dot<path_type>::value, 0 }; - - if ( m_path.empty() ) return *this; - - path_type temp; - iterator start( begin() ); - iterator last( end() ); - iterator stop( last-- ); - for ( iterator itr( start ); itr != stop; ++itr ) - { - // ignore "." except at start and last - if ( itr->size() == 1 - && (*itr)[0] == dot<path_type>::value - && itr != start - && itr != last ) continue; - - // ignore a name and following ".." - if ( !temp.empty() - && itr->size() == 2 - && (*itr)[0] == dot<path_type>::value - && (*itr)[1] == dot<path_type>::value ) // dot dot - { - string_type lf( temp.filename() ); - if ( lf.size() > 0 - && (lf.size() != 1 - || (lf[0] != dot<path_type>::value - && lf[0] != slash<path_type>::value)) - && (lf.size() != 2 - || (lf[0] != dot<path_type>::value - && lf[1] != dot<path_type>::value -# ifdef BOOST_WINDOWS_PATH - && lf[1] != colon<path_type>::value -# endif - ) - ) - ) - { - temp.remove_filename(); - // if not root directory, must also remove "/" if any - if ( temp.m_path.size() > 0 - && temp.m_path[temp.m_path.size()-1] - == slash<path_type>::value ) - { - typename string_type::size_type rds( - detail::root_directory_start<String,Traits>( temp.m_path, - temp.m_path.size() ) ); - if ( rds == string_type::npos - || rds != temp.m_path.size()-1 ) - { temp.m_path.erase( temp.m_path.size()-1 ); } - } - - iterator next( itr ); - if ( temp.empty() && ++next != stop - && next == last && *last == dot_str ) temp /= dot_str; - continue; - } - } - - temp /= *itr; - }; - - if ( temp.empty() ) temp /= dot_str; - m_path = temp.m_path; - return *this; - } +# else +# include <boost/filesystem/v3/path.hpp> # endif - // modifiers ------------------------------------------------------------// - - template<class String, class Traits> - basic_path<String, Traits> & basic_path<String, Traits>::remove_filename() - { - m_path.erase( - detail::filename_pos<String, Traits>( m_path, m_path.size() ) ); - return *this; - } - - template<class String, class Traits> - basic_path<String, Traits> & - basic_path<String, Traits>::replace_extension( const string_type & new_ext ) - { - // erase existing extension if any - string_type old_ext = extension(); - if ( !old_ext.empty() ) - m_path.erase( m_path.size() - old_ext.size() ); - - if ( !new_ext.empty() && new_ext[0] != dot<path_type>::value ) - m_path += dot<path_type>::value; - - m_path += new_ext; - - return *this; - } - - - // path conversion functions --------------------------------------------// - - template<class String, class Traits> - const String - basic_path<String, Traits>::file_string() const - { -# ifdef BOOST_WINDOWS_PATH - // for Windows, use the alternate separator, and bypass extra - // root separators - - typename string_type::size_type root_dir_start( - detail::root_directory_start<String, Traits>( m_path, m_path.size() ) ); - bool in_root( root_dir_start != string_type::npos ); - String s; - for ( typename string_type::size_type pos( 0 ); - pos != m_path.size(); ++pos ) - { - // special case // [net] - if ( pos == 0 && m_path.size() > 1 - && m_path[0] == slash<path_type>::value - && m_path[1] == slash<path_type>::value - && ( m_path.size() == 2 - || !detail::is_separator<path_type>( m_path[2] ) - ) ) - { - ++pos; - s += path_alt_separator<path_type>::value; - s += path_alt_separator<path_type>::value; - continue; - } - - // bypass extra root separators - if ( in_root ) - { - if ( s.size() > 0 - && s[s.size()-1] == path_alt_separator<path_type>::value - && m_path[pos] == slash<path_type>::value - ) continue; - } - - if ( m_path[pos] == slash<path_type>::value ) - s += path_alt_separator<path_type>::value; - else - s += m_path[pos]; - - if ( pos > root_dir_start - && m_path[pos] == slash<path_type>::value ) - { in_root = false; } - } -# ifdef BOOST_CYGWIN_PATH - if ( m_cygwin_root ) s[0] = slash<path_type>::value; -# endif - return s; -# else - return m_path; -# endif - } - - // iterator functions ---------------------------------------------------// - - template<class String, class Traits> - typename basic_path<String, Traits>::iterator basic_path<String, Traits>::begin() const - { - iterator itr; - itr.m_path_ptr = this; - typename string_type::size_type element_size; - detail::first_element<String, Traits>( m_path, itr.m_pos, element_size ); - itr.m_name = m_path.substr( itr.m_pos, element_size ); - return itr; - } - - template<class String, class Traits> - typename basic_path<String, Traits>::iterator basic_path<String, Traits>::end() const - { - iterator itr; - itr.m_path_ptr = this; - itr.m_pos = m_path.size(); - return itr; - } - - namespace detail - { - // do_increment ------------------------------------------------------// - - template<class Path> - void iterator_helper<Path>::do_increment( iterator & itr ) - { - typedef typename Path::string_type string_type; - typedef typename Path::traits_type traits_type; - - assert( itr.m_pos < itr.m_path_ptr->m_path.size() && "basic_path::iterator increment past end()" ); - - bool was_net( itr.m_name.size() > 2 - && itr.m_name[0] == slash<Path>::value - && itr.m_name[1] == slash<Path>::value - && itr.m_name[2] != slash<Path>::value ); - - // increment to position past current element - itr.m_pos += itr.m_name.size(); - - // if end reached, create end iterator - if ( itr.m_pos == itr.m_path_ptr->m_path.size() ) - { - itr.m_name.erase( itr.m_name.begin(), itr.m_name.end() ); // VC++ 6.0 lib didn't supply clear() - return; - } - - // process separator (Windows drive spec is only case not a separator) - if ( itr.m_path_ptr->m_path[itr.m_pos] == slash<Path>::value ) - { - // detect root directory - if ( was_net - # ifdef BOOST_WINDOWS_PATH - // case "c:/" - || itr.m_name[itr.m_name.size()-1] == colon<Path>::value - # endif - ) - { - itr.m_name = slash<Path>::value; - return; - } - - // bypass separators - while ( itr.m_pos != itr.m_path_ptr->m_path.size() - && itr.m_path_ptr->m_path[itr.m_pos] == slash<Path>::value ) - { ++itr.m_pos; } - - // detect trailing separator, and treat it as ".", per POSIX spec - if ( itr.m_pos == itr.m_path_ptr->m_path.size() - && detail::is_non_root_slash< string_type, traits_type >( - itr.m_path_ptr->m_path, itr.m_pos-1 ) ) - { - --itr.m_pos; - itr.m_name = dot<Path>::value; - return; - } - } - - // get next element - typename string_type::size_type end_pos( - itr.m_path_ptr->m_path.find( slash<Path>::value, itr.m_pos ) ); - itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos ); - } - - // do_decrement ------------------------------------------------------// - - template<class Path> - void iterator_helper<Path>::do_decrement( iterator & itr ) - { - assert( itr.m_pos && "basic_path::iterator decrement past begin()" ); - - typedef typename Path::string_type string_type; - typedef typename Path::traits_type traits_type; - - typename string_type::size_type end_pos( itr.m_pos ); - - typename string_type::size_type root_dir_pos( - detail::root_directory_start<string_type, traits_type>( - itr.m_path_ptr->m_path, end_pos ) ); - - // if at end and there was a trailing non-root '/', return "." - if ( itr.m_pos == itr.m_path_ptr->m_path.size() - && itr.m_path_ptr->m_path.size() > 1 - && itr.m_path_ptr->m_path[itr.m_pos-1] == slash<Path>::value - && detail::is_non_root_slash< string_type, traits_type >( - itr.m_path_ptr->m_path, itr.m_pos-1 ) - ) - { - --itr.m_pos; - itr.m_name = dot<Path>::value; - return; - } - - // skip separators unless root directory - for ( - ; - end_pos > 0 - && (end_pos-1) != root_dir_pos - && itr.m_path_ptr->m_path[end_pos-1] == slash<Path>::value - ; - --end_pos ) {} - - itr.m_pos = detail::filename_pos<string_type, traits_type> - ( itr.m_path_ptr->m_path, end_pos ); - itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos ); - } - } // namespace detail - - // basic_filesystem_error implementation --------------------------------// - - template<class Path> - basic_filesystem_error<Path>::basic_filesystem_error( - const std::string & what_arg, system::error_code ec ) - : system::system_error(ec, what_arg) - { - try - { - m_imp_ptr.reset( new m_imp ); - } - catch (...) { m_imp_ptr.reset(); } - } - - template<class Path> - basic_filesystem_error<Path>::basic_filesystem_error( - const std::string & what_arg, const path_type & path1_arg, - system::error_code ec ) - : system::system_error(ec, what_arg) - { - try - { - m_imp_ptr.reset( new m_imp ); - m_imp_ptr->m_path1 = path1_arg; - } - catch (...) { m_imp_ptr.reset(); } - } - - template<class Path> - basic_filesystem_error<Path>::basic_filesystem_error( - const std::string & what_arg, const path_type & path1_arg, - const path_type & path2_arg, system::error_code ec ) - : system::system_error(ec, what_arg) - { - try - { - m_imp_ptr.reset( new m_imp ); - m_imp_ptr->m_path1 = path1_arg; - m_imp_ptr->m_path2 = path2_arg; - } - catch (...) { m_imp_ptr.reset(); } - } - - } // namespace BOOST_FILESYSTEM_NAMESPACE -} // namespace boost - -#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas - -#endif // BOOST_FILESYSTEM_PATH_HPP +#endif // BOOST_FILESYSTEM_PATHX_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/v2/config.hpp b/3rdParty/Boost/src/boost/filesystem/v2/config.hpp new file mode 100644 index 0000000..62656ef --- /dev/null +++ b/3rdParty/Boost/src/boost/filesystem/v2/config.hpp @@ -0,0 +1,96 @@ +// boost/filesystem/v2/config.hpp ------------------------------------------// + +// Copyright Beman Dawes 2003 + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM2_CONFIG_HPP +#define BOOST_FILESYSTEM2_CONFIG_HPP + +# if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION != 2 +# error Compiling Filesystem version 2 file with BOOST_FILESYSTEM_VERSION defined != 2 +# endif + +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 2 +# endif + +#define BOOST_FILESYSTEM_I18N // aid users wishing to compile several versions + +// ability to change namespace aids path_table.cpp ------------------------// +#ifndef BOOST_FILESYSTEM2_NAMESPACE +# define BOOST_FILESYSTEM2_NAMESPACE filesystem2 +#endif + +#include <boost/config.hpp> +#include <boost/system/api_config.hpp> // for BOOST_POSIX_API or BOOST_WINDOWS_API +#include <boost/detail/workaround.hpp> + +// BOOST_POSIX_PATH or BOOST_WINDOWS_PATH specify which path syntax to recognise + +# if defined(BOOST_WINDOWS_API) && defined(BOOST_POSIX_PATH) +# error builds with Windows API do not support BOOST_POSIX_PATH +# endif + +# if !defined(_WIN32) && !defined(__CYGWIN__) && defined(BOOST_WINDOWS_PATH) +# error builds on non-Windows platforms do not support BOOST_WINDOWS_PATH +# endif + +# if defined(BOOST_WINDOWS_PATH) && defined(BOOST_POSIX_PATH) +# error both BOOST_WINDOWS_PATH and BOOST_POSIX_PATH are defined +# elif !defined(BOOST_WINDOWS_PATH) && !defined(BOOST_POSIX_PATH) +# if !defined(BOOST_POSIX_PATH) && (defined(_WIN32) || defined(__CYGWIN__)) +# define BOOST_WINDOWS_PATH +# else +# define BOOST_POSIX_PATH +# endif +# endif + +// narrow support only for badly broken compilers or libraries -------------// + +# if defined(BOOST_NO_STD_WSTRING) || defined(BOOST_NO_SFINAE) || defined(BOOST_NO_STD_LOCALE) || BOOST_WORKAROUND(__BORLANDC__, <0x610) +# define BOOST_FILESYSTEM2_NARROW_ONLY +# endif + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +// enable dynamic linking ---------------------------------------------------// + +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) +# if defined(BOOST_FILESYSTEM_SOURCE) +# define BOOST_FILESYSTEM_DECL BOOST_SYMBOL_EXPORT +# else +# define BOOST_FILESYSTEM_DECL BOOST_SYMBOL_IMPORT +# endif +#else +# define BOOST_FILESYSTEM_DECL +#endif + +// enable automatic library variant selection ------------------------------// + +#if !defined(BOOST_FILESYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) \ + && !defined(BOOST_FILESYSTEM_NO_LIB) +// +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_filesystem +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include <boost/config/auto_link.hpp> +#endif // auto-linking disabled + +#endif // BOOST_FILESYSTEM2_CONFIG_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/convenience.hpp b/3rdParty/Boost/src/boost/filesystem/v2/convenience.hpp index d0e6c54..4695a01 100644 --- a/3rdParty/Boost/src/boost/filesystem/convenience.hpp +++ b/3rdParty/Boost/src/boost/filesystem/v2/convenience.hpp @@ -10,8 +10,8 @@ //----------------------------------------------------------------------------// -#ifndef BOOST_FILESYSTEM_CONVENIENCE_HPP -#define BOOST_FILESYSTEM_CONVENIENCE_HPP +#ifndef BOOST_FILESYSTEM2_CONVENIENCE_HPP +#define BOOST_FILESYSTEM2_CONVENIENCE_HPP #include <boost/filesystem/operations.hpp> #include <boost/system/error_code.hpp> @@ -20,7 +20,7 @@ #include <boost/config/abi_prefix.hpp> // must be the last #include -# ifndef BOOST_FILESYSTEM_NARROW_ONLY +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY # define BOOST_FS_FUNC(BOOST_FS_TYPE) \ template<class Path> typename boost::enable_if<is_basic_path<Path>, \ BOOST_FS_TYPE>::type @@ -35,7 +35,7 @@ namespace boost { - namespace filesystem + namespace filesystem2 { BOOST_FS_FUNC(bool) create_directories(const Path& ph) @@ -45,7 +45,7 @@ namespace boost if ( !ph.empty() && !is_directory(ph) ) boost::throw_exception( basic_filesystem_error<Path>( "boost::filesystem::create_directories", ph, - make_error_code( boost::system::posix::file_exists ) ) ); + make_error_code( boost::system::errc::file_exists ) ) ); return false; } @@ -81,11 +81,18 @@ namespace boost BOOST_FS_FUNC(Path) change_extension( const Path & ph, const BOOST_FS_TYPENAME Path::string_type & new_extension ) - { return ph.parent_path() / (basename(ph) + new_extension); } - + { +# if !defined(_STLPORT_VERSION) + return ph.parent_path() / (basename(ph) + new_extension); +# else + typedef BOOST_FS_TYPENAME Path::string_type string_type; + string_type filename = basename(ph) + new_extension; + return ph.parent_path() / filename; +# endif + } # endif -# ifndef BOOST_FILESYSTEM_NARROW_ONLY +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY // "do-the-right-thing" overloads ---------------------------------------// @@ -199,7 +206,7 @@ namespace boost }; typedef basic_recursive_directory_iterator<path> recursive_directory_iterator; -# ifndef BOOST_FILESYSTEM_NARROW_ONLY +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY typedef basic_recursive_directory_iterator<wpath> wrecursive_directory_iterator; # endif @@ -296,11 +303,36 @@ namespace boost if ( m_imp->m_stack.empty() ) m_imp.reset(); // done, so make end iterator } - } // namespace filesystem + } // namespace filesystem2 } // namespace boost #undef BOOST_FS_FUNC_STRING #undef BOOST_FS_FUNC +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + using filesystem2::create_directories; + using filesystem2::basic_recursive_directory_iterator; + using filesystem2::recursive_directory_iterator; + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + using filesystem2::extension; + using filesystem2::basename; + using filesystem2::change_extension; +# endif + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + using filesystem2::wrecursive_directory_iterator; +# endif + + } +} + +//----------------------------------------------------------------------------// + #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas -#endif // BOOST_FILESYSTEM_CONVENIENCE_HPP +#endif // BOOST_FILESYSTEM2_CONVENIENCE_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/v2/exception.hpp b/3rdParty/Boost/src/boost/filesystem/v2/exception.hpp new file mode 100644 index 0000000..edea663 --- /dev/null +++ b/3rdParty/Boost/src/boost/filesystem/v2/exception.hpp @@ -0,0 +1,9 @@ +// boost/filesystem/exception.hpp -------------------------------------------// + +// Copyright Beman Dawes 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) + +// This header is no long used. The contents have been moved to path.hpp. +// It is provided so that user code #includes do not have to be changed. diff --git a/3rdParty/Boost/src/boost/filesystem/v2/fstream.hpp b/3rdParty/Boost/src/boost/filesystem/v2/fstream.hpp new file mode 100644 index 0000000..bdcd485 --- /dev/null +++ b/3rdParty/Boost/src/boost/filesystem/v2/fstream.hpp @@ -0,0 +1,612 @@ +// boost/filesystem/fstream.hpp --------------------------------------------// + +// Copyright Beman Dawes 2002. +// 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 library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM2_FSTREAM_HPP +#define BOOST_FILESYSTEM2_FSTREAM_HPP + +#include <boost/filesystem/v2/operations.hpp> // for 8.3 hack (see below) +#include <boost/utility/enable_if.hpp> +#include <boost/detail/workaround.hpp> + +#include <iosfwd> +#include <fstream> + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +// NOTE: fstream.hpp for Boost 1.32.0 and earlier supplied workarounds for +// various compiler problems. They have been removed to ease development of the +// basic i18n functionality. Once the new interface is stable, the workarounds +// will be reinstated for any compilers that otherwise can support the rest of +// the library after internationalization. + +namespace boost +{ + namespace filesystem2 + { + namespace detail + { +# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM2_NARROW_ONLY) +# if !defined(BOOST_DINKUMWARE_STDLIB) || BOOST_DINKUMWARE_STDLIB < 405 + // The 8.3 hack: + // C++98 does not supply a wchar_t open, so try to get an equivalent + // narrow char name based on the short, so-called 8.3, name. + // Not needed for Dinkumware 405 and later as they do supply wchar_t open. + BOOST_FILESYSTEM_DECL bool create_file_api( const std::wstring & ph, + std::ios_base::openmode mode ); // true if succeeds + BOOST_FILESYSTEM_DECL std::string narrow_path_api( + const std::wstring & ph ); // return is empty if fails + + inline std::string path_proxy( const std::wstring & file_ph, + std::ios_base::openmode mode ) + // Return a non-existant path if cannot supply narrow short path. + // An empty path doesn't work because some Dinkumware versions + // assert the path is non-empty. + { + std::string narrow_ph; + bool created_file( false ); + if ( !exists( file_ph ) + && (mode & std::ios_base::out) != 0 + && create_file_api( file_ph, mode ) ) + { + created_file = true; + } + narrow_ph = narrow_path_api( file_ph ); + if ( narrow_ph.empty() ) + { + if ( created_file ) remove_api( file_ph ); + narrow_ph = "\x01"; + } + return narrow_ph; + } +# else + // Dinkumware 405 and later does supply wchar_t functions + inline const std::wstring & path_proxy( const std::wstring & file_ph, + std::ios_base::openmode ) + { return file_ph; } +# endif +# endif + + inline const std::string & path_proxy( const std::string & file_ph, + std::ios_base::openmode ) + { return file_ph; } + + } // namespace detail + + template < class charT, class traits = std::char_traits<charT> > + class basic_filebuf : public std::basic_filebuf<charT,traits> + { + private: // disallow copying + basic_filebuf( const basic_filebuf & ); + const basic_filebuf & operator=( const basic_filebuf & ); + public: + basic_filebuf() {} + virtual ~basic_filebuf() {} + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + template<class Path> + typename boost::enable_if<is_basic_path<Path>, + basic_filebuf<charT,traits> *>::type + open( const Path & file_ph, std::ios_base::openmode mode ); + + basic_filebuf<charT,traits> * + open( const wpath & file_ph, std::ios_base::openmode mode ); +# endif + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + basic_filebuf<charT,traits> * + open( const path & file_ph, std::ios_base::openmode mode ); +# endif + }; + + template < class charT, class traits = std::char_traits<charT> > + class basic_ifstream : public std::basic_ifstream<charT,traits> + { + private: // disallow copying + basic_ifstream( const basic_ifstream & ); + const basic_ifstream & operator=( const basic_ifstream & ); + public: + basic_ifstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + template<class Path> + explicit basic_ifstream( const Path & file_ph, + typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); + + template<class Path> + basic_ifstream( const Path & file_ph, std::ios_base::openmode mode, + typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); + + template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + open( const Path & file_ph ); + + template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + open( const Path & file_ph, std::ios_base::openmode mode ); + + explicit basic_ifstream( const wpath & file_ph ); + basic_ifstream( const wpath & file_ph, std::ios_base::openmode mode ); + void open( const wpath & file_ph ); + void open( const wpath & file_ph, std::ios_base::openmode mode ); +# endif + + explicit basic_ifstream( const path & file_ph ); + basic_ifstream( const path & file_ph, std::ios_base::openmode mode ); +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + void open( const path & file_ph ); + void open( const path & file_ph, std::ios_base::openmode mode ); +# endif + virtual ~basic_ifstream() {} + }; + + template < class charT, class traits = std::char_traits<charT> > + class basic_ofstream : public std::basic_ofstream<charT,traits> + { + private: // disallow copying + basic_ofstream( const basic_ofstream & ); + const basic_ofstream & operator=( const basic_ofstream & ); + public: + basic_ofstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + + template<class Path> + explicit basic_ofstream( const Path & file_ph, + typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); + explicit basic_ofstream( const wpath & file_ph ); + + template<class Path> + basic_ofstream( const Path & file_ph, std::ios_base::openmode mode, + typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); + basic_ofstream( const wpath & file_ph, std::ios_base::openmode mode ); + + template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + open( const Path & file_ph ); + void open( const wpath & file_ph ); + + template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + open( const Path & file_ph, std::ios_base::openmode mode ); + void open( const wpath & file_ph, std::ios_base::openmode mode ); + +# endif + + explicit basic_ofstream( const path & file_ph ); + basic_ofstream( const path & file_ph, std::ios_base::openmode mode ); +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + void open( const path & file_ph ); + void open( const path & file_ph, std::ios_base::openmode mode ); +# endif + virtual ~basic_ofstream() {} + }; + + template < class charT, class traits = std::char_traits<charT> > + class basic_fstream : public std::basic_fstream<charT,traits> + { + private: // disallow copying + basic_fstream( const basic_fstream & ); + const basic_fstream & operator=( const basic_fstream & ); + public: + basic_fstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + + template<class Path> + explicit basic_fstream( const Path & file_ph, + typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); + explicit basic_fstream( const wpath & file_ph ); + + template<class Path> + basic_fstream( const Path & file_ph, std::ios_base::openmode mode, + typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); + basic_fstream( const wpath & file_ph, std::ios_base::openmode mode ); + + template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + open( const Path & file_ph ); + void open( const wpath & file_ph ); + + template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + open( const Path & file_ph, std::ios_base::openmode mode ); + void open( const wpath & file_ph, std::ios_base::openmode mode ); + +# endif + + explicit basic_fstream( const path & file_ph ); + basic_fstream( const path & file_ph, std::ios_base::openmode mode ); +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + void open( const path & file_ph ); + void open( const path & file_ph, std::ios_base::openmode mode ); +# endif + virtual ~basic_fstream() {} + + }; + + typedef basic_filebuf<char> filebuf; + typedef basic_ifstream<char> ifstream; + typedef basic_ofstream<char> ofstream; + typedef basic_fstream<char> fstream; + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + typedef basic_filebuf<wchar_t> wfilebuf; + typedef basic_ifstream<wchar_t> wifstream; + typedef basic_fstream<wchar_t> wfstream; + typedef basic_ofstream<wchar_t> wofstream; +# endif + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + +// basic_filebuf definitions -----------------------------------------------// + + template <class charT, class traits> + template<class Path> + typename boost::enable_if<is_basic_path<Path>, + basic_filebuf<charT,traits> *>::type + basic_filebuf<charT,traits>::open( const Path & file_ph, + std::ios_base::openmode mode ) + { + return (std::basic_filebuf<charT,traits>::open( detail::path_proxy( + file_ph.external_file_string(), mode ).c_str(), mode ) + == 0) ? 0 : this; + } + + template <class charT, class traits> + basic_filebuf<charT,traits> * + basic_filebuf<charT, traits>::open( const wpath & file_ph, + std::ios_base::openmode mode ) + { + return this->BOOST_NESTED_TEMPLATE open<wpath>( file_ph, mode ); + } + +// basic_ifstream definitions ----------------------------------------------// + + template <class charT, class traits> template<class Path> + basic_ifstream<charT,traits>::basic_ifstream(const Path & file_ph, + typename boost::enable_if<is_basic_path<Path> >::type* ) + : std::basic_ifstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in ).c_str(), std::ios_base::in ) {} + + template <class charT, class traits> + basic_ifstream<charT,traits>::basic_ifstream( const wpath & file_ph ) + : std::basic_ifstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in ).c_str(), std::ios_base::in ) {} + + template <class charT, class traits> template<class Path> + basic_ifstream<charT,traits>::basic_ifstream( const Path & file_ph, + std::ios_base::openmode mode, + typename boost::enable_if<is_basic_path<Path> >::type* ) + : std::basic_ifstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode ) {} + + template <class charT, class traits> + basic_ifstream<charT,traits>::basic_ifstream( const wpath & file_ph, + std::ios_base::openmode mode ) + : std::basic_ifstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode ) {} + + template <class charT, class traits> template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + basic_ifstream<charT,traits>::open( const Path & file_ph ) + { + std::basic_ifstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in ).c_str(), std::ios_base::in ); + } + + template <class charT, class traits> + void basic_ifstream<charT,traits>::open( const wpath & file_ph ) + { + std::basic_ifstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in ).c_str(), std::ios_base::in ); + } + + template <class charT, class traits> template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + basic_ifstream<charT,traits>::open( const Path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ifstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode ); + } + + template <class charT, class traits> + void basic_ifstream<charT,traits>::open( const wpath & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ifstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode ); + } + +// basic_ofstream definitions ----------------------------------------------// + + template <class charT, class traits> template<class Path> + basic_ofstream<charT,traits>::basic_ofstream(const Path & file_ph, + typename boost::enable_if<is_basic_path<Path> >::type* ) + : std::basic_ofstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::out ).c_str(), std::ios_base::out ) {} + + template <class charT, class traits> + basic_ofstream<charT,traits>::basic_ofstream( const wpath & file_ph ) + : std::basic_ofstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::out ).c_str(), std::ios_base::out ) {} + + template <class charT, class traits> template<class Path> + basic_ofstream<charT,traits>::basic_ofstream( const Path & file_ph, + std::ios_base::openmode mode, + typename boost::enable_if<is_basic_path<Path> >::type* ) + : std::basic_ofstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode ) {} + + template <class charT, class traits> + basic_ofstream<charT,traits>::basic_ofstream( const wpath & file_ph, + std::ios_base::openmode mode ) + : std::basic_ofstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode ) {} + + template <class charT, class traits> template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + basic_ofstream<charT,traits>::open( const Path & file_ph ) + { + std::basic_ofstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::out ).c_str(), std::ios_base::out ); + } + + template <class charT, class traits> + void basic_ofstream<charT,traits>::open( const wpath & file_ph ) + { + std::basic_ofstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::out ).c_str(), std::ios_base::out ); + } + + template <class charT, class traits> template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + basic_ofstream<charT,traits>::open( const Path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ofstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode ); + } + + template <class charT, class traits> + void basic_ofstream<charT,traits>::open( const wpath & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ofstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode ); + } + +// basic_fstream definitions -----------------------------------------------// + + template <class charT, class traits> template<class Path> + basic_fstream<charT,traits>::basic_fstream(const Path & file_ph, + typename boost::enable_if<is_basic_path<Path> >::type* ) + : std::basic_fstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in|std::ios_base::out ).c_str(), + std::ios_base::in|std::ios_base::out ) {} + + template <class charT, class traits> + basic_fstream<charT,traits>::basic_fstream( const wpath & file_ph ) + : std::basic_fstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in|std::ios_base::out ).c_str(), + std::ios_base::in|std::ios_base::out ) {} + + template <class charT, class traits> template<class Path> + basic_fstream<charT,traits>::basic_fstream( const Path & file_ph, + std::ios_base::openmode mode, + typename boost::enable_if<is_basic_path<Path> >::type* ) + : std::basic_fstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode ) {} + + template <class charT, class traits> + basic_fstream<charT,traits>::basic_fstream( const wpath & file_ph, + std::ios_base::openmode mode ) + : std::basic_fstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode ) {} + + template <class charT, class traits> template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + basic_fstream<charT,traits>::open( const Path & file_ph ) + { + std::basic_fstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in|std::ios_base::out ).c_str(), + std::ios_base::in|std::ios_base::out ); + } + + template <class charT, class traits> + void basic_fstream<charT,traits>::open( const wpath & file_ph ) + { + std::basic_fstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in|std::ios_base::out ).c_str(), + std::ios_base::in|std::ios_base::out ); + } + + template <class charT, class traits> template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + basic_fstream<charT,traits>::open( const Path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_fstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode ); + } + + template <class charT, class traits> + void basic_fstream<charT,traits>::open( const wpath & file_ph, + std::ios_base::openmode mode ) + { + std::basic_fstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode ); + } + +# endif + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + template <class charT, class traits> + basic_filebuf<charT,traits> * + basic_filebuf<charT, traits>::open( const path & file_ph, + std::ios_base::openmode mode ) + { + return std::basic_filebuf<charT,traits>::open( + file_ph.file_string().c_str(), mode ) == 0 ? 0 : this; + } +# endif + + template <class charT, class traits> + basic_ifstream<charT,traits>::basic_ifstream( const path & file_ph ) + : std::basic_ifstream<charT,traits>( + file_ph.file_string().c_str(), std::ios_base::in ) {} + + template <class charT, class traits> + basic_ifstream<charT,traits>::basic_ifstream( const path & file_ph, + std::ios_base::openmode mode ) + : std::basic_ifstream<charT,traits>( + file_ph.file_string().c_str(), mode ) {} + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + template <class charT, class traits> + void basic_ifstream<charT,traits>::open( const path & file_ph ) + { + std::basic_ifstream<charT,traits>::open( + file_ph.file_string().c_str(), std::ios_base::in ); + } + + template <class charT, class traits> + void basic_ifstream<charT,traits>::open( const path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ifstream<charT,traits>::open( + file_ph.file_string().c_str(), mode ); + } +# endif + + template <class charT, class traits> + basic_ofstream<charT,traits>::basic_ofstream( const path & file_ph ) + : std::basic_ofstream<charT,traits>( + file_ph.file_string().c_str(), std::ios_base::out ) {} + + template <class charT, class traits> + basic_ofstream<charT,traits>::basic_ofstream( const path & file_ph, + std::ios_base::openmode mode ) + : std::basic_ofstream<charT,traits>( + file_ph.file_string().c_str(), mode ) {} + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + template <class charT, class traits> + void basic_ofstream<charT,traits>::open( const path & file_ph ) + { + std::basic_ofstream<charT,traits>::open( + file_ph.file_string().c_str(), std::ios_base::out ); + } + + template <class charT, class traits> + void basic_ofstream<charT,traits>::open( const path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ofstream<charT,traits>::open( + file_ph.file_string().c_str(), mode ); + } +# endif + + template <class charT, class traits> + basic_fstream<charT,traits>::basic_fstream( const path & file_ph ) + : std::basic_fstream<charT,traits>( + file_ph.file_string().c_str(), + std::ios_base::in|std::ios_base::out ) {} + + + template <class charT, class traits> + basic_fstream<charT,traits>::basic_fstream( const path & file_ph, + std::ios_base::openmode mode ) + : std::basic_fstream<charT,traits>( + file_ph.file_string().c_str(), mode ) {} + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + template <class charT, class traits> + void basic_fstream<charT,traits>::open( const path & file_ph ) + { + std::basic_fstream<charT,traits>::open( + file_ph.file_string().c_str(), std::ios_base::in|std::ios_base::out ); + } + + template <class charT, class traits> + void basic_fstream<charT,traits>::open( const path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_fstream<charT,traits>::open( + file_ph.file_string().c_str(), mode ); + } +# endif + } // namespace filesystem2 +} // namespace boost + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + using filesystem2::wfilebuf; + using filesystem2::wifstream; + using filesystem2::wfstream; + using filesystem2::wofstream; +# endif + using filesystem2::filebuf; + using filesystem2::ifstream; + using filesystem2::ofstream; + using filesystem2::fstream; + using filesystem2::basic_filebuf; + using filesystem2::basic_ifstream; + using filesystem2::basic_ofstream; + using filesystem2::basic_fstream; + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED +# endif + } +} + +//----------------------------------------------------------------------------// + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM2_FSTREAM_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/v2/operations.hpp b/3rdParty/Boost/src/boost/filesystem/v2/operations.hpp new file mode 100644 index 0000000..c60046f --- /dev/null +++ b/3rdParty/Boost/src/boost/filesystem/v2/operations.hpp @@ -0,0 +1,1244 @@ +// boost/filesystem/operations.hpp -----------------------------------------// + +// Copyright 2002-2005 Beman Dawes +// Copyright 2002 Jan Langer +// Copyright 2001 Dietmar Kuehl +// +// 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 library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM2_OPERATIONS_HPP +#define BOOST_FILESYSTEM2_OPERATIONS_HPP + +#include <boost/filesystem/v2/path.hpp> +#include <boost/detail/scoped_enum_emulation.hpp> + +#include <boost/shared_ptr.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/iterator.hpp> +#include <boost/cstdint.hpp> +#include <boost/assert.hpp> + +#include <string> +#include <utility> // for pair +#include <ctime> + +#ifdef BOOST_WINDOWS_API +# include <fstream> +# if !defined(_WIN32_WINNT) || _WIN32_WINNT >= 0x0500 +# define BOOST_FS_HARD_LINK // Default for Windows 2K or later +# endif +#endif + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +# ifdef BOOST_NO_STDC_NAMESPACE + namespace std { using ::time_t; } +# endif + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem2 + { + +// typedef boost::filesystem::path Path; needs to be in namespace boost::filesystem +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY +# define BOOST_FS_FUNC(BOOST_FS_TYPE) \ + template<class Path> typename boost::enable_if<is_basic_path<Path>, \ + BOOST_FS_TYPE>::type +# define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) \ + template<class Path> inline typename boost::enable_if<is_basic_path<Path>, \ + BOOST_FS_TYPE>::type +# define BOOST_FS_TYPENAME typename +# else +# define BOOST_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE +# define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE + typedef boost::filesystem2::path Path; +# define BOOST_FS_TYPENAME +# endif + + template<class Path> class basic_directory_iterator; + + // BOOST_FILESYSTEM2_NARROW_ONLY needs this: + typedef basic_directory_iterator<path> directory_iterator; + + template<class Path> class basic_directory_entry; + + enum file_type + { + status_unknown, + file_not_found, + regular_file, + directory_file, + // the following will never be reported by some operating or file systems + symlink_file, + block_file, + character_file, + fifo_file, + socket_file, + type_unknown // file does exist, but isn't one of the above types or + // we don't have strong enough permission to find its type + }; + + class file_status + { + public: + explicit file_status( file_type v = status_unknown ) : m_value(v) {} + + void type( file_type v ) { m_value = v; } + file_type type() const { return m_value; } + + private: + // the internal representation is unspecified so that additional state + // information such as permissions can be added in the future; this + // implementation just uses status_type as the internal representation + + file_type m_value; + }; + + inline bool status_known( file_status f ) { return f.type() != status_unknown; } + inline bool exists( file_status f ) { return f.type() != status_unknown && f.type() != file_not_found; } + inline bool is_regular_file(file_status f){ return f.type() == regular_file; } + inline bool is_directory( file_status f ) { return f.type() == directory_file; } + inline bool is_symlink( file_status f ) { return f.type() == symlink_file; } + inline bool is_other( file_status f ) { return exists(f) && !is_regular_file(f) && !is_directory(f) && !is_symlink(f); } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool is_regular( file_status f ) { return f.type() == regular_file; } +# endif + + struct space_info + { + // all values are byte counts + boost::uintmax_t capacity; + boost::uintmax_t free; // <= capacity + boost::uintmax_t available; // <= free + }; + + namespace detail + { + typedef std::pair< system::error_code, bool > + query_pair; + + typedef std::pair< system::error_code, boost::uintmax_t > + uintmax_pair; + + typedef std::pair< system::error_code, std::time_t > + time_pair; + + typedef std::pair< system::error_code, space_info > + space_pair; + + template< class Path > + struct directory_pair + { + typedef std::pair< system::error_code, + typename Path::external_string_type > type; + }; + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + BOOST_FILESYSTEM_DECL bool + symbolic_link_exists_api( const std::string & ); // deprecated +# endif + + BOOST_FILESYSTEM_DECL file_status + status_api( const std::string & ph, system::error_code & ec ); +# ifndef BOOST_WINDOWS_API + BOOST_FILESYSTEM_DECL file_status + symlink_status_api( const std::string & ph, system::error_code & ec ); +# endif + BOOST_FILESYSTEM_DECL query_pair + is_empty_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL query_pair + equivalent_api( const std::string & ph1, const std::string & ph2 ); + BOOST_FILESYSTEM_DECL uintmax_pair + file_size_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL space_pair + space_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL time_pair + last_write_time_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + last_write_time_api( const std::string & ph, std::time_t new_value ); + BOOST_FILESYSTEM_DECL system::error_code + get_current_path_api( std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + set_current_path_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL query_pair + create_directory_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + create_hard_link_api( const std::string & to_ph, + const std::string & from_ph ); + BOOST_FILESYSTEM_DECL system::error_code + create_symlink_api( const std::string & to_ph, + const std::string & from_ph ); + BOOST_FILESYSTEM_DECL system::error_code + remove_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + rename_api( const std::string & from, const std::string & to ); + BOOST_FILESYSTEM_DECL system::error_code + copy_file_api( const std::string & from, const std::string & to, bool fail_if_exists ); + +# if defined(BOOST_WINDOWS_API) + + BOOST_FILESYSTEM_DECL system::error_code + get_full_path_name_api( const std::string & ph, std::string & target ); + +# if !defined(BOOST_FILESYSTEM2_NARROW_ONLY) + + BOOST_FILESYSTEM_DECL boost::filesystem2::file_status + status_api( const std::wstring & ph, system::error_code & ec ); + BOOST_FILESYSTEM_DECL query_pair + is_empty_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL query_pair + equivalent_api( const std::wstring & ph1, const std::wstring & ph2 ); + BOOST_FILESYSTEM_DECL uintmax_pair + file_size_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL space_pair + space_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + get_full_path_name_api( const std::wstring & ph, std::wstring & target ); + BOOST_FILESYSTEM_DECL time_pair + last_write_time_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + last_write_time_api( const std::wstring & ph, std::time_t new_value ); + BOOST_FILESYSTEM_DECL system::error_code + get_current_path_api( std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + set_current_path_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL query_pair + create_directory_api( const std::wstring & ph ); +# ifdef BOOST_FS_HARD_LINK + BOOST_FILESYSTEM_DECL system::error_code + create_hard_link_api( const std::wstring & existing_ph, + const std::wstring & new_ph ); +# endif + BOOST_FILESYSTEM_DECL system::error_code + create_symlink_api( const std::wstring & to_ph, + const std::wstring & from_ph ); + BOOST_FILESYSTEM_DECL system::error_code + remove_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + rename_api( const std::wstring & from, const std::wstring & to ); + BOOST_FILESYSTEM_DECL system::error_code + copy_file_api( const std::wstring & from, const std::wstring & to, bool fail_if_exists ); + +# endif +# endif + + template<class Path> + bool remove_aux( const Path & ph, file_status f ); + + template<class Path> + unsigned long remove_all_aux( const Path & ph, file_status f ); + + } // namespace detail + +// operations functions ----------------------------------------------------// + + // The non-template overloads enable automatic conversion from std and + // C-style strings. See basic_path constructors. The enable_if for the + // templates implements the famous "do-the-right-thing" rule. + +// query functions ---------------------------------------------------------// + + BOOST_INLINE_FS_FUNC(file_status) + status( const Path & ph, system::error_code & ec ) + { return detail::status_api( ph.external_file_string(), ec ); } + + BOOST_FS_FUNC(file_status) + status( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::status", ph, ec ) ); + return result; + } + + BOOST_INLINE_FS_FUNC(file_status) + symlink_status( const Path & ph, system::error_code & ec ) +# ifdef BOOST_WINDOWS_API + { return detail::status_api( ph.external_file_string(), ec ); } +# else + { return detail::symlink_status_api( ph.external_file_string(), ec ); } +# endif + + BOOST_FS_FUNC(file_status) + symlink_status( const Path & ph ) + { + system::error_code ec; + file_status result( symlink_status( ph, ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::symlink_status", ph, ec ) ); + return result; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool symbolic_link_exists( const path & ph ) + { return is_symlink( symlink_status(ph) ); } +# endif + + BOOST_FS_FUNC(bool) exists( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::exists", ph, ec ) ); + return exists( result ); + } + + BOOST_FS_FUNC(bool) is_directory( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::is_directory", ph, ec ) ); + return is_directory( result ); + } + + BOOST_FS_FUNC(bool) is_regular_file( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::is_regular_file", ph, ec ) ); + return is_regular_file( result ); + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + BOOST_FS_FUNC(bool) is_regular( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::is_regular", ph, ec ) ); + return is_regular( result ); + } +# endif + + BOOST_FS_FUNC(bool) is_other( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::is_other", ph, ec ) ); + return is_other( result ); + } + + BOOST_FS_FUNC(bool) is_symlink( +# ifdef BOOST_WINDOWS_API + const Path & ) + { + return false; +# else + const Path & ph) + { + system::error_code ec; + file_status result( detail::symlink_status_api( ph.external_file_string(), ec ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::is_symlink", ph, ec ) ); + return is_symlink( result ); +# endif + } + + // VC++ 7.0 and earlier has a serious namespace bug that causes a clash + // between boost::filesystem2::is_empty and the unrelated type trait + // boost::is_empty. + +# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 + BOOST_FS_FUNC(bool) is_empty( const Path & ph ) +# else + BOOST_FS_FUNC(bool) _is_empty( const Path & ph ) +# endif + { + detail::query_pair result( + detail::is_empty_api( ph.external_file_string() ) ); + if ( result.first ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::is_empty", ph, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(bool) equivalent( const Path & ph1, const Path & ph2 ) + { + detail::query_pair result( detail::equivalent_api( + ph1.external_file_string(), ph2.external_file_string() ) ); + if ( result.first ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::equivalent", ph1, ph2, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(boost::uintmax_t) file_size( const Path & ph ) + { + detail::uintmax_pair result + ( detail::file_size_api( ph.external_file_string() ) ); + if ( result.first ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::file_size", ph, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(space_info) space( const Path & ph ) + { + detail::space_pair result + ( detail::space_api( ph.external_file_string() ) ); + if ( result.first ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::space", ph, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(std::time_t) last_write_time( const Path & ph ) + { + detail::time_pair result + ( detail::last_write_time_api( ph.external_file_string() ) ); + if ( result.first ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::last_write_time", ph, result.first ) ); + return result.second; + } + + +// operations --------------------------------------------------------------// + + BOOST_FS_FUNC(bool) create_directory( const Path & dir_ph ) + { + detail::query_pair result( + detail::create_directory_api( dir_ph.external_directory_string() ) ); + if ( result.first ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::create_directory", + dir_ph, result.first ) ); + return result.second; + } + +#if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK) + BOOST_FS_FUNC(void) + create_hard_link( const Path & to_ph, const Path & from_ph ) + { + system::error_code ec( + detail::create_hard_link_api( + to_ph.external_file_string(), + from_ph.external_file_string() ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::create_hard_link", + to_ph, from_ph, ec ) ); + } + + BOOST_FS_FUNC(system::error_code) + create_hard_link( const Path & to_ph, const Path & from_ph, + system::error_code & ec ) + { + ec = detail::create_hard_link_api( + to_ph.external_file_string(), + from_ph.external_file_string() ); + return ec; + } +#endif + + BOOST_FS_FUNC(void) + create_symlink( const Path & to_ph, const Path & from_ph ) + { + system::error_code ec( + detail::create_symlink_api( + to_ph.external_file_string(), + from_ph.external_file_string() ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::create_symlink", + to_ph, from_ph, ec ) ); + } + + BOOST_FS_FUNC(system::error_code) + create_symlink( const Path & to_ph, const Path & from_ph, + system::error_code & ec ) + { + ec = detail::create_symlink_api( + to_ph.external_file_string(), + from_ph.external_file_string() ); + return ec; + } + + BOOST_FS_FUNC(bool) remove( const Path & ph ) + { + system::error_code ec; + file_status f = symlink_status( ph, ec ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::remove", ph, ec ) ); + return detail::remove_aux( ph, f ); + } + + BOOST_FS_FUNC(unsigned long) remove_all( const Path & ph ) + { + system::error_code ec; + file_status f = symlink_status( ph, ec ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::remove_all", ph, ec ) ); + return exists( f ) ? detail::remove_all_aux( ph, f ) : 0; + } + + BOOST_FS_FUNC(void) rename( const Path & from_path, const Path & to_path ) + { + system::error_code ec( detail::rename_api( + from_path.external_directory_string(), + to_path.external_directory_string() ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::rename", + from_path, to_path, ec ) ); + } + + BOOST_SCOPED_ENUM_START(copy_option) + { fail_if_exists, overwrite_if_exists }; + BOOST_SCOPED_ENUM_END + + BOOST_FS_FUNC(void) copy_file( const Path & from_path, const Path & to_path, + BOOST_SCOPED_ENUM(copy_option) option = copy_option::fail_if_exists ) + { + system::error_code ec( detail::copy_file_api( + from_path.external_directory_string(), + to_path.external_directory_string(), option == copy_option::fail_if_exists ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::copy_file", + from_path, to_path, ec ) ); + } + + template< class Path > + Path current_path() + { + typename Path::external_string_type ph; + system::error_code ec( detail::get_current_path_api( ph ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::current_path", ec ) ); + return Path( Path::traits_type::to_internal( ph ) ); + } + + BOOST_FS_FUNC(void) current_path( const Path & ph ) + { + system::error_code ec( detail::set_current_path_api( + ph.external_directory_string() ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::current_path", ph, ec ) ); + } + + template< class Path > + const Path & initial_path() + { + static Path init_path; + if ( init_path.empty() ) init_path = current_path<Path>(); + return init_path; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + // legacy support + inline path current_path() // overload supports pre-i18n apps + { return current_path<boost::filesystem2::path>(); } + inline const path & initial_path() // overload supports pre-i18n apps + { return initial_path<boost::filesystem2::path>(); } +# endif + + BOOST_FS_FUNC(Path) system_complete( const Path & ph ) + { +# ifdef BOOST_WINDOWS_API + if ( ph.empty() ) return ph; + BOOST_FS_TYPENAME Path::external_string_type sys_ph; + system::error_code ec( detail::get_full_path_name_api( ph.external_file_string(), + sys_ph ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::system_complete", ph, ec ) ); + return Path( Path::traits_type::to_internal( sys_ph ) ); +# else + return (ph.empty() || ph.is_complete()) + ? ph : current_path<Path>() / ph; +# endif + } + + BOOST_FS_FUNC(Path) + complete( const Path & ph, + const Path & base/* = initial_path<Path>() */) + { + BOOST_ASSERT( base.is_complete() + && (ph.is_complete() || !ph.has_root_name()) + && "boost::filesystem::complete() precondition not met" ); +# ifdef BOOST_WINDOWS_PATH + if (ph.empty() || ph.is_complete()) return ph; + if ( !ph.has_root_name() ) + return ph.has_root_directory() + ? Path( base.root_name() ) / ph + : base / ph; + return base / ph; +# else + return (ph.empty() || ph.is_complete()) ? ph : base / ph; +# endif + } + + // VC++ 7.1 had trouble with default arguments, so separate one argument + // signatures are provided as workarounds; the effect is the same. + BOOST_FS_FUNC(Path) complete( const Path & ph ) + { return complete( ph, initial_path<Path>() ); } + + BOOST_FS_FUNC(void) + last_write_time( const Path & ph, const std::time_t new_time ) + { + system::error_code ec( detail::last_write_time_api( ph.external_file_string(), + new_time ) ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::last_write_time", ph, ec ) ); + } + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + + // "do-the-right-thing" overloads ---------------------------------------// + + inline file_status status( const path & ph ) + { return status<path>( ph ); } + inline file_status status( const wpath & ph ) + { return status<wpath>( ph ); } + + inline file_status status( const path & ph, system::error_code & ec ) + { return status<path>( ph, ec ); } + inline file_status status( const wpath & ph, system::error_code & ec ) + { return status<wpath>( ph, ec ); } + + inline file_status symlink_status( const path & ph ) + { return symlink_status<path>( ph ); } + inline file_status symlink_status( const wpath & ph ) + { return symlink_status<wpath>( ph ); } + + inline file_status symlink_status( const path & ph, system::error_code & ec ) + { return symlink_status<path>( ph, ec ); } + inline file_status symlink_status( const wpath & ph, system::error_code & ec ) + { return symlink_status<wpath>( ph, ec ); } + + inline bool exists( const path & ph ) { return exists<path>( ph ); } + inline bool exists( const wpath & ph ) { return exists<wpath>( ph ); } + + inline bool is_directory( const path & ph ) + { return is_directory<path>( ph ); } + inline bool is_directory( const wpath & ph ) + { return is_directory<wpath>( ph ); } + + inline bool is_regular_file( const path & ph ) + { return is_regular_file<path>( ph ); } + inline bool is_regular_file( const wpath & ph ) + { return is_regular_file<wpath>( ph ); } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool is_regular( const path & ph ) + { return is_regular<path>( ph ); } + inline bool is_regular( const wpath & ph ) + { return is_regular<wpath>( ph ); } +# endif + + inline bool is_other( const path & ph ) + { return is_other<path>( ph ); } + inline bool is_other( const wpath & ph ) + { return is_other<wpath>( ph ); } + + inline bool is_symlink( const path & ph ) + { return is_symlink<path>( ph ); } + inline bool is_symlink( const wpath & ph ) + { return is_symlink<wpath>( ph ); } + + inline bool is_empty( const path & ph ) + { return boost::filesystem2::is_empty<path>( ph ); } + inline bool is_empty( const wpath & ph ) + { return boost::filesystem2::is_empty<wpath>( ph ); } + + inline bool equivalent( const path & ph1, const path & ph2 ) + { return equivalent<path>( ph1, ph2 ); } + inline bool equivalent( const wpath & ph1, const wpath & ph2 ) + { return equivalent<wpath>( ph1, ph2 ); } + + inline boost::uintmax_t file_size( const path & ph ) + { return file_size<path>( ph ); } + inline boost::uintmax_t file_size( const wpath & ph ) + { return file_size<wpath>( ph ); } + + inline space_info space( const path & ph ) + { return space<path>( ph ); } + inline space_info space( const wpath & ph ) + { return space<wpath>( ph ); } + + inline std::time_t last_write_time( const path & ph ) + { return last_write_time<path>( ph ); } + inline std::time_t last_write_time( const wpath & ph ) + { return last_write_time<wpath>( ph ); } + + inline bool create_directory( const path & dir_ph ) + { return create_directory<path>( dir_ph ); } + inline bool create_directory( const wpath & dir_ph ) + { return create_directory<wpath>( dir_ph ); } + +#if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK) + inline void create_hard_link( const path & to_ph, + const path & from_ph ) + { return create_hard_link<path>( to_ph, from_ph ); } + inline void create_hard_link( const wpath & to_ph, + const wpath & from_ph ) + { return create_hard_link<wpath>( to_ph, from_ph ); } + + inline system::error_code create_hard_link( const path & to_ph, + const path & from_ph, system::error_code & ec ) + { return create_hard_link<path>( to_ph, from_ph, ec ); } + inline system::error_code create_hard_link( const wpath & to_ph, + const wpath & from_ph, system::error_code & ec ) + { return create_hard_link<wpath>( to_ph, from_ph, ec ); } +#endif + + inline void create_symlink( const path & to_ph, + const path & from_ph ) + { return create_symlink<path>( to_ph, from_ph ); } + inline void create_symlink( const wpath & to_ph, + const wpath & from_ph ) + { return create_symlink<wpath>( to_ph, from_ph ); } + + inline system::error_code create_symlink( const path & to_ph, + const path & from_ph, system::error_code & ec ) + { return create_symlink<path>( to_ph, from_ph, ec ); } + inline system::error_code create_symlink( const wpath & to_ph, + const wpath & from_ph, system::error_code & ec ) + { return create_symlink<wpath>( to_ph, from_ph, ec ); } + + inline bool remove( const path & ph ) + { return remove<path>( ph ); } + inline bool remove( const wpath & ph ) + { return remove<wpath>( ph ); } + + inline unsigned long remove_all( const path & ph ) + { return remove_all<path>( ph ); } + inline unsigned long remove_all( const wpath & ph ) + { return remove_all<wpath>( ph ); } + + inline void rename( const path & from_path, const path & to_path ) + { return rename<path>( from_path, to_path ); } + inline void rename( const wpath & from_path, const wpath & to_path ) + { return rename<wpath>( from_path, to_path ); } + + inline void copy_file( const path & from_path, const path & to_path ) + { return copy_file<path>( from_path, to_path ); } + inline void copy_file( const wpath & from_path, const wpath & to_path ) + { return copy_file<wpath>( from_path, to_path ); } + + inline path system_complete( const path & ph ) + { return system_complete<path>( ph ); } + inline wpath system_complete( const wpath & ph ) + { return system_complete<wpath>( ph ); } + + inline path complete( const path & ph, + const path & base/* = initial_path<path>()*/ ) + { return complete<path>( ph, base ); } + inline wpath complete( const wpath & ph, + const wpath & base/* = initial_path<wpath>()*/ ) + { return complete<wpath>( ph, base ); } + + inline path complete( const path & ph ) + { return complete<path>( ph, initial_path<path>() ); } + inline wpath complete( const wpath & ph ) + { return complete<wpath>( ph, initial_path<wpath>() ); } + + inline void last_write_time( const path & ph, const std::time_t new_time ) + { last_write_time<path>( ph, new_time ); } + inline void last_write_time( const wpath & ph, const std::time_t new_time ) + { last_write_time<wpath>( ph, new_time ); } + + inline void current_path( const path & ph ) + { current_path<path>( ph ); } + inline void current_path( const wpath & ph ) + { current_path<wpath>( ph ); } + +# endif // ifndef BOOST_FILESYSTEM2_NARROW_ONLY + + namespace detail + { + template<class Path> + bool remove_aux( const Path & ph, file_status f ) + { + if ( exists( f ) ) + { + system::error_code ec = remove_api( ph.external_file_string() ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::remove", ph, ec ) ); + return true; + } + return false; + } + + template<class Path> + unsigned long remove_all_aux( const Path & ph, file_status f ) + { + static const boost::filesystem2::basic_directory_iterator<Path> end_itr; + unsigned long count = 1; + if ( !boost::filesystem2::is_symlink( f ) // don't recurse symbolic links + && boost::filesystem2::is_directory( f ) ) + { + for ( boost::filesystem2::basic_directory_iterator<Path> itr( ph ); + itr != end_itr; ++itr ) + { + boost::system::error_code ec; + boost::filesystem2::file_status fn = boost::filesystem2::symlink_status( itr->path(), ec ); + if ( ec ) + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem:remove_all", ph, ec ) ); + count += remove_all_aux( itr->path(), fn ); + } + } + remove_aux( ph, f ); + return count; + } + +// test helper -------------------------------------------------------------// + + // not part of the documented interface because false positives are possible; + // there is no law that says that an OS that has large stat.st_size + // actually supports large file sizes. + BOOST_FILESYSTEM_DECL bool possible_large_file_size_support(); + +// directory_iterator helpers ----------------------------------------------// + +// forwarding functions avoid need for BOOST_FILESYSTEM_DECL for class +// basic_directory_iterator, and so avoid iterator_facade DLL template +// problems. They also overload to the proper external path character type. + + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_first( void *& handle, +#if defined(BOOST_POSIX_API) + void *& buffer, +#endif + const std::string & dir_path, + std::string & target, file_status & fs, file_status & symlink_fs ); + // eof: return==0 && handle==0 + + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_increment( void *& handle, +#if defined(BOOST_POSIX_API) + void *& buffer, +#endif + std::string & target, file_status & fs, file_status & symlink_fs ); + // eof: return==0 && handle==0 + + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_close( void *& handle +#if defined(BOOST_POSIX_API) + , void *& buffer +#endif + ); + // Effects: none if handle==0, otherwise close handle, set handle=0 + +# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM2_NARROW_ONLY) + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_first( void *& handle, const std::wstring & ph, + std::wstring & target, file_status & fs, file_status & symlink_fs ); + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_increment( void *& handle, std::wstring & target, + file_status & fs, file_status & symlink_fs ); +# endif + + template< class Path > + class dir_itr_imp + { + public: + basic_directory_entry<Path> m_directory_entry; + void * m_handle; +# ifdef BOOST_POSIX_API + void * m_buffer; // see dir_itr_increment implementation +# endif + dir_itr_imp() : m_handle(0) +# ifdef BOOST_POSIX_API + , m_buffer(0) +# endif + {} + + ~dir_itr_imp() { dir_itr_close( m_handle +#if defined(BOOST_POSIX_API) + , m_buffer +#endif + ); } + }; + + BOOST_FILESYSTEM_DECL system::error_code not_found_error(); + + } // namespace detail + +// basic_directory_iterator ------------------------------------------------// + + template< class Path > + class basic_directory_iterator + : public boost::iterator_facade< + basic_directory_iterator<Path>, + basic_directory_entry<Path>, + boost::single_pass_traversal_tag > + { + public: + typedef Path path_type; + + basic_directory_iterator(){} // creates the "end" iterator + + explicit basic_directory_iterator( const Path & dir_path ); + basic_directory_iterator( const Path & dir_path, system::error_code & ec ); + + private: + + // shared_ptr provides shallow-copy semantics required for InputIterators. + // m_imp.get()==0 indicates the end iterator. + boost::shared_ptr< detail::dir_itr_imp< Path > > m_imp; + + friend class boost::iterator_core_access; + + typename boost::iterator_facade< + basic_directory_iterator<Path>, + basic_directory_entry<Path>, + boost::single_pass_traversal_tag >::reference dereference() const + { + BOOST_ASSERT( m_imp.get() && "attempt to dereference end iterator" ); + return m_imp->m_directory_entry; + } + + void increment(); + + bool equal( const basic_directory_iterator & rhs ) const + { return m_imp == rhs.m_imp; } + + system::error_code m_init( const Path & dir_path ); + }; + + typedef basic_directory_iterator< path > directory_iterator; +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + typedef basic_directory_iterator< wpath > wdirectory_iterator; +# endif + + // basic_directory_iterator implementation ---------------------------// + + template<class Path> + system::error_code basic_directory_iterator<Path>::m_init( + const Path & dir_path ) + { + if ( dir_path.empty() ) + { + m_imp.reset(); + return detail::not_found_error(); + } + typename Path::external_string_type name; + file_status fs, symlink_fs; + system::error_code ec( detail::dir_itr_first( m_imp->m_handle, +#if defined(BOOST_POSIX_API) + m_imp->m_buffer, +#endif + dir_path.external_directory_string(), + name, fs, symlink_fs ) ); + + if ( ec ) + { + m_imp.reset(); + return ec; + } + + if ( m_imp->m_handle == 0 ) m_imp.reset(); // eof, so make end iterator + else // not eof + { + m_imp->m_directory_entry.assign( dir_path + / Path::traits_type::to_internal( name ), fs, symlink_fs ); + if ( name[0] == dot<Path>::value // dot or dot-dot + && (name.size() == 1 + || (name[1] == dot<Path>::value + && name.size() == 2)) ) + { increment(); } + } + return boost::system::error_code(); + } + + template<class Path> + basic_directory_iterator<Path>::basic_directory_iterator( + const Path & dir_path ) + : m_imp( new detail::dir_itr_imp<Path> ) + { + system::error_code ec( m_init(dir_path) ); + if ( ec ) + { + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::basic_directory_iterator constructor", + dir_path, ec ) ); + } + } + + template<class Path> + basic_directory_iterator<Path>::basic_directory_iterator( + const Path & dir_path, system::error_code & ec ) + : m_imp( new detail::dir_itr_imp<Path> ) + { + ec = m_init(dir_path); + } + + template<class Path> + void basic_directory_iterator<Path>::increment() + { + BOOST_ASSERT( m_imp.get() && "attempt to increment end iterator" ); + BOOST_ASSERT( m_imp->m_handle != 0 && "internal program error" ); + + typename Path::external_string_type name; + file_status fs, symlink_fs; + system::error_code ec; + + for (;;) + { + ec = detail::dir_itr_increment( m_imp->m_handle, +#if defined(BOOST_POSIX_API) + m_imp->m_buffer, +#endif + name, fs, symlink_fs ); + if ( ec ) + { + boost::throw_exception( basic_filesystem_error<Path>( + "boost::filesystem::basic_directory_iterator increment", + m_imp->m_directory_entry.path().parent_path(), ec ) ); + } + if ( m_imp->m_handle == 0 ) { m_imp.reset(); return; } // eof, make end + if ( !(name[0] == dot<Path>::value // !(dot or dot-dot) + && (name.size() == 1 + || (name[1] == dot<Path>::value + && name.size() == 2))) ) + { + m_imp->m_directory_entry.replace_filename( + Path::traits_type::to_internal( name ), fs, symlink_fs ); + return; + } + } + } + + // basic_directory_entry -----------------------------------------------// + + template<class Path> + class basic_directory_entry + { + public: + typedef Path path_type; + typedef typename Path::string_type string_type; + + // compiler generated copy-ctor, copy assignment, and destructor apply + + basic_directory_entry() {} + explicit basic_directory_entry( const path_type & p, + file_status st = file_status(), file_status symlink_st=file_status() ) + : m_path(p), m_status(st), m_symlink_status(symlink_st) + {} + + void assign( const path_type & p, + file_status st, file_status symlink_st ) + { m_path = p; m_status = st; m_symlink_status = symlink_st; } + + void replace_filename( const string_type & s, + file_status st, file_status symlink_st ) + { + m_path.remove_filename(); + m_path /= s; + m_status = st; + m_symlink_status = symlink_st; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + void replace_leaf( const string_type & s, + file_status st, file_status symlink_st ) + { replace_filename( s, st, symlink_st ); } +# endif + + const Path & path() const { return m_path; } + file_status status() const; + file_status status( system::error_code & ec ) const; + file_status symlink_status() const; + file_status symlink_status( system::error_code & ec ) const; + + // conversion simplifies the most common use of basic_directory_entry + operator const path_type &() const { return m_path; } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + // deprecated functions preserve common use cases in legacy code + typename Path::string_type filename() const + { + return path().filename(); + } + typename Path::string_type leaf() const + { + return path().filename(); + } + typename Path::string_type string() const + { + return path().string(); + } +# endif + + private: + path_type m_path; + mutable file_status m_status; // stat()-like + mutable file_status m_symlink_status; // lstat()-like + // note: m_symlink_status is not used by Windows implementation + + }; // basic_directory_status + + typedef basic_directory_entry<path> directory_entry; +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + typedef basic_directory_entry<wpath> wdirectory_entry; +# endif + + // basic_directory_entry implementation --------------------------------// + + template<class Path> + file_status + basic_directory_entry<Path>::status() const + { + if ( !status_known( m_status ) ) + { +# ifndef BOOST_WINDOWS_API + if ( status_known( m_symlink_status ) + && !is_symlink( m_symlink_status ) ) + { m_status = m_symlink_status; } + else { m_status = boost::filesystem2::status( m_path ); } +# else + m_status = boost::filesystem2::status( m_path ); +# endif + } + return m_status; + } + + template<class Path> + file_status + basic_directory_entry<Path>::status( system::error_code & ec ) const + { + if ( !status_known( m_status ) ) + { +# ifndef BOOST_WINDOWS_API + if ( status_known( m_symlink_status ) + && !is_symlink( m_symlink_status ) ) + { ec = boost::system::error_code();; m_status = m_symlink_status; } + else { m_status = boost::filesystem2::status( m_path, ec ); } +# else + m_status = boost::filesystem2::status( m_path, ec ); +# endif + } + else ec = boost::system::error_code();; + return m_status; + } + + template<class Path> + file_status + basic_directory_entry<Path>::symlink_status() const + { +# ifndef BOOST_WINDOWS_API + if ( !status_known( m_symlink_status ) ) + { m_symlink_status = boost::filesystem2::symlink_status( m_path ); } + return m_symlink_status; +# else + return status(); +# endif + } + + template<class Path> + file_status + basic_directory_entry<Path>::symlink_status( system::error_code & ec ) const + { +# ifndef BOOST_WINDOWS_API + if ( !status_known( m_symlink_status ) ) + { m_symlink_status = boost::filesystem2::symlink_status( m_path, ec ); } + else ec = boost::system::error_code();; + return m_symlink_status; +# else + return status( ec ); +# endif + } + } // namespace filesystem2 +} // namespace boost + +#undef BOOST_FS_FUNC + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + using filesystem2::basic_directory_entry; + using filesystem2::basic_directory_iterator; + using filesystem2::block_file; + using filesystem2::character_file; + using filesystem2::complete; + using filesystem2::copy_file; + using filesystem2::copy_option; + using filesystem2::create_directory; +# if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK) + using filesystem2::create_hard_link; +# endif + using filesystem2::create_symlink; + using filesystem2::current_path; + using filesystem2::directory_entry; + using filesystem2::directory_file; + using filesystem2::directory_iterator; + using filesystem2::equivalent; + using filesystem2::exists; + using filesystem2::fifo_file; + using filesystem2::file_not_found; + using filesystem2::file_size; + using filesystem2::file_status; + using filesystem2::file_type; + using filesystem2::initial_path; + using filesystem2::is_directory; + using filesystem2::is_directory; + using filesystem2::is_empty; + using filesystem2::is_other; + using filesystem2::is_regular_file; + using filesystem2::is_symlink; + using filesystem2::last_write_time; + using filesystem2::regular_file; + using filesystem2::remove; + using filesystem2::remove_all; + using filesystem2::rename; + using filesystem2::socket_file; + using filesystem2::space; + using filesystem2::space_info; + using filesystem2::status; + using filesystem2::status_known; + using filesystem2::symlink_file; + using filesystem2::symlink_status; + using filesystem2::system_complete; + using filesystem2::type_unknown; +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + using filesystem2::is_regular; + using filesystem2::symbolic_link_exists; +# endif +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + using filesystem2::wdirectory_iterator; + using filesystem2::wdirectory_entry; +# endif + namespace detail + { + using filesystem2::detail::not_found_error; + using filesystem2::detail::possible_large_file_size_support; + } + } +} + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM2_OPERATIONS_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/v2/path.hpp b/3rdParty/Boost/src/boost/filesystem/v2/path.hpp new file mode 100644 index 0000000..16d67ca --- /dev/null +++ b/3rdParty/Boost/src/boost/filesystem/v2/path.hpp @@ -0,0 +1,1572 @@ +// boost/filesystem/path.hpp -----------------------------------------------// + +// Copyright Beman Dawes 2002-2005 +// Copyright Vladimir Prus 2002 + +// 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 library home page at http://www.boost.org/libs/filesystem + +// basic_path's stem(), extension(), and replace_extension() are based on +// basename(), extension(), and change_extension() from the original +// filesystem/convenience.hpp header by Vladimir Prus. + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM2_PATH_HPP +#define BOOST_FILESYSTEM2_PATH_HPP + +#include <boost/filesystem/v2/config.hpp> +#include <boost/system/system_error.hpp> +#include <boost/iterator/iterator_facade.hpp> +#include <boost/throw_exception.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/static_assert.hpp> + +#include <string> +#include <algorithm> // for lexicographical_compare +#include <iosfwd> // needed by basic_path inserter and extractor +#include <stdexcept> +#include <cassert> + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY +# include <locale> +# endif + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +namespace boost +{ + namespace BOOST_FILESYSTEM2_NAMESPACE + { + template<class String, class Traits> class basic_path; + + struct path_traits; + typedef basic_path< std::string, path_traits > path; + + struct path_traits + { + typedef std::string internal_string_type; + typedef std::string external_string_type; + static external_string_type to_external( const path &, + const internal_string_type & src ) { return src; } + static internal_string_type to_internal( + const external_string_type & src ) { return src; } + }; + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + + struct BOOST_FILESYSTEM_DECL wpath_traits; + + typedef basic_path< std::wstring, wpath_traits > wpath; + + struct BOOST_FILESYSTEM_DECL wpath_traits + { + typedef std::wstring internal_string_type; +# ifdef BOOST_WINDOWS_API + typedef std::wstring external_string_type; + static external_string_type to_external( const wpath &, + const internal_string_type & src ) { return src; } + static internal_string_type to_internal( + const external_string_type & src ) { return src; } +# else + typedef std::string external_string_type; + static external_string_type to_external( const wpath & ph, + const internal_string_type & src ); + static internal_string_type to_internal( + const external_string_type & src ); +# endif + static void imbue( const std::locale & loc ); + static bool imbue( const std::locale & loc, const std::nothrow_t & ); + }; + +# endif // ifndef BOOST_FILESYSTEM2_NARROW_ONLY + + // path traits ---------------------------------------------------------// + + template<class Path> struct is_basic_path + { BOOST_STATIC_CONSTANT( bool, value = false ); }; + template<> struct is_basic_path<path> + { BOOST_STATIC_CONSTANT( bool, value = true ); }; +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + template<> struct is_basic_path<wpath> + { BOOST_STATIC_CONSTANT( bool, value = true ); }; +# endif + + // These only have to be specialized if Path::string_type::value_type + // is not convertible from char, although specializations may eliminate + // compiler warnings. See ticket 2543. + template<class Path> struct slash + { BOOST_STATIC_CONSTANT( char, value = '/' ); }; + + template<class Path> struct dot + { BOOST_STATIC_CONSTANT( char, value = '.' ); }; + + template<class Path> struct colon + { BOOST_STATIC_CONSTANT( char, value = ':' ); }; + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + template<> struct slash<wpath> + { BOOST_STATIC_CONSTANT( wchar_t, value = L'/' ); }; + template<> struct dot<wpath> + { BOOST_STATIC_CONSTANT( wchar_t, value = L'.' ); }; + template<> struct colon<wpath> + { BOOST_STATIC_CONSTANT( wchar_t, value = L':' ); }; +# endif + +# ifdef BOOST_WINDOWS_PATH + template<class Path> struct path_alt_separator + { BOOST_STATIC_CONSTANT( char, value = '\\' ); }; +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + template<> struct path_alt_separator<wpath> + { BOOST_STATIC_CONSTANT( wchar_t, value = L'\\' ); }; +# endif +# endif + + // workaround for VC++ 7.0 and earlier issues with nested classes + namespace detail + { + template<class Path> + class iterator_helper + { + public: + typedef typename Path::iterator iterator; + static void do_increment( iterator & ph ); + static void do_decrement( iterator & ph ); + }; + } + + // basic_path ----------------------------------------------------------// + + template<class String, class Traits> + class basic_path + { + // invariant: m_path valid according to the portable generic path grammar + + // validate template arguments +// TODO: get these working +// BOOST_STATIC_ASSERT( ::boost::is_same<String,typename Traits::internal_string_type>::value ); +// BOOST_STATIC_ASSERT( ::boost::is_same<typename Traits::external_string_type,std::string>::value || ::boost::is_same<typename Traits::external_string_type,std::wstring>::value ); + + public: + // compiler generates copy constructor and copy assignment + + typedef basic_path<String, Traits> path_type; + typedef String string_type; + typedef typename String::value_type value_type; + typedef Traits traits_type; + typedef typename Traits::external_string_type external_string_type; + + // constructors/destructor + basic_path() {} + basic_path( const string_type & s ) { operator/=( s ); } + basic_path( const value_type * s ) { operator/=( s ); } +# ifndef BOOST_NO_MEMBER_TEMPLATES + template <class InputIterator> + basic_path( InputIterator first, InputIterator last ) + { append( first, last ); } +# endif + ~basic_path() {} + + // assignments + basic_path & operator=( const string_type & s ) + { +# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310) + m_path.clear(); +# else + m_path.erase( m_path.begin(), m_path.end() ); +# endif + operator/=( s ); + return *this; + } + basic_path & operator=( const value_type * s ) + { +# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310) + m_path.clear(); +# else + m_path.erase( m_path.begin(), m_path.end() ); +# endif + operator/=( s ); + return *this; + } +# ifndef BOOST_NO_MEMBER_TEMPLATES + template <class InputIterator> + basic_path & assign( InputIterator first, InputIterator last ) + { m_path.clear(); append( first, last ); return *this; } +# endif + + // modifiers + basic_path & operator/=( const basic_path & rhs ) { return operator /=( rhs.string().c_str() ); } + basic_path & operator/=( const string_type & rhs ) { return operator /=( rhs.c_str() ); } + basic_path & operator/=( const value_type * s ); +# ifndef BOOST_NO_MEMBER_TEMPLATES + template <class InputIterator> + basic_path & append( InputIterator first, InputIterator last ); +# endif + + void clear() + { +# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310) + m_path.clear(); +# else + m_path.erase( m_path.begin(), m_path.end() ); +# endif + } + + void swap( basic_path & rhs ) + { + m_path.swap( rhs.m_path ); +# ifdef BOOST_CYGWIN_PATH + std::swap( m_cygwin_root, rhs.m_cygwin_root ); +# endif + } + + basic_path & remove_filename(); + basic_path & replace_extension( const string_type & new_extension = string_type() ); + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + basic_path & remove_leaf() { return remove_filename(); } +# endif + + // observers + const string_type & string() const { return m_path; } + const string_type file_string() const; + const string_type directory_string() const { return file_string(); } + + const external_string_type external_file_string() const { return Traits::to_external( *this, file_string() ); } + const external_string_type external_directory_string() const { return Traits::to_external( *this, directory_string() ); } + + basic_path root_path() const; + string_type root_name() const; + string_type root_directory() const; + basic_path relative_path() const; + basic_path parent_path() const; + string_type filename() const; + string_type stem() const; + string_type extension() const; + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + string_type leaf() const { return filename(); } + basic_path branch_path() const { return parent_path(); } + bool has_leaf() const { return !m_path.empty(); } + bool has_branch_path() const { return !parent_path().empty(); } +# endif + + bool empty() const { return m_path.empty(); } // name consistent with std containers + bool is_complete() const; + bool has_root_path() const; + bool has_root_name() const; + bool has_root_directory() const; + bool has_relative_path() const { return !relative_path().empty(); } + bool has_filename() const { return !m_path.empty(); } + bool has_parent_path() const { return !parent_path().empty(); } + + // iterators + class iterator : public boost::iterator_facade< + iterator, + string_type const, + boost::bidirectional_traversal_tag > + { + private: + friend class boost::iterator_core_access; + friend class boost::BOOST_FILESYSTEM2_NAMESPACE::basic_path<String, Traits>; + + const string_type & dereference() const + { return m_name; } + bool equal( const iterator & rhs ) const + { return m_path_ptr == rhs.m_path_ptr && m_pos == rhs.m_pos; } + + friend class boost::BOOST_FILESYSTEM2_NAMESPACE::detail::iterator_helper<path_type>; + + void increment() + { + boost::BOOST_FILESYSTEM2_NAMESPACE::detail::iterator_helper<path_type>::do_increment( + *this ); + } + void decrement() + { + boost::BOOST_FILESYSTEM2_NAMESPACE::detail::iterator_helper<path_type>::do_decrement( + *this ); + } + + string_type m_name; // current element + const basic_path * m_path_ptr; // path being iterated over + typename string_type::size_type m_pos; // position of name in + // path_ptr->string(). The + // end() iterator is indicated by + // pos == path_ptr->m_path.size() + }; // iterator + + typedef iterator const_iterator; + + iterator begin() const; + iterator end() const; + + private: + // Note: This is an implementation for POSIX and Windows, where there + // are only minor differences between generic and native path grammars. + // Private members might be quite different in other implementations, + // particularly where there were wide differences between portable and + // native path formats, or between file_string() and + // directory_string() formats, or simply that the implementation + // was willing expend additional memory to achieve greater speed for + // some operations at the expense of other operations. + + string_type m_path; // invariant: portable path grammar + // on Windows, backslashes converted to slashes + +# ifdef BOOST_CYGWIN_PATH + bool m_cygwin_root; // if present, m_path[0] was slash. note: initialization + // done by append +# endif + + void m_append_separator_if_needed(); + void m_append( value_type value ); // converts Windows alt_separator + + // Was qualified; como433beta8 reports: + // warning #427-D: qualified name is not allowed in member declaration + friend class iterator; + friend class boost::BOOST_FILESYSTEM2_NAMESPACE::detail::iterator_helper<path_type>; + + // Deprecated features ease transition for existing code. Don't use these + // in new code. +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + public: + typedef bool (*name_check)( const std::string & name ); + basic_path( const string_type & str, name_check ) { operator/=( str ); } + basic_path( const typename string_type::value_type * s, name_check ) + { operator/=( s );} + string_type native_file_string() const { return file_string(); } + string_type native_directory_string() const { return directory_string(); } + static bool default_name_check_writable() { return false; } + static void default_name_check( name_check ) {} + static name_check default_name_check() { return 0; } + basic_path & canonize(); + basic_path & normalize(); +# endif + }; + + // basic_path non-member functions ---------------------------------------// + + template< class String, class Traits > + inline void swap( basic_path<String, Traits> & lhs, + basic_path<String, Traits> & rhs ) { lhs.swap( rhs ); } + + template< class String, class Traits > + bool operator<( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) + { + return std::lexicographical_compare( + lhs.begin(), lhs.end(), rhs.begin(), rhs.end() ); + } + + template< class String, class Traits > + bool operator<( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) + { + basic_path<String, Traits> tmp( lhs ); + return std::lexicographical_compare( + tmp.begin(), tmp.end(), rhs.begin(), rhs.end() ); + } + + template< class String, class Traits > + bool operator<( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) + { + basic_path<String, Traits> tmp( lhs ); + return std::lexicographical_compare( + tmp.begin(), tmp.end(), rhs.begin(), rhs.end() ); + } + + template< class String, class Traits > + bool operator<( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { + basic_path<String, Traits> tmp( rhs ); + return std::lexicographical_compare( + lhs.begin(), lhs.end(), tmp.begin(), tmp.end() ); + } + + template< class String, class Traits > + bool operator<( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { + basic_path<String, Traits> tmp( rhs ); + return std::lexicographical_compare( + lhs.begin(), lhs.end(), tmp.begin(), tmp.end() ); + } + + // operator == uses hand-written compare rather than !(lhs < rhs) && !(rhs < lhs) + // because the result is the same yet the direct compare is much more efficient + // than lexicographical_compare, which would also be called twice. + + template< class String, class Traits > + inline bool operator==( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { + typedef typename + boost::BOOST_FILESYSTEM2_NAMESPACE::basic_path<String, Traits> path_type; + const typename path_type::string_type::value_type * l (lhs.string().c_str()); + while ( (*l == *rhs +# ifdef BOOST_WINDOWS_PATH + || (*l == path_alt_separator<path_type>::value && *rhs == slash<path_type>::value) + || (*l == slash<path_type>::value && *rhs == path_alt_separator<path_type>::value) +# endif + ) && *l ) { ++l; ++rhs; } + return *l == *rhs +# ifdef BOOST_WINDOWS_PATH + || (*l == path_alt_separator<path_type>::value && *rhs == slash<path_type>::value) + || (*l == slash<path_type>::value && *rhs == path_alt_separator<path_type>::value) +# endif + ; + } + + template< class String, class Traits > + inline bool operator==( const basic_path<String, Traits> & lhs, + const basic_path<String, Traits> & rhs ) + { + return lhs == rhs.string().c_str(); + } + + template< class String, class Traits > + inline bool operator==( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) + { + return rhs == lhs; + } + + template< class String, class Traits > + inline bool operator==( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) + { + return rhs == lhs.c_str(); + } + + template< class String, class Traits > + inline bool operator==( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { + return lhs == rhs.c_str(); + } + + template< class String, class Traits > + inline bool operator!=( const basic_path<String, Traits> & lhs, + const basic_path<String, Traits> & rhs ) + { return !(lhs == rhs); } + + template< class String, class Traits > + inline bool operator!=( const typename basic_path<String, + Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) + { return !(lhs == rhs); } + + template< class String, class Traits > + inline bool operator!=( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) + { return !(lhs == rhs); } + + template< class String, class Traits > + inline bool operator!=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { return !(lhs == rhs); } + + template< class String, class Traits > + inline bool operator!=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { return !(lhs == rhs); } + + template< class String, class Traits > + inline bool operator>( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return rhs < lhs; } + + template< class String, class Traits > + inline bool operator>( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) { return rhs < basic_path<String, Traits>(lhs); } + + template< class String, class Traits > + inline bool operator>( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) { return rhs < basic_path<String, Traits>(lhs); } + + template< class String, class Traits > + inline bool operator>( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { return basic_path<String, Traits>(rhs) < lhs; } + + template< class String, class Traits > + inline bool operator>( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { return basic_path<String, Traits>(rhs) < lhs; } + + template< class String, class Traits > + inline bool operator<=( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return !(rhs < lhs); } + + template< class String, class Traits > + inline bool operator<=( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) { return !(rhs < basic_path<String, Traits>(lhs)); } + + template< class String, class Traits > + inline bool operator<=( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) { return !(rhs < basic_path<String, Traits>(lhs)); } + + template< class String, class Traits > + inline bool operator<=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { return !(basic_path<String, Traits>(rhs) < lhs); } + + template< class String, class Traits > + inline bool operator<=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { return !(basic_path<String, Traits>(rhs) < lhs); } + + template< class String, class Traits > + inline bool operator>=( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return !(lhs < rhs); } + + template< class String, class Traits > + inline bool operator>=( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) { return !(lhs < basic_path<String, Traits>(rhs)); } + + template< class String, class Traits > + inline bool operator>=( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) { return !(lhs < basic_path<String, Traits>(rhs)); } + + template< class String, class Traits > + inline bool operator>=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { return !(basic_path<String, Traits>(lhs) < rhs); } + + template< class String, class Traits > + inline bool operator>=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { return !(basic_path<String, Traits>(lhs) < rhs); } + + // operator / + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const basic_path<String, Traits> & lhs, + const basic_path<String, Traits> & rhs ) + { return basic_path<String, Traits>( lhs ) /= rhs; } + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const basic_path<String, Traits> & lhs, + const typename String::value_type * rhs ) + { return basic_path<String, Traits>( lhs ) /= + basic_path<String, Traits>( rhs ); } + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const basic_path<String, Traits> & lhs, const String & rhs ) + { return basic_path<String, Traits>( lhs ) /= + basic_path<String, Traits>( rhs ); } + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const typename String::value_type * lhs, + const basic_path<String, Traits> & rhs ) + { return basic_path<String, Traits>( lhs ) /= rhs; } + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const String & lhs, const basic_path<String, Traits> & rhs ) + { return basic_path<String, Traits>( lhs ) /= rhs; } + + // inserters and extractors --------------------------------------------// + +// bypass VC++ 7.0 and earlier, and broken Borland compilers +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && !BOOST_WORKAROUND(__BORLANDC__, < 0x610) + template< class Path > + std::basic_ostream< typename Path::string_type::value_type, + typename Path::string_type::traits_type > & + operator<< + ( std::basic_ostream< typename Path::string_type::value_type, + typename Path::string_type::traits_type >& os, const Path & ph ) + { + os << ph.string(); + return os; + } + + template< class Path > + std::basic_istream< typename Path::string_type::value_type, + typename Path::string_type::traits_type > & + operator>> + ( std::basic_istream< typename Path::string_type::value_type, + typename Path::string_type::traits_type >& is, Path & ph ) + { + typename Path::string_type str; + std::getline(is, str); // See ticket 3863 + ph = str; + return is; + } +# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + template< class String, class Traits > + std::basic_ostream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type > & + operator<< + ( std::basic_ostream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type >& os, + const basic_path< String, Traits > & ph ) + { + os << ph.string(); + return os; + } + + template< class String, class Traits > + std::basic_istream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type > & + operator>> + ( std::basic_istream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type> & is, + basic_path< String, Traits > & ph ) + { + String str; + std::getline(is, str); // See ticket 3863 + ph = str; + return is; + } +# endif + + // basic_filesystem_error helpers --------------------------------------// + + // Originally choice of implementation was done via specialization of + // basic_filesystem_error::what(). Several compilers (GCC, aCC, etc.) + // couldn't handle that, so the choice is now accomplished by overloading. + + namespace detail + { + // BOOST_FILESYSTEM_DECL version works for VC++ but not GCC. Go figure! + inline + const char * what( const char * sys_err_what, + const path & path1_arg, const path & path2_arg, std::string & target ) + { + try + { + if ( target.empty() ) + { + target = sys_err_what; + if ( !path1_arg.empty() ) + { + target += ": \""; + target += path1_arg.file_string(); + target += "\""; + } + if ( !path2_arg.empty() ) + { + target += ", \""; + target += path2_arg.file_string(); + target += "\""; + } + } + return target.c_str(); + } + catch (...) + { + return sys_err_what; + } + } + + template<class Path> + const char * what( const char * sys_err_what, + const Path & /*path1_arg*/, const Path & /*path2_arg*/, std::string & /*target*/ ) + { + return sys_err_what; + } + } + + // basic_filesystem_error ----------------------------------------------// + + template<class Path> + class basic_filesystem_error : public system::system_error + { + // see http://www.boost.org/more/error_handling.html for design rationale + public: + // compiler generates copy constructor and copy assignment + + typedef Path path_type; + + basic_filesystem_error( const std::string & what_arg, + system::error_code ec ); + + basic_filesystem_error( const std::string & what_arg, + const path_type & path1_arg, system::error_code ec ); + + basic_filesystem_error( const std::string & what_arg, const path_type & path1_arg, + const path_type & path2_arg, system::error_code ec ); + + ~basic_filesystem_error() throw() {} + + const path_type & path1() const + { + static const path_type empty_path; + return m_imp_ptr.get() ? m_imp_ptr->m_path1 : empty_path ; + } + const path_type & path2() const + { + static const path_type empty_path; + return m_imp_ptr.get() ? m_imp_ptr->m_path2 : empty_path ; + } + + const char * what() const throw() + { + if ( !m_imp_ptr.get() ) + return system::system_error::what(); + return detail::what( system::system_error::what(), m_imp_ptr->m_path1, + m_imp_ptr->m_path2, m_imp_ptr->m_what ); + } + + private: + struct m_imp + { + path_type m_path1; // may be empty() + path_type m_path2; // may be empty() + std::string m_what; // not built until needed + }; + boost::shared_ptr<m_imp> m_imp_ptr; + }; + + typedef basic_filesystem_error<path> filesystem_error; + +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + typedef basic_filesystem_error<wpath> wfilesystem_error; +# endif + + // path::name_checks -----------------------------------------------------// + + BOOST_FILESYSTEM_DECL bool portable_posix_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool windows_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool portable_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool portable_directory_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool portable_file_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool native( const std::string & name ); + inline bool no_check( const std::string & ) + { return true; } + +// implementation -----------------------------------------------------------// + + namespace detail + { + + // is_separator helper ------------------------------------------------// + + template<class Path> + inline bool is_separator( typename Path::string_type::value_type c ) + { + return c == slash<Path>::value +# ifdef BOOST_WINDOWS_PATH + || c == path_alt_separator<Path>::value +# endif + ; + } + + // filename_pos helper ----------------------------------------------------// + + template<class String, class Traits> + typename String::size_type filename_pos( + const String & str, // precondition: portable generic path grammar + typename String::size_type end_pos ) // end_pos is past-the-end position + // return 0 if str itself is filename (or empty) + { + typedef typename + boost::BOOST_FILESYSTEM2_NAMESPACE::basic_path<String, Traits> path_type; + + // case: "//" + if ( end_pos == 2 + && str[0] == slash<path_type>::value + && str[1] == slash<path_type>::value ) return 0; + + // case: ends in "/" + if ( end_pos && str[end_pos-1] == slash<path_type>::value ) + return end_pos-1; + + // set pos to start of last element + typename String::size_type pos( + str.find_last_of( slash<path_type>::value, end_pos-1 ) ); +# ifdef BOOST_WINDOWS_PATH + if ( pos == String::npos ) + pos = str.find_last_of( path_alt_separator<path_type>::value, end_pos-1 ); + if ( pos == String::npos ) + pos = str.find_last_of( colon<path_type>::value, end_pos-2 ); +# endif + + return ( pos == String::npos // path itself must be a filename (or empty) + || (pos == 1 && str[0] == slash<path_type>::value) ) // or net + ? 0 // so filename is entire string + : pos + 1; // or starts after delimiter + } + + // first_element helper -----------------------------------------------// + // sets pos and len of first element, excluding extra separators + // if src.empty(), sets pos,len, to 0,0. + + template<class String, class Traits> + void first_element( + const String & src, // precondition: portable generic path grammar + typename String::size_type & element_pos, + typename String::size_type & element_size, +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1310 ) // VC++ 7.1 + typename String::size_type size = String::npos +# else + typename String::size_type size = -1 +# endif + ) + { + if ( size == String::npos ) size = src.size(); + element_pos = 0; + element_size = 0; + if ( src.empty() ) return; + + typedef typename boost::BOOST_FILESYSTEM2_NAMESPACE::basic_path<String, Traits> path_type; + + typename String::size_type cur(0); + + // deal with // [network] + if ( size >= 2 && src[0] == slash<path_type>::value + && src[1] == slash<path_type>::value + && (size == 2 + || src[2] != slash<path_type>::value) ) + { + cur += 2; + element_size += 2; + } + + // leading (not non-network) separator + else if ( src[0] == slash<path_type>::value ) + { + ++element_size; + // bypass extra leading separators + while ( cur+1 < size + && src[cur+1] == slash<path_type>::value ) + { + ++cur; + ++element_pos; + } + return; + } + + // at this point, we have either a plain name, a network name, + // or (on Windows only) a device name + + // find the end + while ( cur < size +# ifdef BOOST_WINDOWS_PATH + && src[cur] != colon<path_type>::value +# endif + && src[cur] != slash<path_type>::value ) + { + ++cur; + ++element_size; + } + +# ifdef BOOST_WINDOWS_PATH + if ( cur == size ) return; + // include device delimiter + if ( src[cur] == colon<path_type>::value ) + { ++element_size; } +# endif + + return; + } + + // root_directory_start helper ----------------------------------------// + + template<class String, class Traits> + typename String::size_type root_directory_start( + const String & s, // precondition: portable generic path grammar + typename String::size_type size ) + // return npos if no root_directory found + { + typedef typename boost::BOOST_FILESYSTEM2_NAMESPACE::basic_path<String, Traits> path_type; + +# ifdef BOOST_WINDOWS_PATH + // case "c:/" + if ( size > 2 + && s[1] == colon<path_type>::value + && s[2] == slash<path_type>::value ) return 2; +# endif + + // case "//" + if ( size == 2 + && s[0] == slash<path_type>::value + && s[1] == slash<path_type>::value ) return String::npos; + + // case "//net {/}" + if ( size > 3 + && s[0] == slash<path_type>::value + && s[1] == slash<path_type>::value + && s[2] != slash<path_type>::value ) + { + typename String::size_type pos( + s.find( slash<path_type>::value, 2 ) ); + return pos < size ? pos : String::npos; + } + + // case "/" + if ( size > 0 && s[0] == slash<path_type>::value ) return 0; + + return String::npos; + } + + // is_non_root_slash helper -------------------------------------------// + + template<class String, class Traits> + bool is_non_root_slash( const String & str, + typename String::size_type pos ) // pos is position of the slash + { + typedef typename + boost::BOOST_FILESYSTEM2_NAMESPACE::basic_path<String, Traits> + path_type; + + assert( !str.empty() && str[pos] == slash<path_type>::value + && "precondition violation" ); + + // subsequent logic expects pos to be for leftmost slash of a set + while ( pos > 0 && str[pos-1] == slash<path_type>::value ) + --pos; + + return pos != 0 + && (pos <= 2 || str[1] != slash<path_type>::value + || str.find( slash<path_type>::value, 2 ) != pos) +# ifdef BOOST_WINDOWS_PATH + && (pos !=2 || str[1] != colon<path_type>::value) +# endif + ; + } + } // namespace detail + + // decomposition functions ----------------------------------------------// + + template<class String, class Traits> + String basic_path<String, Traits>::filename() const + { + typename String::size_type end_pos( + detail::filename_pos<String, Traits>( m_path, m_path.size() ) ); + return (m_path.size() + && end_pos + && m_path[end_pos] == slash<path_type>::value + && detail::is_non_root_slash< String, Traits >(m_path, end_pos)) + ? String( 1, dot<path_type>::value ) + : m_path.substr( end_pos ); + } + + template<class String, class Traits> + String basic_path<String, Traits>::stem() const + { + string_type name = filename(); + typename string_type::size_type n = name.rfind(dot<path_type>::value); + return name.substr(0, n); + } + + template<class String, class Traits> + String basic_path<String, Traits>::extension() const + { + string_type name = filename(); + typename string_type::size_type n = name.rfind(dot<path_type>::value); + if (n != string_type::npos) + return name.substr(n); + else + return string_type(); + } + + template<class String, class Traits> + basic_path<String, Traits> basic_path<String, Traits>::parent_path() const + { + typename String::size_type end_pos( + detail::filename_pos<String, Traits>( m_path, m_path.size() ) ); + + bool filename_was_separator( m_path.size() + && m_path[end_pos] == slash<path_type>::value ); + + // skip separators unless root directory + typename string_type::size_type root_dir_pos( detail::root_directory_start + <string_type, traits_type>( m_path, end_pos ) ); + for ( ; + end_pos > 0 + && (end_pos-1) != root_dir_pos + && m_path[end_pos-1] == slash<path_type>::value + ; + --end_pos ) {} + + return (end_pos == 1 && root_dir_pos == 0 && filename_was_separator) + ? path_type() + : path_type( m_path.substr( 0, end_pos ) ); + } + + template<class String, class Traits> + basic_path<String, Traits> basic_path<String, Traits>::relative_path() const + { + iterator itr( begin() ); + for ( ; itr.m_pos != m_path.size() + && (itr.m_name[0] == slash<path_type>::value +# ifdef BOOST_WINDOWS_PATH + || itr.m_name[itr.m_name.size()-1] + == colon<path_type>::value +# endif + ); ++itr ) {} + + return basic_path<String, Traits>( m_path.substr( itr.m_pos ) ); + } + + template<class String, class Traits> + String basic_path<String, Traits>::root_name() const + { + iterator itr( begin() ); + + return ( itr.m_pos != m_path.size() + && ( + ( itr.m_name.size() > 1 + && itr.m_name[0] == slash<path_type>::value + && itr.m_name[1] == slash<path_type>::value + ) +# ifdef BOOST_WINDOWS_PATH + || itr.m_name[itr.m_name.size()-1] + == colon<path_type>::value +# endif + ) ) + ? *itr + : String(); + } + + template<class String, class Traits> + String basic_path<String, Traits>::root_directory() const + { + typename string_type::size_type start( + detail::root_directory_start<String, Traits>( m_path, m_path.size() ) ); + + return start == string_type::npos + ? string_type() + : m_path.substr( start, 1 ); + } + + template<class String, class Traits> + basic_path<String, Traits> basic_path<String, Traits>::root_path() const + { + // even on POSIX, root_name() is non-empty() on network paths + return basic_path<String, Traits>( root_name() ) /= root_directory(); + } + + // path query functions -------------------------------------------------// + + template<class String, class Traits> + inline bool basic_path<String, Traits>::is_complete() const + { +# ifdef BOOST_WINDOWS_PATH + return has_root_name() && has_root_directory(); +# else + return has_root_directory(); +# endif + } + + template<class String, class Traits> + inline bool basic_path<String, Traits>::has_root_path() const + { + return !root_path().empty(); + } + + template<class String, class Traits> + inline bool basic_path<String, Traits>::has_root_name() const + { + return !root_name().empty(); + } + + template<class String, class Traits> + inline bool basic_path<String, Traits>::has_root_directory() const + { + return !root_directory().empty(); + } + + // append ---------------------------------------------------------------// + + template<class String, class Traits> + void basic_path<String, Traits>::m_append_separator_if_needed() + // requires: !empty() + { + if ( +# ifdef BOOST_WINDOWS_PATH + *(m_path.end()-1) != colon<path_type>::value && +# endif + *(m_path.end()-1) != slash<path_type>::value ) + { + m_path += slash<path_type>::value; + } + } + + template<class String, class Traits> + void basic_path<String, Traits>::m_append( value_type value ) + { +# ifdef BOOST_CYGWIN_PATH + if ( m_path.empty() ) m_cygwin_root = (value == slash<path_type>::value); +# endif + +# ifdef BOOST_WINDOWS_PATH + // for BOOST_WINDOWS_PATH, convert alt_separator ('\') to separator ('/') + m_path += ( value == path_alt_separator<path_type>::value + ? slash<path_type>::value + : value ); +# else + m_path += value; +# endif + } + + // except that it wouldn't work for BOOST_NO_MEMBER_TEMPLATES compilers, + // the append() member template could replace this code. + template<class String, class Traits> + basic_path<String, Traits> & basic_path<String, Traits>::operator /= + ( const value_type * next_p ) + { + // ignore escape sequence on POSIX or Windows + if ( *next_p == slash<path_type>::value + && *(next_p+1) == slash<path_type>::value + && *(next_p+2) == colon<path_type>::value ) next_p += 3; + + // append slash<path_type>::value if needed + if ( !empty() && *next_p != 0 + && !detail::is_separator<path_type>( *next_p ) ) + { m_append_separator_if_needed(); } + + for ( ; *next_p != 0; ++next_p ) m_append( *next_p ); + return *this; + } + +# ifndef BOOST_NO_MEMBER_TEMPLATES + template<class String, class Traits> template <class InputIterator> + basic_path<String, Traits> & basic_path<String, Traits>::append( + InputIterator first, InputIterator last ) + { + // append slash<path_type>::value if needed + if ( !empty() && first != last + && !detail::is_separator<path_type>( *first ) ) + { m_append_separator_if_needed(); } + + // song-and-dance to avoid violating InputIterator requirements + // (which prohibit lookahead) in detecting a possible escape sequence + // (escape sequences are simply ignored on POSIX and Windows) + bool was_escape_sequence(true); + std::size_t append_count(0); + typename String::size_type initial_pos( m_path.size() ); + + for ( ; first != last && *first; ++first ) + { + if ( append_count == 0 && *first != slash<path_type>::value ) + was_escape_sequence = false; + if ( append_count == 1 && *first != slash<path_type>::value ) + was_escape_sequence = false; + if ( append_count == 2 && *first != colon<path_type>::value ) + was_escape_sequence = false; + m_append( *first ); + ++append_count; + } + + // erase escape sequence if any + if ( was_escape_sequence && append_count >= 3 ) + m_path.erase( initial_pos, 3 ); + + return *this; + } +# endif + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + + // canonize ------------------------------------------------------------// + + template<class String, class Traits> + basic_path<String, Traits> & basic_path<String, Traits>::canonize() + { + static const typename string_type::value_type dot_str[] + = { dot<path_type>::value, 0 }; + + if ( m_path.empty() ) return *this; + + path_type temp; + + for ( iterator itr( begin() ); itr != end(); ++itr ) + { + temp /= *itr; + }; + + if ( temp.empty() ) temp /= dot_str; + m_path = temp.m_path; + return *this; + } + + // normalize ------------------------------------------------------------// + + template<class String, class Traits> + basic_path<String, Traits> & basic_path<String, Traits>::normalize() + { + static const typename string_type::value_type dot_str[] + = { dot<path_type>::value, 0 }; + + if ( m_path.empty() ) return *this; + + path_type temp; + iterator start( begin() ); + iterator last( end() ); + iterator stop( last-- ); + for ( iterator itr( start ); itr != stop; ++itr ) + { + // ignore "." except at start and last + if ( itr->size() == 1 + && (*itr)[0] == dot<path_type>::value + && itr != start + && itr != last ) continue; + + // ignore a name and following ".." + if ( !temp.empty() + && itr->size() == 2 + && (*itr)[0] == dot<path_type>::value + && (*itr)[1] == dot<path_type>::value ) // dot dot + { + string_type lf( temp.filename() ); + if ( lf.size() > 0 + && (lf.size() != 1 + || (lf[0] != dot<path_type>::value + && lf[0] != slash<path_type>::value)) + && (lf.size() != 2 + || (lf[0] != dot<path_type>::value + && lf[1] != dot<path_type>::value +# ifdef BOOST_WINDOWS_PATH + && lf[1] != colon<path_type>::value +# endif + ) + ) + ) + { + temp.remove_filename(); + // if not root directory, must also remove "/" if any + if ( temp.m_path.size() > 0 + && temp.m_path[temp.m_path.size()-1] + == slash<path_type>::value ) + { + typename string_type::size_type rds( + detail::root_directory_start<String,Traits>( temp.m_path, + temp.m_path.size() ) ); + if ( rds == string_type::npos + || rds != temp.m_path.size()-1 ) + { temp.m_path.erase( temp.m_path.size()-1 ); } + } + + iterator next( itr ); + if ( temp.empty() && ++next != stop + && next == last && *last == dot_str ) temp /= dot_str; + continue; + } + } + + temp /= *itr; + }; + + if ( temp.empty() ) temp /= dot_str; + m_path = temp.m_path; + return *this; + } + +# endif + + // modifiers ------------------------------------------------------------// + + template<class String, class Traits> + basic_path<String, Traits> & basic_path<String, Traits>::remove_filename() + { + m_path.erase( + detail::filename_pos<String, Traits>( m_path, m_path.size() ) ); + return *this; + } + + template<class String, class Traits> + basic_path<String, Traits> & + basic_path<String, Traits>::replace_extension( const string_type & new_ext ) + { + // erase existing extension if any + string_type old_ext = extension(); + if ( !old_ext.empty() ) + m_path.erase( m_path.size() - old_ext.size() ); + + if ( !new_ext.empty() && new_ext[0] != dot<path_type>::value ) + m_path += dot<path_type>::value; + + m_path += new_ext; + + return *this; + } + + + // path conversion functions --------------------------------------------// + + template<class String, class Traits> + const String + basic_path<String, Traits>::file_string() const + { +# ifdef BOOST_WINDOWS_PATH + // for Windows, use the alternate separator, and bypass extra + // root separators + + typename string_type::size_type root_dir_start( + detail::root_directory_start<String, Traits>( m_path, m_path.size() ) ); + bool in_root( root_dir_start != string_type::npos ); + String s; + for ( typename string_type::size_type pos( 0 ); + pos != m_path.size(); ++pos ) + { + // special case // [net] + if ( pos == 0 && m_path.size() > 1 + && m_path[0] == slash<path_type>::value + && m_path[1] == slash<path_type>::value + && ( m_path.size() == 2 + || !detail::is_separator<path_type>( m_path[2] ) + ) ) + { + ++pos; + s += path_alt_separator<path_type>::value; + s += path_alt_separator<path_type>::value; + continue; + } + + // bypass extra root separators + if ( in_root ) + { + if ( s.size() > 0 + && s[s.size()-1] == path_alt_separator<path_type>::value + && m_path[pos] == slash<path_type>::value + ) continue; + } + + if ( m_path[pos] == slash<path_type>::value ) + s += path_alt_separator<path_type>::value; + else + s += m_path[pos]; + + if ( pos > root_dir_start + && m_path[pos] == slash<path_type>::value ) + { in_root = false; } + } +# ifdef BOOST_CYGWIN_PATH + if ( m_cygwin_root ) s[0] = slash<path_type>::value; +# endif + return s; +# else + return m_path; +# endif + } + + // iterator functions ---------------------------------------------------// + + template<class String, class Traits> + typename basic_path<String, Traits>::iterator basic_path<String, Traits>::begin() const + { + iterator itr; + itr.m_path_ptr = this; + typename string_type::size_type element_size; + detail::first_element<String, Traits>( m_path, itr.m_pos, element_size ); + itr.m_name = m_path.substr( itr.m_pos, element_size ); + return itr; + } + + template<class String, class Traits> + typename basic_path<String, Traits>::iterator basic_path<String, Traits>::end() const + { + iterator itr; + itr.m_path_ptr = this; + itr.m_pos = m_path.size(); + return itr; + } + + namespace detail + { + // do_increment ------------------------------------------------------// + + template<class Path> + void iterator_helper<Path>::do_increment( iterator & itr ) + { + typedef typename Path::string_type string_type; + typedef typename Path::traits_type traits_type; + + assert( itr.m_pos < itr.m_path_ptr->m_path.size() && "basic_path::iterator increment past end()" ); + + bool was_net( itr.m_name.size() > 2 + && itr.m_name[0] == slash<Path>::value + && itr.m_name[1] == slash<Path>::value + && itr.m_name[2] != slash<Path>::value ); + + // increment to position past current element + itr.m_pos += itr.m_name.size(); + + // if end reached, create end iterator + if ( itr.m_pos == itr.m_path_ptr->m_path.size() ) + { + itr.m_name.erase( itr.m_name.begin(), itr.m_name.end() ); // VC++ 6.0 lib didn't supply clear() + return; + } + + // process separator (Windows drive spec is only case not a separator) + if ( itr.m_path_ptr->m_path[itr.m_pos] == slash<Path>::value ) + { + // detect root directory + if ( was_net + # ifdef BOOST_WINDOWS_PATH + // case "c:/" + || itr.m_name[itr.m_name.size()-1] == colon<Path>::value + # endif + ) + { + itr.m_name = slash<Path>::value; + return; + } + + // bypass separators + while ( itr.m_pos != itr.m_path_ptr->m_path.size() + && itr.m_path_ptr->m_path[itr.m_pos] == slash<Path>::value ) + { ++itr.m_pos; } + + // detect trailing separator, and treat it as ".", per POSIX spec + if ( itr.m_pos == itr.m_path_ptr->m_path.size() + && detail::is_non_root_slash< string_type, traits_type >( + itr.m_path_ptr->m_path, itr.m_pos-1 ) ) + { + --itr.m_pos; + itr.m_name = dot<Path>::value; + return; + } + } + + // get next element + typename string_type::size_type end_pos( + itr.m_path_ptr->m_path.find( slash<Path>::value, itr.m_pos ) ); + itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos ); + } + + // do_decrement ------------------------------------------------------// + + template<class Path> + void iterator_helper<Path>::do_decrement( iterator & itr ) + { + assert( itr.m_pos && "basic_path::iterator decrement past begin()" ); + + typedef typename Path::string_type string_type; + typedef typename Path::traits_type traits_type; + + typename string_type::size_type end_pos( itr.m_pos ); + + typename string_type::size_type root_dir_pos( + detail::root_directory_start<string_type, traits_type>( + itr.m_path_ptr->m_path, end_pos ) ); + + // if at end and there was a trailing non-root '/', return "." + if ( itr.m_pos == itr.m_path_ptr->m_path.size() + && itr.m_path_ptr->m_path.size() > 1 + && itr.m_path_ptr->m_path[itr.m_pos-1] == slash<Path>::value + && detail::is_non_root_slash< string_type, traits_type >( + itr.m_path_ptr->m_path, itr.m_pos-1 ) + ) + { + --itr.m_pos; + itr.m_name = dot<Path>::value; + return; + } + + // skip separators unless root directory + for ( + ; + end_pos > 0 + && (end_pos-1) != root_dir_pos + && itr.m_path_ptr->m_path[end_pos-1] == slash<Path>::value + ; + --end_pos ) {} + + itr.m_pos = detail::filename_pos<string_type, traits_type> + ( itr.m_path_ptr->m_path, end_pos ); + itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos ); + } + } // namespace detail + + // basic_filesystem_error implementation --------------------------------// + + template<class Path> + basic_filesystem_error<Path>::basic_filesystem_error( + const std::string & what_arg, system::error_code ec ) + : system::system_error(ec, what_arg) + { + try + { + m_imp_ptr.reset( new m_imp ); + } + catch (...) { m_imp_ptr.reset(); } + } + + template<class Path> + basic_filesystem_error<Path>::basic_filesystem_error( + const std::string & what_arg, const path_type & path1_arg, + system::error_code ec ) + : system::system_error(ec, what_arg) + { + try + { + m_imp_ptr.reset( new m_imp ); + m_imp_ptr->m_path1 = path1_arg; + } + catch (...) { m_imp_ptr.reset(); } + } + + template<class Path> + basic_filesystem_error<Path>::basic_filesystem_error( + const std::string & what_arg, const path_type & path1_arg, + const path_type & path2_arg, system::error_code ec ) + : system::system_error(ec, what_arg) + { + try + { + m_imp_ptr.reset( new m_imp ); + m_imp_ptr->m_path1 = path1_arg; + m_imp_ptr->m_path2 = path2_arg; + } + catch (...) { m_imp_ptr.reset(); } + } + + } // namespace BOOST_FILESYSTEM2_NAMESPACE +} // namespace boost + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + using filesystem2::basic_path; + using filesystem2::path_traits; + + using filesystem2::slash; + using filesystem2::dot; + using filesystem2::colon; + + using filesystem2::path; +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY + using filesystem2::wpath_traits; + using filesystem2::wpath; + using filesystem2::wfilesystem_error; +# endif + using filesystem2::basic_filesystem_error; + using filesystem2::filesystem_error; + using filesystem2::portable_posix_name; + using filesystem2::windows_name; + using filesystem2::portable_name; + using filesystem2::portable_directory_name; + using filesystem2::portable_file_name; + using filesystem2::native; + using filesystem2::no_check; + using filesystem2::swap; + using filesystem2::operator<; + using filesystem2::operator==; + using filesystem2::operator!=; + using filesystem2::operator>; + using filesystem2::operator<=; + using filesystem2::operator>=; + using filesystem2::operator/; + using filesystem2::operator<<; + using filesystem2::operator>>; + } +} + +//----------------------------------------------------------------------------// + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas + +#endif // BOOST_FILESYSTEM2_PATH_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/v3/config.hpp b/3rdParty/Boost/src/boost/filesystem/v3/config.hpp new file mode 100644 index 0000000..13fc308 --- /dev/null +++ b/3rdParty/Boost/src/boost/filesystem/v3/config.hpp @@ -0,0 +1,85 @@ +// boost/filesystem/v3/config.hpp ----------------------------------------------------// + +// Copyright Beman Dawes 2003 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM3_CONFIG_HPP +#define BOOST_FILESYSTEM3_CONFIG_HPP + +# if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION != 3 +# error Compiling Filesystem version 3 file with BOOST_FILESYSTEM_VERSION defined != 3 +# endif + +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 3 +# endif + +#define BOOST_FILESYSTEM_I18N // aid users wishing to compile several versions + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +#include <boost/config.hpp> +#include <boost/system/api_config.hpp> // for BOOST_POSIX_API or BOOST_WINDOWS_API +#include <boost/detail/workaround.hpp> + +// BOOST_FILESYSTEM_DEPRECATED needed for source compiles -----------------------------// + +# ifdef BOOST_FILESYSTEM_SOURCE +# define BOOST_FILESYSTEM_DEPRECATED +# endif + +// throw an exception ----------------------------------------------------------------// +// +// Exceptions were originally thrown via boost::throw_exception(). +// As throw_exception() became more complex, it caused user error reporting +// to be harder to interpret, since the exception reported became much more complex. +// The immediate fix was to throw directly, wrapped in a macro to make any later change +// easier. + +#define BOOST_FILESYSTEM_THROW(EX) throw EX + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +// enable dynamic linking -------------------------------------------------------------// + +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) +# if defined(BOOST_FILESYSTEM_SOURCE) +# define BOOST_FILESYSTEM_DECL BOOST_SYMBOL_EXPORT +# else +# define BOOST_FILESYSTEM_DECL BOOST_SYMBOL_IMPORT +# endif +#else +# define BOOST_FILESYSTEM_DECL +#endif + +// enable automatic library variant selection ----------------------------------------// + +#if !defined(BOOST_FILESYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) \ + && !defined(BOOST_FILESYSTEM_NO_LIB) +// +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_filesystem +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include <boost/config/auto_link.hpp> +#endif // auto-linking disabled + +#endif // BOOST_FILESYSTEM3_CONFIG_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/v3/convenience.hpp b/3rdParty/Boost/src/boost/filesystem/v3/convenience.hpp new file mode 100644 index 0000000..1a1f943 --- /dev/null +++ b/3rdParty/Boost/src/boost/filesystem/v3/convenience.hpp @@ -0,0 +1,74 @@ +// boost/filesystem/convenience.hpp ----------------------------------------// + +// Copyright Beman Dawes, 2002-2005 +// Copyright Vladimir Prus, 2002 +// 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 library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM3_CONVENIENCE_HPP +#define BOOST_FILESYSTEM3_CONVENIENCE_HPP + +#include <boost/config.hpp> + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include <boost/filesystem/v3/operations.hpp> +#include <boost/system/error_code.hpp> + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +namespace boost +{ + namespace filesystem3 + { + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + + inline std::string extension(const path & p) + { + return p.extension().string(); + } + + inline std::string basename(const path & p) + { + return p.stem().string(); + } + + inline path change_extension( const path & p, const path & new_extension ) + { + path new_p( p ); + new_p.replace_extension( new_extension ); + return new_p; + } + +# endif + + + } // namespace filesystem3 +} // namespace boost + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + using filesystem3::extension; + using filesystem3::basename; + using filesystem3::change_extension; +# endif + } +} + +//----------------------------------------------------------------------------// + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM3_CONVENIENCE_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/v3/exception.hpp b/3rdParty/Boost/src/boost/filesystem/v3/exception.hpp new file mode 100644 index 0000000..985cd8f --- /dev/null +++ b/3rdParty/Boost/src/boost/filesystem/v3/exception.hpp @@ -0,0 +1,9 @@ +// boost/filesystem/exception.hpp -----------------------------------------------------// + +// Copyright Beman Dawes 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) + +// This header is no longer used. The contents have been moved to path.hpp. +// It is provided so that user code #includes do not have to be changed. diff --git a/3rdParty/Boost/src/boost/filesystem/v3/fstream.hpp b/3rdParty/Boost/src/boost/filesystem/v3/fstream.hpp new file mode 100644 index 0000000..235aa79 --- /dev/null +++ b/3rdParty/Boost/src/boost/filesystem/v3/fstream.hpp @@ -0,0 +1,207 @@ +// boost/filesystem/fstream.hpp ------------------------------------------------------// + +// Copyright Beman Dawes 2002 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM3_FSTREAM_HPP +#define BOOST_FILESYSTEM3_FSTREAM_HPP + +#include <boost/config.hpp> + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include <boost/filesystem/v3/path.hpp> +#include <iosfwd> +#include <fstream> + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +// on Windows, except for standard libaries known to have wchar_t overloads for +// file stream I/O, use path::string() to get a narrow character c_str() +#if defined(BOOST_WINDOWS_API) \ + && !(defined(_CPPLIB_VER) && _CPPLIB_VER >= 405) // not (Dinkumware with overloads) +# define BOOST_FILESYSTEM_C_STR string().c_str() // use narrow, since wide not available +#else // use the native c_str, which will be narrow on POSIX, wide on Windows +# define BOOST_FILESYSTEM_C_STR c_str() +#endif + +namespace boost +{ +namespace filesystem3 +{ + +//--------------------------------------------------------------------------------------// +// basic_filebuf // +//--------------------------------------------------------------------------------------// + + template < class charT, class traits = std::char_traits<charT> > + class basic_filebuf : public std::basic_filebuf<charT,traits> + { + private: // disallow copying + basic_filebuf(const basic_filebuf&); + const basic_filebuf& operator=(const basic_filebuf&); + + public: + basic_filebuf() {} + virtual ~basic_filebuf() {} + + basic_filebuf<charT,traits>* + open(const path& p, std::ios_base::openmode mode) + { + return std::basic_filebuf<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, mode) + ? this : 0; + } + }; + +//--------------------------------------------------------------------------------------// +// basic_ifstream // +//--------------------------------------------------------------------------------------// + + template < class charT, class traits = std::char_traits<charT> > + class basic_ifstream : public std::basic_ifstream<charT,traits> + { + private: // disallow copying + basic_ifstream(const basic_ifstream&); + const basic_ifstream& operator=(const basic_ifstream&); + + public: + basic_ifstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + + explicit basic_ifstream(const path& p) + : std::basic_ifstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, std::ios_base::in) {} + + basic_ifstream(const path& p, std::ios_base::openmode mode) + : std::basic_ifstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, mode) {} + + void open(const path& p) + { std::basic_ifstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, std::ios_base::in); } + + void open(const path& p, std::ios_base::openmode mode) + { std::basic_ifstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, mode); } + + virtual ~basic_ifstream() {} + }; + +//--------------------------------------------------------------------------------------// +// basic_ofstream // +//--------------------------------------------------------------------------------------// + + template < class charT, class traits = std::char_traits<charT> > + class basic_ofstream : public std::basic_ofstream<charT,traits> + { + private: // disallow copying + basic_ofstream(const basic_ofstream&); + const basic_ofstream& operator=(const basic_ofstream&); + + public: + basic_ofstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + + explicit basic_ofstream(const path& p) + : std::basic_ofstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, std::ios_base::out) {} + + basic_ofstream(const path& p, std::ios_base::openmode mode) + : std::basic_ofstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, mode) {} + + void open(const path& p) + { std::basic_ofstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, std::ios_base::out); } + + void open(const path& p, std::ios_base::openmode mode) + { std::basic_ofstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, mode); } + + virtual ~basic_ofstream() {} + }; + +//--------------------------------------------------------------------------------------// +// basic_fstream // +//--------------------------------------------------------------------------------------// + + template < class charT, class traits = std::char_traits<charT> > + class basic_fstream : public std::basic_fstream<charT,traits> + { + private: // disallow copying + basic_fstream(const basic_fstream&); + const basic_fstream & operator=(const basic_fstream&); + + public: + basic_fstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + + explicit basic_fstream(const path& p) + : std::basic_fstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, + std::ios_base::in | std::ios_base::out) {} + + basic_fstream(const path& p, std::ios_base::openmode mode) + : std::basic_fstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, mode) {} + + void open(const path& p) + { std::basic_fstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, + std::ios_base::in | std::ios_base::out); } + + void open(const path& p, std::ios_base::openmode mode) + { std::basic_fstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, mode); } + + virtual ~basic_fstream() {} + + }; + +//--------------------------------------------------------------------------------------// +// typedefs // +//--------------------------------------------------------------------------------------// + + typedef basic_filebuf<char> filebuf; + typedef basic_ifstream<char> ifstream; + typedef basic_ofstream<char> ofstream; + typedef basic_fstream<char> fstream; + + typedef basic_filebuf<wchar_t> wfilebuf; + typedef basic_ifstream<wchar_t> wifstream; + typedef basic_ofstream<wchar_t> wofstream; + typedef basic_fstream<wchar_t> wfstream; + +} // namespace filesystem3 +} // namespace boost + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + using filesystem3::filebuf; + using filesystem3::ifstream; + using filesystem3::ofstream; + using filesystem3::fstream; + using filesystem3::wfilebuf; + using filesystem3::wifstream; + using filesystem3::wfstream; + using filesystem3::wofstream; + using filesystem3::basic_filebuf; + using filesystem3::basic_ifstream; + using filesystem3::basic_ofstream; + using filesystem3::basic_fstream; + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED +# endif + } +} + +//----------------------------------------------------------------------------// + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM3_FSTREAM_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/v3/operations.hpp b/3rdParty/Boost/src/boost/filesystem/v3/operations.hpp new file mode 100644 index 0000000..cf47c56 --- /dev/null +++ b/3rdParty/Boost/src/boost/filesystem/v3/operations.hpp @@ -0,0 +1,1007 @@ +// boost/filesystem/operations.hpp ---------------------------------------------------// + +// Copyright Beman Dawes 2002-2009 +// Copyright Jan Langer 2002 +// Copyright Dietmar Kuehl 2001 +// Copyright Vladimir Prus 2002 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM3_OPERATIONS_HPP +#define BOOST_FILESYSTEM3_OPERATIONS_HPP + +#include <boost/config.hpp> + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include <boost/filesystem/v3/config.hpp> +#include <boost/filesystem/v3/path.hpp> + +#include <boost/detail/scoped_enum_emulation.hpp> +#include <boost/system/error_code.hpp> +#include <boost/system/system_error.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/iterator.hpp> +#include <boost/cstdint.hpp> +#include <boost/assert.hpp> + +#include <string> +#include <utility> // for pair +#include <ctime> +#include <vector> +#include <stack> + +#ifdef BOOST_WINDOWS_API +# include <fstream> +#endif + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +//--------------------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem3 + { + +//--------------------------------------------------------------------------------------// +// // +// support classes and enums // +// // +//--------------------------------------------------------------------------------------// + + enum file_type + { + status_error, +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + status_unknown = status_error, +# endif + file_not_found, + regular_file, + directory_file, + // the following may not apply to some operating systems or file systems + symlink_file, + block_file, + character_file, + fifo_file, + socket_file, + reparse_file, // Windows: FILE_ATTRIBUTE_REPARSE_POINT that is not a symlink + type_unknown, // file does exist, but isn't one of the above types or + // we don't have strong enough permission to find its type + + _detail_directory_symlink // internal use only; never exposed to users + }; + + class BOOST_FILESYSTEM_DECL file_status + { + public: + explicit file_status(file_type v = status_error) : m_value(v) {} + + void type(file_type v) { m_value = v; } + file_type type() const { return m_value; } + + bool operator==(const file_status& rhs) const { return type() == rhs.type(); } + bool operator!=(const file_status& rhs) const { return !(*this == rhs); } + + private: + // the internal representation is unspecified so that additional state + // information such as permissions can be added in the future; this + // implementation just uses file_type as the internal representation + + file_type m_value; + }; + + inline bool status_known(file_status f) { return f.type() != status_error; } + inline bool exists(file_status f) { return f.type() != status_error + && f.type() != file_not_found; } + inline bool is_regular_file(file_status f){ return f.type() == regular_file; } + inline bool is_directory(file_status f) { return f.type() == directory_file; } + inline bool is_symlink(file_status f) { return f.type() == symlink_file; } + inline bool is_other(file_status f) { return exists(f) && !is_regular_file(f) + && !is_directory(f) && !is_symlink(f); } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool is_regular(file_status f) { return f.type() == regular_file; } +# endif + + struct space_info + { + // all values are byte counts + boost::uintmax_t capacity; + boost::uintmax_t free; // <= capacity + boost::uintmax_t available; // <= free + }; + + BOOST_SCOPED_ENUM_START(copy_option) + {fail_if_exists, overwrite_if_exists}; + BOOST_SCOPED_ENUM_END + +//--------------------------------------------------------------------------------------// +// implementation details // +//--------------------------------------------------------------------------------------// + + namespace detail + { + BOOST_FILESYSTEM_DECL + file_status status(const path&p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + file_status symlink_status(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + bool is_empty(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path initial_path(system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void copy(const path& from, const path& to, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void copy_directory(const path& from, const path& to, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void copy_file(const path& from, const path& to, + BOOST_SCOPED_ENUM(copy_option) option, // See ticket #2925 + system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + bool create_directories(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + bool create_directory(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void create_directory_symlink(const path& to, const path& from, + system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void create_hard_link(const path& to, const path& from, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void create_symlink(const path& to, const path& from, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path current_path(system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void current_path(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + bool equivalent(const path& p1, const path& p2, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + boost::uintmax_t file_size(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + boost::uintmax_t hard_link_count(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + std::time_t last_write_time(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void last_write_time(const path& p, const std::time_t new_time, + system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path read_symlink(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + // For standardization, if the committee doesn't like "remove", consider "eliminate" + bool remove(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + boost::uintmax_t remove_all(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void rename(const path& old_p, const path& new_p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void resize_file(const path& p, uintmax_t size, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + space_info space(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path system_complete(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path unique_path(const path& p, system::error_code* ec=0); + } // namespace detail + +//--------------------------------------------------------------------------------------// +// // +// status query functions // +// // +//--------------------------------------------------------------------------------------// + + inline + file_status status(const path& p) {return detail::status(p);} + inline + file_status status(const path& p, system::error_code& ec) + {return detail::status(p, &ec);} + inline + file_status symlink_status(const path& p) {return detail::symlink_status(p);} + inline + file_status symlink_status(const path& p, system::error_code& ec) + {return detail::symlink_status(p, &ec);} + inline + bool exists(const path& p) {return exists(detail::status(p));} + inline + bool exists(const path& p, system::error_code& ec) + {return exists(detail::status(p, &ec));} + inline + bool is_directory(const path& p) {return is_directory(detail::status(p));} + inline + bool is_directory(const path& p, system::error_code& ec) + {return is_directory(detail::status(p, &ec));} + inline + bool is_regular_file(const path& p) {return is_regular_file(detail::status(p));} + inline + bool is_regular_file(const path& p, system::error_code& ec) + {return is_regular_file(detail::status(p, &ec));} + inline + bool is_other(const path& p) {return is_other(detail::status(p));} + inline + bool is_other(const path& p, system::error_code& ec) + {return is_other(detail::status(p, &ec));} + inline + bool is_symlink(const path& p) {return is_symlink(detail::symlink_status(p));} + inline + bool is_symlink(const path& p, system::error_code& ec) + {return is_symlink(detail::symlink_status(p, &ec));} +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline + bool is_regular(const path& p) {return is_regular(detail::status(p));} + inline + bool is_regular(const path& p, system::error_code& ec) + {return is_regular(detail::status(p, &ec));} +# endif + + inline + bool is_empty(const path& p) {return detail::is_empty(p);} + inline + bool is_empty(const path& p, system::error_code& ec) + {return detail::is_empty(p, &ec);} + +//--------------------------------------------------------------------------------------// +// // +// operational functions // +// in alphabetical order, unless otherwise noted // +// // +//--------------------------------------------------------------------------------------// + + // forward declarations + path current_path(); // fwd declaration +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + path initial_path(); +# endif + + BOOST_FILESYSTEM_DECL + path absolute(const path& p, const path& base=current_path()); + // If base.is_absolute(), throws nothing. Thus no need for ec argument + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline + path complete(const path& p) + { + return absolute(p, initial_path()); + } + + inline + path complete(const path& p, const path& base) + { + return absolute(p, base); + } +# endif + + inline + void copy(const path& from, const path& to) {detail::copy(from, to);} + + inline + void copy(const path& from, const path& to, system::error_code& ec) + {detail::copy(from, to, &ec);} + inline + void copy_directory(const path& from, const path& to) + {detail::copy_directory(from, to);} + inline + void copy_directory(const path& from, const path& to, system::error_code& ec) + {detail::copy_directory(from, to, &ec);} + inline + void copy_file(const path& from, const path& to, // See ticket #2925 + BOOST_SCOPED_ENUM(copy_option) option) + {detail::copy_file(from, to, option);} + inline + void copy_file(const path& from, const path& to) + {detail::copy_file(from, to, copy_option::fail_if_exists);} + inline + void copy_file(const path& from, const path& to, // See ticket #2925 + BOOST_SCOPED_ENUM(copy_option) option, system::error_code& ec) + {detail::copy_file(from, to, option, &ec);} + inline + void copy_file(const path& from, const path& to, system::error_code& ec) + {detail::copy_file(from, to, copy_option::fail_if_exists, &ec);} + inline + void copy_symlink(const path& existing_symlink, const path& new_symlink) {detail::copy_symlink(existing_symlink, new_symlink);} + + inline + void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code& ec) + {detail::copy_symlink(existing_symlink, new_symlink, &ec);} + inline + bool create_directories(const path& p) {return detail::create_directories(p);} + + inline + bool create_directories(const path& p, system::error_code& ec) + {return detail::create_directories(p, &ec);} + inline + bool create_directory(const path& p) {return detail::create_directory(p);} + + inline + bool create_directory(const path& p, system::error_code& ec) + {return detail::create_directory(p, &ec);} + inline + void create_directory_symlink(const path& to, const path& from) + {detail::create_directory_symlink(to, from);} + inline + void create_directory_symlink(const path& to, const path& from, system::error_code& ec) + {detail::create_directory_symlink(to, from, &ec);} + inline + void create_hard_link(const path& to, const path& from) {detail::create_hard_link(to, from);} + + inline + void create_hard_link(const path& to, const path& from, system::error_code& ec) + {detail::create_hard_link(to, from, &ec);} + inline + void create_symlink(const path& to, const path& from) {detail::create_symlink(to, from);} + + inline + void create_symlink(const path& to, const path& from, system::error_code& ec) + {detail::create_symlink(to, from, &ec);} + inline + path current_path() {return detail::current_path();} + + inline + path current_path(system::error_code& ec) {return detail::current_path(&ec);} + + inline + void current_path(const path& p) {detail::current_path(p);} + + inline + void current_path(const path& p, system::error_code& ec) {detail::current_path(p, &ec);} + + inline + bool equivalent(const path& p1, const path& p2) {return detail::equivalent(p1, p2);} + + inline + bool equivalent(const path& p1, const path& p2, system::error_code& ec) + {return detail::equivalent(p1, p2, &ec);} + inline + boost::uintmax_t file_size(const path& p) {return detail::file_size(p);} + + inline + boost::uintmax_t file_size(const path& p, system::error_code& ec) + {return detail::file_size(p, &ec);} + inline + boost::uintmax_t hard_link_count(const path& p) {return detail::hard_link_count(p);} + + inline + boost::uintmax_t hard_link_count(const path& p, system::error_code& ec) + {return detail::hard_link_count(p, &ec);} +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline + path initial_path() {return detail::initial_path();} + + inline + path initial_path(system::error_code& ec) {return detail::initial_path(&ec);} + + template <class Path> + path initial_path() {return initial_path();} + template <class Path> + path initial_path(system::error_code& ec) {return detail::initial_path(&ec);} +# endif + + inline + std::time_t last_write_time(const path& p) {return detail::last_write_time(p);} + + inline + std::time_t last_write_time(const path& p, system::error_code& ec) + {return detail::last_write_time(p, &ec);} + inline + void last_write_time(const path& p, const std::time_t new_time) + {detail::last_write_time(p, new_time);} + inline + void last_write_time(const path& p, const std::time_t new_time, system::error_code& ec) + {detail::last_write_time(p, new_time, &ec);} + inline + path read_symlink(const path& p) {return detail::read_symlink(p);} + + inline + path read_symlink(const path& p, system::error_code& ec) + {return detail::read_symlink(p, &ec);} + inline + // For standardization, if the committee doesn't like "remove", consider "eliminate" + bool remove(const path& p) {return detail::remove(p);} + + inline + bool remove(const path& p, system::error_code& ec) {return detail::remove(p, &ec);} + + inline + boost::uintmax_t remove_all(const path& p) {return detail::remove_all(p);} + + inline + boost::uintmax_t remove_all(const path& p, system::error_code& ec) + {return detail::remove_all(p, &ec);} + inline + void rename(const path& old_p, const path& new_p) {detail::rename(old_p, new_p);} + + inline + void rename(const path& old_p, const path& new_p, system::error_code& ec) + {detail::rename(old_p, new_p, &ec);} + inline // name suggested by Scott McMurray + void resize_file(const path& p, uintmax_t size) {detail::resize_file(p, size);} + + inline + void resize_file(const path& p, uintmax_t size, system::error_code& ec) + {detail::resize_file(p, size, &ec);} + inline + space_info space(const path& p) {return detail::space(p);} + + inline + space_info space(const path& p, system::error_code& ec) {return detail::space(p, &ec);} + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool symbolic_link_exists(const path& p) + { return is_symlink(symlink_status(p)); } +# endif + + inline + path system_complete(const path& p) {return detail::system_complete(p);} + + inline + path system_complete(const path& p, system::error_code& ec) + {return detail::system_complete(p, &ec);} + inline + path unique_path(const path& p="%%%%-%%%%-%%%%-%%%%") + { return detail::unique_path(p); } + inline + path unique_path(const path& p, system::error_code& ec) + { return detail::unique_path(p, &ec); } + +//--------------------------------------------------------------------------------------// +// // +// directory_entry // +// // +//--------------------------------------------------------------------------------------// + +// GCC has a problem with a member function named path within a namespace or +// sub-namespace that also has a class named path. The workaround is to always +// fully qualify the name path when it refers to the class name. + +class BOOST_FILESYSTEM_DECL directory_entry +{ +public: + + // compiler generated copy constructor, copy assignment, and destructor apply + + directory_entry() {} + explicit directory_entry(const boost::filesystem::path& p, + file_status st = file_status(), file_status symlink_st=file_status()) + : m_path(p), m_status(st), m_symlink_status(symlink_st) + {} + + void assign(const boost::filesystem::path& p, + file_status st = file_status(), file_status symlink_st = file_status()) + { m_path = p; m_status = st; m_symlink_status = symlink_st; } + + void replace_filename(const boost::filesystem::path& p, + file_status st = file_status(), file_status symlink_st = file_status()) + { + m_path.remove_filename(); + m_path /= p; + m_status = st; + m_symlink_status = symlink_st; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + void replace_leaf(const boost::filesystem::path& p, + file_status st, file_status symlink_st) + { replace_filename(p, st, symlink_st); } +# endif + + const boost::filesystem::path& path() const {return m_path;} + file_status status() const {return m_get_status();} + file_status status(system::error_code& ec) const {return m_get_status(&ec);} + file_status symlink_status() const {return m_get_symlink_status();} + file_status symlink_status(system::error_code& ec) const {return m_get_symlink_status(&ec);} + + bool operator==(const directory_entry& rhs) {return m_path == rhs.m_path;} + bool operator!=(const directory_entry& rhs) {return m_path != rhs.m_path;} + bool operator< (const directory_entry& rhs) {return m_path < rhs.m_path;} + bool operator<=(const directory_entry& rhs) {return m_path <= rhs.m_path;} + bool operator> (const directory_entry& rhs) {return m_path > rhs.m_path;} + bool operator>=(const directory_entry& rhs) {return m_path >= rhs.m_path;} + +private: + boost::filesystem::path m_path; + mutable file_status m_status; // stat()-like + mutable file_status m_symlink_status; // lstat()-like + + file_status m_get_status(system::error_code* ec=0) const; + file_status m_get_symlink_status(system::error_code* ec=0) const; +}; // directory_entry + +//--------------------------------------------------------------------------------------// +// // +// directory_iterator helpers // +// // +//--------------------------------------------------------------------------------------// + +class directory_iterator; + +namespace detail +{ + BOOST_FILESYSTEM_DECL + system::error_code dir_itr_close(// never throws() + void *& handle +# if defined(BOOST_POSIX_API) + , void *& buffer +# endif + ); + + struct dir_itr_imp + { + directory_entry dir_entry; + void* handle; + +# ifdef BOOST_POSIX_API + void* buffer; // see dir_itr_increment implementation +# endif + + dir_itr_imp() : handle(0) +# ifdef BOOST_POSIX_API + , buffer(0) +# endif + {} + + ~dir_itr_imp() // never throws + { + dir_itr_close(handle +# if defined(BOOST_POSIX_API) + , buffer +# endif + ); + } + }; + + // see path::iterator: comment below + BOOST_FILESYSTEM_DECL void directory_iterator_construct(directory_iterator& it, + const path& p, system::error_code* ec); + BOOST_FILESYSTEM_DECL void directory_iterator_increment(directory_iterator& it, + system::error_code* ec); + +} // namespace detail + +//--------------------------------------------------------------------------------------// +// // +// directory_iterator // +// // +//--------------------------------------------------------------------------------------// + + class directory_iterator + : public boost::iterator_facade< directory_iterator, + directory_entry, + boost::single_pass_traversal_tag > + { + public: + + directory_iterator(){} // creates the "end" iterator + + // iterator_facade derived classes don't seem to like implementations in + // separate translation unit dll's, so forward to detail functions + explicit directory_iterator(const path& p) + : m_imp(new detail::dir_itr_imp) + { detail::directory_iterator_construct(*this, p, 0); } + + directory_iterator(const path& p, system::error_code& ec) + : m_imp(new detail::dir_itr_imp) + { detail::directory_iterator_construct(*this, p, &ec); } + + ~directory_iterator() {} // never throws + + directory_iterator& increment(system::error_code& ec) + { + detail::directory_iterator_increment(*this, &ec); + return *this; + } + + private: + friend struct detail::dir_itr_imp; + friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_construct(directory_iterator& it, + const path& p, system::error_code* ec); + friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_increment(directory_iterator& it, + system::error_code* ec); + + // shared_ptr provides shallow-copy semantics required for InputIterators. + // m_imp.get()==0 indicates the end iterator. + boost::shared_ptr< detail::dir_itr_imp > m_imp; + + friend class boost::iterator_core_access; + + boost::iterator_facade< + directory_iterator, + directory_entry, + boost::single_pass_traversal_tag >::reference dereference() const + { + BOOST_ASSERT(m_imp.get() && "attempt to dereference end iterator"); + return m_imp->dir_entry; + } + + void increment() { detail::directory_iterator_increment(*this, 0); } + + bool equal(const directory_iterator& rhs) const + { return m_imp == rhs.m_imp; } + }; + +//--------------------------------------------------------------------------------------// +// // +// recursive_directory_iterator helpers // +// // +//--------------------------------------------------------------------------------------// + + namespace detail + { + struct recur_dir_itr_imp + { + typedef directory_iterator element_type; + std::stack< element_type, std::vector< element_type > > m_stack; + int m_level; + bool m_no_push_request; + + recur_dir_itr_imp() : m_level(0), m_no_push_request(false) {} + + void increment(system::error_code* ec); // ec == 0 means throw on error + + void pop(); + + }; + + // Implementation is inline to avoid dynamic linking difficulties with m_stack: + // Microsoft warning C4251, m_stack needs to have dll-interface to be used by + // clients of struct 'boost::filesystem::detail::recur_dir_itr_imp' + + inline + void recur_dir_itr_imp::increment(system::error_code* ec) + // ec == 0 means throw on error + { + if (m_no_push_request) + { m_no_push_request = false; } + else if (is_directory(m_stack.top()->status())) + { + if (ec == 0) + m_stack.push(directory_iterator(m_stack.top()->path())); + else + { + m_stack.push(directory_iterator(m_stack.top()->path(), *ec)); + if (*ec) return; + } + if (m_stack.top() != directory_iterator()) + { + ++m_level; + return; + } + m_stack.pop(); + } + + while (!m_stack.empty() && ++m_stack.top() == directory_iterator()) + { + m_stack.pop(); + --m_level; + } + } + + inline + void recur_dir_itr_imp::pop() + { + BOOST_ASSERT(m_level > 0 && "pop() on recursive_directory_iterator with level < 1"); + + do + { + m_stack.pop(); + --m_level; + } + while (!m_stack.empty() && ++m_stack.top() == directory_iterator()); + } + } // namespace detail + +//--------------------------------------------------------------------------------------// +// // +// recursive_directory_iterator // +// // +//--------------------------------------------------------------------------------------// + + class recursive_directory_iterator + : public boost::iterator_facade< + recursive_directory_iterator, + directory_entry, + boost::single_pass_traversal_tag > + { + public: + + recursive_directory_iterator(){} // creates the "end" iterator + + explicit recursive_directory_iterator(const path& dir_path) + : m_imp(new detail::recur_dir_itr_imp) + { + m_imp->m_stack.push(directory_iterator(dir_path)); + if (m_imp->m_stack.top() == directory_iterator()) + { m_imp.reset (); } + } + + recursive_directory_iterator(const path& dir_path, + system::error_code & ec) + : m_imp(new detail::recur_dir_itr_imp) + { + m_imp->m_stack.push(directory_iterator(dir_path, ec)); + if (m_imp->m_stack.top() == directory_iterator()) + { m_imp.reset (); } + } + + recursive_directory_iterator& increment(system::error_code* ec) + { + BOOST_ASSERT(m_imp.get() && "increment() on end recursive_directory_iterator"); + m_imp->increment(ec); + return *this; + } + + int level() const + { + BOOST_ASSERT(m_imp.get() && "level() on end recursive_directory_iterator"); + return m_imp->m_level; + } + + bool no_push_request() const + { + BOOST_ASSERT(m_imp.get() && "no_push_request() on end recursive_directory_iterator"); + return m_imp->m_no_push_request; + } + + void pop() + { + BOOST_ASSERT(m_imp.get() && "pop() on end recursive_directory_iterator"); + m_imp->pop(); + if (m_imp->m_stack.empty()) m_imp.reset(); // done, so make end iterator + } + + void no_push() + { + BOOST_ASSERT(m_imp.get() && "no_push() on end recursive_directory_iterator"); + m_imp->m_no_push_request = true; + } + + file_status status() const + { + BOOST_ASSERT(m_imp.get() + && "status() on end recursive_directory_iterator"); + return m_imp->m_stack.top()->status(); + } + + file_status symlink_status() const + { + BOOST_ASSERT(m_imp.get() + && "symlink_status() on end recursive_directory_iterator"); + return m_imp->m_stack.top()->symlink_status(); + } + + private: + + // shared_ptr provides shallow-copy semantics required for InputIterators. + // m_imp.get()==0 indicates the end iterator. + boost::shared_ptr< detail::recur_dir_itr_imp > m_imp; + + friend class boost::iterator_core_access; + + boost::iterator_facade< + recursive_directory_iterator, + directory_entry, + boost::single_pass_traversal_tag >::reference + dereference() const + { + BOOST_ASSERT(m_imp.get() && "dereference of end recursive_directory_iterator"); + return *m_imp->m_stack.top(); + } + + void increment() + { + BOOST_ASSERT(m_imp.get() && "increment of end recursive_directory_iterator"); + m_imp->increment(0); + if (m_imp->m_stack.empty()) m_imp.reset(); // done, so make end iterator + } + + bool equal(const recursive_directory_iterator& rhs) const + { return m_imp == rhs.m_imp; } + + }; + +# if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) + typedef recursive_directory_iterator wrecursive_directory_iterator; +# endif + +//--------------------------------------------------------------------------------------// +// // +// class filesystem_error // +// // +//--------------------------------------------------------------------------------------// + + class BOOST_SYMBOL_VISIBLE filesystem_error : public system::system_error + { + // see http://www.boost.org/more/error_handling.html for design rationale + + // all functions are inline to avoid issues with crossing dll boundaries + + public: + // compiler generates copy constructor and copy assignment + + filesystem_error( + const std::string & what_arg, system::error_code ec) + : system::system_error(ec, what_arg) + { + try + { + m_imp_ptr.reset(new m_imp); + } + catch (...) { m_imp_ptr.reset(); } + } + + filesystem_error( + const std::string & what_arg, const path& path1_arg, + system::error_code ec) + : system::system_error(ec, what_arg) + { + try + { + m_imp_ptr.reset(new m_imp); + m_imp_ptr->m_path1 = path1_arg; + } + catch (...) { m_imp_ptr.reset(); } + } + + filesystem_error( + const std::string & what_arg, const path& path1_arg, + const path& path2_arg, system::error_code ec) + : system::system_error(ec, what_arg) + { + try + { + m_imp_ptr.reset(new m_imp); + m_imp_ptr->m_path1 = path1_arg; + m_imp_ptr->m_path2 = path2_arg; + } + catch (...) { m_imp_ptr.reset(); } + } + + ~filesystem_error() throw() {} + + const path& path1() const + { + static const path empty_path; + return m_imp_ptr.get() ? m_imp_ptr->m_path1 : empty_path ; + } + const path& path2() const + { + static const path empty_path; + return m_imp_ptr.get() ? m_imp_ptr->m_path2 : empty_path ; + } + + const char* what() const throw() + { + if (!m_imp_ptr.get()) + return system::system_error::what(); + + try + { + if (m_imp_ptr->m_what.empty()) + { + m_imp_ptr->m_what = system::system_error::what(); + if (!m_imp_ptr->m_path1.empty()) + { + m_imp_ptr->m_what += ": \""; + m_imp_ptr->m_what += m_imp_ptr->m_path1.string(); + m_imp_ptr->m_what += "\""; + } + if (!m_imp_ptr->m_path2.empty()) + { + m_imp_ptr->m_what += ", \""; + m_imp_ptr->m_what += m_imp_ptr->m_path2.string(); + m_imp_ptr->m_what += "\""; + } + } + return m_imp_ptr->m_what.c_str(); + } + catch (...) + { + return system::system_error::what(); + } + } + + private: + struct m_imp + { + path m_path1; // may be empty() + path m_path2; // may be empty() + std::string m_what; // not built until needed + }; + boost::shared_ptr<m_imp> m_imp_ptr; + }; + +// test helper -----------------------------------------------------------------------// + +// Not part of the documented interface since false positives are possible; +// there is no law that says that an OS that has large stat.st_size +// actually supports large file sizes. + + namespace detail + { + BOOST_FILESYSTEM_DECL bool possible_large_file_size_support(); + } + + } // namespace filesystem3 +} // namespace boost + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + using filesystem3::absolute; + using filesystem3::block_file; + using filesystem3::character_file; +// using filesystem3::copy; + using filesystem3::copy_file; + using filesystem3::copy_option; + using filesystem3::copy_symlink; + using filesystem3::create_directories; + using filesystem3::create_directory; + using filesystem3::create_hard_link; + using filesystem3::create_symlink; + using filesystem3::create_directory_symlink; + using filesystem3::current_path; + using filesystem3::directory_entry; + using filesystem3::directory_file; + using filesystem3::directory_iterator; + using filesystem3::equivalent; + using filesystem3::exists; + using filesystem3::fifo_file; + using filesystem3::file_not_found; + using filesystem3::file_size; + using filesystem3::file_status; + using filesystem3::file_type; + using filesystem3::filesystem_error; + using filesystem3::hard_link_count; + using filesystem3::is_directory; + using filesystem3::is_directory; + using filesystem3::is_empty; + using filesystem3::is_other; + using filesystem3::is_regular_file; + using filesystem3::is_symlink; + using filesystem3::last_write_time; + using filesystem3::read_symlink; + using filesystem3::recursive_directory_iterator; + using filesystem3::regular_file; + using filesystem3::remove; + using filesystem3::remove_all; + using filesystem3::rename; + using filesystem3::resize_file; + using filesystem3::socket_file; + using filesystem3::space; + using filesystem3::space_info; + using filesystem3::status; + using filesystem3::status_error; + using filesystem3::status_known; + using filesystem3::symlink_file; + using filesystem3::symlink_status; + using filesystem3::system_complete; + using filesystem3::type_unknown; + using filesystem3::unique_path; +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + using filesystem3::initial_path; + using filesystem3::is_regular; + using filesystem3::status_unknown; + using filesystem3::symbolic_link_exists; + //using filesystem3::wdirectory_iterator; + //using filesystem3::wdirectory_entry; +# endif + namespace detail + { + using filesystem3::detail::possible_large_file_size_support; + } + } +} + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM3_OPERATIONS_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/v3/path.hpp b/3rdParty/Boost/src/boost/filesystem/v3/path.hpp new file mode 100644 index 0000000..1cd1522 --- /dev/null +++ b/3rdParty/Boost/src/boost/filesystem/v3/path.hpp @@ -0,0 +1,714 @@ +// filesystem path.hpp ---------------------------------------------------------------// + +// Copyright Beman Dawes 2002-2005, 2009 +// Copyright Vladimir Prus 2002 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +// path::stem(), extension(), and replace_extension() are based on +// basename(), extension(), and change_extension() from the original +// filesystem/convenience.hpp header by Vladimir Prus. + +#ifndef BOOST_FILESYSTEM_PATH_HPP +#define BOOST_FILESYSTEM_PATH_HPP + +#include <boost/config.hpp> + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include <boost/filesystem/v3/config.hpp> +#include <boost/filesystem/v3/path_traits.hpp> // includes <cwchar> +#include <boost/system/error_code.hpp> +#include <boost/system/system_error.hpp> +#include <boost/iterator/iterator_facade.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/io/detail/quoted_manip.hpp> +#include <boost/static_assert.hpp> +#include <string> +#include <iterator> +#include <cstring> +#include <iosfwd> +#include <stdexcept> +#include <cassert> +#include <locale> +#include <algorithm> + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +namespace boost +{ +namespace filesystem3 +{ + //------------------------------------------------------------------------------------// + // // + // class path // + // // + //------------------------------------------------------------------------------------// + + class BOOST_FILESYSTEM_DECL path + { + public: + + // value_type is the character type used by the operating system API to + // represent paths. + +# ifdef BOOST_WINDOWS_API + typedef wchar_t value_type; +# else + typedef char value_type; +# endif + typedef std::basic_string<value_type> string_type; + typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type; + + + // ----- character encoding conversions ----- + + // Following the principle of least astonishment, path input arguments + // passed to or obtained from the operating system via objects of + // class path behave as if they were directly passed to or + // obtained from the O/S API, unless conversion is explicitly requested. + // + // POSIX specfies that path strings are passed unchanged to and from the + // API. Note that this is different from the POSIX command line utilities, + // which convert according to a locale. + // + // Thus for POSIX, char strings do not undergo conversion. wchar_t strings + // are converted to/from char using the path locale or, if a conversion + // argument is given, using a conversion object modeled on + // std::wstring_convert. + // + // The path locale, which is global to the thread, can be changed by the + // imbue() function. It is initialized to an implementation defined locale. + // + // For Windows, wchar_t strings do not undergo conversion. char strings + // are converted using the "ANSI" or "OEM" code pages, as determined by + // the AreFileApisANSI() function, or, if a conversion argument is given, + // using a conversion object modeled on std::wstring_convert. + // + // See m_pathname comments for further important rationale. + + // TODO: rules needed for operating systems that use / or . + // differently, or format directory paths differently from file paths. + // + // ************************************************************************ + // + // More work needed: How to handle an operating system that may have + // slash characters or dot characters in valid filenames, either because + // it doesn't follow the POSIX standard, or because it allows MBCS + // filename encodings that may contain slash or dot characters. For + // example, ISO/IEC 2022 (JIS) encoding which allows switching to + // JIS x0208-1983 encoding. A valid filename in this set of encodings is + // 0x1B 0x24 0x42 [switch to X0208-1983] 0x24 0x2F [U+304F Kiragana letter KU] + // ^^^^ + // Note that 0x2F is the ASCII slash character + // + // ************************************************************************ + + // Supported source arguments: half-open iterator range, container, c-array, + // and single pointer to null terminated string. + + // All source arguments except pointers to null terminated byte strings support + // multi-byte character strings which may have embedded nulls. Embedded null + // support is required for some Asian languages on Windows. + + // "const codecvt_type& cvt=codecvt()" default arguments are not used because some + // compilers, such as Microsoft prior to VC++ 10, do not handle defaults correctly + // in templates. + + // ----- constructors ----- + + path(){} + + path(const path& p) : m_pathname(p.m_pathname) {} + + template <class Source> + path(Source const& source, + typename boost::enable_if<path_traits::is_pathable< + typename boost::decay<Source>::type> >::type* =0) + { + path_traits::dispatch(source, m_pathname, codecvt()); + } + + template <class Source> + path(Source const& source, const codecvt_type& cvt) + // see note above explaining why codecvt() default arguments are not used + { + path_traits::dispatch(source, m_pathname, cvt); + } + + template <class InputIterator> + path(InputIterator begin, InputIterator end) + { + if (begin != end) + { + std::basic_string<typename std::iterator_traits<InputIterator>::value_type> + s(begin, end); + path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, codecvt()); + } + } + + template <class InputIterator> + path(InputIterator begin, InputIterator end, const codecvt_type& cvt) + { + if (begin != end) + { + std::basic_string<typename std::iterator_traits<InputIterator>::value_type> + s(begin, end); + path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt); + } + } + + // ----- assignments ----- + + path& operator=(const path& p) + { + m_pathname = p.m_pathname; + return *this; + } + + template <class Source> + typename boost::enable_if<path_traits::is_pathable< + typename boost::decay<Source>::type>, path&>::type + operator=(Source const& source) + { + m_pathname.clear(); + path_traits::dispatch(source, m_pathname, codecvt()); + return *this; + } + + template <class Source> + path& assign(Source const& source, const codecvt_type& cvt) + { + m_pathname.clear(); + path_traits::dispatch(source, m_pathname, cvt); + return *this; + } + + template <class InputIterator> + path& assign(InputIterator begin, InputIterator end) + { + return assign(begin, end, codecvt()); + } + + template <class InputIterator> + path& assign(InputIterator begin, InputIterator end, const codecvt_type& cvt) + { + m_pathname.clear(); + if (begin != end) + { + std::basic_string<typename std::iterator_traits<InputIterator>::value_type> + s(begin, end); + path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt); + } + return *this; + } + + // ----- appends ----- + + // if a separator is added, it is the preferred separator for the platform; + // slash for POSIX, backslash for Windows + + path& operator/=(const path& p); + + template <class Source> + typename boost::enable_if<path_traits::is_pathable< + typename boost::decay<Source>::type>, path&>::type + operator/=(Source const& source) + { + return append(source, codecvt()); + } + + template <class Source> + path& append(Source const& source, const codecvt_type& cvt); + + template <class InputIterator> + path& append(InputIterator begin, InputIterator end) + { + return append(begin, end, codecvt()); + } + + template <class InputIterator> + path& append(InputIterator begin, InputIterator end, const codecvt_type& cvt); + + // ----- modifiers ----- + + void clear() { m_pathname.clear(); } + path& make_preferred() +# ifdef BOOST_POSIX_API + { return *this; } // POSIX no effect +# else // BOOST_WINDOWS_API + ; // change slashes to backslashes +# endif + path& remove_filename(); + path& replace_extension(const path& new_extension = path()); + void swap(path& rhs) { m_pathname.swap(rhs.m_pathname); } + + // ----- observers ----- + + // For operating systems that format file paths differently than directory + // paths, return values from observers are formatted as file names unless there + // is a trailing separator, in which case returns are formatted as directory + // paths. POSIX and Windows make no such distinction. + + // Implementations are permitted to return const values or const references. + + // The string or path returned by an observer are specified as being formatted + // as "native" or "generic". + // + // For POSIX, these are all the same format; slashes and backslashes are as input and + // are not modified. + // + // For Windows, native: as input; slashes and backslashes are not modified; + // this is the format of the internally stored string. + // generic: backslashes are converted to slashes + + // ----- native format observers ----- + + const string_type& native() const { return m_pathname; } // Throws: nothing + const value_type* c_str() const { return m_pathname.c_str(); } // Throws: nothing + + template <class String> + String string() const; + + template <class String> + String string(const codecvt_type& cvt) const; + +# ifdef BOOST_WINDOWS_API + const std::string string() const { return string(codecvt()); } + const std::string string(const codecvt_type& cvt) const + { + std::string tmp; + if (!m_pathname.empty()) + path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(), + tmp, cvt); + return tmp; + } + + // string_type is std::wstring, so there is no conversion + const std::wstring& wstring() const { return m_pathname; } + const std::wstring& wstring(const codecvt_type&) const { return m_pathname; } + +# else // BOOST_POSIX_API + // string_type is std::string, so there is no conversion + const std::string& string() const { return m_pathname; } + const std::string& string(const codecvt_type&) const { return m_pathname; } + + const std::wstring wstring() const { return wstring(codecvt()); } + const std::wstring wstring(const codecvt_type& cvt) const + { + std::wstring tmp; + if (!m_pathname.empty()) + path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(), + tmp, cvt); + return tmp; + } + +# endif + + // ----- generic format observers ----- + + template <class String> + String generic_string() const; + + template <class String> + String generic_string(const codecvt_type& cvt) const; + +# ifdef BOOST_WINDOWS_API + const std::string generic_string() const { return generic_string(codecvt()); } + const std::string generic_string(const codecvt_type& cvt) const; + const std::wstring generic_wstring() const; + const std::wstring generic_wstring(const codecvt_type&) const { return generic_wstring(); }; + +# else // BOOST_POSIX_API + // On POSIX-like systems, the generic format is the same as the native format + const std::string& generic_string() const { return m_pathname; } + const std::string& generic_string(const codecvt_type&) const { return m_pathname; } + const std::wstring generic_wstring() const { return wstring(codecvt()); } + const std::wstring generic_wstring(const codecvt_type& cvt) const { return wstring(cvt); } + +# endif + + // ----- decomposition ----- + + path root_path() const; + path root_name() const; // returns 0 or 1 element path + // even on POSIX, root_name() is non-empty() for network paths + path root_directory() const; // returns 0 or 1 element path + path relative_path() const; + path parent_path() const; + path filename() const; // returns 0 or 1 element path + path stem() const; // returns 0 or 1 element path + path extension() const; // returns 0 or 1 element path + + // ----- query ----- + + bool empty() const { return m_pathname.empty(); } // name consistent with std containers + bool has_root_path() const { return has_root_directory() || has_root_name(); } + bool has_root_name() const { return !root_name().empty(); } + bool has_root_directory() const { return !root_directory().empty(); } + bool has_relative_path() const { return !relative_path().empty(); } + bool has_parent_path() const { return !parent_path().empty(); } + bool has_filename() const { return !m_pathname.empty(); } + bool has_stem() const { return !stem().empty(); } + bool has_extension() const { return !extension().empty(); } + bool is_absolute() const + { +# ifdef BOOST_WINDOWS_API + return has_root_name() && has_root_directory(); +# else + return has_root_directory(); +# endif + } + bool is_relative() const { return !is_absolute(); } + + // ----- imbue ----- + + static std::locale imbue(const std::locale& loc); + + // ----- codecvt ----- + + static const codecvt_type& codecvt() + { + return *wchar_t_codecvt_facet(); + } + + // ----- iterators ----- + + class iterator; + typedef iterator const_iterator; + + iterator begin() const; + iterator end() const; + + // ----- deprecated functions ----- + +# if defined(BOOST_FILESYSTEM_DEPRECATED) && defined(BOOST_FILESYSTEM_NO_DEPRECATED) +# error both BOOST_FILESYSTEM_DEPRECATED and BOOST_FILESYSTEM_NO_DEPRECATED are defined +# endif + +# if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) + // recently deprecated functions supplied by default + path& normalize() { return m_normalize(); } + path& remove_leaf() { return remove_filename(); } + path leaf() const { return filename(); } + path branch_path() const { return parent_path(); } + bool has_leaf() const { return !m_pathname.empty(); } + bool has_branch_path() const { return !parent_path().empty(); } + bool is_complete() const { return is_absolute(); } +# endif + +# if defined(BOOST_FILESYSTEM_DEPRECATED) + // deprecated functions with enough signature or semantic changes that they are + // not supplied by default + const std::string file_string() const { return string(); } + const std::string directory_string() const { return string(); } + const std::string native_file_string() const { return string(); } + const std::string native_directory_string() const { return string(); } + const string_type external_file_string() const { return native(); } + const string_type external_directory_string() const { return native(); } + + // older functions no longer supported + //typedef bool (*name_check)(const std::string & name); + //basic_path(const string_type& str, name_check) { operator/=(str); } + //basic_path(const typename string_type::value_type* s, name_check) + // { operator/=(s);} + //static bool default_name_check_writable() { return false; } + //static void default_name_check(name_check) {} + //static name_check default_name_check() { return 0; } + //basic_path& canonize(); +# endif + +//--------------------------------------------------------------------------------------// +// class path private members // +//--------------------------------------------------------------------------------------// + + private: +# if defined(_MSC_VER) +# pragma warning(push) // Save warning settings +# pragma warning(disable : 4251) // disable warning: class 'std::basic_string<_Elem,_Traits,_Ax>' +# endif // needs to have dll-interface... +/* + m_pathname has the type, encoding, and format required by the native + operating system. Thus for POSIX and Windows there is no conversion for + passing m_pathname.c_str() to the O/S API or when obtaining a path from the + O/S API. POSIX encoding is unspecified other than for dot and slash + characters; POSIX just treats paths as a sequence of bytes. Windows + encoding is UCS-2 or UTF-16 depending on the version. +*/ + string_type m_pathname; // Windows: as input; backslashes NOT converted to slashes, + // slashes NOT converted to backslashes +# if defined(_MSC_VER) +# pragma warning(pop) // restore warning settings. +# endif + + string_type::size_type m_append_separator_if_needed(); + // Returns: If separator is to be appended, m_pathname.size() before append. Otherwise 0. + // Note: An append is never performed if size()==0, so a returned 0 is unambiguous. + + void m_erase_redundant_separator(string_type::size_type sep_pos); + string_type::size_type m_parent_path_end() const; + void m_portable(); + + path& m_normalize(); + + // Was qualified; como433beta8 reports: + // warning #427-D: qualified name is not allowed in member declaration + friend class iterator; + friend bool operator<(const path& lhs, const path& rhs); + + // see path::iterator::increment/decrement comment below + static void m_path_iterator_increment(path::iterator & it); + static void m_path_iterator_decrement(path::iterator & it); + + static const codecvt_type *& wchar_t_codecvt_facet(); + + }; // class path + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + typedef path wpath; +# endif + + //------------------------------------------------------------------------------------// + // class path::iterator // + //------------------------------------------------------------------------------------// + + class path::iterator + : public boost::iterator_facade< + iterator, + path const, + boost::bidirectional_traversal_tag > + { + private: + friend class boost::iterator_core_access; + friend class boost::filesystem3::path; + friend void m_path_iterator_increment(path::iterator & it); + friend void m_path_iterator_decrement(path::iterator & it); + + const path& dereference() const { return m_element; } + + bool equal(const iterator & rhs) const + { + return m_path_ptr == rhs.m_path_ptr && m_pos == rhs.m_pos; + } + + // iterator_facade derived classes don't seem to like implementations in + // separate translation unit dll's, so forward to class path static members + void increment() { m_path_iterator_increment(*this); } + void decrement() { m_path_iterator_decrement(*this); } + + path m_element; // current element + const path * m_path_ptr; // path being iterated over + string_type::size_type m_pos; // position of name in + // m_path_ptr->m_pathname. The + // end() iterator is indicated by + // m_pos == m_path_ptr->m_pathname.size() + }; // path::iterator + + //------------------------------------------------------------------------------------// + // // + // non-member functions // + // // + //------------------------------------------------------------------------------------// + + // std::lexicographical_compare would infinately recurse because path iterators + // yield paths, so provide a path aware version + inline bool lexicographical_compare(path::iterator first1, path::iterator last1, + path::iterator first2, path::iterator last2) + { + for (; first1 != last1 && first2 != last2 ; ++first1, ++first2) + { + if (first1->native() < first2->native()) return true; + if (first2->native() < first1->native()) return false; + } + return first1 == last1 && first2 != last2; + } + + inline bool operator<(const path& lhs, const path& rhs) + { + return lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + } + + inline bool operator<=(const path& lhs, const path& rhs) { return !(rhs < lhs); } + inline bool operator> (const path& lhs, const path& rhs) { return rhs < lhs; } + inline bool operator>=(const path& lhs, const path& rhs) { return !(lhs < rhs); } + + // equality operators act as if comparing generic format strings, to achieve the + // effect of lexicographical_compare element by element compare. + // operator==() efficiency is a concern; a user reported the original version 2 + // !(lhs < rhs) && !(rhs < lhs) implementation caused a serious performance problem + // for a map of 10,000 paths. + +# ifdef BOOST_WINDOWS_API + inline bool operator==(const path& lhs, const path::value_type* rhs) + { + const path::value_type* l(lhs.c_str()); + while ((*l == *rhs || (*l == L'\\' && *rhs == L'/') || (*l == L'/' && *rhs == L'\\')) + && *l) { ++l; ++rhs; } + return *l == *rhs || (*l == L'\\' && *rhs == L'/') || (*l == L'/' && *rhs == L'\\'); + } + inline bool operator==(const path& lhs, const path& rhs) { return lhs == rhs.c_str(); } + inline bool operator==(const path& lhs, const path::string_type& rhs) { return lhs == rhs.c_str(); } + inline bool operator==(const path::string_type& lhs, const path& rhs) { return rhs == lhs.c_str(); } + inline bool operator==(const path::value_type* lhs, const path& rhs) { return rhs == lhs; } +# else // BOOST_POSIX_API + inline bool operator==(const path& lhs, const path& rhs) { return lhs.native() == rhs.native(); } + inline bool operator==(const path& lhs, const path::string_type& rhs) { return lhs.native() == rhs; } + inline bool operator==(const path& lhs, const path::value_type* rhs) { return lhs.native() == rhs; } + inline bool operator==(const path::string_type& lhs, const path& rhs) { return lhs == rhs.native(); } + inline bool operator==(const path::value_type* lhs, const path& rhs) { return lhs == rhs.native(); } +# endif + + inline bool operator!=(const path& lhs, const path& rhs) { return !(lhs == rhs); } + inline bool operator!=(const path& lhs, const path::string_type& rhs) { return !(lhs == rhs); } + inline bool operator!=(const path& lhs, const path::value_type* rhs) { return !(lhs == rhs); } + inline bool operator!=(const path::string_type& lhs, const path& rhs) { return !(lhs == rhs); } + inline bool operator!=(const path::value_type* lhs, const path& rhs) { return !(lhs == rhs); } + + inline void swap(path& lhs, path& rhs) { lhs.swap(rhs); } + + inline path operator/(const path& lhs, const path& rhs) { return path(lhs) /= rhs; } + + // inserters and extractors + // use boost::io::quoted() to handle spaces in paths + // use '&' as escape character to ease use for Windows paths + + template <class Char, class Traits> + inline std::basic_ostream<Char, Traits>& + operator<<(std::basic_ostream<Char, Traits>& os, const path& p) + { + return os + << boost::io::quoted(p.string<std::basic_string<Char> >(), static_cast<Char>('&')); + } + + template <class Char, class Traits> + inline std::basic_istream<Char, Traits>& + operator>>(std::basic_istream<Char, Traits>& is, path& p) + { + std::basic_string<Char> str; + is >> boost::io::quoted(str, static_cast<Char>('&')); + p = str; + return is; + } + + // name_checks + + // These functions are holdovers from version 1. It isn't clear they have much + // usefulness, or how to generalize them for later versions. + + BOOST_FILESYSTEM_DECL bool portable_posix_name(const std::string & name); + BOOST_FILESYSTEM_DECL bool windows_name(const std::string & name); + BOOST_FILESYSTEM_DECL bool portable_name(const std::string & name); + BOOST_FILESYSTEM_DECL bool portable_directory_name(const std::string & name); + BOOST_FILESYSTEM_DECL bool portable_file_name(const std::string & name); + BOOST_FILESYSTEM_DECL bool native(const std::string & name); + +//--------------------------------------------------------------------------------------// +// class path member template implementation // +//--------------------------------------------------------------------------------------// + + template <class InputIterator> + path& path::append(InputIterator begin, InputIterator end, const codecvt_type& cvt) + { + if (begin == end) + return *this; + string_type::size_type sep_pos(m_append_separator_if_needed()); + std::basic_string<typename std::iterator_traits<InputIterator>::value_type> + s(begin, end); + path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt); + if (sep_pos) + m_erase_redundant_separator(sep_pos); + return *this; + } + + template <class Source> + path& path::append(Source const & source, const codecvt_type& cvt) + { + if (path_traits::empty(source)) + return *this; + string_type::size_type sep_pos(m_append_separator_if_needed()); + path_traits::dispatch(source, m_pathname, cvt); + if (sep_pos) + m_erase_redundant_separator(sep_pos); + return *this; + } + +//--------------------------------------------------------------------------------------// +// class path member template specializations // +//--------------------------------------------------------------------------------------// + + template <> inline + std::string path::string<std::string>() const + { return string(); } + + template <> inline + std::wstring path::string<std::wstring>() const + { return wstring(); } + + template <> inline + std::string path::string<std::string>(const codecvt_type& cvt) const + { return string(cvt); } + + template <> inline + std::wstring path::string<std::wstring>(const codecvt_type& cvt) const + { return wstring(cvt); } + + template <> inline + std::string path::generic_string<std::string>() const + { return generic_string(); } + + template <> inline + std::wstring path::generic_string<std::wstring>() const + { return generic_wstring(); } + + template <> inline + std::string path::generic_string<std::string>(const codecvt_type& cvt) const + { return generic_string(cvt); } + + template <> inline + std::wstring path::generic_string<std::wstring>(const codecvt_type& cvt) const + { return generic_wstring(cvt); } + + +} // namespace filesystem3 +} // namespace boost + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + using filesystem3::path; +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + using filesystem3::wpath; +# endif + using filesystem3::lexicographical_compare; + using filesystem3::portable_posix_name; + using filesystem3::windows_name; + using filesystem3::portable_name; + using filesystem3::portable_directory_name; + using filesystem3::portable_file_name; + using filesystem3::native; + using filesystem3::swap; + using filesystem3::operator<; + using filesystem3::operator==; + using filesystem3::operator!=; + using filesystem3::operator>; + using filesystem3::operator<=; + using filesystem3::operator>=; + using filesystem3::operator/; + using filesystem3::operator<<; + using filesystem3::operator>>; + } +} + +//----------------------------------------------------------------------------// + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas + +#endif // BOOST_FILESYSTEM_PATH_HPP diff --git a/3rdParty/Boost/src/boost/filesystem/v3/path_traits.hpp b/3rdParty/Boost/src/boost/filesystem/v3/path_traits.hpp new file mode 100644 index 0000000..71e80e2 --- /dev/null +++ b/3rdParty/Boost/src/boost/filesystem/v3/path_traits.hpp @@ -0,0 +1,247 @@ +// filesystem path_traits.hpp --------------------------------------------------------// + +// Copyright Beman Dawes 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +#ifndef BOOST_FILESYSTEM_PATH_TRAITS_HPP +#define BOOST_FILESYSTEM_PATH_TRAITS_HPP + +#include <boost/config.hpp> + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include <boost/filesystem/v3/config.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_array.hpp> +#include <boost/type_traits/decay.hpp> +#include <boost/system/error_code.hpp> +#include <cwchar> // for mbstate_t +#include <string> +#include <vector> +#include <list> +#include <iterator> +#include <locale> +#include <boost/assert.hpp> +// #include <iostream> //**** comment me out **** + +#include <boost/config/abi_prefix.hpp> // must be the last #include + +namespace boost { namespace filesystem3 { + + BOOST_FILESYSTEM_DECL const system::error_category& codecvt_error_category(); + // uses std::codecvt_base::result used for error codes: + // + // ok: Conversion successful. + // partial: Not all source characters converted; one or more additional source + // characters are needed to produce the final target character, or the + // size of the target intermediate buffer was too small to hold the result. + // error: A character in the source could not be converted to the target encoding. + // noconv: The source and target characters have the same type and encoding, so no + // conversion was necessary. + + class directory_entry; + +namespace path_traits { + + typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type; + + // is_pathable type trait; allows disabling over-agressive class path member templates + + template <class T> + struct is_pathable { static const bool value = false; }; + + template<> struct is_pathable<char*> { static const bool value = true; }; + template<> struct is_pathable<const char*> { static const bool value = true; }; + template<> struct is_pathable<wchar_t*> { static const bool value = true; }; + template<> struct is_pathable<const wchar_t*> { static const bool value = true; }; + template<> struct is_pathable<std::string> { static const bool value = true; }; + template<> struct is_pathable<std::wstring> { static const bool value = true; }; + template<> struct is_pathable<std::vector<char> > { static const bool value = true; }; + template<> struct is_pathable<std::vector<wchar_t> > { static const bool value = true; }; + template<> struct is_pathable<std::list<char> > { static const bool value = true; }; + template<> struct is_pathable<std::list<wchar_t> > { static const bool value = true; }; + template<> struct is_pathable<directory_entry> { static const bool value = true; }; + + // Pathable empty + + template <class Container> inline + // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for + // conforming compilers. Replace by plain "bool" at some future date (2012?) + typename boost::disable_if<boost::is_array<Container>, bool>::type + empty(const Container & c) + { return c.begin() == c.end(); } + + template <class T> inline + bool empty(T * const & c_str) + { + BOOST_ASSERT(c_str); + return !*c_str; + } + + template <typename T, size_t N> inline + bool empty(T (&)[N]) + { return N <= 1; } + + // value types differ ---------------------------------------------------------------// + // + // A from_end argument of 0 is less efficient than a known end, so use only if needed + + BOOST_FILESYSTEM_DECL + void convert(const char* from, + const char* from_end, // 0 for null terminated MBCS + std::wstring & to, + const codecvt_type& cvt); + + BOOST_FILESYSTEM_DECL + void convert(const wchar_t* from, + const wchar_t* from_end, // 0 for null terminated MBCS + std::string & to, + const codecvt_type& cvt); + + inline + void convert(const char* from, + std::wstring & to, + const codecvt_type& cvt) + { + BOOST_ASSERT(from); + convert(from, 0, to, cvt); + } + + inline + void convert(const wchar_t* from, + std::string & to, + const codecvt_type& cvt) + { + BOOST_ASSERT(from); + convert(from, 0, to, cvt); + } + + // value types same -----------------------------------------------------------------// + + // char + + inline + void convert(const char* from, const char* from_end, std::string & to, + const codecvt_type&) + { + BOOST_ASSERT(from); + BOOST_ASSERT(from_end); + to.append(from, from_end); + } + + inline + void convert(const char* from, + std::string & to, + const codecvt_type&) + { + BOOST_ASSERT(from); + to += from; + } + + // wchar_t + + inline + void convert(const wchar_t* from, const wchar_t* from_end, std::wstring & to, + const codecvt_type&) + { + BOOST_ASSERT(from); + BOOST_ASSERT(from_end); + to.append(from, from_end); + } + + inline + void convert(const wchar_t* from, + std::wstring & to, + const codecvt_type&) + { + BOOST_ASSERT(from); + to += from; + } + + // Source dispatch + + // contiguous containers + template <class U> inline + void dispatch(const std::string& c, U& to, const codecvt_type& cvt) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); + } + template <class U> inline + void dispatch(const std::wstring& c, U& to, const codecvt_type& cvt) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); + } + template <class U> inline + void dispatch(const std::vector<char>& c, U& to, const codecvt_type& cvt) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); + } + template <class U> inline + void dispatch(const std::vector<wchar_t>& c, U& to, const codecvt_type& cvt) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); + } + + // non-contiguous containers + template <class Container, class U> inline + // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for + // conforming compilers. Replace by plain "void" at some future date (2012?) + typename boost::disable_if<boost::is_array<Container>, void>::type + dispatch(const Container & c, U& to, const codecvt_type& cvt) + { + if (c.size()) + { + std::basic_string<typename Container::value_type> s(c.begin(), c.end()); + convert(s.c_str(), s.c_str()+s.size(), to, cvt); + } + } + + // c_str + template <class T, class U> inline + void dispatch(T * const & c_str, U& to, const codecvt_type& cvt) + { +// std::cout << "dispatch() const T *\n"; + BOOST_ASSERT(c_str); + convert(c_str, to, cvt); + } + + // Note: there is no dispatch on C-style arrays because the array may + // contain a string smaller than the array size. + + BOOST_FILESYSTEM_DECL + void dispatch(const directory_entry & de, +# ifdef BOOST_WINDOWS_API + std::wstring & to, +# else + std::string & to, +# endif + const codecvt_type&); + + +}}} // namespace boost::filesystem::path_traits + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + using filesystem3::codecvt_error_category; +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED +# endif + } +} + +#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas + +#endif // BOOST_FILESYSTEM_PATH_TRAITS_HPP diff --git a/3rdParty/Boost/src/boost/foreach.hpp b/3rdParty/Boost/src/boost/foreach.hpp index 9a5b931..db5b203 100644 --- a/3rdParty/Boost/src/boost/foreach.hpp +++ b/3rdParty/Boost/src/boost/foreach.hpp @@ -31,8 +31,9 @@ // Some compilers let us detect even const-qualified rvalues at compile-time #if BOOST_WORKAROUND(BOOST_MSVC, >= 1310) && !defined(_PREFAST_) \ - || (BOOST_WORKAROUND(__GNUC__, >= 4) && !defined(BOOST_INTEL)) \ - || (BOOST_WORKAROUND(__GNUC__, == 3) && (__GNUC_MINOR__ >= 4) && !defined(BOOST_INTEL)) + || (BOOST_WORKAROUND(__GNUC__, >= 4) && !defined(BOOST_INTEL) && !defined(BOOST_CLANG)) \ + || (BOOST_WORKAROUND(__GNUC__, == 3) && (__GNUC_MINOR__ >= 4) && !defined(BOOST_INTEL) && \ + !defined(BOOST_CLANG)) # define BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION #else // Some compilers allow temporaries to be bound to non-const references. @@ -41,7 +42,7 @@ # if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ || BOOST_WORKAROUND(__BORLANDC__, < 0x593) \ || (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \ - || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x570)) \ + || BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) \ || BOOST_WORKAROUND(__DECCXX_VER, <= 60590042) # define BOOST_FOREACH_NO_RVALUE_DETECTION # endif @@ -56,6 +57,7 @@ || (BOOST_WORKAROUND(__GNUC__, == 3) && (__GNUC_MINOR__ <= 3) && defined(__APPLE_CC__)) \ || BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) \ || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) \ + || BOOST_WORKAROUND(__SUNPRO_CC, >= 0x5100) \ || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x590)) # define BOOST_FOREACH_NO_CONST_RVALUE_DETECTION # else @@ -80,6 +82,7 @@ #include <boost/type_traits/is_base_and_derived.hpp> #include <boost/iterator/iterator_traits.hpp> #include <boost/utility/addressof.hpp> +#include <boost/foreach_fwd.hpp> #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION # include <new> @@ -88,12 +91,6 @@ # include <boost/type_traits/remove_const.hpp> #endif -// This must be at global scope, hence the uglified name -enum boost_foreach_argument_dependent_lookup_hack -{ - boost_foreach_argument_dependent_lookup_hack_value -}; - namespace boost { @@ -117,11 +114,6 @@ namespace foreach } /////////////////////////////////////////////////////////////////////////////// - // boost::foreach::tag - // - typedef boost_foreach_argument_dependent_lookup_hack tag; - - /////////////////////////////////////////////////////////////////////////////// // boost::foreach::is_lightweight_proxy // Specialize this for user-defined collection types if they are inexpensive to copy. // This tells BOOST_FOREACH it can avoid the rvalue/lvalue detection stuff. @@ -254,7 +246,7 @@ struct auto_any_base template<typename T> struct auto_any : auto_any_base { - auto_any(T const &t) + explicit auto_any(T const &t) : item(t) { } @@ -614,7 +606,7 @@ should_copy_impl(boost::mpl::false_ *, boost::mpl::false_ *, bool *is_rvalue) template<typename T> inline auto_any<T> contain(T const &t, boost::mpl::true_ *) // rvalue { - return t; + return auto_any<T>(t); } template<typename T> @@ -622,18 +614,18 @@ inline auto_any<T *> contain(T &t, boost::mpl::false_ *) // lvalue { // Cannot seem to get sunpro to handle addressof() with array types. #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x570)) - return &t; + return auto_any<T *>(&t); #else - return boost::addressof(t); + return auto_any<T *>(boost::addressof(t)); #endif } #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION template<typename T> -auto_any<simple_variant<T> > +inline auto_any<simple_variant<T> > contain(T const &t, bool *rvalue) { - return *rvalue ? simple_variant<T>(t) : simple_variant<T>(&t); + return auto_any<simple_variant<T> >(*rvalue ? simple_variant<T>(t) : simple_variant<T>(&t)); } #endif @@ -644,7 +636,8 @@ template<typename T, typename C> inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> begin(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue { - return boost::begin(auto_any_cast<T, C>(col)); + return auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>( + boost::begin(auto_any_cast<T, C>(col))); } template<typename T, typename C> @@ -653,15 +646,17 @@ begin(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue { typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iterator; - return iterator(boost::begin(derefof(auto_any_cast<type *, boost::mpl::false_>(col)))); + return auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>( + iterator(boost::begin(derefof(auto_any_cast<type *, boost::mpl::false_>(col))))); } #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION template<typename T> -auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type> +inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type> begin(auto_any_t col, type2type<T, const_> *, bool *) { - return boost::begin(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get()); + return auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type>( + boost::begin(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get())); } #endif @@ -670,7 +665,7 @@ template<typename T, typename C> inline auto_any<T *> begin(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings { - return auto_any_cast<T *, boost::mpl::false_>(col); + return auto_any<T *>(auto_any_cast<T *, boost::mpl::false_>(col)); } #endif @@ -681,7 +676,8 @@ template<typename T, typename C> inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> end(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue { - return boost::end(auto_any_cast<T, C>(col)); + return auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>( + boost::end(auto_any_cast<T, C>(col))); } template<typename T, typename C> @@ -690,24 +686,26 @@ end(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue { typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iterator; - return iterator(boost::end(derefof(auto_any_cast<type *, boost::mpl::false_>(col)))); + return auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>( + iterator(boost::end(derefof(auto_any_cast<type *, boost::mpl::false_>(col))))); } #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION template<typename T> -auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type> +inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type> end(auto_any_t col, type2type<T, const_> *, bool *) { - return boost::end(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get()); + return auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type>( + boost::end(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get())); } #endif #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING template<typename T, typename C> inline auto_any<int> -end(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings +end(auto_any_t, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings { - return 0; // not used + return auto_any<int>(0); // not used } #endif @@ -757,7 +755,8 @@ template<typename T, typename C> inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> rbegin(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue { - return boost::rbegin(auto_any_cast<T, C>(col)); + return auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type>( + boost::rbegin(auto_any_cast<T, C>(col))); } template<typename T, typename C> @@ -766,15 +765,17 @@ rbegin(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue { typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iterator; - return iterator(boost::rbegin(derefof(auto_any_cast<type *, boost::mpl::false_>(col)))); + return auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type>( + iterator(boost::rbegin(derefof(auto_any_cast<type *, boost::mpl::false_>(col))))); } #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION template<typename T> -auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type> +inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type> rbegin(auto_any_t col, type2type<T, const_> *, bool *) { - return boost::rbegin(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get()); + return auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type>( + boost::rbegin(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get())); } #endif @@ -786,7 +787,7 @@ rbegin(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-termina T *p = auto_any_cast<T *, boost::mpl::false_>(col); while(0 != *p) ++p; - return reverse_iterator<T *>(p); + return auto_any<reverse_iterator<T *> >(reverse_iterator<T *>(p)); } #endif @@ -797,7 +798,8 @@ template<typename T, typename C> inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> rend(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue { - return boost::rend(auto_any_cast<T, C>(col)); + return auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type>( + boost::rend(auto_any_cast<T, C>(col))); } template<typename T, typename C> @@ -806,15 +808,17 @@ rend(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue { typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iterator; - return iterator(boost::rend(derefof(auto_any_cast<type *, boost::mpl::false_>(col)))); + return auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type>( + iterator(boost::rend(derefof(auto_any_cast<type *, boost::mpl::false_>(col))))); } #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION template<typename T> -auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type> +inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type> rend(auto_any_t col, type2type<T, const_> *, bool *) { - return boost::rend(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get()); + return auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type>( + boost::rend(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get())); } #endif @@ -823,7 +827,8 @@ template<typename T, typename C> inline auto_any<reverse_iterator<T *> > rend(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings { - return reverse_iterator<T *>(auto_any_cast<T *, boost::mpl::false_>(col)); + return auto_any<reverse_iterator<T *> >( + reverse_iterator<T *>(auto_any_cast<T *, boost::mpl::false_>(col))); } #endif diff --git a/3rdParty/Boost/src/boost/foreach_fwd.hpp b/3rdParty/Boost/src/boost/foreach_fwd.hpp new file mode 100644 index 0000000..4e0bb37 --- /dev/null +++ b/3rdParty/Boost/src/boost/foreach_fwd.hpp @@ -0,0 +1,51 @@ +/////////////////////////////////////////////////////////////////////////////// +// foreach.hpp header file +// +// Copyright 2010 Eric Niebler. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// See http://www.boost.org/libs/foreach for documentation +// +// Credits: +// Kazutoshi Satoda: for suggesting the need for a _fwd header for foreach's +// customization points. + +#ifndef BOOST_FOREACH_FWD_HPP +#define BOOST_FOREACH_FWD_HPP + +// This must be at global scope, hence the uglified name +enum boost_foreach_argument_dependent_lookup_hack +{ + boost_foreach_argument_dependent_lookup_hack_value +}; + +namespace boost +{ + +namespace foreach +{ + /////////////////////////////////////////////////////////////////////////////// + // boost::foreach::tag + // + typedef boost_foreach_argument_dependent_lookup_hack tag; + + /////////////////////////////////////////////////////////////////////////////// + // boost::foreach::is_lightweight_proxy + // Specialize this for user-defined collection types if they are inexpensive to copy. + // This tells BOOST_FOREACH it can avoid the rvalue/lvalue detection stuff. + template<typename T> + struct is_lightweight_proxy; + + /////////////////////////////////////////////////////////////////////////////// + // boost::foreach::is_noncopyable + // Specialize this for user-defined collection types if they cannot be copied. + // This also tells BOOST_FOREACH to avoid the rvalue/lvalue detection stuff. + template<typename T> + struct is_noncopyable; + +} // namespace foreach + +} // namespace boost + +#endif diff --git a/3rdParty/Boost/src/boost/function/function_base.hpp b/3rdParty/Boost/src/boost/function/function_base.hpp index eb201a8..fe9bbbe 100644 --- a/3rdParty/Boost/src/boost/function/function_base.hpp +++ b/3rdParty/Boost/src/boost/function/function_base.hpp @@ -264,12 +264,12 @@ namespace boost { A(a) { } - - functor_wrapper(const functor_wrapper& f) : + + functor_wrapper(const functor_wrapper& f) : F(static_cast<const F&>(f)), A(static_cast<const A&>(f)) - { - } + { + } }; /** diff --git a/3rdParty/Boost/src/boost/functional/hash/hash.hpp b/3rdParty/Boost/src/boost/functional/hash/hash.hpp index e85ca5a..0eedf7f 100644 --- a/3rdParty/Boost/src/boost/functional/hash/hash.hpp +++ b/3rdParty/Boost/src/boost/functional/hash/hash.hpp @@ -16,6 +16,10 @@ #include <string> #include <boost/limits.hpp> +#if defined(BOOST_HASH_NO_IMPLICIT_CASTS) +#include <boost/static_assert.hpp> +#endif + #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) #include <boost/type_traits/is_pointer.hpp> #endif @@ -29,6 +33,18 @@ namespace boost { +#if defined(BOOST_HASH_NO_IMPLICIT_CASTS) + + // If you get a static assertion here, it's because hash_value + // isn't declared for your type. + template <typename T> + std::size_t hash_value(T const&) { + BOOST_STATIC_ASSERT((T*) 0 && false); + return 0; + } + +#endif + std::size_t hash_value(bool); std::size_t hash_value(char); std::size_t hash_value(unsigned char); @@ -193,9 +209,15 @@ namespace boost template <class T> std::size_t hash_value(T* v) #endif { +#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64 + // for some reason ptrdiff_t on OpenVMS compiler with + // 64 bit is not 64 bit !!! + std::size_t x = static_cast<std::size_t>( + reinterpret_cast<long long int>(v)); +#else std::size_t x = static_cast<std::size_t>( reinterpret_cast<std::ptrdiff_t>(v)); - +#endif return x + (x >> 3); } diff --git a/3rdParty/Boost/src/boost/integer.hpp b/3rdParty/Boost/src/boost/integer.hpp index 3393c81..fc0b398 100644 --- a/3rdParty/Boost/src/boost/integer.hpp +++ b/3rdParty/Boost/src/boost/integer.hpp @@ -57,6 +57,8 @@ namespace boost // no specializations for 0 and 5: requests for a type > long are in error #ifdef BOOST_HAS_LONG_LONG template<> struct int_least_helper<1> { typedef boost::long_long_type least; }; +#elif defined(BOOST_HAS_MS_INT64) + template<> struct int_least_helper<1> { typedef __int64 least; }; #endif template<> struct int_least_helper<2> { typedef long least; }; template<> struct int_least_helper<3> { typedef int least; }; @@ -64,6 +66,8 @@ namespace boost template<> struct int_least_helper<5> { typedef signed char least; }; #ifdef BOOST_HAS_LONG_LONG template<> struct int_least_helper<6> { typedef boost::ulong_long_type least; }; +#elif defined(BOOST_HAS_MS_INT64) + template<> struct int_least_helper<6> { typedef unsigned __int64 least; }; #endif template<> struct int_least_helper<7> { typedef unsigned long least; }; template<> struct int_least_helper<8> { typedef unsigned int least; }; diff --git a/3rdParty/Boost/src/boost/integer_fwd.hpp b/3rdParty/Boost/src/boost/integer_fwd.hpp index 01b0a08..20eff2b 100644 --- a/3rdParty/Boost/src/boost/integer_fwd.hpp +++ b/3rdParty/Boost/src/boost/integer_fwd.hpp @@ -77,12 +77,18 @@ template < > template < > class integer_traits< unsigned long >; -#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && (defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)) +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG) template < > - class integer_traits< ::boost::long_long_type>; +class integer_traits< ::boost::long_long_type>; template < > - class integer_traits< ::boost::ulong_long_type >; +class integer_traits< ::boost::ulong_long_type >; +#elif !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_MS_INT64) +template < > +class integer_traits<__int64>; + +template < > +class integer_traits<unsigned __int64>; #endif @@ -130,22 +136,6 @@ template < std::size_t Bits > template < > struct low_bits_mask_t< ::std::numeric_limits<unsigned char>::digits >; -#if USHRT_MAX > UCHAR_MAX -template < > - struct low_bits_mask_t< ::std::numeric_limits<unsigned short>::digits >; -#endif - -#if UINT_MAX > USHRT_MAX -template < > - struct low_bits_mask_t< ::std::numeric_limits<unsigned int>::digits >; -#endif - -#if ULONG_MAX > UINT_MAX -template < > - struct low_bits_mask_t< ::std::numeric_limits<unsigned long>::digits >; -#endif - - // From <boost/integer/static_log2.hpp> ------------------------------------// template <static_log2_argument_type Value > diff --git a/3rdParty/Boost/src/boost/io/detail/quoted_manip.hpp b/3rdParty/Boost/src/boost/io/detail/quoted_manip.hpp new file mode 100644 index 0000000..13cfc35 --- /dev/null +++ b/3rdParty/Boost/src/boost/io/detail/quoted_manip.hpp @@ -0,0 +1,190 @@ +// boost/io/quoted_manip.hpp ---------------------------------------------------------// + +// Copyright Beman Dawes 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page http://www.boost.org/libs/io + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_IO_QUOTED_MANIP +#define BOOST_IO_QUOTED_MANIP + +#include <iosfwd> +#include <ios> +#include <string> +#include <iterator> +#include <boost/io/ios_state.hpp> + +namespace boost +{ + namespace io + { + namespace detail { template <class String, class Char> struct quoted_proxy; } + + // ------------ public interface ------------------------------------------------// + + // manipulator for const std::basic_string& + template <class Char, class Traits, class Alloc> + detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char> + quoted(const std::basic_string<Char, Traits, Alloc>& s, + Char escape='\\', Char delim='\"'); + + // manipulator for non-const std::basic_string& + template <class Char, class Traits, class Alloc> + detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char> + quoted(std::basic_string<Char, Traits, Alloc>& s, + Char escape='\\', Char delim='\"'); + + // manipulator for const C-string* + template <class Char> + detail::quoted_proxy<const Char*, Char> + quoted(const Char* s, Char escape='\\', Char delim='\"'); + + // ----------- implementation details -------------------------------------------// + + namespace detail + { + // proxy used as an argument pack + template <class String, class Char> + struct quoted_proxy + { + String string; + Char escape; + Char delim; + + quoted_proxy(String s_, Char escape_, Char delim_) + : string(s_), escape(escape_), delim(delim_) {} + private: + // String may be a const type, so disable the assignment operator + quoted_proxy& operator=(const quoted_proxy&); // = deleted + }; + + // abstract away difference between proxies with const or non-const basic_strings + template <class Char, class Traits, class Alloc> + std::basic_ostream<Char, Traits>& + basic_string_inserter_imp(std::basic_ostream<Char, Traits>& os, + std::basic_string<Char, Traits, Alloc> const & string, Char escape, Char delim) + { + os << delim; + typename std::basic_string<Char, Traits, Alloc>::const_iterator + end_it = string.end(); + for (typename std::basic_string<Char, Traits, Alloc>::const_iterator + it = string.begin(); + it != end_it; + ++it ) + { + if (*it == delim || *it == escape) + os << escape; + os << *it; + } + os << delim; + return os; + } + + // inserter for const std::basic_string& proxies + template <class Char, class Traits, class Alloc> + inline + std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, + const quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>& proxy) + { + return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim); + } + + // inserter for non-const std::basic_string& proxies + template <class Char, class Traits, class Alloc> + inline + std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, + const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy) + { + return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim); + } + + // inserter for const C-string* proxies + template <class Char, class Traits> + std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os, + const quoted_proxy<const Char*, Char>& proxy) + { + os << proxy.delim; + for (const Char* it = proxy.string; + *it; + ++it ) + { + if (*it == proxy.delim || *it == proxy.escape) + os << proxy.escape; + os << *it; + } + os << proxy.delim; + return os; + } + + // extractor for non-const std::basic_string& proxies + template <class Char, class Traits, class Alloc> + std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& is, + const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy) + { + Char c; + is >> c; + if (c != proxy.delim) + { + proxy.string = c; + is >> proxy.string; + return is; + } + proxy.string.clear(); + { + boost::io::ios_flags_saver ifs(is); + is >> std::noskipws; + for (;;) + { + is >> c; + if (!is.good()) // cope with I/O errors or end-of-file + break; + if (c == proxy.escape) + { + is >> c; + if (!is.good()) // cope with I/O errors or end-of-file + break; + } + else if (c == proxy.delim) + break; + proxy.string += c; + } + } + return is; + } + + } // namespace detail + + // manipulator implementation for const std::basic_string& + template <class Char, class Traits, class Alloc> + inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char> + quoted(const std::basic_string<Char, Traits, Alloc>& s, Char escape, Char delim) + { + return detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char> + (s, escape, delim); + } + + // manipulator implementation for non-const std::basic_string& + template <class Char, class Traits, class Alloc> + inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char> + quoted(std::basic_string<Char, Traits, Alloc>& s, Char escape, Char delim) + { + return detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char> + (s, escape, delim); + } + + // manipulator implementation for const C-string* + template <class Char> + inline detail::quoted_proxy<const Char*, Char> + quoted(const Char* s, Char escape, Char delim) + { + return detail::quoted_proxy<const Char*, Char> (s, escape, delim); + } + + } // namespace io +} // namespace boost + +#endif // BOOST_IO_QUOTED_MANIP diff --git a/3rdParty/Boost/src/boost/iterator/transform_iterator.hpp b/3rdParty/Boost/src/boost/iterator/transform_iterator.hpp index e449a8b..c365fe0 100644 --- a/3rdParty/Boost/src/boost/iterator/transform_iterator.hpp +++ b/3rdParty/Boost/src/boost/iterator/transform_iterator.hpp @@ -7,7 +7,6 @@ #ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP #define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP -#include <boost/function.hpp> #include <boost/iterator.hpp> #include <boost/iterator/detail/enable_if.hpp> #include <boost/iterator/iterator_adaptor.hpp> diff --git a/3rdParty/Boost/src/boost/mpl/aux_/config/has_xxx.hpp b/3rdParty/Boost/src/boost/mpl/aux_/config/has_xxx.hpp index 8f2a46d..e03fe11 100644 --- a/3rdParty/Boost/src/boost/mpl/aux_/config/has_xxx.hpp +++ b/3rdParty/Boost/src/boost/mpl/aux_/config/has_xxx.hpp @@ -11,9 +11,9 @@ // // See http://www.boost.org/libs/mpl for documentation. -// $Id: has_xxx.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ -// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ -// $Revision: 49267 $ +// $Id: has_xxx.hpp 63518 2010-07-02 08:32:03Z agurtovoy $ +// $Date: 2010-07-02 04:32:03 -0400 (Fri, 02 Jul 2010) $ +// $Revision: 63518 $ #include <boost/mpl/aux_/config/overload_resolution.hpp> #include <boost/mpl/aux_/config/workaround.hpp> @@ -27,6 +27,7 @@ ) # define BOOST_MPL_CFG_NO_HAS_XXX +# define BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE #endif diff --git a/3rdParty/Boost/src/boost/mpl/aux_/contains_impl.hpp b/3rdParty/Boost/src/boost/mpl/aux_/contains_impl.hpp new file mode 100644 index 0000000..2ee4056 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/aux_/contains_impl.hpp @@ -0,0 +1,61 @@ + +#ifndef BOOST_MPL_AUX_CONTAINS_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_CONTAINS_IMPL_HPP_INCLUDED + +// Copyright Eric Friedman 2002 +// Copyright Aleksey Gurtovoy 2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: contains_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/contains_fwd.hpp> +#include <boost/mpl/begin_end.hpp> +#include <boost/mpl/find.hpp> +#include <boost/mpl/not.hpp> +#include <boost/mpl/aux_/traits_lambda_spec.hpp> +#include <boost/mpl/aux_/config/forwarding.hpp> +#include <boost/mpl/aux_/config/static_constant.hpp> + +#include <boost/type_traits/is_same.hpp> + +namespace boost { namespace mpl { + +template< typename Tag > +struct contains_impl +{ + template< typename Sequence, typename T > struct apply +#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) + : not_< is_same< + typename find<Sequence,T>::type + , typename end<Sequence>::type + > > + { +#else + { + typedef not_< is_same< + typename find<Sequence,T>::type + , typename end<Sequence>::type + > > type; + + BOOST_STATIC_CONSTANT(bool, value = + (not_< is_same< + typename find<Sequence,T>::type + , typename end<Sequence>::type + > >::value) + ); +#endif + }; +}; + +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(2,contains_impl) + +}} + +#endif // BOOST_MPL_AUX_CONTAINS_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/aux_/size_impl.hpp b/3rdParty/Boost/src/boost/mpl/aux_/size_impl.hpp new file mode 100644 index 0000000..0e4885d --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/aux_/size_impl.hpp @@ -0,0 +1,52 @@ + +#ifndef BOOST_MPL_AUX_SIZE_IMPL_HPP_INCLUDED +#define BOOST_MPL_AUX_SIZE_IMPL_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: size_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/size_fwd.hpp> +#include <boost/mpl/begin_end.hpp> +#include <boost/mpl/distance.hpp> +#include <boost/mpl/aux_/traits_lambda_spec.hpp> +#include <boost/mpl/aux_/config/workaround.hpp> + +namespace boost { namespace mpl { + +// default implementation; conrete sequences might override it by +// specializing either the 'size_impl' or the primary 'size' template + +template< typename Tag > +struct size_impl +{ + template< typename Sequence > struct apply +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x561)) + : distance< + typename begin<Sequence>::type + , typename end<Sequence>::type + > + { +#else + { + typedef typename distance< + typename begin<Sequence>::type + , typename end<Sequence>::type + >::type type; +#endif + }; +}; + +BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1, size_impl) + +}} + +#endif // BOOST_MPL_AUX_SIZE_IMPL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/contains.hpp b/3rdParty/Boost/src/boost/mpl/contains.hpp new file mode 100644 index 0000000..68e50bb --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/contains.hpp @@ -0,0 +1,41 @@ + +#ifndef BOOST_MPL_CONTAINS_HPP_INCLUDED +#define BOOST_MPL_CONTAINS_HPP_INCLUDED + +// Copyright Eric Friedman 2002 +// Copyright Aleksey Gurtovoy 2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: contains.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/contains_fwd.hpp> +#include <boost/mpl/sequence_tag.hpp> +#include <boost/mpl/aux_/contains_impl.hpp> +#include <boost/mpl/aux_/na_spec.hpp> +#include <boost/mpl/aux_/lambda_support.hpp> + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + , typename BOOST_MPL_AUX_NA_PARAM(T) + > +struct contains + : contains_impl< typename sequence_tag<Sequence>::type > + ::template apply< Sequence,T > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,contains,(Sequence,T)) +}; + +BOOST_MPL_AUX_NA_SPEC(2, contains) + +}} + +#endif // BOOST_MPL_CONTAINS_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/contains_fwd.hpp b/3rdParty/Boost/src/boost/mpl/contains_fwd.hpp new file mode 100644 index 0000000..57ae63f --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/contains_fwd.hpp @@ -0,0 +1,25 @@ + +#ifndef BOOST_MPL_CONTAINS_FWD_HPP_INCLUDED +#define BOOST_MPL_CONTAINS_FWD_HPP_INCLUDED + +// Copyright Eric Friedman 2002 +// Copyright Aleksey Gurtovoy 2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: contains_fwd.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +namespace boost { namespace mpl { + +template< typename Tag > struct contains_impl; +template< typename Sequence, typename T > struct contains; + +}} + +#endif // BOOST_MPL_CONTAINS_FWD_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/copy.hpp b/3rdParty/Boost/src/boost/mpl/copy.hpp new file mode 100644 index 0000000..77376d0 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/copy.hpp @@ -0,0 +1,58 @@ + +#ifndef BOOST_MPL_COPY_HPP_INCLUDED +#define BOOST_MPL_COPY_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// Copyright David Abrahams 2003-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: copy.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/fold.hpp> +#include <boost/mpl/reverse_fold.hpp> +#include <boost/mpl/aux_/inserter_algorithm.hpp> + +namespace boost { namespace mpl { + +namespace aux { + +template< + typename Sequence + , typename Inserter + > +struct copy_impl + : fold< + Sequence + , typename Inserter::state + , typename Inserter::operation + > +{ +}; + +template< + typename Sequence + , typename Inserter + > +struct reverse_copy_impl + : reverse_fold< + Sequence + , typename Inserter::state + , typename Inserter::operation + > +{ +}; + +} // namespace aux + +BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF(2, copy) + +}} + +#endif // BOOST_MPL_COPY_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/eval_if.hpp b/3rdParty/Boost/src/boost/mpl/eval_if.hpp index 3d94caf..d483c72 100644 --- a/3rdParty/Boost/src/boost/mpl/eval_if.hpp +++ b/3rdParty/Boost/src/boost/mpl/eval_if.hpp @@ -10,9 +10,9 @@ // // See http://www.boost.org/libs/mpl for documentation. -// $Id: eval_if.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ -// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ -// $Revision: 49267 $ +// $Id: eval_if.hpp 61921 2010-05-11 21:33:24Z neilgroves $ +// $Date: 2010-05-11 17:33:24 -0400 (Tue, 11 May 2010) $ +// $Revision: 61921 $ #include <boost/mpl/if.hpp> #include <boost/mpl/aux_/na_spec.hpp> diff --git a/3rdParty/Boost/src/boost/mpl/find.hpp b/3rdParty/Boost/src/boost/mpl/find.hpp new file mode 100644 index 0000000..6d71a88 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/find.hpp @@ -0,0 +1,38 @@ + +#ifndef BOOST_MPL_FIND_HPP_INCLUDED +#define BOOST_MPL_FIND_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2002 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: find.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/find_if.hpp> +#include <boost/mpl/same_as.hpp> +#include <boost/mpl/aux_/na_spec.hpp> +#include <boost/mpl/aux_/lambda_support.hpp> + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + , typename BOOST_MPL_AUX_NA_PARAM(T) + > +struct find + : find_if< Sequence,same_as<T> > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(2,find,(Sequence,T)) +}; + +BOOST_MPL_AUX_NA_SPEC(2, find) + +}} + +#endif // BOOST_MPL_FIND_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/has_xxx.hpp b/3rdParty/Boost/src/boost/mpl/has_xxx.hpp index 39ed909..9258759 100644 --- a/3rdParty/Boost/src/boost/mpl/has_xxx.hpp +++ b/3rdParty/Boost/src/boost/mpl/has_xxx.hpp @@ -4,6 +4,7 @@ // Copyright Aleksey Gurtovoy 2002-2006 // Copyright David Abrahams 2002-2003 +// Copyright Daniel Walker 2007 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -11,20 +12,26 @@ // // See http://www.boost.org/libs/mpl for documentation. -// $Id: has_xxx.hpp 49273 2008-10-11 06:54:06Z agurtovoy $ -// $Date: 2008-10-11 02:54:06 -0400 (Sat, 11 Oct 2008) $ -// $Revision: 49273 $ +// $Id: has_xxx.hpp 64146 2010-07-19 00:46:31Z djwalker $ +// $Date: 2010-07-18 20:46:31 -0400 (Sun, 18 Jul 2010) $ +// $Revision: 64146 $ #include <boost/mpl/bool.hpp> +#include <boost/mpl/aux_/na_spec.hpp> #include <boost/mpl/aux_/type_wrapper.hpp> #include <boost/mpl/aux_/yes_no.hpp> +#include <boost/mpl/aux_/config/gcc.hpp> #include <boost/mpl/aux_/config/has_xxx.hpp> #include <boost/mpl/aux_/config/msvc_typename.hpp> #include <boost/mpl/aux_/config/msvc.hpp> #include <boost/mpl/aux_/config/static_constant.hpp> #include <boost/mpl/aux_/config/workaround.hpp> +#include <boost/preprocessor/array/elem.hpp> #include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/control/if.hpp> +#include <boost/preprocessor/repetition/enum_params.hpp> +#include <boost/preprocessor/repetition/enum_trailing_params.hpp> #if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) ) # include <boost/type_traits/is_class.hpp> @@ -271,4 +278,363 @@ struct trait \ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(BOOST_PP_CAT(has_,name), name, false) \ /**/ + +#if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) + +// Create a boolean Metafunction to detect a nested template +// member. This implementation is based on a USENET newsgroup's +// posting by Aleksey Gurtovoy (comp.lang.c++.moderated, 2002-03-19), +// Rani Sharoni's USENET posting cited above, the non-template has_xxx +// implementations above, and discussion on the Boost mailing list. + +# if !defined(BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES) +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) +# define BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 1 +# endif +# endif + +# if !defined(BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION) +# if (defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)) +# define BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 1 +# endif +# endif + +# if !defined(BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE) +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) +# define BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 1 +# endif +# endif + +// NOTE: Many internal implementation macros take a Boost.Preprocessor +// array argument called args which is of the following form. +// ( 4, ( trait, name, max_arity, default_ ) ) + +# define BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ + BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _introspect) \ + /**/ + +# define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ + BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _substitute), n) \ + /**/ + +# define BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) \ + BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _test) \ + /**/ + +// Thanks to Guillaume Melquiond for pointing out the need for the +// "substitute" template as an argument to the overloaded test +// functions to get SFINAE to work for member templates with the +// correct name but different number of arguments. +# define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE(z, n, args) \ + template< \ + template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename V) > class V \ + > \ + struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) { \ + }; \ + /**/ + +# define BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \ + BOOST_PP_REPEAT( \ + BOOST_PP_ARRAY_ELEM(2, args) \ + , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE \ + , args \ + ) \ + /**/ + +# if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION +# define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ + template< typename V > \ + static boost::mpl::aux::no_tag \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \ + /**/ +# else +# define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ + static boost::mpl::aux::no_tag \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \ + /**/ +# endif + +# if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES +# define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT(z, n, args) \ + template< typename V > \ + static boost::mpl::aux::yes_tag \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ + boost::mpl::aux::type_wrapper< V > const volatile* \ + , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) < \ + V::template BOOST_PP_ARRAY_ELEM(1, args) \ + >* = 0 \ + ); \ + /**/ +# define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ + BOOST_PP_REPEAT( \ + BOOST_PP_ARRAY_ELEM(2, args) \ + , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT \ + , args \ + ) \ + /**/ +# else +# define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ + template< typename V > \ + static boost::mpl::aux::yes_tag \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ + V const volatile* \ + , member_macro(args, V, T)* = 0 \ + ); \ + /**/ +# endif + +# if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION +# define BOOST_MPL_HAS_MEMBER_TEST(args) \ + sizeof(BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U >(0)) \ + == sizeof(boost::mpl::aux::yes_tag) \ + /**/ +# else +# if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES +# define BOOST_MPL_HAS_MEMBER_TEST(args) \ + sizeof( \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ + static_cast< boost::mpl::aux::type_wrapper< U >* >(0) \ + ) \ + ) == sizeof(boost::mpl::aux::yes_tag) \ + /**/ +# else +# define BOOST_MPL_HAS_MEMBER_TEST(args) \ + sizeof( \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ + static_cast< U* >(0) \ + ) \ + ) == sizeof(boost::mpl::aux::yes_tag) \ + /**/ +# endif +# endif + +# define BOOST_MPL_HAS_MEMBER_INTROSPECT( \ + args, substitute_macro, member_macro \ + ) \ + template< typename U > \ + struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) { \ + BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \ + BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ + BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ + BOOST_STATIC_CONSTANT( \ + bool, value = BOOST_MPL_HAS_MEMBER_TEST(args) \ + ); \ + typedef boost::mpl::bool_< value > type; \ + }; \ + /**/ + +# define BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ + args, introspect_macro, substitute_macro, member_macro \ + ) \ + template< \ + typename T \ + , typename fallback_ \ + = boost::mpl::bool_< BOOST_PP_ARRAY_ELEM(3, args) > \ + > \ + class BOOST_PP_ARRAY_ELEM(0, args) { \ + introspect_macro(args, substitute_macro, member_macro) \ + public: \ + static const bool value \ + = BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< T >::value; \ + typedef typename BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< \ + T \ + >::type type; \ + }; \ + /**/ + +// BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE expands to the full +// implementation of the function-based metafunction. Compile with -E +// to see the preprocessor output for this macro. +# define BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \ + args, substitute_macro, member_macro \ + ) \ + BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ + args \ + , BOOST_MPL_HAS_MEMBER_INTROSPECT \ + , substitute_macro \ + , member_macro \ + ) \ + /**/ + +# if BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE + +# if !defined(BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE) +# if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) +# define BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE 1 +# endif +# endif + +# if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE +# define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ + args, n \ + ) \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ + /**/ +# else +# define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ + args, n \ + ) \ + BOOST_PP_CAT( \ + boost_mpl_has_xxx_ \ + , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ + ) \ + /**/ +# endif + +# define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME( \ + args \ + ) \ + BOOST_PP_CAT( \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ + args, 0 \ + ) \ + , _tag \ + ) \ + /**/ + +# define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ + z, n, args \ + ) \ + template< \ + template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename U) > class U \ + > \ + struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ + args, n \ + ) { \ + typedef \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \ + type; \ + }; \ + /**/ + +# define BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ + args, substitute_macro \ + ) \ + typedef void \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \ + BOOST_PP_REPEAT( \ + BOOST_PP_ARRAY_ELEM(2, args) \ + , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE \ + , args \ + ) \ + /**/ + +# define BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE( \ + args, member_macro \ + ) \ + template< \ + typename U \ + , typename V \ + = BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \ + > \ + struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) { \ + BOOST_STATIC_CONSTANT(bool, value = false); \ + typedef boost::mpl::bool_< value > type; \ + }; \ + /**/ + +# define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE( \ + z, n, args \ + ) \ + template< typename U > \ + struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \ + U \ + , typename \ + BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ + args, n \ + )< \ + BOOST_MSVC_TYPENAME U::BOOST_PP_ARRAY_ELEM(1, args)< > \ + >::type \ + > { \ + BOOST_STATIC_CONSTANT(bool, value = true); \ + typedef boost::mpl::bool_< value > type; \ + }; \ + /**/ + +# define BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE( \ + args, member_macro \ + ) \ + BOOST_PP_REPEAT( \ + BOOST_PP_ARRAY_ELEM(2, args) \ + , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE \ + , args \ + ) \ + /**/ + +# define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \ + args, substitute_macro, member_macro \ + ) \ + BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE(args, member_macro) \ + BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE(args, member_macro) \ + template< typename U > \ + struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ + : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U > { \ + }; \ + /**/ + +// BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE expands to the full +// implementation of the template-based metafunction. Compile with -E +// to see the preprocessor output for this macro. +// +// Note that if BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE is +// defined BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE needs +// to be expanded at namespace level before +// BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE can be used. +# define BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \ + args, substitute_macro, member_macro \ + ) \ + BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ + args, substitute_macro \ + ) \ + BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ + args \ + , BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \ + , substitute_macro \ + , member_macro \ + ) \ + /**/ + +# endif // BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE + +// Note: In the current implementation the parameter and access macros +// are no longer expanded. +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400) +# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ + BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \ + ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \ + , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \ + , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \ + ) \ + /**/ +# else +# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ + BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \ + ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \ + , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \ + , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \ + ) \ + /**/ +# endif + +#else // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE + +// placeholder implementation + +# define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \ + template< typename T \ + , typename fallback_ = boost::mpl::bool_< default_ > > \ + struct trait { \ + BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \ + typedef fallback_ type; \ + }; \ + /**/ + +#endif // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE + +# define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name) \ + BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( \ + BOOST_PP_CAT(has_, name), name, false \ + ) \ + /**/ + #endif // BOOST_MPL_HAS_XXX_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/mpl/size.hpp b/3rdParty/Boost/src/boost/mpl/size.hpp new file mode 100644 index 0000000..6ff2e65 --- /dev/null +++ b/3rdParty/Boost/src/boost/mpl/size.hpp @@ -0,0 +1,42 @@ + +#ifndef BOOST_MPL_SIZE_HPP_INCLUDED +#define BOOST_MPL_SIZE_HPP_INCLUDED + +// Copyright Aleksey Gurtovoy 2000-2004 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/mpl for documentation. + +// $Id: size.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ +// $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ +// $Revision: 49267 $ + +#include <boost/mpl/size_fwd.hpp> +#include <boost/mpl/sequence_tag.hpp> +#include <boost/mpl/aux_/size_impl.hpp> +#include <boost/mpl/aux_/na_spec.hpp> +#include <boost/mpl/aux_/lambda_support.hpp> +#include <boost/mpl/aux_/msvc_eti_base.hpp> + +namespace boost { namespace mpl { + +template< + typename BOOST_MPL_AUX_NA_PARAM(Sequence) + > +struct size + : aux::msvc_eti_base< + typename size_impl< typename sequence_tag<Sequence>::type > + ::template apply< Sequence >::type + >::type +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1, size, (Sequence)) +}; + +BOOST_MPL_AUX_NA_SPEC(1, size) + +}} + +#endif // BOOST_MPL_SIZE_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/optional/optional.hpp b/3rdParty/Boost/src/boost/optional/optional.hpp index 42277ba..88041d1 100644 --- a/3rdParty/Boost/src/boost/optional/optional.hpp +++ b/3rdParty/Boost/src/boost/optional/optional.hpp @@ -4,7 +4,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// See http://www.boost.org/lib/optional for documentation. +// See http://www.boost.org/libs/optional for documentation. // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com @@ -168,8 +168,10 @@ class optional_base : public optional_tag typedef BOOST_DEDUCED_TYPENAME is_reference<T>::type is_reference_predicate ; + public: typedef BOOST_DEDUCED_TYPENAME mpl::if_<is_reference_predicate,types_when_ref,types_when_not_ref>::type types ; + protected: typedef bool (this_type::*unspecified_bool_type)() const; typedef BOOST_DEDUCED_TYPENAME types::reference_type reference_type ; diff --git a/3rdParty/Boost/src/boost/optional/optional_fwd.hpp b/3rdParty/Boost/src/boost/optional/optional_fwd.hpp index 2cf4fa6..dcde233 100644 --- a/3rdParty/Boost/src/boost/optional/optional_fwd.hpp +++ b/3rdParty/Boost/src/boost/optional/optional_fwd.hpp @@ -4,7 +4,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// See http://www.boost.org/lib/optional for documentation. +// See http://www.boost.org/libs/optional for documentation. // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com diff --git a/3rdParty/Boost/src/boost/program_options/detail/cmdline.hpp b/3rdParty/Boost/src/boost/program_options/detail/cmdline.hpp index 8d60ead..7c43152 100644 --- a/3rdParty/Boost/src/boost/program_options/detail/cmdline.hpp +++ b/3rdParty/Boost/src/boost/program_options/detail/cmdline.hpp @@ -22,6 +22,11 @@ #include <string> #include <vector> +#if defined(BOOST_MSVC) +# pragma warning (push) +# pragma warning (disable:4251) // class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class 'boost::program_options::positional_options_description' +#endif + namespace boost { namespace program_options { namespace detail { /** Command line parser class. Main requirements were: @@ -134,5 +139,9 @@ namespace boost { namespace program_options { namespace detail { }}} +#if defined(BOOST_MSVC) +# pragma warning (pop) +#endif + #endif diff --git a/3rdParty/Boost/src/boost/program_options/detail/parsers.hpp b/3rdParty/Boost/src/boost/program_options/detail/parsers.hpp index ee19207..506cb35 100644 --- a/3rdParty/Boost/src/boost/program_options/detail/parsers.hpp +++ b/3rdParty/Boost/src/boost/program_options/detail/parsers.hpp @@ -29,8 +29,8 @@ namespace boost { namespace program_options { template<class charT> basic_command_line_parser<charT>:: basic_command_line_parser(const std::vector< - std::basic_string<charT> >& args) - : detail::cmdline(to_internal(args)) + std::basic_string<charT> >& xargs) + : detail::cmdline(to_internal(xargs)) {} @@ -64,9 +64,9 @@ namespace boost { namespace program_options { template<class charT> basic_command_line_parser<charT>& - basic_command_line_parser<charT>::style(int style) + basic_command_line_parser<charT>::style(int xstyle) { - detail::cmdline::style(style); + detail::cmdline::style(xstyle); return *this; } diff --git a/3rdParty/Boost/src/boost/program_options/detail/value_semantic.hpp b/3rdParty/Boost/src/boost/program_options/detail/value_semantic.hpp index 464e306..e4b15d7 100644 --- a/3rdParty/Boost/src/boost/program_options/detail/value_semantic.hpp +++ b/3rdParty/Boost/src/boost/program_options/detail/value_semantic.hpp @@ -143,9 +143,9 @@ namespace boost { namespace program_options { a validator for class T, we use it even when parsing vector<T>. */ boost::any a; - std::vector<std::basic_string<charT> > v; - v.push_back(s[i]); - validate(a, v, (T*)0, 0); + std::vector<std::basic_string<charT> > cv; + cv.push_back(s[i]); + validate(a, cv, (T*)0, 0); tv->push_back(boost::any_cast<T>(a)); } catch(const bad_lexical_cast& /*e*/) { diff --git a/3rdParty/Boost/src/boost/program_options/errors.hpp b/3rdParty/Boost/src/boost/program_options/errors.hpp index 116af58..ff6bc7f 100644 --- a/3rdParty/Boost/src/boost/program_options/errors.hpp +++ b/3rdParty/Boost/src/boost/program_options/errors.hpp @@ -13,14 +13,18 @@ #include <stdexcept> #include <vector> - +#if defined(BOOST_MSVC) +# pragma warning (push) +# pragma warning (disable:4275) // non dll-interface class 'std::logic_error' used as base for dll-interface class 'boost::program_options::error' +# pragma warning (disable:4251) // class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class 'boost::program_options::ambiguous_option' +#endif namespace boost { namespace program_options { /** Base class for all errors in the library. */ class BOOST_PROGRAM_OPTIONS_DECL error : public std::logic_error { public: - error(const std::string& what) : std::logic_error(what) {} + error(const std::string& xwhat) : std::logic_error(xwhat) {} }; class BOOST_PROGRAM_OPTIONS_DECL invalid_syntax : public error { @@ -78,9 +82,9 @@ namespace boost { namespace program_options { class BOOST_PROGRAM_OPTIONS_DECL ambiguous_option : public error { public: ambiguous_option(const std::string& name, - const std::vector<std::string>& alternatives) + const std::vector<std::string>& xalternatives) : error(std::string("ambiguous option ").append(name)) - , m_alternatives(alternatives) + , m_alternatives(xalternatives) , m_option_name(name) {} @@ -232,5 +236,8 @@ namespace boost { namespace program_options { }; }} +#if defined(BOOST_MSVC) +# pragma warning (pop) +#endif #endif diff --git a/3rdParty/Boost/src/boost/program_options/option.hpp b/3rdParty/Boost/src/boost/program_options/option.hpp index 557c692..fa6be52 100644 --- a/3rdParty/Boost/src/boost/program_options/option.hpp +++ b/3rdParty/Boost/src/boost/program_options/option.hpp @@ -28,10 +28,10 @@ namespace boost { namespace program_options { , unregistered(false) , case_insensitive(false) {} - basic_option(const std::string& string_key, - const std::vector< std::string> &value) - : string_key(string_key) - , value(value) + basic_option(const std::string& xstring_key, + const std::vector< std::string> &xvalue) + : string_key(xstring_key) + , value(xvalue) , unregistered(false) , case_insensitive(false) {} diff --git a/3rdParty/Boost/src/boost/program_options/options_description.hpp b/3rdParty/Boost/src/boost/program_options/options_description.hpp index 0486f02..eff1f90 100644 --- a/3rdParty/Boost/src/boost/program_options/options_description.hpp +++ b/3rdParty/Boost/src/boost/program_options/options_description.hpp @@ -25,6 +25,12 @@ #include <iosfwd> +#if defined(BOOST_MSVC) +# pragma warning (push) +# pragma warning (disable:4251) // class 'boost::shared_ptr<T>' needs to have dll-interface to be used by clients of class 'boost::program_options::option_description' +#endif + + /** Boost namespace */ namespace boost { /** Namespace for the library. */ @@ -65,7 +71,7 @@ namespace program_options { The 'name' parameter is interpreted by the following rules: - if there's no "," character in 'name', it specifies long name - otherwise, the part before "," specifies long name and the part - after -- long name. + after -- short name. */ option_description(const char* name, const value_semantic* s); @@ -81,12 +87,12 @@ namespace program_options { enum match_result { no_match, full_match, approximate_match }; /** Given 'option', specified in the input source, - return 'true' is 'option' specifies *this. + returns 'true' if 'option' specifies *this. */ match_result match(const std::string& option, bool approx, bool long_ignore_case, bool short_ignore_case) const; - /** Return the key that should identify the option, in + /** Returns the key that should identify the option, in particular in the variables_map class. The 'option' parameter is the option spelling from the input source. @@ -107,7 +113,7 @@ namespace program_options { /// Returns the option name, formatted suitably for usage message. std::string format_name() const; - /** Return the parameter name and properties, formatted suitably for + /** Returns the parameter name and properties, formatted suitably for usage message. */ std::string format_parameter() const; @@ -211,7 +217,7 @@ namespace program_options { friend BOOST_PROGRAM_OPTIONS_DECL std::ostream& operator<<(std::ostream& os, const options_description& desc); - /** Output 'desc' to the specified stream, calling 'f' to output each + /** Outputs 'desc' to the specified stream, calling 'f' to output each option_description element. */ void print(std::ostream& os) const; @@ -247,8 +253,12 @@ namespace program_options { /** Class thrown when duplicate option description is found. */ class BOOST_PROGRAM_OPTIONS_DECL duplicate_option_error : public error { public: - duplicate_option_error(const std::string& what) : error(what) {} + duplicate_option_error(const std::string& xwhat) : error(xwhat) {} }; }} +#if defined(BOOST_MSVC) +# pragma warning (pop) +#endif + #endif diff --git a/3rdParty/Boost/src/boost/program_options/parsers.hpp b/3rdParty/Boost/src/boost/program_options/parsers.hpp index e2a4467..49fb19c 100644 --- a/3rdParty/Boost/src/boost/program_options/parsers.hpp +++ b/3rdParty/Boost/src/boost/program_options/parsers.hpp @@ -17,6 +17,11 @@ #include <vector> #include <utility> +#if defined(BOOST_MSVC) +# pragma warning (push) +# pragma warning (disable:4251) // class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class 'boost::program_options::basic_parsed_options<wchar_t>' +#endif + namespace boost { namespace program_options { class options_description; @@ -31,8 +36,8 @@ namespace boost { namespace program_options { template<class charT> class basic_parsed_options { public: - explicit basic_parsed_options(const options_description* description) - : description(description) {} + explicit basic_parsed_options(const options_description* xdescription) + : description(xdescription) {} /** Options found in the source. */ std::vector< basic_option<charT> > options; /** Options description that was used for parsing. diff --git a/3rdParty/Boost/src/boost/program_options/positional_options.hpp b/3rdParty/Boost/src/boost/program_options/positional_options.hpp index 01406e0..ac2a312 100644 --- a/3rdParty/Boost/src/boost/program_options/positional_options.hpp +++ b/3rdParty/Boost/src/boost/program_options/positional_options.hpp @@ -11,6 +11,11 @@ #include <vector> #include <string> +#if defined(BOOST_MSVC) +# pragma warning (push) +# pragma warning (disable:4251) // class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class 'boost::program_options::positional_options_description' +#endif + namespace boost { namespace program_options { /** Describes positional options. @@ -61,5 +66,9 @@ namespace boost { namespace program_options { }} +#if defined(BOOST_MSVC) +# pragma warning (pop) +#endif + #endif diff --git a/3rdParty/Boost/src/boost/program_options/variables_map.hpp b/3rdParty/Boost/src/boost/program_options/variables_map.hpp index 02c4af2..9621e05 100644 --- a/3rdParty/Boost/src/boost/program_options/variables_map.hpp +++ b/3rdParty/Boost/src/boost/program_options/variables_map.hpp @@ -16,6 +16,11 @@ #include <map> #include <set> +#if defined(BOOST_MSVC) +# pragma warning (push) +# pragma warning (disable:4251) // 'boost::program_options::variable_value::v' : class 'boost::any' needs to have dll-interface to be used by clients of class 'boost::program_options::variable_value +#endif + namespace boost { namespace program_options { template<class charT> @@ -53,8 +58,8 @@ namespace boost { namespace program_options { class BOOST_PROGRAM_OPTIONS_DECL variable_value { public: variable_value() : m_defaulted(false) {} - variable_value(const boost::any& v, bool defaulted) - : v(v), m_defaulted(defaulted) + variable_value(const boost::any& xv, bool xdefaulted) + : v(xv), m_defaulted(xdefaulted) {} /** If stored value if of type T, returns that value. Otherwise, diff --git a/3rdParty/Boost/src/boost/range/algorithm/equal.hpp b/3rdParty/Boost/src/boost/range/algorithm/equal.hpp index 7226440..a3ebc29 100755 --- a/3rdParty/Boost/src/boost/range/algorithm/equal.hpp +++ b/3rdParty/Boost/src/boost/range/algorithm/equal.hpp @@ -159,8 +159,8 @@ namespace boost template< class SinglePassRange1, class SinglePassRange2 > inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2 ) { - BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> )); - BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> )); return ::boost::range_detail::equal( ::boost::begin(rng1), ::boost::end(rng1), @@ -172,8 +172,8 @@ namespace boost inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred ) { - BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> )); - BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> )); return ::boost::range_detail::equal( ::boost::begin(rng1), ::boost::end(rng1), diff --git a/3rdParty/Boost/src/boost/regex/config.hpp b/3rdParty/Boost/src/boost/regex/config.hpp index e4b2138..a88a785 100644 --- a/3rdParty/Boost/src/boost/regex/config.hpp +++ b/3rdParty/Boost/src/boost/regex/config.hpp @@ -186,16 +186,19 @@ * ****************************************************************************/ -#if defined(BOOST_HAS_DECLSPEC) && (defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_REGEX_STATIC_LINK) +#ifndef BOOST_SYMBOL_EXPORT +# define BOOST_SYMBOL_EXPORT +# define BOOST_SYMBOL_IMPORT +#endif + +#if (defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_REGEX_STATIC_LINK) # if defined(BOOST_REGEX_SOURCE) -# define BOOST_REGEX_DECL __declspec(dllexport) +# define BOOST_REGEX_DECL BOOST_SYMBOL_EXPORT # define BOOST_REGEX_BUILD_DLL # else -# define BOOST_REGEX_DECL __declspec(dllimport) +# define BOOST_REGEX_DECL BOOST_SYMBOL_IMPORT # endif -#endif - -#ifndef BOOST_REGEX_DECL +#else # define BOOST_REGEX_DECL #endif @@ -252,6 +255,10 @@ # define BOOST_REGEX_USE_CPP_LOCALE #endif +#if defined(__CYGWIN__) +# define BOOST_REGEX_USE_C_LOCALE +#endif + /* Win32 defaults to native Win32 locale: */ #if defined(_WIN32) && !defined(BOOST_REGEX_USE_WIN32_LOCALE) && !defined(BOOST_REGEX_USE_C_LOCALE) && !defined(BOOST_REGEX_USE_CPP_LOCALE) && !defined(BOOST_REGEX_NO_W32) # define BOOST_REGEX_USE_WIN32_LOCALE diff --git a/3rdParty/Boost/src/boost/regex/icu.hpp b/3rdParty/Boost/src/boost/regex/icu.hpp index c8770c6..e9a55c0 100644 --- a/3rdParty/Boost/src/boost/regex/icu.hpp +++ b/3rdParty/Boost/src/boost/regex/icu.hpp @@ -27,6 +27,10 @@ #include <boost/mpl/int_fwd.hpp> #include <bitset> +#ifdef BOOST_MSVC +#pragma warning (push) +#pragma warning (disable: 4251) +#endif namespace boost{ @@ -1015,6 +1019,10 @@ inline U_NAMESPACE_QUALIFIER UnicodeString u32regex_replace(const U_NAMESPACE_QU } // namespace boost. +#ifdef BOOST_MSVC +#pragma warning (pop) +#endif + #include <boost/regex/v4/u32regex_iterator.hpp> #include <boost/regex/v4/u32regex_token_iterator.hpp> diff --git a/3rdParty/Boost/src/boost/regex/pending/object_cache.hpp b/3rdParty/Boost/src/boost/regex/pending/object_cache.hpp index e1aa191..db60e28 100644 --- a/3rdParty/Boost/src/boost/regex/pending/object_cache.hpp +++ b/3rdParty/Boost/src/boost/regex/pending/object_cache.hpp @@ -41,10 +41,10 @@ public: typedef std::map<Key, list_iterator> map_type; typedef typename map_type::iterator map_iterator; typedef typename list_type::size_type size_type; - static boost::shared_ptr<Object const> get(const Key& k, size_type max_cache_size); + static boost::shared_ptr<Object const> get(const Key& k, size_type l_max_cache_size); private: - static boost::shared_ptr<Object const> do_get(const Key& k, size_type max_cache_size); + static boost::shared_ptr<Object const> do_get(const Key& k, size_type l_max_cache_size); struct data { @@ -58,7 +58,7 @@ private: }; template <class Key, class Object> -boost::shared_ptr<Object const> object_cache<Key, Object>::get(const Key& k, size_type max_cache_size) +boost::shared_ptr<Object const> object_cache<Key, Object>::get(const Key& k, size_type l_max_cache_size) { #ifdef BOOST_HAS_THREADS static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT; @@ -66,7 +66,7 @@ boost::shared_ptr<Object const> object_cache<Key, Object>::get(const Key& k, siz boost::static_mutex::scoped_lock l(mut); if(l) { - return do_get(k, max_cache_size); + return do_get(k, l_max_cache_size); } // // what do we do if the lock fails? @@ -77,12 +77,12 @@ boost::shared_ptr<Object const> object_cache<Key, Object>::get(const Key& k, siz return boost::shared_ptr<Object>(); #endif #else - return do_get(k, max_cache_size); + return do_get(k, l_max_cache_size); #endif } template <class Key, class Object> -boost::shared_ptr<Object const> object_cache<Key, Object>::do_get(const Key& k, size_type max_cache_size) +boost::shared_ptr<Object const> object_cache<Key, Object>::do_get(const Key& k, size_type l_max_cache_size) { typedef typename object_cache<Key, Object>::data object_data; typedef typename map_type::size_type map_size_type; @@ -128,7 +128,7 @@ boost::shared_ptr<Object const> object_cache<Key, Object>::do_get(const Key& k, BOOST_ASSERT(s_data.index[k]->first.get() == result.get()); BOOST_ASSERT(&(s_data.index.find(k)->first) == s_data.cont.back().second); BOOST_ASSERT(s_data.index.find(k)->first == k); - if(s > max_cache_size) + if(s > l_max_cache_size) { // // We have too many items in the list, so we need to start @@ -137,7 +137,7 @@ boost::shared_ptr<Object const> object_cache<Key, Object>::do_get(const Key& k, // list_iterator pos = s_data.cont.begin(); list_iterator last = s_data.cont.end(); - while((pos != last) && (s > max_cache_size)) + while((pos != last) && (s > l_max_cache_size)) { if(pos->first.unique()) { diff --git a/3rdParty/Boost/src/boost/regex/pending/static_mutex.hpp b/3rdParty/Boost/src/boost/regex/pending/static_mutex.hpp index 334ef27..9c10050 100644 --- a/3rdParty/Boost/src/boost/regex/pending/static_mutex.hpp +++ b/3rdParty/Boost/src/boost/regex/pending/static_mutex.hpp @@ -96,8 +96,14 @@ class BOOST_REGEX_DECL scoped_static_mutex_lock public: scoped_static_mutex_lock(static_mutex& mut, bool lk = true); ~scoped_static_mutex_lock(); - operator void const*()const; - bool locked()const; + operator void const*()const + { + return locked() ? this : 0; + } + bool locked()const + { + return m_have_lock; + } void lock(); void unlock(); private: @@ -107,16 +113,6 @@ private: scoped_static_mutex_lock& operator=(const scoped_static_mutex_lock&); }; -inline scoped_static_mutex_lock::operator void const*()const -{ - return locked() ? this : 0; -} - -inline bool scoped_static_mutex_lock::locked()const -{ - return m_have_lock; -} - } // namespace #else diff --git a/3rdParty/Boost/src/boost/regex/v4/basic_regex.hpp b/3rdParty/Boost/src/boost/regex/v4/basic_regex.hpp index 09b0467..04c7bb3 100644 --- a/3rdParty/Boost/src/boost/regex/v4/basic_regex.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/basic_regex.hpp @@ -53,7 +53,7 @@ void bubble_down_one(I first, I last) if(first != last) { I next = last - 1; - while((next != first) && !(*(next-1) < *next)) + while((next != first) && (*next < *(next-1))) { (next-1)->swap(*next); --next; @@ -61,70 +61,59 @@ void bubble_down_one(I first, I last) } } -// -// Class named_subexpressions -// Contains information about named subexpressions within the regex. -// -template <class charT> -class named_subexpressions_base -{ -public: - virtual int get_id(const charT* i, const charT* j)const = 0; - virtual int get_id(std::size_t hash)const = 0; -#ifdef __GNUC__ - // warning supression: - virtual ~named_subexpressions_base(){} -#endif -}; - template <class Iterator> -inline std::size_t hash_value_from_capture_name(Iterator i, Iterator j) +inline int hash_value_from_capture_name(Iterator i, Iterator j) { std::size_t r = boost::hash_range(i, j); r %= ((std::numeric_limits<int>::max)() - 10001); r += 10000; - return r; + return static_cast<int>(r); } -template <class charT> -class named_subexpressions : public named_subexpressions_base<charT> +class named_subexpressions { +public: struct name { + template <class charT> name(const charT* i, const charT* j, int idx) - : /*n(i, j), */ index(idx) + : index(idx) { hash = hash_value_from_capture_name(i, j); } - name(std::size_t h, int idx) + name(int h, int idx) : index(idx), hash(h) { } - //std::vector<charT> n; int index; - std::size_t hash; + int hash; bool operator < (const name& other)const { - return hash < other.hash; //std::lexicographical_compare(n.begin(), n.end(), other.n.begin(), other.n.end()); + return hash < other.hash; } bool operator == (const name& other)const { - return hash == other.hash; //n == other.n; + return hash == other.hash; } void swap(name& other) { - //n.swap(other.n); std::swap(index, other.index); std::swap(hash, other.hash); } }; -public: + + typedef std::vector<name>::const_iterator const_iterator; + typedef std::pair<const_iterator, const_iterator> range_type; + named_subexpressions(){} + + template <class charT> void set_name(const charT* i, const charT* j, int index) { m_sub_names.push_back(name(i, j, index)); bubble_down_one(m_sub_names.begin(), m_sub_names.end()); } + template <class charT> int get_id(const charT* i, const charT* j)const { name t(i, j, 0); @@ -135,72 +124,37 @@ public: } return -1; } - int get_id(std::size_t h)const + template <class charT> + range_type equal_range(const charT* i, const charT* j)const + { + name t(i, j, 0); + return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t); + } + int get_id(int h)const { name t(h, 0); - typename std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t); + std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t); if((pos != m_sub_names.end()) && (*pos == t)) { return pos->index; } return -1; } -private: - std::vector<name> m_sub_names; -}; - -template <class charT, class Other> -class named_subexpressions_converter : public named_subexpressions_base<charT> -{ - boost::shared_ptr<named_subexpressions<Other> > m_converter; -public: - named_subexpressions_converter(boost::shared_ptr<named_subexpressions<Other> > s) - : m_converter(s) {} - int get_id(const charT* i, const charT* j)const - { - if(i == j) - return -1; - std::vector<Other> v; - while(i != j) - { - v.push_back(*i); - ++i; - } - return m_converter->get_id(&v[0], &v[0] + v.size()); - } - int get_id(std::size_t h)const + range_type equal_range(int h)const { - return m_converter->get_id(h); + name t(h, 0); + return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t); } +private: + std::vector<name> m_sub_names; }; -template <class To> -inline boost::shared_ptr<named_subexpressions_base<To> > convert_to_named_subs_imp( - boost::shared_ptr<named_subexpressions<To> > s, - boost::integral_constant<bool,true> const&) -{ - return s; -} -template <class To, class From> -inline boost::shared_ptr<named_subexpressions_base<To> > convert_to_named_subs_imp( - boost::shared_ptr<named_subexpressions<From> > s, - boost::integral_constant<bool,false> const&) -{ - return boost::shared_ptr<named_subexpressions_converter<To, From> >(new named_subexpressions_converter<To, From>(s)); -} -template <class To, class From> -inline boost::shared_ptr<named_subexpressions_base<To> > convert_to_named_subs( - boost::shared_ptr<named_subexpressions<From> > s) -{ - typedef typename boost::is_same<To, From>::type tag_type; - return convert_to_named_subs_imp<To>(s, tag_type()); -} // // class regex_data: // represents the data we wish to expose to the matching algorithms. // template <class charT, class traits> -struct regex_data : public named_subexpressions<charT> +struct regex_data : public named_subexpressions { typedef regex_constants::syntax_option_type flag_type; typedef std::size_t size_type; @@ -672,7 +626,7 @@ public: BOOST_ASSERT(0 != m_pimpl.get()); return m_pimpl->get_data(); } - boost::shared_ptr<re_detail::named_subexpressions<charT> > get_named_subs()const + boost::shared_ptr<re_detail::named_subexpressions > get_named_subs()const { return m_pimpl; } diff --git a/3rdParty/Boost/src/boost/regex/v4/basic_regex_creator.hpp b/3rdParty/Boost/src/boost/regex/v4/basic_regex_creator.hpp index 883ecf1..efa9f7d 100644 --- a/3rdParty/Boost/src/boost/regex/v4/basic_regex_creator.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/basic_regex_creator.hpp @@ -769,14 +769,14 @@ void basic_regex_creator<charT, traits>::fixup_recursions(re_syntax_base* state) case syntax_element_assert_backref: { // just check that the index is valid: - int idVar = static_cast<const re_brace*>(state)->index; - if(idVar < 0) + int idx = static_cast<const re_brace*>(state)->index; + if(idx < 0) { - idVar = -idVar-1; - if(idVar >= 10000) + idx = -idx-1; + if(idx >= 10000) { - idVar = m_pdata->get_id(idVar); - if(idVar <= 0) + idx = m_pdata->get_id(idx); + if(idx <= 0) { // check of sub-expression that doesn't exist: if(0 == this->m_pdata->m_status) // update the error code if not already set @@ -804,12 +804,18 @@ void basic_regex_creator<charT, traits>::fixup_recursions(re_syntax_base* state) { bool ok = false; re_syntax_base* p = base; - int idVar = static_cast<re_jump*>(state)->alt.i; - if(idVar > 10000) - idVar = m_pdata->get_id(idVar); + std::ptrdiff_t idx = static_cast<re_jump*>(state)->alt.i; + if(idx > 10000) + { + // + // There may be more than one capture group with this hash, just do what Perl + // does and recurse to the leftmost: + // + idx = m_pdata->get_id(static_cast<int>(idx)); + } while(p) { - if((p->type == syntax_element_startmark) && (static_cast<re_brace*>(p)->index == idVar)) + if((p->type == syntax_element_startmark) && (static_cast<re_brace*>(p)->index == idx)) { // // We've found the target of the recursion, set the jump target: @@ -833,7 +839,7 @@ void basic_regex_creator<charT, traits>::fixup_recursions(re_syntax_base* state) next_rep_id = static_cast<re_repeat*>(p)->state_id; break; case syntax_element_endmark: - if(static_cast<const re_brace*>(p)->index == idVar) + if(static_cast<const re_brace*>(p)->index == idx) next_rep_id = -1; break; default: @@ -1039,6 +1045,14 @@ int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state case syntax_element_jump: state = static_cast<re_jump*>(state)->alt.p; continue; + case syntax_element_alt: + { + int r1 = calculate_backstep(state->next.p); + int r2 = calculate_backstep(static_cast<re_alt*>(state)->alt.p); + if((r1 < 0) || (r1 != r2)) + return -1; + return result + r1; + } default: break; } @@ -1543,3 +1557,4 @@ void basic_regex_creator<charT, traits>::probe_leading_repeat(re_syntax_base* st #endif #endif + diff --git a/3rdParty/Boost/src/boost/regex/v4/basic_regex_parser.hpp b/3rdParty/Boost/src/boost/regex/v4/basic_regex_parser.hpp index 3ea4d64..4dacfc6 100644 --- a/3rdParty/Boost/src/boost/regex/v4/basic_regex_parser.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/basic_regex_parser.hpp @@ -820,7 +820,11 @@ escape_type_class_jump: return false; } // maybe have \g{ddd} - if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace) + regex_constants::syntax_type syn = this->m_traits.syntax_type(*m_position); + regex_constants::syntax_type syn_end = 0; + if((syn == regex_constants::syntax_open_brace) + || (syn == regex_constants::escape_type_left_word) + || (syn == regex_constants::escape_type_end_buffer)) { if(++m_position == m_end) { @@ -828,6 +832,18 @@ escape_type_class_jump: return false; } have_brace = true; + switch(syn) + { + case regex_constants::syntax_open_brace: + syn_end = regex_constants::syntax_close_brace; + break; + case regex_constants::escape_type_left_word: + syn_end = regex_constants::escape_type_right_word; + break; + default: + syn_end = regex_constants::escape_type_end_buffer; + break; + } } negative = (*m_position == static_cast<charT>('-')); if((negative) && (++m_position == m_end)) @@ -837,18 +853,20 @@ escape_type_class_jump: } const charT* pc = m_position; int i = this->m_traits.toi(pc, m_end, 10); - if(i < 0) + if((i < 0) && syn_end) { - // Check for a named capture: + // Check for a named capture, get the leftmost one if there is more than one: const charT* base = m_position; - while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace)) + while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != syn_end)) + { ++m_position; - i = this->m_pdata->get_id(base, m_position); + } + i = hash_value_from_capture_name(base, m_position); pc = m_position; } if(negative) i = 1 + m_mark_count - i; - if((i > 0) && (this->m_backrefs & (1u << (i-1)))) + if(((i > 0) && (this->m_backrefs & (1u << (i-1)))) || ((i > 10000) && (this->m_pdata->get_id(i) > 0) && (this->m_backrefs & (1u << (this->m_pdata->get_id(i)-1))))) { m_position = pc; re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace))); @@ -863,7 +881,7 @@ escape_type_class_jump: m_position = pc; if(have_brace) { - if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace)) + if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != syn_end)) { fail(regex_constants::error_escape, m_position - m_base, incomplete_message); return false; @@ -1003,6 +1021,21 @@ bool basic_regex_parser<charT, traits>::parse_repeat(std::size_t low, std::size_ // if(pocessive) { + if(m_position != m_end) + { + // + // Check for illegal following quantifier, we have to do this here, because + // the extra states we insert below circumvents are usual error checking :-( + // + switch(this->m_traits.syntax_type(*m_position)) + { + case regex_constants::syntax_star: + case regex_constants::syntax_plus: + case regex_constants::syntax_question: + fail(regex_constants::error_badrepeat, m_position - m_base); + return false; + } + } re_brace* pb = static_cast<re_brace*>(this->insert_state(insert_point, syntax_element_startmark, sizeof(re_brace))); pb->index = -3; pb->icase = this->flags() & regbase::icase; @@ -1906,7 +1939,9 @@ bool basic_regex_parser<charT, traits>::parse_perl_extension() m_has_case_change = false; charT name_delim; int mark_reset = m_mark_reset; + int max_mark = m_max_mark; m_mark_reset = -1; + m_max_mark = m_mark_count; int v; // // select the actual extension used: @@ -2536,6 +2571,7 @@ option_group_jump: m_mark_count = m_max_mark; } m_mark_reset = mark_reset; + m_max_mark = max_mark; if(markid > 0) diff --git a/3rdParty/Boost/src/boost/regex/v4/cpp_regex_traits.hpp b/3rdParty/Boost/src/boost/regex/v4/cpp_regex_traits.hpp index bb40aa1..cd22bd8 100644 --- a/3rdParty/Boost/src/boost/regex/v4/cpp_regex_traits.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/cpp_regex_traits.hpp @@ -56,7 +56,7 @@ #ifdef BOOST_MSVC #pragma warning(push) -#pragma warning(disable:4786) +#pragma warning(disable:4786 4251) #endif namespace boost{ @@ -827,20 +827,20 @@ template <class charT> bool cpp_regex_traits_implementation<charT>::isctype(const charT c, char_class_type mask) const { return - ((mask & ::boost::re_detail::char_class_space) && (m_pctype->is(std::ctype<charT>::space, c))) - || ((mask & ::boost::re_detail::char_class_print) && (m_pctype->is(std::ctype<charT>::print, c))) - || ((mask & ::boost::re_detail::char_class_cntrl) && (m_pctype->is(std::ctype<charT>::cntrl, c))) - || ((mask & ::boost::re_detail::char_class_upper) && (m_pctype->is(std::ctype<charT>::upper, c))) - || ((mask & ::boost::re_detail::char_class_lower) && (m_pctype->is(std::ctype<charT>::lower, c))) - || ((mask & ::boost::re_detail::char_class_alpha) && (m_pctype->is(std::ctype<charT>::alpha, c))) - || ((mask & ::boost::re_detail::char_class_digit) && (m_pctype->is(std::ctype<charT>::digit, c))) - || ((mask & ::boost::re_detail::char_class_punct) && (m_pctype->is(std::ctype<charT>::punct, c))) - || ((mask & ::boost::re_detail::char_class_xdigit) && (m_pctype->is(std::ctype<charT>::xdigit, c))) - || ((mask & ::boost::re_detail::char_class_blank) && (m_pctype->is(std::ctype<charT>::space, c)) && !::boost::re_detail::is_separator(c)) + ((mask & ::boost::re_detail::char_class_space) && (this->m_pctype->is(std::ctype<charT>::space, c))) + || ((mask & ::boost::re_detail::char_class_print) && (this->m_pctype->is(std::ctype<charT>::print, c))) + || ((mask & ::boost::re_detail::char_class_cntrl) && (this->m_pctype->is(std::ctype<charT>::cntrl, c))) + || ((mask & ::boost::re_detail::char_class_upper) && (this->m_pctype->is(std::ctype<charT>::upper, c))) + || ((mask & ::boost::re_detail::char_class_lower) && (this->m_pctype->is(std::ctype<charT>::lower, c))) + || ((mask & ::boost::re_detail::char_class_alpha) && (this->m_pctype->is(std::ctype<charT>::alpha, c))) + || ((mask & ::boost::re_detail::char_class_digit) && (this->m_pctype->is(std::ctype<charT>::digit, c))) + || ((mask & ::boost::re_detail::char_class_punct) && (this->m_pctype->is(std::ctype<charT>::punct, c))) + || ((mask & ::boost::re_detail::char_class_xdigit) && (this->m_pctype->is(std::ctype<charT>::xdigit, c))) + || ((mask & ::boost::re_detail::char_class_blank) && (this->m_pctype->is(std::ctype<charT>::space, c)) && !::boost::re_detail::is_separator(c)) || ((mask & ::boost::re_detail::char_class_word) && (c == '_')) || ((mask & ::boost::re_detail::char_class_unicode) && ::boost::re_detail::is_extended(c)) || ((mask & ::boost::re_detail::char_class_vertical_space) && (is_separator(c) || (c == '\v'))) - || ((mask & ::boost::re_detail::char_class_horizontal_space) && m_pctype->is(std::ctype<charT>::space, c) && !(is_separator(c) || (c == '\v'))); + || ((mask & ::boost::re_detail::char_class_horizontal_space) && this->m_pctype->is(std::ctype<charT>::space, c) && !(is_separator(c) || (c == '\v'))); } #endif diff --git a/3rdParty/Boost/src/boost/regex/v4/instances.hpp b/3rdParty/Boost/src/boost/regex/v4/instances.hpp index d12dc6b..c62d136 100644 --- a/3rdParty/Boost/src/boost/regex/v4/instances.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/instances.hpp @@ -118,10 +118,14 @@ template class BOOST_REGEX_TEMPLATE_DECL ::boost::re_detail::perl_matcher< std:: #undef BOOST_REGEX_TEMPLATE_DECL -#elif (defined(__GNUC__) && (__GNUC__ >= 3)) +#elif (defined(__GNUC__) && (__GNUC__ >= 3)) || !defined(BOOST_NO_EXTERN_TEMPLATE) # ifndef BOOST_REGEX_INSTANTIATE -# define template __extension__ extern template +# ifdef __GNUC__ +# define template __extension__ extern template +# else +# define template extern template +# endif # endif #if !defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_REGEX_ICU_INSTANCES) diff --git a/3rdParty/Boost/src/boost/regex/v4/match_results.hpp b/3rdParty/Boost/src/boost/regex/v4/match_results.hpp index cd6b9eb..ca9898f 100644 --- a/3rdParty/Boost/src/boost/regex/v4/match_results.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/match_results.hpp @@ -38,7 +38,6 @@ namespace boost{ namespace re_detail{ -template <class charT> class named_subexpressions; } @@ -69,7 +68,7 @@ public: typedef typename re_detail::regex_iterator_traits< BidiIterator>::value_type char_type; typedef std::basic_string<char_type> string_type; - typedef re_detail::named_subexpressions_base<char_type> named_sub_type; + typedef re_detail::named_subexpressions named_sub_type; // construct/copy/destroy: explicit match_results(const Allocator& a = Allocator()) @@ -225,10 +224,15 @@ public: // const_reference named_subexpression(const char_type* i, const char_type* j) const { + // + // Scan for the leftmost *matched* subexpression with the specified named: + // if(m_is_singular) raise_logic_error(); - int index = m_named_subs->get_id(i, j); - return index > 0 ? (*this)[index] : m_null; + re_detail::named_subexpressions::range_type r = m_named_subs->equal_range(i, j); + while((r.first != r.second) && ((*this)[r.first->index].matched == false)) + ++r.first; + return r.first != r.second ? (*this)[r.first->index] : m_null; } template <class charT> const_reference named_subexpression(const charT* i, const charT* j) const @@ -243,10 +247,20 @@ public: } int named_subexpression_index(const char_type* i, const char_type* j) const { + // + // Scan for the leftmost *matched* subexpression with the specified named. + // If none found then return the leftmost expression with that name, + // otherwise an invalid index: + // if(m_is_singular) raise_logic_error(); - int index = m_named_subs->get_id(i, j); - return index > 0 ? index : -20; + re_detail::named_subexpressions::range_type s, r; + s = r = m_named_subs->equal_range(i, j); + while((r.first != r.second) && ((*this)[r.first->index].matched == false)) + ++r.first; + if(r.first == r.second) + r = s; + return r.first != r.second ? r.first->index : -20; } template <class charT> int named_subexpression_index(const charT* i, const charT* j) const @@ -393,7 +407,6 @@ public: std::swap(m_subs, that.m_subs); std::swap(m_named_subs, that.m_named_subs); std::swap(m_last_closed_paren, that.m_last_closed_paren); - std::swap(m_is_singular, that.m_is_singular); if(m_is_singular) { if(!that.m_is_singular) @@ -412,6 +425,7 @@ public: std::swap(m_base, that.m_base); std::swap(m_null, that.m_null); } + std::swap(m_is_singular, that.m_is_singular); } bool operator==(const match_results& that)const { @@ -457,7 +471,7 @@ public: void BOOST_REGEX_CALL set_second(BidiIterator i, size_type pos, bool m = true, bool escape_k = false) { if(pos) - m_last_closed_paren = pos; + m_last_closed_paren = static_cast<int>(pos); pos += 2; BOOST_ASSERT(m_subs.size() > pos); m_subs[pos].second = i; diff --git a/3rdParty/Boost/src/boost/regex/v4/perl_matcher.hpp b/3rdParty/Boost/src/boost/regex/v4/perl_matcher.hpp index 52e0bce..52cc55c 100644 --- a/3rdParty/Boost/src/boost/regex/v4/perl_matcher.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/perl_matcher.hpp @@ -336,7 +336,7 @@ struct recursion_info { typedef typename Results::value_type value_type; typedef typename value_type::iterator iterator; - int id; + int idx; const re_syntax_base* preturn_address; Results results; repeater_count<iterator>* repeater_stack; @@ -366,7 +366,7 @@ public: BidiIterator l_base) : m_result(what), base(first), last(end), position(first), backstop(l_base), re(e), traits_inst(e.get_traits()), - m_independent(false), next_count(&rep_obj), rep_obj(&next_count), recursion_stack_position(0) + m_independent(false), next_count(&rep_obj), rep_obj(&next_count) { construct_init(e, f); } @@ -468,9 +468,9 @@ private: // matching flags in use: match_flag_type m_match_flags; // how many states we have examined so far: - boost::uintmax_t state_count; + std::ptrdiff_t state_count; // max number of states to examine before giving up: - boost::uintmax_t max_state_count; + std::ptrdiff_t max_state_count; // whether we should ignore case or not: bool icase; // set to true when (position == last), indicates that we may have a partial match: @@ -488,8 +488,7 @@ private: // the bitmask to use when determining whether a match_any matches a newline or not: unsigned char match_any_mask; // recursion information: - recursion_info<results_type> recursion_stack[50]; - unsigned recursion_stack_position; + std::vector<recursion_info<results_type> > recursion_stack; #ifdef BOOST_REGEX_NON_RECURSIVE // @@ -523,7 +522,7 @@ private: void push_repeater_count(int i, repeater_count<BidiIterator>** s); void push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id); void push_non_greedy_repeat(const re_syntax_base* ps); - void push_recursion(int id, const re_syntax_base* p, results_type* presults); + void push_recursion(int idx, const re_syntax_base* p, results_type* presults); void push_recursion_pop(); // pointer to base of stack: diff --git a/3rdParty/Boost/src/boost/regex/v4/perl_matcher_common.hpp b/3rdParty/Boost/src/boost/regex/v4/perl_matcher_common.hpp index 5da53c5..b8c4e96 100644 --- a/3rdParty/Boost/src/boost/regex/v4/perl_matcher_common.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/perl_matcher_common.hpp @@ -98,23 +98,23 @@ void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std // // Calculate NS^2 first: // - static const boost::uintmax_t k = 100000; - boost::uintmax_t dist = boost::re_detail::distance(base, last); + static const std::ptrdiff_t k = 100000; + std::ptrdiff_t dist = boost::re_detail::distance(base, last); if(dist == 0) dist = 1; - boost::uintmax_t states = re.size(); + std::ptrdiff_t states = re.size(); if(states == 0) states = 1; states *= states; - if((std::numeric_limits<boost::uintmax_t>::max)() / dist < states) + if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states) { - max_state_count = (std::numeric_limits<boost::uintmax_t>::max)() - 2; + max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2); return; } states *= dist; - if((std::numeric_limits<boost::uintmax_t>::max)() - k < states) + if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states) { - max_state_count = (std::numeric_limits<boost::uintmax_t>::max)() - 2; + max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2); return; } states += k; @@ -125,15 +125,15 @@ void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std // Now calculate N^2: // states = dist; - if((std::numeric_limits<boost::uintmax_t>::max)() / dist < states) + if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states) { - max_state_count = (std::numeric_limits<boost::uintmax_t>::max)() - 2; + max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2); return; } states *= dist; - if((std::numeric_limits<boost::uintmax_t>::max)() - k < states) + if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states) { - max_state_count = (std::numeric_limits<boost::uintmax_t>::max)() - 2; + max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2); return; } states += k; @@ -200,7 +200,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_imp() m_match_flags |= regex_constants::match_all; m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), search_base, last); m_presult->set_base(base); - m_presult->set_named_subs(re_detail::convert_to_named_subs<typename match_results<BidiIterator>::char_type>(this->re.get_named_subs())); + m_presult->set_named_subs(this->re.get_named_subs()); if(m_match_flags & match_posix) m_result = *m_presult; verify_options(re.flags(), m_match_flags); @@ -262,7 +262,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::find_imp() pstate = re.get_first_state(); m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), base, last); m_presult->set_base(base); - m_presult->set_named_subs(re_detail::convert_to_named_subs<typename match_results<BidiIterator>::char_type>(this->re.get_named_subs())); + m_presult->set_named_subs(this->re.get_named_subs()); m_match_flags |= regex_constants::match_init; } else @@ -588,8 +588,23 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_backref() // in the match, this is in line with ECMAScript, but not Perl // or PCRE. // - BidiIterator i = (*m_presult)[static_cast<const re_brace*>(pstate)->index].first; - BidiIterator j = (*m_presult)[static_cast<const re_brace*>(pstate)->index].second; + int index = static_cast<const re_brace*>(pstate)->index; + if(index >= 10000) + { + named_subexpressions::range_type r = re.get_data().equal_range(index); + BOOST_ASSERT(r.first != r.second); + do + { + index = r.first->index; + ++r.first; + }while((r.first != r.second) && ((*m_presult)[index].matched != true)); + } + + if((m_match_flags & match_perl) && !(*m_presult)[index].matched) + return false; + + BidiIterator i = (*m_presult)[index].first; + BidiIterator j = (*m_presult)[index].second; while(i != j) { if((position == last) || (traits_inst.translate(*position, icase) != traits_inst.translate(*i, icase))) @@ -713,7 +728,7 @@ inline bool perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref( { // return true if marked sub-expression N has been matched: int index = static_cast<const re_brace*>(pstate)->index; - bool result; + bool result = false; if(index == 9999) { // Magic value for a (DEFINE) block: @@ -721,21 +736,47 @@ inline bool perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref( } else if(index > 0) { + // Have we matched subexpression "index"? // Check if index is a hash value: if(index >= 10000) - index = re.get_data().get_id(index); - // Have we matched subexpression "index"? - result = (*m_presult)[index].matched; + { + named_subexpressions::range_type r = re.get_data().equal_range(index); + while(r.first != r.second) + { + if((*m_presult)[r.first->index].matched) + { + result = true; + break; + } + ++r.first; + } + } + else + { + result = (*m_presult)[index].matched; + } pstate = pstate->next.p; } else { // Have we recursed into subexpression "index"? // If index == 0 then check for any recursion at all, otherwise for recursion to -index-1. - int idVar = -index-1; - if(idVar >= 10000) - idVar = re.get_data().get_id(idVar); - result = recursion_stack_position && ((recursion_stack[recursion_stack_position-1].id == idVar) || (index == 0)); + int idx = -index-1; + if(idx >= 10000) + { + named_subexpressions::range_type r = re.get_data().equal_range(idx); + int stack_index = recursion_stack.empty() ? -1 : recursion_stack.back().idx; + while(r.first != r.second) + { + result |= (stack_index == r.first->index); + if(result)break; + ++r.first; + } + } + else + { + result = !recursion_stack.empty() && ((recursion_stack.back().idx == idx) || (index == 0)); + } pstate = pstate->next.p; } return result; diff --git a/3rdParty/Boost/src/boost/regex/v4/perl_matcher_non_recursive.hpp b/3rdParty/Boost/src/boost/regex/v4/perl_matcher_non_recursive.hpp index 0fcd454..7ab6781 100644 --- a/3rdParty/Boost/src/boost/regex/v4/perl_matcher_non_recursive.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/perl_matcher_non_recursive.hpp @@ -130,8 +130,8 @@ struct saved_single_repeat : public saved_state template <class Results> struct saved_recursion : public saved_state { - saved_recursion(int id, const re_syntax_base* p, Results* pr) - : saved_state(14), recursion_id(id), preturn_address(p), results(*pr) + saved_recursion(int idx, const re_syntax_base* p, Results* pr) + : saved_state(14), recursion_id(idx), preturn_address(p), results(*pr) {} int recursion_id; const re_syntax_base* preturn_address; @@ -329,7 +329,7 @@ inline void perl_matcher<BidiIterator, Allocator, traits>::push_single_repeat(st } template <class BidiIterator, class Allocator, class traits> -inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int id, const re_syntax_base* p, results_type* presults) +inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int idx, const re_syntax_base* p, results_type* presults) { saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state); --pmp; @@ -339,7 +339,7 @@ inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int id pmp = static_cast<saved_recursion<results_type>*>(m_backup_state); --pmp; } - (void) new (pmp)saved_recursion<results_type>(id, p, presults); + (void) new (pmp)saved_recursion<results_type>(idx, p, presults); m_backup_state = pmp; } @@ -898,20 +898,19 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion() // // Set new call stack: // - if(recursion_stack_position >= static_cast<int>(sizeof(recursion_stack)/sizeof(recursion_stack[0]))) + if(recursion_stack.capacity() == 0) { - return false; + recursion_stack.reserve(50); } - recursion_stack[recursion_stack_position].preturn_address = pstate->next.p; - recursion_stack[recursion_stack_position].results = *m_presult; + recursion_stack.push_back(recursion_info<results_type>()); + recursion_stack.back().preturn_address = pstate->next.p; + recursion_stack.back().results = *m_presult; if(static_cast<const re_recurse*>(pstate)->state_id > 0) { push_repeater_count(static_cast<const re_recurse*>(pstate)->state_id, &next_count); } pstate = static_cast<const re_jump*>(pstate)->alt.p; - recursion_stack[recursion_stack_position].id = static_cast<const re_brace*>(pstate)->index; - ++recursion_stack_position; - //BOOST_ASSERT(recursion_stack[recursion_stack_position-1].id); + recursion_stack.back().idx = static_cast<const re_brace*>(pstate)->index; return true; } @@ -927,14 +926,14 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark() { m_presult->set_second(position, index); } - if(recursion_stack_position) + if(!recursion_stack.empty()) { - if(index == recursion_stack[recursion_stack_position-1].id) + if(index == recursion_stack.back().idx) { - --recursion_stack_position; - pstate = recursion_stack[recursion_stack_position].preturn_address; - *m_presult = recursion_stack[recursion_stack_position].results; - push_recursion(recursion_stack[recursion_stack_position].id, recursion_stack[recursion_stack_position].preturn_address, &recursion_stack[recursion_stack_position].results); + pstate = recursion_stack.back().preturn_address; + *m_presult = recursion_stack.back().results; + push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, &recursion_stack.back().results); + recursion_stack.pop_back(); } } } @@ -951,13 +950,13 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark() template <class BidiIterator, class Allocator, class traits> bool perl_matcher<BidiIterator, Allocator, traits>::match_match() { - if(recursion_stack_position) + if(!recursion_stack.empty()) { - BOOST_ASSERT(0 == recursion_stack[recursion_stack_position-1].id); - --recursion_stack_position; - pstate = recursion_stack[recursion_stack_position].preturn_address; - *m_presult = recursion_stack[recursion_stack_position].results; - push_recursion(recursion_stack[recursion_stack_position].id, recursion_stack[recursion_stack_position].preturn_address, &recursion_stack[recursion_stack_position].results); + BOOST_ASSERT(0 == recursion_stack.back().idx); + pstate = recursion_stack.back().preturn_address; + *m_presult = recursion_stack.back().results; + push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, &recursion_stack.back().results); + recursion_stack.pop_back(); return true; } if((m_match_flags & match_not_null) && (position == (*m_presult)[0].first)) @@ -1523,10 +1522,10 @@ bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion(bool r) saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state); if(!r) { - recursion_stack[recursion_stack_position].id = pmp->recursion_id; - recursion_stack[recursion_stack_position].preturn_address = pmp->preturn_address; - recursion_stack[recursion_stack_position].results = pmp->results; - ++recursion_stack_position; + recursion_stack.push_back(recursion_info<results_type>()); + recursion_stack.back().idx = pmp->recursion_id; + recursion_stack.back().preturn_address = pmp->preturn_address; + recursion_stack.back().results = pmp->results; } boost::re_detail::inplace_destroy(pmp++); m_backup_state = pmp; @@ -1539,7 +1538,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop(bool r) saved_state* pmp = static_cast<saved_state*>(m_backup_state); if(!r) { - --recursion_stack_position; + recursion_stack.pop_back(); } boost::re_detail::inplace_destroy(pmp++); m_backup_state = pmp; diff --git a/3rdParty/Boost/src/boost/regex/v4/perl_matcher_recursive.hpp b/3rdParty/Boost/src/boost/regex/v4/perl_matcher_recursive.hpp index d0de802..07a1c20 100644 --- a/3rdParty/Boost/src/boost/regex/v4/perl_matcher_recursive.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/perl_matcher_recursive.hpp @@ -200,11 +200,11 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark() BidiIterator saved_position = position; const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p; pstate = pstate->next.p->next.p; - bool r = match_all_states(); + bool res = match_all_states(); position = saved_position; if(negated) - r = !r; - if(r) + res = !res; + if(res) pstate = next_pstate; else pstate = alt->alt.p; @@ -857,16 +857,16 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion() // // Set new call stack: // - if(recursion_stack_position >= static_cast<int>(sizeof(recursion_stack)/sizeof(recursion_stack[0]))) + if(recursion_stack.capacity() == 0) { - return false; + recursion_stack.reserve(50); } - recursion_stack[recursion_stack_position].preturn_address = pstate->next.p; - recursion_stack[recursion_stack_position].results = *m_presult; - recursion_stack[recursion_stack_position].repeater_stack = next_count; + recursion_stack.push_back(recursion_info<results_type>()); + recursion_stack.back().preturn_address = pstate->next.p; + recursion_stack.back().results = *m_presult; + recursion_stack.back().repeater_stack = next_count; pstate = static_cast<const re_jump*>(pstate)->alt.p; - recursion_stack[recursion_stack_position].id = static_cast<const re_brace*>(pstate)->index; - ++recursion_stack_position; + recursion_stack.back().idx = static_cast<const re_brace*>(pstate)->index; repeater_count<BidiIterator>* saved = next_count; repeater_count<BidiIterator> r(&next_count); // resets all repeat counts since we're recursing and starting fresh on those @@ -876,9 +876,9 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion() if(!result) { - --recursion_stack_position; - next_count = recursion_stack[recursion_stack_position].repeater_stack; - *m_presult = recursion_stack[recursion_stack_position].results; + next_count = recursion_stack.back().repeater_stack; + *m_presult = recursion_stack.back().results; + recursion_stack.pop_back(); return false; } return true; @@ -895,20 +895,19 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark() { m_presult->set_second(position, index); } - if(recursion_stack_position) + if(!recursion_stack.empty()) { - if(index == recursion_stack[recursion_stack_position-1].id) + if(index == recursion_stack.back().idx) { - --recursion_stack_position; - recursion_info<results_type> saved = recursion_stack[recursion_stack_position]; - const re_syntax_base* saved_state = pstate = saved.preturn_address; + recursion_info<results_type> saved = recursion_stack.back(); + recursion_stack.pop_back(); + pstate = saved.preturn_address; repeater_count<BidiIterator>* saved_count = next_count; next_count = saved.repeater_stack; *m_presult = saved.results; if(!match_all_states()) { - recursion_stack[recursion_stack_position] = saved; - ++recursion_stack_position; + recursion_stack.push_back(saved); next_count = saved_count; return false; } @@ -928,17 +927,17 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark() template <class BidiIterator, class Allocator, class traits> bool perl_matcher<BidiIterator, Allocator, traits>::match_match() { - if(recursion_stack_position) + if(!recursion_stack.empty()) { - BOOST_ASSERT(0 == recursion_stack[recursion_stack_position-1].id); - --recursion_stack_position; - const re_syntax_base* saved_state = pstate = recursion_stack[recursion_stack_position].preturn_address; - *m_presult = recursion_stack[recursion_stack_position].results; + BOOST_ASSERT(0 == recursion_stack.back().idx); + const re_syntax_base* saved_state = pstate = recursion_stack.back().preturn_address; + *m_presult = recursion_stack.back().results; + recursion_stack.pop_back(); if(!match_all_states()) { - recursion_stack[recursion_stack_position].preturn_address = saved_state; - recursion_stack[recursion_stack_position].results = *m_presult; - ++recursion_stack_position; + recursion_stack.push_back(recursion_info<results_type>()); + recursion_stack.back().preturn_address = saved_state; + recursion_stack.back().results = *m_presult; return false; } return true; diff --git a/3rdParty/Boost/src/boost/regex/v4/regex_format.hpp b/3rdParty/Boost/src/boost/regex/v4/regex_format.hpp index 0ca9baa..4406839 100644 --- a/3rdParty/Boost/src/boost/regex/v4/regex_format.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/regex_format.hpp @@ -34,6 +34,7 @@ #ifndef BOOST_NO_SFINAE #include <boost/mpl/has_xxx.hpp> #endif +#include <boost/ref.hpp> namespace boost{ @@ -152,6 +153,11 @@ private: typedef typename boost::is_convertible<ForwardIter, const char_type*>::type tag_type; return get_named_sub_index(i, j, tag_type()); } +#ifdef BOOST_MSVC + // msvc-8.0 issues a spurious warning on the call to std::advance here: +#pragma warning(push) +#pragma warning(disable:4244) +#endif inline int toi(ForwardIter& i, ForwardIter j, int base, const boost::mpl::false_&) { if(i != j) @@ -165,6 +171,9 @@ private: } return -1; } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif inline int toi(ForwardIter& i, ForwardIter j, int base, const boost::mpl::true_&) { return m_traits.toi(i, j, base); @@ -334,7 +343,7 @@ void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format m_position = --base; } } - put((this->m_results)[this->m_results.size() > 1 ? this->m_results.size() - 1 : 1]); + put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]); break; case '{': have_brace = true; @@ -384,7 +393,7 @@ bool basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::handle if(have_brace && (*m_position == '^')) ++m_position; - int max_len = m_end - m_position; + std::ptrdiff_t max_len = m_end - m_position; if((max_len >= 5) && std::equal(m_position, m_position + 5, MATCH)) { @@ -447,7 +456,7 @@ bool basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::handle return false; } } - put((this->m_results)[this->m_results.size() > 1 ? this->m_results.size() - 1 : 1]); + put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]); return true; } if((max_len >= 20) && std::equal(m_position, m_position + 20, LAST_SUBMATCH_RESULT)) @@ -895,7 +904,7 @@ private: // F must be a pointer, a function, or a class with a function call operator: // BOOST_STATIC_ASSERT((::boost::is_pointer<F>::value || ::boost::is_function<F>::value || ::boost::is_class<F>::value)); - static formatter_wrapper<F> f; + static formatter_wrapper<typename unwrap_reference<F>::type> f; static M m; static O out; static boost::regex_constants::match_flag_type flags; @@ -963,7 +972,7 @@ struct format_functor3 template <class OutputIter> OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f) { - return func(m, i, f); + return boost::unwrap_ref(func)(m, i, f); } template <class OutputIter, class Traits> OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&) @@ -983,7 +992,7 @@ struct format_functor2 template <class OutputIter> OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/) { - return func(m, i); + return boost::unwrap_ref(func)(m, i); } template <class OutputIter, class Traits> OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&) @@ -1020,7 +1029,7 @@ struct format_functor1 template <class OutputIter> OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/) { - return do_format_string(func(m), i); + return do_format_string(boost::unwrap_ref(func)(m), i); } template <class OutputIter, class Traits> OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&) diff --git a/3rdParty/Boost/src/boost/regex/v4/regex_workaround.hpp b/3rdParty/Boost/src/boost/regex/v4/regex_workaround.hpp index 06527f1..46a8a8d 100644 --- a/3rdParty/Boost/src/boost/regex/v4/regex_workaround.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/regex_workaround.hpp @@ -149,7 +149,37 @@ namespace boost{ namespace re_detail{ { return stdext::unchecked_equal(first, last, with); } - +#elif BOOST_WORKAROUND(BOOST_MSVC, > 1500) + // + // MSVC 10 will either emit warnings or else refuse to compile + // code that makes perfectly legitimate use of std::copy, when + // the OutputIterator type is a user-defined class (apparently all user + // defined iterators are "unsafe"). What's more Microsoft have removed their + // non-standard "unchecked" versions, even though their still in the MS + // documentation!! Work around this as best we can: + // + template<class InputIterator, class OutputIterator> + inline OutputIterator copy( + InputIterator first, + InputIterator last, + OutputIterator dest + ) + { + while(first != last) + *dest++ = *first++; + return dest; + } + template<class InputIterator1, class InputIterator2> + inline bool equal( + InputIterator1 first, + InputIterator1 last, + InputIterator2 with + ) + { + while(first != last) + if(*first++ != *with++) return false; + return true; + } #else using std::copy; using std::equal; diff --git a/3rdParty/Boost/src/boost/regex/v4/sub_match.hpp b/3rdParty/Boost/src/boost/regex/v4/sub_match.hpp index 1c79e39..34a8684 100644 --- a/3rdParty/Boost/src/boost/regex/v4/sub_match.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/sub_match.hpp @@ -56,7 +56,7 @@ struct sub_match : public std::pair<BidiIterator, BidiIterator> template <class T, class A> operator std::basic_string<value_type, T, A> ()const { - return std::basic_string<value_type, T, A>(this->first, this->second); + return matched ? std::basic_string<value_type, T, A>(this->first, this->second) : std::basic_string<value_type, T, A>(); } #else operator std::basic_string<value_type> ()const @@ -66,19 +66,22 @@ struct sub_match : public std::pair<BidiIterator, BidiIterator> #endif difference_type BOOST_REGEX_CALL length()const { - difference_type n = ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second); + difference_type n = matched ? ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second) : 0; return n; } std::basic_string<value_type> str()const { std::basic_string<value_type> result; - std::size_t len = ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second); - result.reserve(len); - BidiIterator i = this->first; - while(i != this->second) + if(matched) { - result.append(1, *i); - ++i; + std::size_t len = ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second); + result.reserve(len); + BidiIterator i = this->first; + while(i != this->second) + { + result.append(1, *i); + ++i; + } } return result; } diff --git a/3rdParty/Boost/src/boost/regex/v4/u32regex_token_iterator.hpp b/3rdParty/Boost/src/boost/regex/v4/u32regex_token_iterator.hpp index c47a219..4b0ac92 100644 --- a/3rdParty/Boost/src/boost/regex/v4/u32regex_token_iterator.hpp +++ b/3rdParty/Boost/src/boost/regex/v4/u32regex_token_iterator.hpp @@ -292,7 +292,7 @@ template <class charT, class Traits, class Alloc> inline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default) { typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type; - return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, m); + return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, submatch, m); } inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default) { @@ -361,7 +361,7 @@ inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m); } -#if BOOST_WORKAROUND(BOOST_MSVC, == 1310) +#if BOOST_WORKAROUND(BOOST_MSVC, > 1300) # pragma warning(pop) #endif #ifdef BOOST_HAS_ABI_HEADERS diff --git a/3rdParty/Boost/src/boost/smart_ptr/detail/sp_convertible.hpp b/3rdParty/Boost/src/boost/smart_ptr/detail/sp_convertible.hpp index fe44069..eb39797 100644 --- a/3rdParty/Boost/src/boost/smart_ptr/detail/sp_convertible.hpp +++ b/3rdParty/Boost/src/boost/smart_ptr/detail/sp_convertible.hpp @@ -45,7 +45,7 @@ template< class Y, class T > struct sp_convertible static yes f( T* ); static no f( ... ); - enum _vt { value = sizeof( f( static_cast<Y*>(0) ) ) == sizeof(yes) }; + enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) }; }; struct sp_empty diff --git a/3rdParty/Boost/src/boost/smart_ptr/detail/yield_k.hpp b/3rdParty/Boost/src/boost/smart_ptr/detail/yield_k.hpp index a956cc0..23eadd8 100644 --- a/3rdParty/Boost/src/boost/smart_ptr/detail/yield_k.hpp +++ b/3rdParty/Boost/src/boost/smart_ptr/detail/yield_k.hpp @@ -55,7 +55,7 @@ namespace detail { #if !defined( BOOST_USE_WINDOWS_H ) - extern "C" void __stdcall Sleep( unsigned ms ); + extern "C" void __stdcall Sleep( unsigned long ms ); #endif inline void yield( unsigned k ) diff --git a/3rdParty/Boost/src/boost/system/api_config.hpp b/3rdParty/Boost/src/boost/system/api_config.hpp new file mode 100644 index 0000000..28b8bec --- /dev/null +++ b/3rdParty/Boost/src/boost/system/api_config.hpp @@ -0,0 +1,42 @@ +// boost/system/api_config.hpp -------------------------------------------------------// + +// Copyright Beman Dawes 2003, 2006, 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/system for documentation. + +//--------------------------------------------------------------------------------------// + +// Boost.System calls operating system API functions to implement system error category +// functions. Usually there is no question as to which API is to be used. +// +// In the case of MinGW or Cygwin/MinGW, however, both POSIX and Windows API's are +// available. Chaos ensues if other code thinks one is in use when Boost.System was +// actually built with the other. This header centralizes the API choice and prevents +// user definition of API macros, thus elminating the possibility of mismatches and the +// need to test configurations with little or no practical value. +// + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_SYSTEM_API_CONFIG_HPP +#define BOOST_SYSTEM_API_CONFIG_HPP + +# if defined(BOOST_POSIX_API) || defined(BOOST_WINDOWS_API) +# error user defined BOOST_POSIX_API or BOOST_WINDOWS_API not supported +# endif + +// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use +// Cygwin/MinGW does not predefine _WIN32. +// Standalone MinGW and all other known Windows compilers do predefine _WIN32 +// Compilers that predefine _WIN32 or __MINGW32__ do so for Windows 64-bit builds too. + +# if defined(_WIN32) || defined(__CYGWIN__) // Windows default, including MinGW and Cygwin +# define BOOST_WINDOWS_API +# else +# define BOOST_POSIX_API +# endif + +#endif // BOOST_SYSTEM_API_CONFIG_HPP diff --git a/3rdParty/Boost/src/boost/system/config.hpp b/3rdParty/Boost/src/boost/system/config.hpp index fa09099..bf78051 100644 --- a/3rdParty/Boost/src/boost/system/config.hpp +++ b/3rdParty/Boost/src/boost/system/config.hpp @@ -1,4 +1,4 @@ -// boost/system/config.hpp -------------------------------------------------// +// boost/system/config.hpp -----------------------------------------------------------// // Copyright Beman Dawes 2003, 2006 @@ -11,47 +11,24 @@ #define BOOST_SYSTEM_CONFIG_HPP #include <boost/config.hpp> +#include <boost/system/api_config.hpp> // for BOOST_POSIX_API or BOOST_WINDOWS_API -// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use. -// If not specified, a sensible default will be applied. +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html -# if defined( BOOST_WINDOWS_API ) && defined( BOOST_POSIX_API ) -# error both BOOST_WINDOWS_API and BOOST_POSIX_API are defined -# elif !defined( BOOST_WINDOWS_API ) && !defined( BOOST_POSIX_API ) -# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) -# define BOOST_WINDOWS_API -# else -# define BOOST_POSIX_API -# endif -# endif - -// enable dynamic linking on Windows ---------------------------------------// - -//# if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK)) && defined(__BORLANDC__) && defined(__WIN32__) -//# error Dynamic linking Boost.System does not work for Borland; use static linking instead -//# endif +// enable dynamic or static linking as requested --------------------------------------// -#ifdef BOOST_HAS_DECLSPEC // defined in config system -// we need to import/export our code only if the user has specifically -// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost -// libraries to be dynamically linked, or BOOST_SYSTEM_DYN_LINK -// if they want just this one to be dynamically liked: #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK) -// export if this is our own source, otherwise import: -#ifdef BOOST_SYSTEM_SOURCE -# define BOOST_SYSTEM_DECL __declspec(dllexport) +# if defined(BOOST_SYSTEM_SOURCE) +# define BOOST_SYSTEM_DECL BOOST_SYMBOL_EXPORT +# else +# define BOOST_SYSTEM_DECL BOOST_SYMBOL_IMPORT +# endif #else -# define BOOST_SYSTEM_DECL __declspec(dllimport) -#endif // BOOST_SYSTEM_SOURCE -#endif // DYN_LINK -#endif // BOOST_HAS_DECLSPEC -// -// if BOOST_SYSTEM_DECL isn't defined yet define it now: -#ifndef BOOST_SYSTEM_DECL -#define BOOST_SYSTEM_DECL +# define BOOST_SYSTEM_DECL #endif -// enable automatic library variant selection ------------------------------// +// enable automatic library variant selection ----------------------------------------// #if !defined(BOOST_SYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SYSTEM_NO_LIB) // diff --git a/3rdParty/Boost/src/boost/system/error_code.hpp b/3rdParty/Boost/src/boost/system/error_code.hpp index d0eb6c5..b22775f 100644 --- a/3rdParty/Boost/src/boost/system/error_code.hpp +++ b/3rdParty/Boost/src/boost/system/error_code.hpp @@ -202,18 +202,18 @@ namespace boost // predefined error categories -----------------------------------------// - BOOST_SYSTEM_DECL const error_category & get_system_category(); - BOOST_SYSTEM_DECL const error_category & get_generic_category(); + BOOST_SYSTEM_DECL const error_category & system_category(); + BOOST_SYSTEM_DECL const error_category & generic_category(); + + // deprecated synonyms --------------------------------------------------// - static const error_category & system_category = get_system_category(); - static const error_category & generic_category = get_generic_category(); - # ifndef BOOST_SYSTEM_NO_DEPRECATED - // deprecated synonyms - inline const error_category & get_posix_category() { return get_generic_category(); } - static const error_category & posix_category = get_generic_category(); - static const error_category & errno_ecat = get_generic_category(); - static const error_category & native_ecat = get_system_category(); + inline const error_category & get_system_category() { return system_category(); } + inline const error_category & get_generic_category() { return generic_category(); } + inline const error_category & get_posix_category() { return generic_category(); } + static const error_category & posix_category = generic_category(); + static const error_category & errno_ecat = generic_category(); + static const error_category & native_ecat = system_category(); # endif // class error_condition -----------------------------------------------// @@ -225,7 +225,7 @@ namespace boost public: // constructors: - error_condition() : m_val(0), m_cat(&get_generic_category()) {} + error_condition() : m_val(0), m_cat(&generic_category()) {} error_condition( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {} template <class ErrorConditionEnum> @@ -254,7 +254,7 @@ namespace boost void clear() { m_val = 0; - m_cat = &get_generic_category(); + m_cat = &generic_category(); } // observers: @@ -312,7 +312,7 @@ namespace boost public: // constructors: - error_code() : m_val(0), m_cat(&get_system_category()) {} + error_code() : m_val(0), m_cat(&system_category()) {} error_code( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {} template <class ErrorCodeEnum> @@ -340,7 +340,7 @@ namespace boost void clear() { m_val = 0; - m_cat = &get_system_category(); + m_cat = &system_category(); } // observers: @@ -473,11 +473,11 @@ namespace boost { // explicit conversion: inline error_code make_error_code( errc_t e ) - { return error_code( e, get_generic_category() ); } + { return error_code( e, generic_category() ); } // implicit conversion: inline error_condition make_error_condition( errc_t e ) - { return error_condition( e, get_generic_category() ); } + { return error_condition( e, generic_category() ); } } // error_category default implementation -------------------------------// diff --git a/3rdParty/Boost/src/boost/system/system_error.hpp b/3rdParty/Boost/src/boost/system/system_error.hpp index 4091647..065d365 100644 --- a/3rdParty/Boost/src/boost/system/system_error.hpp +++ b/3rdParty/Boost/src/boost/system/system_error.hpp @@ -17,9 +17,11 @@ namespace boost { namespace system { - // class system_error --------------------------------------------------// + // class system_error ------------------------------------------------------------// - class system_error : public std::runtime_error + class BOOST_SYMBOL_VISIBLE system_error : public std::runtime_error + // BOOST_SYMBOL_VISIBLE is needed by GCC to ensure system_error thrown from a shared + // library can be caught. See svn.boost.org/trac/boost/ticket/3697 { public: system_error( error_code ec ) @@ -62,11 +64,8 @@ namespace boost try { m_what = this->std::runtime_error::what(); - if ( m_error_code ) - { - if ( !m_what.empty() ) m_what += ": "; - m_what += m_error_code.message(); - } + if ( !m_what.empty() ) m_what += ": "; + m_what += m_error_code.message(); } catch (...) { return std::runtime_error::what(); } } diff --git a/3rdParty/Boost/src/boost/thread/detail/config.hpp b/3rdParty/Boost/src/boost/thread/detail/config.hpp index 7661507..4015a6c 100644 --- a/3rdParty/Boost/src/boost/thread/detail/config.hpp +++ b/3rdParty/Boost/src/boost/thread/detail/config.hpp @@ -19,8 +19,14 @@ #include "platform.hpp" +// provided for backwards compatibility, since this +// macro was used for several releases by mistake. +#if defined(BOOST_THREAD_DYN_DLL) +# define BOOST_THREAD_DYN_LINK +#endif + // compatibility with the rest of Boost's auto-linking code: -#if defined(BOOST_THREAD_DYN_DLL) || defined(BOOST_ALL_DYN_LINK) +#if defined(BOOST_THREAD_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) # undef BOOST_THREAD_USE_LIB # define BOOST_THREAD_USE_DLL #endif diff --git a/3rdParty/Boost/src/boost/thread/detail/platform.hpp b/3rdParty/Boost/src/boost/thread/detail/platform.hpp index 4a37cf3..58601b0 100644 --- a/3rdParty/Boost/src/boost/thread/detail/platform.hpp +++ b/3rdParty/Boost/src/boost/thread/detail/platform.hpp @@ -29,7 +29,7 @@ # define BOOST_THREAD_HPUX #elif defined(__CYGWIN__) # define BOOST_THREAD_CYGWIN -#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +#elif (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(BOOST_DISABLE_WIN32) # define BOOST_THREAD_WIN32 #elif defined(__BEOS__) # define BOOST_THREAD_BEOS diff --git a/3rdParty/Boost/src/boost/thread/detail/thread.hpp b/3rdParty/Boost/src/boost/thread/detail/thread.hpp index 9615a39..005555e 100644 --- a/3rdParty/Boost/src/boost/thread/detail/thread.hpp +++ b/3rdParty/Boost/src/boost/thread/detail/thread.hpp @@ -3,10 +3,12 @@ // 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) -// (C) Copyright 2007-8 Anthony Williams +// (C) Copyright 2007-10 Anthony Williams #include <boost/thread/exceptions.hpp> +#ifndef BOOST_NO_IOSTREAM #include <ostream> +#endif #include <boost/thread/detail/move.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/xtime.hpp> @@ -113,14 +115,13 @@ namespace boost void release_handle(); - mutable boost::mutex thread_info_mutex; detail::thread_data_ptr thread_info; void start_thread(); explicit thread(detail::thread_data_ptr data); - detail::thread_data_ptr get_thread_info() const; + detail::thread_data_ptr get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const; #ifndef BOOST_NO_RVALUE_REFERENCES template<typename F> @@ -147,7 +148,7 @@ namespace boost #endif struct dummy; public: -#ifdef __SUNPRO_CC +#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) thread(const volatile thread&); #endif thread(); @@ -157,7 +158,7 @@ namespace boost #ifdef BOOST_MSVC template <class F> explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0): - thread_info(make_thread_info(f)) + thread_info(make_thread_info(static_cast<F&&>(f))) { start_thread(); } @@ -217,7 +218,7 @@ namespace boost x->thread_info.reset(); } -#ifdef __SUNPRO_CC +#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) thread& operator=(thread x) { swap(x); @@ -394,7 +395,7 @@ namespace boost thread_data(thread_data_) {} friend class thread; - friend id this_thread::get_id(); + friend id BOOST_THREAD_DECL this_thread::get_id(); public: id(): thread_data() @@ -430,6 +431,8 @@ namespace boost return !(thread_data<y.thread_data); } +#ifndef BOOST_NO_IOSTREAM +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS template<class charT, class traits> friend std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const id& x) @@ -443,8 +446,34 @@ namespace boost return os<<"{Not-any-thread}"; } } +#else + template<class charT, class traits> + std::basic_ostream<charT, traits>& + print(std::basic_ostream<charT, traits>& os) const + { + if(thread_data) + { + return os<<thread_data; + } + else + { + return os<<"{Not-any-thread}"; + } + } + +#endif +#endif }; +#if !defined(BOOST_NO_IOSTREAM) && defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template<class charT, class traits> + std::basic_ostream<charT, traits>& + operator<<(std::basic_ostream<charT, traits>& os, const thread::id& x) + { + return x.print(os); + } +#endif + inline bool thread::operator==(const thread& other) const { return get_id()==other.get_id(); diff --git a/3rdParty/Boost/src/boost/thread/detail/thread_group.hpp b/3rdParty/Boost/src/boost/thread/detail/thread_group.hpp index 823b92e..f1ccdf8 100644 --- a/3rdParty/Boost/src/boost/thread/detail/thread_group.hpp +++ b/3rdParty/Boost/src/boost/thread/detail/thread_group.hpp @@ -18,10 +18,13 @@ namespace boost { - class thread_group: - private noncopyable + class thread_group { + private: + thread_group(thread_group const&); + thread_group& operator=(thread_group const&); public: + thread_group() {} ~thread_group() { for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); diff --git a/3rdParty/Boost/src/boost/thread/detail/tss_hooks.hpp b/3rdParty/Boost/src/boost/thread/detail/tss_hooks.hpp index c496844..b2ceece 100644 --- a/3rdParty/Boost/src/boost/thread/detail/tss_hooks.hpp +++ b/3rdParty/Boost/src/boost/thread/detail/tss_hooks.hpp @@ -12,27 +12,9 @@ #if defined(BOOST_HAS_WINTHREADS) - typedef void (__cdecl *thread_exit_handler)(void); - - extern "C" BOOST_THREAD_DECL int at_thread_exit( - thread_exit_handler exit_handler - ); - //Add a function to the list of functions that will - //be called when a thread is about to exit. - //Currently only implemented for Win32, but should - //later be implemented for all platforms. - //Used by Win32 implementation of Boost.Threads - //tss to perform cleanup. - //Like the C runtime library atexit() function, - //which it mimics, at_thread_exit() returns - //zero if successful and a nonzero - //value if an error occurs. - -#endif //defined(BOOST_HAS_WINTHREADS) - -#if defined(BOOST_HAS_WINTHREADS) - - extern "C" BOOST_THREAD_DECL void on_process_enter(void); +namespace boost +{ + BOOST_THREAD_DECL void __cdecl on_process_enter(void); //Function to be called when the exe or dll //that uses Boost.Threads first starts //or is first loaded. @@ -42,7 +24,7 @@ //a method for doing so has been discovered. //May be omitted; may be called multiple times. - extern "C" BOOST_THREAD_DECL void on_process_exit(void); + BOOST_THREAD_DECL void __cdecl on_process_exit(void); //Function to be called when the exe or dll //that uses Boost.Threads first starts //or is first loaded. @@ -52,7 +34,7 @@ //a method for doing so has been discovered. //Must not be omitted; may be called multiple times. - extern "C" BOOST_THREAD_DECL void on_thread_enter(void); + BOOST_THREAD_DECL void __cdecl on_thread_enter(void); //Function to be called just after a thread starts //in an exe or dll that uses Boost.Threads. //Must be called in the context of the thread @@ -61,7 +43,7 @@ //a method for doing so has been discovered. //May be omitted; may be called multiple times. - extern "C" BOOST_THREAD_DECL void __cdecl on_thread_exit(void); + BOOST_THREAD_DECL void __cdecl on_thread_exit(void); //Function to be called just be fore a thread ends //in an exe or dll that uses Boost.Threads. //Must be called in the context of the thread @@ -70,10 +52,11 @@ //a method for doing so has been discovered. //Must not be omitted; may be called multiple times. - extern "C" void tss_cleanup_implemented(void); + void tss_cleanup_implemented(); //Dummy function used both to detect whether tss cleanup //cleanup has been implemented and to force //it to be linked into the Boost.Threads library. +} #endif //defined(BOOST_HAS_WINTHREADS) diff --git a/3rdParty/Boost/src/boost/thread/future.hpp b/3rdParty/Boost/src/boost/thread/future.hpp index 8111d9e..a4b4343 100644 --- a/3rdParty/Boost/src/boost/thread/future.hpp +++ b/3rdParty/Boost/src/boost/thread/future.hpp @@ -9,6 +9,8 @@ #include <stdexcept> #include <boost/thread/detail/move.hpp> #include <boost/thread/thread_time.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/condition_variable.hpp> #include <boost/exception_ptr.hpp> #include <boost/shared_ptr.hpp> #include <boost/scoped_ptr.hpp> @@ -140,6 +142,8 @@ namespace boost { lock.lock(); } + private: + relocker& operator=(relocker const&); }; void do_callback(boost::unique_lock<boost::mutex>& lock) @@ -388,15 +392,18 @@ namespace boost class future_waiter { + struct registered_waiter; + typedef std::vector<registered_waiter>::size_type count_type; + struct registered_waiter { boost::shared_ptr<detail::future_object_base> future; detail::future_object_base::waiter_list::iterator wait_iterator; - unsigned index; + count_type index; registered_waiter(boost::shared_ptr<detail::future_object_base> const& future_, detail::future_object_base::waiter_list::iterator wait_iterator_, - unsigned index_): + count_type index_): future(future_),wait_iterator(wait_iterator_),index(index_) {} @@ -404,7 +411,6 @@ namespace boost struct all_futures_lock { - typedef std::vector<registered_waiter>::size_type count_type; count_type count; boost::scoped_array<boost::unique_lock<boost::mutex> > locks; @@ -424,7 +430,7 @@ namespace boost void unlock() { - for(unsigned i=0;i<count;++i) + for(count_type i=0;i<count;++i) { locks[i].unlock(); } @@ -433,7 +439,7 @@ namespace boost boost::condition_variable_any cv; std::vector<registered_waiter> futures; - unsigned future_count; + count_type future_count; public: future_waiter(): @@ -450,12 +456,12 @@ namespace boost ++future_count; } - unsigned wait() + count_type wait() { all_futures_lock lk(futures); for(;;) { - for(unsigned i=0;i<futures.size();++i) + for(count_type i=0;i<futures.size();++i) { if(futures[i].future->done) { @@ -468,7 +474,7 @@ namespace boost ~future_waiter() { - for(unsigned i=0;i<futures.size();++i) + for(count_type i=0;i<futures.size();++i) { futures[i].future->remove_external_waiter(futures[i].wait_iterator); } @@ -548,6 +554,9 @@ namespace boost template<typename Iterator> typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end) { + if(begin==end) + return end; + detail::future_waiter waiter; for(Iterator current=begin;current!=end;++current) { @@ -903,10 +912,10 @@ namespace boost void lazy_init() { - if(!future) + if(!atomic_load(&future)) { - future_obtained=false; - future.reset(new detail::future_object<R>); + future_ptr blank; + atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<R>)); } } @@ -936,12 +945,14 @@ namespace boost future_obtained(rhs.future_obtained) { future.swap(rhs.future); + rhs.future_obtained=false; } promise & operator=(promise&& rhs) { future.swap(rhs.future); future_obtained=rhs.future_obtained; rhs.future.reset(); + rhs.future_obtained=false; return *this; } #else @@ -949,12 +960,14 @@ namespace boost future(rhs->future),future_obtained(rhs->future_obtained) { rhs->future.reset(); + rhs->future_obtained=false; } promise & operator=(boost::detail::thread_move_t<promise> rhs) { future=rhs->future; future_obtained=rhs->future_obtained; rhs->future.reset(); + rhs->future_obtained=false; return *this; } @@ -1038,10 +1051,10 @@ namespace boost void lazy_init() { - if(!future) + if(!atomic_load(&future)) { - future_obtained=false; - future.reset(new detail::future_object<void>); + future_ptr blank; + atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<void>)); } } public: @@ -1070,12 +1083,14 @@ namespace boost future_obtained(rhs.future_obtained) { future.swap(rhs.future); + rhs.future_obtained=false; } promise & operator=(promise&& rhs) { future.swap(rhs.future); future_obtained=rhs.future_obtained; rhs.future.reset(); + rhs.future_obtained=false; return *this; } #else @@ -1083,12 +1098,14 @@ namespace boost future(rhs->future),future_obtained(rhs->future_obtained) { rhs->future.reset(); + rhs->future_obtained=false; } promise & operator=(boost::detail::thread_move_t<promise> rhs) { future=rhs->future; future_obtained=rhs->future_obtained; rhs->future.reset(); + rhs->future_obtained=false; return *this; } diff --git a/3rdParty/Boost/src/boost/thread/locks.hpp b/3rdParty/Boost/src/boost/thread/locks.hpp index 3cd6f28..d23e619 100644 --- a/3rdParty/Boost/src/boost/thread/locks.hpp +++ b/3rdParty/Boost/src/boost/thread/locks.hpp @@ -11,6 +11,7 @@ #include <iterator> #include <boost/thread/thread_time.hpp> #include <boost/detail/workaround.hpp> +#include <boost/type_traits/is_class.hpp> #include <boost/config/abi_prefix.hpp> @@ -27,41 +28,101 @@ namespace boost #ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES namespace detail { - template<typename T> +#define BOOST_DEFINE_HAS_MEMBER_CALLED(member_name) \ + template<typename T, bool=boost::is_class<T>::value> \ + struct has_member_called_##member_name \ + { \ + BOOST_STATIC_CONSTANT(bool, value=false); \ + }; \ + \ + template<typename T> \ + struct has_member_called_##member_name<T,true> \ + { \ + typedef char true_type; \ + struct false_type \ + { \ + true_type dummy[2]; \ + }; \ + \ + struct fallback { int member_name; }; \ + struct derived: \ + T, fallback \ + { \ + derived(); \ + }; \ + \ + template<int fallback::*> struct tester; \ + \ + template<typename U> \ + static false_type has_member(tester<&U::member_name>*); \ + template<typename U> \ + static true_type has_member(...); \ + \ + BOOST_STATIC_CONSTANT( \ + bool, value=sizeof(has_member<derived>(0))==sizeof(true_type)); \ + } + + BOOST_DEFINE_HAS_MEMBER_CALLED(lock); + BOOST_DEFINE_HAS_MEMBER_CALLED(unlock); + BOOST_DEFINE_HAS_MEMBER_CALLED(try_lock); + + template<typename T,bool=has_member_called_lock<T>::value > struct has_member_lock { + BOOST_STATIC_CONSTANT(bool, value=false); + }; + + template<typename T> + struct has_member_lock<T,true> + { typedef char true_type; struct false_type { true_type dummy[2]; }; + template<typename U,typename V> + static true_type has_member(V (U::*)()); template<typename U> - static true_type has_member(U*,void (U::*dummy)()=&U::lock); - static false_type has_member(void*); + static false_type has_member(U); - BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_lock<T>::has_member((T*)NULL))==sizeof(true_type)); + BOOST_STATIC_CONSTANT( + bool,value=sizeof(has_member_lock<T>::has_member(&T::lock))==sizeof(true_type)); }; - - template<typename T> + + template<typename T,bool=has_member_called_unlock<T>::value > struct has_member_unlock { + BOOST_STATIC_CONSTANT(bool, value=false); + }; + + template<typename T> + struct has_member_unlock<T,true> + { typedef char true_type; struct false_type { true_type dummy[2]; }; + template<typename U,typename V> + static true_type has_member(V (U::*)()); template<typename U> - static true_type has_member(U*,void (U::*dummy)()=&U::unlock); - static false_type has_member(void*); + static false_type has_member(U); - BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_unlock<T>::has_member((T*)NULL))==sizeof(true_type)); + BOOST_STATIC_CONSTANT( + bool,value=sizeof(has_member_unlock<T>::has_member(&T::unlock))==sizeof(true_type)); }; - template<typename T> + template<typename T,bool=has_member_called_try_lock<T>::value > struct has_member_try_lock { + BOOST_STATIC_CONSTANT(bool, value=false); + }; + + template<typename T> + struct has_member_try_lock<T,true> + { typedef char true_type; struct false_type { @@ -69,10 +130,12 @@ namespace boost }; template<typename U> - static true_type has_member(U*,bool (U::*dummy)()=&U::try_lock); - static false_type has_member(void*); + static true_type has_member(bool (U::*)()); + template<typename U> + static false_type has_member(U); - BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_try_lock<T>::has_member((T*)NULL))==sizeof(true_type)); + BOOST_STATIC_CONSTANT( + bool,value=sizeof(has_member_try_lock<T>::has_member(&T::try_lock))==sizeof(true_type)); }; } @@ -214,7 +277,7 @@ namespace boost unique_lock& operator=(unique_lock&); unique_lock& operator=(upgrade_lock<Mutex>& other); public: -#ifdef __SUNPRO_CC +#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) unique_lock(const volatile unique_lock&); #endif unique_lock(): @@ -300,7 +363,7 @@ namespace boost return detail::thread_move_t<unique_lock<Mutex> >(*this); } -#ifdef __SUNPRO_CC +#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) unique_lock& operator=(unique_lock<Mutex> other) { swap(other); @@ -422,6 +485,18 @@ namespace boost { lhs.swap(rhs); } + + template<typename Mutex> + inline upgrade_lock<Mutex>&& move(upgrade_lock<Mutex>&& ul) + { + return static_cast<upgrade_lock<Mutex>&&>(ul); + } + + template<typename Mutex> + inline upgrade_lock<Mutex>&& move(upgrade_lock<Mutex>& ul) + { + return static_cast<upgrade_lock<Mutex>&&>(ul); + } #endif template<typename Mutex> void swap(unique_lock<Mutex>& lhs,unique_lock<Mutex>& rhs) @@ -678,6 +753,39 @@ namespace boost { try_lock(); } +#ifdef BOOST_HAS_RVALUE_REFS + upgrade_lock(upgrade_lock<Mutex>&& other): + m(other.m),is_locked(other.is_locked) + { + other.is_locked=false; + other.m=0; + } + + upgrade_lock(unique_lock<Mutex>&& other): + m(other.m),is_locked(other.is_locked) + { + if(is_locked) + { + m->unlock_and_lock_upgrade(); + } + other.is_locked=false; + other.m=0; + } + + upgrade_lock& operator=(upgrade_lock<Mutex>&& other) + { + upgrade_lock temp(static_cast<upgrade_lock<Mutex>&&>(other)); + swap(temp); + return *this; + } + + upgrade_lock& operator=(unique_lock<Mutex>&& other) + { + upgrade_lock temp(static_cast<unique_lock<Mutex>&&>(other)); + swap(temp); + return *this; + } +#else upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other): m(other->m),is_locked(other->is_locked) { @@ -720,6 +828,7 @@ namespace boost swap(temp); return *this; } +#endif void swap(upgrade_lock& other) { @@ -824,6 +933,20 @@ namespace boost } } +#ifdef BOOST_HAS_RVALUE_REFS + upgrade_to_unique_lock(upgrade_to_unique_lock<Mutex>&& other): + source(other.source),exclusive(move(other.exclusive)) + { + other.source=0; + } + + upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Mutex>&& other) + { + upgrade_to_unique_lock temp(other); + swap(temp); + return *this; + } +#else upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other): source(other->source),exclusive(move(other->exclusive)) { @@ -836,6 +959,7 @@ namespace boost swap(temp); return *this; } +#endif void swap(upgrade_to_unique_lock& other) { std::swap(source,other.source); @@ -923,15 +1047,15 @@ namespace boost return *this; } - void swap(try_lock_wrapper& other) - { - base::swap(other); - } void swap(detail::thread_move_t<try_lock_wrapper<Mutex> > other) { base::swap(*other); } #endif + void swap(try_lock_wrapper& other) + { + base::swap(other); + } void lock() { base::lock(); @@ -1116,7 +1240,7 @@ namespace boost { unsigned const lock_count=2; unsigned lock_first=0; - while(true) + for(;;) { switch(lock_first) { @@ -1169,7 +1293,7 @@ namespace boost { unsigned const lock_count=3; unsigned lock_first=0; - while(true) + for(;;) { switch(lock_first) { @@ -1201,7 +1325,7 @@ namespace boost { unsigned const lock_count=4; unsigned lock_first=0; - while(true) + for(;;) { switch(lock_first) { @@ -1239,7 +1363,7 @@ namespace boost { unsigned const lock_count=5; unsigned lock_first=0; - while(true) + for(;;) { switch(lock_first) { diff --git a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp index 8e8f5b5..9c5bee2 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp @@ -3,7 +3,7 @@ // 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) -// (C) Copyright 2007-8 Anthony Williams +// (C) Copyright 2007-10 Anthony Williams #include "timespec.hpp" #include "pthread_mutex_scoped_lock.hpp" @@ -14,17 +14,55 @@ namespace boost { + namespace this_thread + { + void BOOST_THREAD_DECL interruption_point(); + } + + namespace thread_cv_detail + { + template<typename MutexType> + struct lock_on_exit + { + MutexType* m; + + lock_on_exit(): + m(0) + {} + + void activate(MutexType& m_) + { + m_.unlock(); + m=&m_; + } + ~lock_on_exit() + { + if(m) + { + m->lock(); + } + } + }; + } + inline void condition_variable::wait(unique_lock<mutex>& m) { - detail::interruption_checker check_for_interruption(&cond); - BOOST_VERIFY(!pthread_cond_wait(&cond,m.mutex()->native_handle())); + thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard; + detail::interruption_checker check_for_interruption(&internal_mutex,&cond); + guard.activate(m); + int const res=pthread_cond_wait(&cond,&internal_mutex); + BOOST_ASSERT(!res); + this_thread::interruption_point(); } inline bool condition_variable::timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until) { - detail::interruption_checker check_for_interruption(&cond); + thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard; + detail::interruption_checker check_for_interruption(&internal_mutex,&cond); + guard.activate(m); struct timespec const timeout=detail::get_timespec(wait_until); - int const cond_res=pthread_cond_timedwait(&cond,m.mutex()->native_handle(),&timeout); + int const cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); + this_thread::interruption_point(); if(cond_res==ETIMEDOUT) { return false; @@ -35,11 +73,13 @@ namespace boost inline void condition_variable::notify_one() { + boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); BOOST_VERIFY(!pthread_cond_signal(&cond)); } inline void condition_variable::notify_all() { + boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); BOOST_VERIFY(!pthread_cond_broadcast(&cond)); } @@ -48,8 +88,8 @@ namespace boost pthread_mutex_t internal_mutex; pthread_cond_t cond; - condition_variable_any(condition_variable&); - condition_variable_any& operator=(condition_variable&); + condition_variable_any(condition_variable_any&); + condition_variable_any& operator=(condition_variable_any&); public: condition_variable_any() @@ -77,13 +117,11 @@ namespace boost { int res=0; { - detail::interruption_checker check_for_interruption(&cond); - { - boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); - m.unlock(); - res=pthread_cond_wait(&cond,&internal_mutex); - } - m.lock(); + thread_cv_detail::lock_on_exit<lock_type> guard; + detail::interruption_checker check_for_interruption(&internal_mutex,&cond); + guard.activate(m); + res=pthread_cond_wait(&cond,&internal_mutex); + this_thread::interruption_point(); } if(res) { @@ -103,13 +141,11 @@ namespace boost struct timespec const timeout=detail::get_timespec(wait_until); int res=0; { - detail::interruption_checker check_for_interruption(&cond); - { - boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); - m.unlock(); - res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); - } - m.lock(); + thread_cv_detail::lock_on_exit<lock_type> guard; + detail::interruption_checker check_for_interruption(&internal_mutex,&cond); + guard.activate(m); + res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); + this_thread::interruption_point(); } if(res==ETIMEDOUT) { diff --git a/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp b/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp index 59908f4..365f511 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp @@ -20,6 +20,7 @@ namespace boost class condition_variable { private: + pthread_mutex_t internal_mutex; pthread_cond_t cond; condition_variable(condition_variable&); @@ -28,14 +29,21 @@ namespace boost public: condition_variable() { - int const res=pthread_cond_init(&cond,NULL); + int const res=pthread_mutex_init(&internal_mutex,NULL); if(res) { boost::throw_exception(thread_resource_error()); } + int const res2=pthread_cond_init(&cond,NULL); + if(res2) + { + BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); + boost::throw_exception(thread_resource_error()); + } } ~condition_variable() { + BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); BOOST_VERIFY(!pthread_cond_destroy(&cond)); } @@ -47,7 +55,8 @@ namespace boost while(!pred()) wait(m); } - bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until); + inline bool timed_wait(unique_lock<mutex>& m, + boost::system_time const& wait_until); bool timed_wait(unique_lock<mutex>& m,xtime const& wait_until) { return timed_wait(m,system_time(wait_until)); diff --git a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp index 1f7f790..2a326d7 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp @@ -27,10 +27,11 @@ namespace boost { - class mutex: - boost::noncopyable + class mutex { private: + mutex(mutex const&); + mutex& operator=(mutex const&); pthread_mutex_t m; public: mutex() @@ -48,7 +49,11 @@ namespace boost void lock() { - BOOST_VERIFY(!pthread_mutex_lock(&m)); + int const res=pthread_mutex_lock(&m); + if(res) + { + boost::throw_exception(lock_error(res)); + } } void unlock() @@ -59,7 +64,11 @@ namespace boost bool try_lock() { int const res=pthread_mutex_trylock(&m); - BOOST_ASSERT(!res || res==EBUSY); + if(res && (res!=EBUSY)) + { + boost::throw_exception(lock_error(res)); + } + return !res; } @@ -75,10 +84,12 @@ namespace boost typedef mutex try_mutex; - class timed_mutex: - boost::noncopyable + class timed_mutex { private: + timed_mutex(timed_mutex const&); + timed_mutex& operator=(timed_mutex const&); + private: pthread_mutex_t m; #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK pthread_cond_t cond; diff --git a/3rdParty/Boost/src/boost/thread/pthread/pthread_mutex_scoped_lock.hpp b/3rdParty/Boost/src/boost/thread/pthread/pthread_mutex_scoped_lock.hpp index 2407f91..cdbf8c6 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/pthread_mutex_scoped_lock.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/pthread_mutex_scoped_lock.hpp @@ -18,15 +18,25 @@ namespace boost class pthread_mutex_scoped_lock { pthread_mutex_t* m; + bool locked; public: explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_): - m(m_) + m(m_),locked(true) { BOOST_VERIFY(!pthread_mutex_lock(m)); } - ~pthread_mutex_scoped_lock() + void unlock() { BOOST_VERIFY(!pthread_mutex_unlock(m)); + locked=false; + } + + ~pthread_mutex_scoped_lock() + { + if(locked) + { + unlock(); + } } }; diff --git a/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp index ad3b7e1..4158a57 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp @@ -26,18 +26,30 @@ #endif #endif +#if defined(BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE) && defined(BOOST_PTHREAD_HAS_TIMEDLOCK) +#define BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK +#endif + #include <boost/config/abi_prefix.hpp> namespace boost { - class recursive_mutex: - boost::noncopyable + class recursive_mutex { private: + recursive_mutex(recursive_mutex const&); + recursive_mutex& operator=(recursive_mutex const&); pthread_mutex_t m; +#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE + pthread_cond_t cond; + bool is_locked; + pthread_t owner; + unsigned count; +#endif public: recursive_mutex() { +#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE pthread_mutexattr_t attr; int const init_attr_res=pthread_mutexattr_init(&attr); @@ -48,21 +60,42 @@ namespace boost int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE); if(set_attr_res) { + BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); boost::throw_exception(thread_resource_error()); } int const res=pthread_mutex_init(&m,&attr); if(res) { + BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); boost::throw_exception(thread_resource_error()); } BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); +#else + int const res=pthread_mutex_init(&m,NULL); + if(res) + { + boost::throw_exception(thread_resource_error()); + } + int const res2=pthread_cond_init(&cond,NULL); + if(res2) + { + BOOST_VERIFY(!pthread_mutex_destroy(&m)); + boost::throw_exception(thread_resource_error()); + } + is_locked=false; + count=0; +#endif } ~recursive_mutex() { BOOST_VERIFY(!pthread_mutex_destroy(&m)); +#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE + BOOST_VERIFY(!pthread_cond_destroy(&cond)); +#endif } - + +#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE void lock() { BOOST_VERIFY(!pthread_mutex_lock(&m)); @@ -79,25 +112,70 @@ namespace boost BOOST_ASSERT(!res || res==EBUSY); return !res; } - typedef pthread_mutex_t* native_handle_type; native_handle_type native_handle() { return &m; } +#else + void lock() + { + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + if(is_locked && pthread_equal(owner,pthread_self())) + { + ++count; + return; + } + + while(is_locked) + { + BOOST_VERIFY(!pthread_cond_wait(&cond,&m)); + } + is_locked=true; + ++count; + owner=pthread_self(); + } + + void unlock() + { + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + if(!--count) + { + is_locked=false; + } + BOOST_VERIFY(!pthread_cond_signal(&cond)); + } + + bool try_lock() + { + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + if(is_locked && !pthread_equal(owner,pthread_self())) + { + return false; + } + is_locked=true; + ++count; + owner=pthread_self(); + return true; + } + +#endif + typedef unique_lock<recursive_mutex> scoped_lock; typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock; }; typedef recursive_mutex recursive_try_mutex; - class recursive_timed_mutex: - boost::noncopyable + class recursive_timed_mutex { private: + recursive_timed_mutex(recursive_timed_mutex const&); + recursive_timed_mutex& operator=(recursive_timed_mutex const&); + private: pthread_mutex_t m; -#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK +#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK pthread_cond_t cond; bool is_locked; pthread_t owner; @@ -106,7 +184,7 @@ namespace boost public: recursive_timed_mutex() { -#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK +#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK pthread_mutexattr_t attr; int const init_attr_res=pthread_mutexattr_init(&attr); @@ -146,7 +224,7 @@ namespace boost ~recursive_timed_mutex() { BOOST_VERIFY(!pthread_mutex_destroy(&m)); -#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK +#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK BOOST_VERIFY(!pthread_cond_destroy(&cond)); #endif } @@ -157,7 +235,7 @@ namespace boost return timed_lock(get_system_time()+relative_time); } -#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK +#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK void lock() { BOOST_VERIFY(!pthread_mutex_lock(&m)); diff --git a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp index 30440eb..bc26282 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp @@ -225,7 +225,7 @@ namespace boost template<typename TimeDuration> bool timed_lock_upgrade(TimeDuration const & relative_time) { - return timed_lock(get_system_time()+relative_time); + return timed_lock_upgrade(get_system_time()+relative_time); } bool try_lock_upgrade() diff --git a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp index 730c77c..1bee28b 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp @@ -12,6 +12,7 @@ #include <boost/thread/mutex.hpp> #include <boost/optional.hpp> #include <pthread.h> +#include <boost/assert.hpp> #include "condition_variable_fwd.hpp" #include <map> @@ -55,6 +56,7 @@ namespace boost std::map<void const*,boost::detail::tss_data_node> tss_data; bool interrupt_enabled; bool interrupt_requested; + pthread_mutex_t* cond_mutex; pthread_cond_t* current_cond; thread_data_base(): @@ -76,6 +78,8 @@ namespace boost class interruption_checker { thread_data_base* const thread_info; + pthread_mutex_t* m; + bool set; void check_for_interruption() { @@ -88,23 +92,35 @@ namespace boost void operator=(interruption_checker&); public: - explicit interruption_checker(pthread_cond_t* cond): - thread_info(detail::get_current_thread_data()) + explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond): + thread_info(detail::get_current_thread_data()),m(cond_mutex), + set(thread_info && thread_info->interrupt_enabled) { - if(thread_info && thread_info->interrupt_enabled) + if(set) { lock_guard<mutex> guard(thread_info->data_mutex); check_for_interruption(); + thread_info->cond_mutex=cond_mutex; thread_info->current_cond=cond; + BOOST_VERIFY(!pthread_mutex_lock(m)); + } + else + { + BOOST_VERIFY(!pthread_mutex_lock(m)); } } ~interruption_checker() { - if(thread_info && thread_info->interrupt_enabled) + if(set) { + BOOST_VERIFY(!pthread_mutex_unlock(m)); lock_guard<mutex> guard(thread_info->data_mutex); + thread_info->cond_mutex=NULL; thread_info->current_cond=NULL; - check_for_interruption(); + } + else + { + BOOST_VERIFY(!pthread_mutex_unlock(m)); } } }; diff --git a/3rdParty/Boost/src/boost/thread/thread_time.hpp b/3rdParty/Boost/src/boost/thread/thread_time.hpp index 8b557d5..ffdcf85 100644 --- a/3rdParty/Boost/src/boost/thread/thread_time.hpp +++ b/3rdParty/Boost/src/boost/thread/thread_time.hpp @@ -6,6 +6,7 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include <boost/date_time/time_clock.hpp> #include <boost/date_time/microsec_time_clock.hpp> #include <boost/date_time/posix_time/posix_time_types.hpp> @@ -17,7 +18,11 @@ namespace boost inline system_time get_system_time() { +#if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) return boost::date_time::microsec_clock<system_time>::universal_time(); +#else // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) + return boost::date_time::second_clock<system_time>::universal_time(); +#endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK) } namespace detail diff --git a/3rdParty/Boost/src/boost/thread/tss.hpp b/3rdParty/Boost/src/boost/thread/tss.hpp index e38e3e9..c920024 100644 --- a/3rdParty/Boost/src/boost/thread/tss.hpp +++ b/3rdParty/Boost/src/boost/thread/tss.hpp @@ -62,6 +62,8 @@ namespace boost boost::shared_ptr<detail::tss_cleanup_function> cleanup; public: + typedef T element_type; + thread_specific_ptr(): cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>()) {} diff --git a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp index efe6241..d59fbfa 100644 --- a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp @@ -20,9 +20,11 @@ namespace boost } class mutex: - boost::noncopyable, public ::boost::detail::underlying_mutex { + private: + mutex(mutex const&); + mutex& operator=(mutex const&); public: mutex() { @@ -40,9 +42,11 @@ namespace boost typedef mutex try_mutex; class timed_mutex: - boost::noncopyable, public ::boost::detail::basic_timed_mutex { + private: + timed_mutex(timed_mutex const&); + timed_mutex& operator=(timed_mutex const&); public: timed_mutex() { diff --git a/3rdParty/Boost/src/boost/thread/win32/once.hpp b/3rdParty/Boost/src/boost/thread/win32/once.hpp index c25f9ab..e1b1843 100644 --- a/3rdParty/Boost/src/boost/thread/win32/once.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/once.hpp @@ -34,42 +34,85 @@ namespace boost { long status; long count; - long throw_count; - void* event_handle; + }; + +#define BOOST_ONCE_INIT {0,0} + + namespace detail + { +#ifdef BOOST_NO_ANSI_APIS + typedef wchar_t once_char_type; +#else + typedef char once_char_type; +#endif + unsigned const once_mutex_name_fixed_length=54; + unsigned const once_mutex_name_length=once_mutex_name_fixed_length+ + sizeof(void*)*2+sizeof(unsigned long)*2+1; - ~once_flag() + template <class I> + void int_to_string(I p, once_char_type* buf) { - if(count) + for(unsigned i=0; i < sizeof(I)*2; ++i,++buf) { - BOOST_ASSERT(count==throw_count); +#ifdef BOOST_NO_ANSI_APIS + once_char_type const a=L'A'; +#else + once_char_type const a='A'; +#endif + *buf = a + static_cast<once_char_type>((p >> (i*4)) & 0x0f); } + *buf = 0; + } + + inline void name_once_mutex(once_char_type* mutex_name,void* flag_address) + { +#ifdef BOOST_NO_ANSI_APIS + static const once_char_type fixed_mutex_name[]=L"Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag"; +#else + static const once_char_type fixed_mutex_name[]="Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag"; +#endif + BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) == + (sizeof(once_char_type)*(once_mutex_name_fixed_length+1))); - void* const old_event=BOOST_INTERLOCKED_EXCHANGE_POINTER(&event_handle,0); - if(old_event) + std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name)); + detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address), + mutex_name + once_mutex_name_fixed_length); + detail::int_to_string(win32::GetCurrentProcessId(), + mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2); + } + + inline void* open_once_event(once_char_type* mutex_name,void* flag_address) + { + if(!*mutex_name) { - ::boost::detail::win32::CloseHandle(old_event); + name_once_mutex(mutex_name,flag_address); } + +#ifdef BOOST_NO_ANSI_APIS + return ::boost::detail::win32::OpenEventW( +#else + return ::boost::detail::win32::OpenEventA( +#endif + ::boost::detail::win32::synchronize | + ::boost::detail::win32::event_modify_state, + false, + mutex_name); } - }; -#define BOOST_ONCE_INIT {0,0,0,0} - - namespace detail - { - inline void* allocate_event_handle(void*& handle) + inline void* create_once_event(once_char_type* mutex_name,void* flag_address) { - void* const new_handle=::boost::detail::win32::create_anonymous_event( - ::boost::detail::win32::manual_reset_event, - ::boost::detail::win32::event_initially_reset); - - void* event_handle=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&handle, - new_handle,0); - if(event_handle) + if(!*mutex_name) { - ::boost::detail::win32::CloseHandle(new_handle); - return event_handle; + name_once_mutex(mutex_name,flag_address); } - return new_handle; +#ifdef BOOST_NO_ANSI_APIS + return ::boost::detail::win32::CreateEventW( +#else + return ::boost::detail::win32::CreateEventA( +#endif + 0,::boost::detail::win32::manual_reset_event, + ::boost::detail::win32::event_initially_reset, + mutex_name); } } @@ -83,8 +126,9 @@ namespace boost long const running_value=0x7f0725e3; long status; bool counted=false; - void* event_handle=0; - long throw_count=0; + detail::win32::handle_manager event_handle; + detail::once_char_type mutex_name[detail::once_mutex_name_length]; + mutex_name[0]=0; while((status=::boost::detail::interlocked_read_acquire(&flag.status)) !=function_complete_flag_value) @@ -96,7 +140,7 @@ namespace boost { if(!event_handle) { - event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle); + event_handle=detail::open_once_event(mutex_name,&flag); } if(event_handle) { @@ -112,25 +156,20 @@ namespace boost if(!event_handle && (::boost::detail::interlocked_read_acquire(&flag.count)>1)) { - event_handle=::boost::detail::allocate_event_handle(flag.event_handle); + event_handle=detail::create_once_event(mutex_name,&flag); } if(event_handle) { ::boost::detail::win32::SetEvent(event_handle); } - throw_count=::boost::detail::interlocked_read_acquire(&flag.throw_count); break; } catch(...) { - if(counted) - { - BOOST_INTERLOCKED_INCREMENT(&flag.throw_count); - } BOOST_INTERLOCKED_EXCHANGE(&flag.status,0); if(!event_handle) { - event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle); + event_handle=detail::open_once_event(mutex_name,&flag); } if(event_handle) { @@ -149,31 +188,15 @@ namespace boost { break; } - event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle); if(!event_handle) { - event_handle=::boost::detail::allocate_event_handle(flag.event_handle); + event_handle=detail::create_once_event(mutex_name,&flag); continue; } } BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( event_handle,::boost::detail::win32::infinite)); } - if(counted || throw_count) - { - if(!BOOST_INTERLOCKED_EXCHANGE_ADD(&flag.count,(counted?-1:0)-throw_count)) - { - if(!event_handle) - { - event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle); - } - if(event_handle) - { - BOOST_INTERLOCKED_EXCHANGE_POINTER(&flag.event_handle,0); - ::boost::detail::win32::CloseHandle(event_handle); - } - } - } } } diff --git a/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp index 2360a92..e83d3bc 100644 --- a/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp @@ -20,9 +20,11 @@ namespace boost { class recursive_mutex: - boost::noncopyable, public ::boost::detail::basic_recursive_mutex { + private: + recursive_mutex(recursive_mutex const&); + recursive_mutex& operator=(recursive_mutex const&); public: recursive_mutex() { @@ -40,9 +42,11 @@ namespace boost typedef recursive_mutex recursive_try_mutex; class recursive_timed_mutex: - boost::noncopyable, public ::boost::detail::basic_recursive_timed_mutex { + private: + recursive_timed_mutex(recursive_timed_mutex const&); + recursive_timed_mutex& operator=(recursive_timed_mutex const&); public: recursive_timed_mutex() { diff --git a/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp index 58e8093..58fc622 100644 --- a/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp @@ -19,10 +19,12 @@ namespace boost { - class shared_mutex: - private boost::noncopyable + class shared_mutex { private: + shared_mutex(shared_mutex const&); + shared_mutex& operator=(shared_mutex const&); + private: struct state_data { unsigned shared_count:11, @@ -49,33 +51,35 @@ namespace boost return *reinterpret_cast<T const*>(&res); } + enum + { + unlock_sem = 0, + exclusive_sem = 1 + }; + state_data state; detail::win32::handle semaphores[2]; - detail::win32::handle &unlock_sem; - detail::win32::handle &exclusive_sem; detail::win32::handle upgrade_sem; void release_waiters(state_data old_state) { if(old_state.exclusive_waiting) { - BOOST_VERIFY(detail::win32::ReleaseSemaphore(exclusive_sem,1,0)!=0); + BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0); } if(old_state.shared_waiting || old_state.exclusive_waiting) { - BOOST_VERIFY(detail::win32::ReleaseSemaphore(unlock_sem,old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0); + BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0); } } public: - shared_mutex(): - unlock_sem(semaphores[0]), - exclusive_sem(semaphores[1]) + shared_mutex() { - unlock_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX); - exclusive_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX); + semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX); + semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX); upgrade_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX); state_data state_={0}; state=state_; @@ -84,8 +88,8 @@ namespace boost ~shared_mutex() { detail::win32::CloseHandle(upgrade_sem); - detail::win32::CloseHandle(unlock_sem); - detail::win32::CloseHandle(exclusive_sem); + detail::win32::CloseHandle(semaphores[unlock_sem]); + detail::win32::CloseHandle(semaphores[exclusive_sem]); } bool try_lock_shared() @@ -97,6 +101,10 @@ namespace boost if(!new_state.exclusive && !new_state.exclusive_waiting_blocked) { ++new_state.shared_count; + if(!new_state.shared_count) + { + return false; + } } state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); @@ -131,10 +139,18 @@ namespace boost if(new_state.exclusive || new_state.exclusive_waiting_blocked) { ++new_state.shared_waiting; + if(!new_state.shared_waiting) + { + boost::throw_exception(boost::lock_error()); + } } else { ++new_state.shared_count; + if(!new_state.shared_count) + { + boost::throw_exception(boost::lock_error()); + } } state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); @@ -150,7 +166,7 @@ namespace boost return true; } - unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,::boost::detail::get_milliseconds_until(wait_until)); + unsigned long const res=detail::win32::WaitForSingleObject(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until)); if(res==detail::win32::timeout) { for(;;) @@ -166,6 +182,10 @@ namespace boost else { ++new_state.shared_count; + if(!new_state.shared_count) + { + return false; + } } state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); @@ -282,6 +302,11 @@ namespace boost if(new_state.shared_count || new_state.exclusive) { ++new_state.exclusive_waiting; + if(!new_state.exclusive_waiting) + { + boost::throw_exception(boost::lock_error()); + } + new_state.exclusive_waiting_blocked=true; } else @@ -374,10 +399,18 @@ namespace boost if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade) { ++new_state.shared_waiting; + if(!new_state.shared_waiting) + { + boost::throw_exception(boost::lock_error()); + } } else { ++new_state.shared_count; + if(!new_state.shared_count) + { + boost::throw_exception(boost::lock_error()); + } new_state.upgrade=true; } @@ -394,7 +427,7 @@ namespace boost return; } - BOOST_VERIFY(!detail::win32::WaitForSingleObject(unlock_sem,detail::win32::infinite)); + BOOST_VERIFY(!detail::win32::WaitForSingleObject(semaphores[unlock_sem],detail::win32::infinite)); } } @@ -411,6 +444,10 @@ namespace boost else { ++new_state.shared_count; + if(!new_state.shared_count) + { + return false; + } new_state.upgrade=true; } diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp index 1a6a1e0..c86b0fa 100644 --- a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp @@ -144,6 +144,11 @@ namespace boost start(0),milliseconds(~uintmax_t(0)),relative(true) {} }; + + inline unsigned long pin_to_zero(long value) + { + return (value<0)?0u:(unsigned long)value; + } } namespace this_thread @@ -163,7 +168,7 @@ namespace boost template<typename TimeDuration> inline void sleep(TimeDuration const& rel_time) { - interruptible_wait(static_cast<unsigned long>(rel_time.total_milliseconds())); + interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds())); } inline void sleep(system_time const& abs_time) { diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp index 2359c38..9b20e86 100644 --- a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp @@ -31,14 +31,18 @@ namespace boost unsigned const infinite=INFINITE; unsigned const timeout=WAIT_TIMEOUT; handle const invalid_handle_value=INVALID_HANDLE_VALUE; + unsigned const event_modify_state=EVENT_MODIFY_STATE; + unsigned const synchronize=SYNCHRONIZE; # ifdef BOOST_NO_ANSI_APIS using ::CreateMutexW; using ::CreateEventW; + using ::OpenEventW; using ::CreateSemaphoreW; # else using ::CreateMutexA; using ::CreateEventA; + using ::OpenEventA; using ::CreateSemaphoreA; # endif using ::CloseHandle; @@ -100,6 +104,8 @@ namespace boost unsigned const infinite=~0U; unsigned const timeout=258U; handle const invalid_handle_value=(handle)(-1); + unsigned const event_modify_state=2; + unsigned const synchronize=0x100000u; extern "C" { @@ -108,10 +114,12 @@ namespace boost __declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*); __declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*); __declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*); + __declspec(dllimport) void* __stdcall OpenEventW(unsigned long,int,wchar_t const*); # else __declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*); __declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*); __declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*); + __declspec(dllimport) void* __stdcall OpenEventA(unsigned long,int,char const*); # endif __declspec(dllimport) int __stdcall CloseHandle(void*); __declspec(dllimport) int __stdcall ReleaseMutex(void*); diff --git a/3rdParty/Boost/src/boost/throw_exception.hpp b/3rdParty/Boost/src/boost/throw_exception.hpp index 1d018c5..a384054 100644 --- a/3rdParty/Boost/src/boost/throw_exception.hpp +++ b/3rdParty/Boost/src/boost/throw_exception.hpp @@ -43,26 +43,6 @@ namespace boost { -#if !defined( BOOST_EXCEPTION_DISABLE ) - namespace - exception_detail - { - template <class E> - void - throw_exception_( E const & x, char const * current_function, char const * file, int line ) - { - throw_exception( - set_info( - set_info( - set_info( - enable_error_info(x), - throw_function(current_function)), - throw_file(file)), - throw_line(line))); - } - } -#endif - #ifdef BOOST_NO_EXCEPTIONS void throw_exception( std::exception const & e ); // user defined @@ -86,6 +66,26 @@ template<class E> BOOST_ATTRIBUTE_NORETURN inline void throw_exception( E const #endif +#if !defined( BOOST_EXCEPTION_DISABLE ) + namespace + exception_detail + { + template <class E> + BOOST_ATTRIBUTE_NORETURN + void + throw_exception_( E const & x, char const * current_function, char const * file, int line ) + { + boost::throw_exception( + set_info( + set_info( + set_info( + enable_error_info(x), + throw_function(current_function)), + throw_file(file)), + throw_line(line))); + } + } +#endif } // namespace boost #endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/token_functions.hpp b/3rdParty/Boost/src/boost/token_functions.hpp index ef7ba73..4e2d745 100644 --- a/3rdParty/Boost/src/boost/token_functions.hpp +++ b/3rdParty/Boost/src/boost/token_functions.hpp @@ -40,6 +40,9 @@ #include <boost/assert.hpp> #include <boost/detail/workaround.hpp> #include <boost/mpl/if.hpp> +#if !defined(BOOST_NO_CWCTYPE) +#include <cwctype> +#endif // // the following must not be macros if we are to prefix them @@ -48,9 +51,15 @@ #ifdef ispunct # undef ispunct #endif +#ifdef iswpunct +# undef iswpunct +#endif #ifdef isspace # undef isspace #endif +#ifdef iswspace +# undef iswspace +#endif // // fix namespace problems: // @@ -58,11 +67,14 @@ namespace std{ using ::ispunct; using ::isspace; +#if !defined(BOOST_NO_CWCTYPE) + using ::iswpunct; + using ::iswspace; +#endif } #endif namespace boost{ - //=========================================================================== // The escaped_list_separator class. Which is a model of TokenizerFunction // An escaped list is a super-set of what is commonly known as a comma @@ -76,17 +88,12 @@ namespace boost{ struct escaped_list_error : public std::runtime_error{ escaped_list_error(const std::string& what_arg):std::runtime_error(what_arg) { } }; - + // The out of the box GCC 2.95 on cygwin does not have a char_traits class. // MSVC does not like the following typename -#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - template <class Char, - class Traits = typename std::basic_string<Char>::traits_type > -#else - template <class Char, - class Traits = std::basic_string<Char>::traits_type > -#endif + template <class Char, + class Traits = BOOST_DEDUCED_TYPENAME std::basic_string<Char>::traits_type > class escaped_list_separator { private: @@ -100,7 +107,7 @@ namespace boost{ }; string_type escape_; string_type c_; - string_type quote_; + string_type quote_; bool last_; bool is_escape(Char e) { @@ -140,21 +147,21 @@ namespace boost{ } public: - + explicit escaped_list_separator(Char e = '\\', Char c = ',',Char q = '\"') : escape_(1,e), c_(1,c), quote_(1,q), last_(false) { } - + escaped_list_separator(string_type e, string_type c, string_type q) : escape_(e), c_(c), quote_(q), last_(false) { } - + void reset() {last_=false;} template <typename InputIterator, typename Token> bool operator()(InputIterator& next,InputIterator end,Token& tok) { bool bInQuote = false; tok = Token(); - + if (next == end) { if (last_) { last_ = false; @@ -193,8 +200,44 @@ namespace boost{ //=========================================================================== // The classes here are used by offset_separator and char_separator to implement // faster assigning of tokens using assign instead of += - + namespace tokenizer_detail { + //=========================================================================== + // Tokenizer was broken for wide character separators, at least on Windows, since + // CRT functions isspace etc only expect values in [0, 0xFF]. Debug build asserts + // if higher values are passed in. The traits extension class should take care of this. + // Assuming that the conditional will always get optimized out in the function + // implementations, argument types are not a problem since both forms of character classifiers + // expect an int. + // In case there is no cwctype header, we implement the checks manually. + // We make use of the fact that the tested categories should fit in ASCII. + template<typename traits> + struct traits_extension : public traits { + typedef typename traits::char_type char_type; + static bool isspace(char_type c) + { +#if !defined(BOOST_NO_CWCTYPE) + if (sizeof(char_type) == 1) + return std::isspace(c) != 0; + else + return std::iswspace(c) != 0; +#else + return static_cast< unsigned >(c) <= 255 && std::isspace(c) != 0; +#endif + } + + static bool ispunct(char_type c) + { +#if !defined(BOOST_NO_CWCTYPE) + if (sizeof(char_type) == 1) + return std::ispunct(c) != 0; + else + return std::iswpunct(c) != 0; +#else + return static_cast< unsigned >(c) <= 255 && std::ispunct(c) != 0; +#endif + } + }; // The assign_or_plus_equal struct contains functions that implement // assign, +=, and clearing based on the iterator type. The @@ -229,26 +272,20 @@ namespace boost{ } - template<class Token, class Value> - static void plus_equal(Token &, const Value &) { - - } + template<class Token, class Value> + static void plus_equal(Token &, const Value &) { } // If we are doing an assign, there is no need for the - // the clear. + // the clear. // template<class Token> - static void clear(Token &) { - - } + static void clear(Token &) { } }; template <> struct assign_or_plus_equal<std::input_iterator_tag> { template<class Iterator, class Token> - static void assign(Iterator b, Iterator e, Token &t) { - - } + static void assign(Iterator b, Iterator e, Token &t) { } template<class Token, class Value> static void plus_equal(Token &t, const Value &v) { t += v; @@ -284,10 +321,10 @@ namespace boost{ typedef typename cat::type iterator_category; }; - -} - + } // namespace tokenizer_detail + + //=========================================================================== // The offset_separator class, which is a model of TokenizerFunction. // Offset breaks a string into tokens based on a range of offsets @@ -299,7 +336,7 @@ namespace boost{ unsigned int current_offset_; bool wrap_offsets_; bool return_partial_last_; - + public: template <typename Iter> offset_separator(Iter begin, Iter end, bool wrap_offsets = true, @@ -307,7 +344,7 @@ namespace boost{ : offsets_(begin,end), current_offset_(0), wrap_offsets_(wrap_offsets), return_partial_last_(return_partial_last) { } - + offset_separator() : offsets_(1,1), current_offset_(), wrap_offsets_(true), return_partial_last_(true) { } @@ -320,18 +357,16 @@ namespace boost{ bool operator()(InputIterator& next, InputIterator end, Token& tok) { typedef tokenizer_detail::assign_or_plus_equal< -#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - typename -#endif - tokenizer_detail::get_iterator_category< - InputIterator>::iterator_category> assigner; - + BOOST_DEDUCED_TYPENAME tokenizer_detail::get_iterator_category< + InputIterator + >::iterator_category + > assigner; BOOST_ASSERT(!offsets_.empty()); - + assigner::clear(tok); InputIterator start(next); - + if (next == end) return false; @@ -342,7 +377,7 @@ namespace boost{ else return false; } - + int c = offsets_[current_offset_]; int i = 0; for (; i < c; ++i) { @@ -350,11 +385,11 @@ namespace boost{ assigner::plus_equal(tok,*next++); } assigner::assign(start,next,tok); - + if (!return_partial_last_) if (i < (c-1) ) return false; - + ++current_offset_; return true; } @@ -378,16 +413,12 @@ namespace boost{ enum empty_token_policy { drop_empty_tokens, keep_empty_tokens }; // The out of the box GCC 2.95 on cygwin does not have a char_traits class. -#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - template <typename Char, - typename Traits = typename std::basic_string<Char>::traits_type > -#else - template <typename Char, - typename Traits = std::basic_string<Char>::traits_type > -#endif + template <typename Char, + typename Tr = BOOST_DEDUCED_TYPENAME std::basic_string<Char>::traits_type > class char_separator { - typedef std::basic_string<Char,Traits> string_type; + typedef tokenizer_detail::traits_extension<Tr> Traits; + typedef std::basic_string<Char,Tr> string_type; public: explicit char_separator(const Char* dropped_delims, @@ -407,8 +438,8 @@ namespace boost{ // use ispunct() for kept delimiters and isspace for dropped. explicit char_separator() - : m_use_ispunct(true), - m_use_isspace(true), + : m_use_ispunct(true), + m_use_isspace(true), m_empty_tokens(drop_empty_tokens) { } void reset() { } @@ -417,11 +448,10 @@ namespace boost{ bool operator()(InputIterator& next, InputIterator end, Token& tok) { typedef tokenizer_detail::assign_or_plus_equal< -#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - typename -#endif - tokenizer_detail::get_iterator_category< - InputIterator>::iterator_category> assigner; + BOOST_DEDUCED_TYPENAME tokenizer_detail::get_iterator_category< + InputIterator + >::iterator_category + > assigner; assigner::clear(tok); @@ -429,7 +459,7 @@ namespace boost{ if (m_empty_tokens == drop_empty_tokens) for (; next != end && is_dropped(*next); ++next) { } - + InputIterator start(next); if (m_empty_tokens == drop_empty_tokens) { @@ -446,13 +476,13 @@ namespace boost{ // append all the non delim characters for (; next != end && !is_dropped(*next) && !is_kept(*next); ++next) assigner::plus_equal(tok,*next); - } + } else { // m_empty_tokens == keep_empty_tokens - + // Handle empty token at the end if (next == end) { - if (m_output_done == false) + if (m_output_done == false) { m_output_done = true; assigner::assign(start,next,tok); @@ -461,7 +491,7 @@ namespace boost{ else return false; } - + if (is_kept(*next)) { if (m_output_done == false) m_output_done = true; @@ -493,13 +523,13 @@ namespace boost{ bool m_use_isspace; empty_token_policy m_empty_tokens; bool m_output_done; - + bool is_kept(Char E) const - { + { if (m_kept_delims.length()) return m_kept_delims.find(E) != string_type::npos; else if (m_use_ispunct) { - return std::ispunct(E) != 0; + return Traits::ispunct(E) != 0; } else return false; } @@ -508,7 +538,7 @@ namespace boost{ if (m_dropped_delims.length()) return m_dropped_delims.find(E) != string_type::npos; else if (m_use_isspace) { - return std::isspace(E) != 0; + return Traits::isspace(E) != 0; } else return false; } @@ -525,31 +555,27 @@ namespace boost{ // cannot be returned as tokens. These are often whitespace // The out of the box GCC 2.95 on cygwin does not have a char_traits class. -#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - template <class Char, - class Traits = typename std::basic_string<Char>::traits_type > -#else - template <class Char, - class Traits = std::basic_string<Char>::traits_type > -#endif + template <class Char, + class Tr = BOOST_DEDUCED_TYPENAME std::basic_string<Char>::traits_type > class char_delimiters_separator { - private: + private: - typedef std::basic_string<Char,Traits> string_type; + typedef tokenizer_detail::traits_extension<Tr> Traits; + typedef std::basic_string<Char,Tr> string_type; string_type returnable_; string_type nonreturnable_; bool return_delims_; bool no_ispunct_; bool no_isspace_; - + bool is_ret(Char E)const - { + { if (returnable_.length()) return returnable_.find(E) != string_type::npos; else{ if (no_ispunct_) {return false;} else{ - int r = std::ispunct(E); + int r = Traits::ispunct(E); return r != 0; } } @@ -561,12 +587,12 @@ namespace boost{ else{ if (no_isspace_) {return false;} else{ - int r = std::isspace(E); + int r = Traits::isspace(E); return r != 0; } } } - + public: explicit char_delimiters_separator(bool return_delims = false, const Char* returnable = 0, @@ -575,7 +601,7 @@ namespace boost{ nonreturnable_(nonreturnable ? nonreturnable:string_type().c_str()), return_delims_(return_delims), no_ispunct_(returnable!=0), no_isspace_(nonreturnable!=0) { } - + void reset() { } public: @@ -583,16 +609,16 @@ namespace boost{ template <typename InputIterator, typename Token> bool operator()(InputIterator& next, InputIterator end,Token& tok) { tok = Token(); - + // skip past all nonreturnable delims // skip past the returnable only if we are not returning delims for (;next!=end && ( is_nonret(*next) || (is_ret(*next) && !return_delims_ ) );++next) { } - + if (next == end) { return false; } - + // if we are to return delims and we are one a returnable one // move past it and stop if (is_ret(*next) && return_delims_) { @@ -603,8 +629,8 @@ namespace boost{ // append all the non delim characters for (;next!=end && !is_nonret(*next) && !is_ret(*next);++next) tok+=*next; - - + + return true; } }; @@ -612,10 +638,4 @@ namespace boost{ } //namespace boost - -#endif - - - - - +#endif diff --git a/3rdParty/Boost/src/boost/type_traits.hpp b/3rdParty/Boost/src/boost/type_traits.hpp index 0c313b8..c725296 100644 --- a/3rdParty/Boost/src/boost/type_traits.hpp +++ b/3rdParty/Boost/src/boost/type_traits.hpp @@ -12,10 +12,22 @@ #include "boost/type_traits/add_const.hpp" #include "boost/type_traits/add_cv.hpp" +#include "boost/type_traits/add_lvalue_reference.hpp" #include "boost/type_traits/add_pointer.hpp" #include "boost/type_traits/add_reference.hpp" +#include "boost/type_traits/add_rvalue_reference.hpp" #include "boost/type_traits/add_volatile.hpp" +#include "boost/type_traits/aligned_storage.hpp" #include "boost/type_traits/alignment_of.hpp" +#include "boost/type_traits/common_type.hpp" +#include "boost/type_traits/conditional.hpp" +#include "boost/type_traits/decay.hpp" +#include "boost/type_traits/extent.hpp" +#include "boost/type_traits/floating_point_promotion.hpp" +#include "boost/type_traits/function_traits.hpp" +#if !defined(__BORLANDC__) && !defined(__CUDACC__) +#include "boost/type_traits/has_new_operator.hpp" +#endif #include "boost/type_traits/has_nothrow_assign.hpp" #include "boost/type_traits/has_nothrow_constructor.hpp" #include "boost/type_traits/has_nothrow_copy.hpp" @@ -25,14 +37,13 @@ #include "boost/type_traits/has_trivial_copy.hpp" #include "boost/type_traits/has_trivial_destructor.hpp" #include "boost/type_traits/has_virtual_destructor.hpp" -#include "boost/type_traits/is_signed.hpp" -#include "boost/type_traits/is_unsigned.hpp" #include "boost/type_traits/is_abstract.hpp" #include "boost/type_traits/is_arithmetic.hpp" #include "boost/type_traits/is_array.hpp" #include "boost/type_traits/is_base_and_derived.hpp" #include "boost/type_traits/is_base_of.hpp" #include "boost/type_traits/is_class.hpp" +#include <boost/type_traits/is_complex.hpp> #include "boost/type_traits/is_compound.hpp" #include "boost/type_traits/is_const.hpp" #include "boost/type_traits/is_convertible.hpp" @@ -43,6 +54,7 @@ #include "boost/type_traits/is_function.hpp" #include "boost/type_traits/is_fundamental.hpp" #include "boost/type_traits/is_integral.hpp" +#include "boost/type_traits/is_lvalue_reference.hpp" #include "boost/type_traits/is_member_function_pointer.hpp" #include "boost/type_traits/is_member_object_pointer.hpp" #include "boost/type_traits/is_member_pointer.hpp" @@ -51,14 +63,19 @@ #include "boost/type_traits/is_polymorphic.hpp" #include "boost/type_traits/is_pointer.hpp" #include "boost/type_traits/is_reference.hpp" +#include "boost/type_traits/is_rvalue_reference.hpp" +#include "boost/type_traits/is_signed.hpp" #include "boost/type_traits/is_same.hpp" #include "boost/type_traits/is_scalar.hpp" #include "boost/type_traits/is_stateless.hpp" #include "boost/type_traits/is_union.hpp" +#include "boost/type_traits/is_unsigned.hpp" #include "boost/type_traits/is_void.hpp" +#include "boost/type_traits/is_virtual_base_of.hpp" #include "boost/type_traits/is_volatile.hpp" +#include <boost/type_traits/make_unsigned.hpp> +#include <boost/type_traits/make_signed.hpp> #include "boost/type_traits/rank.hpp" -#include "boost/type_traits/extent.hpp" #include "boost/type_traits/remove_bounds.hpp" #include "boost/type_traits/remove_extent.hpp" #include "boost/type_traits/remove_all_extents.hpp" @@ -68,17 +85,10 @@ #include "boost/type_traits/remove_reference.hpp" #include "boost/type_traits/remove_volatile.hpp" #include "boost/type_traits/type_with_alignment.hpp" -#include "boost/type_traits/function_traits.hpp" -#include "boost/type_traits/aligned_storage.hpp" -#include "boost/type_traits/floating_point_promotion.hpp" #if !(defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238)) #include "boost/type_traits/integral_promotion.hpp" #include "boost/type_traits/promote.hpp" #endif -#include <boost/type_traits/make_unsigned.hpp> -#include <boost/type_traits/make_signed.hpp> -#include <boost/type_traits/decay.hpp> -#include <boost/type_traits/is_complex.hpp> #include "boost/type_traits/ice.hpp" diff --git a/3rdParty/Boost/src/boost/type_traits/add_lvalue_reference.hpp b/3rdParty/Boost/src/boost/type_traits/add_lvalue_reference.hpp new file mode 100644 index 0000000..4156372 --- /dev/null +++ b/3rdParty/Boost/src/boost/type_traits/add_lvalue_reference.hpp @@ -0,0 +1,26 @@ +// Copyright 2010 John Maddock + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP +#define BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP + +#include <boost/type_traits/add_reference.hpp> + +// should be the last #include +#include <boost/type_traits/detail/type_trait_def.hpp> + +namespace boost{ + +BOOST_TT_AUX_TYPE_TRAIT_DEF1(add_lvalue_reference,T,typename boost::add_reference<T>::type) + +#ifndef BOOST_NO_RVALUE_REFERENCES +BOOST_TT_AUX_TYPE_TRAIT_PARTIAL_SPEC1_1(typename T,add_lvalue_reference,T&&,T&) +#endif + +} + +#include <boost/type_traits/detail/type_trait_undef.hpp> + +#endif // BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP diff --git a/3rdParty/Boost/src/boost/type_traits/add_reference.hpp b/3rdParty/Boost/src/boost/type_traits/add_reference.hpp index 7dfb4be..eb4f9b1 100644 --- a/3rdParty/Boost/src/boost/type_traits/add_reference.hpp +++ b/3rdParty/Boost/src/boost/type_traits/add_reference.hpp @@ -51,13 +51,31 @@ struct add_reference_impl }; #else +// +// We can't filter out rvalue_references at the same level as +// references or we get ambiguities from msvc: +// template <typename T> -struct add_reference_impl +struct add_reference_rvalue_layer { typedef T& type; }; +#ifndef BOOST_NO_RVALUE_REFERENCES +template <typename T> +struct add_reference_rvalue_layer<T&&> +{ + typedef T&& type; +}; +#endif + +template <typename T> +struct add_reference_impl +{ + typedef typename add_reference_rvalue_layer<T>::type type; +}; + #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION BOOST_TT_AUX_TYPE_TRAIT_IMPL_PARTIAL_SPEC1_1(typename T,add_reference,T&,T&) #endif diff --git a/3rdParty/Boost/src/boost/type_traits/add_rvalue_reference.hpp b/3rdParty/Boost/src/boost/type_traits/add_rvalue_reference.hpp new file mode 100644 index 0000000..00b723c --- /dev/null +++ b/3rdParty/Boost/src/boost/type_traits/add_rvalue_reference.hpp @@ -0,0 +1,67 @@ +// add_rvalue_reference.hpp ---------------------------------------------------------// + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP +#define BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP + +#include <boost/config.hpp> + +//----------------------------------------------------------------------------// + +#include <boost/type_traits/is_void.hpp> +#include <boost/type_traits/is_reference.hpp> + +// should be the last #include +#include <boost/type_traits/detail/type_trait_def.hpp> + +//----------------------------------------------------------------------------// +// // +// C++03 implementation of // +// 20.7.6.2 Reference modifications [meta.trans.ref] // +// Written by Vicente J. Botet Escriba // +// // +// If T names an object or function type then the member typedef type +// shall name T&&; otherwise, type shall name T. [ Note: This rule reflects +// the semantics of reference collapsing. For example, when a type T names +// a type T1&, the type add_rvalue_reference<T>::type is not an rvalue +// reference. —end note ] +//----------------------------------------------------------------------------// + +namespace boost { + +namespace type_traits_detail { + + template <typename T, bool b> + struct add_rvalue_reference_helper + { typedef T type; }; + + template <typename T> + struct add_rvalue_reference_helper<T, true> + { +#if !defined(BOOST_NO_RVALUE_REFERENCES) + typedef T&& type; +#else + typedef T type; +#endif + }; + + template <typename T> + struct add_rvalue_reference_imp + { + typedef typename boost::type_traits_detail::add_rvalue_reference_helper + <T, (!is_void<T>::value && !is_reference<T>::value) >::type type; + }; + +} + +BOOST_TT_AUX_TYPE_TRAIT_DEF1(add_rvalue_reference,T,typename boost::type_traits_detail::add_rvalue_reference_imp<T>::type) + +} // namespace boost + +#include <boost/type_traits/detail/type_trait_undef.hpp> + +#endif // BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP diff --git a/3rdParty/Boost/src/boost/type_traits/common_type.hpp b/3rdParty/Boost/src/boost/type_traits/common_type.hpp new file mode 100644 index 0000000..58525fd --- /dev/null +++ b/3rdParty/Boost/src/boost/type_traits/common_type.hpp @@ -0,0 +1,153 @@ +// common_type.hpp ---------------------------------------------------------// + +// Copyright 2008 Howard Hinnant +// Copyright 2008 Beman Dawes + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_TYPE_TRAITS_COMMON_TYPE_HPP +#define BOOST_TYPE_TRAITS_COMMON_TYPE_HPP + +#include <boost/config.hpp> + +#ifdef __SUNPRO_CC +# define BOOST_COMMON_TYPE_DONT_USE_TYPEOF +#endif +#ifdef __IBMCPP__ +# define BOOST_COMMON_TYPE_DONT_USE_TYPEOF +#endif + +//----------------------------------------------------------------------------// +#if defined(BOOST_NO_VARIADIC_TEMPLATES) +#define BOOST_COMMON_TYPE_ARITY 3 +#endif + +//----------------------------------------------------------------------------// +#if defined(BOOST_NO_DECLTYPE) && !defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF) +#define BOOST_TYPEOF_SILENT +#include <boost/typeof/typeof.hpp> // boost wonders never cease! +#endif + +//----------------------------------------------------------------------------// +#ifndef BOOST_NO_STATIC_ASSERT +#define BOOST_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) static_assert(CND,MSG) +#elif defined(BOOST_COMMON_TYPE_USES_MPL_ASSERT) +#include <boost/mpl/assert.hpp> +#include <boost/mpl/bool.hpp> +#define BOOST_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) \ + BOOST_MPL_ASSERT_MSG(boost::mpl::bool_< (CND) >::type::value, MSG, TYPES) +#else +#include <boost/static_assert.hpp> +#define BOOST_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) BOOST_STATIC_ASSERT(CND) +#endif + +#if !defined(BOOST_NO_STATIC_ASSERT) || !defined(BOOST_COMMON_TYPE_USES_MPL_ASSERT) +#define BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE "must be complete type" +#endif + +#if defined(BOOST_NO_DECLTYPE) && defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF) +#include <boost/type_traits/detail/common_type_imp.hpp> +#include <boost/type_traits/remove_cv.hpp> +#endif +#include <boost/mpl/if.hpp> +#include <boost/utility/declval.hpp> +#include <boost/type_traits/add_rvalue_reference.hpp> + +//----------------------------------------------------------------------------// +// // +// C++03 implementation of // +// 20.6.7 Other transformations [meta.trans.other] // +// Written by Howard Hinnant // +// Adapted for Boost by Beman Dawes, Vicente Botet and Jeffrey Hellrung // +// // +//----------------------------------------------------------------------------// + +namespace boost { + +// prototype +#if !defined(BOOST_NO_VARIADIC_TEMPLATES) + template<typename... T> + struct common_type; +#else // or no specialization + template <class T, class U = void, class V = void> + struct common_type + { + public: + typedef typename common_type<typename common_type<T, U>::type, V>::type type; + }; +#endif + + +// 1 arg + template<typename T> +#if !defined(BOOST_NO_VARIADIC_TEMPLATES) + struct common_type<T> +#else + struct common_type<T, void, void> + +#endif + { + BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T)); + public: + typedef T type; + }; + +// 2 args +namespace type_traits_detail { + + template <class T, class U> + struct common_type_2 + { + private: + BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T)); + BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(U) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (U)); + static bool declval_bool(); // workaround gcc bug; not required by std + static typename add_rvalue_reference<T>::type declval_T(); // workaround gcc bug; not required by std + static typename add_rvalue_reference<U>::type declval_U(); // workaround gcc bug; not required by std + static typename add_rvalue_reference<bool>::type declval_b(); + +#if !defined(BOOST_NO_DECLTYPE) + public: + typedef decltype(declval<bool>() ? declval<T>() : declval<U>()) type; +#elif defined(BOOST_COMMON_TYPE_DONT_USE_TYPEOF) + public: + typedef typename detail_type_traits_common_type::common_type_impl< + typename remove_cv<T>::type, + typename remove_cv<U>::type + >::type type; +#else + public: + typedef BOOST_TYPEOF_TPL(declval_b() ? declval_T() : declval_U()) type; +#endif + }; + + template <class T> + struct common_type_2<T, T> + { + typedef T type; + }; + } + +#if !defined(BOOST_NO_VARIADIC_TEMPLATES) + template <class T, class U> + struct common_type<T, U> +#else + template <class T, class U> + struct common_type<T, U, void> +#endif + : type_traits_detail::common_type_2<T,U> + { }; + + +// 3 or more args +#if !defined(BOOST_NO_VARIADIC_TEMPLATES) + template<typename T, typename U, typename... V> + struct common_type<T, U, V...> { + public: + typedef typename common_type<typename common_type<T, U>::type, V...>::type type; + }; +#endif +} // namespace boost + +#endif // BOOST_TYPE_TRAITS_COMMON_TYPE_HPP diff --git a/3rdParty/Boost/src/boost/type_traits/conditional.hpp b/3rdParty/Boost/src/boost/type_traits/conditional.hpp new file mode 100644 index 0000000..8bbda85 --- /dev/null +++ b/3rdParty/Boost/src/boost/type_traits/conditional.hpp @@ -0,0 +1,25 @@ + +// (C) Copyright John Maddock 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/type_traits for most recent version including documentation. + + +#ifndef BOOST_TT_CONDITIONAL_HPP_INCLUDED +#define BOOST_TT_CONDITIONAL_HPP_INCLUDED + +#include <boost/mpl/if.hpp> + +namespace boost { + +template <bool b, class T, class U> +struct conditional : public mpl::if_c<b, T, U> +{ +}; + +} // namespace boost + + +#endif // BOOST_TT_CONDITIONAL_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/type_traits/detail/common_type_imp.hpp b/3rdParty/Boost/src/boost/type_traits/detail/common_type_imp.hpp new file mode 100644 index 0000000..9e06282 --- /dev/null +++ b/3rdParty/Boost/src/boost/type_traits/detail/common_type_imp.hpp @@ -0,0 +1,302 @@ +/******************************************************************************* + * boost/type_traits/detail/common_type_imp.hpp + * + * Copyright 2010, Jeffrey Hellrung. + * 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) + * + * struct boost::common_type<T,U> + * + * common_type<T,U>::type is the type of the expression + * b() ? x() : y() + * where b() returns a bool, x() has return type T, and y() has return type U. + * See + * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm#common_type + * + * Note that this evaluates to void if one or both of T and U is void. + ******************************************************************************/ + +#ifndef BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMP_HPP +#define BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_IMP_HPP + +#include <cstddef> + +#include <boost/mpl/assert.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/begin_end.hpp> +#include <boost/mpl/contains.hpp> +#include <boost/mpl/copy.hpp> +#include <boost/mpl/deref.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/inserter.hpp> +#include <boost/mpl/next.hpp> +#include <boost/mpl/or.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/push_back.hpp> +#include <boost/mpl/size.hpp> +#include <boost/mpl/vector/vector0.hpp> +#include <boost/mpl/vector/vector10.hpp> +#include <boost/type_traits/integral_constant.hpp> +#include <boost/type_traits/is_enum.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/type_traits/make_signed.hpp> +#include <boost/type_traits/make_unsigned.hpp> +#include <boost/type_traits/remove_cv.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/utility/declval.hpp> + +namespace boost +{ + +namespace detail_type_traits_common_type +{ + +/******************************************************************************* + * struct propagate_cv< From, To > + * + * This metafunction propagates cv-qualifiers on type From to type To. + ******************************************************************************/ + +template< class From, class To > +struct propagate_cv +{ typedef To type; }; +template< class From, class To > +struct propagate_cv< const From, To > +{ typedef To const type; }; +template< class From, class To > +struct propagate_cv< volatile From, To > +{ typedef To volatile type; }; +template< class From, class To > +struct propagate_cv< const volatile From, To > +{ typedef To const volatile type; }; + +/******************************************************************************* + * struct is_signable_integral<T> + * + * This metafunction determines if T is an integral type which can be made + * signed or unsigned. + ******************************************************************************/ + +template< class T > +struct is_signable_integral + : mpl::or_< is_integral<T>, is_enum<T> > +{ }; +template<> +struct is_signable_integral< bool > + : false_type +{ }; + +/******************************************************************************* + * struct sizeof_t<N> + * typedef ... yes_type + * typedef ... no_type + * + * These types are integral players in the use of the "sizeof trick", i.e., we + * can distinguish overload selection by inspecting the size of the return type + * of the overload. + ******************************************************************************/ + +template< std::size_t N > struct sizeof_t { char _dummy[N]; }; +typedef sizeof_t<1> yes_type; +typedef sizeof_t<2> no_type; +BOOST_MPL_ASSERT_RELATION( sizeof( yes_type ), ==, 1 ); +BOOST_MPL_ASSERT_RELATION( sizeof( no_type ), ==, 2 ); + +/******************************************************************************* + * rvalue_test(T&) -> no_type + * rvalue_test(...) -> yes_type + * + * These overloads are used to determine the rvalue-ness of an expression. + ******************************************************************************/ + +template< class T > no_type rvalue_test(T&); +yes_type rvalue_test(...); + +/******************************************************************************* + * struct conversion_test_overloads< Sequence > + * + * This struct has multiple overloads of the static member function apply, each + * one taking a single parameter of a type within the Boost.MPL sequence + * Sequence. Each such apply overload has a return type with sizeof equal to + * one plus the index of the parameter type within Sequence. Thus, we can + * deduce the type T of an expression as long as we can generate a finite set of + * candidate types containing T via these apply overloads and the "sizeof + * trick". + ******************************************************************************/ + +template< class First, class Last, std::size_t Index > +struct conversion_test_overloads_iterate + : conversion_test_overloads_iterate< + typename mpl::next< First >::type, Last, Index + 1 + > +{ + using conversion_test_overloads_iterate< + typename mpl::next< First >::type, Last, Index + 1 + >::apply; + static sizeof_t< Index + 1 > + apply(typename mpl::deref< First >::type); +}; + +template< class Last, std::size_t Index > +struct conversion_test_overloads_iterate< Last, Last, Index > +{ static sizeof_t< Index + 1 > apply(...); }; + +template< class Sequence > +struct conversion_test_overloads + : conversion_test_overloads_iterate< + typename mpl::begin< Sequence >::type, + typename mpl::end< Sequence >::type, + 0 + > +{ }; + +/******************************************************************************* + * struct select< Sequence, Index > + * + * select is synonymous with mpl::at_c unless Index equals the size of the + * Boost.MPL Sequence, in which case this evaluates to void. + ******************************************************************************/ + +template< + class Sequence, int Index, + int N = mpl::size< Sequence >::value +> +struct select + : mpl::at_c< Sequence, Index > +{ }; +template< class Sequence, int N > +struct select< Sequence, N, N > +{ typedef void type; }; + +/******************************************************************************* + * class deduce_common_type< T, U, NominalCandidates > + * struct nominal_candidates<T,U> + * struct common_type_dispatch_on_rvalueness<T,U> + * struct common_type_impl<T,U> + * + * These classes and structs implement the logic behind common_type, which goes + * roughly as follows. Let C be the type of the conditional expression + * declval< bool >() ? declval<T>() : declval<U>() + * if C is an rvalue, then: + * let T' and U' be T and U stripped of reference- and cv-qualifiers + * if T' and U' are pointer types, say, T' = V* and U' = W*, then: + * define the set of NominalCandidates to be + * { V*, W*, V'*, W'* } + * where V' is V with whatever cv-qualifiers are on W, and W' is W + * with whatever cv-qualifiers are on V + * else T' and U' are both "signable integral types" (integral and enum + * types excepting bool), then: + * define the set of NominalCandidates to be + * { unsigned(T'), unsigned(U'), signed(T'), signed(U') } + * where unsigned(X) is make_unsigned<X>::type and signed(X) is + * make_signed<X>::type + * else + * define the set of NominalCandidates to be + * { T', U' } + * else + * let V and W be T and U stripped of reference-qualifiers + * define the set of NominalCandidates to be + * { V&, W&, V'&, W'& } + * where V' is V with whatever cv-qualifiers are on W, and W' is W with + * whatever cv-qualifiers are on V + * define the set of Candidates to be equal to the set of NominalCandidates with + * duplicates removed, and use this set of Candidates to determine C using the + * conversion_test_overloads struct + ******************************************************************************/ + +template< class T, class U, class NominalCandidates > +class deduce_common_type +{ + typedef typename mpl::copy< + NominalCandidates, + mpl::inserter< + mpl::vector0<>, + mpl::if_< + mpl::contains< mpl::_1, mpl::_2 >, + mpl::_1, + mpl::push_back< mpl::_1, mpl::_2 > + > + > + >::type candidate_types; + static const int best_candidate_index = + sizeof( conversion_test_overloads< candidate_types >::apply( + declval< bool >() ? declval<T>() : declval<U>() + ) ) - 1; +public: + typedef typename select< candidate_types, best_candidate_index >::type type; +}; + +template< + class T, class U, + class V = typename remove_cv< typename remove_reference<T>::type >::type, + class W = typename remove_cv< typename remove_reference<U>::type >::type, + bool = is_signable_integral<V>::value && is_signable_integral<W>::value +> +struct nominal_candidates; + +template< class T, class U, class V, class W > +struct nominal_candidates< T, U, V, W, false > +{ typedef mpl::vector2<V,W> type; }; + +template< class T, class U, class V, class W > +struct nominal_candidates< T, U, V, W, true > +{ + typedef mpl::vector4< + typename make_unsigned<V>::type, + typename make_unsigned<W>::type, + typename make_signed<V>::type, + typename make_signed<W>::type + > type; +}; + +template< class T, class U, class V, class W > +struct nominal_candidates< T, U, V*, W*, false > +{ + typedef mpl::vector4< + V*, W*, + typename propagate_cv<W,V>::type *, + typename propagate_cv<V,W>::type * + > type; +}; + +template<class T, class U, bool b> +struct common_type_dispatch_on_rvalueness + : deduce_common_type< T, U, typename nominal_candidates<T,U>::type > +{ }; + +template< class T, class U > +struct common_type_dispatch_on_rvalueness< T, U, false > +{ +private: + typedef typename remove_reference<T>::type unrefed_T_type; + typedef typename remove_reference<U>::type unrefed_U_type; +public: + typedef typename deduce_common_type< + T, U, + mpl::vector4< + unrefed_T_type &, + unrefed_U_type &, + typename propagate_cv< unrefed_U_type, unrefed_T_type >::type &, + typename propagate_cv< unrefed_T_type, unrefed_U_type >::type & + > + >::type type; +}; + +template< class T, class U > +struct common_type_impl + : common_type_dispatch_on_rvalueness<T,U, sizeof( ::boost::detail_type_traits_common_type::rvalue_test( + declval< bool >() ? declval<T>() : declval<U>() ) ) == sizeof( yes_type ) > +{ }; + +template< class T > struct common_type_impl< T, void > { typedef void type; }; +template< class T > struct common_type_impl< void, T > { typedef void type; }; +template<> struct common_type_impl< void, void > { typedef void type; }; + +} // namespace detail_type_traits_common_type + + +} // namespace boost + +#endif // BOOST_TYPE_TRAITS_DETAIL_COMMON_TYPE_HPP + diff --git a/3rdParty/Boost/src/boost/type_traits/function_traits.hpp b/3rdParty/Boost/src/boost/type_traits/function_traits.hpp index bfc3f7e..6d708cd 100644 --- a/3rdParty/Boost/src/boost/type_traits/function_traits.hpp +++ b/3rdParty/Boost/src/boost/type_traits/function_traits.hpp @@ -166,7 +166,7 @@ struct function_traits_helper<R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> template<typename Function> struct function_traits : - public detail::function_traits_helper<typename boost::add_pointer<Function>::type> + public boost::detail::function_traits_helper<typename boost::add_pointer<Function>::type> { }; @@ -227,7 +227,7 @@ type_of_size<11> function_arity_helper(R (*f)(T1, T2, T3, T4, T5, T6, T7, T8, template<typename Function> struct function_traits { - BOOST_STATIC_CONSTANT(unsigned, arity = (sizeof(detail::function_arity_helper((Function*)0))-1)); + BOOST_STATIC_CONSTANT(unsigned, arity = (sizeof(boost::detail::function_arity_helper((Function*)0))-1)); }; #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION diff --git a/3rdParty/Boost/src/boost/type_traits/has_new_operator.hpp b/3rdParty/Boost/src/boost/type_traits/has_new_operator.hpp new file mode 100644 index 0000000..2c2c322 --- /dev/null +++ b/3rdParty/Boost/src/boost/type_traits/has_new_operator.hpp @@ -0,0 +1,140 @@ + +// (C) Copyright Runar Undheim, Robert Ramey & John Maddock 2008. +// 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/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_HAS_NEW_OPERATOR_HPP_INCLUDED +#define BOOST_TT_HAS_NEW_OPERATOR_HPP_INCLUDED + +#include <new> // std::nothrow_t +#include <cstddef> // std::size_t +#include <boost/type_traits/config.hpp> +#include <boost/type_traits/detail/yes_no_type.hpp> +#include <boost/type_traits/detail/ice_or.hpp> + +// should be the last #include +#include <boost/type_traits/detail/bool_trait_def.hpp> + +namespace boost { +namespace detail { + template <class U, U x> + struct test; + + template <typename T> + struct has_new_operator_impl { + template<class U> + static type_traits::yes_type check_sig1( + U*, + test< + void *(*)(std::size_t), + &U::operator new + >* = NULL + ); + template<class U> + static type_traits::no_type check_sig1(...); + + template<class U> + static type_traits::yes_type check_sig2( + U*, + test< + void *(*)(std::size_t, const std::nothrow_t&), + &U::operator new + >* = NULL + ); + template<class U> + static type_traits::no_type check_sig2(...); + + template<class U> + static type_traits::yes_type check_sig3( + U*, + test< + void *(*)(std::size_t, void*), + &U::operator new + >* = NULL + ); + template<class U> + static type_traits::no_type check_sig3(...); + + + template<class U> + static type_traits::yes_type check_sig4( + U*, + test< + void *(*)(std::size_t), + &U::operator new[] + >* = NULL + ); + template<class U> + static type_traits::no_type check_sig4(...); + + template<class U> + static type_traits::yes_type check_sig5( + U*, + test< + void *(*)(std::size_t, const std::nothrow_t&), + &U::operator new[] + >* = NULL + ); + template<class U> + static type_traits::no_type check_sig5(...); + + template<class U> + static type_traits::yes_type check_sig6( + U*, + test< + void *(*)(std::size_t, void*), + &U::operator new[] + >* = NULL + ); + template<class U> + static type_traits::no_type check_sig6(...); + + // GCC2 won't even parse this template if we embed the computation + // of s1 in the computation of value. + #ifdef __GNUC__ + BOOST_STATIC_CONSTANT(unsigned, s1 = sizeof(has_new_operator_impl<T>::template check_sig1<T>(0))); + BOOST_STATIC_CONSTANT(unsigned, s2 = sizeof(has_new_operator_impl<T>::template check_sig2<T>(0))); + BOOST_STATIC_CONSTANT(unsigned, s3 = sizeof(has_new_operator_impl<T>::template check_sig3<T>(0))); + BOOST_STATIC_CONSTANT(unsigned, s4 = sizeof(has_new_operator_impl<T>::template check_sig4<T>(0))); + BOOST_STATIC_CONSTANT(unsigned, s5 = sizeof(has_new_operator_impl<T>::template check_sig5<T>(0))); + BOOST_STATIC_CONSTANT(unsigned, s6 = sizeof(has_new_operator_impl<T>::template check_sig6<T>(0))); + #else + #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) + #pragma warning(push) + #pragma warning(disable:6334) + #endif + + BOOST_STATIC_CONSTANT(unsigned, s1 = sizeof(check_sig1<T>(0))); + BOOST_STATIC_CONSTANT(unsigned, s2 = sizeof(check_sig2<T>(0))); + BOOST_STATIC_CONSTANT(unsigned, s3 = sizeof(check_sig3<T>(0))); + BOOST_STATIC_CONSTANT(unsigned, s4 = sizeof(check_sig4<T>(0))); + BOOST_STATIC_CONSTANT(unsigned, s5 = sizeof(check_sig5<T>(0))); + BOOST_STATIC_CONSTANT(unsigned, s6 = sizeof(check_sig6<T>(0))); + + #if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) + #pragma warning(pop) + #endif + #endif + BOOST_STATIC_CONSTANT(bool, value = + (::boost::type_traits::ice_or< + (s1 == sizeof(type_traits::yes_type)), + (s2 == sizeof(type_traits::yes_type)), + (s3 == sizeof(type_traits::yes_type)), + (s4 == sizeof(type_traits::yes_type)), + (s5 == sizeof(type_traits::yes_type)), + (s6 == sizeof(type_traits::yes_type)) + >::value) + ); + }; +} // namespace detail + +BOOST_TT_AUX_BOOL_TRAIT_DEF1(has_new_operator,T,::boost::detail::has_new_operator_impl<T>::value) + +} // namespace boost + +#include <boost/type_traits/detail/bool_trait_undef.hpp> + +#endif // BOOST_TT_HAS_NEW_OPERATOR_HPP_INCLUDED diff --git a/3rdParty/Boost/src/boost/type_traits/intrinsics.hpp b/3rdParty/Boost/src/boost/type_traits/intrinsics.hpp index 8f88036..9666456 100644 --- a/3rdParty/Boost/src/boost/type_traits/intrinsics.hpp +++ b/3rdParty/Boost/src/boost/type_traits/intrinsics.hpp @@ -159,6 +159,33 @@ # define BOOST_HAS_TYPE_TRAITS_INTRINSICS #endif +#if defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600) +# include <boost/type_traits/is_same.hpp> +# include <boost/type_traits/is_reference.hpp> +# include <boost/type_traits/is_volatile.hpp> + +# define BOOST_IS_UNION(T) __is_union(T) +# define BOOST_IS_POD(T) __is_pod(T) +# define BOOST_IS_EMPTY(T) __is_empty(T) +# define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) +# define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) && !is_reference<T>::value) +# define BOOST_HAS_TRIVIAL_ASSIGN(T) __has_trivial_assign(T) +# define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T) +# define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T) +# define BOOST_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T) && !is_volatile<T>::value && !is_reference<T>::value) +# define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) && !is_volatile<T>::value) +# define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) + +# define BOOST_IS_ABSTRACT(T) __is_abstract(T) +# define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same<T,U>::value) +# define BOOST_IS_CLASS(T) __is_class(T) +# define BOOST_IS_ENUM(T) __is_enum(T) +# define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) +# define BOOST_ALIGNMENT_OF(T) __alignof__(T) + +# define BOOST_HAS_TYPE_TRAITS_INTRINSICS +#endif + # if defined(__CODEGEARC__) # include <boost/type_traits/is_same.hpp> # include <boost/type_traits/is_reference.hpp> diff --git a/3rdParty/Boost/src/boost/type_traits/is_complex.hpp b/3rdParty/Boost/src/boost/type_traits/is_complex.hpp index 9ccc333..0813dac 100644 --- a/3rdParty/Boost/src/boost/type_traits/is_complex.hpp +++ b/3rdParty/Boost/src/boost/type_traits/is_complex.hpp @@ -25,7 +25,7 @@ struct is_convertible_from_tester } -BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_complex,T,(::boost::is_convertible<T, detail::is_convertible_from_tester>::value)) +BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_complex,T,(::boost::is_convertible<T, boost::detail::is_convertible_from_tester>::value)) } // namespace boost diff --git a/3rdParty/Boost/src/boost/type_traits/is_const.hpp b/3rdParty/Boost/src/boost/type_traits/is_const.hpp index e66d18a..812ed15 100644 --- a/3rdParty/Boost/src/boost/type_traits/is_const.hpp +++ b/3rdParty/Boost/src/boost/type_traits/is_const.hpp @@ -50,12 +50,31 @@ BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_const,T,__is_const(T)) #elif !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) -//* is a type T declared const - is_const<T> +namespace detail{ +// +// We can't filter out rvalue_references at the same level as +// references or we get ambiguities from msvc: +// +template <class T> +struct is_const_rvalue_filter +{ #if BOOST_WORKAROUND(BOOST_MSVC, < 1400) - BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_const,T,::boost::detail::cv_traits_imp<typename remove_bounds<T>::type*>::is_const) + BOOST_STATIC_CONSTANT(bool, value = ::boost::detail::cv_traits_imp<typename boost::remove_bounds<T>::type*>::is_const); #else - BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_const,T,::boost::detail::cv_traits_imp<T*>::is_const) + BOOST_STATIC_CONSTANT(bool, value = ::boost::detail::cv_traits_imp<T*>::is_const); +#endif +}; +#ifndef BOOST_NO_RVALUE_REFERENCES +template <class T> +struct is_const_rvalue_filter<T&&> +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; #endif +} + +//* is a type T declared const - is_const<T> +BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_const,T,::boost::detail::is_const_rvalue_filter<T>::value) BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_const,T&,false) #if defined(BOOST_ILLEGAL_CV_REFERENCES) @@ -98,7 +117,7 @@ struct is_const_helper<false,false> { static T* t; BOOST_STATIC_CONSTANT(bool, value = ( - sizeof(detail::yes_type) == sizeof(detail::is_const_tester(t)) + sizeof(boost::detail::yes_type) == sizeof(boost::detail::is_const_tester(t)) )); }; }; @@ -110,7 +129,7 @@ struct is_const_helper<false,true> { static T t; BOOST_STATIC_CONSTANT(bool, value = ( - sizeof(detail::yes_type) == sizeof(detail::is_const_tester(&t)) + sizeof(boost::detail::yes_type) == sizeof(boost::detail::is_const_tester(&t)) )); }; }; diff --git a/3rdParty/Boost/src/boost/type_traits/is_convertible.hpp b/3rdParty/Boost/src/boost/type_traits/is_convertible.hpp index a31a930..c05c297 100644 --- a/3rdParty/Boost/src/boost/type_traits/is_convertible.hpp +++ b/3rdParty/Boost/src/boost/type_traits/is_convertible.hpp @@ -132,7 +132,7 @@ template <typename From, typename To> struct is_convertible_basic_impl { static From _m_from; - static bool const value = sizeof( detail::checker<To>::_m_check(_m_from, 0) ) + static bool const value = sizeof( boost::detail::checker<To>::_m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type); }; diff --git a/3rdParty/Boost/src/boost/type_traits/is_function.hpp b/3rdParty/Boost/src/boost/type_traits/is_function.hpp index 95dba0d..55c05c1 100644 --- a/3rdParty/Boost/src/boost/type_traits/is_function.hpp +++ b/3rdParty/Boost/src/boost/type_traits/is_function.hpp @@ -95,6 +95,9 @@ struct is_function_impl<T&> : public false_type BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_function,T,__is_function(T)) #else BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_function,T,::boost::detail::is_function_impl<T>::value) +#ifndef BOOST_NO_RVALUE_REFERENCES +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_function,T&&,false) +#endif #endif } // namespace boost diff --git a/3rdParty/Boost/src/boost/type_traits/is_lvalue_reference.hpp b/3rdParty/Boost/src/boost/type_traits/is_lvalue_reference.hpp new file mode 100644 index 0000000..a6af859 --- /dev/null +++ b/3rdParty/Boost/src/boost/type_traits/is_lvalue_reference.hpp @@ -0,0 +1,118 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, +// Howard Hinnant and John Maddock 2000. +// (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 + +// 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/type_traits for most recent version including documentation. + +// Fixed is_pointer, is_lvalue_reference, is_const, is_volatile, is_same, +// is_member_pointer based on the Simulated Partial Specialization work +// of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or +// http://groups.yahoo.com/group/boost/message/5441 +// Some workarounds in here use ideas suggested from "Generic<Programming>: +// Mappings between Types and Values" +// by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). + + +#ifndef BOOST_TT_IS_LVALUE_REFERENCE_HPP_INCLUDED +#define BOOST_TT_IS_LVALUE_REFERENCE_HPP_INCLUDED + +#include <boost/type_traits/config.hpp> + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# include <boost/type_traits/detail/yes_no_type.hpp> +# include <boost/type_traits/detail/wrap.hpp> +#endif + +// should be the last #include +#include <boost/type_traits/detail/bool_trait_def.hpp> + +namespace boost { + +#if defined( __CODEGEARC__ ) +BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_lvalue_reference,T,__is_reference(T)) +#elif !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_lvalue_reference,T,false) +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_lvalue_reference,T&,true) + +#if defined(BOOST_ILLEGAL_CV_REFERENCES) +// these are illegal specialisations; cv-qualifies applied to +// references have no effect according to [8.3.2p1], +// C++ Builder requires them though as it treats cv-qualified +// references as distinct types... +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_lvalue_reference,T& const,true) +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_lvalue_reference,T& volatile,true) +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_lvalue_reference,T& const volatile,true) +#endif + +#if defined(__GNUC__) && (__GNUC__ < 3) +// these allow us to work around illegally cv-qualified reference +// types. +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_lvalue_reference,T const ,::boost::is_lvalue_reference<T>::value) +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_lvalue_reference,T volatile ,::boost::is_lvalue_reference<T>::value) +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_lvalue_reference,T const volatile ,::boost::is_lvalue_reference<T>::value) +// However, the above specializations confuse gcc 2.96 unless we also +// supply these specializations for array types +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_2(typename T,unsigned long N,is_lvalue_reference,T[N],false) +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_2(typename T,unsigned long N,is_lvalue_reference,const T[N],false) +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_2(typename T,unsigned long N,is_lvalue_reference,volatile T[N],false) +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_2(typename T,unsigned long N,is_lvalue_reference,const volatile T[N],false) +#endif + +#else + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable: 4181 4097) +#endif + +namespace detail { + +using ::boost::type_traits::yes_type; +using ::boost::type_traits::no_type; +using ::boost::type_traits::wrap; + +template <class T> T&(* is_lvalue_reference_helper1(wrap<T>) )(wrap<T>); +char is_lvalue_reference_helper1(...); + +template <class T> no_type is_lvalue_reference_helper2(T&(*)(wrap<T>)); +yes_type is_lvalue_reference_helper2(...); + +template <typename T> +struct is_lvalue_reference_impl +{ + BOOST_STATIC_CONSTANT( + bool, value = sizeof( + ::boost::detail::is_lvalue_reference_helper2( + ::boost::detail::is_lvalue_reference_helper1(::boost::type_traits::wrap<T>()))) == 1 + ); +}; + +BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_lvalue_reference,void,false) +#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS +BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_lvalue_reference,void const,false) +BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_lvalue_reference,void volatile,false) +BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_lvalue_reference,void const volatile,false) +#endif + +} // namespace detail + +BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_lvalue_reference,T,::boost::detail::is_lvalue_reference_impl<T>::value) + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +} // namespace boost + +#include <boost/type_traits/detail/bool_trait_undef.hpp> + +#endif // BOOST_TT_IS_REFERENCE_HPP_INCLUDED + diff --git a/3rdParty/Boost/src/boost/type_traits/is_reference.hpp b/3rdParty/Boost/src/boost/type_traits/is_reference.hpp index dcf84db..49b5f9f 100644 --- a/3rdParty/Boost/src/boost/type_traits/is_reference.hpp +++ b/3rdParty/Boost/src/boost/type_traits/is_reference.hpp @@ -1,6 +1,6 @@ // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, -// Howard Hinnant and John Maddock 2000. +// Howard Hinnant and John Maddock 2000, 2010. // (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 // Use, modification and distribution are subject to the Boost Software License, @@ -9,107 +9,34 @@ // // See http://www.boost.org/libs/type_traits for most recent version including documentation. -// Fixed is_pointer, is_reference, is_const, is_volatile, is_same, -// is_member_pointer based on the Simulated Partial Specialization work -// of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or -// http://groups.yahoo.com/group/boost/message/5441 -// Some workarounds in here use ideas suggested from "Generic<Programming>: -// Mappings between Types and Values" -// by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). - - #ifndef BOOST_TT_IS_REFERENCE_HPP_INCLUDED #define BOOST_TT_IS_REFERENCE_HPP_INCLUDED #include <boost/type_traits/config.hpp> - -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -# include <boost/type_traits/detail/yes_no_type.hpp> -# include <boost/type_traits/detail/wrap.hpp> -#endif +#include <boost/type_traits/is_lvalue_reference.hpp> +#include <boost/type_traits/is_rvalue_reference.hpp> +#include <boost/type_traits/ice.hpp> // should be the last #include #include <boost/type_traits/detail/bool_trait_def.hpp> namespace boost { -#if defined( __CODEGEARC__ ) -BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_reference,T,__is_reference(T)) -#elif !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - -BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_reference,T,false) -BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_reference,T&,true) - -#if defined(BOOST_ILLEGAL_CV_REFERENCES) -// these are illegal specialisations; cv-qualifies applied to -// references have no effect according to [8.3.2p1], -// C++ Builder requires them though as it treats cv-qualified -// references as distinct types... -BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_reference,T& const,true) -BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_reference,T& volatile,true) -BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_reference,T& const volatile,true) -#endif - -#if defined(__GNUC__) && (__GNUC__ < 3) -// these allow us to work around illegally cv-qualified reference -// types. -BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_reference,T const ,::boost::is_reference<T>::value) -BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_reference,T volatile ,::boost::is_reference<T>::value) -BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_reference,T const volatile ,::boost::is_reference<T>::value) -// However, the above specializations confuse gcc 2.96 unless we also -// supply these specializations for array types -BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_2(typename T,unsigned long N,is_reference,T[N],false) -BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_2(typename T,unsigned long N,is_reference,const T[N],false) -BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_2(typename T,unsigned long N,is_reference,volatile T[N],false) -BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_2(typename T,unsigned long N,is_reference,const volatile T[N],false) -#endif - -#else - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable: 4181 4097) -#endif - namespace detail { -using ::boost::type_traits::yes_type; -using ::boost::type_traits::no_type; -using ::boost::type_traits::wrap; - -template <class T> T&(* is_reference_helper1(wrap<T>) )(wrap<T>); -char is_reference_helper1(...); - -template <class T> no_type is_reference_helper2(T&(*)(wrap<T>)); -yes_type is_reference_helper2(...); - template <typename T> struct is_reference_impl { - BOOST_STATIC_CONSTANT( - bool, value = sizeof( - ::boost::detail::is_reference_helper2( - ::boost::detail::is_reference_helper1(::boost::type_traits::wrap<T>()))) == 1 - ); + BOOST_STATIC_CONSTANT(bool, value = + (::boost::type_traits::ice_or< + ::boost::is_lvalue_reference<T>::value, ::boost::is_rvalue_reference<T>::value + >::value)); }; -BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_reference,void,false) -#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS -BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_reference,void const,false) -BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_reference,void volatile,false) -BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_reference,void const volatile,false) -#endif - } // namespace detail BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_reference,T,::boost::detail::is_reference_impl<T>::value) -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - } // namespace boost #include <boost/type_traits/detail/bool_trait_undef.hpp> diff --git a/3rdParty/Boost/src/boost/type_traits/is_rvalue_reference.hpp b/3rdParty/Boost/src/boost/type_traits/is_rvalue_reference.hpp new file mode 100644 index 0000000..cac2ee0 --- /dev/null +++ b/3rdParty/Boost/src/boost/type_traits/is_rvalue_reference.hpp @@ -0,0 +1,29 @@ + +// (C) John Maddock 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/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_RVALUE_REFERENCE_HPP_INCLUDED +#define BOOST_TT_IS_RVALUE_REFERENCE_HPP_INCLUDED + +#include <boost/type_traits/config.hpp> + +// should be the last #include +#include <boost/type_traits/detail/bool_trait_def.hpp> + +namespace boost { + +BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_rvalue_reference,T,false) +#ifndef BOOST_NO_RVALUE_REFERENCES +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_rvalue_reference,T&&,true) +#endif + +} // namespace boost + +#include <boost/type_traits/detail/bool_trait_undef.hpp> + +#endif // BOOST_TT_IS_REFERENCE_HPP_INCLUDED + diff --git a/3rdParty/Boost/src/boost/type_traits/is_same.hpp b/3rdParty/Boost/src/boost/type_traits/is_same.hpp index e0d1808..c6afbd7 100644 --- a/3rdParty/Boost/src/boost/type_traits/is_same.hpp +++ b/3rdParty/Boost/src/boost/type_traits/is_same.hpp @@ -61,7 +61,7 @@ struct is_same_part_1 template< typename T1, typename T2 > struct is_same_impl { - enum { value = detail::is_same_part_1<T1>::template part_2<T2>::value }; + enum { value = boost::detail::is_same_part_1<T1>::template part_2<T2>::value }; }; #else // generic "no-partial-specialization" version @@ -81,7 +81,7 @@ struct is_same_impl BOOST_STATIC_CONSTANT(bool, value = (::boost::type_traits::ice_and< - (sizeof(type_traits::yes_type) == sizeof(detail::is_same_tester(&t,&u))), + (sizeof(type_traits::yes_type) == sizeof(boost::detail::is_same_tester(&t,&u))), (::boost::is_reference<T>::value == ::boost::is_reference<U>::value), (sizeof(T) == sizeof(U)) >::value)); diff --git a/3rdParty/Boost/src/boost/type_traits/is_signed.hpp b/3rdParty/Boost/src/boost/type_traits/is_signed.hpp index bf7bbfd..ba7d6e9 100644 --- a/3rdParty/Boost/src/boost/type_traits/is_signed.hpp +++ b/3rdParty/Boost/src/boost/type_traits/is_signed.hpp @@ -24,14 +24,19 @@ namespace boost { namespace detail{ -#if !(defined(__EDG_VERSION__) && __EDG_VERSION__ <= 238) +#if !(defined(__EDG_VERSION__) && __EDG_VERSION__ <= 238) && !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) template <class T> struct is_signed_values { + // + // Note that we cannot use BOOST_STATIC_CONSTANT here, using enum's + // rather than "real" static constants simply doesn't work or give + // the correct answer. + // typedef typename remove_cv<T>::type no_cv_t; - BOOST_STATIC_CONSTANT(no_cv_t, minus_one = (static_cast<no_cv_t>(-1))); - BOOST_STATIC_CONSTANT(no_cv_t, zero = (static_cast<no_cv_t>(0))); + static const no_cv_t minus_one = (static_cast<no_cv_t>(-1)); + static const no_cv_t zero = (static_cast<no_cv_t>(0)); }; template <class T> diff --git a/3rdParty/Boost/src/boost/type_traits/is_unsigned.hpp b/3rdParty/Boost/src/boost/type_traits/is_unsigned.hpp index 98baf4e..d8e5a89 100644 --- a/3rdParty/Boost/src/boost/type_traits/is_unsigned.hpp +++ b/3rdParty/Boost/src/boost/type_traits/is_unsigned.hpp @@ -24,14 +24,19 @@ namespace boost { namespace detail{ -#if !(defined(__EDG_VERSION__) && __EDG_VERSION__ <= 238) +#if !(defined(__EDG_VERSION__) && __EDG_VERSION__ <= 238) && !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) template <class T> struct is_unsigned_values { + // + // Note that we cannot use BOOST_STATIC_CONSTANT here, using enum's + // rather than "real" static constants simply doesn't work or give + // the correct answer. + // typedef typename remove_cv<T>::type no_cv_t; - BOOST_STATIC_CONSTANT(no_cv_t, minus_one = (static_cast<no_cv_t>(-1))); - BOOST_STATIC_CONSTANT(no_cv_t, zero = (static_cast<no_cv_t>(0))); + static const no_cv_t minus_one = (static_cast<no_cv_t>(-1)); + static const no_cv_t zero = (static_cast<no_cv_t>(0)); }; template <class T> diff --git a/3rdParty/Boost/src/boost/type_traits/is_virtual_base_of.hpp b/3rdParty/Boost/src/boost/type_traits/is_virtual_base_of.hpp new file mode 100644 index 0000000..98ab159 --- /dev/null +++ b/3rdParty/Boost/src/boost/type_traits/is_virtual_base_of.hpp @@ -0,0 +1,104 @@ +// (C) Copyright Daniel Frey and Robert Ramey 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/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_VIRTUAL_BASE_OF_HPP_INCLUDED +#define BOOST_TT_IS_VIRTUAL_BASE_OF_HPP_INCLUDED + +#include <boost/type_traits/is_base_of.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/and.hpp> +#include <boost/mpl/not.hpp> + +// should be the last #include +#include <boost/type_traits/detail/bool_trait_def.hpp> + +namespace boost { +namespace detail { + + +#ifdef BOOST_MSVC +#pragma warning( push ) +#pragma warning( disable : 4584 ) +#elif defined __GNUC__ +#pragma GCC system_header +#endif + +template<typename Base, typename Derived, typename tag> +struct is_virtual_base_of_impl +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template<typename Base, typename Derived> +struct is_virtual_base_of_impl<Base, Derived, mpl::true_> +{ +#ifdef __BORLANDC__ + struct boost_type_traits_internal_struct_X : public virtual Derived, public virtual Base + { + boost_type_traits_internal_struct_X(); + boost_type_traits_internal_struct_X(const boost_type_traits_internal_struct_X&); + boost_type_traits_internal_struct_X& operator=(const boost_type_traits_internal_struct_X&); + ~boost_type_traits_internal_struct_X()throw(); + }; + struct boost_type_traits_internal_struct_Y : public virtual Derived + { + boost_type_traits_internal_struct_Y(); + boost_type_traits_internal_struct_Y(const boost_type_traits_internal_struct_Y&); + boost_type_traits_internal_struct_Y& operator=(const boost_type_traits_internal_struct_Y&); + ~boost_type_traits_internal_struct_Y()throw(); + }; +#else + struct boost_type_traits_internal_struct_X : Derived, virtual Base + { + boost_type_traits_internal_struct_X(); + boost_type_traits_internal_struct_X(const boost_type_traits_internal_struct_X&); + boost_type_traits_internal_struct_X& operator=(const boost_type_traits_internal_struct_X&); + ~boost_type_traits_internal_struct_X()throw(); + }; + struct boost_type_traits_internal_struct_Y : Derived + { + boost_type_traits_internal_struct_Y(); + boost_type_traits_internal_struct_Y(const boost_type_traits_internal_struct_Y&); + boost_type_traits_internal_struct_Y& operator=(const boost_type_traits_internal_struct_Y&); + ~boost_type_traits_internal_struct_Y()throw(); + }; +#endif + BOOST_STATIC_CONSTANT(bool, value = (sizeof(boost_type_traits_internal_struct_X)==sizeof(boost_type_traits_internal_struct_Y))); +}; + +template<typename Base, typename Derived> +struct is_virtual_base_of_impl2 +{ + typedef typename mpl::and_<is_base_of<Base, Derived>, mpl::not_<is_same<Base, Derived> > >::type tag_type; + typedef is_virtual_base_of_impl<Base, Derived, tag_type> imp; + BOOST_STATIC_CONSTANT(bool, value = imp::value); +}; + +#ifdef BOOST_MSVC +#pragma warning( pop ) +#endif + +} // namespace detail + +BOOST_TT_AUX_BOOL_TRAIT_DEF2( + is_virtual_base_of + , Base + , Derived + , (::boost::detail::is_virtual_base_of_impl2<Base,Derived>::value) +) + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_2(typename Base,typename Derived,is_virtual_base_of,Base&,Derived,false) +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_2(typename Base,typename Derived,is_virtual_base_of,Base,Derived&,false) +BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_2(typename Base,typename Derived,is_virtual_base_of,Base&,Derived&,false) +#endif + +} // namespace boost + +#include <boost/type_traits/detail/bool_trait_undef.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/type_traits/is_volatile.hpp b/3rdParty/Boost/src/boost/type_traits/is_volatile.hpp index 7ab253a..e531263 100644 --- a/3rdParty/Boost/src/boost/type_traits/is_volatile.hpp +++ b/3rdParty/Boost/src/boost/type_traits/is_volatile.hpp @@ -41,16 +41,35 @@ namespace boost { +namespace detail{ +template <class T> +struct is_volatile_rval_filter +{ +#if BOOST_WORKAROUND(BOOST_MSVC, < 1400) + BOOST_STATIC_CONSTANT(bool, value = ::boost::detail::cv_traits_imp<typename boost::remove_bounds<T>::type*>::is_volatile); +#else + BOOST_STATIC_CONSTANT(bool, value = ::boost::detail::cv_traits_imp<T*>::is_volatile); +#endif +}; +#ifndef BOOST_NO_RVALUE_REFERENCES +// +// We can't filter out rvalue_references at the same level as +// references or we get ambiguities from msvc: +// +template <class T> +struct is_volatile_rval_filter<T&&> +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; +#endif +} + #if defined( __CODEGEARC__ ) BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_volatile,T,__is_volatile(T)) #elif !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) //* is a type T declared volatile - is_volatile<T> -#if BOOST_WORKAROUND(BOOST_MSVC, < 1400) - BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_volatile,T,::boost::detail::cv_traits_imp<typename boost::remove_bounds<T>::type*>::is_volatile) -#else - BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_volatile,T,::boost::detail::cv_traits_imp<T*>::is_volatile) -#endif +BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_volatile,T,::boost::detail::is_volatile_rval_filter<T>::value) BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC1_1(typename T,is_volatile,T&,false) #if defined(BOOST_ILLEGAL_CV_REFERENCES) @@ -86,7 +105,7 @@ struct is_volatile_helper<false,false> { static T* t; BOOST_STATIC_CONSTANT(bool, value = ( - sizeof(detail::yes_type) == sizeof(detail::is_volatile_tester(t)) + sizeof(boost::detail::yes_type) == sizeof(boost::detail::is_volatile_tester(t)) )); }; }; @@ -98,7 +117,7 @@ struct is_volatile_helper<false,true> { static T t; BOOST_STATIC_CONSTANT(bool, value = ( - sizeof(detail::yes_type) == sizeof(detail::is_volatile_tester(&t)) + sizeof(boost::detail::yes_type) == sizeof(boost::detail::is_volatile_tester(&t)) )); }; }; diff --git a/3rdParty/Boost/src/boost/type_traits/msvc/remove_all_extents.hpp b/3rdParty/Boost/src/boost/type_traits/msvc/remove_all_extents.hpp index 3517132..25c0edf 100644 --- a/3rdParty/Boost/src/boost/type_traits/msvc/remove_all_extents.hpp +++ b/3rdParty/Boost/src/boost/type_traits/msvc/remove_all_extents.hpp @@ -36,7 +36,7 @@ namespace boost { template<typename T> struct remove_all_extents { - typedef typename detail::remove_all_extents_impl_typeof< + typedef typename boost::detail::remove_all_extents_impl_typeof< boost::is_array<T>::value >::template inner<T,remove_all_extents<T> >::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,remove_all_extents,T) diff --git a/3rdParty/Boost/src/boost/type_traits/msvc/remove_bounds.hpp b/3rdParty/Boost/src/boost/type_traits/msvc/remove_bounds.hpp index 12a9b05..4b23b35 100644 --- a/3rdParty/Boost/src/boost/type_traits/msvc/remove_bounds.hpp +++ b/3rdParty/Boost/src/boost/type_traits/msvc/remove_bounds.hpp @@ -32,7 +32,7 @@ namespace boost { template<typename T> struct remove_bounds { - typedef typename detail::remove_bounds_impl_typeof< + typedef typename boost::detail::remove_bounds_impl_typeof< boost::is_array<T>::value >::template inner<T,remove_bounds<T> >::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,remove_bounds,T) diff --git a/3rdParty/Boost/src/boost/type_traits/msvc/remove_const.hpp b/3rdParty/Boost/src/boost/type_traits/msvc/remove_const.hpp index 5395e80..d370754 100644 --- a/3rdParty/Boost/src/boost/type_traits/msvc/remove_const.hpp +++ b/3rdParty/Boost/src/boost/type_traits/msvc/remove_const.hpp @@ -124,7 +124,7 @@ namespace boost { template<typename T> struct remove_const { - typedef detail::remove_const_impl_typeof< + typedef boost::detail::remove_const_impl_typeof< boost::is_pointer<T>::value, boost::is_array<T>::value, boost::is_const<T>::value, diff --git a/3rdParty/Boost/src/boost/type_traits/msvc/remove_cv.hpp b/3rdParty/Boost/src/boost/type_traits/msvc/remove_cv.hpp index c7b0379..9fbf8b8 100644 --- a/3rdParty/Boost/src/boost/type_traits/msvc/remove_cv.hpp +++ b/3rdParty/Boost/src/boost/type_traits/msvc/remove_cv.hpp @@ -171,7 +171,7 @@ namespace boost { template<typename T> struct remove_cv { - typedef detail::remove_cv_impl_typeof< + typedef boost::detail::remove_cv_impl_typeof< boost::is_pointer<T>::value, boost::is_array<T>::value, boost::is_const<T>::value, diff --git a/3rdParty/Boost/src/boost/type_traits/msvc/remove_extent.hpp b/3rdParty/Boost/src/boost/type_traits/msvc/remove_extent.hpp index f87ec41..c5a59ef 100644 --- a/3rdParty/Boost/src/boost/type_traits/msvc/remove_extent.hpp +++ b/3rdParty/Boost/src/boost/type_traits/msvc/remove_extent.hpp @@ -32,7 +32,7 @@ namespace boost { template<typename T> struct remove_extent { - typedef typename detail::remove_extent_impl_typeof< + typedef typename boost::detail::remove_extent_impl_typeof< boost::is_array<T>::value >::template inner<T,remove_extent<T> >::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,remove_extent,T) diff --git a/3rdParty/Boost/src/boost/type_traits/msvc/remove_pointer.hpp b/3rdParty/Boost/src/boost/type_traits/msvc/remove_pointer.hpp index 8b9b0d4..ec847f9 100644 --- a/3rdParty/Boost/src/boost/type_traits/msvc/remove_pointer.hpp +++ b/3rdParty/Boost/src/boost/type_traits/msvc/remove_pointer.hpp @@ -32,7 +32,7 @@ namespace boost { template<typename T> struct remove_pointer { - typedef typename detail::remove_pointer_impl_typeof< + typedef typename boost::detail::remove_pointer_impl_typeof< boost::is_pointer<T>::value >::template inner<T,remove_pointer<T> >::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,remove_pointer,T) diff --git a/3rdParty/Boost/src/boost/type_traits/msvc/remove_reference.hpp b/3rdParty/Boost/src/boost/type_traits/msvc/remove_reference.hpp index 367d352..f8a77d4 100644 --- a/3rdParty/Boost/src/boost/type_traits/msvc/remove_reference.hpp +++ b/3rdParty/Boost/src/boost/type_traits/msvc/remove_reference.hpp @@ -32,7 +32,7 @@ namespace boost { template<typename T> struct remove_reference { - typedef typename detail::remove_reference_impl_typeof< + typedef typename boost::detail::remove_reference_impl_typeof< boost::is_reference<T>::value >::template inner<T,remove_reference<T> >::type type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,remove_reference,T) diff --git a/3rdParty/Boost/src/boost/type_traits/msvc/remove_volatile.hpp b/3rdParty/Boost/src/boost/type_traits/msvc/remove_volatile.hpp index 3759f2a..6f9259c 100644 --- a/3rdParty/Boost/src/boost/type_traits/msvc/remove_volatile.hpp +++ b/3rdParty/Boost/src/boost/type_traits/msvc/remove_volatile.hpp @@ -124,7 +124,7 @@ namespace boost { template<typename T> struct remove_volatile { - typedef detail::remove_volatile_impl_typeof< + typedef boost::detail::remove_volatile_impl_typeof< boost::is_pointer<T>::value, boost::is_array<T>::value, boost::is_const<T>::value, diff --git a/3rdParty/Boost/src/boost/type_traits/remove_const.hpp b/3rdParty/Boost/src/boost/type_traits/remove_const.hpp index 7e18d88..f4d1739 100644 --- a/3rdParty/Boost/src/boost/type_traits/remove_const.hpp +++ b/3rdParty/Boost/src/boost/type_traits/remove_const.hpp @@ -54,6 +54,18 @@ struct remove_const_impl >::type type; }; +#ifndef BOOST_NO_RVALUE_REFERENCES +// +// We can't filter out rvalue_references at the same level as +// references or we get ambiguities from msvc: +// +template <typename T> +struct remove_const_impl<T&&> +{ + typedef T&& type; +}; +#endif + } // namespace detail // * convert a type T to non-const type - remove_const<T> diff --git a/3rdParty/Boost/src/boost/type_traits/remove_cv.hpp b/3rdParty/Boost/src/boost/type_traits/remove_cv.hpp index 09f8ff1..668e755 100644 --- a/3rdParty/Boost/src/boost/type_traits/remove_cv.hpp +++ b/3rdParty/Boost/src/boost/type_traits/remove_cv.hpp @@ -27,10 +27,32 @@ namespace boost { +namespace detail{ + +template <class T> +struct rvalue_ref_filter_rem_cv +{ + typedef typename boost::detail::cv_traits_imp<T*>::unqualified_type type; +}; + +#ifndef BOOST_NO_RVALUE_REFERENCES +// +// We can't filter out rvalue_references at the same level as +// references or we get ambiguities from msvc: +// +template <class T> +struct rvalue_ref_filter_rem_cv<T&&> +{ + typedef T&& type; +}; +#endif + +} + #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // convert a type T to a non-cv-qualified type - remove_cv<T> -BOOST_TT_AUX_TYPE_TRAIT_DEF1(remove_cv,T,typename boost::detail::cv_traits_imp<T*>::unqualified_type) +BOOST_TT_AUX_TYPE_TRAIT_DEF1(remove_cv,T,typename boost::detail::rvalue_ref_filter_rem_cv<T>::type) BOOST_TT_AUX_TYPE_TRAIT_PARTIAL_SPEC1_1(typename T,remove_cv,T&,T&) #if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) BOOST_TT_AUX_TYPE_TRAIT_PARTIAL_SPEC1_2(typename T,std::size_t N,remove_cv,T const[N],T type[N]) diff --git a/3rdParty/Boost/src/boost/type_traits/remove_reference.hpp b/3rdParty/Boost/src/boost/type_traits/remove_reference.hpp index 8fddc46..a87db33 100644 --- a/3rdParty/Boost/src/boost/type_traits/remove_reference.hpp +++ b/3rdParty/Boost/src/boost/type_traits/remove_reference.hpp @@ -24,7 +24,27 @@ namespace boost { #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -BOOST_TT_AUX_TYPE_TRAIT_DEF1(remove_reference,T,T) +namespace detail{ +// +// We can't filter out rvalue_references at the same level as +// references or we get ambiguities from msvc: +// +template <class T> +struct remove_rvalue_ref +{ + typedef T type; +}; +#ifndef BOOST_NO_RVALUE_REFERENCES +template <class T> +struct remove_rvalue_ref<T&&> +{ + typedef T type; +}; +#endif + +} // namespace detail + +BOOST_TT_AUX_TYPE_TRAIT_DEF1(remove_reference,T,typename boost::detail::remove_rvalue_ref<T>::type) BOOST_TT_AUX_TYPE_TRAIT_PARTIAL_SPEC1_1(typename T,remove_reference,T&,T) #if defined(BOOST_ILLEGAL_CV_REFERENCES) diff --git a/3rdParty/Boost/src/boost/type_traits/remove_volatile.hpp b/3rdParty/Boost/src/boost/type_traits/remove_volatile.hpp index 723ebe3..073a2a3 100644 --- a/3rdParty/Boost/src/boost/type_traits/remove_volatile.hpp +++ b/3rdParty/Boost/src/boost/type_traits/remove_volatile.hpp @@ -53,6 +53,17 @@ struct remove_volatile_impl >::type type; }; +// +// We can't filter out rvalue_references at the same level as +// references or we get ambiguities from msvc: +// +#ifndef BOOST_NO_RVALUE_REFERENCES +template <typename T> +struct remove_volatile_impl<T&&> +{ + typedef T&& type; +}; +#endif } // namespace detail // * convert a type T to a non-volatile type - remove_volatile<T> diff --git a/3rdParty/Boost/src/boost/type_traits/type_with_alignment.hpp b/3rdParty/Boost/src/boost/type_traits/type_with_alignment.hpp index d790ee1..ac31055 100644 --- a/3rdParty/Boost/src/boost/type_traits/type_with_alignment.hpp +++ b/3rdParty/Boost/src/boost/type_traits/type_with_alignment.hpp @@ -286,43 +286,43 @@ struct __declspec(align(128)) a128 { template<> class type_with_alignment<8> { typedef mpl::if_c< - ::boost::alignment_of<detail::max_align>::value < 8, + ::boost::alignment_of<boost::detail::max_align>::value < 8, align::a8, - detail::type_with_alignment_imp<8> >::type t1; + boost::detail::type_with_alignment_imp<8> >::type t1; public: typedef t1::type type; }; template<> class type_with_alignment<16> { typedef mpl::if_c< - ::boost::alignment_of<detail::max_align>::value < 16, + ::boost::alignment_of<boost::detail::max_align>::value < 16, align::a16, - detail::type_with_alignment_imp<16> >::type t1; + boost::detail::type_with_alignment_imp<16> >::type t1; public: typedef t1::type type; }; template<> class type_with_alignment<32> { typedef mpl::if_c< - ::boost::alignment_of<detail::max_align>::value < 32, + ::boost::alignment_of<boost::detail::max_align>::value < 32, align::a32, - detail::type_with_alignment_imp<32> >::type t1; + boost::detail::type_with_alignment_imp<32> >::type t1; public: typedef t1::type type; }; template<> class type_with_alignment<64> { typedef mpl::if_c< - ::boost::alignment_of<detail::max_align>::value < 64, + ::boost::alignment_of<boost::detail::max_align>::value < 64, align::a64, - detail::type_with_alignment_imp<64> >::type t1; + boost::detail::type_with_alignment_imp<64> >::type t1; public: typedef t1::type type; }; template<> class type_with_alignment<128> { typedef mpl::if_c< - ::boost::alignment_of<detail::max_align>::value < 128, + ::boost::alignment_of<boost::detail::max_align>::value < 128, align::a128, - detail::type_with_alignment_imp<128> >::type t1; + boost::detail::type_with_alignment_imp<128> >::type t1; public: typedef t1::type type; }; diff --git a/3rdParty/Boost/src/boost/typeof/message.hpp b/3rdParty/Boost/src/boost/typeof/message.hpp index 1471ef3..cabbb82 100644 --- a/3rdParty/Boost/src/boost/typeof/message.hpp +++ b/3rdParty/Boost/src/boost/typeof/message.hpp @@ -2,7 +2,7 @@ // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt) -#if defined(_MSC_VER) && !defined BOOST_TYPEOF_SILENT +#if defined(_MSC_VER) && defined BOOST_TYPEOF_MESSAGES # pragma message(BOOST_TYPEOF_TEXT) #endif #undef BOOST_TYPEOF_TEXT diff --git a/3rdParty/Boost/src/boost/typeof/register_functions.hpp b/3rdParty/Boost/src/boost/typeof/register_functions.hpp index 2af7cec..407bba3 100644 --- a/3rdParty/Boost/src/boost/typeof/register_functions.hpp +++ b/3rdParty/Boost/src/boost/typeof/register_functions.hpp @@ -24,12 +24,19 @@ enum { FUN_ID = BOOST_TYPEOF_UNIQUE_ID(), - FUN_PTR_ID = FUN_ID + 1 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), - FUN_REF_ID = FUN_ID + 2 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), - MEM_FUN_ID = FUN_ID + 3 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), - CONST_MEM_FUN_ID = FUN_ID + 4 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), - VOLATILE_MEM_FUN_ID = FUN_ID + 5 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), - VOLATILE_CONST_MEM_FUN_ID = FUN_ID + 6 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY) + FUN_PTR_ID = FUN_ID + 1 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), + FUN_REF_ID = FUN_ID + 2 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), + MEM_FUN_ID = FUN_ID + 3 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), + CONST_MEM_FUN_ID = FUN_ID + 4 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), + VOLATILE_MEM_FUN_ID = FUN_ID + 5 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), + VOLATILE_CONST_MEM_FUN_ID = FUN_ID + 6 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), + FUN_VAR_ID = FUN_ID + 7 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), + FUN_VAR_PTR_ID = FUN_ID + 8 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), + FUN_VAR_REF_ID = FUN_ID + 9 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), + MEM_FUN_VAR_ID = FUN_ID + 10 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), + CONST_MEM_FUN_VAR_ID = FUN_ID + 11 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), + VOLATILE_MEM_FUN_VAR_ID = FUN_ID + 12 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY), + VOLATILE_CONST_MEM_FUN_VAR_ID = FUN_ID + 13 * BOOST_PP_INC(BOOST_TYPEOF_LIMIT_FUNCTION_ARITY) }; BOOST_TYPEOF_BEGIN_ENCODE_NS diff --git a/3rdParty/Boost/src/boost/typeof/register_functions_iterate.hpp b/3rdParty/Boost/src/boost/typeof/register_functions_iterate.hpp index b1048ad..aaa43f3 100644 --- a/3rdParty/Boost/src/boost/typeof/register_functions_iterate.hpp +++ b/3rdParty/Boost/src/boost/typeof/register_functions_iterate.hpp @@ -15,6 +15,13 @@ struct encode_type_impl<V, R(*)(BOOST_PP_ENUM_PARAMS(n, P))> typedef BOOST_TYPEOF_ENCODE_PARAMS(BOOST_PP_INC(n), FUN_PTR_ID + n) type; }; +template<class V, class R BOOST_PP_ENUM_TRAILING_PARAMS(n, class P)> +struct encode_type_impl<V, R(*)(BOOST_PP_ENUM_PARAMS(n, P) ...)> +{ + typedef R BOOST_PP_CAT(P, n); + typedef BOOST_TYPEOF_ENCODE_PARAMS(BOOST_PP_INC(n), FUN_VAR_PTR_ID + n) type; +}; + template<class Iter> struct decode_type_impl<boost::mpl::size_t<FUN_PTR_ID + n>, Iter> { @@ -24,6 +31,15 @@ struct decode_type_impl<boost::mpl::size_t<FUN_PTR_ID + n>, Iter> typedef BOOST_PP_CAT(iter, BOOST_PP_INC(n)) iter; }; +template<class Iter> +struct decode_type_impl<boost::mpl::size_t<FUN_VAR_PTR_ID + n>, Iter> +{ + typedef Iter iter0; + BOOST_TYPEOF_DECODE_PARAMS(BOOST_PP_INC(n)) + typedef BOOST_PP_CAT(p, n)(*type)(BOOST_PP_ENUM_PARAMS(n, p) ...); + typedef BOOST_PP_CAT(iter, BOOST_PP_INC(n)) iter; +}; + #ifndef BOOST_TYPEOF_NO_FUNCTION_TYPES // function references @@ -35,6 +51,13 @@ struct decode_type_impl<boost::mpl::size_t<FUN_PTR_ID + n>, Iter> typedef BOOST_TYPEOF_ENCODE_PARAMS(BOOST_PP_INC(n), FUN_REF_ID + n) type; }; + template<class V, class R BOOST_PP_ENUM_TRAILING_PARAMS(n, class P)> + struct encode_type_impl<V, R(&)(BOOST_PP_ENUM_PARAMS(n, P) ...)> + { + typedef R BOOST_PP_CAT(P, n); + typedef BOOST_TYPEOF_ENCODE_PARAMS(BOOST_PP_INC(n), FUN_VAR_REF_ID + n) type; + }; + template<class Iter> struct decode_type_impl<boost::mpl::size_t<FUN_REF_ID + n>, Iter> { @@ -44,6 +67,15 @@ struct decode_type_impl<boost::mpl::size_t<FUN_PTR_ID + n>, Iter> typedef BOOST_PP_CAT(iter, BOOST_PP_INC(n)) iter; }; + template<class Iter> + struct decode_type_impl<boost::mpl::size_t<FUN_VAR_REF_ID + n>, Iter> + { + typedef Iter iter0; + BOOST_TYPEOF_DECODE_PARAMS(BOOST_PP_INC(n)) + typedef BOOST_PP_CAT(p, n)(&type)(BOOST_PP_ENUM_PARAMS(n, p) ...); + typedef BOOST_PP_CAT(iter, BOOST_PP_INC(n)) iter; + }; + // functions template<class V, class R BOOST_PP_ENUM_TRAILING_PARAMS(n, class P)> @@ -53,6 +85,13 @@ struct decode_type_impl<boost::mpl::size_t<FUN_PTR_ID + n>, Iter> typedef BOOST_TYPEOF_ENCODE_PARAMS(BOOST_PP_INC(n), FUN_ID + n) type; }; + template<class V, class R BOOST_PP_ENUM_TRAILING_PARAMS(n, class P)> + struct encode_type_impl<V, R(BOOST_PP_ENUM_PARAMS(n, P) ...)> + { + typedef R BOOST_PP_CAT(P, n); + typedef BOOST_TYPEOF_ENCODE_PARAMS(BOOST_PP_INC(n), FUN_VAR_ID + n) type; + }; + template<class Iter> struct decode_type_impl<boost::mpl::size_t<FUN_ID + n>, Iter> { @@ -62,6 +101,15 @@ struct decode_type_impl<boost::mpl::size_t<FUN_PTR_ID + n>, Iter> typedef BOOST_PP_CAT(iter, BOOST_PP_INC(n)) iter; }; + template<class Iter> + struct decode_type_impl<boost::mpl::size_t<FUN_VAR_ID + n>, Iter> + { + typedef Iter iter0; + BOOST_TYPEOF_DECODE_PARAMS(BOOST_PP_INC(n)) + typedef BOOST_PP_CAT(p, n)(type)(BOOST_PP_ENUM_PARAMS(n, p) ...); + typedef BOOST_PP_CAT(iter, BOOST_PP_INC(n)) iter; + }; + #endif//BOOST_TYPEOF_NO_FUNCTION_TYPES #ifndef BOOST_TYPEOF_NO_MEMBER_FUNCTION_TYPES diff --git a/3rdParty/Boost/src/boost/typeof/typeof.hpp b/3rdParty/Boost/src/boost/typeof/typeof.hpp index 165ef95..3e91649 100644 --- a/3rdParty/Boost/src/boost/typeof/typeof.hpp +++ b/3rdParty/Boost/src/boost/typeof/typeof.hpp @@ -15,7 +15,7 @@ #if defined(__COMO__) # ifdef __GNUG__ -# ifndef(BOOST_TYPEOF_EMULATION) +# ifndef BOOST_TYPEOF_EMULATION # ifndef BOOST_TYPEOF_NATIVE # define BOOST_TYPEOF_NATIVE # endif @@ -65,7 +65,7 @@ # endif # define BOOST_TYPEOF_KEYWORD __typeof__ # else -# error typeof emulation is not supported +# define BOOST_TYPEOF_EMULATION_UNSUPPORTED # endif # else // 9.x # ifndef BOOST_TYPEOF_EMULATION @@ -75,7 +75,22 @@ # define BOOST_TYPEOF_KEYWORD __typeof__ # endif # endif - +#elif defined __CODEGEARC__ +# ifndef BOOST_TYPEOF_EMULATION +# ifndef BOOST_TYPEOF_NATIVE +# define BOOST_TYPEOF_EMULATION_UNSUPPORTED +# endif +# else +# define BOOST_TYPEOF_EMULATION_UNSUPPORTED +# endif +#elif defined __BORLANDC__ +# ifndef BOOST_TYPEOF_EMULATION +# ifndef BOOST_TYPEOF_NATIVE +# define BOOST_TYPEOF_EMULATION_UNSUPPORTED +# endif +# else +# define BOOST_TYPEOF_EMULATION_UNSUPPORTED +# endif #elif defined __DMC__ # ifndef BOOST_TYPEOF_EMULATION # ifndef BOOST_TYPEOF_NATIVE @@ -95,24 +110,21 @@ # else # error typeof emulation is not supported # endif -# elif (_MSC_VER >= 1310) // 7.1, 8.0 +# elif (_MSC_VER >= 1310) // 7.1 -> # ifndef BOOST_TYPEOF_EMULATION # ifndef BOOST_TYPEOF_NATIVE -# define BOOST_TYPEOF_NATIVE +# ifndef _MSC_EXTENSIONS +# define BOOST_TYPEOF_EMULATION +# else +# define BOOST_TYPEOF_NATIVE +# endif # endif +# endif +# ifdef BOOST_TYPEOF_NATIVE # include <boost/typeof/msvc/typeof_impl.hpp> # define MSVC_TYPEOF_HACK # endif -/*# else // 8.0 -# ifndef BOOST_TYPEOF_NATIVE -# ifndef BOOST_TYPEOF_EMULATION -# define BOOST_TYPEOF_EMULATION -# endif -# else -# error native typeof is not supported -# endif*/ # endif - #elif defined(__HP_aCC) # ifndef BOOST_TYPEOF_NATIVE # ifndef BOOST_TYPEOF_EMULATION @@ -163,7 +175,9 @@ #define BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()\ <boost/typeof/incr_registration_group.hpp> -#ifdef BOOST_TYPEOF_EMULATION +#ifdef BOOST_TYPEOF_EMULATION_UNSUPPORTED +# include <boost/typeof/unsupported.hpp> +#elif defined BOOST_TYPEOF_EMULATION # define BOOST_TYPEOF_TEXT "using typeof emulation" # include <boost/typeof/message.hpp> # include <boost/typeof/typeof_impl.hpp> diff --git a/3rdParty/Boost/src/boost/typeof/unsupported.hpp b/3rdParty/Boost/src/boost/typeof/unsupported.hpp new file mode 100644 index 0000000..83d3a55 --- /dev/null +++ b/3rdParty/Boost/src/boost/typeof/unsupported.hpp @@ -0,0 +1,29 @@ +// Copyright (C) 2010 Peder Holt +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_TYPEOF_UNSUPPORTED_HPP_INCLUDED +#define BOOST_TYPEOF_UNSUPPORTED_HPP_INCLUDED + +namespace boost { namespace type_of { + struct typeof_emulation_is_unsupported_on_this_compiler {}; +}} + +#define BOOST_TYPEOF(expr) boost::type_of::typeof_emulation_is_unsupported_on_this_compiler +#define BOOST_TYPEOF_TPL BOOST_TYPEOF + +#define BOOST_TYPEOF_NESTED_TYPEDEF_TPL(name,expr) \ +struct name {\ + typedef BOOST_TYPEOF_TPL(expr) type;\ +}; + +#define BOOST_TYPEOF_NESTED_TYPEDEF(name,expr) \ +struct name {\ + typedef BOOST_TYPEOF(expr) type;\ +}; + + +#define BOOST_TYPEOF_REGISTER_TYPE(x) +#define BOOST_TYPEOF_REGISTER_TEMPLATE(x, params) + +#endif
\ No newline at end of file diff --git a/3rdParty/Boost/src/boost/utility/compare_pointees.hpp b/3rdParty/Boost/src/boost/utility/compare_pointees.hpp index e6888a6..7e2515c 100644 --- a/3rdParty/Boost/src/boost/utility/compare_pointees.hpp +++ b/3rdParty/Boost/src/boost/utility/compare_pointees.hpp @@ -4,7 +4,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// See http://www.boost.org/lib/optional for documentation. +// See http://www.boost.org/libs/optional for documentation. // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com diff --git a/3rdParty/Boost/src/boost/utility/declval.hpp b/3rdParty/Boost/src/boost/utility/declval.hpp new file mode 100644 index 0000000..41ec3dc --- /dev/null +++ b/3rdParty/Boost/src/boost/utility/declval.hpp @@ -0,0 +1,44 @@ +// common_type.hpp ---------------------------------------------------------// + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP +#define BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP + +#include <boost/config.hpp> + +//----------------------------------------------------------------------------// + +#include <boost/type_traits/add_rvalue_reference.hpp> + +//----------------------------------------------------------------------------// +// // +// C++03 implementation of // +// Written by Vicente J. Botet Escriba // +//~ 20.3.4 Function template declval [declval] +//~ 1 The library provides the function template declval to simplify the definition of expressions which occur as +//~ unevaluated operands. +//~ 2 Remarks: If this function is used, the program is ill-formed. +//~ 3 Remarks: The template parameter T of declval may be an incomplete type. +//~ [ Example: + +//~ template <class To, class From> +//~ decltype(static_cast<To>(declval<From>())) convert(From&&); + +//~ declares a function template convert which only participats in overloading if the type From can be +//~ explicitly converted to type To. For another example see class template common_type (20.7.6.6). —end +//~ example ] +// // +//----------------------------------------------------------------------------// + +namespace boost { + + template <typename T> + typename add_rvalue_reference<T>::type declval(); //noexcept; // as unevaluated operand + +} // namespace boost + +#endif // BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP diff --git a/3rdParty/Boost/src/boost/uuid/uuid.hpp b/3rdParty/Boost/src/boost/uuid/uuid.hpp index ceebd4d..2678d85 100644 --- a/3rdParty/Boost/src/boost/uuid/uuid.hpp +++ b/3rdParty/Boost/src/boost/uuid/uuid.hpp @@ -37,8 +37,10 @@ #include <boost/cstdint.hpp> #include <algorithm> #include <boost/config.hpp> // for static assert -#include <boost/mpl/bool.hpp> +#ifndef BOOST_UUID_NO_TYPE_TRAITS #include <boost/type_traits/is_pod.hpp> +#include <boost/type_traits/integral_constant.hpp> +#endif #if defined(_MSC_VER) #pragma warning(push) // Save warning settings. @@ -202,14 +204,15 @@ inline std::size_t hash_value(uuid const& u) /* throw() */ }} //namespace boost::uuids +#ifndef BOOST_UUID_NO_TYPE_TRAITS // type traits specializations namespace boost { template <> -struct is_pod<uuids::uuid> : mpl::true_ -{}; +struct is_pod<uuids::uuid> : true_type {}; } // namespace boost +#endif #if defined(_MSC_VER) #pragma warning(pop) // Restore warnings to previous state. diff --git a/3rdParty/Boost/src/boost/uuid/uuid_io.hpp b/3rdParty/Boost/src/boost/uuid/uuid_io.hpp index c2b050f..592a509 100644 --- a/3rdParty/Boost/src/boost/uuid/uuid_io.hpp +++ b/3rdParty/Boost/src/boost/uuid/uuid_io.hpp @@ -32,11 +32,20 @@ template <typename ch, typename char_traits> std::basic_ostream<ch, char_traits>& operator<<(std::basic_ostream<ch, char_traits> &os, uuid const& u) { io::ios_flags_saver flags_saver(os); - io::ios_width_saver width_saver(os); io::basic_ios_fill_saver<ch, char_traits> fill_saver(os); const typename std::basic_ostream<ch, char_traits>::sentry ok(os); if (ok) { + const std::streamsize width = os.width(0); + const std::streamsize uuid_width = 36; + const std::ios_base::fmtflags flags = os.flags(); + const typename std::basic_ios<ch, char_traits>::char_type fill = os.fill(); + if (flags & (std::ios_base::right | std::ios_base::internal)) { + for (std::streamsize i=uuid_width; i<width; i++) { + os << fill; + } + } + os << std::hex; os.fill(os.widen('0')); @@ -48,6 +57,14 @@ template <typename ch, typename char_traits> os << os.widen('-'); } } + + if (flags & std::ios_base::left) { + for (std::streamsize i=uuid_width; i<width; i++) { + os << fill; + } + } + + os.width(0); //used the width so reset it } return os; } @@ -110,6 +127,68 @@ template <typename ch, typename char_traits> return is; } +namespace detail { +inline char to_char(size_t i) { + if (i <= 9) { + return static_cast<char>('0' + i); + } else { + return static_cast<char>('a' + (i-10)); + } +} + +inline wchar_t to_wchar(size_t i) { + if (i <= 9) { + return static_cast<wchar_t>(L'0' + i); + } else { + return static_cast<wchar_t>(L'a' + (i-10)); + } +} + +} // namespace detail + +inline std::string to_string(uuid const& u) +{ + std::string result; + result.reserve(36); + + std::size_t i=0; + for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) { + const size_t hi = ((*it_data) >> 4) & 0x0F; + result += detail::to_char(hi); + + const size_t lo = (*it_data) & 0x0F; + result += detail::to_char(lo); + + if (i == 3 || i == 5 || i == 7 || i == 9) { + result += '-'; + } + } + return result; +} + +#ifndef BOOST_NO_STD_WSTRING +inline std::wstring to_wstring(uuid const& u) +{ + std::wstring result; + result.reserve(36); + + std::size_t i=0; + for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) { + const size_t hi = ((*it_data) >> 4) & 0x0F; + result += detail::to_wchar(hi); + + const size_t lo = (*it_data) & 0x0F; + result += detail::to_wchar(lo); + + if (i == 3 || i == 5 || i == 7 || i == 9) { + result += L'-'; + } + } + return result; +} + +#endif + }} //namespace boost::uuids #if defined(_MSC_VER) diff --git a/3rdParty/Boost/src/boost/variant/detail/apply_visitor_binary.hpp b/3rdParty/Boost/src/boost/variant/detail/apply_visitor_binary.hpp index 92cdb42..f1c1fb6 100644 --- a/3rdParty/Boost/src/boost/variant/detail/apply_visitor_binary.hpp +++ b/3rdParty/Boost/src/boost/variant/detail/apply_visitor_binary.hpp @@ -19,7 +19,11 @@ #include "boost/variant/detail/apply_visitor_unary.hpp" +#if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302)) #include "boost/utility/enable_if.hpp" +#include "boost/mpl/not.hpp" +#include "boost/type_traits/is_const.hpp" +#endif namespace boost { @@ -63,6 +67,9 @@ public: // visitor interfaces return visitor_(value1_, value2); } +private: + apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&); + }; template <typename Visitor, typename Visitable2> @@ -100,6 +107,9 @@ public: // visitor interfaces return boost::apply_visitor(invoker, visitable2_); } +private: + apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&); + }; }} // namespace detail::variant diff --git a/3rdParty/Boost/src/boost/variant/detail/apply_visitor_delayed.hpp b/3rdParty/Boost/src/boost/variant/detail/apply_visitor_delayed.hpp index 31c79a2..2650508 100644 --- a/3rdParty/Boost/src/boost/variant/detail/apply_visitor_delayed.hpp +++ b/3rdParty/Boost/src/boost/variant/detail/apply_visitor_delayed.hpp @@ -72,6 +72,9 @@ public: // binary visitor interface return apply_visitor(visitor_, visitable1, visitable2); } +private: + apply_visitor_delayed_t& operator=(const apply_visitor_delayed_t&); + }; template <typename Visitor> diff --git a/3rdParty/Boost/src/boost/variant/detail/apply_visitor_unary.hpp b/3rdParty/Boost/src/boost/variant/detail/apply_visitor_unary.hpp index 10b361a..64199d8 100644 --- a/3rdParty/Boost/src/boost/variant/detail/apply_visitor_unary.hpp +++ b/3rdParty/Boost/src/boost/variant/detail/apply_visitor_unary.hpp @@ -17,7 +17,11 @@ #include "boost/detail/workaround.hpp" #include "boost/variant/detail/generic_result_type.hpp" +#if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302)) #include "boost/utility/enable_if.hpp" +#include "boost/mpl/not.hpp" +#include "boost/type_traits/is_const.hpp" +#endif namespace boost { diff --git a/3rdParty/Boost/src/boost/variant/detail/variant_io.hpp b/3rdParty/Boost/src/boost/variant/detail/variant_io.hpp index c72491a..192a3de 100644 --- a/3rdParty/Boost/src/boost/variant/detail/variant_io.hpp +++ b/3rdParty/Boost/src/boost/variant/detail/variant_io.hpp @@ -64,6 +64,9 @@ public: // visitor interface out_ << operand; } +private: + printer& operator=(const printer&); + }; }} // namespace detail::variant diff --git a/3rdParty/Boost/src/boost/variant/detail/visitation_impl.hpp b/3rdParty/Boost/src/boost/variant/detail/visitation_impl.hpp index 36ab906..0d4271a 100644 --- a/3rdParty/Boost/src/boost/variant/detail/visitation_impl.hpp +++ b/3rdParty/Boost/src/boost/variant/detail/visitation_impl.hpp @@ -35,6 +35,10 @@ #include "boost/type_traits/has_nothrow_copy.hpp" #include "boost/variant/detail/has_nothrow_move.hpp" +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +# pragma warning (push) +# pragma warning (disable : 4702) //unreachable code +#endif /////////////////////////////////////////////////////////////////////////////// // BOOST_VARIANT_VISITATION_UNROLLING_LIMIT @@ -283,4 +287,8 @@ visitation_impl( }} // namespace detail::variant } // namespace boost +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +# pragma warning(pop) +#endif + #endif // BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP diff --git a/3rdParty/Boost/src/boost/variant/variant.hpp b/3rdParty/Boost/src/boost/variant/variant.hpp index 7e3c9e8..205ad8d 100644 --- a/3rdParty/Boost/src/boost/variant/variant.hpp +++ b/3rdParty/Boost/src/boost/variant/variant.hpp @@ -56,6 +56,7 @@ #include "boost/mpl/eval_if.hpp" #include "boost/mpl/begin_end.hpp" #include "boost/mpl/bool.hpp" +#include "boost/mpl/not.hpp" #include "boost/mpl/empty.hpp" #include "boost/mpl/find_if.hpp" #include "boost/mpl/front.hpp" @@ -698,6 +699,9 @@ public: // internal visitor interfaces ::boost::detail::variant::move_swap( operand, other ); } +private: + swap_with& operator=(const swap_with&); + }; /////////////////////////////////////////////////////////////////////////////// @@ -759,6 +763,9 @@ public: // visitor interfaces return Comp()(lhs_content, rhs_content); } +private: + comparer& operator=(const comparer&); + }; /////////////////////////////////////////////////////////////////////////////// diff --git a/3rdParty/Boost/src/boost/version.hpp b/3rdParty/Boost/src/boost/version.hpp index 82a1daf..bdb68d4 100644 --- a/3rdParty/Boost/src/boost/version.hpp +++ b/3rdParty/Boost/src/boost/version.hpp @@ -19,7 +19,7 @@ // BOOST_VERSION / 100 % 1000 is the minor version // BOOST_VERSION / 100000 is the major version -#define BOOST_VERSION 104300 +#define BOOST_VERSION 104500 // // BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION @@ -27,7 +27,7 @@ // number, y is the minor version number, and z is the patch level if not 0. // This is used by <config/auto_link.hpp> to select which library version to link to. -#define BOOST_LIB_VERSION "1_43" +#define BOOST_LIB_VERSION "1_45" #endif diff --git a/3rdParty/Boost/src/libs/filesystem/src/operations.cpp b/3rdParty/Boost/src/libs/filesystem/v2/src/v2_operations.cpp index d0655b9..10df199 100644 --- a/3rdParty/Boost/src/libs/filesystem/src/operations.cpp +++ b/3rdParty/Boost/src/libs/filesystem/v2/src/v2_operations.cpp @@ -12,15 +12,14 @@ // define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows // the library is being built (possibly exporting rather than importing code) -#define BOOST_FILESYSTEM_SOURCE +#define BOOST_FILESYSTEM_SOURCE -#define _POSIX_PTHREAD_SEMANTICS // Sun readdir_r() needs this - -// enable the XPG-compliant version of readdir_r() on AIX -#if defined(_AIX) -# define _LINUX_SOURCE_COMPAT +#ifndef BOOST_SYSTEM_NO_DEPRECATED +# define BOOST_SYSTEM_NO_DEPRECATED #endif +#define _POSIX_PTHREAD_SEMANTICS // Sun readdir_r() needs this + #if !(defined(__HP_aCC) && defined(_ILP32) && \ !defined(_STATVFS_ACPP_PROBLEMS_FIXED)) #define _FILE_OFFSET_BITS 64 // at worst, these defines may have no effect, @@ -43,12 +42,13 @@ #endif -#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/v2/operations.hpp> #include <boost/scoped_array.hpp> #include <boost/throw_exception.hpp> #include <boost/detail/workaround.hpp> +#include <cstdlib> // for malloc, free -namespace fs = boost::filesystem; +namespace fs = boost::filesystem2; using boost::system::error_code; using boost::system::system_category; @@ -122,7 +122,7 @@ namespace inline DWORD get_file_attributes( const char * ph ) { return ::GetFileAttributesA( ph ); } -# ifndef BOOST_FILESYSTEM_NARROW_ONLY +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY inline DWORD get_file_attributes( const wchar_t * ph ) { return ::GetFileAttributesW( ph ); } @@ -180,7 +180,7 @@ namespace { return ::CreateHardLinkW( from_ph.c_str(), to_ph.c_str(), 0 ) != 0; } #endif -# endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY +# endif // ifndef BOOST_FILESYSTEM2_NARROW_ONLY template< class String > fs::file_status status_template( const String & ph, error_code & ec ) @@ -188,11 +188,12 @@ namespace DWORD attr( get_file_attributes( ph.c_str() ) ); if ( attr == 0xFFFFFFFF ) { - ec = error_code( ::GetLastError(), system_category ); + ec = error_code( ::GetLastError(), system_category() ); if ((ec.value() == ERROR_FILE_NOT_FOUND) || (ec.value() == ERROR_PATH_NOT_FOUND) || (ec.value() == ERROR_INVALID_NAME) // "tools/jam/src/:sys:stat.h", "//foo" || (ec.value() == ERROR_INVALID_DRIVE) // USB card reader with no card inserted + || (ec.value() == ERROR_NOT_READY) // CD/DVD drive with no disc inserted || (ec.value() == ERROR_INVALID_PARAMETER) // ":sys:stat.h" || (ec.value() == ERROR_BAD_PATHNAME) // "//nosuch" on Win64 || (ec.value() == ERROR_BAD_NETPATH)) // "//nosuch" on Win32 @@ -220,12 +221,12 @@ namespace { return ::GetFileAttributesExA( ph, ::GetFileExInfoStandard, &fad ); } template< class String > - boost::filesystem::detail::query_pair + boost::filesystem2::detail::query_pair is_empty_template( const String & ph ) { WIN32_FILE_ATTRIBUTE_DATA fad; if ( get_file_attributes_ex( ph.c_str(), fad ) == 0 ) - return std::make_pair( error_code( ::GetLastError(), system_category ), false ); + return std::make_pair( error_code( ::GetLastError(), system_category() ), false ); return std::make_pair( ok, ( fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ? is_empty_directory( ph ) @@ -258,7 +259,7 @@ namespace }; template< class String > - boost::filesystem::detail::query_pair + boost::filesystem2::detail::query_pair equivalent_template( const String & ph1, const String & ph2 ) { // Note well: Physical location on external media is part of the @@ -295,14 +296,14 @@ namespace { return std::make_pair( ok, false ); } assert( p1.handle == INVALID_HANDLE_VALUE && p2.handle == INVALID_HANDLE_VALUE ); - { return std::make_pair( error_code( error1, system_category), false ); } + { return std::make_pair( error_code( error1, system_category()), false ); } } // at this point, both handles are known to be valid BY_HANDLE_FILE_INFORMATION info1, info2; if ( !::GetFileInformationByHandle( p1.handle, &info1 ) ) - { return std::make_pair( error_code( ::GetLastError(), system_category ), false ); } + { return std::make_pair( error_code( ::GetLastError(), system_category() ), false ); } if ( !::GetFileInformationByHandle( p2.handle, &info2 ) ) - { return std::make_pair( error_code( ::GetLastError(), system_category ), false ); } + { return std::make_pair( error_code( ::GetLastError(), system_category() ), false ); } // In theory, volume serial numbers are sufficient to distinguish between // devices, but in practice VSN's are sometimes duplicated, so last write // time and file size are also checked. @@ -319,15 +320,15 @@ namespace } template< class String > - boost::filesystem::detail::uintmax_pair + boost::filesystem2::detail::uintmax_pair file_size_template( const String & ph ) { WIN32_FILE_ATTRIBUTE_DATA fad; // by now, intmax_t is 64-bits on all Windows compilers if ( get_file_attributes_ex( ph.c_str(), fad ) == 0 ) - return std::make_pair( error_code( ::GetLastError(), system_category ), 0 ); + return std::make_pair( error_code( ::GetLastError(), system_category() ), 0 ); if ( (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) !=0 ) - return std::make_pair( error_code( ERROR_FILE_NOT_FOUND, system_category), 0 ); + return std::make_pair( error_code( ERROR_FILE_NOT_FOUND, system_category()), 0 ); return std::make_pair( ok, (static_cast<boost::uintmax_t>(fad.nFileSizeHigh) << (sizeof(fad.nFileSizeLow)*8)) @@ -339,11 +340,11 @@ namespace { return ::GetDiskFreeSpaceExA( ph.c_str(), avail, total, free ) != 0; } template< class String > - boost::filesystem::detail::space_pair + boost::filesystem2::detail::space_pair space_template( String & ph ) { ULARGE_INTEGER avail, total, free; - boost::filesystem::detail::space_pair result; + boost::filesystem2::detail::space_pair result; if ( get_free_disk_space( ph, &avail, &total, &free ) ) { result.first = ok; @@ -359,7 +360,7 @@ namespace } else { - result.first = error_code( ::GetLastError(), system_category ); + result.first = error_code( ::GetLastError(), system_category() ); result.second.capacity = result.second.free = result.second.available = 0; } @@ -380,7 +381,7 @@ namespace typedef typename String::value_type value_type; boost::scoped_array<value_type> buf( new value_type[sz] ); if ( get_current_directory( sz, buf.get() ) == 0 ) - return error_code( ::GetLastError(), system_category ); + return error_code( ::GetLastError(), system_category() ); ph = buf.get(); return ok; } @@ -393,7 +394,7 @@ namespace set_current_path_template( const String & ph ) { return error_code( set_current_directory( ph.c_str() ) - ? 0 : ::GetLastError(), system_category ); + ? 0 : ::GetLastError(), system_category() ); } inline std::size_t get_full_path_name( @@ -414,13 +415,13 @@ namespace typename String::value_type * pfn; std::size_t len = get_full_path_name( ph, buf_size , buf, &pfn ); - if ( len == 0 ) return error_code( ::GetLastError(), system_category ); + if ( len == 0 ) return error_code( ::GetLastError(), system_category() ); if ( len > buf_size ) { typedef typename String::value_type value_type; boost::scoped_array<value_type> big_buf( new value_type[len] ); if ( (len=get_full_path_name( ph, len , big_buf.get(), &pfn )) - == 0 ) return error_code( ::GetLastError(), system_category ); + == 0 ) return error_code( ::GetLastError(), system_category() ); big_buf[len] = '\0'; target = big_buf.get(); return ok; @@ -439,9 +440,9 @@ namespace FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ) ); if ( hw.handle == INVALID_HANDLE_VALUE ) - return error_code( ::GetLastError(), system_category ); + return error_code( ::GetLastError(), system_category() ); return error_code( ::GetFileTime( hw.handle, 0, 0, &last_write_time ) != 0 - ? 0 : ::GetLastError(), system_category ); + ? 0 : ::GetLastError(), system_category() ); } template<class String> @@ -453,9 +454,9 @@ namespace FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ) ); if ( hw.handle == INVALID_HANDLE_VALUE ) - return error_code( ::GetLastError(), system_category ); + return error_code( ::GetLastError(), system_category() ); return error_code( ::SetFileTime( hw.handle, 0, 0, &last_write_time ) != 0 - ? 0 : ::GetLastError(), system_category ); + ? 0 : ::GetLastError(), system_category() ); } // these constants come from inspecting some Microsoft sample code @@ -486,7 +487,7 @@ namespace } template<class String> - boost::filesystem::detail::time_pair + boost::filesystem2::detail::time_pair last_write_time_template( const String & ph ) { FILETIME lwt; @@ -525,11 +526,11 @@ namespace if ( fs::is_directory( sf ) ) { if ( !remove_directory( ph ) ) - return error_code(::GetLastError(), system_category); + return error_code(::GetLastError(), system_category()); } else { - if ( !delete_file( ph ) ) return error_code(::GetLastError(), system_category); + if ( !delete_file( ph ) ) return error_code(::GetLastError(), system_category()); } return ok; } @@ -538,12 +539,12 @@ namespace { return ::CreateDirectoryA( dir.c_str(), 0 ) != 0; } template<class String> - boost::filesystem::detail::query_pair + boost::filesystem2::detail::query_pair create_directory_template( const String & dir_ph ) { error_code error, dummy; if ( create_directory( dir_ph ) ) return std::make_pair( error, true ); - error = error_code( ::GetLastError(), system_category ); + error = error_code( ::GetLastError(), system_category() ); // an error here may simply mean the postcondition is already met if ( error.value() == ERROR_ALREADY_EXISTS && fs::is_directory( fs::detail::status_api( dir_ph, dummy ) ) ) @@ -564,7 +565,7 @@ namespace const String & from_ph ) { return error_code( create_hard_link( to_ph.c_str(), from_ph.c_str() ) - ? 0 : ::GetLastError(), system_category ); + ? 0 : ::GetLastError(), system_category() ); } #endif @@ -591,7 +592,7 @@ namespace namespace boost { - namespace filesystem + namespace filesystem2 { namespace detail { @@ -602,9 +603,9 @@ namespace boost BOOST_FILESYSTEM_DECL error_code not_found_error() { # ifdef BOOST_WINDOWS_API - return error_code(ERROR_PATH_NOT_FOUND, system_category); + return error_code(ERROR_PATH_NOT_FOUND, system_category()); # else - return error_code(ENOENT, system_category); + return error_code(ENOENT, system_category()); # endif } @@ -624,7 +625,7 @@ namespace boost status_api( const std::string & ph, error_code & ec ) { return status_template( ph, ec ); } -# ifndef BOOST_FILESYSTEM_NARROW_ONLY +# ifndef BOOST_FILESYSTEM2_NARROW_ONLY BOOST_FILESYSTEM_DECL fs::file_status status_api( const std::wstring & ph, error_code & ec ) @@ -686,7 +687,7 @@ namespace boost BOOST_FILESYSTEM_DECL error_code create_symlink_api( const std::wstring & /*to_ph*/, const std::wstring & /*from_ph*/ ) - { return error_code( ERROR_NOT_SUPPORTED, system_category ); } + { return error_code( ERROR_NOT_SUPPORTED, system_category() ); } BOOST_FILESYSTEM_DECL error_code remove_api( const std::wstring & ph ) { return remove_template( ph ); } @@ -695,14 +696,14 @@ namespace boost rename_api( const std::wstring & from, const std::wstring & to ) { return error_code( ::MoveFileW( from.c_str(), to.c_str() ) - ? 0 : ::GetLastError(), system_category ); + ? 0 : ::GetLastError(), system_category() ); } BOOST_FILESYSTEM_DECL error_code copy_file_api( const std::wstring & from, const std::wstring & to, bool fail_if_exists ) { return error_code( ::CopyFileW( from.c_str(), to.c_str(), fail_if_exists ) - ? 0 : ::GetLastError(), system_category ); + ? 0 : ::GetLastError(), system_category() ); } BOOST_FILESYSTEM_DECL bool create_file_api( const std::wstring & ph, @@ -778,7 +779,7 @@ namespace boost { handle = 0; return error_code( ::GetLastError() == ERROR_FILE_NOT_FOUND - ? 0 : ::GetLastError(), system_category ); + ? 0 : ::GetLastError(), system_category() ); } target = data.cFileName; if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) @@ -796,7 +797,7 @@ namespace boost { int error = ::GetLastError(); dir_itr_close( handle ); - return error_code( error == ERROR_NO_MORE_FILES ? 0 : error, system_category ); + return error_code( error == ERROR_NO_MORE_FILES ? 0 : error, system_category() ); } target = data.cFileName; if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) @@ -805,7 +806,7 @@ namespace boost return ok; } -# endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY +# endif // ifndef BOOST_FILESYSTEM2_NARROW_ONLY // suggested by Walter Landry BOOST_FILESYSTEM_DECL bool symbolic_link_exists_api( const std::string & ) @@ -866,7 +867,7 @@ namespace boost BOOST_FILESYSTEM_DECL error_code create_symlink_api( const std::string & /*to_ph*/, const std::string & /*from_ph*/ ) - { return error_code( ERROR_NOT_SUPPORTED, system_category ); } + { return error_code( ERROR_NOT_SUPPORTED, system_category() ); } BOOST_FILESYSTEM_DECL error_code remove_api( const std::string & ph ) { return remove_template( ph ); } @@ -875,14 +876,14 @@ namespace boost rename_api( const std::string & from, const std::string & to ) { return error_code( ::MoveFileA( from.c_str(), to.c_str() ) - ? 0 : ::GetLastError(), system_category ); + ? 0 : ::GetLastError(), system_category() ); } BOOST_FILESYSTEM_DECL error_code copy_file_api( const std::string & from, const std::string & to, bool fail_if_exists ) { return error_code( ::CopyFileA( from.c_str(), to.c_str(), fail_if_exists ) - ? 0 : ::GetLastError(), system_category ); + ? 0 : ::GetLastError(), system_category() ); } BOOST_FILESYSTEM_DECL error_code @@ -903,8 +904,10 @@ namespace boost == INVALID_HANDLE_VALUE ) { handle = 0; - return error_code( ::GetLastError() == ERROR_FILE_NOT_FOUND - ? 0 : ::GetLastError(), system_category ); + return error_code( (::GetLastError() == ERROR_FILE_NOT_FOUND + // Windows Mobile returns ERROR_NO_MORE_FILES; see ticket #3551 + || ::GetLastError() == ERROR_NO_MORE_FILES) + ? 0 : ::GetLastError(), system_category() ); } target = data.cFileName; if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) @@ -920,7 +923,7 @@ namespace boost { bool ok = ::FindClose( handle ) != 0; handle = 0; - return error_code( ok ? 0 : ::GetLastError(), system_category ); + return error_code( ok ? 0 : ::GetLastError(), system_category() ); } return ok; } @@ -934,7 +937,7 @@ namespace boost { int error = ::GetLastError(); dir_itr_close( handle ); - return error_code( error == ERROR_NO_MORE_FILES ? 0 : error, system_category ); + return error_code( error == ERROR_NO_MORE_FILES ? 0 : error, system_category() ); } target = data.cFileName; if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) @@ -956,7 +959,7 @@ namespace boost ec = ok; return fs::file_status( fs::file_not_found ); } - ec = error_code( errno, system_category ); + ec = error_code( errno, system_category() ); return fs::file_status( fs::status_unknown ); } ec = ok; @@ -986,7 +989,7 @@ namespace boost ec = ok; return fs::file_status( fs::file_not_found ); } - ec = error_code( errno, system_category ); + ec = error_code( errno, system_category() ); return fs::file_status( fs::status_unknown ); } ec = ok; @@ -1021,7 +1024,7 @@ namespace boost { struct stat path_stat; if ( (::stat( ph.c_str(), &path_stat )) != 0 ) - return std::make_pair( error_code( errno, system_category ), false ); + return std::make_pair( error_code( errno, system_category() ), false ); return std::make_pair( ok, S_ISDIR( path_stat.st_mode ) ? is_empty_directory( ph ) : path_stat.st_size == 0 ); @@ -1035,7 +1038,7 @@ namespace boost struct stat s1; int e1( ::stat( ph1.c_str(), &s1 ) ); if ( e1 != 0 || e2 != 0 ) - return std::make_pair( error_code( e1 != 0 && e2 != 0 ? errno : 0, system_category ), false ); + return std::make_pair( error_code( e1 != 0 && e2 != 0 ? errno : 0, system_category() ), false ); // at this point, both stats are known to be valid return std::make_pair( ok, s1.st_dev == s2.st_dev @@ -1052,9 +1055,9 @@ namespace boost { struct stat path_stat; if ( ::stat( ph.c_str(), &path_stat ) != 0 ) - return std::make_pair( error_code( errno, system_category ), 0 ); + return std::make_pair( error_code( errno, system_category() ), 0 ); if ( !S_ISREG( path_stat.st_mode ) ) - return std::make_pair( error_code( EPERM, system_category ), 0 ); + return std::make_pair( error_code( EPERM, system_category() ), 0 ); return std::make_pair( ok, static_cast<boost::uintmax_t>(path_stat.st_size) ); } @@ -1066,7 +1069,7 @@ namespace boost space_pair result; if ( ::BOOST_STATVFS( ph.c_str(), &vfs ) != 0 ) { - result.first = error_code( errno, system_category ); + result.first = error_code( errno, system_category() ); result.second.capacity = result.second.free = result.second.available = 0; } @@ -1088,7 +1091,7 @@ namespace boost { struct stat path_stat; if ( ::stat( ph.c_str(), &path_stat ) != 0 ) - return std::make_pair( error_code( errno, system_category ), 0 ); + return std::make_pair( error_code( errno, system_category() ), 0 ); return std::make_pair( ok, path_stat.st_mtime ); } @@ -1097,11 +1100,11 @@ namespace boost { struct stat path_stat; if ( ::stat( ph.c_str(), &path_stat ) != 0 ) - return error_code( errno, system_category ); + return error_code( errno, system_category() ); ::utimbuf buf; buf.actime = path_stat.st_atime; // utime() updates access time too:-( buf.modtime = new_value; - return error_code( ::utime( ph.c_str(), &buf ) != 0 ? errno : 0, system_category ); + return error_code( ::utime( ph.c_str(), &buf ) != 0 ? errno : 0, system_category() ); } BOOST_FILESYSTEM_DECL error_code @@ -1118,7 +1121,7 @@ namespace boost # if defined(__MSL__) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && errno != 0 # endif - ) return error_code( errno, system_category ); + ) return error_code( errno, system_category() ); } else { @@ -1133,7 +1136,7 @@ namespace boost set_current_path_api( const std::string & ph ) { return error_code( ::chdir( ph.c_str() ) - ? errno : 0, system_category ); + ? errno : 0, system_category() ); } BOOST_FILESYSTEM_DECL fs::detail::query_pair @@ -1145,7 +1148,7 @@ namespace boost error_code dummy; if ( ec != EEXIST || !fs::is_directory( status_api( ph, dummy ) ) ) - { return std::make_pair( error_code( ec, system_category ), false ); } + { return std::make_pair( error_code( ec, system_category() ), false ); } return std::make_pair( ok, false ); } @@ -1154,7 +1157,7 @@ namespace boost const std::string & from_ph ) { return error_code( ::link( to_ph.c_str(), from_ph.c_str() ) == 0 - ? 0 : errno, system_category ); + ? 0 : errno, system_category() ); } BOOST_FILESYSTEM_DECL error_code @@ -1162,7 +1165,7 @@ namespace boost const std::string & from_ph ) { return error_code( ::symlink( to_ph.c_str(), from_ph.c_str() ) == 0 - ? 0 : errno, system_category ); + ? 0 : errno, system_category() ); } BOOST_FILESYSTEM_DECL error_code @@ -1180,7 +1183,7 @@ namespace boost // ignore errors if post-condition satisfied return status_api(ph, ec).type() == file_not_found - ? ok : error_code( error, system_category ) ; + ? ok : error_code( error, system_category() ) ; } BOOST_FILESYSTEM_DECL error_code @@ -1189,9 +1192,9 @@ namespace boost // POSIX is too permissive so must check error_code dummy; if ( fs::exists( status_api( to, dummy ) ) ) - return error_code( EEXIST, system_category ); + return error_code( EEXIST, system_category() ); return error_code( std::rename( from.c_str(), to.c_str() ) != 0 - ? errno : 0, system_category ); + ? errno : 0, system_category() ); } BOOST_FILESYSTEM_DECL error_code @@ -1206,11 +1209,11 @@ namespace boost // introduced a gratuitous race condition; the stat() is now done after the open() if ( (infile = ::open( from_file_ph.c_str(), O_RDONLY )) < 0 ) - { return error_code( errno, system_category ); } + { return error_code( errno, system_category() ); } struct stat from_stat; if ( ::stat( from_file_ph.c_str(), &from_stat ) != 0 ) - { return error_code( errno, system_category ); } + { return error_code( errno, system_category() ); } int oflag = O_CREAT | O_WRONLY; if ( fail_if_exists ) oflag |= O_EXCL; @@ -1219,7 +1222,7 @@ namespace boost int open_errno = errno; BOOST_ASSERT( infile >= 0 ); ::close( infile ); - return error_code( open_errno, system_category ); + return error_code( open_errno, system_category() ); } ssize_t sz, sz_read=1, sz_write; @@ -1244,7 +1247,7 @@ namespace boost if ( ::close( infile) < 0 ) sz_read = -1; if ( ::close( outfile) < 0 ) sz_read = -1; - return error_code( sz_read < 0 ? errno : 0, system_category ); + return error_code( sz_read < 0 ? errno : 0, system_category() ); } // this code is based on Stevens and Rago, Advanced Programming in the @@ -1264,7 +1267,7 @@ namespace boost { if ( errno == 0 ) // indeterminate max = 4096; // guess - else return error_code( errno, system_category ); + else return error_code( errno, system_category() ); } else max = static_cast<std::size_t>( tmp + 1 ); // relative root } @@ -1278,7 +1281,7 @@ namespace boost file_status &, file_status & ) { if ( (handle = ::opendir( dir.c_str() )) == 0 ) - return error_code( errno, system_category ); + return error_code( errno, system_category() ); target = std::string( "." ); // string was static but caused trouble // when iteration called from dtor, after // static had already been destroyed @@ -1299,7 +1302,7 @@ namespace boost if ( handle == 0 ) return ok; DIR * h( static_cast<DIR*>(handle) ); handle = 0; - return error_code( ::closedir( h ) == 0 ? 0 : errno, system_category ); + return error_code( ::closedir( h ) == 0 ? 0 : errno, system_category() ); } // warning: the only dirent member updated is d_name @@ -1312,7 +1315,8 @@ namespace boost && defined(_POSIX_THREAD_SAFE_FUNCTIONS) \ && defined(_SC_THREAD_SAFE_FUNCTIONS) \ && (_POSIX_THREAD_SAFE_FUNCTIONS+0 >= 0) \ - && (!defined(__hpux) || (defined(__hpux) && defined(_REENTRANT))) + && (!defined(__hpux) || defined(_REENTRANT)) \ + && (!defined(_AIX) || defined(__THREAD_SAFE)) if ( ::sysconf( _SC_THREAD_SAFE_FUNCTIONS ) >= 0 ) { return ::readdir_r( dirp, entry, result ); } # endif @@ -1335,7 +1339,7 @@ namespace boost dirent * result; int return_code; if ( (return_code = readdir_r_simulator( static_cast<DIR*>(handle), - entry, &result )) != 0 ) return error_code( errno, system_category ); + entry, &result )) != 0 ) return error_code( errno, system_category() ); if ( result == 0 ) return dir_itr_close( handle, buffer ); target = entry->d_name; # ifdef BOOST_FILESYSTEM_STATUS_CACHE @@ -1364,5 +1368,5 @@ namespace boost # endif } // namespace detail - } // namespace filesystem + } // namespace filesystem2 } // namespace boost diff --git a/3rdParty/Boost/src/libs/filesystem/src/path.cpp b/3rdParty/Boost/src/libs/filesystem/v2/src/v2_path.cpp index 6d7d40c..7adeaff 100644 --- a/3rdParty/Boost/src/libs/filesystem/src/path.cpp +++ b/3rdParty/Boost/src/libs/filesystem/v2/src/v2_path.cpp @@ -13,11 +13,15 @@ // the library is being built (possibly exporting rather than importing code) #define BOOST_FILESYSTEM_SOURCE -#include <boost/filesystem/config.hpp> +#ifndef BOOST_SYSTEM_NO_DEPRECATED +# define BOOST_SYSTEM_NO_DEPRECATED +#endif + +#include <boost/filesystem/v2/config.hpp> -#ifndef BOOST_FILESYSTEM_NARROW_ONLY +#ifndef BOOST_FILESYSTEM2_NARROW_ONLY -#include <boost/filesystem/path.hpp> +#include <boost/filesystem/v2/path.hpp> #include <boost/scoped_array.hpp> #include <locale> @@ -26,6 +30,11 @@ #include <cwchar> // for std::mbstate_t +#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +# include <boost/filesystem/detail/utf8_codecvt_facet.hpp> +#endif + + namespace { // std::locale construction can throw (if LC_MESSAGES is wrong, for example), @@ -37,8 +46,13 @@ namespace #if !defined(macintosh) && !defined(__APPLE__) && !defined(__APPLE_CC__) // ISO C calls this "the locale-specific native environment": static std::locale lc(""); -#else - static std::locale lc = std::locale(); // Mac OS doesn't support locale("") +#else // Mac OS + // "All BSD system functions expect their string parameters to be in UTF-8 encoding + // and nothing else." + // See http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPInternational/Articles/FileEncodings.html + std::locale global_loc = std::locale(); // Mac OS doesn't support locale("") + static std::locale lc(global_loc, + new boost::filesystem::detail::utf8_codecvt_facet); #endif return lc; } @@ -58,7 +72,7 @@ namespace namespace boost { - namespace filesystem + namespace filesystem2 { bool wpath_traits::imbue( const std::locale & new_loc, const std::nothrow_t & ) { @@ -75,7 +89,7 @@ namespace boost if ( locked ) boost::throw_exception( wfilesystem_error( "boost::filesystem::wpath_traits::imbue() after lockdown", - make_error_code( system::posix::not_supported ) ) ); + make_error_code( system::errc::not_supported ) ) ); imbue( new_loc, std::nothrow ); } @@ -132,7 +146,7 @@ namespace boost work.get()+work_size, to_next ) != std::codecvt_base::ok ) boost::throw_exception( boost::filesystem::wfilesystem_error( "boost::filesystem::wpath::to_external conversion error", - ph, system::error_code( system::posix::invalid_argument, system::system_category ) ) ); + ph, system::error_code( system::errc::invalid_argument, system::system_category() ) ) ); *to_next = '\0'; return external_string_type( work.get() ); } @@ -151,13 +165,13 @@ namespace boost work.get()+work_size, to_next ) != std::codecvt_base::ok ) boost::throw_exception( boost::filesystem::wfilesystem_error( "boost::filesystem::wpath::to_internal conversion error", - system::error_code( system::posix::invalid_argument, system::system_category ) ) ); + system::error_code( system::errc::invalid_argument, system::system_category() ) ) ); *to_next = L'\0'; return internal_string_type( work.get() ); } # endif // BOOST_POSIX_API - } // namespace filesystem + } // namespace filesystem2 } // namespace boost -#endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY +#endif // ifndef BOOST_FILESYSTEM2_NARROW_ONLY diff --git a/3rdParty/Boost/src/libs/filesystem/src/portability.cpp b/3rdParty/Boost/src/libs/filesystem/v2/src/v2_portability.cpp index 347180a..4d27543 100644 --- a/3rdParty/Boost/src/libs/filesystem/src/portability.cpp +++ b/3rdParty/Boost/src/libs/filesystem/v2/src/v2_portability.cpp @@ -13,10 +13,14 @@ // the library is being built (possibly exporting rather than importing code) #define BOOST_FILESYSTEM_SOURCE -#include <boost/filesystem/config.hpp> -#include <boost/filesystem/path.hpp> +#ifndef BOOST_SYSTEM_NO_DEPRECATED +# define BOOST_SYSTEM_NO_DEPRECATED +#endif -namespace fs = boost::filesystem; +#include <boost/filesystem/v2/config.hpp> +#include <boost/filesystem/v2/path.hpp> + +namespace fs = boost::filesystem2; #include <cstring> // SGI MIPSpro compilers need this @@ -43,7 +47,7 @@ namespace namespace boost { - namespace filesystem + namespace filesystem2 { // name_check functions ----------------------------------------------// @@ -111,5 +115,5 @@ namespace boost ; } - } // namespace filesystem + } // namespace filesystem2 } // namespace boost diff --git a/3rdParty/Boost/src/libs/filesystem/v3/src/codecvt_error_category.cpp b/3rdParty/Boost/src/libs/filesystem/v3/src/codecvt_error_category.cpp new file mode 100644 index 0000000..b35b4a9 --- /dev/null +++ b/3rdParty/Boost/src/libs/filesystem/v3/src/codecvt_error_category.cpp @@ -0,0 +1,93 @@ +// codecvt_error_category implementation file ----------------------------------------// + +// Copyright Beman Dawes 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt) + +// Library home page at http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#include <boost/config.hpp> +#if !defined( BOOST_NO_STD_WSTRING ) +// Boost.Filesystem V3 and later requires std::wstring support. +// During the transition to V3, libraries are compiled with both V2 and V3 sources. +// On old compilers that don't support V3 anyhow, we just skip everything so the compile +// will succeed and the library can be built. + +#include <boost/config/warning_disable.hpp> + +// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_FILESYSTEM_SOURCE + +#ifndef BOOST_SYSTEM_NO_DEPRECATED +# define BOOST_SYSTEM_NO_DEPRECATED +#endif + +#include <boost/filesystem/v3/config.hpp> +#include <boost/filesystem/v3/path_traits.hpp> +#include <boost/system/error_code.hpp> +#include <locale> +#include <vector> +#include <cstdlib> +#include <cassert> + +//--------------------------------------------------------------------------------------// + +namespace +{ + class codecvt_error_cat : public boost::system::error_category + { + public: + codecvt_error_cat(){} + const char* name() const; + std::string message(int ev) const; + }; + + const char* codecvt_error_cat::name() const + { + return "codecvt"; + } + + std::string codecvt_error_cat::message(int ev) const + { + std::string str; + switch (ev) + { + case std::codecvt_base::ok: + str = "ok"; + break; + case std::codecvt_base::partial: + str = "partial"; + break; + case std::codecvt_base::error: + str = "error"; + break; + case std::codecvt_base::noconv: + str = "noconv"; + break; + default: + str = "unknown error"; + } + return str; + } + +} // unnamed namespace + +namespace boost +{ + namespace filesystem3 + { + + BOOST_FILESYSTEM_DECL const boost::system::error_category& codecvt_error_category() + { + static const codecvt_error_cat codecvt_error_cat_const; + return codecvt_error_cat_const; + } + + } // namespace filesystem3 +} // namespace boost + +#endif // no wide character support diff --git a/3rdParty/Boost/src/libs/filesystem/v3/src/operations.cpp b/3rdParty/Boost/src/libs/filesystem/v3/src/operations.cpp new file mode 100644 index 0000000..04d9c17 --- /dev/null +++ b/3rdParty/Boost/src/libs/filesystem/v3/src/operations.cpp @@ -0,0 +1,1897 @@ +// operations.cpp --------------------------------------------------------------------// + +// Copyright 2002-2009 Beman Dawes +// Copyright 2001 Dietmar Kuehl + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See library home page at http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#include <boost/config.hpp> +#if !defined( BOOST_NO_STD_WSTRING ) +// Boost.Filesystem V3 and later requires std::wstring support. +// During the transition to V3, libraries are compiled with both V2 and V3 sources. +// On old compilers that don't support V3 anyhow, we just skip everything so the compile +// will succeed and the library can be built. + +// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows +// the library is being built (possibly exporting rather than importing code) + +#define BOOST_FILESYSTEM_SOURCE + +#ifndef BOOST_SYSTEM_NO_DEPRECATED +# define BOOST_SYSTEM_NO_DEPRECATED +#endif + +#ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS // Sun readdir_r()needs this +#endif + +#if !(defined(__HP_aCC) && defined(_ILP32) && \ + !defined(_STATVFS_ACPP_PROBLEMS_FIXED)) +#define _FILE_OFFSET_BITS 64 // at worst, these defines may have no effect, +#endif +#define __USE_FILE_OFFSET64 // but that is harmless on Windows and on POSIX + // 64-bit systems or on 32-bit systems which don't have files larger + // than can be represented by a traditional POSIX/UNIX off_t type. + // OTOH, defining them should kick in 64-bit off_t's (and thus + // st_size)on 32-bit systems that provide the Large File + // Support (LFS)interface, such as Linux, Solaris, and IRIX. + // The defines are given before any headers are included to + // ensure that they are available to all included headers. + // That is required at least on Solaris, and possibly on other + // systems as well. + +#include <boost/filesystem/v3/operations.hpp> +#include <boost/scoped_array.hpp> +#include <boost/detail/workaround.hpp> +#include <cstdlib> // for malloc, free + +#ifdef BOOST_FILEYSTEM_INCLUDE_IOSTREAM +# include <iostream> +#endif + +namespace fs = boost::filesystem3; +using boost::filesystem3::path; +using boost::filesystem3::filesystem_error; +using boost::system::error_code; +using boost::system::error_category; +using boost::system::system_category; +using std::string; +using std::wstring; + +# ifdef BOOST_POSIX_API + +# include <sys/types.h> +# if !defined(__APPLE__) && !defined(__OpenBSD__) +# include <sys/statvfs.h> +# define BOOST_STATVFS statvfs +# define BOOST_STATVFS_F_FRSIZE vfs.f_frsize +# else +# ifdef __OpenBSD__ +# include <sys/param.h> +# endif +# include <sys/mount.h> +# define BOOST_STATVFS statfs +# define BOOST_STATVFS_F_FRSIZE static_cast<boost::uintmax_t>(vfs.f_bsize) +# endif +# include <dirent.h> +# include <unistd.h> +# include <fcntl.h> +# include <utime.h> +# include "limits.h" + +# else // BOOST_WINDOW_API + +# if (defined(__MINGW32__) || defined(__CYGWIN__)) && !defined(WINVER) + // Versions of MinGW or Cygwin that support Filesystem V3 support at least WINVER 0x501. + // See MinGW's windef.h +# define WINVER 0x501 +# endif +# include <windows.h> +# include <winnt.h> +# if !defined(_WIN32_WINNT) +# define _WIN32_WINNT 0x0500 +# endif +# if defined(__BORLANDC__) || defined(__MWERKS__) +# if defined(__BORLANDC__) + using std::time_t; +# endif +# include <utime.h> +# else +# include <sys/utime.h> +# endif + +// REPARSE_DATA_BUFFER related definitions are found in ntifs.h, which is part of the +// Windows Device Driver Kit. Since that's inconvenient, the definitions are provided +// here. See http://msdn.microsoft.com/en-us/library/ms791514.aspx + +#if !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) // mingw winnt.h does provide the defs + +#define SYMLINK_FLAG_RELATIVE 1 + +typedef struct _REPARSE_DATA_BUFFER { + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union { + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + /* Example of distinction between substitute and print names: + mklink /d ldrive c:\ + SubstituteName: c:\\??\ + PrintName: c:\ + */ + } SymbolicLinkReparseBuffer; + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + struct { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + }; +} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; + +#define REPARSE_DATA_BUFFER_HEADER_SIZE \ + FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) + +#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) +#endif + +# ifndef FSCTL_GET_REPARSE_POINT +# define FSCTL_GET_REPARSE_POINT 0x900a8 +# endif + +# ifndef IO_REPARSE_TAG_SYMLINK +# define IO_REPARSE_TAG_SYMLINK (0xA000000CL) +# endif + +# endif // BOOST_WINDOWS_API + +// BOOST_FILESYSTEM_STATUS_CACHE enables file_status cache in +// dir_itr_increment. The config tests are placed here because some of the +// macros being tested come from dirent.h. +// +// TODO: find out what macros indicate dirent::d_type present in more libraries +# if defined(BOOST_WINDOWS_API)\ + || defined(_DIRENT_HAVE_D_TYPE)// defined by GNU C library if d_type present +# define BOOST_FILESYSTEM_STATUS_CACHE +# endif + +#include <sys/stat.h> // even on Windows some functions use stat() +#include <string> +#include <cstring> +#include <cstdio> // for remove, rename +#include <cerrno> +#include <cassert> +// #include <iostream> // for debugging only; comment out when not in use + +// POSIX/Windows macros ----------------------------------------------------// + +// Portions of the POSIX and Windows API's are very similar, except for name, +// order of arguments, and meaning of zero/non-zero returns. The macros below +// abstract away those differences. They follow Windows naming and order of +// arguments, and return true to indicate no error occurred. [POSIX naming, +// order of arguments, and meaning of return were followed initially, but +// found to be less clear and cause more coding errors.] + +# if defined(BOOST_POSIX_API) + +// POSIX uses a 0 return to indicate success +# define BOOST_ERRNO errno +# define BOOST_SET_CURRENT_DIRECTORY(P)(::chdir(P)== 0) +# define BOOST_CREATE_DIRECTORY(P)(::mkdir(P, S_IRWXU|S_IRWXG|S_IRWXO)== 0) +# define BOOST_CREATE_HARD_LINK(F,T)(::link(T, F)== 0) +# define BOOST_CREATE_SYMBOLIC_LINK(F,T,Flag)(::symlink(T, F)== 0) +# define BOOST_REMOVE_DIRECTORY(P)(::rmdir(P)== 0) +# define BOOST_DELETE_FILE(P)(::unlink(P)== 0) +# define BOOST_COPY_DIRECTORY(F,T)(!(::stat(from.c_str(), &from_stat)!= 0\ + || ::mkdir(to.c_str(),from_stat.st_mode)!= 0)) +# define BOOST_COPY_FILE(F,T,FailIfExistsBool)copy_file_api(F, T, FailIfExistsBool) +# define BOOST_MOVE_FILE(OLD,NEW)(::rename(OLD, NEW)== 0) +# define BOOST_RESIZE_FILE(P,SZ)(::truncate(P, SZ)== 0) + +# define BOOST_ERROR_NOT_SUPPORTED ENOSYS +# define BOOST_ERROR_ALREADY_EXISTS EEXIST + +# else // BOOST_WINDOWS_API + +// Windows uses a non-0 return to indicate success +# define BOOST_ERRNO ::GetLastError() +# define BOOST_SET_CURRENT_DIRECTORY(P)(::SetCurrentDirectoryW(P)!= 0) +# define BOOST_CREATE_DIRECTORY(P)(::CreateDirectoryW(P, 0)!= 0) +# define BOOST_CREATE_HARD_LINK(F,T)(create_hard_link_api(F, T, 0)!= 0) +# define BOOST_CREATE_SYMBOLIC_LINK(F,T,Flag)(create_symbolic_link_api(F, T, Flag)!= 0) +# define BOOST_REMOVE_DIRECTORY(P)(::RemoveDirectoryW(P)!= 0) +# define BOOST_DELETE_FILE(P)(::DeleteFileW(P)!= 0) +# define BOOST_COPY_DIRECTORY(F,T)(::CreateDirectoryExW(F, T, 0)!= 0) +# define BOOST_COPY_FILE(F,T,FailIfExistsBool)(::CopyFileW(F, T, FailIfExistsBool)!= 0) +# define BOOST_MOVE_FILE(OLD,NEW)(::MoveFileExW(OLD, NEW, MOVEFILE_REPLACE_EXISTING)!= 0) +# define BOOST_RESIZE_FILE(P,SZ)(resize_file_api(P, SZ)!= 0) +# define BOOST_READ_SYMLINK(P,T) + +# define BOOST_ERROR_ALREADY_EXISTS ERROR_ALREADY_EXISTS +# define BOOST_ERROR_NOT_SUPPORTED ERROR_NOT_SUPPORTED + +# endif + +//--------------------------------------------------------------------------------------// +// // +// helpers (all operating systems) // +// // +//--------------------------------------------------------------------------------------// + +namespace +{ + +# ifdef BOOST_POSIX_API + const char dot = '.'; +# else + const wchar_t dot = L'.'; +# endif + + fs::file_type query_file_type(const path& p, error_code* ec); + + boost::filesystem3::directory_iterator end_dir_itr; + + const std::size_t buf_size(128); + const error_code ok; + + bool error(bool was_error, error_code* ec, const string& message) + { + if (!was_error) + { + if (ec != 0) ec->clear(); + } + else + { // error + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error(message, + error_code(BOOST_ERRNO, system_category()))); + else + ec->assign(BOOST_ERRNO, system_category()); + } + return was_error; + } + + bool error(bool was_error, const path& p, error_code* ec, const string& message) + { + if (!was_error) + { + if (ec != 0) ec->clear(); + } + else + { // error + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error(message, + p, error_code(BOOST_ERRNO, system_category()))); + else + ec->assign(BOOST_ERRNO, system_category()); + } + return was_error; + } + + bool error(bool was_error, const path& p1, const path& p2, error_code* ec, + const string& message) + { + if (!was_error) + { + if (ec != 0) ec->clear(); + } + else + { // error + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error(message, + p1, p2, error_code(BOOST_ERRNO, system_category()))); + else + ec->assign(BOOST_ERRNO, system_category()); + } + return was_error; + } + + bool error(bool was_error, const error_code& result, + const path& p, error_code* ec, const string& message) + // Overwrites ec if there has already been an error + { + if (!was_error) + { + if (ec != 0) ec->clear(); + } + else + { // error + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error(message, p, result)); + else + *ec = result; + } + return was_error; + } + + bool error(bool was_error, const error_code& result, + const path& p1, const path& p2, error_code* ec, const string& message) + // Overwrites ec if there has already been an error + { + if (!was_error) + { + if (ec != 0) ec->clear(); + } + else + { // error + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error(message, p1, p2, result)); + else + *ec = result; + } + return was_error; + } + + bool is_empty_directory(const path& p) + { + return fs::directory_iterator(p)== end_dir_itr; + } + + bool remove_directory(const path& p) // true if succeeds + { return BOOST_REMOVE_DIRECTORY(p.c_str()); } + + bool remove_file(const path& p) // true if succeeds + { return BOOST_DELETE_FILE(p.c_str()); } + + // called by remove and remove_all_aux + bool remove_file_or_directory(const path& p, fs::file_type type, error_code* ec) + // return true if file removed, false if not removed + { + if (type == fs::file_not_found) + { + if (ec != 0) ec->clear(); + return false; + } + + if (type == fs::directory_file +# ifdef BOOST_WINDOWS_API + || type == fs::_detail_directory_symlink +# endif + ) + { + if (error(!remove_directory(p), p, ec, "boost::filesystem::remove")) + return false; + } + else + { + if (error(!remove_file(p), p, ec, "boost::filesystem::remove")) + return false; + } + return true; + } + + boost::uintmax_t remove_all_aux(const path& p, fs::file_type type, + error_code* ec) + { + boost::uintmax_t count = 1; + + if (type == fs::directory_file) // but not a directory symlink + { + for (fs::directory_iterator itr(p); + itr != end_dir_itr; ++itr) + { + fs::file_type tmp_type = query_file_type(itr->path(), ec); + if (ec != 0 && *ec) + return count; + count += remove_all_aux(itr->path(), tmp_type, ec); + } + } + remove_file_or_directory(p, type, ec); + return count; + } + +#ifdef BOOST_POSIX_API + +//--------------------------------------------------------------------------------------// +// // +// POSIX-specific helpers // +// // +//--------------------------------------------------------------------------------------// + + bool not_found_error(int errval) + { + return errno == ENOENT || errno == ENOTDIR; + } + + bool // true if ok + copy_file_api(const std::string& from_p, + const std::string& to_p, bool fail_if_exists) + { + const std::size_t buf_sz = 32768; + boost::scoped_array<char> buf(new char [buf_sz]); + int infile=-1, outfile=-1; // -1 means not open + + // bug fixed: code previously did a stat()on the from_file first, but that + // introduced a gratuitous race condition; the stat()is now done after the open() + + if ((infile = ::open(from_p.c_str(), O_RDONLY))< 0) + { return false; } + + struct stat from_stat; + if (::stat(from_p.c_str(), &from_stat)!= 0) + { return false; } + + int oflag = O_CREAT | O_WRONLY; + if (fail_if_exists)oflag |= O_EXCL; + if ((outfile = ::open(to_p.c_str(), oflag, from_stat.st_mode))< 0) + { + int open_errno = errno; + BOOST_ASSERT(infile >= 0); + ::close(infile); + errno = open_errno; + return false; + } + + ssize_t sz, sz_read=1, sz_write; + while (sz_read > 0 + && (sz_read = ::read(infile, buf.get(), buf_sz))> 0) + { + // Allow for partial writes - see Advanced Unix Programming (2nd Ed.), + // Marc Rochkind, Addison-Wesley, 2004, page 94 + sz_write = 0; + do + { + if ((sz = ::write(outfile, buf.get() + sz_write, + sz_read - sz_write))< 0) + { + sz_read = sz; // cause read loop termination + break; // and error to be thrown after closes + } + sz_write += sz; + } while (sz_write < sz_read); + } + + if (::close(infile)< 0)sz_read = -1; + if (::close(outfile)< 0)sz_read = -1; + + return sz_read >= 0; + } + + inline fs::file_type query_file_type(const path& p, error_code* ec) + { + return fs::detail::symlink_status(p, ec).type(); + } + +# else + +//--------------------------------------------------------------------------------------// +// // +// Windows-specific helpers // +// // +//--------------------------------------------------------------------------------------// + + bool not_found_error(int errval) + { + return errval == ERROR_FILE_NOT_FOUND + || errval == ERROR_PATH_NOT_FOUND + || errval == ERROR_INVALID_NAME // "tools/jam/src/:sys:stat.h", "//foo" + || errval == ERROR_INVALID_DRIVE // USB card reader with no card inserted + || errval == ERROR_NOT_READY // CD/DVD drive with no disc inserted + || errval == ERROR_INVALID_PARAMETER // ":sys:stat.h" + || errval == ERROR_BAD_PATHNAME // "//nosuch" on Win64 + || errval == ERROR_BAD_NETPATH; // "//nosuch" on Win32 + } + + // these constants come from inspecting some Microsoft sample code + std::time_t to_time_t(const FILETIME & ft) + { + __int64 t = (static_cast<__int64>(ft.dwHighDateTime)<< 32) + + ft.dwLowDateTime; +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // > VC++ 7.0 + t -= 116444736000000000LL; +# else + t -= 116444736000000000; +# endif + t /= 10000000; + return static_cast<std::time_t>(t); + } + + void to_FILETIME(std::time_t t, FILETIME & ft) + { + __int64 temp = t; + temp *= 10000000; +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // > VC++ 7.0 + temp += 116444736000000000LL; +# else + temp += 116444736000000000; +# endif + ft.dwLowDateTime = static_cast<DWORD>(temp); + ft.dwHighDateTime = static_cast<DWORD>(temp >> 32); + } + + // Thanks to Jeremy Maitin-Shepard for much help and for permission to + // base the equivalent()implementation on portions of his + // file-equivalence-win32.cpp experimental code. + + struct handle_wrapper + { + HANDLE handle; + handle_wrapper(HANDLE h) + : handle(h){} + ~handle_wrapper() + { + if (handle != INVALID_HANDLE_VALUE) + ::CloseHandle(handle); + } + }; + + HANDLE create_file_handle(const path& p, DWORD dwDesiredAccess, + DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile) + { + return ::CreateFileW(p.c_str(), dwDesiredAccess, dwShareMode, + lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, + hTemplateFile); + } + + bool is_reparse_point_a_symlink(const path& p) + { + handle_wrapper h(create_file_handle(p, FILE_READ_EA, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL)); + if (h.handle == INVALID_HANDLE_VALUE) + return false; + + boost::scoped_array<char> buf(new char [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]); + + // Query the reparse data + DWORD dwRetLen; + BOOL result = ::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT, NULL, 0, buf.get(), + MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &dwRetLen, NULL); + if (!result) return false; + + return reinterpret_cast<const REPARSE_DATA_BUFFER*>(buf.get()) + ->ReparseTag == IO_REPARSE_TAG_SYMLINK; + } + + inline std::size_t get_full_path_name( + const path& src, std::size_t len, wchar_t* buf, wchar_t** p) + { + return static_cast<std::size_t>( + ::GetFullPathNameW(src.c_str(), static_cast<DWORD>(len), buf, p)); + } + + fs::file_status process_status_failure(const path& p, error_code* ec) + { + int errval(::GetLastError()); + if (ec != 0) // always report errval, even though some + ec->assign(errval, system_category()); // errval values are not status_errors + + if (not_found_error(errval)) + { + return fs::file_status(fs::file_not_found); + } + else if ((errval == ERROR_SHARING_VIOLATION)) + { + return fs::file_status(fs::type_unknown); + } + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status", + p, error_code(errval, system_category()))); + return fs::file_status(fs::status_error); + } + + // differs from symlink_status() in that directory symlinks are reported as + // _detail_directory_symlink, as required on Windows by remove() and its helpers. + fs::file_type query_file_type(const path& p, error_code* ec) + { + DWORD attr(::GetFileAttributesW(p.c_str())); + if (attr == 0xFFFFFFFF) + { + return process_status_failure(p, ec).type(); + } + + if (ec != 0) ec->clear(); + + if (attr & FILE_ATTRIBUTE_REPARSE_POINT) + { + if (is_reparse_point_a_symlink(p)) + return (attr & FILE_ATTRIBUTE_DIRECTORY) + ? fs::_detail_directory_symlink + : fs::symlink_file; + return fs::reparse_file; + } + + return (attr & FILE_ATTRIBUTE_DIRECTORY) + ? fs::directory_file + : fs::regular_file; + } + + BOOL resize_file_api(const wchar_t* p, boost::uintmax_t size) + { + HANDLE handle = CreateFileW(p, GENERIC_WRITE, 0, 0, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, 0); + LARGE_INTEGER sz; + sz.QuadPart = size; + return handle != INVALID_HANDLE_VALUE + && ::SetFilePointerEx(handle, sz, 0, FILE_BEGIN) + && ::SetEndOfFile(handle) + && ::CloseHandle(handle); + } + + // Windows kernel32.dll functions that may or may not be present + // must be accessed through pointers + + typedef BOOL (WINAPI *PtrCreateHardLinkW)( + /*__in*/ LPCWSTR lpFileName, + /*__in*/ LPCWSTR lpExistingFileName, + /*__reserved*/ LPSECURITY_ATTRIBUTES lpSecurityAttributes + ); + + PtrCreateHardLinkW create_hard_link_api = PtrCreateHardLinkW( + ::GetProcAddress( + ::GetModuleHandle(TEXT("kernel32.dll")), "CreateHardLinkW")); + + typedef BOOLEAN (WINAPI *PtrCreateSymbolicLinkW)( + /*__in*/ LPCWSTR lpSymlinkFileName, + /*__in*/ LPCWSTR lpTargetFileName, + /*__in*/ DWORD dwFlags + ); + + PtrCreateSymbolicLinkW create_symbolic_link_api = PtrCreateSymbolicLinkW( + ::GetProcAddress( + ::GetModuleHandle(TEXT("kernel32.dll")), "CreateSymbolicLinkW")); + +#endif + +//#ifdef BOOST_WINDOWS_API +// +// +// inline bool get_free_disk_space(const std::wstring& ph, +// PULARGE_INTEGER avail, PULARGE_INTEGER total, PULARGE_INTEGER free) +// { return ::GetDiskFreeSpaceExW(ph.c_str(), avail, total, free)!= 0; } +// +//#endif + +} // unnamed namespace + +//--------------------------------------------------------------------------------------// +// // +// operations functions declared in operations.hpp // +// in alphabetic order // +// // +//--------------------------------------------------------------------------------------// + +namespace boost +{ +namespace filesystem3 +{ + + BOOST_FILESYSTEM_DECL + path absolute(const path& p, const path& base) + { +// if ( p.empty() || p.is_absolute() ) +// return p; +// // recursively calling absolute is sub-optimal, but is simple +// path abs_base(base.is_absolute() ? base : absolute(base)); +//# ifdef BOOST_WINDOWS_API +// if (p.has_root_directory()) +// return abs_base.root_name() / p; +// // !p.has_root_directory +// if (p.has_root_name()) +// return p.root_name() +// / abs_base.root_directory() / abs_base.relative_path() / p.relative_path(); +// // !p.has_root_name() +//# endif +// return abs_base / p; + + // recursively calling absolute is sub-optimal, but is sure and simple + path abs_base(base.is_absolute() ? base : absolute(base)); + + // store expensive to compute values that are needed multiple times + path p_root_name (p.root_name()); + path base_root_name (abs_base.root_name()); + path p_root_directory (p.root_directory()); + + if (p.empty()) + return abs_base; + + if (!p_root_name.empty()) // p.has_root_name() + { + if (p_root_directory.empty()) // !p.has_root_directory() + return p_root_name / abs_base.root_directory() + / abs_base.relative_path() / p.relative_path(); + // p is absolute, so fall through to return p at end of block + } + + else if (!p_root_directory.empty()) // p.has_root_directory() + { +# ifdef BOOST_POSIX_API + // POSIX can have root name it it is a network path + if (base_root_name.empty()) // !abs_base.has_root_name() + return p; +# endif + return base_root_name / p; + } + + else + { + return abs_base / p; + } + + return p; // p.is_absolute() is true + } + +namespace detail +{ + BOOST_FILESYSTEM_DECL bool possible_large_file_size_support() + { +# ifdef BOOST_POSIX_API + struct stat lcl_stat; + return sizeof(lcl_stat.st_size)> 4; +# else + return true; +# endif + } + + BOOST_FILESYSTEM_DECL + void copy(const path& from, const path& to, system::error_code* ec) + { + file_status s(symlink_status(from, *ec)); + if (ec != 0 && *ec) return; + + if(is_symlink(s)) + { + copy_symlink(from, to, *ec); + } + else if(is_directory(s)) + { + copy_directory(from, to, *ec); + } + else if(is_regular_file(s)) + { + copy_file(from, to, copy_option::fail_if_exists, *ec); + } + else + { + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::copy", + from, to, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()))); + ec->assign(BOOST_ERROR_NOT_SUPPORTED, system_category()); + } + } + + BOOST_FILESYSTEM_DECL + void copy_directory(const path& from, const path& to, system::error_code* ec) + { +# ifdef BOOST_POSIX_API + struct stat from_stat; +# endif + error(!BOOST_COPY_DIRECTORY(from.c_str(), to.c_str()), + from, to, ec, "boost::filesystem::copy_directory"); + } + + BOOST_FILESYSTEM_DECL + void copy_file(const path& from, const path& to, + BOOST_SCOPED_ENUM(copy_option)option, + error_code* ec) + { + error(!BOOST_COPY_FILE(from.c_str(), to.c_str(), + option == copy_option::fail_if_exists), + from, to, ec, "boost::filesystem::copy_file"); + } + + BOOST_FILESYSTEM_DECL + void copy_symlink(const path& existing_symlink, const path& new_symlink, + system::error_code* ec) + { +# if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600 + error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), + new_symlink, existing_symlink, ec, + "boost::filesystem::copy_symlink"); + +# else // modern Windows or BOOST_POSIX_API + path p(read_symlink(existing_symlink, ec)); + if (ec != 0 && *ec) return; + create_symlink(p, new_symlink, ec); + +# endif + } + + BOOST_FILESYSTEM_DECL + bool create_directories(const path& p, system::error_code* ec) + { + if (p.empty() || exists(p)) + { + if (!p.empty() && !is_directory(p)) + { + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error( + "boost::filesystem::create_directories", p, + error_code(system::errc::file_exists, system::generic_category()))); + else ec->assign(system::errc::file_exists, system::generic_category()); + } + return false; + } + + // First create branch, by calling ourself recursively + create_directories(p.parent_path(), ec); + // Now that parent's path exists, create the directory + create_directory(p, ec); + return true; + } + + BOOST_FILESYSTEM_DECL + bool create_directory(const path& p, error_code* ec) + { + if (BOOST_CREATE_DIRECTORY(p.c_str())) + { + if (ec != 0) ec->clear(); + return true; + } + + // attempt to create directory failed + int errval(BOOST_ERRNO); // save reason for failure + error_code dummy; + if (errval == BOOST_ERROR_ALREADY_EXISTS && is_directory(p, dummy)) + { + if (ec != 0) ec->clear(); + return false; + } + + // attempt to create directory failed && it doesn't already exist + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::create_directory", + p, error_code(errval, system_category()))); + else + ec->assign(errval, system_category()); + return false; + } + + BOOST_FILESYSTEM_DECL + void create_directory_symlink(const path& to, const path& from, + system::error_code* ec) + { +# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0600 // SDK earlier than Vista and Server 2008 + + error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), to, from, ec, + "boost::filesystem::create_directory_symlink"); +# else + +# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT >= 0x0600 + // see if actually supported by Windows runtime dll + if (error(!create_symbolic_link_api, + error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), + to, from, ec, + "boost::filesystem::create_directory_symlink")) + return; +# endif + + error(!BOOST_CREATE_SYMBOLIC_LINK(from.c_str(), to.c_str(), SYMBOLIC_LINK_FLAG_DIRECTORY), + to, from, ec, "boost::filesystem::create_directory_symlink"); +# endif + } + + BOOST_FILESYSTEM_DECL + void create_hard_link(const path& to, const path& from, error_code* ec) + { + +# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0500 // SDK earlier than Win 2K + + error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), to, from, ec, + "boost::filesystem::create_hard_link"); +# else + +# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT >= 0x0500 + // see if actually supported by Windows runtime dll + if (error(!create_hard_link_api, + error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), + to, from, ec, + "boost::filesystem::create_hard_link")) + return; +# endif + + error(!BOOST_CREATE_HARD_LINK(from.c_str(), to.c_str()), to, from, ec, + "boost::filesystem::create_hard_link"); +# endif + } + + BOOST_FILESYSTEM_DECL + void create_symlink(const path& to, const path& from, error_code* ec) + { +# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0600 // SDK earlier than Vista and Server 2008 + error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), to, from, ec, + "boost::filesystem::create_directory_symlink"); +# else + +# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT >= 0x0600 + // see if actually supported by Windows runtime dll + if (error(!create_symbolic_link_api, + error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), + to, from, ec, + "boost::filesystem::create_symlink")) + return; +# endif + + error(!BOOST_CREATE_SYMBOLIC_LINK(from.c_str(), to.c_str(), 0), + to, from, ec, "boost::filesystem::create_symlink"); +# endif + } + + BOOST_FILESYSTEM_DECL + path current_path(error_code* ec) + { +# ifdef BOOST_POSIX_API + path cur; + for (long path_max = 128;; path_max *=2)// loop 'til buffer large enough + { + boost::scoped_array<char> + buf(new char[static_cast<std::size_t>(path_max)]); + if (::getcwd(buf.get(), static_cast<std::size_t>(path_max))== 0) + { + if (error(errno != ERANGE + // bug in some versions of the Metrowerks C lib on the Mac: wrong errno set +# if defined(__MSL__) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) + && errno != 0 +# endif + , ec, "boost::filesystem::current_path")) + { + break; + } + } + else + { + cur = buf.get(); + if (ec != 0) ec->clear(); + break; + } + } + return cur; + +# else + DWORD sz; + if ((sz = ::GetCurrentDirectoryW(0, NULL))== 0)sz = 1; + boost::scoped_array<path::value_type> buf(new path::value_type[sz]); + error(::GetCurrentDirectoryW(sz, buf.get())== 0, ec, + "boost::filesystem::current_path"); + return path(buf.get()); +# endif + } + + + BOOST_FILESYSTEM_DECL + void current_path(const path& p, system::error_code* ec) + { + error(!BOOST_SET_CURRENT_DIRECTORY(p.c_str()), + p, ec, "boost::filesystem::current_path"); + } + + BOOST_FILESYSTEM_DECL + bool equivalent(const path& p1, const path& p2, system::error_code* ec) + { +# ifdef BOOST_POSIX_API + struct stat s2; + int e2(::stat(p2.c_str(), &s2)); + struct stat s1; + int e1(::stat(p1.c_str(), &s1)); + + if (e1 != 0 || e2 != 0) + { + // if one is invalid and the other isn't then they aren't equivalent, + // but if both are invalid then it is an error + error (e1 != 0 && e2 != 0, p1, p2, ec, "boost::filesystem::equivalent"); + return false; + } + + // both stats now known to be valid + return s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino + // According to the POSIX stat specs, "The st_ino and st_dev fields + // taken together uniquely identify the file within the system." + // Just to be sure, size and mod time are also checked. + && s1.st_size == s2.st_size && s1.st_mtime == s2.st_mtime; + +# else // Windows + + // Note well: Physical location on external media is part of the + // equivalence criteria. If there are no open handles, physical location + // can change due to defragmentation or other relocations. Thus handles + // must be held open until location information for both paths has + // been retrieved. + + // p2 is done first, so any error reported is for p1 + handle_wrapper h2( + create_file_handle( + p2.c_str(), + 0, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + 0)); + + handle_wrapper h1( + create_file_handle( + p1.c_str(), + 0, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + 0)); + + if (h1.handle == INVALID_HANDLE_VALUE + || h2.handle == INVALID_HANDLE_VALUE) + { + // if one is invalid and the other isn't, then they aren't equivalent, + // but if both are invalid then it is an error + error(h1.handle == INVALID_HANDLE_VALUE + && h2.handle == INVALID_HANDLE_VALUE, p1, p2, ec, + "boost::filesystem::equivalent"); + return false; + } + + // at this point, both handles are known to be valid + + BY_HANDLE_FILE_INFORMATION info1, info2; + + if (error(!::GetFileInformationByHandle(h1.handle, &info1), + p1, p2, ec, "boost::filesystem::equivalent")) + return false; + + if (error(!::GetFileInformationByHandle(h2.handle, &info2), + p1, p2, ec, "boost::filesystem::equivalent")) + return false; + + // In theory, volume serial numbers are sufficient to distinguish between + // devices, but in practice VSN's are sometimes duplicated, so last write + // time and file size are also checked. + return + info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber + && info1.nFileIndexHigh == info2.nFileIndexHigh + && info1.nFileIndexLow == info2.nFileIndexLow + && info1.nFileSizeHigh == info2.nFileSizeHigh + && info1.nFileSizeLow == info2.nFileSizeLow + && info1.ftLastWriteTime.dwLowDateTime + == info2.ftLastWriteTime.dwLowDateTime + && info1.ftLastWriteTime.dwHighDateTime + == info2.ftLastWriteTime.dwHighDateTime; + +# endif + } + + BOOST_FILESYSTEM_DECL + boost::uintmax_t file_size(const path& p, error_code* ec) + { +# ifdef BOOST_POSIX_API + + struct stat path_stat; + if (error(::stat(p.c_str(), &path_stat)!= 0, + p, ec, "boost::filesystem::file_size")) + return static_cast<boost::uintmax_t>(-1); + if (error(!S_ISREG(path_stat.st_mode), + error_code(EPERM, system_category()), + p, ec, "boost::filesystem::file_size")) + return static_cast<boost::uintmax_t>(-1); + + return static_cast<boost::uintmax_t>(path_stat.st_size); + +# else // Windows + + // assume uintmax_t is 64-bits on all Windows compilers + + WIN32_FILE_ATTRIBUTE_DATA fad; + + if (error(::GetFileAttributesExW(p.c_str(), ::GetFileExInfoStandard, &fad)== 0, + p, ec, "boost::filesystem::file_size")) + return static_cast<boost::uintmax_t>(-1); + + if (error((fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)!= 0, + error_code(ERROR_NOT_SUPPORTED, system_category()), + p, ec, "boost::filesystem::file_size")) + return static_cast<boost::uintmax_t>(-1); + + return (static_cast<boost::uintmax_t>(fad.nFileSizeHigh) + << (sizeof(fad.nFileSizeLow)*8)) + fad.nFileSizeLow; +# endif + } + + BOOST_FILESYSTEM_DECL + boost::uintmax_t hard_link_count(const path& p, system::error_code* ec) + { +# ifdef BOOST_POSIX_API + + struct stat path_stat; + return error(::stat(p.c_str(), &path_stat)!= 0, + p, ec, "boost::filesystem::hard_link_count") + ? 0 + : static_cast<boost::uintmax_t>(path_stat.st_nlink); + +# else // Windows + + // Link count info is only available through GetFileInformationByHandle + BY_HANDLE_FILE_INFORMATION info; + handle_wrapper h( + create_file_handle(p.c_str(), 0, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); + return + !error(h.handle == INVALID_HANDLE_VALUE, + p, ec, "boost::filesystem::hard_link_count") + && !error(::GetFileInformationByHandle(h.handle, &info)== 0, + p, ec, "boost::filesystem::hard_link_count") + ? info.nNumberOfLinks + : 0; +# endif + } + + BOOST_FILESYSTEM_DECL + path initial_path(error_code* ec) + { + static path init_path; + if (init_path.empty()) + init_path = current_path(ec); + else if (ec != 0) ec->clear(); + return init_path; + } + + BOOST_FILESYSTEM_DECL + bool is_empty(const path& p, system::error_code* ec) + { +# ifdef BOOST_POSIX_API + + struct stat path_stat; + if (error(::stat(p.c_str(), &path_stat)!= 0, + p, ec, "boost::filesystem::is_empty")) + return false; + return S_ISDIR(path_stat.st_mode) + ? is_empty_directory(p) + : path_stat.st_size == 0; +# else + + WIN32_FILE_ATTRIBUTE_DATA fad; + if (error(::GetFileAttributesExW(p.c_str(), ::GetFileExInfoStandard, &fad)== 0, + p, ec, "boost::filesystem::is_empty")) + return false; + + if (ec != 0) ec->clear(); + return + (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + ? is_empty_directory(p) + : (!fad.nFileSizeHigh && !fad.nFileSizeLow); +# endif + } + + BOOST_FILESYSTEM_DECL + std::time_t last_write_time(const path& p, system::error_code* ec) + { +# ifdef BOOST_POSIX_API + + struct stat path_stat; + if (error(::stat(p.c_str(), &path_stat)!= 0, + p, ec, "boost::filesystem::last_write_time")) + return std::time_t(-1); + return path_stat.st_mtime; + +# else + + handle_wrapper hw( + create_file_handle(p.c_str(), 0, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); + + if (error(hw.handle == INVALID_HANDLE_VALUE, + p, ec, "boost::filesystem::last_write_time")) + return std::time_t(-1); + + FILETIME lwt; + + if (error(::GetFileTime(hw.handle, 0, 0, &lwt)== 0, + p, ec, "boost::filesystem::last_write_time")) + return std::time_t(-1); + + return to_time_t(lwt); +# endif + } + + BOOST_FILESYSTEM_DECL + void last_write_time(const path& p, const std::time_t new_time, + system::error_code* ec) + { +# ifdef BOOST_POSIX_API + + struct stat path_stat; + if (error(::stat(p.c_str(), &path_stat)!= 0, + p, ec, "boost::filesystem::last_write_time")) + return; + ::utimbuf buf; + buf.actime = path_stat.st_atime; // utime()updates access time too:-( + buf.modtime = new_time; + error(::utime(p.c_str(), &buf)!= 0, + p, ec, "boost::filesystem::last_write_time"); + +# else + + handle_wrapper hw( + create_file_handle(p.c_str(), FILE_WRITE_ATTRIBUTES, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); + + if (error(hw.handle == INVALID_HANDLE_VALUE, + p, ec, "boost::filesystem::last_write_time")) + return; + + FILETIME lwt; + to_FILETIME(new_time, lwt); + + error(::SetFileTime(hw.handle, 0, 0, &lwt)== 0, + p, ec, "boost::filesystem::last_write_time"); +# endif + } + + BOOST_FILESYSTEM_DECL + path read_symlink(const path& p, system::error_code* ec) + { + path symlink_path; + +# ifdef BOOST_POSIX_API + + for (std::size_t path_max = 64;; path_max *= 2)// loop 'til buffer large enough + { + boost::scoped_array<char> buf(new char[path_max]); + ssize_t result; + if ((result=::readlink(p.c_str(), buf.get(), path_max))== -1) + { + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::read_symlink", + p, error_code(errno, system_category()))); + else ec->assign(errno, system_category()); + break; + } + else + { + if(result != static_cast<ssize_t>(path_max)) + { + symlink_path.assign(buf.get(), buf.get() + result); + if (ec != 0) ec->clear(); + break; + } + } + } + +# elif _WIN32_WINNT < 0x0600 // SDK earlier than Vista and Server 2008 + error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), p, ec, + "boost::filesystem::read_symlink"); +# else // Vista and Server 2008 SDK, or later + + union info_t + { + char buf[REPARSE_DATA_BUFFER_HEADER_SIZE+MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + REPARSE_DATA_BUFFER rdb; + } info; + + handle_wrapper h( + create_file_handle(p.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0)); + + if (error(h.handle == INVALID_HANDLE_VALUE, p, ec, "boost::filesystem::read_symlink")) + return symlink_path; + + DWORD sz; + + if (!error(::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT, + 0, 0, info.buf, sizeof(info), &sz, 0) == 0, p, ec, + "boost::filesystem::read_symlink" )) + symlink_path.assign( + static_cast<wchar_t*>(info.rdb.SymbolicLinkReparseBuffer.PathBuffer) + + info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(wchar_t), + static_cast<wchar_t*>(info.rdb.SymbolicLinkReparseBuffer.PathBuffer) + + info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(wchar_t) + + info.rdb.SymbolicLinkReparseBuffer.PrintNameLength/sizeof(wchar_t)); +# endif + return symlink_path; + } + + BOOST_FILESYSTEM_DECL + bool remove(const path& p, error_code* ec) + { + error_code tmp_ec; + file_type type = query_file_type(p, &tmp_ec); + if (error(type == status_error, tmp_ec, p, ec, + "boost::filesystem::remove")) + return false; + + // Since POSIX remove() is specified to work with either files or directories, in a + // perfect world it could just be called. But some important real-world operating + // systems (Windows, Mac OS X, for example) don't implement the POSIX spec. So + // remove_file_or_directory() is always called to kep it simple. + return remove_file_or_directory(p, type, ec); + } + + BOOST_FILESYSTEM_DECL + boost::uintmax_t remove_all(const path& p, error_code* ec) + { + error_code tmp_ec; + file_type type = query_file_type(p, &tmp_ec); + if (error(type == status_error, tmp_ec, p, ec, + "boost::filesystem::remove_all")) + return 0; + + return (type != status_error && type != file_not_found) // exists + ? remove_all_aux(p, type, ec) + : 0; + } + + BOOST_FILESYSTEM_DECL + void rename(const path& old_p, const path& new_p, error_code* ec) + { + error(!BOOST_MOVE_FILE(old_p.c_str(), new_p.c_str()), old_p, new_p, ec, + "boost::filesystem::rename"); + } + + BOOST_FILESYSTEM_DECL + void resize_file(const path& p, uintmax_t size, system::error_code* ec) + { + error(!BOOST_RESIZE_FILE(p.c_str(), size), p, ec, "boost::filesystem::resize_file"); + } + + BOOST_FILESYSTEM_DECL + space_info space(const path& p, error_code* ec) + { +# ifdef BOOST_POSIX_API + struct BOOST_STATVFS vfs; + space_info info; + if (!error(::BOOST_STATVFS(p.c_str(), &vfs)!= 0, + p, ec, "boost::filesystem::space")) + { + info.capacity + = static_cast<boost::uintmax_t>(vfs.f_blocks)* BOOST_STATVFS_F_FRSIZE; + info.free + = static_cast<boost::uintmax_t>(vfs.f_bfree)* BOOST_STATVFS_F_FRSIZE; + info.available + = static_cast<boost::uintmax_t>(vfs.f_bavail)* BOOST_STATVFS_F_FRSIZE; + } + +# else + ULARGE_INTEGER avail, total, free; + space_info info; + + if (!error(::GetDiskFreeSpaceExW(p.c_str(), &avail, &total, &free)== 0, + p, ec, "boost::filesystem::space")) + { + info.capacity + = (static_cast<boost::uintmax_t>(total.HighPart)<< 32) + + total.LowPart; + info.free + = (static_cast<boost::uintmax_t>(free.HighPart)<< 32) + + free.LowPart; + info.available + = (static_cast<boost::uintmax_t>(avail.HighPart)<< 32) + + avail.LowPart; + } + +# endif + + else + { + info.capacity = info.free = info.available = 0; + } + return info; + } + + BOOST_FILESYSTEM_DECL + file_status status(const path& p, error_code* ec) + { +# ifdef BOOST_POSIX_API + + struct stat path_stat; + if (::stat(p.c_str(), &path_stat)!= 0) + { + if (ec != 0) // always report errno, even though some + ec->assign(errno, system_category()); // errno values are not status_errors + + if (not_found_error(errno)) + { + return fs::file_status(fs::file_not_found); + } + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status", + p, error_code(errno, system_category()))); + return fs::file_status(fs::status_error); + } + if (ec != 0) ec->clear();; + if (S_ISDIR(path_stat.st_mode)) + return fs::file_status(fs::directory_file); + if (S_ISREG(path_stat.st_mode)) + return fs::file_status(fs::regular_file); + if (S_ISBLK(path_stat.st_mode)) + return fs::file_status(fs::block_file); + if (S_ISCHR(path_stat.st_mode)) + return fs::file_status(fs::character_file); + if (S_ISFIFO(path_stat.st_mode)) + return fs::file_status(fs::fifo_file); + if (S_ISSOCK(path_stat.st_mode)) + return fs::file_status(fs::socket_file); + return fs::file_status(fs::type_unknown); + +# else // Windows + + DWORD attr(::GetFileAttributesW(p.c_str())); + if (attr == 0xFFFFFFFF) + { + return process_status_failure(p, ec); + } + + // reparse point handling + if (attr & FILE_ATTRIBUTE_REPARSE_POINT) + { + handle_wrapper h( + create_file_handle( + p.c_str(), + 0, // dwDesiredAccess; attributes only + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, // lpSecurityAttributes + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + 0)); // hTemplateFile + if (h.handle == INVALID_HANDLE_VALUE) + { + return process_status_failure(p, ec); + } + } + + if (ec != 0) ec->clear(); + return (attr & FILE_ATTRIBUTE_DIRECTORY) + ? file_status(directory_file) + : file_status(regular_file); + +# endif + } + + BOOST_FILESYSTEM_DECL + file_status symlink_status(const path& p, error_code* ec) + { +# ifdef BOOST_POSIX_API + + struct stat path_stat; + if (::lstat(p.c_str(), &path_stat)!= 0) + { + if (ec != 0) // always report errno, even though some + ec->assign(errno, system_category()); // errno values are not status_errors + + if (errno == ENOENT || errno == ENOTDIR) // these are not errors + { + return fs::file_status(fs::file_not_found); + } + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status", + p, error_code(errno, system_category()))); + return fs::file_status(fs::status_error); + } + if (ec != 0) ec->clear(); + if (S_ISREG(path_stat.st_mode)) + return fs::file_status(fs::regular_file); + if (S_ISDIR(path_stat.st_mode)) + return fs::file_status(fs::directory_file); + if (S_ISLNK(path_stat.st_mode)) + return fs::file_status(fs::symlink_file); + if (S_ISBLK(path_stat.st_mode)) + return fs::file_status(fs::block_file); + if (S_ISCHR(path_stat.st_mode)) + return fs::file_status(fs::character_file); + if (S_ISFIFO(path_stat.st_mode)) + return fs::file_status(fs::fifo_file); + if (S_ISSOCK(path_stat.st_mode)) + return fs::file_status(fs::socket_file); + return fs::file_status(fs::type_unknown); + +# else // Windows + + DWORD attr(::GetFileAttributesW(p.c_str())); + if (attr == 0xFFFFFFFF) + { + return process_status_failure(p, ec); + } + + if (ec != 0) ec->clear(); + + if (attr & FILE_ATTRIBUTE_REPARSE_POINT) + return is_reparse_point_a_symlink(p) + ? file_status(symlink_file) + : file_status(reparse_file); + + return (attr & FILE_ATTRIBUTE_DIRECTORY) + ? file_status(directory_file) + : file_status(regular_file); + +# endif + } + + BOOST_FILESYSTEM_DECL + path system_complete(const path& p, system::error_code* ec) + { +# ifdef BOOST_POSIX_API + return (p.empty() || p.is_absolute()) + ? p : current_path()/ p; + +# else + if (p.empty()) + { + if (ec != 0) ec->clear(); + return p; + } + wchar_t buf[buf_size]; + wchar_t* pfn; + std::size_t len = get_full_path_name(p, buf_size, buf, &pfn); + + if (error(len == 0, p, ec, "boost::filesystem::system_complete")) + return path(); + + if (len < buf_size)// len does not include null termination character + return path(&buf[0]); + + boost::scoped_array<wchar_t> big_buf(new wchar_t[len]); + + return error(get_full_path_name(p, len , big_buf.get(), &pfn)== 0, + p, ec, "boost::filesystem::system_complete") + ? path() + : path(big_buf.get()); +# endif + } + +} // namespace detail + +//--------------------------------------------------------------------------------------// +// // +// directory_entry // +// // +//--------------------------------------------------------------------------------------// + + file_status + directory_entry::m_get_status(system::error_code* ec) const + { + if (!status_known(m_status)) + { + // optimization: if the symlink status is known, and it isn't a symlink, + // then status and symlink_status are identical so just copy the + // symlink status to the regular status. + if (status_known(m_symlink_status) + && !is_symlink(m_symlink_status)) + { + m_status = m_symlink_status; + if (ec != 0) ec->clear(); + } + else m_status = detail::status(m_path, ec); + } + else if (ec != 0) ec->clear(); + return m_status; + } + + file_status + directory_entry::m_get_symlink_status(system::error_code* ec) const + { + if (!status_known(m_symlink_status)) + m_symlink_status = detail::symlink_status(m_path, ec); + else if (ec != 0) ec->clear(); + return m_symlink_status; + } + +// dispatch directory_entry supplied here rather than in +// <boost/filesystem/path_traits.hpp>, thus avoiding header circularity. +// test cases are in operations_unit_test.cpp + +namespace path_traits +{ + void dispatch(const directory_entry & de, +# ifdef BOOST_WINDOWS_API + std::wstring& to, +# else + std::string& to, +# endif + const codecvt_type &) + { + to = de.path().native(); + } + +} // namespace path_traits +} // namespace filesystem3 +} // namespace boost + +//--------------------------------------------------------------------------------------// +// // +// directory_iterator // +// // +//--------------------------------------------------------------------------------------// + +namespace +{ +# ifdef BOOST_POSIX_API + + error_code path_max(std::size_t & result) + // this code is based on Stevens and Rago, Advanced Programming in the + // UNIX envirnment, 2nd Ed., ISBN 0-201-43307-9, page 49 + { +# ifdef PATH_MAX + static std::size_t max = PATH_MAX; +# else + static std::size_t max = 0; +# endif + if (max == 0) + { + errno = 0; + long tmp = ::pathconf("/", _PC_NAME_MAX); + if (tmp < 0) + { + if (errno == 0)// indeterminate + max = 4096; // guess + else return error_code(errno, system_category()); + } + else max = static_cast<std::size_t>(tmp + 1); // relative root + } + result = max; + return ok; + } + + error_code dir_itr_first(void *& handle, void *& buffer, + const char* dir, string& target, + fs::file_status &, fs::file_status &) + { + if ((handle = ::opendir(dir))== 0) + return error_code(errno, system_category()); + target = string("."); // string was static but caused trouble + // when iteration called from dtor, after + // static had already been destroyed + std::size_t path_size (0); // initialization quiets gcc warning (ticket #3509) + error_code ec = path_max(path_size); + if (ec)return ec; + dirent de; + buffer = std::malloc((sizeof(dirent) - sizeof(de.d_name)) + + path_size + 1); // + 1 for "/0" + return ok; + } + + // warning: the only dirent member updated is d_name + inline int readdir_r_simulator(DIR * dirp, struct dirent * entry, + struct dirent ** result)// *result set to 0 on end of directory + { + errno = 0; + +# if !defined(__CYGWIN__)\ + && defined(_POSIX_THREAD_SAFE_FUNCTIONS)\ + && defined(_SC_THREAD_SAFE_FUNCTIONS)\ + && (_POSIX_THREAD_SAFE_FUNCTIONS+0 >= 0)\ + && (!defined(__hpux) || defined(_REENTRANT)) \ + && (!defined(_AIX) || defined(__THREAD_SAFE)) + if (::sysconf(_SC_THREAD_SAFE_FUNCTIONS)>= 0) + { return ::readdir_r(dirp, entry, result); } +# endif + + struct dirent * p; + *result = 0; + if ((p = ::readdir(dirp))== 0) + return errno; + std::strcpy(entry->d_name, p->d_name); + *result = entry; + return 0; + } + + error_code dir_itr_increment(void *& handle, void *& buffer, + string& target, fs::file_status & sf, fs::file_status & symlink_sf) + { + BOOST_ASSERT(buffer != 0); + dirent * entry(static_cast<dirent *>(buffer)); + dirent * result; + int return_code; + if ((return_code = readdir_r_simulator(static_cast<DIR*>(handle), + entry, &result))!= 0)return error_code(errno, system_category()); + if (result == 0) + return fs::detail::dir_itr_close(handle, buffer); + target = entry->d_name; +# ifdef BOOST_FILESYSTEM_STATUS_CACHE + if (entry->d_type == DT_UNKNOWN) // filesystem does not supply d_type value + { + sf = symlink_sf = fs::file_status(fs::status_error); + } + else // filesystem supplies d_type value + { + if (entry->d_type == DT_DIR) + sf = symlink_sf = fs::file_status(fs::directory_file); + else if (entry->d_type == DT_REG) + sf = symlink_sf = fs::file_status(fs::regular_file); + else if (entry->d_type == DT_LNK) + { + sf = fs::file_status(fs::status_error); + symlink_sf = fs::file_status(fs::symlink_file); + } + else sf = symlink_sf = fs::file_status(fs::status_error); + } +# else + sf = symlink_sf = fs::file_status(fs::status_error); +# endif + return ok; + } + +# else // BOOST_WINDOWS_API + + error_code dir_itr_first(void *& handle, const fs::path& dir, + wstring& target, fs::file_status & sf, fs::file_status & symlink_sf) + // Note: an empty root directory has no "." or ".." entries, so this + // causes a ERROR_FILE_NOT_FOUND error which we do not considered an + // error. It is treated as eof instead. + { + // use a form of search Sebastian Martel reports will work with Win98 + wstring dirpath(dir.wstring()); + dirpath += (dirpath.empty() + || (dirpath[dirpath.size()-1] != L'\\' + && dirpath[dirpath.size()-1] != L'/' + && dirpath[dirpath.size()-1] != L':'))? L"\\*" : L"*"; + + WIN32_FIND_DATAW data; + if ((handle = ::FindFirstFileW(dirpath.c_str(), &data)) + == INVALID_HANDLE_VALUE) + { + handle = 0; + return error_code( (::GetLastError() == ERROR_FILE_NOT_FOUND + // Windows Mobile returns ERROR_NO_MORE_FILES; see ticket #3551 + || ::GetLastError() == ERROR_NO_MORE_FILES) + ? 0 : ::GetLastError(), system_category() ); + } + target = data.cFileName; + if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { sf.type(fs::directory_file); symlink_sf.type(fs::directory_file); } + else { sf.type(fs::regular_file); symlink_sf.type(fs::regular_file); } + return error_code(); + } + + error_code dir_itr_increment(void *& handle, wstring& target, + fs::file_status & sf, fs::file_status & symlink_sf) + { + WIN32_FIND_DATAW data; + if (::FindNextFileW(handle, &data)== 0)// fails + { + int error = ::GetLastError(); + fs::detail::dir_itr_close(handle); + return error_code(error == ERROR_NO_MORE_FILES ? 0 : error, system_category()); + } + target = data.cFileName; + if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { sf.type(fs::directory_file); symlink_sf.type(fs::directory_file); } + else { sf.type(fs::regular_file); symlink_sf.type(fs::regular_file); } + return error_code(); + } +#endif + + const error_code not_found_error_code ( +# ifdef BOOST_WINDOWS_API + ERROR_PATH_NOT_FOUND +# else + ENOENT +# endif + , system_category()); + +} // unnamed namespace + +namespace boost +{ +namespace filesystem3 +{ + +namespace detail +{ + // dir_itr_close is called both from the ~dir_itr_imp()destructor + // and dir_itr_increment() + BOOST_FILESYSTEM_DECL + system::error_code dir_itr_close( // never throws + void *& handle +# if defined(BOOST_POSIX_API) + , void *& buffer +# endif + ) + { +# ifdef BOOST_POSIX_API + std::free(buffer); + buffer = 0; + if (handle == 0)return ok; + DIR * h(static_cast<DIR*>(handle)); + handle = 0; + return error_code(::closedir(h)== 0 ? 0 : errno, system_category()); + +# else + if (handle != 0) + { + ::FindClose(handle); + handle = 0; + } + return ok; + +# endif + } + + void directory_iterator_construct(directory_iterator& it, + const path& p, system::error_code* ec) + { + if (error(p.empty(), not_found_error_code, p, ec, + "boost::filesystem::directory_iterator::construct"))return; + + path::string_type filename; + file_status file_stat, symlink_file_stat; + error_code result = dir_itr_first(it.m_imp->handle, +# if defined(BOOST_POSIX_API) + it.m_imp->buffer, +# endif + p.c_str(), filename, file_stat, symlink_file_stat); + + if (result) + { + it.m_imp.reset(); + error(true, result, p, + ec, "boost::filesystem::directory_iterator::construct"); + return; + } + + if (it.m_imp->handle == 0)it.m_imp.reset(); // eof, so make end iterator + else // not eof + { + it.m_imp->dir_entry.assign(p / filename, + file_stat, symlink_file_stat); + if (filename[0] == dot // dot or dot-dot + && (filename.size()== 1 + || (filename[1] == dot + && filename.size()== 2))) + { it.increment(); } + } + } + + void directory_iterator_increment(directory_iterator& it, + system::error_code* ec) + { + BOOST_ASSERT(it.m_imp.get() && "attempt to increment end iterator"); + BOOST_ASSERT(it.m_imp->handle != 0 && "internal program error"); + + path::string_type filename; + file_status file_stat, symlink_file_stat; + system::error_code temp_ec; + + for (;;) + { + temp_ec = dir_itr_increment(it.m_imp->handle, +# if defined(BOOST_POSIX_API) + it.m_imp->buffer, +# endif + filename, file_stat, symlink_file_stat); + + if (temp_ec) + { + it.m_imp.reset(); + if (ec == 0) + BOOST_FILESYSTEM_THROW( + filesystem_error("boost::filesystem::directory_iterator::operator++", + it.m_imp->dir_entry.path().parent_path(), + error_code(BOOST_ERRNO, system_category()))); + ec->assign(BOOST_ERRNO, system_category()); + return; + } + else if (ec != 0) ec->clear(); + + if (it.m_imp->handle == 0){ it.m_imp.reset(); return; } // eof, make end + if (!(filename[0] == dot // !(dot or dot-dot) + && (filename.size()== 1 + || (filename[1] == dot + && filename.size()== 2)))) + { + it.m_imp->dir_entry.replace_filename( + filename, file_stat, symlink_file_stat); + return; + } + } + } +} // namespace detail +} // namespace filesystem3 +} // namespace boost + +#endif // no wide character support diff --git a/3rdParty/Boost/src/libs/filesystem/v3/src/path.cpp b/3rdParty/Boost/src/libs/filesystem/v3/src/path.cpp new file mode 100644 index 0000000..53a4cc6 --- /dev/null +++ b/3rdParty/Boost/src/libs/filesystem/v3/src/path.cpp @@ -0,0 +1,807 @@ +// filesystem path.cpp ------------------------------------------------------------- // + +// Copyright Beman Dawes 2008 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +#include <boost/config.hpp> +#if !defined( BOOST_NO_STD_WSTRING ) +// Boost.Filesystem V3 and later requires std::wstring support. +// During the transition to V3, libraries are compiled with both V2 and V3 sources. +// On old compilers that don't support V3 anyhow, we just skip everything so the compile +// will succeed and the library can be built. + +// define BOOST_FILESYSTEM_SOURCE so that <boost/system/config.hpp> knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_FILESYSTEM_SOURCE + +#ifndef BOOST_SYSTEM_NO_DEPRECATED +# define BOOST_SYSTEM_NO_DEPRECATED +#endif + +#include <boost/filesystem/v3/config.hpp> +#include <boost/filesystem/v3/path.hpp> +#include <boost/scoped_array.hpp> +#include <boost/system/error_code.hpp> +#include <boost/assert.hpp> +#include <cstddef> +#include <cstring> +#include <cassert> + +#ifdef BOOST_WINDOWS_API +# include "windows_file_codecvt.hpp" +# include <windows.h> +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +# include <boost/filesystem/detail/utf8_codecvt_facet.hpp> +#endif + +#ifdef BOOST_FILESYSTEM_DEBUG +# include <iostream> +# include <iomanip> +#endif + +namespace fs = boost::filesystem3; + +using boost::filesystem3::path; + +using std::string; +using std::wstring; + +using boost::system::error_code; + +#ifndef BOOST_FILESYSTEM_CODECVT_BUF_SIZE +# define BOOST_FILESYSTEM_CODECVT_BUF_SIZE 256 +#endif + +//--------------------------------------------------------------------------------------// +// // +// class path helpers // +// // +//--------------------------------------------------------------------------------------// + +namespace +{ + //------------------------------------------------------------------------------------// + // miscellaneous class path helpers // + //------------------------------------------------------------------------------------// + + typedef path::value_type value_type; + typedef path::string_type string_type; + typedef string_type::size_type size_type; + + const std::size_t default_codecvt_buf_size = BOOST_FILESYSTEM_CODECVT_BUF_SIZE; + +# ifdef BOOST_WINDOWS_API + + const wchar_t separator = L'/'; + const wchar_t preferred_separator = L'\\'; + const wchar_t* const separators = L"/\\"; + const wchar_t* separator_string = L"/"; + const wchar_t* preferred_separator_string = L"\\"; + const wchar_t colon = L':'; + const wchar_t dot = L'.'; + const fs::path dot_path(L"."); + const fs::path dot_dot_path(L".."); + +# else + + const char separator = '/'; + const char preferred_separator = '/'; + const char* const separators = "/"; + const char* separator_string = "/"; + const char* preferred_separator_string = "/"; + const char colon = ':'; + const char dot = '.'; + const fs::path dot_path("."); + const fs::path dot_dot_path(".."); + +# endif + + inline bool is_separator(fs::path::value_type c) + { + return c == separator +# ifdef BOOST_WINDOWS_API + || c == preferred_separator +# endif + ; + } + + bool is_non_root_separator(const string_type& str, size_type pos); + // pos is position of the separator + + size_type filename_pos(const string_type& str, + size_type end_pos); // end_pos is past-the-end position + // Returns: 0 if str itself is filename (or empty) + + size_type root_directory_start(const string_type& path, size_type size); + // Returns: npos if no root_directory found + + void first_element( + const string_type& src, + size_type& element_pos, + size_type& element_size, +# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1310) // VC++ 7.1 + size_type size = string_type::npos +# else + size_type size = -1 +# endif + ); + +} // unnamed namespace + +//--------------------------------------------------------------------------------------// +// // +// class path implementation // +// // +//--------------------------------------------------------------------------------------// + +namespace boost +{ +namespace filesystem3 +{ + + path & path::operator/=(const path & p) + { + if (p.empty()) + return *this; + if (!is_separator(*p.m_pathname.begin())) + m_append_separator_if_needed(); + m_pathname += p.m_pathname; + return *this; + } + +# ifdef BOOST_WINDOWS_API + + void path::m_portable() + { + for (string_type::iterator it = m_pathname.begin(); + it != m_pathname.end(); ++it) + { + if (*it == L'\\') + *it = L'/'; + } + } + + const std::string path::generic_string(const codecvt_type& cvt) const + { + path tmp(*this); + tmp.m_portable(); + return tmp.string(cvt); + } + + const std::wstring path::generic_wstring() const + { + path tmp(*this); + tmp.m_portable(); + return tmp.wstring(); + } + +# endif // BOOST_WINDOWS_API + + // m_append_separator_if_needed ----------------------------------------------------// + + path::string_type::size_type path::m_append_separator_if_needed() + { + if (!m_pathname.empty() && +# ifdef BOOST_WINDOWS_API + *(m_pathname.end()-1) != colon && +# endif + !is_separator(*(m_pathname.end()-1))) + { + string_type::size_type tmp(m_pathname.size()); + m_pathname += preferred_separator; + return tmp; + } + return 0; + } + + // m_erase_redundant_separator -----------------------------------------------------// + + void path::m_erase_redundant_separator(string_type::size_type sep_pos) + { + if (sep_pos // a separator was added + && sep_pos < m_pathname.size() // and something was appended + && (m_pathname[sep_pos+1] == separator // and it was also separator +# ifdef BOOST_WINDOWS_API + || m_pathname[sep_pos+1] == preferred_separator // or preferred_separator +# endif +)) { m_pathname.erase(sep_pos, 1); } // erase the added separator + } + + // modifiers -----------------------------------------------------------------------// + +# ifdef BOOST_WINDOWS_API + path & path::make_preferred() + { + for (string_type::iterator it = m_pathname.begin(); + it != m_pathname.end(); ++it) + { + if (*it == L'/') + *it = L'\\'; + } + return *this; + } +# endif + + path& path::remove_filename() + { + m_pathname.erase(m_parent_path_end()); + return *this; + } + + path & path::replace_extension(const path & source) + { + // erase existing extension if any + size_type pos(m_pathname.rfind(dot)); + if (pos != string_type::npos && pos >= filename_pos(m_pathname, m_pathname.size())) + m_pathname.erase(pos); + + // append source extension if any + pos = source.m_pathname.rfind(dot); + if (pos != string_type::npos) + m_pathname += source.c_str() + pos; + + return *this; + } + + // decomposition -------------------------------------------------------------------// + + path path::root_path() const + { + path temp(root_name()); + if (!root_directory().empty()) temp.m_pathname += root_directory().c_str(); + return temp; + } + + path path::root_name() const + { + iterator itr(begin()); + + return (itr.m_pos != m_pathname.size() + && ( + (itr.m_element.m_pathname.size() > 1 + && is_separator(itr.m_element.m_pathname[0]) + && is_separator(itr.m_element.m_pathname[1]) + ) +# ifdef BOOST_WINDOWS_API + || itr.m_element.m_pathname[itr.m_element.m_pathname.size()-1] == colon +# endif + )) + ? itr.m_element + : path(); + } + + path path::root_directory() const + { + size_type pos(root_directory_start(m_pathname, m_pathname.size())); + + return pos == string_type::npos + ? path() + : path(m_pathname.c_str() + pos, m_pathname.c_str() + pos + 1); + } + + path path::relative_path() const + { + iterator itr(begin()); + + for (; itr.m_pos != m_pathname.size() + && (is_separator(itr.m_element.m_pathname[0]) +# ifdef BOOST_WINDOWS_API + || itr.m_element.m_pathname[itr.m_element.m_pathname.size()-1] == colon +# endif + ); ++itr) {} + + return path(m_pathname.c_str() + itr.m_pos); + } + + string_type::size_type path::m_parent_path_end() const + { + size_type end_pos(filename_pos(m_pathname, m_pathname.size())); + + bool filename_was_separator(m_pathname.size() + && is_separator(m_pathname[end_pos])); + + // skip separators unless root directory + size_type root_dir_pos(root_directory_start(m_pathname, end_pos)); + for (; + end_pos > 0 + && (end_pos-1) != root_dir_pos + && is_separator(m_pathname[end_pos-1]) + ; + --end_pos) {} + + return (end_pos == 1 && root_dir_pos == 0 && filename_was_separator) + ? string_type::npos + : end_pos; + } + + path path::parent_path() const + { + size_type end_pos(m_parent_path_end()); + return end_pos == string_type::npos + ? path() + : path(m_pathname.c_str(), m_pathname.c_str() + end_pos); + } + + path path::filename() const + { + size_type pos(filename_pos(m_pathname, m_pathname.size())); + return (m_pathname.size() + && pos + && is_separator(m_pathname[pos]) + && is_non_root_separator(m_pathname, pos)) + ? dot_path + : path(m_pathname.c_str() + pos); + } + + path path::stem() const + { + path name(filename()); + if (name == dot_path || name == dot_dot_path) return name; + size_type pos(name.m_pathname.rfind(dot)); + return pos == string_type::npos + ? name + : path(name.m_pathname.c_str(), name.m_pathname.c_str() + pos); + } + + path path::extension() const + { + path name(filename()); + if (name == dot_path || name == dot_dot_path) return path(); + size_type pos(name.m_pathname.rfind(dot)); + return pos == string_type::npos + ? path() + : path(name.m_pathname.c_str() + pos); + } + + // m_normalize ----------------------------------------------------------------------// + + path& path::m_normalize() + { + if (m_pathname.empty()) return *this; + + path temp; + iterator start(begin()); + iterator last(end()); + iterator stop(last--); + for (iterator itr(start); itr != stop; ++itr) + { + // ignore "." except at start and last + if (itr->native().size() == 1 + && (itr->native())[0] == dot + && itr != start + && itr != last) continue; + + // ignore a name and following ".." + if (!temp.empty() + && itr->native().size() == 2 + && (itr->native())[0] == dot + && (itr->native())[1] == dot) // dot dot + { + string_type lf(temp.filename().native()); + if (lf.size() > 0 + && (lf.size() != 1 + || (lf[0] != dot + && lf[0] != separator)) + && (lf.size() != 2 + || (lf[0] != dot + && lf[1] != dot +# ifdef BOOST_WINDOWS_API + && lf[1] != colon +# endif + ) + ) + ) + { + temp.remove_filename(); + // if not root directory, must also remove "/" if any + if (temp.m_pathname.size() > 0 + && temp.m_pathname[temp.m_pathname.size()-1] + == separator) + { + string_type::size_type rds( + root_directory_start(temp.m_pathname, temp.m_pathname.size())); + if (rds == string_type::npos + || rds != temp.m_pathname.size()-1) + { temp.m_pathname.erase(temp.m_pathname.size()-1); } + } + + iterator next(itr); + if (temp.empty() && ++next != stop + && next == last && *last == dot_path) temp /= dot_path; + continue; + } + } + + temp /= *itr; + }; + + if (temp.empty()) temp /= dot_path; + m_pathname = temp.m_pathname; + return *this; + } + +} // namespace filesystem3 +} // namespace boost + +//--------------------------------------------------------------------------------------// +// // +// class path helpers implementation // +// // +//--------------------------------------------------------------------------------------// + +namespace +{ + + // is_non_root_separator -------------------------------------------------// + + bool is_non_root_separator(const string_type & str, size_type pos) + // pos is position of the separator + { + BOOST_ASSERT(!str.empty() && is_separator(str[pos]) + && "precondition violation"); + + // subsequent logic expects pos to be for leftmost slash of a set + while (pos > 0 && is_separator(str[pos-1])) + --pos; + + return pos != 0 + && (pos <= 2 || !is_separator(str[1]) + || str.find_first_of(separators, 2) != pos) +# ifdef BOOST_WINDOWS_API + && (pos !=2 || str[1] != colon) +# endif + ; + } + + // filename_pos --------------------------------------------------------------------// + + size_type filename_pos(const string_type & str, + size_type end_pos) // end_pos is past-the-end position + // return 0 if str itself is filename (or empty) + { + // case: "//" + if (end_pos == 2 + && is_separator(str[0]) + && is_separator(str[1])) return 0; + + // case: ends in "/" + if (end_pos && is_separator(str[end_pos-1])) + return end_pos-1; + + // set pos to start of last element + size_type pos(str.find_last_of(separators, end_pos-1)); + +# ifdef BOOST_WINDOWS_API + if (pos == string_type::npos) + pos = str.find_last_of(colon, end_pos-2); +# endif + + return (pos == string_type::npos // path itself must be a filename (or empty) + || (pos == 1 && is_separator(str[0]))) // or net + ? 0 // so filename is entire string + : pos + 1; // or starts after delimiter + } + + // root_directory_start ------------------------------------------------------------// + + size_type root_directory_start(const string_type & path, size_type size) + // return npos if no root_directory found + { + +# ifdef BOOST_WINDOWS_API + // case "c:/" + if (size > 2 + && path[1] == colon + && is_separator(path[2])) return 2; +# endif + + // case "//" + if (size == 2 + && is_separator(path[0]) + && is_separator(path[1])) return string_type::npos; + + // case "//net {/}" + if (size > 3 + && is_separator(path[0]) + && is_separator(path[1]) + && !is_separator(path[2])) + { + string_type::size_type pos(path.find_first_of(separators, 2)); + return pos < size ? pos : string_type::npos; + } + + // case "/" + if (size > 0 && is_separator(path[0])) return 0; + + return string_type::npos; + } + + // first_element --------------------------------------------------------------------// + // sets pos and len of first element, excluding extra separators + // if src.empty(), sets pos,len, to 0,0. + + void first_element( + const string_type & src, + size_type & element_pos, + size_type & element_size, + size_type size +) + { + if (size == string_type::npos) size = src.size(); + element_pos = 0; + element_size = 0; + if (src.empty()) return; + + string_type::size_type cur(0); + + // deal with // [network] + if (size >= 2 && is_separator(src[0]) + && is_separator(src[1]) + && (size == 2 + || !is_separator(src[2]))) + { + cur += 2; + element_size += 2; + } + + // leading (not non-network) separator + else if (is_separator(src[0])) + { + ++element_size; + // bypass extra leading separators + while (cur+1 < size + && is_separator(src[cur+1])) + { + ++cur; + ++element_pos; + } + return; + } + + // at this point, we have either a plain name, a network name, + // or (on Windows only) a device name + + // find the end + while (cur < size +# ifdef BOOST_WINDOWS_API + && src[cur] != colon +# endif + && !is_separator(src[cur])) + { + ++cur; + ++element_size; + } + +# ifdef BOOST_WINDOWS_API + if (cur == size) return; + // include device delimiter + if (src[cur] == colon) + { ++element_size; } +# endif + + return; + } + +} // unnammed namespace + +//--------------------------------------------------------------------------------------// +// // +// class path::iterator implementation // +// // +//--------------------------------------------------------------------------------------// + +namespace boost +{ +namespace filesystem3 +{ + + path::iterator path::begin() const + { + iterator itr; + itr.m_path_ptr = this; + size_type element_size; + first_element(m_pathname, itr.m_pos, element_size); + itr.m_element = m_pathname.substr(itr.m_pos, element_size); + if (itr.m_element.m_pathname == preferred_separator_string) + itr.m_element.m_pathname = separator_string; // needed for Windows, harmless on POSIX + return itr; + } + + path::iterator path::end() const + { + iterator itr; + itr.m_path_ptr = this; + itr.m_pos = m_pathname.size(); + return itr; + } + + void path::m_path_iterator_increment(path::iterator & it) + { + BOOST_ASSERT(it.m_pos < it.m_path_ptr->m_pathname.size() && "path::basic_iterator increment past end()"); + + // increment to position past current element + it.m_pos += it.m_element.m_pathname.size(); + + // if end reached, create end basic_iterator + if (it.m_pos == it.m_path_ptr->m_pathname.size()) + { + it.m_element.clear(); + return; + } + + // both POSIX and Windows treat paths that begin with exactly two separators specially + bool was_net(it.m_element.m_pathname.size() > 2 + && is_separator(it.m_element.m_pathname[0]) + && is_separator(it.m_element.m_pathname[1]) + && !is_separator(it.m_element.m_pathname[2])); + + // process separator (Windows drive spec is only case not a separator) + if (is_separator(it.m_path_ptr->m_pathname[it.m_pos])) + { + // detect root directory + if (was_net +# ifdef BOOST_WINDOWS_API + // case "c:/" + || it.m_element.m_pathname[it.m_element.m_pathname.size()-1] == colon +# endif + ) + { + it.m_element.m_pathname = separator; + return; + } + + // bypass separators + while (it.m_pos != it.m_path_ptr->m_pathname.size() + && is_separator(it.m_path_ptr->m_pathname[it.m_pos])) + { ++it.m_pos; } + + // detect trailing separator, and treat it as ".", per POSIX spec + if (it.m_pos == it.m_path_ptr->m_pathname.size() + && is_non_root_separator(it.m_path_ptr->m_pathname, it.m_pos-1)) + { + --it.m_pos; + it.m_element = dot_path; + return; + } + } + + // get next element + size_type end_pos(it.m_path_ptr->m_pathname.find_first_of(separators, it.m_pos)); + if (end_pos == string_type::npos) end_pos = it.m_path_ptr->m_pathname.size(); + it.m_element = it.m_path_ptr->m_pathname.substr(it.m_pos, end_pos - it.m_pos); + } + + void path::m_path_iterator_decrement(path::iterator & it) + { + BOOST_ASSERT(it.m_pos && "path::iterator decrement past begin()"); + + size_type end_pos(it.m_pos); + + // if at end and there was a trailing non-root '/', return "." + if (it.m_pos == it.m_path_ptr->m_pathname.size() + && it.m_path_ptr->m_pathname.size() > 1 + && is_separator(it.m_path_ptr->m_pathname[it.m_pos-1]) + && is_non_root_separator(it.m_path_ptr->m_pathname, it.m_pos-1) + ) + { + --it.m_pos; + it.m_element = dot_path; + return; + } + + size_type root_dir_pos(root_directory_start(it.m_path_ptr->m_pathname, end_pos)); + + // skip separators unless root directory + for ( + ; + end_pos > 0 + && (end_pos-1) != root_dir_pos + && is_separator(it.m_path_ptr->m_pathname[end_pos-1]) + ; + --end_pos) {} + + it.m_pos = filename_pos(it.m_path_ptr->m_pathname, end_pos); + it.m_element = it.m_path_ptr->m_pathname.substr(it.m_pos, end_pos - it.m_pos); + if (it.m_element.m_pathname == preferred_separator_string) + it.m_element.m_pathname = separator_string; // needed for Windows, harmless on POSIX + } + +} // namespace filesystem3 +} // namespace boost + +//--------------------------------------------------------------------------------------// +// // +// detail helpers // +// // +//--------------------------------------------------------------------------------------// + +namespace +{ + + //------------------------------------------------------------------------------------// + // locale helpers // + //------------------------------------------------------------------------------------// + + // std::locale construction can throw (if LC_MESSAGES is wrong, for example), + // so a static at function scope is used to ensure that exceptions can be + // caught. (A previous version was at namespace scope, so initialization + // occurred before main(), preventing exceptions from being caught.) + + std::locale default_locale() + { +# ifdef BOOST_WINDOWS_API + std::locale global_loc = std::locale(); + std::locale loc(global_loc, new windows_file_codecvt); + return loc; + +# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + // "All BSD system functions expect their string parameters to be in UTF-8 encoding + // and nothing else." http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPInternational/Articles/FileEncodings.html + // + // "The kernel will reject any filename that is not a valid UTF-8 string, and it will + // even be normalized (to Unicode NFD) before stored on disk, at least when using HFS. + // The right way to deal with it would be to always convert the filename to UTF-8 + // before trying to open/create a file." http://lists.apple.com/archives/unix-porting/2007/Sep/msg00023.html + // + // "How a file name looks at the API level depends on the API. Current Carbon APIs + // handle file names as an array of UTF-16 characters; POSIX ones handle them as an + // array of UTF-8, which is why UTF-8 works well in Terminal. How it's stored on disk + // depends on the disk format; HFS+ uses UTF-16, but that's not important in most + // cases." http://lists.apple.com/archives/applescript-users/2002/Sep/msg00319.html + // + // Many thanks to Peter Dimov for digging out the above references! + std::locale global_loc = std::locale(); + std::locale loc(global_loc, new boost::filesystem::detail::utf8_codecvt_facet); + return loc; + +# else + // ISO C calls this "the locale-specific native environment": + return std::locale(""); + +# endif + } + + std::locale & path_locale() + { + static std::locale loc(default_locale()); + return loc; + } + +} // unnamed namespace + +//--------------------------------------------------------------------------------------// +// path::imbue implementation // +//--------------------------------------------------------------------------------------// + +namespace boost +{ +namespace filesystem3 +{ + + const path::codecvt_type *& + path::wchar_t_codecvt_facet() + { + static const std::codecvt<wchar_t, char, std::mbstate_t> * + facet( + &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> > + (path_locale())); + return facet; + } + + std::locale path::imbue(const std::locale & loc) + { + std::locale temp(path_locale()); + path_locale() = loc; + wchar_t_codecvt_facet() = &std::use_facet + <std::codecvt<wchar_t, char, std::mbstate_t> >(path_locale()); + return temp; + } + +} // namespace filesystem3 +} // namespace boost + +#endif // no wide character support diff --git a/3rdParty/Boost/src/libs/filesystem/v3/src/path_traits.cpp b/3rdParty/Boost/src/libs/filesystem/v3/src/path_traits.cpp new file mode 100644 index 0000000..6606437 --- /dev/null +++ b/3rdParty/Boost/src/libs/filesystem/v3/src/path_traits.cpp @@ -0,0 +1,209 @@ +// filesystem path_traits.cpp --------------------------------------------------------// + +// Copyright Beman Dawes 2008, 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#include <boost/config.hpp> +#if !defined( BOOST_NO_STD_WSTRING ) +// Boost.Filesystem V3 and later requires std::wstring support. +// During the transition to V3, libraries are compiled with both V2 and V3 sources. +// On old compilers that don't support V3 anyhow, we just skip everything so the compile +// will succeed and the library can be built. + +// define BOOST_FILESYSTEM_SOURCE so that <boost/system/config.hpp> knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_FILESYSTEM_SOURCE + +#ifndef BOOST_SYSTEM_NO_DEPRECATED +# define BOOST_SYSTEM_NO_DEPRECATED +#endif + +#include <boost/filesystem/v3/config.hpp> +#include <boost/filesystem/v3/path_traits.hpp> +#include <boost/system/system_error.hpp> +#include <boost/scoped_array.hpp> +#include <locale> // for codecvt_base::result +#include <cstring> // for strlen +#include <cwchar> // for wcslen + +namespace pt = boost::filesystem3::path_traits; +namespace fs = boost::filesystem3; +namespace bs = boost::system; + +//--------------------------------------------------------------------------------------// +// configuration // +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_CODECVT_BUF_SIZE +# define BOOST_FILESYSTEM_CODECVT_BUF_SIZE 256 +#endif + +namespace { + + const std::size_t default_codecvt_buf_size = BOOST_FILESYSTEM_CODECVT_BUF_SIZE; + + +//--------------------------------------------------------------------------------------// +// // +// The public convert() functions do buffer management, and then forward to the // +// convert_aux() functions for the actual call to the codecvt facet. // +// // +//--------------------------------------------------------------------------------------// + +//--------------------------------------------------------------------------------------// +// convert_aux const char* to wstring // +//--------------------------------------------------------------------------------------// + + void convert_aux( + const char* from, + const char* from_end, + wchar_t* to, wchar_t* to_end, + std::wstring & target, + const pt::codecvt_type & cvt) + { + //std::cout << std::hex + // << " from=" << std::size_t(from) + // << " from_end=" << std::size_t(from_end) + // << " to=" << std::size_t(to) + // << " to_end=" << std::size_t(to_end) + // << std::endl; + + std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports + const char* from_next; + wchar_t* to_next; + + std::codecvt_base::result res; + + if ((res=cvt.in(state, from, from_end, from_next, + to, to_end, to_next)) != std::codecvt_base::ok) + { + //std::cout << " result is " << static_cast<int>(res) << std::endl; + BOOST_FILESYSTEM_THROW(bs::system_error(res, fs::codecvt_error_category(), + "boost::filesystem::path codecvt to wstring")); + } + target.append(to, to_next); + } + +//--------------------------------------------------------------------------------------// +// convert_aux const wchar_t* to string // +//--------------------------------------------------------------------------------------// + + void convert_aux( + const wchar_t* from, + const wchar_t* from_end, + char* to, char* to_end, + std::string & target, + const pt::codecvt_type & cvt) + { + //std::cout << std::hex + // << " from=" << std::size_t(from) + // << " from_end=" << std::size_t(from_end) + // << " to=" << std::size_t(to) + // << " to_end=" << std::size_t(to_end) + // << std::endl; + + std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports + const wchar_t* from_next; + char* to_next; + + std::codecvt_base::result res; + + if ((res=cvt.out(state, from, from_end, from_next, + to, to_end, to_next)) != std::codecvt_base::ok) + { + //std::cout << " result is " << static_cast<int>(res) << std::endl; + BOOST_FILESYSTEM_THROW(bs::system_error(res, fs::codecvt_error_category(), + "boost::filesystem::path codecvt to string")); + } + target.append(to, to_next); + } + +} // unnamed namespace + +//--------------------------------------------------------------------------------------// +// path_traits // +//--------------------------------------------------------------------------------------// + +namespace boost { namespace filesystem3 { namespace path_traits { + +//--------------------------------------------------------------------------------------// +// convert const char* to wstring // +//--------------------------------------------------------------------------------------// + + BOOST_FILESYSTEM_DECL + void convert(const char* from, + const char* from_end, // 0 for null terminated MBCS + std::wstring & to, + const codecvt_type & cvt) + { + BOOST_ASSERT(from); + + if (!from_end) // null terminated + { + from_end = from + std::strlen(from); + } + + if (from == from_end) return; + + std::size_t buf_size = (from_end - from) * 3; // perhaps too large, but that's OK + + // dynamically allocate a buffer only if source is unusually large + if (buf_size > default_codecvt_buf_size) + { + boost::scoped_array< wchar_t > buf(new wchar_t [buf_size]); + convert_aux(from, from_end, buf.get(), buf.get()+buf_size, to, cvt); + } + else + { + wchar_t buf[default_codecvt_buf_size]; + convert_aux(from, from_end, buf, buf+default_codecvt_buf_size, to, cvt); + } + } + +//--------------------------------------------------------------------------------------// +// convert const wchar_t* to string // +//--------------------------------------------------------------------------------------// + + BOOST_FILESYSTEM_DECL + void convert(const wchar_t* from, + const wchar_t* from_end, // 0 for null terminated MBCS + std::string & to, + const codecvt_type & cvt) + { + BOOST_ASSERT(from); + + if (!from_end) // null terminated + { + from_end = from + std::wcslen(from); + } + + if (from == from_end) return; + + // The codecvt length functions may not be implemented, and I don't really + // understand them either. Thus this code is just a guess; if it turns + // out the buffer is too small then an error will be reported and the code + // will have to be fixed. + std::size_t buf_size = (from_end - from) * 4; // perhaps too large, but that's OK + buf_size += 4; // encodings like shift-JIS need some prefix space + + // dynamically allocate a buffer only if source is unusually large + if (buf_size > default_codecvt_buf_size) + { + boost::scoped_array< char > buf(new char [buf_size]); + convert_aux(from, from_end, buf.get(), buf.get()+buf_size, to, cvt); + } + else + { + char buf[default_codecvt_buf_size]; + convert_aux(from, from_end, buf, buf+default_codecvt_buf_size, to, cvt); + } + } +}}} // namespace boost::filesystem3::path_traits + +#endif // no wide character support diff --git a/3rdParty/Boost/src/libs/filesystem/v3/src/portability.cpp b/3rdParty/Boost/src/libs/filesystem/v3/src/portability.cpp new file mode 100644 index 0000000..31e0176 --- /dev/null +++ b/3rdParty/Boost/src/libs/filesystem/v3/src/portability.cpp @@ -0,0 +1,128 @@ +// portability.cpp -------------------------------------------------------------------// + +// Copyright 2002-2005 Beman Dawes +// 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 library home page at http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#include <boost/config.hpp> +#if !defined( BOOST_NO_STD_WSTRING ) +// Boost.Filesystem V3 and later requires std::wstring support. +// During the transition to V3, libraries are compiled with both V2 and V3 sources. +// On old compilers that don't support V3 anyhow, we just skip everything so the compile +// will succeed and the library can be built. + +// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_FILESYSTEM_SOURCE + +#ifndef BOOST_SYSTEM_NO_DEPRECATED +# define BOOST_SYSTEM_NO_DEPRECATED +#endif + +#include <boost/filesystem/v3/config.hpp> +#include <boost/filesystem/v3/path.hpp> + +namespace fs = boost::filesystem3; + +#include <cstring> // SGI MIPSpro compilers need this + +# ifdef BOOST_NO_STDC_NAMESPACE + namespace std { using ::strerror; } +# endif + +//--------------------------------------------------------------------------------------// + +namespace +{ + const char invalid_chars[] = + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" + "<>:\"/\\|"; + // note that the terminating '\0' is part of the string - thus the size below + // is sizeof(invalid_chars) rather than sizeof(invalid_chars)-1. I + const std::string windows_invalid_chars(invalid_chars, sizeof(invalid_chars)); + + const std::string valid_posix( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"); + +} // unnamed namespace + +namespace boost +{ + namespace filesystem3 + { + + // name_check functions ----------------------------------------------// + +# ifdef BOOST_WINDOWS + BOOST_FILESYSTEM_DECL bool native(const std::string & name) + { + return windows_name(name); + } +# else + BOOST_FILESYSTEM_DECL bool native(const std::string & name) + { + return name.size() != 0 + && name[0] != ' ' + && name.find('/') == std::string::npos; + } +# endif + + BOOST_FILESYSTEM_DECL bool portable_posix_name(const std::string & name) + { + return name.size() != 0 + && name.find_first_not_of(valid_posix) == std::string::npos; + } + + BOOST_FILESYSTEM_DECL bool windows_name(const std::string & name) + { + return name.size() != 0 + && name[0] != ' ' + && name.find_first_of(windows_invalid_chars) == std::string::npos + && *(name.end()-1) != ' ' + && (*(name.end()-1) != '.' + || name.length() == 1 || name == ".."); + } + + BOOST_FILESYSTEM_DECL bool portable_name(const std::string & name) + { + return + name.size() != 0 + && (name == "." + || name == ".." + || (windows_name(name) + && portable_posix_name(name) + && name[0] != '.' && name[0] != '-')); + } + + BOOST_FILESYSTEM_DECL bool portable_directory_name(const std::string & name) + { + return + name == "." + || name == ".." + || (portable_name(name) + && name.find('.') == std::string::npos); + } + + BOOST_FILESYSTEM_DECL bool portable_file_name(const std::string & name) + { + std::string::size_type pos; + return + portable_name(name) + && name != "." + && name != ".." + && ((pos = name.find('.')) == std::string::npos + || (name.find('.', pos+1) == std::string::npos + && (pos + 5) > name.length())) + ; + } + + } // namespace filesystem3 +} // namespace boost + +#endif // no wide character support diff --git a/3rdParty/Boost/src/libs/filesystem/v3/src/unique_path.cpp b/3rdParty/Boost/src/libs/filesystem/v3/src/unique_path.cpp new file mode 100644 index 0000000..1569b32 --- /dev/null +++ b/3rdParty/Boost/src/libs/filesystem/v3/src/unique_path.cpp @@ -0,0 +1,151 @@ +// filesystem system_crypt_random.cpp ------------------------------------------------// + +// Copyright Beman Dawes 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#include <boost/config.hpp> +#if !defined( BOOST_NO_STD_WSTRING ) +// Boost.Filesystem V3 and later requires std::wstring support. +// During the transition to V3, libraries are compiled with both V2 and V3 sources. +// On old compilers that don't support V3 anyhow, we just skip everything so the compile +// will succeed and the library can be built. + +// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_FILESYSTEM_SOURCE + +#ifndef BOOST_SYSTEM_NO_DEPRECATED +# define BOOST_SYSTEM_NO_DEPRECATED +#endif + +#include <boost/filesystem/v3/operations.hpp> + +# ifdef BOOST_POSIX_API +# include <fcntl.h> +# else // BOOST_WINDOWS_API +# include <windows.h> +# include <wincrypt.h> +# pragma comment(lib, "Advapi32.lib") +# endif + +namespace { + +void fail(int err, boost::system::error_code* ec) +{ + if (ec == 0) + BOOST_FILESYSTEM_THROW( boost::system::system_error(err, + boost::system::system_category(), + "boost::filesystem::unique_path")); + + ec->assign(err, boost::system::system_category()); + return; +} + +void system_crypt_random(void* buf, std::size_t len, boost::system::error_code* ec) +{ +# ifdef BOOST_POSIX_API + + int file = open("/dev/urandom", O_RDONLY); + if (file == -1) + { + file = open("/dev/random", O_RDONLY); + if (file == -1) + { + fail(errno, ec); + return; + } + } + + size_t bytes_read = 0; + while (bytes_read < len) + { + ssize_t n = read(file, buf, len - bytes_read); + if (n == -1) + { + close(file); + fail(errno, ec); + return; + } + bytes_read += n; + buf = static_cast<char*>(buf) + n; + } + + close(file); + +# else // BOOST_WINDOWS_API + + HCRYPTPROV handle; + int errval = 0; + + if (!::CryptAcquireContextW(&handle, 0, 0, PROV_RSA_FULL, 0)) + { + errval = ::GetLastError(); + if (errval == NTE_BAD_KEYSET) + { + if (!::CryptAcquireContextW(&handle, 0, 0, PROV_RSA_FULL, CRYPT_NEWKEYSET)) + { + errval = ::GetLastError(); + } + else errval = 0; + } + } + + if (!errval) + { + BOOL gen_ok = ::CryptGenRandom(handle, len, static_cast<unsigned char*>(buf)); + if (!gen_ok) + errval = ::GetLastError(); + ::CryptReleaseContext(handle, 0); + } + + if (!errval) return; + + fail(errval, ec); +# endif +} + +} // unnamed namespace + +namespace boost { namespace filesystem3 { namespace detail { + +BOOST_FILESYSTEM_DECL +path unique_path(const path& model, system::error_code* ec) +{ + std::wstring s (model.wstring()); // std::string ng for MBCS encoded POSIX + const wchar_t hex[] = L"0123456789abcdef"; + const int n_ran = 16; + const int max_nibbles = 2 * n_ran; // 4-bits per nibble + char ran[n_ran]; + + int nibbles_used = max_nibbles; + for(std::wstring::size_type i=0; i < s.size(); ++i) + { + if (s[i] == L'%') // digit request + { + if (nibbles_used == max_nibbles) + { + system_crypt_random(ran, sizeof(ran), ec); + if (ec != 0 && *ec) + return ""; + nibbles_used = 0; + } + int c = ran[nibbles_used/2]; + c >>= 4 * (nibbles_used++ & 1); // if odd, shift right 1 nibble + s[i] = hex[c & 0xf]; // convert to hex digit and replace + } + } + + if (ec != 0) ec->clear(); + + return s; +} + +}}} + +#endif // no wide character support diff --git a/3rdParty/Boost/src/libs/filesystem/src/utf8_codecvt_facet.cpp b/3rdParty/Boost/src/libs/filesystem/v3/src/utf8_codecvt_facet.cpp index 3fe3e95..1849a1a 100644 --- a/3rdParty/Boost/src/libs/filesystem/src/utf8_codecvt_facet.cpp +++ b/3rdParty/Boost/src/libs/filesystem/v3/src/utf8_codecvt_facet.cpp @@ -3,6 +3,10 @@ // (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_SYSTEM_NO_DEPRECATED +# define BOOST_SYSTEM_NO_DEPRECATED +#endif + #define BOOST_FILESYSTEM_SOURCE #include <boost/filesystem/config.hpp> @@ -14,7 +18,6 @@ #include "libs/detail/utf8_codecvt_facet.cpp" - #undef BOOST_UTF8_BEGIN_NAMESPACE #undef BOOST_UTF8_END_NAMESPACE #undef BOOST_UTF8_DECL diff --git a/3rdParty/Boost/src/libs/filesystem/v3/src/windows_file_codecvt.cpp b/3rdParty/Boost/src/libs/filesystem/v3/src/windows_file_codecvt.cpp new file mode 100644 index 0000000..dd89c02 --- /dev/null +++ b/3rdParty/Boost/src/libs/filesystem/v3/src/windows_file_codecvt.cpp @@ -0,0 +1,79 @@ +// filesystem windows_file_codecvt.cpp -----------------------------------------// + +// Copyright Beman Dawes 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#include <boost/config.hpp> +#if !defined( BOOST_NO_STD_WSTRING ) +// Boost.Filesystem V3 and later requires std::wstring support. +// During the transition to V3, libraries are compiled with both V2 and V3 sources. +// On old compilers that don't support V3 anyhow, we just skip everything so the compile +// will succeed and the library can be built. + +// define BOOST_FILESYSTEM_SOURCE so that <boost/system/config.hpp> knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_FILESYSTEM_SOURCE + +#ifndef BOOST_SYSTEM_NO_DEPRECATED +# define BOOST_SYSTEM_NO_DEPRECATED +#endif + +#include <boost/filesystem/v3/config.hpp> +#include <cwchar> // for mbstate_t + +#ifdef BOOST_WINDOWS_API + +#include "windows_file_codecvt.hpp" + +#define WINVER 0x0500 // MinGW for GCC 4.4 requires this +#include <windows.h> + + std::codecvt_base::result windows_file_codecvt::do_in( + std::mbstate_t &, + const char* from, const char* from_end, const char*& from_next, + wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const + { + UINT codepage = AreFileApisANSI() ? CP_THREAD_ACP : CP_OEMCP; + + int count; + if ((count = ::MultiByteToWideChar(codepage, MB_PRECOMPOSED, from, + from_end - from, to, to_end - to)) == 0) + { + return error; // conversion failed + } + + from_next = from_end; + to_next = to + count; + *to_next = L'\0'; + return ok; + } + + std::codecvt_base::result windows_file_codecvt::do_out( + std::mbstate_t &, + const wchar_t* from, const wchar_t* from_end, const wchar_t* & from_next, + char* to, char* to_end, char* & to_next) const + { + UINT codepage = AreFileApisANSI() ? CP_THREAD_ACP : CP_OEMCP; + + int count; + if ((count = ::WideCharToMultiByte(codepage, WC_NO_BEST_FIT_CHARS, from, + from_end - from, to, to_end - to, 0, 0)) == 0) + { + return error; // conversion failed + } + + from_next = from_end; + to_next = to + count; + *to_next = '\0'; + return ok; + } + + # endif // BOOST_WINDOWS_API + +#endif // no wide character support diff --git a/3rdParty/Boost/src/libs/filesystem/v3/src/windows_file_codecvt.hpp b/3rdParty/Boost/src/libs/filesystem/v3/src/windows_file_codecvt.hpp new file mode 100644 index 0000000..d845d37 --- /dev/null +++ b/3rdParty/Boost/src/libs/filesystem/v3/src/windows_file_codecvt.hpp @@ -0,0 +1,56 @@ +// filesystem windows_file_codecvt.hpp -----------------------------------------------// + +// Copyright Beman Dawes 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +#ifndef BOOST_FILESYSTEM3_WIN_FILE_CODECVT_HPP +#define BOOST_FILESYSTEM3_WIN_FILE_CODECVT_HPP + +#include <boost/filesystem/v3/config.hpp> +#include <locale> + + //------------------------------------------------------------------------------------// + // // + // class windows_file_codecvt // + // // + // Warning: partial implementation; even do_in and do_out only partially meet the // + // standard library specifications as the "to" buffer must hold the entire result. // + // // + //------------------------------------------------------------------------------------// + + class BOOST_FILESYSTEM_DECL windows_file_codecvt + : public std::codecvt< wchar_t, char, std::mbstate_t > + { + public: + explicit windows_file_codecvt() + : std::codecvt<wchar_t, char, std::mbstate_t>() {} + protected: + + virtual bool do_always_noconv() const throw() { return false; } + + // seems safest to assume variable number of characters since we don't + // actually know what codepage is active + virtual int do_encoding() const throw() { return 0; } + + virtual std::codecvt_base::result do_in(std::mbstate_t& state, + const char* from, const char* from_end, const char*& from_next, + wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const; + + virtual std::codecvt_base::result do_out(std::mbstate_t & state, + const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next, + char* to, char* to_end, char*& to_next) const; + + virtual std::codecvt_base::result do_unshift(std::mbstate_t&, + char* /*from*/, char* /*to*/, char* & /*next*/) const { return ok; } + + virtual int do_length(std::mbstate_t&, + const char* /*from*/, const char* /*from_end*/, std::size_t /*max*/) const { return 0; } + + virtual int do_max_length() const throw () { return 0; } + }; + +#endif // BOOST_FILESYSTEM3_WIN_FILE_CODECVT_HPP diff --git a/3rdParty/Boost/src/libs/program_options/src/options_description.cpp b/3rdParty/Boost/src/libs/program_options/src/options_description.cpp index bfd113d..0d8dfd4 100644 --- a/3rdParty/Boost/src/libs/program_options/src/options_description.cpp +++ b/3rdParty/Boost/src/libs/program_options/src/options_description.cpp @@ -306,6 +306,7 @@ namespace boost { namespace program_options { bool short_ignore_case) const { shared_ptr<option_description> found; + bool had_full_match = false; vector<string> approximate_matches; vector<string> full_matches; @@ -323,15 +324,17 @@ namespace boost { namespace program_options { if (r == option_description::full_match) { full_matches.push_back(m_options[i]->key(name)); + found = m_options[i]; + had_full_match = true; } else { // FIXME: the use of 'key' here might not // be the best approach. approximate_matches.push_back(m_options[i]->key(name)); + if (!had_full_match) + found = m_options[i]; } - - found = m_options[i]; } if (full_matches.size() > 1) boost::throw_exception( diff --git a/3rdParty/Boost/src/libs/program_options/src/winmain.cpp b/3rdParty/Boost/src/libs/program_options/src/winmain.cpp index 64cc790..8a7c43f 100644 --- a/3rdParty/Boost/src/libs/program_options/src/winmain.cpp +++ b/3rdParty/Boost/src/libs/program_options/src/winmain.cpp @@ -30,6 +30,7 @@ namespace boost { namespace program_options { std::string current; bool inside_quoted = false; + bool empty_quote = false; int backslash_count = 0; for(; i != e; ++i) { @@ -38,6 +39,7 @@ namespace boost { namespace program_options { // n/2 backslashes and is a quoted block delimiter if (backslash_count % 2 == 0) { current.append(backslash_count / 2, '\\'); + empty_quote = inside_quoted && current.empty(); inside_quoted = !inside_quoted; // '"' preceded by odd number (n) of backslashes generates // (n-1)/2 backslashes and is literal quote. @@ -59,6 +61,7 @@ namespace boost { namespace program_options { // Space outside quoted section terminate the current argument result.push_back(current); current.resize(0); + empty_quote = false; for(;i != e && isspace((unsigned char)*i); ++i) ; --i; @@ -74,7 +77,7 @@ namespace boost { namespace program_options { // If we have non-empty 'current' or we're still in quoted // section (even if 'current' is empty), add the last token. - if (!current.empty() || inside_quoted) + if (!current.empty() || inside_quoted || empty_quote) result.push_back(current); } return result; @@ -94,3 +97,4 @@ namespace boost { namespace program_options { }} #endif + diff --git a/3rdParty/Boost/src/libs/regex/src/c_regex_traits.cpp b/3rdParty/Boost/src/libs/regex/src/c_regex_traits.cpp index 6466bc4..a99de14 100644 --- a/3rdParty/Boost/src/libs/regex/src/c_regex_traits.cpp +++ b/3rdParty/Boost/src/libs/regex/src/c_regex_traits.cpp @@ -155,16 +155,16 @@ c_regex_traits<char>::char_class_type BOOST_REGEX_CALL c_regex_traits<char>::loo char_class_xdigit, }; - int id = ::boost::re_detail::get_default_class_id(p1, p2); - if(id < 0) + int idx = ::boost::re_detail::get_default_class_id(p1, p2); + if(idx < 0) { std::string s(p1, p2); for(std::string::size_type i = 0; i < s.size(); ++i) s[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(s[i]))); - id = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.begin() + s.size()); + idx = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.begin() + s.size()); } - BOOST_ASSERT(std::size_t(id+1) < sizeof(masks) / sizeof(masks[0])); - return masks[id+1]; + BOOST_ASSERT(std::size_t(idx+1) < sizeof(masks) / sizeof(masks[0])); + return masks[idx+1]; } bool BOOST_REGEX_CALL c_regex_traits<char>::isctype(char c, char_class_type mask) diff --git a/3rdParty/Boost/src/libs/regex/src/cregex.cpp b/3rdParty/Boost/src/libs/regex/src/cregex.cpp index f67d371..5c27330 100644 --- a/3rdParty/Boost/src/libs/regex/src/cregex.cpp +++ b/3rdParty/Boost/src/libs/regex/src/cregex.cpp @@ -31,6 +31,9 @@ typedef boost::match_flag_type match_flag_type; #ifdef BOOST_MSVC #pragma warning(disable:4309) #endif +#ifdef BOOST_INTEL +#pragma warning(disable:981 383) +#endif namespace boost{ diff --git a/3rdParty/Boost/src/libs/regex/src/icu.cpp b/3rdParty/Boost/src/libs/regex/src/icu.cpp index a815e91..2fa2b3b 100644 --- a/3rdParty/Boost/src/libs/regex/src/icu.cpp +++ b/3rdParty/Boost/src/libs/regex/src/icu.cpp @@ -22,6 +22,10 @@ #define BOOST_REGEX_ICU_INSTANTIATE #include <boost/regex/icu.hpp> +#ifdef BOOST_INTEL +#pragma warning(disable:981 2259 383) +#endif + namespace boost{ namespace re_detail{ @@ -388,14 +392,14 @@ icu_regex_traits::char_class_type icu_regex_traits::lookup_classname(const char_ char_class_type(U_GC_ND_MASK) | mask_xdigit, }; - int id = ::boost::re_detail::get_default_class_id(p1, p2); - if(id >= 0) - return masks[id+1]; + int idx = ::boost::re_detail::get_default_class_id(p1, p2); + if(idx >= 0) + return masks[idx+1]; char_class_type result = lookup_icu_mask(p1, p2); if(result != 0) return result; - if(id < 0) + if(idx < 0) { string_type s(p1, p2); string_type::size_type i = 0; @@ -411,16 +415,16 @@ icu_regex_traits::char_class_type icu_regex_traits::lookup_classname(const char_ } } if(s.size()) - id = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.begin() + s.size()); - if(id >= 0) - return masks[id+1]; + idx = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.begin() + s.size()); + if(idx >= 0) + return masks[idx+1]; if(s.size()) result = lookup_icu_mask(&*s.begin(), &*s.begin() + s.size()); if(result != 0) return result; } - BOOST_ASSERT(std::size_t(id+1) < sizeof(masks) / sizeof(masks[0])); - return masks[id+1]; + BOOST_ASSERT(std::size_t(idx+1) < sizeof(masks) / sizeof(masks[0])); + return masks[idx+1]; } icu_regex_traits::string_type icu_regex_traits::lookup_collatename(const char_type* p1, const char_type* p2) const diff --git a/3rdParty/Boost/src/libs/regex/src/regex.cpp b/3rdParty/Boost/src/libs/regex/src/regex.cpp index 0a50382..1f1caa6 100644 --- a/3rdParty/Boost/src/libs/regex/src/regex.cpp +++ b/3rdParty/Boost/src/libs/regex/src/regex.cpp @@ -44,6 +44,9 @@ #endif #endif +#ifdef BOOST_INTEL +#pragma warning(disable:383) +#endif namespace boost{ diff --git a/3rdParty/Boost/src/libs/regex/src/regex_traits_defaults.cpp b/3rdParty/Boost/src/libs/regex/src/regex_traits_defaults.cpp index 31b7918..5f06149 100644 --- a/3rdParty/Boost/src/libs/regex/src/regex_traits_defaults.cpp +++ b/3rdParty/Boost/src/libs/regex/src/regex_traits_defaults.cpp @@ -100,7 +100,7 @@ BOOST_REGEX_DECL const char* BOOST_REGEX_CALL get_default_syntax(regex_constants "p", "P", "N", - "g", + "gk", "K", "R", }; diff --git a/3rdParty/Boost/src/libs/regex/src/w32_regex_traits.cpp b/3rdParty/Boost/src/libs/regex/src/w32_regex_traits.cpp index 365fccc..8c22214 100644 --- a/3rdParty/Boost/src/libs/regex/src/w32_regex_traits.cpp +++ b/3rdParty/Boost/src/libs/regex/src/w32_regex_traits.cpp @@ -43,10 +43,10 @@ namespace std{ namespace boost{ namespace re_detail{ #ifdef BOOST_NO_ANSI_APIS -UINT get_code_page_for_locale_id(lcid_type id) +UINT get_code_page_for_locale_id(lcid_type idx) { WCHAR code_page_string[7]; - if (::GetLocaleInfoW(id, LOCALE_IDEFAULTANSICODEPAGE, code_page_string, 7) == 0) + if (::GetLocaleInfoW(idx, LOCALE_IDEFAULTANSICODEPAGE, code_page_string, 7) == 0) return 0; return static_cast<UINT>(_wtol(code_page_string)); @@ -157,15 +157,15 @@ BOOST_REGEX_DECL lcid_type BOOST_REGEX_CALL w32_get_default_locale() return ::GetUserDefaultLCID(); } -BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(char c, lcid_type id) +BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(char c, lcid_type idx) { #ifndef BOOST_NO_ANSI_APIS WORD mask; - if(::GetStringTypeExA(id, CT_CTYPE1, &c, 1, &mask) && (mask & C1_LOWER)) + if(::GetStringTypeExA(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_LOWER)) return true; return false; #else - UINT code_page = get_code_page_for_locale_id(id); + UINT code_page = get_code_page_for_locale_id(idx); if (code_page == 0) return false; @@ -174,39 +174,39 @@ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(char c, lcid_type id) return false; WORD mask; - if(::GetStringTypeExW(id, CT_CTYPE1, &wide_c, 1, &mask) && (mask & C1_LOWER)) + if(::GetStringTypeExW(idx, CT_CTYPE1, &wide_c, 1, &mask) && (mask & C1_LOWER)) return true; return false; #endif } -BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(wchar_t c, lcid_type id) +BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(wchar_t c, lcid_type idx) { WORD mask; - if(::GetStringTypeExW(id, CT_CTYPE1, &c, 1, &mask) && (mask & C1_LOWER)) + if(::GetStringTypeExW(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_LOWER)) return true; return false; } #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T -BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(unsigned short ca, lcid_type id) +BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(unsigned short ca, lcid_type idx) { WORD mask; wchar_t c = ca; - if(::GetStringTypeExW(id, CT_CTYPE1, &c, 1, &mask) && (mask & C1_LOWER)) + if(::GetStringTypeExW(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_LOWER)) return true; return false; } #endif -BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(char c, lcid_type id) +BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(char c, lcid_type idx) { #ifndef BOOST_NO_ANSI_APIS WORD mask; - if(::GetStringTypeExA(id, CT_CTYPE1, &c, 1, &mask) && (mask & C1_UPPER)) + if(::GetStringTypeExA(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_UPPER)) return true; return false; #else - UINT code_page = get_code_page_for_locale_id(id); + UINT code_page = get_code_page_for_locale_id(idx); if (code_page == 0) return false; @@ -215,25 +215,25 @@ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(char c, lcid_type id) return false; WORD mask; - if(::GetStringTypeExW(id, CT_CTYPE1, &wide_c, 1, &mask) && (mask & C1_UPPER)) + if(::GetStringTypeExW(idx, CT_CTYPE1, &wide_c, 1, &mask) && (mask & C1_UPPER)) return true; return false; #endif } -BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(wchar_t c, lcid_type id) +BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(wchar_t c, lcid_type idx) { WORD mask; - if(::GetStringTypeExW(id, CT_CTYPE1, &c, 1, &mask) && (mask & C1_UPPER)) + if(::GetStringTypeExW(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_UPPER)) return true; return false; } #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T -BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(unsigned short ca, lcid_type id) +BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(unsigned short ca, lcid_type idx) { WORD mask; wchar_t c = ca; - if(::GetStringTypeExW(id, CT_CTYPE1, &c, 1, &mask) && (mask & C1_UPPER)) + if(::GetStringTypeExW(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_UPPER)) return true; return false; } @@ -322,11 +322,11 @@ BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_cat_get( } #endif #endif -BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type id, const char* p1, const char* p2) +BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type idx, const char* p1, const char* p2) { #ifndef BOOST_NO_ANSI_APIS int bytes = ::LCMapStringA( - id, // locale identifier + idx, // locale identifier LCMAP_SORTKEY, // mapping transformation type p1, // source string static_cast<int>(p2 - p1), // number of characters in source string @@ -337,7 +337,7 @@ BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type id, const return std::string(p1, p2); std::string result(++bytes, '\0'); bytes = ::LCMapStringA( - id, // locale identifier + idx, // locale identifier LCMAP_SORTKEY, // mapping transformation type p1, // source string static_cast<int>(p2 - p1), // number of characters in source string @@ -345,7 +345,7 @@ BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type id, const bytes // size of destination buffer ); #else - UINT code_page = get_code_page_for_locale_id(id); + UINT code_page = get_code_page_for_locale_id(idx); if(code_page == 0) return std::string(p1, p2); @@ -355,7 +355,7 @@ BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type id, const return std::string(p1, p2); int bytes = ::LCMapStringW( - id, // locale identifier + idx, // locale identifier LCMAP_SORTKEY, // mapping transformation type wide_p1, // source string src_len, // number of characters in source string @@ -366,7 +366,7 @@ BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type id, const return std::string(p1, p2); std::string result(++bytes, '\0'); bytes = ::LCMapStringW( - id, // locale identifier + idx, // locale identifier LCMAP_SORTKEY, // mapping transformation type wide_p1, // source string src_len, // number of characters in source string @@ -384,10 +384,10 @@ BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type id, const } #ifndef BOOST_NO_WREGEX -BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_transform(lcid_type id, const wchar_t* p1, const wchar_t* p2) +BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_transform(lcid_type idx, const wchar_t* p1, const wchar_t* p2) { int bytes = ::LCMapStringW( - id, // locale identifier + idx, // locale identifier LCMAP_SORTKEY, // mapping transformation type p1, // source string static_cast<int>(p2 - p1), // number of characters in source string @@ -398,7 +398,7 @@ BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_transform(lcid_type id, const return std::wstring(p1, p2); std::string result(++bytes, '\0'); bytes = ::LCMapStringW( - id, // locale identifier + idx, // locale identifier LCMAP_SORTKEY, // mapping transformation type p1, // source string static_cast<int>(p2 - p1), // number of characters in source string @@ -417,10 +417,10 @@ BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_transform(lcid_type id, const return r2; } #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T -BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_transform(lcid_type id, const unsigned short* p1, const unsigned short* p2) +BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_transform(lcid_type idx, const unsigned short* p1, const unsigned short* p2) { int bytes = ::LCMapStringW( - id, // locale identifier + idx, // locale identifier LCMAP_SORTKEY, // mapping transformation type (LPCWSTR)p1, // source string static_cast<int>(p2 - p1), // number of characters in source string @@ -431,7 +431,7 @@ BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_transfor return std::basic_string<unsigned short>(p1, p2); std::string result(++bytes, '\0'); bytes = ::LCMapStringW( - id, // locale identifier + idx, // locale identifier LCMAP_SORTKEY, // mapping transformation type (LPCWSTR)p1, // source string static_cast<int>(p2 - p1), // number of characters in source string @@ -451,12 +451,12 @@ BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_transfor } #endif #endif -BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_tolower(char c, lcid_type id) +BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_tolower(char c, lcid_type idx) { char result[2]; #ifndef BOOST_NO_ANSI_APIS int b = ::LCMapStringA( - id, // locale identifier + idx, // locale identifier LCMAP_LOWERCASE, // mapping transformation type &c, // source string 1, // number of characters in source string @@ -465,7 +465,7 @@ BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_tolower(char c, lcid_type id) if(b == 0) return c; #else - UINT code_page = get_code_page_for_locale_id(id); + UINT code_page = get_code_page_for_locale_id(idx); if (code_page == 0) return c; @@ -475,7 +475,7 @@ BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_tolower(char c, lcid_type id) WCHAR wide_result; int b = ::LCMapStringW( - id, // locale identifier + idx, // locale identifier LCMAP_LOWERCASE, // mapping transformation type &wide_c, // source string 1, // number of characters in source string @@ -491,11 +491,11 @@ BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_tolower(char c, lcid_type id) } #ifndef BOOST_NO_WREGEX -BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_tolower(wchar_t c, lcid_type id) +BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_tolower(wchar_t c, lcid_type idx) { wchar_t result[2]; int b = ::LCMapStringW( - id, // locale identifier + idx, // locale identifier LCMAP_LOWERCASE, // mapping transformation type &c, // source string 1, // number of characters in source string @@ -506,11 +506,11 @@ BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_tolower(wchar_t c, lcid_type id) return result[0]; } #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T -BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL w32_tolower(unsigned short c, lcid_type id) +BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL w32_tolower(unsigned short c, lcid_type idx) { wchar_t result[2]; int b = ::LCMapStringW( - id, // locale identifier + idx, // locale identifier LCMAP_LOWERCASE, // mapping transformation type (wchar_t const*)&c, // source string 1, // number of characters in source string @@ -522,12 +522,12 @@ BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL w32_tolower(unsigned short c, l } #endif #endif -BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_toupper(char c, lcid_type id) +BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_toupper(char c, lcid_type idx) { char result[2]; #ifndef BOOST_NO_ANSI_APIS int b = ::LCMapStringA( - id, // locale identifier + idx, // locale identifier LCMAP_UPPERCASE, // mapping transformation type &c, // source string 1, // number of characters in source string @@ -536,7 +536,7 @@ BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_toupper(char c, lcid_type id) if(b == 0) return c; #else - UINT code_page = get_code_page_for_locale_id(id); + UINT code_page = get_code_page_for_locale_id(idx); if(code_page == 0) return c; @@ -546,7 +546,7 @@ BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_toupper(char c, lcid_type id) WCHAR wide_result; int b = ::LCMapStringW( - id, // locale identifier + idx, // locale identifier LCMAP_UPPERCASE, // mapping transformation type &wide_c, // source string 1, // number of characters in source string @@ -562,11 +562,11 @@ BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_toupper(char c, lcid_type id) } #ifndef BOOST_NO_WREGEX -BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_toupper(wchar_t c, lcid_type id) +BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_toupper(wchar_t c, lcid_type idx) { wchar_t result[2]; int b = ::LCMapStringW( - id, // locale identifier + idx, // locale identifier LCMAP_UPPERCASE, // mapping transformation type &c, // source string 1, // number of characters in source string @@ -577,11 +577,11 @@ BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_toupper(wchar_t c, lcid_type id) return result[0]; } #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T -BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL w32_toupper(unsigned short c, lcid_type id) +BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL w32_toupper(unsigned short c, lcid_type idx) { wchar_t result[2]; int b = ::LCMapStringW( - id, // locale identifier + idx, // locale identifier LCMAP_UPPERCASE, // mapping transformation type (wchar_t const*)&c, // source string 1, // number of characters in source string @@ -593,14 +593,14 @@ BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL w32_toupper(unsigned short c, l } #endif #endif -BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type id, boost::uint32_t m, char c) +BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type idx, boost::uint32_t m, char c) { WORD mask; #ifndef BOOST_NO_ANSI_APIS - if(::GetStringTypeExA(id, CT_CTYPE1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation<char>::mask_base)) + if(::GetStringTypeExA(idx, CT_CTYPE1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation<char>::mask_base)) return true; #else - UINT code_page = get_code_page_for_locale_id(id); + UINT code_page = get_code_page_for_locale_id(idx); if(code_page == 0) return false; @@ -608,7 +608,7 @@ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type id, boost::uint32_t m, c if (::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0) return false; - if(::GetStringTypeExW(id, CT_CTYPE1, &wide_c, 1, &mask) && (mask & m & w32_regex_traits_implementation<char>::mask_base)) + if(::GetStringTypeExW(idx, CT_CTYPE1, &wide_c, 1, &mask) && (mask & m & w32_regex_traits_implementation<char>::mask_base)) return true; #endif if((m & w32_regex_traits_implementation<char>::mask_word) && (c == '_')) @@ -617,10 +617,10 @@ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type id, boost::uint32_t m, c } #ifndef BOOST_NO_WREGEX -BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type id, boost::uint32_t m, wchar_t c) +BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type idx, boost::uint32_t m, wchar_t c) { WORD mask; - if(::GetStringTypeExW(id, CT_CTYPE1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation<wchar_t>::mask_base)) + if(::GetStringTypeExW(idx, CT_CTYPE1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation<wchar_t>::mask_base)) return true; if((m & w32_regex_traits_implementation<wchar_t>::mask_word) && (c == '_')) return true; @@ -629,10 +629,10 @@ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type id, boost::uint32_t m, w return false; } #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T -BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type id, boost::uint32_t m, unsigned short c) +BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type idx, boost::uint32_t m, unsigned short c) { WORD mask; - if(::GetStringTypeExW(id, CT_CTYPE1, (wchar_t const*)&c, 1, &mask) && (mask & m & w32_regex_traits_implementation<wchar_t>::mask_base)) + if(::GetStringTypeExW(idx, CT_CTYPE1, (wchar_t const*)&c, 1, &mask) && (mask & m & w32_regex_traits_implementation<wchar_t>::mask_base)) return true; if((m & w32_regex_traits_implementation<wchar_t>::mask_word) && (c == '_')) return true; diff --git a/3rdParty/Boost/src/libs/regex/src/wc_regex_traits.cpp b/3rdParty/Boost/src/libs/regex/src/wc_regex_traits.cpp index fb622b5..a9e96d9 100644 --- a/3rdParty/Boost/src/libs/regex/src/wc_regex_traits.cpp +++ b/3rdParty/Boost/src/libs/regex/src/wc_regex_traits.cpp @@ -195,16 +195,16 @@ c_regex_traits<wchar_t>::char_class_type BOOST_REGEX_CALL c_regex_traits<wchar_t char_class_xdigit, }; - int id = ::boost::re_detail::get_default_class_id(p1, p2); - if(id < 0) + int idx = ::boost::re_detail::get_default_class_id(p1, p2); + if(idx < 0) { std::wstring s(p1, p2); for(std::wstring::size_type i = 0; i < s.size(); ++i) s[i] = (std::towlower)(s[i]); - id = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.begin() + s.size()); + idx = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.begin() + s.size()); } - BOOST_ASSERT(id+1 < static_cast<int>(sizeof(masks) / sizeof(masks[0]))); - return masks[id+1]; + BOOST_ASSERT(idx+1 < static_cast<int>(sizeof(masks) / sizeof(masks[0]))); + return masks[idx+1]; } bool BOOST_REGEX_CALL c_regex_traits<wchar_t>::isctype(wchar_t c, char_class_type mask) diff --git a/3rdParty/Boost/src/libs/regex/src/wide_posix_api.cpp b/3rdParty/Boost/src/libs/regex/src/wide_posix_api.cpp index bdb7580..3c693c6 100644 --- a/3rdParty/Boost/src/libs/regex/src/wide_posix_api.cpp +++ b/3rdParty/Boost/src/libs/regex/src/wide_posix_api.cpp @@ -29,6 +29,10 @@ #include <cstring> #include <cstdio> +#ifdef BOOST_INTEL +#pragma warning(disable:981) +#endif + #if defined(BOOST_NO_STDC_NAMESPACE) || defined(__NetBSD__) namespace std{ # ifndef BOOST_NO_SWPRINTF diff --git a/3rdParty/Boost/src/libs/system/src/error_code.cpp b/3rdParty/Boost/src/libs/system/src/error_code.cpp index fa2cb0b..bd87403 100644 --- a/3rdParty/Boost/src/libs/system/src/error_code.cpp +++ b/3rdParty/Boost/src/libs/system/src/error_code.cpp @@ -29,8 +29,9 @@ using namespace boost::system::errc; # if defined( BOOST_WINDOWS_API ) # include <windows.h> +# include "local_free_on_destruction.hpp" # ifndef ERROR_INCORRECT_SIZE -# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS +# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS # endif # endif @@ -159,7 +160,7 @@ namespace switch ( ev ) { case 0: return make_error_condition( success ); - # if defined(BOOST_POSIX_API) +# if defined(BOOST_POSIX_API) // POSIX-like O/S -> posix_errno decode table ---------------------------// case E2BIG: return make_error_condition( argument_list_too_long ); case EACCES: return make_error_condition( permission_denied ); @@ -221,7 +222,9 @@ namespace # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value case ENOTEMPTY: return make_error_condition( directory_not_empty ); # endif // ENOTEMPTY != EEXIST - case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable ); + # if ENOTRECOVERABLE != ECONNRESET // the same on some Broadcom chips + case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable ); + # endif // ENOTRECOVERABLE != ECONNRESET case ENOTSOCK: return make_error_condition( not_a_socket ); case ENOTSUP: return make_error_condition( not_supported ); case ENOTTY: return make_error_condition( inappropriate_io_control_operation ); @@ -230,7 +233,9 @@ namespace case EOPNOTSUPP: return make_error_condition( operation_not_supported ); # endif // EOPNOTSUPP != ENOTSUP case EOVERFLOW: return make_error_condition( value_too_large ); - case EOWNERDEAD: return make_error_condition( owner_dead ); + # if EOWNERDEAD != ECONNABORTED // the same on some Broadcom chips + case EOWNERDEAD: return make_error_condition( owner_dead ); + # endif // EOWNERDEAD != ECONNABORTED case EPERM: return make_error_condition( operation_not_permitted ); case EPIPE: return make_error_condition( broken_pipe ); case EPROTO: return make_error_condition( protocol_error ); @@ -325,7 +330,7 @@ namespace case WSAETIMEDOUT: return make_error_condition( timed_out ); case WSAEWOULDBLOCK: return make_error_condition( operation_would_block ); #endif - default: return error_condition( ev, system_category ); + default: return error_condition( ev, system_category() ); } } @@ -333,28 +338,14 @@ namespace std::string system_error_category::message( int ev ) const { - return generic_category.message( ev ); + return generic_category().message( ev ); } # else -// TODO: - -//Some quick notes on the implementation (sorry for the noise if -//someone has already mentioned them): -// -//- The ::LocalFree() usage isn't exception safe. -// -//See: -// -//<http://boost.cvs.sourceforge.net/boost/boost/boost/asio/system_exception.hpp?revision=1.1&view=markup> -// -//in the implementation of what() for an example. -// -//Cheers, -//Chris + std::string system_error_category::message( int ev ) const { # ifndef BOOST_NO_ANSI_APIS - LPVOID lpMsgBuf; + LPVOID lpMsgBuf = 0; DWORD retval = ::FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | @@ -366,13 +357,13 @@ namespace 0, NULL ); + detail::local_free_on_destruction lfod(lpMsgBuf); if (retval == 0) return std::string("Unknown error"); std::string str( static_cast<LPCSTR>(lpMsgBuf) ); - ::LocalFree( lpMsgBuf ); // free the buffer # else // WinCE workaround - LPVOID lpMsgBuf; + LPVOID lpMsgBuf = 0; DWORD retval = ::FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | @@ -384,6 +375,7 @@ namespace 0, NULL ); + detail::local_free_on_destruction lfod(lpMsgBuf); if (retval == 0) return std::string("Unknown error"); @@ -393,7 +385,6 @@ namespace return std::string("Unknown error"); std::string str( narrow_buffer ); - ::LocalFree( lpMsgBuf ); // free the buffer # endif while ( str.size() && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) @@ -419,13 +410,13 @@ namespace boost // address for comparison purposes # endif - BOOST_SYSTEM_DECL const error_category & get_system_category() + BOOST_SYSTEM_DECL const error_category & system_category() { static const system_error_category system_category_const; return system_category_const; } - BOOST_SYSTEM_DECL const error_category & get_generic_category() + BOOST_SYSTEM_DECL const error_category & generic_category() { static const generic_error_category generic_category_const; return generic_category_const; diff --git a/3rdParty/Boost/src/libs/system/src/local_free_on_destruction.hpp b/3rdParty/Boost/src/libs/system/src/local_free_on_destruction.hpp new file mode 100644 index 0000000..110024f --- /dev/null +++ b/3rdParty/Boost/src/libs/system/src/local_free_on_destruction.hpp @@ -0,0 +1,40 @@ +// local_free_on_exit.hpp ------------------------------------------------------------// + +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2010 Beman Dawes + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// This is derived from boost/asio/detail/local_free_on_block_exit.hpp to avoid +// a dependency on asio. Thanks to Chris Kohlhoff for pointing it out. + +#ifndef BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP +#define BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP + +namespace boost { +namespace system { +namespace detail { + +class local_free_on_destruction +{ +public: + explicit local_free_on_destruction(void* p) + : p_(p) {} + + ~local_free_on_destruction() + { + ::LocalFree(p_); + } + +private: + void* p_; + local_free_on_destruction(const local_free_on_destruction&); // = deleted + local_free_on_destruction& operator=(const local_free_on_destruction&); // = deleted +}; + +} // namespace detail +} // namespace system +} // namespace boost + +#endif // BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp b/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp index 1c13a9a..187c024 100644 --- a/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp +++ b/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp @@ -75,7 +75,7 @@ namespace boost { current=next; ++next; - if(current->second.func && current->second.value) + if(current->second.func && (current->second.value!=0)) { (*current->second.func)(current->second.value); } @@ -196,15 +196,14 @@ namespace boost detach(); } - detail::thread_data_ptr thread::get_thread_info() const + detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const { - lock_guard<mutex> l(thread_info_mutex); return thread_info; } void thread::join() { - detail::thread_data_ptr const local_thread_info=get_thread_info(); + detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { bool do_join=false; @@ -238,7 +237,6 @@ namespace boost local_thread_info->done_condition.notify_all(); } - lock_guard<mutex> l1(thread_info_mutex); if(thread_info==local_thread_info) { thread_info.reset(); @@ -248,7 +246,7 @@ namespace boost bool thread::timed_join(system_time const& wait_until) { - detail::thread_data_ptr const local_thread_info=get_thread_info(); + detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { bool do_join=false; @@ -285,7 +283,6 @@ namespace boost local_thread_info->done_condition.notify_all(); } - lock_guard<mutex> l1(thread_info_mutex); if(thread_info==local_thread_info) { thread_info.reset(); @@ -296,17 +293,14 @@ namespace boost bool thread::joinable() const { - return get_thread_info(); + return (get_thread_info)(); } void thread::detach() { detail::thread_data_ptr local_thread_info; - { - lock_guard<mutex> l1(thread_info_mutex); - thread_info.swap(local_thread_info); - } + thread_info.swap(local_thread_info); if(local_thread_info) { @@ -381,8 +375,6 @@ namespace boost { #if defined(PTW32_VERSION) || defined(__hpux) return pthread_num_processors_np(); -#elif defined(_GNU_SOURCE) - return get_nprocs(); #elif defined(__APPLE__) || defined(__FreeBSD__) int count; size_t size=sizeof(count); @@ -390,6 +382,8 @@ namespace boost #elif defined(BOOST_HAS_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN) int const count=sysconf(_SC_NPROCESSORS_ONLN); return (count>0)?count:0; +#elif defined(_GNU_SOURCE) + return get_nprocs(); #else return 0; #endif @@ -397,7 +391,7 @@ namespace boost thread::id thread::get_id() const { - detail::thread_data_ptr const local_thread_info=get_thread_info(); + detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { return id(local_thread_info); @@ -410,13 +404,14 @@ namespace boost void thread::interrupt() { - detail::thread_data_ptr const local_thread_info=get_thread_info(); + detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { lock_guard<mutex> lk(local_thread_info->data_mutex); local_thread_info->interrupt_requested=true; if(local_thread_info->current_cond) { + boost::pthread::pthread_mutex_scoped_lock internal_lock(local_thread_info->cond_mutex); BOOST_VERIFY(!pthread_cond_broadcast(local_thread_info->current_cond)); } } @@ -424,7 +419,7 @@ namespace boost bool thread::interruption_requested() const { - detail::thread_data_ptr const local_thread_info=get_thread_info(); + detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { lock_guard<mutex> lk(local_thread_info->data_mutex); @@ -438,7 +433,7 @@ namespace boost thread::native_handle_type thread::native_handle() { - detail::thread_data_ptr const local_thread_info=get_thread_info(); + detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { lock_guard<mutex> lk(local_thread_info->data_mutex); @@ -582,11 +577,11 @@ namespace boost { if(tss_data_node* const current_node=find_tss_data(key)) { - if(cleanup_existing && current_node->func && current_node->value) + if(cleanup_existing && current_node->func && (current_node->value!=0)) { (*current_node->func)(current_node->value); } - if(func || tss_data) + if(func || (tss_data!=0)) { current_node->func=func; current_node->value=tss_data; diff --git a/3rdParty/Boost/src/libs/thread/src/tss_null.cpp b/3rdParty/Boost/src/libs/thread/src/tss_null.cpp index ff13b30..e93ba0f 100644 --- a/3rdParty/Boost/src/libs/thread/src/tss_null.cpp +++ b/3rdParty/Boost/src/libs/thread/src/tss_null.cpp @@ -8,13 +8,15 @@ #if defined(BOOST_HAS_WINTHREADS) && (defined(BOOST_THREAD_BUILD_LIB) || defined(BOOST_THREAD_TEST) || defined(UNDER_CE)) && (!defined(_MSC_VER) || defined(UNDER_CE)) +namespace boost +{ /* This file is a "null" implementation of tss cleanup; it's purpose is to to eliminate link errors in cases where it is known that tss cleanup is not needed. */ - extern "C" void tss_cleanup_implemented(void) + void tss_cleanup_implemented(void) { /* This function's sole purpose is to cause a link error in cases where @@ -30,5 +32,7 @@ longer needed and can be removed. */ } + +} #endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) && !defined(_MSC_VER) diff --git a/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp b/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp index b85e650..05c7a6c 100644 --- a/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp +++ b/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp @@ -56,7 +56,10 @@ namespace boost void set_current_thread_data(detail::thread_data_base* new_data) { boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key); - BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data)); + if(current_thread_tls_key) + BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data)); + else + boost::throw_exception(thread_resource_error()); } #ifdef BOOST_NO_THREADEX @@ -221,7 +224,15 @@ namespace boost void make_external_thread_data() { externally_launched_thread* me=detail::heap_new<externally_launched_thread>(); - set_current_thread_data(me); + try + { + set_current_thread_data(me); + } + catch(...) + { + detail::heap_delete(me); + throw; + } } detail::thread_data_base* get_or_make_current_thread_data() @@ -244,17 +255,17 @@ namespace boost thread::id thread::get_id() const { - return thread::id(get_thread_info()); + return thread::id((get_thread_info)()); } bool thread::joinable() const { - return get_thread_info(); + return (get_thread_info)(); } void thread::join() { - detail::thread_data_ptr local_thread_info=get_thread_info(); + detail::thread_data_ptr local_thread_info=(get_thread_info)(); if(local_thread_info) { this_thread::interruptible_wait(local_thread_info->thread_handle,detail::timeout::sentinel()); @@ -264,7 +275,7 @@ namespace boost bool thread::timed_join(boost::system_time const& wait_until) { - detail::thread_data_ptr local_thread_info=get_thread_info(); + detail::thread_data_ptr local_thread_info=(get_thread_info)(); if(local_thread_info) { if(!this_thread::interruptible_wait(local_thread_info->thread_handle,get_milliseconds_until(wait_until))) @@ -283,13 +294,12 @@ namespace boost void thread::release_handle() { - lock_guard<mutex> l1(thread_info_mutex); thread_info=0; } void thread::interrupt() { - detail::thread_data_ptr local_thread_info=get_thread_info(); + detail::thread_data_ptr local_thread_info=(get_thread_info)(); if(local_thread_info) { local_thread_info->interrupt(); @@ -298,26 +308,25 @@ namespace boost bool thread::interruption_requested() const { - detail::thread_data_ptr local_thread_info=get_thread_info(); + detail::thread_data_ptr local_thread_info=(get_thread_info)(); return local_thread_info.get() && (detail::win32::WaitForSingleObject(local_thread_info->interruption_handle,0)==0); } unsigned thread::hardware_concurrency() { - SYSTEM_INFO info={0}; + SYSTEM_INFO info={{0}}; GetSystemInfo(&info); return info.dwNumberOfProcessors; } thread::native_handle_type thread::native_handle() { - detail::thread_data_ptr local_thread_info=get_thread_info(); + detail::thread_data_ptr local_thread_info=(get_thread_info)(); return local_thread_info?(detail::win32::handle)local_thread_info->thread_handle:detail::win32::invalid_handle_value; } - detail::thread_data_ptr thread::get_thread_info() const + detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const { - boost::mutex::scoped_lock l(thread_info_mutex); return thread_info; } @@ -327,7 +336,7 @@ namespace boost { LARGE_INTEGER get_due_time(detail::timeout const& target_time) { - LARGE_INTEGER due_time={0}; + LARGE_INTEGER due_time={{0}}; if(target_time.relative) { unsigned long const elapsed_milliseconds=GetTickCount()-target_time.start; @@ -356,7 +365,23 @@ namespace boost else { long const hundred_nanoseconds_in_one_second=10000000; - due_time.QuadPart+=target_time.abs_time.time_of_day().fractional_seconds()*(hundred_nanoseconds_in_one_second/target_time.abs_time.time_of_day().ticks_per_second()); + posix_time::time_duration::tick_type const ticks_per_second= + target_time.abs_time.time_of_day().ticks_per_second(); + if(ticks_per_second>hundred_nanoseconds_in_one_second) + { + posix_time::time_duration::tick_type const + ticks_per_hundred_nanoseconds= + ticks_per_second/hundred_nanoseconds_in_one_second; + due_time.QuadPart+= + target_time.abs_time.time_of_day().fractional_seconds()/ + ticks_per_hundred_nanoseconds; + } + else + { + due_time.QuadPart+= + target_time.abs_time.time_of_day().fractional_seconds()* + (hundred_nanoseconds_in_one_second/ticks_per_second); + } } } return due_time; @@ -526,8 +551,8 @@ namespace boost { detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); thread_exit_callback_node* const new_node= - heap_new<thread_exit_callback_node>(func, - current_thread_data->thread_exit_callbacks); + heap_new<thread_exit_callback_node>( + func,current_thread_data->thread_exit_callbacks); current_thread_data->thread_exit_callbacks=new_node; } @@ -569,30 +594,31 @@ namespace boost current_node->func=func; current_node->value=tss_data; } - else + else if(func && tss_data) { detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); - tss_data_node* const new_node=heap_new<tss_data_node>(key,func,tss_data,current_thread_data->tss_data); + tss_data_node* const new_node= + heap_new<tss_data_node>(key,func,tss_data,current_thread_data->tss_data); current_thread_data->tss_data=new_node; } } } -} + BOOST_THREAD_DECL void __cdecl on_process_enter() + {} + BOOST_THREAD_DECL void __cdecl on_thread_enter() + {} -extern "C" BOOST_THREAD_DECL void on_process_enter() -{} + BOOST_THREAD_DECL void __cdecl on_process_exit() + { + boost::cleanup_tls_key(); + } -extern "C" BOOST_THREAD_DECL void on_thread_enter() -{} + BOOST_THREAD_DECL void __cdecl on_thread_exit() + { + boost::run_thread_exit_callbacks(); + } -extern "C" BOOST_THREAD_DECL void on_process_exit() -{ - boost::cleanup_tls_key(); } -extern "C" BOOST_THREAD_DECL void on_thread_exit() -{ - boost::run_thread_exit_callbacks(); -} diff --git a/3rdParty/Boost/src/libs/thread/src/win32/tss_dll.cpp b/3rdParty/Boost/src/libs/thread/src/win32/tss_dll.cpp index 0522a12..9699a12 100644 --- a/3rdParty/Boost/src/libs/thread/src/win32/tss_dll.cpp +++ b/3rdParty/Boost/src/libs/thread/src/win32/tss_dll.cpp @@ -24,27 +24,27 @@ { case DLL_PROCESS_ATTACH: { - on_process_enter(); - on_thread_enter(); + boost::on_process_enter(); + boost::on_thread_enter(); break; } case DLL_THREAD_ATTACH: { - on_thread_enter(); + boost::on_thread_enter(); break; } case DLL_THREAD_DETACH: { - on_thread_exit(); + boost::on_thread_exit(); break; } case DLL_PROCESS_DETACH: { - on_thread_exit(); - on_process_exit(); + boost::on_thread_exit(); + boost::on_process_exit(); break; } } @@ -52,7 +52,9 @@ return TRUE; } - extern "C" void tss_cleanup_implemented(void) +namespace boost +{ + void tss_cleanup_implemented() { /* This function's sole purpose is to cause a link error in cases where @@ -68,5 +70,7 @@ longer needed and can be removed. */ } +} + #endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL) diff --git a/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp b/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp index ae89bc4..8ef045b 100644 --- a/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp +++ b/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp @@ -1,4 +1,4 @@ -// $Id: tss_pe.cpp 49324 2008-10-13 20:30:13Z anthonyw $ +// $Id: tss_pe.cpp 66259 2010-10-29 23:27:00Z anthonyw $ // (C) Copyright Aaron W. LaFramboise, Roland Schwarz, Michael Glassford 2004. // (C) Copyright 2007 Roland Schwarz // (C) Copyright 2007 Anthony Williams @@ -19,7 +19,10 @@ #include <cstdlib> -extern "C" void tss_cleanup_implemented(void) {} +namespace boost +{ + void tss_cleanup_implemented() {} +} namespace { void NTAPI on_tls_callback(void* h, DWORD dwReason, PVOID pv) @@ -28,33 +31,24 @@ namespace { { case DLL_THREAD_DETACH: { - on_thread_exit(); + boost::on_thread_exit(); break; } } } - - void on_after_ctors(void) - { - on_process_enter(); - } - - void on_before_dtors(void) - { - on_thread_exit(); - } - - void on_after_dtors(void) - { - on_process_exit(); - } } +#if (__MINGW32_MAJOR_VERSION >3) || ((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18)) +extern "C" +{ + PIMAGE_TLS_CALLBACK __crt_xl_tls_callback__ __attribute__ ((section(".CRT$XLB"))) = on_tls_callback; +} +#else extern "C" { - void (* after_ctors )(void) __attribute__((section(".ctors"))) = on_after_ctors; - void (* before_dtors)(void) __attribute__((section(".dtors"))) = on_before_dtors; - void (* after_dtors )(void) __attribute__((section(".dtors.zzz"))) = on_after_dtors; + void (* after_ctors )() __attribute__((section(".ctors"))) = boost::on_process_enter; + void (* before_dtors)() __attribute__((section(".dtors"))) = boost::on_thread_exit; + void (* after_dtors )() __attribute__((section(".dtors.zzz"))) = boost::on_process_exit; ULONG __tls_index__ = 0; char __tls_end__ __attribute__((section(".tls$zzz"))) = 0; @@ -62,10 +56,8 @@ extern "C" { PIMAGE_TLS_CALLBACK __crt_xl_start__ __attribute__ ((section(".CRT$XLA"))) = 0; - PIMAGE_TLS_CALLBACK __crt_xl_tls_callback__ __attribute__ ((section(".CRT$XLB"))) = on_tls_callback; PIMAGE_TLS_CALLBACK __crt_xl_end__ __attribute__ ((section(".CRT$XLZ"))) = 0; } - extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata$T"))) = { (DWORD) &__tls_start__, @@ -75,6 +67,7 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata (DWORD) 0, (DWORD) 0 }; +#endif #elif defined(_MSC_VER) && !defined(UNDER_CE) @@ -89,13 +82,13 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata //Definitions required by implementation #if (_MSC_VER < 1300) // 1300 == VC++ 7.0 - typedef void (__cdecl *_PVFV)(void); + typedef void (__cdecl *_PVFV)(); #define INIRETSUCCESS - #define PVAPI void + #define PVAPI void __cdecl #else - typedef int (__cdecl *_PVFV)(void); + typedef int (__cdecl *_PVFV)(); #define INIRETSUCCESS 0 - #define PVAPI int + #define PVAPI int __cdecl #endif typedef void (NTAPI* _TLSCB)(HINSTANCE, DWORD, PVOID); @@ -112,9 +105,9 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata { //Forward declarations - static PVAPI on_tls_prepare(void); - static PVAPI on_process_init(void); - static PVAPI on_process_term(void); + static PVAPI on_tls_prepare(); + static PVAPI on_process_init(); + static PVAPI on_process_term(); static void NTAPI on_tls_callback(HINSTANCE, DWORD, PVOID); //The .CRT$Xxx information is taken from Codeguru: @@ -169,7 +162,7 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata #pragma warning(disable:4189) #endif - PVAPI on_tls_prepare(void) + PVAPI on_tls_prepare() { //The following line has an important side effect: //if the TLS directory is not already there, it will @@ -210,7 +203,7 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata #pragma warning(pop) #endif - PVAPI on_process_init(void) + PVAPI on_process_init() { //Schedule on_thread_exit() to be called for the main //thread before destructors of global objects have been @@ -221,18 +214,18 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata //for destructors of global objects, so that //shouldn't be a problem. - atexit(on_thread_exit); + atexit(boost::on_thread_exit); //Call Boost process entry callback here - on_process_enter(); + boost::on_process_enter(); return INIRETSUCCESS; } - PVAPI on_process_term(void) + PVAPI on_process_term() { - on_process_exit(); + boost::on_process_exit(); return INIRETSUCCESS; } @@ -241,7 +234,7 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata switch (dwReason) { case DLL_THREAD_DETACH: - on_thread_exit(); + boost::on_thread_exit(); break; } } @@ -251,10 +244,10 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata switch (dwReason) { case DLL_THREAD_DETACH: - on_thread_exit(); + boost::on_thread_exit(); break; case DLL_PROCESS_DETACH: - on_process_exit(); + boost::on_process_exit(); break; } return true; @@ -265,8 +258,9 @@ extern "C" { extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID)=&dll_callback; } - - extern "C" void tss_cleanup_implemented(void) +namespace boost +{ + void tss_cleanup_implemented() { /* This function's sole purpose is to cause a link error in cases where @@ -282,6 +276,8 @@ extern "C" longer needed and can be removed. */ } +} + #endif //defined(_MSC_VER) && !defined(UNDER_CE) #endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) diff --git a/3rdParty/Boost/src/tools/bcp/add_path.cpp b/3rdParty/Boost/src/tools/bcp/add_path.cpp index 04530c6..e55e8e3 100644 --- a/3rdParty/Boost/src/tools/bcp/add_path.cpp +++ b/3rdParty/Boost/src/tools/bcp/add_path.cpp @@ -71,10 +71,11 @@ void bcp_implementation::add_directory(const fs::path& p) std::string s(i->string()); if(m_boost_path.string().size()) s.erase(0, m_boost_path.string().size() + 1); - if(!m_dependencies.count(fs::path(s))) + fs::path np = s; + if(!m_dependencies.count(np)) { - m_dependencies[fs::path(s)] = p; // set up dependency tree - add_path(fs::path(s)); + m_dependencies[np] = p; // set up dependency tree + add_path(np); } ++i; } @@ -290,6 +291,24 @@ void bcp_implementation::add_file_dependencies(const fs::path& p, bool scanfile) continue; } include_file = i->str(); + fs::path test_file(m_boost_path / p.branch_path() / include_file); + if(fs::exists(test_file) && !fs::is_directory(test_file) && (p.branch_path().string() != "boost")) + { + if(!m_dependencies.count(p.branch_path() / include_file)) + { + m_dependencies[p.branch_path() / include_file] = p; + add_path(p.branch_path() / include_file); + } + } + else if(fs::exists(m_boost_path / include_file)) + { + if(!m_dependencies.count(include_file)) + { + m_dependencies[include_file] = p; + add_path(include_file); + } + } + ++i; } catch(const fs::filesystem_error&) { @@ -297,24 +316,6 @@ void bcp_implementation::add_file_dependencies(const fs::path& p, bool scanfile) ++i; continue; } - fs::path test_file(m_boost_path / p.branch_path() / include_file); - if(fs::exists(test_file) && !fs::is_directory(test_file) && (p.branch_path().string() != "boost")) - { - if(!m_dependencies.count(p.branch_path() / include_file)) - { - m_dependencies[p.branch_path() / include_file] = p; - add_path(p.branch_path() / include_file); - } - } - else if(fs::exists(m_boost_path / include_file)) - { - if(!m_dependencies.count(include_file)) - { - m_dependencies[include_file] = p; - add_path(include_file); - } - } - ++i; } // // Now we need to scan for Boost.Preprocessor includes that diff --git a/3rdParty/Boost/src/tools/bcp/copy_path.cpp b/3rdParty/Boost/src/tools/bcp/copy_path.cpp index af99b62..496696a 100644 --- a/3rdParty/Boost/src/tools/bcp/copy_path.cpp +++ b/3rdParty/Boost/src/tools/bcp/copy_path.cpp @@ -58,7 +58,33 @@ void bcp_implementation::copy_path(const fs::path& p) // // do text based copy if requested: // - if(m_namespace_name.size() && m_lib_names.size() && is_jam_file(p)) + if(p.leaf() == "Jamroot") + { + static std::vector<char> v1, v2; + v1.clear(); + v2.clear(); + std::ifstream is((m_boost_path / p).native_file_string().c_str()); + std::copy(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>(), std::back_inserter(v1)); + + static boost::regex libname_matcher; + if(libname_matcher.empty()) + { + libname_matcher.assign("boost_"); + } + + regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), libname_matcher, m_namespace_name + "_"); + std::swap(v1, v2); + v2.clear(); + + std::ofstream os; + if(m_unix_lines) + os.open((m_dest_path / p).native_file_string().c_str(), std::ios_base::binary | std::ios_base::out); + else + os.open((m_dest_path / p).native_file_string().c_str(), std::ios_base::out); + os.write(&*v1.begin(), v1.size()); + os.close(); + } + else if(m_namespace_name.size() && m_lib_names.size() && is_jam_file(p)) { static std::vector<char> v1, v2; v1.clear(); @@ -106,25 +132,33 @@ void bcp_implementation::copy_path(const fs::path& p) static const boost::regex namespace_matcher( "(?|" - "(namespace\\s+)boost(_\\w+)?" + "(namespace\\s+)boost(_\\w+)?(?:(\\s*::\\s*)phoenix)?" "|" "(namespace\\s+)(adstl|phoenix|rapidxml)\\>" "|" - "()boost((?:_\\w+)?\\s*(?:::|,|\\)))" + "()\\<boost((?:_(?!intrusive_tags)\\w+)?\\s*(?:::))(?:(\\s*)phoenix)?" "|" - "()((?:adstl|phoenix|rapidxml)\\s*(?:::|,|\\)))" + "()\\<((?:adstl|phoenix|rapidxml)\\s*(?:::))" "|" - "(namespace\\s+\\w+\\s*=\\s*(?:::\\s*)?)boost(_\\w+)?" + "(namespace\\s+\\w+\\s*=\\s*(?:::\\s*)?)boost(_\\w+)?(?:(\\s*::\\s*)phoenix)?" "|" - "(namespace\\s+\\w+\\s*=\\s*(?:::\\s*)?)(adstl|phoenix|rapidxml)\\>" + "(namespace\\s+\\w+\\s*=\\s*(?:::\\s*)?(?:\\w+\\s*::\\s*)?)(adstl|phoenix|rapidxml)\\>" "|" - "(^\\s*#\\s*define[^\\n]+)boost((?:_\\w+)?\\s*)$" + "(^\\s*#\\s*define\\s+\\w+\\s+)boost((?:_\\w+)?\\s*)$" "|" "(^\\s*#\\s*define[^\\n]+)((?:adstl|phoenix|rapidxml)\\s*)$" + "|" + "()boost(_asio_detail_posix_thread_function|_regex_free_static_mutex)" + "|" + "()(lw_thread_routine|at_thread_exit|on_process_enter|on_process_exit|on_thread_enter|on_thread_exit|tss_cleanup_implemented)" + "|" + "(BOOST_CLASS_REQUIRE4?[^;]*)boost((?:_\\w+)?\\s*,)" + "|" + "(\\(\\s*)boost(\\s*\\))" ")" - ); + ); - regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), namespace_matcher, "$1" + m_namespace_name + "$2"); + regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), namespace_matcher, "$1" + m_namespace_name + "$2(?3$3" + m_namespace_name + "phoenix)", boost::regex_constants::format_all); std::swap(v1, v2); v2.clear(); @@ -171,7 +205,8 @@ void bcp_implementation::copy_path(const fs::path& p) os.open((m_dest_path / p).native_file_string().c_str(), std::ios_base::binary | std::ios_base::out); else os.open((m_dest_path / p).native_file_string().c_str(), std::ios_base::out); - os.write(&*v1.begin(), v1.size()); + if(v1.size()) + os.write(&*v1.begin(), v1.size()); os.close(); } else if(m_unix_lines && !is_binary_file(p)) diff --git a/3rdParty/Boost/src/tools/bcp/fileview.cpp b/3rdParty/Boost/src/tools/bcp/fileview.cpp index da2bcc4..845582d 100644 --- a/3rdParty/Boost/src/tools/bcp/fileview.cpp +++ b/3rdParty/Boost/src/tools/bcp/fileview.cpp @@ -73,7 +73,7 @@ void fileview::open(const boost::filesystem::path& p) // iterators: fileview::const_iterator fileview::begin() const { - return &(pimpl->m_data[0]); + return pimpl->m_data.size() ? &(pimpl->m_data[0]) : 0; } fileview::const_iterator fileview::end() const |