diff options
Diffstat (limited to '3rdParty/Boost/src/libs')
95 files changed, 6574 insertions, 3194 deletions
diff --git a/3rdParty/Boost/src/libs/atomic/src/lockpool.cpp b/3rdParty/Boost/src/libs/atomic/src/lockpool.cpp new file mode 100644 index 0000000..13269a1 --- /dev/null +++ b/3rdParty/Boost/src/libs/atomic/src/lockpool.cpp @@ -0,0 +1,144 @@ +/* + * 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 (c) 2011 Helge Bahmann + * Copyright (c) 2013-2014 Andrey Semashev + */ +/*! + * \file lockpool.cpp + * + * This file contains implementation of the lockpool used to emulate atomic ops. + */ + +#include <cstddef> +#include <boost/config.hpp> +#include <boost/assert.hpp> +#include <boost/memory_order.hpp> +#include <boost/atomic/capabilities.hpp> + +#if BOOST_ATOMIC_FLAG_LOCK_FREE == 2 +#include <boost/atomic/detail/operations_lockfree.hpp> +#elif !defined(BOOST_HAS_PTHREADS) +#error Boost.Atomic: Unsupported target platform, POSIX threads are required when native atomic operations are not available +#else +#include <pthread.h> +#define BOOST_ATOMIC_USE_PTHREAD +#endif + +#include <boost/atomic/detail/lockpool.hpp> +#include <boost/atomic/detail/pause.hpp> + +namespace boost { +namespace atomics { +namespace detail { + +namespace { + +// This seems to be the maximum across all modern CPUs +// NOTE: This constant is made as a macro because some compilers (gcc 4.4 for one) don't allow enums or namespace scope constants in alignment attributes +#define BOOST_ATOMIC_CACHE_LINE_SIZE 64 + +template< unsigned int N > +struct padding +{ + char data[N]; +}; +template< > +struct padding< 0 > +{ +}; + +struct BOOST_ALIGNMENT(BOOST_ATOMIC_CACHE_LINE_SIZE) padded_lock +{ +#if defined(BOOST_ATOMIC_USE_PTHREAD) + typedef pthread_mutex_t lock_type; +#else + typedef atomics::detail::operations< 1u, false > operations; + typedef operations::storage_type lock_type; +#endif + + lock_type lock; + // The additional padding is needed to avoid false sharing between locks + enum { padding_size = (sizeof(lock_type) <= BOOST_ATOMIC_CACHE_LINE_SIZE ? + (BOOST_ATOMIC_CACHE_LINE_SIZE - sizeof(lock_type)) : + (BOOST_ATOMIC_CACHE_LINE_SIZE - sizeof(lock_type) % BOOST_ATOMIC_CACHE_LINE_SIZE)) }; + padding< padding_size > pad; +}; + +static padded_lock g_lock_pool[41] +#if defined(BOOST_ATOMIC_USE_PTHREAD) += +{ + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER +} +#endif +; + +} // namespace + + +#if !defined(BOOST_ATOMIC_USE_PTHREAD) + +// NOTE: This function must NOT be inline. Otherwise MSVC 9 will sometimes generate broken code for modulus operation which result in crashes. +BOOST_ATOMIC_DECL lockpool::scoped_lock::scoped_lock(const volatile void* addr) BOOST_NOEXCEPT : + m_lock(&g_lock_pool[reinterpret_cast< std::size_t >(addr) % (sizeof(g_lock_pool) / sizeof(*g_lock_pool))].lock) +{ + while (padded_lock::operations::test_and_set(*static_cast< padded_lock::lock_type* >(m_lock), memory_order_acquire)) + { + atomics::detail::pause(); + } +} + +BOOST_ATOMIC_DECL lockpool::scoped_lock::~scoped_lock() BOOST_NOEXCEPT +{ + padded_lock::operations::clear(*static_cast< padded_lock::lock_type* >(m_lock), memory_order_release); +} + +BOOST_ATOMIC_DECL void signal_fence() BOOST_NOEXCEPT; + +#else // !defined(BOOST_ATOMIC_USE_PTHREAD) + +BOOST_ATOMIC_DECL lockpool::scoped_lock::scoped_lock(const volatile void* addr) BOOST_NOEXCEPT : + m_lock(&g_lock_pool[reinterpret_cast< std::size_t >(addr) % (sizeof(g_lock_pool) / sizeof(*g_lock_pool))].lock) +{ + BOOST_VERIFY(pthread_mutex_lock(static_cast< pthread_mutex_t* >(m_lock)) == 0); +} + +BOOST_ATOMIC_DECL lockpool::scoped_lock::~scoped_lock() BOOST_NOEXCEPT +{ + BOOST_VERIFY(pthread_mutex_unlock(static_cast< pthread_mutex_t* >(m_lock)) == 0); +} + +#endif // !defined(BOOST_ATOMIC_USE_PTHREAD) + +BOOST_ATOMIC_DECL void lockpool::thread_fence() BOOST_NOEXCEPT +{ +#if BOOST_ATOMIC_THREAD_FENCE > 0 + atomics::detail::thread_fence(memory_order_seq_cst); +#else + // Emulate full fence by locking/unlocking a mutex + scoped_lock lock(0); +#endif +} + +BOOST_ATOMIC_DECL void lockpool::signal_fence() BOOST_NOEXCEPT +{ + // This function is intentionally non-inline, even if empty. This forces the compiler to treat its call as a compiler barrier. +#if BOOST_ATOMIC_SIGNAL_FENCE > 0 + atomics::detail::signal_fence(memory_order_seq_cst); +#endif +} + +} // namespace detail +} // namespace atomics +} // namespace boost diff --git a/3rdParty/Boost/src/libs/date_time/src/gregorian/date_generators.cpp b/3rdParty/Boost/src/libs/date_time/src/gregorian/date_generators.cpp index bbef7f6..32a58c1 100644 --- a/3rdParty/Boost/src/libs/date_time/src/gregorian/date_generators.cpp +++ b/3rdParty/Boost/src/libs/date_time/src/gregorian/date_generators.cpp @@ -4,5 +4,5 @@ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland, Bart Garst - * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + * $Date$ */ @@ -23,5 +23,5 @@ namespace date_time { BOOST_DATE_TIME_DECL const char* nth_as_str(int ele) { - if(ele >= 1 || ele <= 5) { + if(ele >= 1 && ele <= 5) { return _nth_as_str[ele]; } diff --git a/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_month.cpp b/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_month.cpp index efca973..8232378 100644 --- a/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_month.cpp +++ b/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_month.cpp @@ -4,5 +4,5 @@ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland, Bart Garst - * $Date: 2008-11-23 06:13:35 -0500 (Sun, 23 Nov 2008) $ + * $Date$ */ @@ -109,5 +109,5 @@ namespace gregorian { BOOST_DATE_TIME_DECL boost::date_time::all_date_names_put<greg_facet_config, char>* - create_facet_def(char type) + create_facet_def(char /*type*/) { typedef @@ -122,5 +122,5 @@ namespace gregorian { //! generates a locale with the set of gregorian name-strings of type char* - BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, char type){ + BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, char /*type*/){ typedef boost::date_time::all_date_names_put<greg_facet_config, char> facet_def; return std::locale(loc, new facet_def(short_month_names, @@ -140,5 +140,5 @@ namespace gregorian { BOOST_DATE_TIME_DECL boost::date_time::all_date_names_put<greg_facet_config, wchar_t>* - create_facet_def(wchar_t type) + create_facet_def(wchar_t /*type*/) { typedef @@ -153,5 +153,5 @@ namespace gregorian { //! generates a locale with the set of gregorian name-strings of type wchar_t* - BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, wchar_t type){ + BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, wchar_t /*type*/){ typedef boost::date_time::all_date_names_put<greg_facet_config, wchar_t> facet_def; return std::locale(loc, new facet_def(w_short_month_names, diff --git a/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_names.hpp b/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_names.hpp index 76a1a24..f20b320 100644 --- a/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_names.hpp +++ b/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_names.hpp @@ -4,5 +4,5 @@ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland, Bart Garst - * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + * $Date$ */ diff --git a/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_weekday.cpp b/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_weekday.cpp index 4057d29..ffdc96f 100644 --- a/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_weekday.cpp +++ b/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_weekday.cpp @@ -4,5 +4,5 @@ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland, Bart Garst - * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + * $Date$ */ diff --git a/3rdParty/Boost/src/libs/date_time/src/gregorian/gregorian_types.cpp b/3rdParty/Boost/src/libs/date_time/src/gregorian/gregorian_types.cpp index a856e79..7dd7f22 100644 --- a/3rdParty/Boost/src/libs/date_time/src/gregorian/gregorian_types.cpp +++ b/3rdParty/Boost/src/libs/date_time/src/gregorian/gregorian_types.cpp @@ -4,5 +4,5 @@ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland - * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + * $Date$ */ diff --git a/3rdParty/Boost/src/libs/date_time/src/posix_time/posix_time_types.cpp b/3rdParty/Boost/src/libs/date_time/src/posix_time/posix_time_types.cpp index 06ef563..4395301 100644 --- a/3rdParty/Boost/src/libs/date_time/src/posix_time/posix_time_types.cpp +++ b/3rdParty/Boost/src/libs/date_time/src/posix_time/posix_time_types.cpp @@ -5,5 +5,5 @@ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland - * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $ + * $Date$ */ diff --git a/3rdParty/Boost/src/libs/detail/utf8_codecvt_facet.cpp b/3rdParty/Boost/src/libs/detail/utf8_codecvt_facet.cpp deleted file mode 100644 index 7ea5eeb..0000000 --- a/3rdParty/Boost/src/libs/detail/utf8_codecvt_facet.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// utf8_codecvt_facet.cpp - -// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) -// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). -// 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) - -// Please see the comments in <boost/detail/utf8_codecvt_facet.hpp> to -// learn how this file should be used. - -#include <boost/detail/utf8_codecvt_facet.hpp> - -#include <cstdlib> // for multi-byte converson routines -#include <cassert> - -#include <boost/limits.hpp> -#include <boost/config.hpp> - -// If we don't have wstring, then Unicode support -// is not available anyway, so we don't need to even -// compiler this file. This also fixes the problem -// with mingw, which can compile this file, but will -// generate link error when building DLL. -#ifndef BOOST_NO_STD_WSTRING - -BOOST_UTF8_BEGIN_NAMESPACE - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implementation for wchar_t - -// Translate incoming UTF-8 into UCS-4 -std::codecvt_base::result utf8_codecvt_facet::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 { - // Basic algorithm: The first octet determines how many - // octets total make up the UCS-4 character. The remaining - // "continuing octets" all begin with "10". To convert, subtract - // the amount that specifies the number of octets from the first - // octet. Subtract 0x80 (1000 0000) from each continuing octet, - // then mash the whole lot together. Note that each continuing - // octet only uses 6 bits as unique values, so only shift by - // multiples of 6 to combine. - while (from != from_end && to != to_end) { - - // Error checking on the first octet - if (invalid_leading_octet(*from)){ - from_next = from; - to_next = to; - return std::codecvt_base::error; - } - - // The first octet is adjusted by a value dependent upon - // the number of "continuing octets" encoding the character - const int cont_octet_count = get_cont_octet_count(*from); - const wchar_t octet1_modifier_table[] = { - 0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc - }; - - // The unsigned char conversion is necessary in case char is - // signed (I learned this the hard way) - wchar_t ucs_result = - (unsigned char)(*from++) - octet1_modifier_table[cont_octet_count]; - - // Invariants : - // 1) At the start of the loop, 'i' continuing characters have been - // processed - // 2) *from points to the next continuing character to be processed. - int i = 0; - while(i != cont_octet_count && from != from_end) { - - // Error checking on continuing characters - if (invalid_continuing_octet(*from)) { - from_next = from; - to_next = to; - return std::codecvt_base::error; - } - - ucs_result *= (1 << 6); - - // each continuing character has an extra (10xxxxxx)b attached to - // it that must be removed. - ucs_result += (unsigned char)(*from++) - 0x80; - ++i; - } - - // If the buffer ends with an incomplete unicode character... - if (from == from_end && i != cont_octet_count) { - // rewind "from" to before the current character translation - from_next = from - (i+1); - to_next = to; - return std::codecvt_base::partial; - } - *to++ = ucs_result; - } - from_next = from; - to_next = to; - - // Were we done converting or did we run out of destination space? - if(from == from_end) return std::codecvt_base::ok; - else return std::codecvt_base::partial; -} - -std::codecvt_base::result utf8_codecvt_facet::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 -{ - // RG - consider merging this table with the other one - const wchar_t octet1_modifier_table[] = { - 0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc - }; - - wchar_t max_wchar = (std::numeric_limits<wchar_t>::max)(); - while (from != from_end && to != to_end) { - - // Check for invalid UCS-4 character - if (*from > max_wchar) { - from_next = from; - to_next = to; - return std::codecvt_base::error; - } - - int cont_octet_count = get_cont_octet_out_count(*from); - - // RG - comment this formula better - int shift_exponent = (cont_octet_count) * 6; - - // Process the first character - *to++ = static_cast<char>(octet1_modifier_table[cont_octet_count] + - (unsigned char)(*from / (1 << shift_exponent))); - - // Process the continuation characters - // Invariants: At the start of the loop: - // 1) 'i' continuing octets have been generated - // 2) '*to' points to the next location to place an octet - // 3) shift_exponent is 6 more than needed for the next octet - int i = 0; - while (i != cont_octet_count && to != to_end) { - shift_exponent -= 6; - *to++ = static_cast<char>(0x80 + ((*from / (1 << shift_exponent)) % (1 << 6))); - ++i; - } - // If we filled up the out buffer before encoding the character - if(to == to_end && i != cont_octet_count) { - from_next = from; - to_next = to - (i+1); - return std::codecvt_base::partial; - } - ++from; - } - from_next = from; - to_next = to; - // Were we done or did we run out of destination space - if(from == from_end) return std::codecvt_base::ok; - else return std::codecvt_base::partial; -} - -// How many char objects can I process to get <= max_limit -// wchar_t objects? -int utf8_codecvt_facet::do_length( - BOOST_CODECVT_DO_LENGTH_CONST std::mbstate_t &, - const char * from, - const char * from_end, - std::size_t max_limit -#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) -) const throw() -#else -) const -#endif -{ - // RG - this code is confusing! I need a better way to express it. - // and test cases. - - // Invariants: - // 1) last_octet_count has the size of the last measured character - // 2) char_count holds the number of characters shown to fit - // within the bounds so far (no greater than max_limit) - // 3) from_next points to the octet 'last_octet_count' before the - // last measured character. - int last_octet_count=0; - std::size_t char_count = 0; - const char* from_next = from; - // Use "<" because the buffer may represent incomplete characters - while (from_next+last_octet_count <= from_end && char_count <= max_limit) { - from_next += last_octet_count; - last_octet_count = (get_octet_count(*from_next)); - ++char_count; - } - return static_cast<int>(from_next-from_end); -} - -unsigned int utf8_codecvt_facet::get_octet_count( - unsigned char lead_octet -){ - // if the 0-bit (MSB) is 0, then 1 character - if (lead_octet <= 0x7f) return 1; - - // Otherwise the count number of consecutive 1 bits starting at MSB -// assert(0xc0 <= lead_octet && lead_octet <= 0xfd); - - if (0xc0 <= lead_octet && lead_octet <= 0xdf) return 2; - else if (0xe0 <= lead_octet && lead_octet <= 0xef) return 3; - else if (0xf0 <= lead_octet && lead_octet <= 0xf7) return 4; - else if (0xf8 <= lead_octet && lead_octet <= 0xfb) return 5; - else return 6; -} -BOOST_UTF8_END_NAMESPACE - -namespace { -template<std::size_t s> -int get_cont_octet_out_count_impl(wchar_t word){ - if (word < 0x80) { - return 0; - } - if (word < 0x800) { - return 1; - } - return 2; -} - -template<> -int get_cont_octet_out_count_impl<4>(wchar_t word){ - if (word < 0x80) { - return 0; - } - if (word < 0x800) { - return 1; - } - - // Note that the following code will generate warnings on some platforms - // where wchar_t is defined as UCS2. The warnings are superfluous as the - // specialization is never instantitiated with such compilers, but this - // can cause problems if warnings are being treated as errors, so we guard - // against that. Including <boost/detail/utf8_codecvt_facet.hpp> as we do - // should be enough to get WCHAR_MAX defined. -#if !defined(WCHAR_MAX) -# error WCHAR_MAX not defined! -#endif - // cope with VC++ 7.1 or earlier having invalid WCHAR_MAX -#if defined(_MSC_VER) && _MSC_VER <= 1310 // 7.1 or earlier - return 2; -#elif WCHAR_MAX > 0x10000 - - if (word < 0x10000) { - return 2; - } - if (word < 0x200000) { - return 3; - } - if (word < 0x4000000) { - return 4; - } - return 5; - -#else - return 2; -#endif -} - -} // namespace anonymous - -BOOST_UTF8_BEGIN_NAMESPACE -// How many "continuing octets" will be needed for this word -// == total octets - 1. -int utf8_codecvt_facet::get_cont_octet_out_count( - wchar_t word -) const { - return get_cont_octet_out_count_impl<sizeof(wchar_t)>(word); -} -BOOST_UTF8_END_NAMESPACE - -#endif diff --git a/3rdParty/Boost/src/libs/exception/build/Jamfile.v2 b/3rdParty/Boost/src/libs/exception/build/Jamfile.v2 new file mode 100644 index 0000000..fb47659 --- /dev/null +++ b/3rdParty/Boost/src/libs/exception/build/Jamfile.v2 @@ -0,0 +1,14 @@ +# Boost Exception Library build Jamfile +# +# Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +project boost/exception + : source-location ../src + : requirements <link>static + ; + +lib boost_exception : clone_current_exception_non_intrusive.cpp ; +boost-install boost_exception ; diff --git a/3rdParty/Boost/src/libs/exception/src/clone_current_exception_non_intrusive.cpp b/3rdParty/Boost/src/libs/exception/src/clone_current_exception_non_intrusive.cpp new file mode 100644 index 0000000..1710cd7 --- /dev/null +++ b/3rdParty/Boost/src/libs/exception/src/clone_current_exception_non_intrusive.cpp @@ -0,0 +1,320 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +//This MSVC-specific cpp file implements non-intrusive cloning of exception objects. +//Based on an exception_ptr implementation by Anthony Williams. + +#ifdef BOOST_NO_EXCEPTIONS +#error This file requires exception handling to be enabled. +#endif + +#include <boost/exception/detail/clone_current_exception.hpp> + +#if defined(BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR) && defined(_MSC_VER) && defined(_M_IX86) && !defined(_M_X64) + +//Non-intrusive cloning support implemented below, only for MSVC versions mentioned above. +//Thanks Anthony Williams! + +#include <boost/exception/exception.hpp> +#include <boost/shared_ptr.hpp> +#ifndef BOOST_NO_RTTI +#include <typeinfo> +#endif +#include <windows.h> +#include <malloc.h> + +namespace + { + unsigned const exception_maximum_parameters=15; + unsigned const exception_noncontinuable=1; + +#if _MSC_VER==1310 + int const exception_info_offset=0x74; +#elif (_MSC_VER==1400 || _MSC_VER==1500) + int const exception_info_offset=0x80; +#else + int const exception_info_offset=-1; +#endif + + struct + exception_record + { + unsigned long ExceptionCode; + unsigned long ExceptionFlags; + exception_record * ExceptionRecord; + void * ExceptionAddress; + unsigned long NumberParameters; + ULONG_PTR ExceptionInformation[exception_maximum_parameters]; + }; + + struct + exception_pointers + { + exception_record * ExceptionRecord; + void * ContextRecord; + }; + + unsigned const cpp_exception_code=0xE06D7363; + unsigned const cpp_exception_magic_flag=0x19930520; + unsigned const cpp_exception_parameter_count=3; + + struct + dummy_exception_type + { + }; + + typedef int(dummy_exception_type::*normal_copy_constructor_ptr)(void * src); + typedef int(dummy_exception_type::*copy_constructor_with_virtual_base_ptr)(void * src,void * dst); + typedef void (dummy_exception_type::*destructor_ptr)(); + + union + cpp_copy_constructor + { + normal_copy_constructor_ptr normal_copy_constructor; + copy_constructor_with_virtual_base_ptr copy_constructor_with_virtual_base; + }; + + enum + cpp_type_flags + { + class_is_simple_type=1, + class_has_virtual_base=4 + }; + + struct + cpp_type_info + { + unsigned flags; +#ifndef BOOST_NO_RTTI + void const * type_info; +#else + std::type_info * type_info; +#endif + int this_offset; + int vbase_descr; + int vbase_offset; + unsigned long size; + cpp_copy_constructor copy_constructor; + }; + + struct + cpp_type_info_table + { + unsigned count; + const cpp_type_info * info[1]; + }; + + struct + cpp_exception_type + { + unsigned flags; + destructor_ptr destructor; + void(*custom_handler)(); + cpp_type_info_table const * type_info_table; + }; + + struct + exception_object_deleter + { + cpp_exception_type const & et_; + + exception_object_deleter( cpp_exception_type const & et ): + et_(et) + { + } + + void + operator()( void * obj ) + { + BOOST_ASSERT(obj!=0); + dummy_exception_type * dummy_exception_ptr=reinterpret_cast<dummy_exception_type *>(obj); + (dummy_exception_ptr->*(et_.destructor))(); + free(obj); + } + }; + + cpp_type_info const & + get_cpp_type_info( cpp_exception_type const & et ) + { + cpp_type_info const * ti = et.type_info_table->info[0]; + BOOST_ASSERT(ti!=0); + return *ti; + } + + void + copy_msvc_exception( void * dst, void * src, cpp_type_info const & ti ) + { + if( !(ti.flags & class_is_simple_type) && ti.copy_constructor.normal_copy_constructor ) + { + dummy_exception_type * dummy_exception_ptr = reinterpret_cast<dummy_exception_type *>(dst); + if( ti.flags & class_has_virtual_base ) + (dummy_exception_ptr->*(ti.copy_constructor.copy_constructor_with_virtual_base))(src,dst); + else + (dummy_exception_ptr->*(ti.copy_constructor.normal_copy_constructor))(src); + } + else + memmove(dst,src,ti.size); + } + + boost::shared_ptr<void> + clone_msvc_exception( void * src, cpp_exception_type const & et ) + { + assert(src!=0); + cpp_type_info const & ti=get_cpp_type_info(et); + if( void * dst = malloc(ti.size) ) + { + try + { + copy_msvc_exception(dst,src,ti); + } + catch( + ... ) + { + free(dst); + throw; + } + return boost::shared_ptr<void>(dst,exception_object_deleter(et)); + } + else + throw std::bad_alloc(); + } + + class + cloned_exception: + public boost::exception_detail::clone_base + { + cloned_exception( cloned_exception const & ); + cloned_exception & operator=( cloned_exception const & ); + + cpp_exception_type const & et_; + boost::shared_ptr<void> exc_; + + public: + + cloned_exception( void * exc, cpp_exception_type const & et ): + et_(et), + exc_(clone_msvc_exception(exc,et_)) + { + } + + ~cloned_exception() throw() + { + } + + boost::exception_detail::clone_base const * + clone() const + { + return new cloned_exception(exc_.get(),et_); + } + + void + rethrow() const + { + cpp_type_info const & ti=get_cpp_type_info(et_); + void * dst = _alloca(ti.size); + copy_msvc_exception(dst,exc_.get(),ti); + ULONG_PTR args[cpp_exception_parameter_count]; + args[0]=cpp_exception_magic_flag; + args[1]=reinterpret_cast<ULONG_PTR>(dst); + args[2]=reinterpret_cast<ULONG_PTR>(&et_); + RaiseException(cpp_exception_code,EXCEPTION_NONCONTINUABLE,cpp_exception_parameter_count,args); + } + }; + + bool + is_cpp_exception( EXCEPTION_RECORD const * record ) + { + return record && + (record->ExceptionCode==cpp_exception_code) && + (record->NumberParameters==cpp_exception_parameter_count) && + (record->ExceptionInformation[0]==cpp_exception_magic_flag); + } + + unsigned long + exception_cloning_filter( int & result, boost::exception_detail::clone_base const * & ptr, void * info_ ) + { + BOOST_ASSERT(exception_info_offset>=0); + BOOST_ASSERT(info_!=0); + EXCEPTION_POINTERS * info=reinterpret_cast<EXCEPTION_POINTERS *>(info_); + EXCEPTION_RECORD * record=info->ExceptionRecord; + if( is_cpp_exception(record) ) + { + if( !record->ExceptionInformation[2] ) + record = *reinterpret_cast<EXCEPTION_RECORD * *>(reinterpret_cast<char *>(_errno())+exception_info_offset); + if( is_cpp_exception(record) && record->ExceptionInformation[2] ) + try + { + ptr = new cloned_exception( + reinterpret_cast<void *>(record->ExceptionInformation[1]), + *reinterpret_cast<cpp_exception_type const *>(record->ExceptionInformation[2])); + result = boost::exception_detail::clone_current_exception_result::success; + } + catch( + std::bad_alloc & ) + { + result = boost::exception_detail::clone_current_exception_result::bad_alloc; + } + catch( + ... ) + { + result = boost::exception_detail::clone_current_exception_result::bad_exception; + } + } + return EXCEPTION_EXECUTE_HANDLER; + } + } + +namespace +boost + { + namespace + exception_detail + { + int + clone_current_exception_non_intrusive( clone_base const * & cloned ) + { + BOOST_ASSERT(!cloned); + int result = clone_current_exception_result::not_supported; + if( exception_info_offset>=0 ) + { + clone_base const * ptr=0; + __try + { + throw; + } + __except(exception_cloning_filter(result,ptr,GetExceptionInformation())) + { + } + if( result==clone_current_exception_result::success ) + cloned=ptr; + } + BOOST_ASSERT(result!=clone_current_exception_result::success || cloned); + return result; + } + } + } + +#else + +//On all other compilers, return clone_current_exception_result::not_supported. +//On such platforms, only the intrusive enable_current_exception() cloning will work. + +#include <boost/config.hpp> + +namespace +boost + { + namespace + exception_detail + { + int + clone_current_exception_non_intrusive( clone_base const * & ) + { + return clone_current_exception_result::not_supported; + } + } + } + +#endif diff --git a/3rdParty/Boost/src/libs/filesystem/v3/src/codecvt_error_category.cpp b/3rdParty/Boost/src/libs/filesystem/src/codecvt_error_category.cpp index b35b4a9..165c6ea 100644 --- a/3rdParty/Boost/src/libs/filesystem/v3/src/codecvt_error_category.cpp +++ b/3rdParty/Boost/src/libs/filesystem/src/codecvt_error_category.cpp @@ -10,11 +10,4 @@ //--------------------------------------------------------------------------------------// -#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> @@ -27,6 +20,6 @@ #endif -#include <boost/filesystem/v3/config.hpp> -#include <boost/filesystem/v3/path_traits.hpp> +#include <boost/filesystem/config.hpp> +#include <boost/filesystem/path_traits.hpp> #include <boost/system/error_code.hpp> #include <locale> @@ -43,9 +36,9 @@ namespace public: codecvt_error_cat(){} - const char* name() const; + const char* name() const BOOST_SYSTEM_NOEXCEPT; std::string message(int ev) const; }; - const char* codecvt_error_cat::name() const + const char* codecvt_error_cat::name() const BOOST_SYSTEM_NOEXCEPT { return "codecvt"; @@ -79,5 +72,5 @@ namespace namespace boost { - namespace filesystem3 + namespace filesystem { @@ -88,6 +81,4 @@ namespace boost } - } // namespace filesystem3 + } // namespace filesystem } // namespace boost - -#endif // no wide character support diff --git a/3rdParty/Boost/src/libs/filesystem/v3/src/filesystem_utf8_codecvt_facet.cpp b/3rdParty/Boost/src/libs/filesystem/src/filesystem_utf8_codecvt_facet.cpp index 1849a1a..8a5af1e 100644 --- a/3rdParty/Boost/src/libs/filesystem/v3/src/filesystem_utf8_codecvt_facet.cpp +++ b/3rdParty/Boost/src/libs/filesystem/src/filesystem_utf8_codecvt_facet.cpp @@ -4,4 +4,8 @@ // or copy at http://www.boost.org/LICENSE_1_0.txt) +// For HP-UX, request that WCHAR_MAX and WCHAR_MIN be defined as macros, +// not casts. See ticket 5048 +#define _INCLUDE_STDCSOURCE_199901 + #ifndef BOOST_SYSTEM_NO_DEPRECATED # define BOOST_SYSTEM_NO_DEPRECATED @@ -17,5 +21,5 @@ #define BOOST_UTF8_DECL BOOST_FILESYSTEM_DECL -#include "libs/detail/utf8_codecvt_facet.cpp" +#include <boost/detail/utf8_codecvt_facet.ipp> #undef BOOST_UTF8_BEGIN_NAMESPACE diff --git a/3rdParty/Boost/src/libs/filesystem/v3/src/operations.cpp b/3rdParty/Boost/src/libs/filesystem/src/operations.cpp index 2460c1d..09b8853 100644 --- a/3rdParty/Boost/src/libs/filesystem/v3/src/operations.cpp +++ b/3rdParty/Boost/src/libs/filesystem/src/operations.cpp @@ -11,26 +11,6 @@ //--------------------------------------------------------------------------------------// -#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 64-bit offset macros BEFORE including boost/config.hpp (see ticket #5355) +#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 @@ -50,9 +30,27 @@ #endif -#include <boost/filesystem/v3/operations.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 + +#ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS // Sun readdir_r()needs this +#endif + +#include <boost/filesystem/operations.hpp> #include <boost/scoped_array.hpp> #include <boost/detail/workaround.hpp> -#include <cstdlib> // for malloc, free #include <vector> +#include <cstdlib> // for malloc, free +#include <cstring> +#include <cstdio> // for remove, rename +#if defined(__QNXNTO__) // see ticket #5355 +# include <stdio.h> +#endif +#include <cerrno> #ifdef BOOST_FILEYSTEM_INCLUDE_IOSTREAM @@ -60,7 +58,8 @@ #endif -namespace fs = boost::filesystem3; -using boost::filesystem3::path; -using boost::filesystem3::filesystem_error; +namespace fs = boost::filesystem; +using boost::filesystem::path; +using boost::filesystem::filesystem_error; +using boost::filesystem::perms; using boost::system::error_code; using boost::system::error_category; @@ -71,6 +70,9 @@ using std::wstring; # ifdef BOOST_POSIX_API + const fs::path dot_path("."); + const fs::path dot_dot_path(".."); # include <sys/types.h> -# if !defined(__APPLE__) && !defined(__OpenBSD__) +# include <sys/stat.h> +# if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__ANDROID__) # include <sys/statvfs.h> # define BOOST_STATVFS statvfs @@ -79,4 +81,6 @@ using std::wstring; # ifdef __OpenBSD__ # include <sys/param.h> +# elif defined(__ANDROID__) +# include <sys/vfs.h> # endif # include <sys/mount.h> @@ -92,4 +96,6 @@ using std::wstring; # else // BOOST_WINDOW_API + const fs::path dot_path(L"."); + const fs::path dot_dot_path(L".."); # if (defined(__MINGW32__) || defined(__CYGWIN__)) && !defined(WINVER) // Versions of MinGW or Cygwin that support Filesystem V3 support at least WINVER 0x501. @@ -97,4 +103,5 @@ using std::wstring; # define WINVER 0x501 # endif +# include <io.h> # include <windows.h> # include <winnt.h> @@ -179,12 +186,4 @@ typedef struct _REPARSE_DATA_BUFFER { # 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 ----------------------------------------------------// @@ -227,5 +226,5 @@ typedef struct _REPARSE_DATA_BUFFER { # 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_MOVE_FILE(OLD,NEW)(::MoveFileExW(OLD, NEW, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED)!= 0) # define BOOST_RESIZE_FILE(P,SZ)(resize_file_api(P, SZ)!= 0) # define BOOST_READ_SYMLINK(P,T) @@ -245,13 +244,7 @@ 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; + boost::filesystem::directory_iterator end_dir_itr; const std::size_t buf_size(128); @@ -412,4 +405,6 @@ namespace //--------------------------------------------------------------------------------------// + const char dot = '.'; + bool not_found_error(int errval) { @@ -433,5 +428,8 @@ namespace struct stat from_stat; if (::stat(from_p.c_str(), &from_stat)!= 0) - { return false; } + { + ::close(infile); + return false; + } int oflag = O_CREAT | O_WRONLY | O_TRUNC; @@ -485,4 +483,6 @@ namespace //--------------------------------------------------------------------------------------// + const wchar_t dot = L'.'; + bool not_found_error(int errval) { @@ -497,4 +497,26 @@ namespace } +// some distributions of mingw as early as GLIBCXX__ 20110325 have _stricmp, but the +// offical 4.6.2 release with __GLIBCXX__ 20111026 doesn't. Play it safe for now, and +// only use _stricmp if _MSC_VER is defined +#if defined(_MSC_VER) // || (defined(__GLIBCXX__) && __GLIBCXX__ >= 20110325) +# define BOOST_FILESYSTEM_STRICMP _stricmp +#else +# define BOOST_FILESYSTEM_STRICMP strcmp +#endif + + perms make_permissions(const path& p, DWORD attr) + { + perms prms = fs::owner_read | fs::group_read | fs::others_read; + if ((attr & FILE_ATTRIBUTE_READONLY) == 0) + prms |= fs::owner_write | fs::group_write | fs::others_write; + if (BOOST_FILESYSTEM_STRICMP(p.extension().string().c_str(), ".exe") == 0 + || BOOST_FILESYSTEM_STRICMP(p.extension().string().c_str(), ".com") == 0 + || BOOST_FILESYSTEM_STRICMP(p.extension().string().c_str(), ".bat") == 0 + || BOOST_FILESYSTEM_STRICMP(p.extension().string().c_str(), ".cmd") == 0) + prms |= fs::owner_exe | fs::group_exe | fs::others_exe; + return prms; + } + // these constants come from inspecting some Microsoft sample code std::time_t to_time_t(const FILETIME & ft) @@ -585,5 +607,5 @@ namespace if (not_found_error(errval)) { - return fs::file_status(fs::file_not_found); + return fs::file_status(fs::file_not_found, fs::no_perms); } else if ((errval == ERROR_SHARING_VIOLATION)) @@ -680,5 +702,5 @@ namespace namespace boost { -namespace filesystem3 +namespace filesystem { @@ -751,4 +773,86 @@ namespace detail BOOST_FILESYSTEM_DECL + path canonical(const path& p, const path& base, system::error_code* ec) + { + path source (p.is_absolute() ? p : absolute(p, base)); + path root(source.root_path()); + path result; + + system::error_code local_ec; + file_status stat (status(source, local_ec)); + + if (stat.type() == fs::file_not_found) + { + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error( + "boost::filesystem::canonical", source, + error_code(system::errc::no_such_file_or_directory, system::generic_category()))); + ec->assign(system::errc::no_such_file_or_directory, system::generic_category()); + return result; + } + else if (local_ec) + { + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error( + "boost::filesystem::canonical", source, local_ec)); + *ec = local_ec; + return result; + } + + bool scan (true); + while (scan) + { + scan = false; + result.clear(); + for (path::iterator itr = source.begin(); itr != source.end(); ++itr) + { + if (*itr == dot_path) + continue; + if (*itr == dot_dot_path) + { + if (result != root) + result.remove_filename(); + continue; + } + + result /= *itr; + + bool is_sym (is_symlink(detail::symlink_status(result, ec))); + if (ec && *ec) + return path(); + + if (is_sym) + { + path link(detail::read_symlink(result, ec)); + if (ec && *ec) + return path(); + result.remove_filename(); + + if (link.is_absolute()) + { + for (++itr; itr != source.end(); ++itr) + link /= *itr; + source = link; + } + else // link is relative + { + path new_source(result); + new_source /= link; + for (++itr; itr != source.end(); ++itr) + new_source /= *itr; + source = new_source; + } + scan = true; // symlink causes scan to be restarted + break; + } + } + } + if (ec != 0) + ec->clear(); + BOOST_ASSERT_MSG(result.is_absolute(), "canonical() implementation error; please report"); + return result; + } + + BOOST_FILESYSTEM_DECL void copy(const path& from, const path& to, system::error_code* ec) { @@ -817,22 +921,39 @@ namespace detail bool create_directories(const path& p, system::error_code* ec) { - if (p.empty() || exists(p)) + error_code local_ec; + file_status p_status = status(p, local_ec); + + if (p_status.type() == directory_file) { - if (!p.empty() && !is_directory(p)) + if (ec != 0) + ec->clear(); + return false; + } + + path parent = p.parent_path(); + BOOST_ASSERT_MSG(parent != p, "internal error: p == p.parent_path()"); + if (!parent.empty()) + { + // determine if the parent exists + file_status parent_status = status(parent, local_ec); + + // if the parent does not exist, create the parent + if (parent_status.type() == file_not_found) + { + create_directories(parent, local_ec); + if (local_ec) { 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()); - } + "boost::filesystem::create_directories", parent, local_ec)); + else + *ec = local_ec; 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; + // create the directory + return create_directory(p, ec); } @@ -842,5 +963,6 @@ namespace detail if (BOOST_CREATE_DIRECTORY(p.c_str())) { - if (ec != 0) ec->clear(); + if (ec != 0) + ec->clear(); return true; } @@ -851,5 +973,6 @@ namespace detail if (errval == BOOST_ERROR_ALREADY_EXISTS && is_directory(p, dummy)) { - if (ec != 0) ec->clear(); + if (ec != 0) + ec->clear(); return false; } @@ -1244,4 +1367,92 @@ namespace detail } +# ifdef BOOST_POSIX_API + const perms active_bits(all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit); + inline mode_t mode_cast(perms prms) { return prms & active_bits; } +# endif + + BOOST_FILESYSTEM_DECL + void permissions(const path& p, perms prms, system::error_code* ec) + { + BOOST_ASSERT_MSG(!((prms & add_perms) && (prms & remove_perms)), + "add_perms and remove_perms are mutually exclusive"); + + if ((prms & add_perms) && (prms & remove_perms)) // precondition failed + return; + +# ifdef BOOST_POSIX_API + error_code local_ec; + file_status current_status((prms & symlink_perms) + ? fs::symlink_status(p, local_ec) + : fs::status(p, local_ec)); + if (local_ec) + { + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error( + "boost::filesystem::permissions", p, local_ec)); + else + *ec = local_ec; + return; + } + + if (prms & add_perms) + prms |= current_status.permissions(); + else if (prms & remove_perms) + prms = current_status.permissions() & ~prms; + + // Mac OS X Lion and some other platforms don't support fchmodat(). + // Solaris (SunPro and gcc) only support fchmodat() on Solaris 11 and higher, + // and a runtime check is too much trouble. + // Linux does not support permissions on symbolic links and has no plans to + // support them in the future. The chmod() code is thus more practical, + // rather than always hitting ENOTSUP when sending in AT_SYMLINK_NO_FOLLOW. + // - See the 3rd paragraph of + // "Symbolic link ownership, permissions, and timestamps" at: + // "http://man7.org/linux/man-pages/man7/symlink.7.html" + // - See the fchmodat() Linux man page: + // "http://man7.org/linux/man-pages/man2/fchmodat.2.html" +# if defined(AT_FDCWD) && defined(AT_SYMLINK_NOFOLLOW) \ + && !(defined(__SUNPRO_CC) || defined(__sun) || defined(sun)) \ + && !(defined(linux) || defined(__linux) || defined(__linux__)) + if (::fchmodat(AT_FDCWD, p.c_str(), mode_cast(prms), + !(prms & symlink_perms) ? 0 : AT_SYMLINK_NOFOLLOW)) +# else // fallback if fchmodat() not supported + if (::chmod(p.c_str(), mode_cast(prms))) +# endif + { + if (ec == 0) + BOOST_FILESYSTEM_THROW(filesystem_error( + "boost::filesystem::permissions", p, + error_code(errno, system::generic_category()))); + else + ec->assign(errno, system::generic_category()); + } + +# else // Windows + + // if not going to alter FILE_ATTRIBUTE_READONLY, just return + if (!(!((prms & (add_perms | remove_perms))) + || (prms & (owner_write|group_write|others_write)))) + return; + + DWORD attr = ::GetFileAttributesW(p.c_str()); + + if (error(attr == 0, p, ec, "boost::filesystem::permissions")) + return; + + if (prms & add_perms) + attr &= ~FILE_ATTRIBUTE_READONLY; + else if (prms & remove_perms) + attr |= FILE_ATTRIBUTE_READONLY; + else if (prms & (owner_write|group_write|others_write)) + attr &= ~FILE_ATTRIBUTE_READONLY; + else + attr |= FILE_ATTRIBUTE_READONLY; + + error(::SetFileAttributesW(p.c_str(), attr) == 0, + p, ec, "boost::filesystem::permissions"); +# endif + } + BOOST_FILESYSTEM_DECL path read_symlink(const path& p, system::error_code* ec) @@ -1407,5 +1618,5 @@ namespace detail if (not_found_error(errno)) { - return fs::file_status(fs::file_not_found); + return fs::file_status(fs::file_not_found, fs::no_perms); } if (ec == 0) @@ -1416,15 +1627,21 @@ namespace detail if (ec != 0) ec->clear();; if (S_ISDIR(path_stat.st_mode)) - return fs::file_status(fs::directory_file); + return fs::file_status(fs::directory_file, + static_cast<perms>(path_stat.st_mode) & fs::perms_mask); if (S_ISREG(path_stat.st_mode)) - return fs::file_status(fs::regular_file); + return fs::file_status(fs::regular_file, + static_cast<perms>(path_stat.st_mode) & fs::perms_mask); if (S_ISBLK(path_stat.st_mode)) - return fs::file_status(fs::block_file); + return fs::file_status(fs::block_file, + static_cast<perms>(path_stat.st_mode) & fs::perms_mask); if (S_ISCHR(path_stat.st_mode)) - return fs::file_status(fs::character_file); + return fs::file_status(fs::character_file, + static_cast<perms>(path_stat.st_mode) & fs::perms_mask); if (S_ISFIFO(path_stat.st_mode)) - return fs::file_status(fs::fifo_file); + return fs::file_status(fs::fifo_file, + static_cast<perms>(path_stat.st_mode) & fs::perms_mask); if (S_ISSOCK(path_stat.st_mode)) - return fs::file_status(fs::socket_file); + return fs::file_status(fs::socket_file, + static_cast<perms>(path_stat.st_mode) & fs::perms_mask); return fs::file_status(fs::type_unknown); @@ -1437,5 +1654,7 @@ namespace detail } - // reparse point handling + // reparse point handling; + // since GetFileAttributesW does not resolve symlinks, try to open a file + // handle to discover if the file exists if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { @@ -1455,11 +1674,11 @@ namespace detail if (!is_reparse_point_a_symlink(p)) - return file_status(reparse_file); + return file_status(reparse_file, make_permissions(p, attr)); } if (ec != 0) ec->clear(); return (attr & FILE_ATTRIBUTE_DIRECTORY) - ? file_status(directory_file) - : file_status(regular_file); + ? file_status(directory_file, make_permissions(p, attr)) + : file_status(regular_file, make_permissions(p, attr)); # endif @@ -1479,5 +1698,5 @@ namespace detail if (errno == ENOENT || errno == ENOTDIR) // these are not errors { - return fs::file_status(fs::file_not_found); + return fs::file_status(fs::file_not_found, fs::no_perms); } if (ec == 0) @@ -1488,17 +1707,24 @@ namespace detail if (ec != 0) ec->clear(); if (S_ISREG(path_stat.st_mode)) - return fs::file_status(fs::regular_file); + return fs::file_status(fs::regular_file, + static_cast<perms>(path_stat.st_mode) & fs::perms_mask); if (S_ISDIR(path_stat.st_mode)) - return fs::file_status(fs::directory_file); + return fs::file_status(fs::directory_file, + static_cast<perms>(path_stat.st_mode) & fs::perms_mask); if (S_ISLNK(path_stat.st_mode)) - return fs::file_status(fs::symlink_file); + return fs::file_status(fs::symlink_file, + static_cast<perms>(path_stat.st_mode) & fs::perms_mask); if (S_ISBLK(path_stat.st_mode)) - return fs::file_status(fs::block_file); + return fs::file_status(fs::block_file, + static_cast<perms>(path_stat.st_mode) & fs::perms_mask); if (S_ISCHR(path_stat.st_mode)) - return fs::file_status(fs::character_file); + return fs::file_status(fs::character_file, + static_cast<perms>(path_stat.st_mode) & fs::perms_mask); if (S_ISFIFO(path_stat.st_mode)) - return fs::file_status(fs::fifo_file); + return fs::file_status(fs::fifo_file, + static_cast<perms>(path_stat.st_mode) & fs::perms_mask); if (S_ISSOCK(path_stat.st_mode)) - return fs::file_status(fs::socket_file); + return fs::file_status(fs::socket_file, + static_cast<perms>(path_stat.st_mode) & fs::perms_mask); return fs::file_status(fs::type_unknown); @@ -1515,10 +1741,10 @@ namespace detail if (attr & FILE_ATTRIBUTE_REPARSE_POINT) return is_reparse_point_a_symlink(p) - ? file_status(symlink_file) - : file_status(reparse_file); + ? file_status(symlink_file, make_permissions(p, attr)) + : file_status(reparse_file, make_permissions(p, attr)); return (attr & FILE_ATTRIBUTE_DIRECTORY) - ? file_status(directory_file) - : file_status(regular_file); + ? file_status(directory_file, make_permissions(p, attr)) + : file_status(regular_file, make_permissions(p, attr)); # endif @@ -1661,5 +1887,5 @@ namespace path_traits } // namespace path_traits -} // namespace filesystem3 +} // namespace filesystem } // namespace boost @@ -1753,6 +1979,6 @@ namespace 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 ((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); @@ -1801,5 +2027,5 @@ namespace == INVALID_HANDLE_VALUE) { - handle = 0; + handle = 0; // signal eof return error_code( (::GetLastError() == ERROR_FILE_NOT_FOUND // Windows Mobile returns ERROR_NO_MORE_FILES; see ticket #3551 @@ -1809,10 +2035,26 @@ namespace target = data.cFileName; if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) - // reparse points are complex, so don't try to handle them here - { sf.type(fs::status_error); symlink_sf.type(fs::status_error); } - else if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { sf.type(fs::directory_file); symlink_sf.type(fs::directory_file); } + // reparse points are complex, so don't try to handle them here; instead just mark + // them as status_error which causes directory_entry caching to call status() + // and symlink_status() which do handle reparse points fully + { + sf.type(fs::status_error); + symlink_sf.type(fs::status_error); + } + else + { + 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); } + { + sf.type(fs::regular_file); + symlink_sf.type(fs::regular_file); + } + sf.permissions(make_permissions(data.cFileName, data.dwFileAttributes)); + symlink_sf.permissions(sf.permissions()); + } return error_code(); } @@ -1830,10 +2072,26 @@ namespace target = data.cFileName; if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) - // reparse points are complex, so don't try to handle them here - { sf.type(fs::status_error); symlink_sf.type(fs::status_error); } - else if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { sf.type(fs::directory_file); symlink_sf.type(fs::directory_file); } + // reparse points are complex, so don't try to handle them here; instead just mark + // them as status_error which causes directory_entry caching to call status() + // and symlink_status() which do handle reparse points fully + { + sf.type(fs::status_error); + symlink_sf.type(fs::status_error); + } + else + { + 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); } + { + sf.type(fs::regular_file); + symlink_sf.type(fs::regular_file); + } + sf.permissions(make_permissions(data.cFileName, data.dwFileAttributes)); + symlink_sf.permissions(sf.permissions()); + } return error_code(); } @@ -1852,5 +2110,5 @@ namespace namespace boost { -namespace filesystem3 +namespace filesystem { @@ -1890,5 +2148,6 @@ namespace detail { if (error(p.empty(), not_found_error_code, p, ec, - "boost::filesystem::directory_iterator::construct"))return; + "boost::filesystem::directory_iterator::construct")) + return; path::string_type filename; @@ -1908,14 +2167,14 @@ namespace detail } - if (it.m_imp->handle == 0)it.m_imp.reset(); // eof, so make end iterator + 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); + 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(); } + { it.increment(*ec); } } } @@ -1924,6 +2183,6 @@ namespace detail 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"); + BOOST_ASSERT_MSG(it.m_imp.get(), "attempt to increment end iterator"); + BOOST_ASSERT_MSG(it.m_imp->handle != 0, "internal program error"); path::string_type filename; @@ -1939,11 +2198,12 @@ namespace detail filename, file_stat, symlink_file_stat); - if (temp_ec) + if (temp_ec) // happens if filesystem is corrupt, such as on a damaged optical disc { + path error_path(it.m_imp->dir_entry.path().parent_path()); // fix ticket #5900 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_path, error_code(BOOST_ERRNO, system_category()))); ec->assign(BOOST_ERRNO, system_category()); @@ -1970,6 +2230,4 @@ namespace detail } } // namespace detail -} // namespace filesystem3 +} // namespace filesystem } // 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/src/path.cpp index cc30570..a3b3710 100644 --- a/3rdParty/Boost/src/libs/filesystem/v3/src/path.cpp +++ b/3rdParty/Boost/src/libs/filesystem/src/path.cpp @@ -8,10 +8,10 @@ // Library home page: http://www.boost.org/libs/filesystem +// Old standard library configurations, particularly MingGW, don't support wide strings. +// Report this with an explicit error message. #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. +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif // define BOOST_FILESYSTEM_SOURCE so that <boost/system/config.hpp> knows @@ -23,9 +23,13 @@ #endif -#include <boost/filesystem/v3/config.hpp> -#include <boost/filesystem/v3/path.hpp> +#include <boost/filesystem/config.hpp> +#include <boost/filesystem/path.hpp> #include <boost/scoped_array.hpp> #include <boost/system/error_code.hpp> #include <boost/assert.hpp> +//#include <boost/detail/lightweight_mutex.hpp> +// fails on VC++ static builds because the runtime does not permit use of locks in +// staticly initialized code, and VC++ 2010 (and probably other versions) statically +// initializes some instances of class path. #include <algorithm> #include <cstddef> @@ -36,5 +40,5 @@ # include "windows_file_codecvt.hpp" # include <windows.h> -#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) || defined(__FreeBSD__) # include <boost/filesystem/detail/utf8_codecvt_facet.hpp> #endif @@ -45,7 +49,7 @@ #endif -namespace fs = boost::filesystem3; +namespace fs = boost::filesystem; -using boost::filesystem3::path; +using boost::filesystem::path; using std::string; @@ -79,5 +83,4 @@ namespace const wchar_t separator = L'/'; - const wchar_t preferred_separator = L'\\'; const wchar_t* const separators = L"/\\"; const wchar_t* separator_string = L"/"; @@ -85,15 +88,19 @@ namespace const wchar_t colon = L':'; const wchar_t dot = L'.'; + const wchar_t questionmark = L'?'; const fs::path dot_path(L"."); const fs::path dot_dot_path(L".."); + inline bool is_letter(wchar_t c) + { + return (c >= L'a' && c <=L'z') || (c >= L'A' && c <=L'Z'); + } + # 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("."); @@ -106,10 +113,10 @@ namespace return c == separator # ifdef BOOST_WINDOWS_API - || c == preferred_separator + || c == path::preferred_separator # endif ; } - bool is_non_root_separator(const string_type& str, size_type pos); + bool is_root_separator(const string_type& str, size_type pos); // pos is position of the separator @@ -142,17 +149,52 @@ namespace namespace boost { -namespace filesystem3 +namespace filesystem { - path& path::operator/=(const path& p) { if (p.empty()) return *this; + if (this == &p) // self-append + { + path rhs(p); + if (!is_separator(rhs.m_pathname[0])) + m_append_separator_if_needed(); + m_pathname += rhs.m_pathname; + } + else + { if (!is_separator(*p.m_pathname.begin())) m_append_separator_if_needed(); m_pathname += p.m_pathname; + } return *this; } + path& path::operator/=(const value_type* ptr) + { + if (!*ptr) + return *this; + if (ptr >= m_pathname.data() + && ptr < m_pathname.data() + m_pathname.size()) // overlapping source + { + path rhs(ptr); + if (!is_separator(rhs.m_pathname[0])) + m_append_separator_if_needed(); + m_pathname += rhs.m_pathname; + } + else + { + if (!is_separator(*ptr)) + m_append_separator_if_needed(); + m_pathname += ptr; + } + return *this; + } + + int path::compare(const path& p) const BOOST_NOEXCEPT + { + return detail::lex_compare(begin(), end(), p.begin(), p.end()); + } + # ifdef BOOST_WINDOWS_API @@ -160,5 +202,5 @@ namespace filesystem3 { path tmp(*this); - tmp.make_preferred(); + std::replace(tmp.m_pathname.begin(), tmp.m_pathname.end(), L'\\', L'/'); return tmp.string(cvt); } @@ -167,5 +209,5 @@ namespace filesystem3 { path tmp(*this); - tmp.make_preferred(); + std::replace(tmp.m_pathname.begin(), tmp.m_pathname.end(), L'\\', L'/'); return tmp.wstring(); } @@ -208,5 +250,5 @@ namespace filesystem3 path & path::make_preferred() { - std::replace(m_pathname.begin(), m_pathname.end(), L'\\', L'/'); + std::replace(m_pathname.begin(), m_pathname.end(), L'/', L'\\'); return *this; } @@ -219,15 +261,16 @@ namespace filesystem3 } - path & path::replace_extension(const path & source) + path& path::replace_extension(const path& new_extension) { - // 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); + // erase existing extension, including the dot, if any + m_pathname.erase(m_pathname.size()-extension().m_pathname.size()); - // append source extension if any - pos = source.m_pathname.rfind(dot); - if (pos != string_type::npos) - m_pathname += source.c_str() + pos; + if (!new_extension.empty()) + { + // append new_extension, adding the dot if necessary + if (new_extension.m_pathname[0] != dot) + m_pathname.push_back(dot); + m_pathname.append(new_extension.m_pathname); + } return *this; @@ -319,5 +362,5 @@ namespace filesystem3 && pos && is_separator(m_pathname[pos]) - && is_non_root_separator(m_pathname, pos)) + && !is_root_separator(m_pathname, pos)) ? dot_path : path(m_pathname.c_str() + pos); @@ -411,5 +454,5 @@ namespace filesystem3 } -} // namespace filesystem3 +} // namespace filesystem } // namespace boost @@ -423,11 +466,11 @@ namespace { - // is_non_root_separator -------------------------------------------------// + // is_root_separator ---------------------------------------------------------------// - bool is_non_root_separator(const string_type & str, size_type pos) + bool is_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"); + BOOST_ASSERT_MSG(!str.empty() && is_separator(str[pos]), + "precondition violation"); // subsequent logic expects pos to be for leftmost slash of a set @@ -435,11 +478,19 @@ namespace --pos; - return pos != 0 - && (pos <= 2 || !is_separator(str[1]) - || str.find_first_of(separators, 2) != pos) + // "/" [...] + if (pos == 0) + return true; + # ifdef BOOST_WINDOWS_API - && (pos !=2 || str[1] != colon) + // "c:/" [...] + if (pos == 2 && is_letter(str[0]) && str[1] == colon) + return true; # endif - ; + + // "//" name "/" + if (pos < 3 || !is_separator(str[0]) || !is_separator(str[1])) + return false; + + return str.find_first_of(separators, 2) == pos; } @@ -463,5 +514,5 @@ namespace # ifdef BOOST_WINDOWS_API - if (pos == string_type::npos) + if (pos == string_type::npos && end_pos > 1) pos = str.find_last_of(colon, end_pos-2); # endif @@ -491,4 +542,17 @@ namespace && is_separator(path[1])) return string_type::npos; +# ifdef BOOST_WINDOWS_API + // case "\\?\" + if (size > 4 + && is_separator(path[0]) + && is_separator(path[1]) + && path[2] == questionmark + && is_separator(path[3])) + { + string_type::size_type pos(path.find_first_of(separators, 4)); + return pos < size ? pos : string_type::npos; + } +# endif + // case "//net {/}" if (size > 3 @@ -573,5 +637,30 @@ namespace } -} // unnammed namespace +} // unnamed namespace + + +namespace boost +{ +namespace filesystem +{ + namespace detail + { + BOOST_FILESYSTEM_DECL + int lex_compare(path::iterator first1, path::iterator last1, + path::iterator first2, path::iterator last2) + { + for (; first1 != last1 && first2 != last2;) + { + if (first1->native() < first2->native()) return -1; + if (first2->native() < first1->native()) return 1; + BOOST_ASSERT(first2->native() == first1->native()); + ++first1; + ++first2; + } + if (first1 == last1 && first2 == last2) + return 0; + return first1 == last1 ? -1 : 1; + } + } //--------------------------------------------------------------------------------------// @@ -581,9 +670,4 @@ namespace //--------------------------------------------------------------------------------------// -namespace boost -{ -namespace filesystem3 -{ - path::iterator path::begin() const { @@ -608,13 +692,15 @@ namespace filesystem3 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()"); + BOOST_ASSERT_MSG(it.m_pos < it.m_path_ptr->m_pathname.size(), + "path::basic_iterator increment past end()"); - // increment to position past current element + // increment to position past current element; if current element is implicit dot, + // this will cause it.m_pos to represent the end iterator it.m_pos += it.m_element.m_pathname.size(); - // if end reached, create end basic_iterator + // if the end is reached, we are done if (it.m_pos == it.m_path_ptr->m_pathname.size()) { - it.m_element.clear(); + it.m_element.clear(); // aids debugging, may release unneeded memory return; } @@ -637,9 +723,9 @@ namespace filesystem3 ) { - it.m_element.m_pathname = separator; + it.m_element.m_pathname = separator; // generic format; see docs return; } - // bypass separators + // skip separators until it.m_pos points to the start of the next element while (it.m_pos != it.m_path_ptr->m_pathname.size() && is_separator(it.m_path_ptr->m_pathname[it.m_pos])) @@ -648,5 +734,5 @@ namespace filesystem3 // 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)) + && !is_root_separator(it.m_path_ptr->m_pathname, it.m_pos-1)) { --it.m_pos; @@ -656,7 +742,8 @@ namespace filesystem3 } - // get next element + // get m_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(); + 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); } @@ -664,5 +751,5 @@ namespace filesystem3 void path::m_path_iterator_decrement(path::iterator & it) { - BOOST_ASSERT(it.m_pos && "path::iterator decrement past begin()"); + BOOST_ASSERT_MSG(it.m_pos, "path::iterator decrement past begin()"); size_type end_pos(it.m_pos); @@ -672,5 +759,5 @@ namespace filesystem3 && 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) + && !is_root_separator(it.m_path_ptr->m_pathname, it.m_pos-1) ) { @@ -693,17 +780,11 @@ namespace filesystem3 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 + if (it.m_element.m_pathname == preferred_separator_string) // needed for Windows, harmless on POSIX + it.m_element.m_pathname = separator_string; // generic format; see docs } -} // namespace filesystem3 +} // namespace filesystem } // namespace boost -//--------------------------------------------------------------------------------------// -// // -// detail helpers // -// // -//--------------------------------------------------------------------------------------// - namespace { @@ -713,24 +794,37 @@ namespace //------------------------------------------------------------------------------------// - // 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.) + // Prior versions of these locale and codecvt implementations tried to take advantage + // of static initialization where possible, kept a local copy of the current codecvt + // facet (to avoid codecvt() having to call use_facet()), and was not multi-threading + // safe (again for efficiency). + // + // This was error prone, and required different implementation techniques depending + // on the compiler and also whether static or dynamic linking was used. Furthermore, + // users could not easily provide their multi-threading safe wrappers because the + // path interface requires the implementation itself to call codecvt() to obtain the + // default facet, and the initialization of the static within path_locale() could race. + // + // The code below is portable to all platforms, is much simpler, and hopefully will be + // much more robust. Timing tests (on Windows, using a Visual C++ release build) + // indicated the current code is roughly 9% slower than the previous code, and that + // seems a small price to pay for better code that is easier to use. - std::locale default_locale() + //boost::detail::lightweight_mutex locale_mutex; + + inline std::locale default_locale() { -# ifdef BOOST_WINDOWS_API +# if defined(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__) + return std::locale(global_loc, new windows_file_codecvt); +# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) || defined(__FreeBSD__) // "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 + // and nothing else." See + // 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 + // before trying to open/create a file." See + // 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 @@ -738,56 +832,57 @@ namespace // 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 + // cases." See + // 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": + std::locale global_loc = std::locale(); + return std::locale(global_loc, new boost::filesystem::detail::utf8_codecvt_facet); +# else // Other POSIX + // ISO C calls std::locale("") "the locale-specific native environment", and this + // locale is the default for many POSIX-based operating systems such as Linux. return std::locale(""); - # endif } - std::locale & path_locale() + inline std::locale& path_locale() + // std::locale("") construction, needed on non-Apple POSIX systems, can throw + // (if environmental variables LC_MESSAGES or LANG are wrong, for example), so + // path_locale() provides lazy initialization via a local static to ensure that any + // exceptions occur after main() starts and so can be caught. Furthermore, + // path_locale() is only called if path::codecvt() or path::imbue() are themselves + // actually called, ensuring that an exception will only be thrown if std::locale("") + // is really needed. { static std::locale loc(default_locale()); return loc; } - } // unnamed namespace //--------------------------------------------------------------------------------------// -// path::imbue implementation // +// path::codecvt() and path::imbue() implementation // //--------------------------------------------------------------------------------------// namespace boost { -namespace filesystem3 +namespace filesystem { + // See comments above - const path::codecvt_type *& - path::wchar_t_codecvt_facet() + const path::codecvt_type& path::codecvt() { - 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; + BOOST_ASSERT_MSG(&path_locale(), "boost::filesystem::path locale initialization error"); +// boost::detail::lightweight_mutex::scoped_lock lock(locale_mutex); + return std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(path_locale()); } std::locale path::imbue(const std::locale& loc) { +// boost::detail::lightweight_mutex::scoped_lock lock(locale_mutex); 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 filesystem } // 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/src/path_traits.cpp index 6606437..06ac798 100644 --- a/3rdParty/Boost/src/libs/filesystem/v3/src/path_traits.cpp +++ b/3rdParty/Boost/src/libs/filesystem/src/path_traits.cpp @@ -10,11 +10,4 @@ //--------------------------------------------------------------------------------------// -#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) @@ -25,6 +18,6 @@ #endif -#include <boost/filesystem/v3/config.hpp> -#include <boost/filesystem/v3/path_traits.hpp> +#include <boost/filesystem/config.hpp> +#include <boost/filesystem/path_traits.hpp> #include <boost/system/system_error.hpp> #include <boost/scoped_array.hpp> @@ -33,6 +26,6 @@ #include <cwchar> // for wcslen -namespace pt = boost::filesystem3::path_traits; -namespace fs = boost::filesystem3; +namespace pt = boost::filesystem::path_traits; +namespace fs = boost::filesystem; namespace bs = boost::system; @@ -131,5 +124,5 @@ namespace { //--------------------------------------------------------------------------------------// -namespace boost { namespace filesystem3 { namespace path_traits { +namespace boost { namespace filesystem { namespace path_traits { //--------------------------------------------------------------------------------------// @@ -205,5 +198,3 @@ namespace boost { namespace filesystem3 { namespace path_traits { } } -}}} // namespace boost::filesystem3::path_traits - -#endif // no wide character support +}}} // namespace boost::filesystem::path_traits diff --git a/3rdParty/Boost/src/libs/filesystem/v3/src/portability.cpp b/3rdParty/Boost/src/libs/filesystem/src/portability.cpp index 31e0176..b1a1352 100644 --- a/3rdParty/Boost/src/libs/filesystem/v3/src/portability.cpp +++ b/3rdParty/Boost/src/libs/filesystem/src/portability.cpp @@ -10,11 +10,4 @@ //--------------------------------------------------------------------------------------// -#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) @@ -25,8 +18,8 @@ #endif -#include <boost/filesystem/v3/config.hpp> -#include <boost/filesystem/v3/path.hpp> +#include <boost/filesystem/config.hpp> +#include <boost/filesystem/path.hpp> -namespace fs = boost::filesystem3; +namespace fs = boost::filesystem; #include <cstring> // SGI MIPSpro compilers need this @@ -55,5 +48,5 @@ namespace namespace boost { - namespace filesystem3 + namespace filesystem { @@ -123,6 +116,4 @@ namespace boost } - } // namespace filesystem3 + } // namespace filesystem } // 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/src/unique_path.cpp index 1569b32..c25c315 100644 --- a/3rdParty/Boost/src/libs/filesystem/v3/src/unique_path.cpp +++ b/3rdParty/Boost/src/libs/filesystem/src/unique_path.cpp @@ -1,3 +1,3 @@ -// filesystem system_crypt_random.cpp ------------------------------------------------// +// filesystem unique_path.cpp --------------------------------------------------------// // Copyright Beman Dawes 2010 @@ -10,11 +10,4 @@ //--------------------------------------------------------------------------------------// -#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) @@ -25,5 +18,5 @@ #endif -#include <boost/filesystem/v3/operations.hpp> +#include <boost/filesystem/operations.hpp> # ifdef BOOST_POSIX_API @@ -113,5 +106,5 @@ void system_crypt_random(void* buf, std::size_t len, boost::system::error_code* } // unnamed namespace -namespace boost { namespace filesystem3 { namespace detail { +namespace boost { namespace filesystem { namespace detail { BOOST_FILESYSTEM_DECL @@ -148,4 +141,2 @@ path unique_path(const path& model, system::error_code* ec) }}} - -#endif // no wide character support diff --git a/3rdParty/Boost/src/libs/filesystem/v3/src/windows_file_codecvt.cpp b/3rdParty/Boost/src/libs/filesystem/src/windows_file_codecvt.cpp index ae9f9f2..998db60 100644 --- a/3rdParty/Boost/src/libs/filesystem/v3/src/windows_file_codecvt.cpp +++ b/3rdParty/Boost/src/libs/filesystem/src/windows_file_codecvt.cpp @@ -10,11 +10,4 @@ //--------------------------------------------------------------------------------------// -#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) @@ -25,5 +18,5 @@ #endif -#include <boost/filesystem/v3/config.hpp> +#include <boost/filesystem/config.hpp> #include <cwchar> // for mbstate_t @@ -44,5 +37,5 @@ wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const { - UINT codepage = AreFileApisANSI() ? CP_THREAD_ACP : CP_OEMCP; + UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; int count; @@ -64,5 +57,5 @@ char* to, char* to_end, char* & to_next) const { - UINT codepage = AreFileApisANSI() ? CP_THREAD_ACP : CP_OEMCP; + UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; int count; @@ -81,3 +74,2 @@ # 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/src/windows_file_codecvt.hpp index d845d37..52deab1 100644 --- a/3rdParty/Boost/src/libs/filesystem/v3/src/windows_file_codecvt.hpp +++ b/3rdParty/Boost/src/libs/filesystem/src/windows_file_codecvt.hpp @@ -11,5 +11,5 @@ #define BOOST_FILESYSTEM3_WIN_FILE_CODECVT_HPP -#include <boost/filesystem/v3/config.hpp> +#include <boost/filesystem/config.hpp> #include <locale> diff --git a/3rdParty/Boost/src/libs/filesystem/v2/src/v2_operations.cpp b/3rdParty/Boost/src/libs/filesystem/v2/src/v2_operations.cpp deleted file mode 100644 index f29153c..0000000 --- a/3rdParty/Boost/src/libs/filesystem/v2/src/v2_operations.cpp +++ /dev/null @@ -1,1372 +0,0 @@ -// operations.cpp ----------------------------------------------------------// - -// Copyright 2002-2005 Beman Dawes -// Copyright 2001 Dietmar Kuehl -// 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 - -//----------------------------------------------------------------------------// - -// 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 - -#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, -#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. - -// for some compilers (CodeWarrior, for example), windows.h -// is getting included by some other boost header, so do this early: -#if !defined(_WIN32_WINNT) -#define _WIN32_WINNT 0x0500 // Default to Windows 2K or later -#endif - - -#include <boost/filesystem/v2/operations.hpp> -#include <boost/scoped_array.hpp> -#include <boost/assert.hpp> -#include <boost/detail/workaround.hpp> -#include <cstdlib> // for malloc, free - -namespace fs = boost::filesystem2; -using boost::system::error_code; -using boost::system::system_category; - -# if defined(BOOST_WINDOWS_API) -# include <windows.h> -# include <ctime> // for time_t - -# else // 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" -# endif - -// 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 */ \ - && !(defined(__SUNPRO_CC) && !defined(__sun))) // _DIRENT_HAVE_D_TYPE wrong for Sun compiler on Linux -# 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 <iostream> // for debugging only; comment out when not in use - -#ifdef BOOST_NO_STDC_NAMESPACE -namespace std { using ::strcmp; using ::remove; using ::rename; } -#endif - -// helpers -----------------------------------------------------------------// - -namespace -{ - const error_code ok; - - bool is_empty_directory( const std::string & dir_path ) - { - static const fs::directory_iterator end_itr; - return fs::directory_iterator(fs::path(dir_path)) == end_itr; - } - -#ifdef BOOST_WINDOWS_API - -// For Windows, the xxxA form of various function names is used to avoid -// inadvertently getting wide forms of the functions. (The undecorated -// forms are actually macros, so can misfire if the user has various -// other macros defined. There was a bug report of this happening.) - - inline DWORD get_file_attributes( const char * ph ) - { return ::GetFileAttributesA( ph ); } - -# ifndef BOOST_FILESYSTEM2_NARROW_ONLY - - inline DWORD get_file_attributes( const wchar_t * ph ) - { return ::GetFileAttributesW( ph ); } - - bool is_empty_directory( const std::wstring & dir_path ) - { - static const fs::wdirectory_iterator wend_itr; - return fs::wdirectory_iterator(fs::wpath(dir_path)) == wend_itr; - } - - inline BOOL get_file_attributes_ex( const wchar_t * ph, - WIN32_FILE_ATTRIBUTE_DATA & fad ) - { return ::GetFileAttributesExW( ph, ::GetFileExInfoStandard, &fad ); } - - HANDLE create_file( const wchar_t * ph, DWORD dwDesiredAccess, - DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, - HANDLE hTemplateFile ) - { - return ::CreateFileW( ph, dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, - hTemplateFile ); - } - - inline DWORD get_current_directory( DWORD sz, wchar_t * buf ) - { return ::GetCurrentDirectoryW( sz, buf ); } - - inline bool set_current_directory( const wchar_t * buf ) - { return ::SetCurrentDirectoryW( buf ) != 0 ; } - - 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; } - - inline std::size_t get_full_path_name( - const std::wstring & ph, std::size_t len, wchar_t * buf, wchar_t ** p ) - { - return static_cast<std::size_t>( - ::GetFullPathNameW( ph.c_str(), - static_cast<DWORD>(len), buf, p )); - } - - inline bool remove_directory( const std::wstring & ph ) - { return ::RemoveDirectoryW( ph.c_str() ) != 0; } - - inline bool delete_file( const std::wstring & ph ) - { return ::DeleteFileW( ph.c_str() ) != 0; } - - inline bool create_directory( const std::wstring & dir ) - { return ::CreateDirectoryW( dir.c_str(), 0 ) != 0; } - -#if _WIN32_WINNT >= 0x500 - inline bool create_hard_link( const std::wstring & to_ph, - const std::wstring & from_ph ) - { return ::CreateHardLinkW( from_ph.c_str(), to_ph.c_str(), 0 ) != 0; } -#endif - -# endif // ifndef BOOST_FILESYSTEM2_NARROW_ONLY - - template< class String > - fs::file_status status_template( const String & ph, error_code & ec ) - { - DWORD attr( get_file_attributes( ph.c_str() ) ); - if ( attr == 0xFFFFFFFF ) - { - 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 - { - ec = ok; // these are not considered errors; - // the status is considered not found - return fs::file_status( fs::file_not_found ); - } - else if ((ec.value() == ERROR_SHARING_VIOLATION)) - { - ec = ok; // these are not considered errors; - // the file exists but the type is not known - return fs::file_status( fs::type_unknown ); - } - return fs::file_status( fs::status_unknown ); - } - ec = ok;; - return (attr & FILE_ATTRIBUTE_DIRECTORY) - ? fs::file_status( fs::directory_file ) - : fs::file_status( fs::regular_file ); - } - - BOOL get_file_attributes_ex( const char * ph, - WIN32_FILE_ATTRIBUTE_DATA & fad ) - { return ::GetFileAttributesExA( ph, ::GetFileExInfoStandard, &fad ); } - - template< class String > - 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( ok, - ( fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) - ? is_empty_directory( ph ) - :( !fad.nFileSizeHigh && !fad.nFileSizeLow ) ); - } - - HANDLE create_file( const char * ph, DWORD dwDesiredAccess, - DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, - HANDLE hTemplateFile ) - { - return ::CreateFileA( ph, dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, - hTemplateFile ); - } - - // 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); - } - }; - - template< class String > - boost::filesystem2::detail::query_pair - equivalent_template( const String & ph1, const String & ph2 ) - { - // 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. - handle_wrapper p1( - create_file( - ph1.c_str(), - 0, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - 0 ) ); - int error1(0); // save error code in case we have to throw - if ( p1.handle == INVALID_HANDLE_VALUE ) - error1 = ::GetLastError(); - handle_wrapper p2( - create_file( - ph2.c_str(), - 0, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - 0 ) ); - if ( p1.handle == INVALID_HANDLE_VALUE - || p2.handle == INVALID_HANDLE_VALUE ) - { - if ( p1.handle != INVALID_HANDLE_VALUE - || p2.handle != INVALID_HANDLE_VALUE ) - { return std::make_pair( ok, false ); } - BOOST_ASSERT( p1.handle == INVALID_HANDLE_VALUE - && p2.handle == INVALID_HANDLE_VALUE ); - { 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 ); } - if ( !::GetFileInformationByHandle( p2.handle, &info2 ) ) - { 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. - return std::make_pair( ok, - 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 ); - } - - template< class String > - 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 ); - if ( (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) !=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)) - + fad.nFileSizeLow ); - } - - inline bool get_free_disk_space( const std::string & ph, - PULARGE_INTEGER avail, PULARGE_INTEGER total, PULARGE_INTEGER free ) - { return ::GetDiskFreeSpaceExA( ph.c_str(), avail, total, free ) != 0; } - - template< class String > - boost::filesystem2::detail::space_pair - space_template( String & ph ) - { - ULARGE_INTEGER avail, total, free; - boost::filesystem2::detail::space_pair result; - if ( get_free_disk_space( ph, &avail, &total, &free ) ) - { - result.first = ok; - result.second.capacity - = (static_cast<boost::uintmax_t>(total.HighPart) << 32) - + total.LowPart; - result.second.free - = (static_cast<boost::uintmax_t>(free.HighPart) << 32) - + free.LowPart; - result.second.available - = (static_cast<boost::uintmax_t>(avail.HighPart) << 32) - + avail.LowPart; - } - else - { - result.first = error_code( ::GetLastError(), system_category() ); - result.second.capacity = result.second.free - = result.second.available = 0; - } - return result; - } - - inline DWORD get_current_directory( DWORD sz, char * buf ) - { return ::GetCurrentDirectoryA( sz, buf ); } - - template< class String > - error_code - get_current_path_template( String & ph ) - { - DWORD sz; - if ( (sz = get_current_directory( 0, - static_cast<typename String::value_type*>(0) )) == 0 ) - { sz = 1; } - 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() ); - ph = buf.get(); - return ok; - } - - inline bool set_current_directory( const char * buf ) - { return ::SetCurrentDirectoryA( buf ) != 0; } - - template< class String > - error_code - set_current_path_template( const String & ph ) - { - return error_code( set_current_directory( ph.c_str() ) - ? 0 : ::GetLastError(), system_category() ); - } - - inline std::size_t get_full_path_name( - const std::string & ph, std::size_t len, char * buf, char ** p ) - { - return static_cast<std::size_t>( - ::GetFullPathNameA( ph.c_str(), - static_cast<DWORD>(len), buf, p )); - } - - const std::size_t buf_size( 128 ); - - template<class String> - error_code - get_full_path_name_template( const String & ph, String & target ) - { - typename String::value_type buf[buf_size]; - 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 > 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() ); - big_buf[len] = '\0'; - target = big_buf.get(); - return ok; - } - buf[len] = '\0'; - target = buf; - return ok; - } - - template<class String> - error_code - get_file_write_time( const String & ph, FILETIME & last_write_time ) - { - handle_wrapper hw( - create_file( ph.c_str(), 0, - 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( ::GetFileTime( hw.handle, 0, 0, &last_write_time ) != 0 - ? 0 : ::GetLastError(), system_category() ); - } - - template<class String> - error_code - set_file_write_time( const String & ph, const FILETIME & last_write_time ) - { - handle_wrapper hw( - create_file( ph.c_str(), FILE_WRITE_ATTRIBUTES, - 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( ::SetFileTime( hw.handle, 0, 0, &last_write_time ) != 0 - ? 0 : ::GetLastError(), system_category() ); - } - - // 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 ); - } - - template<class String> - boost::filesystem2::detail::time_pair - last_write_time_template( const String & ph ) - { - FILETIME lwt; - error_code ec( - get_file_write_time( ph, lwt ) ); - return std::make_pair( ec, to_time_t( lwt ) ); - } - - template<class String> - error_code - last_write_time_template( const String & ph, const std::time_t new_time ) - { - FILETIME lwt; - to_FILETIME( new_time, lwt ); - return set_file_write_time( ph, lwt ); - } - - bool remove_directory( const std::string & ph ) - { return ::RemoveDirectoryA( ph.c_str() ) != 0; } - - bool delete_file( const std::string & ph ) - { return ::DeleteFileA( ph.c_str() ) != 0; } - - template<class String> - error_code - remove_template( const String & ph ) - { - // TODO: test this code in the presence of Vista symlinks, - // including dangling, self-referal, and cyclic symlinks - error_code ec; - fs::file_status sf( fs::detail::status_api( ph, ec ) ); - if ( ec ) - return ec; - if ( sf.type() == fs::file_not_found ) - return ok; - if ( fs::is_directory( sf ) ) - { - if ( !remove_directory( ph ) ) - return error_code(::GetLastError(), system_category()); - } - else - { - if ( !delete_file( ph ) ) return error_code(::GetLastError(), system_category()); - } - return ok; - } - - inline bool create_directory( const std::string & dir ) - { return ::CreateDirectoryA( dir.c_str(), 0 ) != 0; } - - template<class String> - 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() ); - // 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 ) ) ) - return std::make_pair( ok, false ); - return std::make_pair( error, false ); - } - -#if _WIN32_WINNT >= 0x500 - inline bool create_hard_link( const std::string & to_ph, - const std::string & from_ph ) - { return ::CreateHardLinkA( from_ph.c_str(), to_ph.c_str(), 0 ) != 0; } -#endif - -#if _WIN32_WINNT >= 0x500 - template<class String> - error_code - create_hard_link_template( const String & to_ph, - const String & from_ph ) - { - return error_code( create_hard_link( to_ph.c_str(), from_ph.c_str() ) - ? 0 : ::GetLastError(), system_category() ); - } -#endif - -#else // BOOST_POSIX_API - - int posix_remove( const char * p ) - { -# if defined(__QNXNTO__) || (defined(__MSL__) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))) - // Some Metrowerks C library versions fail on directories because of a - // known Metrowerks coding error in ::remove. Workaround is to call - // rmdir() or unlink() as indicated. - // Same bug also reported for QNX, with the same fix. - int err = ::unlink( p ); - if ( err == 0 || errno != EPERM ) - return err; - return ::rmdir( p ); -# else - return std::remove( p ); -# endif - } - -#endif -} // unnamed namespace - -namespace boost -{ - namespace filesystem2 - { - namespace detail - { - BOOST_FILESYSTEM_DECL system::error_code throws; - -// free functions ----------------------------------------------------------// - - BOOST_FILESYSTEM_DECL error_code not_found_error() - { -# ifdef BOOST_WINDOWS_API - return error_code(ERROR_PATH_NOT_FOUND, system_category()); -# else - return error_code(ENOENT, system_category()); -# endif - } - - 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 - } - -# ifdef BOOST_WINDOWS_API - - BOOST_FILESYSTEM_DECL fs::file_status - status_api( const std::string & ph, error_code & ec ) - { return status_template( ph, ec ); } - -# ifndef BOOST_FILESYSTEM2_NARROW_ONLY - - BOOST_FILESYSTEM_DECL fs::file_status - status_api( const std::wstring & ph, error_code & ec ) - { return status_template( ph, ec ); } - - BOOST_FILESYSTEM_DECL bool symbolic_link_exists_api( const std::wstring & ) - { return false; } - - BOOST_FILESYSTEM_DECL - fs::detail::query_pair is_empty_api( const std::wstring & ph ) - { return is_empty_template( ph ); } - - BOOST_FILESYSTEM_DECL - fs::detail::query_pair - equivalent_api( const std::wstring & ph1, const std::wstring & ph2 ) - { return equivalent_template( ph1, ph2 ); } - - BOOST_FILESYSTEM_DECL - fs::detail::uintmax_pair file_size_api( const std::wstring & ph ) - { return file_size_template( ph ); } - - BOOST_FILESYSTEM_DECL - fs::detail::space_pair space_api( const std::wstring & ph ) - { return space_template( ph ); } - - BOOST_FILESYSTEM_DECL - error_code - get_current_path_api( std::wstring & ph ) - { return get_current_path_template( ph ); } - - BOOST_FILESYSTEM_DECL - error_code - set_current_path_api( const std::wstring & ph ) - { return set_current_path_template( ph ); } - - BOOST_FILESYSTEM_DECL error_code - get_full_path_name_api( const std::wstring & ph, std::wstring & target ) - { return get_full_path_name_template( ph, target ); } - - BOOST_FILESYSTEM_DECL time_pair - last_write_time_api( const std::wstring & ph ) - { return last_write_time_template( ph ); } - - BOOST_FILESYSTEM_DECL error_code - last_write_time_api( const std::wstring & ph, std::time_t new_value ) - { return last_write_time_template( ph, new_value ); } - - BOOST_FILESYSTEM_DECL fs::detail::query_pair - create_directory_api( const std::wstring & ph ) - { return create_directory_template( ph ); } - -#if _WIN32_WINNT >= 0x500 - BOOST_FILESYSTEM_DECL error_code - create_hard_link_api( const std::wstring & to_ph, - const std::wstring & from_ph ) - { return create_hard_link_template( to_ph, from_ph ); } -#endif - - 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() ); } - - BOOST_FILESYSTEM_DECL error_code - remove_api( const std::wstring & ph ) { return remove_template( ph ); } - - BOOST_FILESYSTEM_DECL error_code - rename_api( const std::wstring & from, const std::wstring & to ) - { - return error_code( ::MoveFileW( from.c_str(), to.c_str() ) - ? 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() ); - } - - BOOST_FILESYSTEM_DECL bool create_file_api( const std::wstring & ph, - std::ios_base::openmode mode ) // true if succeeds - { - DWORD access( - ((mode & std::ios_base::in) == 0 ? 0 : GENERIC_READ) - | ((mode & std::ios_base::out) == 0 ? 0 : GENERIC_WRITE) ); - - DWORD disposition(0); // see 27.8.1.3 Table 92 - if ( (mode&~std::ios_base::binary) - == (std::ios_base::out|std::ios_base::app) ) - disposition = OPEN_ALWAYS; - else if ( (mode&~(std::ios_base::binary|std::ios_base::out)) - == std::ios_base::in ) disposition = OPEN_EXISTING; - else if ( ((mode&~(std::ios_base::binary|std::ios_base::trunc)) - == std::ios_base::out ) - || ((mode&~std::ios_base::binary) - == (std::ios_base::in|std::ios_base::out|std::ios_base::trunc)) ) - disposition = CREATE_ALWAYS; - else BOOST_ASSERT( 0 && "invalid mode argument" ); - - HANDLE handle ( ::CreateFileW( ph.c_str(), access, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, - disposition, (mode &std::ios_base::out) != 0 - ? FILE_ATTRIBUTE_ARCHIVE : FILE_ATTRIBUTE_NORMAL, 0 ) ); - if ( handle == INVALID_HANDLE_VALUE ) return false; - ::CloseHandle( handle ); - return true; - } - - BOOST_FILESYSTEM_DECL std::string narrow_path_api( - const std::wstring & ph ) // return is empty if fails - { - std::string narrow_short_form; - std::wstring short_form; - for ( DWORD buf_sz( static_cast<DWORD>( ph.size()+1 ));; ) - { - boost::scoped_array<wchar_t> buf( new wchar_t[buf_sz] ); - DWORD sz( ::GetShortPathNameW( ph.c_str(), buf.get(), buf_sz ) ); - if ( sz == 0 ) return narrow_short_form; - if ( sz <= buf_sz ) - { - short_form += buf.get(); - break; - } - buf_sz = sz + 1; - } - // contributed by Takeshi Mouri: - int narrow_sz( ::WideCharToMultiByte( CP_ACP, 0, - short_form.c_str(), static_cast<int>(short_form.size()), 0, 0, 0, 0 ) ); - boost::scoped_array<char> narrow_buf( new char[narrow_sz] ); - ::WideCharToMultiByte( CP_ACP, 0, - short_form.c_str(), static_cast<int>(short_form.size()), - narrow_buf.get(), narrow_sz, 0, 0 ); - narrow_short_form.assign(narrow_buf.get(), narrow_sz); - - return narrow_short_form; - } - - BOOST_FILESYSTEM_DECL error_code - dir_itr_first( void *& handle, const std::wstring & dir, - std::wstring & target, file_status & sf, file_status & symlink_sf ) - { - // use a form of search Sebastian Martel reports will work with Win98 - std::wstring dirpath( dir ); - dirpath += (dirpath.empty() - || 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 - ? 0 : ::GetLastError(), system_category() ); - } - target = data.cFileName; - if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) - { sf.type( directory_file ); symlink_sf.type( directory_file ); } - else { sf.type( regular_file ); symlink_sf.type( regular_file ); } - return ok; - } - - BOOST_FILESYSTEM_DECL error_code - dir_itr_increment( void *& handle, std::wstring & target, - file_status & sf, file_status & symlink_sf ) - { - WIN32_FIND_DATAW data; - if ( ::FindNextFileW( handle, &data ) == 0 ) // fails - { - int error = ::GetLastError(); - 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( directory_file ); symlink_sf.type( directory_file ); } - else { sf.type( regular_file ); symlink_sf.type( regular_file ); } - return ok; - } - -# endif // ifndef BOOST_FILESYSTEM2_NARROW_ONLY - - // suggested by Walter Landry - BOOST_FILESYSTEM_DECL bool symbolic_link_exists_api( const std::string & ) - { return false; } - - BOOST_FILESYSTEM_DECL - fs::detail::query_pair is_empty_api( const std::string & ph ) - { return is_empty_template( ph ); } - - BOOST_FILESYSTEM_DECL - fs::detail::query_pair - equivalent_api( const std::string & ph1, const std::string & ph2 ) - { return equivalent_template( ph1, ph2 ); } - - BOOST_FILESYSTEM_DECL - fs::detail::uintmax_pair file_size_api( const std::string & ph ) - { return file_size_template( ph ); } - - BOOST_FILESYSTEM_DECL - fs::detail::space_pair space_api( const std::string & ph ) - { return space_template( ph ); } - - BOOST_FILESYSTEM_DECL - error_code - get_current_path_api( std::string & ph ) - { return get_current_path_template( ph ); } - - BOOST_FILESYSTEM_DECL - error_code - set_current_path_api( const std::string & ph ) - { return set_current_path_template( ph ); } - - BOOST_FILESYSTEM_DECL error_code - get_full_path_name_api( const std::string & ph, std::string & target ) - { return get_full_path_name_template( ph, target ); } - - BOOST_FILESYSTEM_DECL time_pair - last_write_time_api( const std::string & ph ) - { return last_write_time_template( ph ); } - - BOOST_FILESYSTEM_DECL error_code - last_write_time_api( const std::string & ph, std::time_t new_value ) - { return last_write_time_template( ph, new_value ); } - - BOOST_FILESYSTEM_DECL fs::detail::query_pair - create_directory_api( const std::string & ph ) - { return create_directory_template( ph ); } - -#if _WIN32_WINNT >= 0x500 - BOOST_FILESYSTEM_DECL error_code - create_hard_link_api( const std::string & to_ph, - const std::string & from_ph ) - { - return create_hard_link_template( to_ph, from_ph ); - } -#endif - - 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() ); } - - BOOST_FILESYSTEM_DECL error_code - remove_api( const std::string & ph ) { return remove_template( ph ); } - - BOOST_FILESYSTEM_DECL error_code - rename_api( const std::string & from, const std::string & to ) - { - return error_code( ::MoveFileA( from.c_str(), to.c_str() ) - ? 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() ); - } - - BOOST_FILESYSTEM_DECL error_code - dir_itr_first( void *& handle, const std::string & dir, - std::string & target, file_status & sf, 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 - std::string dirpath( dir ); - dirpath += (dirpath.empty() - || (dirpath[dirpath.size()-1] != '\\' - && dirpath[dirpath.size()-1] != ':')) ? "\\*" : "*"; - - WIN32_FIND_DATAA data; - if ( (handle = ::FindFirstFileA( 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( directory_file ); symlink_sf.type( directory_file ); } - else { sf.type( regular_file ); symlink_sf.type( regular_file ); } - return ok; - } - - BOOST_FILESYSTEM_DECL error_code - dir_itr_close( void *& handle ) - { - if ( handle != 0 ) - { - bool ok = ::FindClose( handle ) != 0; - handle = 0; - return error_code( ok ? 0 : ::GetLastError(), system_category() ); - } - return ok; - } - - BOOST_FILESYSTEM_DECL error_code - dir_itr_increment( void *& handle, std::string & target, - file_status & sf, file_status & symlink_sf ) - { - WIN32_FIND_DATAA data; - if ( ::FindNextFileA( handle, &data ) == 0 ) // fails - { - int error = ::GetLastError(); - 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( directory_file ); symlink_sf.type( directory_file ); } - else { sf.type( regular_file ); symlink_sf.type( regular_file ); } - return ok; - } - -# else // BOOST_POSIX_API - - BOOST_FILESYSTEM_DECL fs::file_status - status_api( const std::string & ph, error_code & ec ) - { - struct stat path_stat; - if ( ::stat( ph.c_str(), &path_stat ) != 0 ) - { - if ( errno == ENOENT || errno == ENOTDIR ) - { - ec = ok; - return fs::file_status( fs::file_not_found ); - } - ec = error_code( errno, system_category() ); - return fs::file_status( fs::status_unknown ); - } - ec = ok; - 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 ); - } - - BOOST_FILESYSTEM_DECL fs::file_status - symlink_status_api( const std::string & ph, error_code & ec ) - { - struct stat path_stat; - if ( ::lstat( ph.c_str(), &path_stat ) != 0 ) - { - if ( errno == ENOENT || errno == ENOTDIR ) - { - ec = ok; - return fs::file_status( fs::file_not_found ); - } - ec = error_code( errno, system_category() ); - return fs::file_status( fs::status_unknown ); - } - ec = ok; - 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 ); - } - - // suggested by Walter Landry - BOOST_FILESYSTEM_DECL bool - symbolic_link_exists_api( const std::string & ph ) - { - struct stat path_stat; - return ::lstat( ph.c_str(), &path_stat ) == 0 - && S_ISLNK( path_stat.st_mode ); - } - - BOOST_FILESYSTEM_DECL query_pair - is_empty_api( const std::string & ph ) - { - 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( ok, S_ISDIR( path_stat.st_mode ) - ? is_empty_directory( ph ) - : path_stat.st_size == 0 ); - } - - BOOST_FILESYSTEM_DECL query_pair - equivalent_api( const std::string & ph1, const std::string & ph2 ) - { - struct stat s2; - int e2( ::stat( ph2.c_str(), &s2 ) ); - 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 ); - // at this point, both stats are known to be valid - return std::make_pair( ok, - 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 ); - } - - BOOST_FILESYSTEM_DECL uintmax_pair - file_size_api( const std::string & ph ) - { - struct stat path_stat; - if ( ::stat( ph.c_str(), &path_stat ) != 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( ok, - static_cast<boost::uintmax_t>(path_stat.st_size) ); - } - - BOOST_FILESYSTEM_DECL space_pair - space_api( const std::string & ph ) - { - struct BOOST_STATVFS vfs; - space_pair result; - if ( ::BOOST_STATVFS( ph.c_str(), &vfs ) != 0 ) - { - result.first = error_code( errno, system_category() ); - result.second.capacity = result.second.free - = result.second.available = 0; - } - else - { - result.first = ok; - result.second.capacity - = static_cast<boost::uintmax_t>(vfs.f_blocks) * BOOST_STATVFS_F_FRSIZE; - result.second.free - = static_cast<boost::uintmax_t>(vfs.f_bfree) * BOOST_STATVFS_F_FRSIZE; - result.second.available - = static_cast<boost::uintmax_t>(vfs.f_bavail) * BOOST_STATVFS_F_FRSIZE; - } - return result; - } - - BOOST_FILESYSTEM_DECL time_pair - last_write_time_api( const std::string & ph ) - { - 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( ok, path_stat.st_mtime ); - } - - BOOST_FILESYSTEM_DECL error_code - last_write_time_api( const std::string & ph, std::time_t new_value ) - { - struct stat path_stat; - if ( ::stat( ph.c_str(), &path_stat ) != 0 ) - 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() ); - } - - BOOST_FILESYSTEM_DECL error_code - get_current_path_api( std::string & ph ) - { - for ( long path_max = 32;; 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 ( 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 - ) return error_code( errno, system_category() ); - } - else - { - ph = buf.get(); - break; - } - } - return ok; - } - - BOOST_FILESYSTEM_DECL error_code - set_current_path_api( const std::string & ph ) - { - return error_code( ::chdir( ph.c_str() ) - ? errno : 0, system_category() ); - } - - BOOST_FILESYSTEM_DECL fs::detail::query_pair - create_directory_api( const std::string & ph ) - { - if ( ::mkdir( ph.c_str(), S_IRWXU|S_IRWXG|S_IRWXO ) == 0 ) - { return std::make_pair( ok, true ); } - int ec=errno; - 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( ok, false ); - } - - BOOST_FILESYSTEM_DECL error_code - create_hard_link_api( const std::string & to_ph, - const std::string & from_ph ) - { - return error_code( ::link( to_ph.c_str(), from_ph.c_str() ) == 0 - ? 0 : errno, system_category() ); - } - - BOOST_FILESYSTEM_DECL error_code - create_symlink_api( const std::string & to_ph, - const std::string & from_ph ) - { - return error_code( ::symlink( to_ph.c_str(), from_ph.c_str() ) == 0 - ? 0 : errno, system_category() ); - } - - BOOST_FILESYSTEM_DECL error_code - remove_api( const std::string & ph ) - { - if ( posix_remove( ph.c_str() ) == 0 ) - return ok; - int error = errno; - // POSIX says "If the directory is not an empty directory, rmdir() - // shall fail and set errno to EEXIST or ENOTEMPTY." - // Linux uses ENOTEMPTY, Solaris uses EEXIST. - if ( error == EEXIST ) error = ENOTEMPTY; - - error_code ec; - - // ignore errors if post-condition satisfied - return status_api(ph, ec).type() == file_not_found - ? ok : error_code( error, system_category() ) ; - } - - BOOST_FILESYSTEM_DECL error_code - rename_api( const std::string & from, const std::string & to ) - { - // 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( std::rename( from.c_str(), to.c_str() ) != 0 - ? errno : 0, system_category() ); - } - - BOOST_FILESYSTEM_DECL error_code - copy_file_api( const std::string & from_file_ph, - const std::string & to_file_ph, 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_file_ph.c_str(), O_RDONLY )) < 0 ) - { 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() ); } - - int oflag = O_CREAT | O_WRONLY | O_TRUNC; - if ( fail_if_exists ) - oflag |= O_EXCL; - if ( (outfile = ::open( to_file_ph.c_str(), oflag, from_stat.st_mode )) < 0 ) - { - int open_errno = errno; - BOOST_ASSERT( infile >= 0 ); - ::close( infile ); - return error_code( open_errno, system_category() ); - } - - 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 error_code( sz_read < 0 ? errno : 0, system_category() ); - } - - // this code is based on Stevens and Rago, Advanced Programming in the - // UNIX envirnment, 2nd Ed., ISBN 0-201-43307-9, page 49 - error_code path_max( std::size_t & result ) - { -# 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; - } - - BOOST_FILESYSTEM_DECL error_code - dir_itr_first( void *& handle, void *& buffer, - const std::string & dir, std::string & target, - file_status &, file_status & ) - { - if ( (handle = ::opendir( dir.c_str() )) == 0 ) - 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 - std::size_t path_size (0); // initialization quiets gcc warning - 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; - } - - BOOST_FILESYSTEM_DECL error_code - dir_itr_close( void *& handle, void*& buffer ) - { - 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() ); - } - - // 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; - } - - BOOST_FILESYSTEM_DECL error_code - dir_itr_increment( void *& handle, void *& buffer, - std::string & target, file_status & sf, 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 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_unknown); - } - 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_unknown ); - symlink_sf = fs::file_status( fs::symlink_file ); - } - else sf = symlink_sf = fs::file_status( fs::status_unknown ); - } -# else - sf = symlink_sf = fs::file_status( fs::status_unknown ); -# endif - return ok; - } - -# endif - } // namespace detail - } // namespace filesystem2 -} // namespace boost diff --git a/3rdParty/Boost/src/libs/filesystem/v2/src/v2_path.cpp b/3rdParty/Boost/src/libs/filesystem/v2/src/v2_path.cpp deleted file mode 100644 index 16f6583..0000000 --- a/3rdParty/Boost/src/libs/filesystem/v2/src/v2_path.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// path.cpp ----------------------------------------------------------------// - -// Copyright 2005 Beman Dawes - -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -// See library home page at http://www.boost.org/libs/filesystem - -//----------------------------------------------------------------------------// - -// 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/v2/config.hpp> - -#ifndef BOOST_FILESYSTEM2_NARROW_ONLY - -#include <boost/filesystem/v2/path.hpp> -#include <boost/scoped_array.hpp> - -#include <locale> -#include <boost/cerrno.hpp> -#include <boost/system/error_code.hpp> - -#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), - // 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 & loc() - { -#if !defined(macintosh) && !defined(__APPLE__) && !defined(__APPLE_CC__) - // ISO C calls this "the locale-specific native environment": - static std::locale lc(""); -#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; - } - - const std::codecvt<wchar_t, char, std::mbstate_t> *& - converter() - { - static const std::codecvt<wchar_t, char, std::mbstate_t> * - cvtr( - &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> > - ( loc() ) ); - return cvtr; - } - - bool locked(false); -} // unnamed namespace - -namespace boost -{ - namespace filesystem2 - { - bool wpath_traits::imbue( const std::locale & new_loc, const std::nothrow_t & ) - { - if ( locked ) return false; - locked = true; - loc() = new_loc; - converter() = &std::use_facet - <std::codecvt<wchar_t, char, std::mbstate_t> >( loc() ); - return true; - } - - void wpath_traits::imbue( const std::locale & new_loc ) - { - if ( locked ) BOOST_FILESYSTEM_THROW( - wfilesystem_error( - "boost::filesystem::wpath_traits::imbue() after lockdown", - make_error_code( system::errc::not_supported ) ) ); - imbue( new_loc, std::nothrow ); - } - - //namespace detail - //{ - // BOOST_FILESYSTEM_DECL - // const char * what( const char * sys_err_what, - // const path & path1, const path & path2, std::string & target) - // { - // try - // { - // if ( target.empty() ) - // { - // target = sys_err_what; - // if ( !path1.empty() ) - // { - // target += ": \""; - // target += path1.file_string(); - // target += "\""; - // } - // if ( !path2.empty() ) - // { - // target += ", \""; - // target += path2.file_string(); - // target += "\""; - // } - // } - // return target.c_str(); - // } - // catch (...) - // { - // return sys_err_what; - // } - // } - //} - -# ifdef BOOST_POSIX_API - -// Because this is POSIX only code, we don't have to worry about ABI issues -// described in http://www.boost.org/more/separate_compilation.html - - wpath_traits::external_string_type - wpath_traits::to_external( const wpath & ph, - const internal_string_type & src ) - { - locked = true; - std::size_t work_size( converter()->max_length() * (src.size()+1) ); - boost::scoped_array<char> work( new char[ work_size ] ); - std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports - const internal_string_type::value_type * from_next; - external_string_type::value_type * to_next; - if ( converter()->out( - state, src.c_str(), src.c_str()+src.size(), from_next, work.get(), - work.get()+work_size, to_next ) != std::codecvt_base::ok ) - BOOST_FILESYSTEM_THROW( boost::filesystem::wfilesystem_error( - "boost::filesystem::wpath::to_external conversion error", - ph, system::error_code( system::errc::invalid_argument, system::system_category() ) ) ); - *to_next = '\0'; - return external_string_type( work.get() ); - } - - wpath_traits::internal_string_type - wpath_traits::to_internal( const external_string_type & src ) - { - locked = true; - std::size_t work_size( src.size()+1 ); - boost::scoped_array<wchar_t> work( new wchar_t[ work_size ] ); - std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports - const external_string_type::value_type * from_next; - internal_string_type::value_type * to_next; - if ( converter()->in( - state, src.c_str(), src.c_str()+src.size(), from_next, work.get(), - work.get()+work_size, to_next ) != std::codecvt_base::ok ) - BOOST_FILESYSTEM_THROW( boost::filesystem::wfilesystem_error( - "boost::filesystem::wpath::to_internal conversion error", - 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 filesystem2 -} // namespace boost - -#endif // ifndef BOOST_FILESYSTEM2_NARROW_ONLY diff --git a/3rdParty/Boost/src/libs/filesystem/v2/src/v2_portability.cpp b/3rdParty/Boost/src/libs/filesystem/v2/src/v2_portability.cpp deleted file mode 100644 index 4d27543..0000000 --- a/3rdParty/Boost/src/libs/filesystem/v2/src/v2_portability.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// 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 - -//----------------------------------------------------------------------------// - -// 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/v2/config.hpp> -#include <boost/filesystem/v2/path.hpp> - -namespace fs = boost::filesystem2; - -#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 filesystem2 - { - - // 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 filesystem2 -} // namespace boost diff --git a/3rdParty/Boost/src/libs/program_options/src/cmdline.cpp b/3rdParty/Boost/src/libs/program_options/src/cmdline.cpp index be31385..d7910c2 100644 --- a/3rdParty/Boost/src/libs/program_options/src/cmdline.cpp +++ b/3rdParty/Boost/src/libs/program_options/src/cmdline.cpp @@ -35,13 +35,7 @@ namespace boost { namespace program_options { using namespace boost::program_options::command_line_style; - invalid_syntax:: - invalid_syntax(const string& tokens, kind_t kind) - : error(error_message(kind).append(" in '").append(tokens).append("'")) - , m_tokens(tokens) - , m_kind(kind) - {} string - invalid_syntax::error_message(kind_t kind) + invalid_syntax::get_template(kind_t kind) { // Initially, store the message in 'const char*' variable, @@ -50,47 +44,32 @@ namespace boost { namespace program_options { switch(kind) { + case empty_adjacent_parameter: + msg = "the argument for option '%canonical_option%' should follow immediately after the equal sign"; + break; + case missing_parameter: + msg = "the required argument for option '%canonical_option%' is missing"; + break; + case unrecognized_line: + msg = "the options configuration file contains an invalid line '%invalid_line%'"; + break; + // none of the following are currently used: case long_not_allowed: - msg = "long options are not allowed"; + msg = "the unabbreviated option '%canonical_option%' is not valid"; break; case long_adjacent_not_allowed: - msg = "parameters adjacent to long options not allowed"; + msg = "the unabbreviated option '%canonical_option%' does not take any arguments"; break; case short_adjacent_not_allowed: - msg = "parameters adjust to short options are not allowed"; - break; - case empty_adjacent_parameter: - msg = "adjacent parameter is empty"; - break; - case missing_parameter: - msg = "required parameter is missing"; + msg = "the abbreviated option '%canonical_option%' does not take any arguments"; break; case extra_parameter: - msg = "extra parameter"; - break; - case unrecognized_line: - msg = "unrecognized line"; + msg = "option '%canonical_option%' does not take any arguments"; break; default: - msg = "unknown error"; + msg = "unknown command line syntax error for '%s'"; } return msg; } - invalid_syntax::kind_t - invalid_syntax::kind() const - { - return m_kind; - } - - const string& - invalid_syntax::tokens() const - { - return m_tokens; - } - - invalid_command_line_syntax:: - invalid_command_line_syntax(const string& tokens, kind_t kind) - : invalid_syntax(tokens, kind) - {} }} @@ -157,13 +136,24 @@ namespace boost { namespace program_options { namespace detail { if (allow_some_long && !(style & long_allow_adjacent) && !(style & long_allow_next)) - error = "style disallows parameters for long options"; + error = "boost::program_options misconfiguration: " + "choose one or other of 'command_line_style::long_allow_next' " + "(whitespace separated arguments) or " + "'command_line_style::long_allow_adjacent' ('=' separated arguments) for " + "long options."; if (!error && (style & allow_short) && !(style & short_allow_adjacent) && !(style & short_allow_next)) - error = "style disallows parameters for short options"; + error = "boost::program_options misconfiguration: " + "choose one or other of 'command_line_style::short_allow_next' " + "(whitespace separated arguments) or " + "'command_line_style::short_allow_adjacent' ('=' separated arguments) for " + "short options."; if (!error && (style & allow_short) && !(style & allow_dash_for_short) && !(style & allow_slash_for_short)) - error = "style disallows all characters for short options"; + error = "boost::program_options misconfiguration: " + "choose one or other of 'command_line_style::allow_slash_for_short' " + "(slashes) or 'command_line_style::allow_dash_for_short' (dashes) for " + "short options."; if (error) @@ -193,4 +183,21 @@ namespace boost { namespace program_options { namespace detail { } + int + cmdline::get_canonical_option_prefix() + { + if (m_style & allow_long) + return allow_long; + + if (m_style & allow_long_disguise) + return allow_long_disguise; + + if ((m_style & allow_short) && (m_style & allow_dash_for_short)) + return allow_dash_for_short; + + if ((m_style & allow_short) && (m_style & allow_slash_for_short)) + return allow_slash_for_short; + + return 0; + } vector<option> @@ -243,5 +250,5 @@ namespace boost { namespace program_options { namespace detail { for(unsigned i = 0; i < style_parsers.size(); ++i) { - unsigned current_size = args.size(); + unsigned current_size = static_cast<unsigned>(args.size()); vector<option> next = style_parsers[i](args); @@ -278,5 +285,5 @@ namespace boost { namespace program_options { namespace detail { /* If an key option is followed by a positional option, - can can consume more tokens (e.g. it's multitoke option), + can can consume more tokens (e.g. it's multitoken option), give those tokens to it. */ vector<option> result2; @@ -289,9 +296,19 @@ namespace boost { namespace program_options { namespace detail { continue; - const option_description* xd = - m_desc->find_nothrow(opt.string_key, + const option_description* xd; + try + { + xd = m_desc->find_nothrow(opt.string_key, is_style_active(allow_guessing), is_style_active(long_case_insensitive), is_style_active(short_case_insensitive)); + } + catch(error_with_option_name& e) + { + // add context and rethrow + e.add_context(opt.string_key, opt.original_tokens[0], get_canonical_option_prefix()); + throw; + } + if (!xd) continue; @@ -305,5 +322,5 @@ namespace boost { namespace program_options { namespace detail { // recognized as key options. - int can_take_more = max_tokens - opt.value.size(); + int can_take_more = max_tokens - static_cast<int>(opt.value.size()); unsigned j = i+1; for (; can_take_more && j < result.size(); --can_take_more, ++j) @@ -384,4 +401,13 @@ namespace boost { namespace program_options { namespace detail { return; + // + // Be defensive: + // will have no original token if option created by handle_additional_parser() + std::string original_token_for_exceptions = opt.string_key; + if (opt.original_tokens.size()) + original_token_for_exceptions = opt.original_tokens[0]; + + try + { // First check that the option is valid, and get its description. const option_description* xd = m_desc->find_nothrow(opt.string_key, @@ -396,5 +422,5 @@ namespace boost { namespace program_options { namespace detail { return; } else { - boost::throw_exception(unknown_option(opt.string_key)); + boost::throw_exception(unknown_option()); } } @@ -415,5 +441,5 @@ namespace boost { namespace program_options { namespace detail { unsigned max_tokens = d.semantic()->max_tokens(); - unsigned present_tokens = opt.value.size() + other_tokens.size(); + unsigned present_tokens = static_cast<unsigned>(opt.value.size() + other_tokens.size()); if (present_tokens >= min_tokens) @@ -421,6 +447,6 @@ namespace boost { namespace program_options { namespace detail { if (!opt.value.empty() && max_tokens == 0) { - boost::throw_exception(invalid_command_line_syntax(opt.string_key, - invalid_command_line_syntax::extra_parameter)); + boost::throw_exception( + invalid_command_line_syntax(invalid_command_line_syntax::extra_parameter)); } @@ -430,5 +456,5 @@ namespace boost { namespace program_options { namespace detail { if (opt.value.size() <= min_tokens) { - min_tokens -= opt.value.size(); + min_tokens -= static_cast<unsigned>(opt.value.size()); } else @@ -451,4 +477,5 @@ namespace boost { namespace program_options { namespace detail { if (!followed_option.empty()) { + original_token_for_exceptions = other_tokens[0]; const option_description* od = m_desc->find_nothrow(other_tokens[0], is_style_active(allow_guessing), @@ -456,6 +483,6 @@ namespace boost { namespace program_options { namespace detail { is_style_active(short_case_insensitive)); if (od) - boost::throw_exception(invalid_command_line_syntax(opt.string_key, - invalid_command_line_syntax::missing_parameter)); + boost::throw_exception( + invalid_command_line_syntax(invalid_command_line_syntax::missing_parameter)); } opt.value.push_back(other_tokens[0]); @@ -466,9 +493,19 @@ namespace boost { namespace program_options { namespace detail { else { - boost::throw_exception(invalid_command_line_syntax(opt.string_key, - invalid_command_line_syntax::missing_parameter)); + boost::throw_exception( + invalid_command_line_syntax(invalid_command_line_syntax::missing_parameter)); } } + // use only original token for unknown_option / ambiguous_option since by definition + // they are unrecognised / unparsable + catch(error_with_option_name& e) + { + // add context and rethrow + e.add_context(opt.string_key, original_token_for_exceptions, get_canonical_option_prefix()); + throw; + } + + } vector<option> @@ -487,6 +524,9 @@ namespace boost { namespace program_options { namespace detail { adjacent = tok.substr(p+1); if (adjacent.empty()) - boost::throw_exception( invalid_command_line_syntax(name, - invalid_command_line_syntax::empty_adjacent_parameter) ); + boost::throw_exception( invalid_command_line_syntax( + invalid_command_line_syntax::empty_adjacent_parameter, + name, + name, + get_canonical_option_prefix()) ); } else @@ -524,7 +564,18 @@ namespace boost { namespace program_options { namespace detail { // option. for(;;) { - const option_description* d - = m_desc->find_nothrow(name, false, false, + const option_description* d; + try + { + + d = m_desc->find_nothrow(name, false, false, is_style_active(short_case_insensitive)); + } + catch(error_with_option_name& e) + { + // add context and rethrow + e.add_context(name, name, get_canonical_option_prefix()); + throw; + } + // FIXME: check for 'allow_sticky'. @@ -590,4 +641,6 @@ namespace boost { namespace program_options { namespace detail { ((m_style & allow_slash_for_short) && tok[0] == '/'))) { + try + { if (m_desc->find_nothrow(tok.substr(1, tok.find('=')-1), is_style_active(allow_guessing), @@ -601,4 +654,11 @@ namespace boost { namespace program_options { namespace detail { } } + catch(error_with_option_name& e) + { + // add context and rethrow + e.add_context(tok, tok, get_canonical_option_prefix()); + throw; + } + } return vector<option>(); } diff --git a/3rdParty/Boost/src/libs/program_options/src/config_file.cpp b/3rdParty/Boost/src/libs/program_options/src/config_file.cpp index a12844c..f2a57b4 100644 --- a/3rdParty/Boost/src/libs/program_options/src/config_file.cpp +++ b/3rdParty/Boost/src/libs/program_options/src/config_file.cpp @@ -58,5 +58,7 @@ namespace boost { namespace program_options { namespace detail { } if (bad_prefixes) - boost::throw_exception(error("bad prefixes")); + boost::throw_exception(error("options '" + string(name) + "' and '" + + *i + "*' will both match the same " + "arguments from the configuration file")); allowed_prefixes.insert(s); } @@ -118,5 +120,5 @@ namespace boost { namespace program_options { namespace detail { } else { - boost::throw_exception(invalid_syntax(s, invalid_syntax::unrecognized_line)); + boost::throw_exception(invalid_config_file_syntax(s, invalid_syntax::unrecognized_line)); } } 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 0d8dfd4..9d51ce9 100644 --- a/3rdParty/Boost/src/libs/program_options/src/options_description.cpp +++ b/3rdParty/Boost/src/libs/program_options/src/options_description.cpp @@ -138,4 +138,29 @@ namespace boost { namespace program_options { } + std::string + option_description::canonical_display_name(int prefix_style) const + { + if (!m_long_name.empty()) + { + if (prefix_style == command_line_style::allow_long) + return "--" + m_long_name; + if (prefix_style == command_line_style::allow_long_disguise) + return "-" + m_long_name; + } + // sanity check: m_short_name[0] should be '-' or '/' + if (m_short_name.length() == 2) + { + if (prefix_style == command_line_style::allow_slash_for_short) + return string("/") + m_short_name[1]; + if (prefix_style == command_line_style::allow_dash_for_short) + return string("-") + m_short_name[1]; + } + if (!m_long_name.empty()) + return m_long_name; + else + return m_short_name; + } + + const std::string& option_description::long_name() const @@ -175,7 +200,10 @@ namespace boost { namespace program_options { { if (!m_short_name.empty()) - return string(m_short_name).append(" [ --"). + { + return m_long_name.empty() + ? m_short_name + : string(m_short_name).append(" [ --"). append(m_long_name).append(" ]"); - else + } return string("--").append(m_long_name); } @@ -290,5 +318,5 @@ namespace boost { namespace program_options { long_ignore_case, short_ignore_case); if (!d) - boost::throw_exception(unknown_option(name)); + boost::throw_exception(unknown_option()); return *d; } @@ -338,6 +366,5 @@ namespace boost { namespace program_options { } if (full_matches.size() > 1) - boost::throw_exception( - ambiguous_option(name, full_matches)); + boost::throw_exception(ambiguous_option(full_matches)); // If we have a full match, and an approximate match, @@ -347,6 +374,5 @@ namespace boost { namespace program_options { // without ambiguity. if (full_matches.empty() && approximate_matches.size() > 1) - boost::throw_exception( - ambiguous_option(name, approximate_matches)); + boost::throw_exception(ambiguous_option(approximate_matches)); return found.get(); @@ -397,5 +423,5 @@ namespace boost { namespace program_options { { boost::throw_exception(program_options::error( - "Only one tab per paragraph is allowed")); + "Only one tab per paragraph is allowed in the options description")); } @@ -444,5 +470,5 @@ namespace boost { namespace program_options { // the end, since MSVC 8.0 (brokenly), assumes that // doing that, even if no access happens, is a bug. - unsigned remaining = distance(line_begin, par_end); + unsigned remaining = static_cast<unsigned>(std::distance(line_begin, par_end)); string::const_iterator line_end = line_begin + ((remaining < line_length) ? remaining : line_length); @@ -464,5 +490,5 @@ namespace boost { namespace program_options { // is last_space within the second half ot the // current line - if (static_cast<unsigned>(distance(last_space, line_end)) < + if (static_cast<unsigned>(std::distance(last_space, line_end)) < (line_length / 2)) { @@ -477,6 +503,6 @@ namespace boost { namespace program_options { if (first_line) { - indent += par_indent; - line_length -= par_indent; // there's less to work with now + indent += static_cast<unsigned>(par_indent); + line_length -= static_cast<unsigned>(par_indent); // there's less to work with now first_line = false; } @@ -567,5 +593,5 @@ namespace boost { namespace program_options { } } else { - for(unsigned pad = first_column_width - ss.str().size(); pad > 0; --pad) + for(unsigned pad = first_column_width - static_cast<unsigned>(ss.str().size()); pad > 0; --pad) { os.put(' '); @@ -579,10 +605,7 @@ namespace boost { namespace program_options { } - void - options_description::print(std::ostream& os) const + unsigned + options_description::get_option_column_width() const { - if (!m_caption.empty()) - os << m_caption << ":\n"; - /* Find the maximum width of the option column */ unsigned width(23); @@ -595,4 +618,9 @@ namespace boost { namespace program_options { width = (max)(width, static_cast<unsigned>(ss.str().size())); } + + /* Get width of groups as well*/ + for (unsigned j = 0; j < groups.size(); ++j) + width = max(width, groups[j]->get_option_column_width()); + /* this is the column were description should start, if first column is longer, we go to a new line */ @@ -603,7 +631,18 @@ namespace boost { namespace program_options { /* add an additional space to improve readability */ ++width; + return width; + } + + void + options_description::print(std::ostream& os, unsigned width) const + { + if (!m_caption.empty()) + os << m_caption << ":\n"; + + if (!width) + width = get_option_column_width(); /* The options formatting style is stolen from Subversion. */ - for (i = 0; i < m_options.size(); ++i) + for (unsigned i = 0; i < m_options.size(); ++i) { if (belong_to_group[i]) @@ -618,5 +657,6 @@ namespace boost { namespace program_options { for (unsigned j = 0; j < groups.size(); ++j) { - os << "\n" << *groups[j]; + os << "\n"; + groups[j]->print(os, width); } } diff --git a/3rdParty/Boost/src/libs/program_options/src/parsers.cpp b/3rdParty/Boost/src/libs/program_options/src/parsers.cpp index bc3b858..2361a48 100644 --- a/3rdParty/Boost/src/libs/program_options/src/parsers.cpp +++ b/3rdParty/Boost/src/libs/program_options/src/parsers.cpp @@ -46,5 +46,8 @@ // See: http://lists.gnu.org/archive/html/bug-guile/2004-01/msg00013.html #if defined(__APPLE__) && defined(__DYNAMIC__) -#include <crt_externs.h> +// The proper include for this is crt_externs.h, however it's not +// available on iOS. The right replacement is not known. See +// https://svn.boost.org/trac/boost/ticket/5053 +extern "C" { extern char ***_NSGetEnviron(void); } #define environ (*_NSGetEnviron()) #else @@ -86,5 +89,6 @@ namespace boost { namespace program_options { ::basic_parsed_options(const parsed_options& po) : description(po.description), - utf8_encoded_options(po) + utf8_encoded_options(po), + m_options_prefix(po.m_options_prefix) { for (unsigned i = 0; i < po.options.size(); ++i) @@ -108,5 +112,5 @@ namespace boost { namespace program_options { if (d.long_name().empty()) boost::throw_exception( - error("long name required for config file")); + error("abbreviated option names are not permitted in options configuration files")); allowed_options.insert(d.long_name()); diff --git a/3rdParty/Boost/src/libs/program_options/src/positional_options.cpp b/3rdParty/Boost/src/libs/program_options/src/positional_options.cpp index 55995d7..72dc0d6 100644 --- a/3rdParty/Boost/src/libs/program_options/src/positional_options.cpp +++ b/3rdParty/Boost/src/libs/program_options/src/positional_options.cpp @@ -35,5 +35,5 @@ namespace boost { namespace program_options { { return m_trailing.empty() ? - m_names.size() : (std::numeric_limits<unsigned>::max)(); + static_cast<unsigned>(m_names.size()) : (std::numeric_limits<unsigned>::max)(); } diff --git a/3rdParty/Boost/src/libs/program_options/src/program_options_utf8_codecvt_facet.cpp b/3rdParty/Boost/src/libs/program_options/src/program_options_utf8_codecvt_facet.cpp index c0fd7c0..2e4c532 100644 --- a/3rdParty/Boost/src/libs/program_options/src/program_options_utf8_codecvt_facet.cpp +++ b/3rdParty/Boost/src/libs/program_options/src/program_options_utf8_codecvt_facet.cpp @@ -13,5 +13,5 @@ #define BOOST_UTF8_DECL BOOST_PROGRAM_OPTIONS_DECL -#include "../../detail/utf8_codecvt_facet.cpp" +#include <boost/detail/utf8_codecvt_facet.ipp> diff --git a/3rdParty/Boost/src/libs/program_options/src/value_semantic.cpp b/3rdParty/Boost/src/libs/program_options/src/value_semantic.cpp index f5770f1..5314029 100644 --- a/3rdParty/Boost/src/libs/program_options/src/value_semantic.cpp +++ b/3rdParty/Boost/src/libs/program_options/src/value_semantic.cpp @@ -8,4 +8,6 @@ #include <boost/program_options/value_semantic.hpp> #include <boost/program_options/detail/convert.hpp> +#include <boost/program_options/detail/cmdline.hpp> +#include <set> #include <cctype> @@ -15,4 +17,20 @@ namespace boost { namespace program_options { using namespace std; + +#ifndef BOOST_NO_STD_WSTRING + namespace + { + std::string convert_value(const std::wstring& s) + { + try { + return to_local_8_bit(s); + } + catch(const std::exception&) { + return "<unrepresentable unicode string>"; + } + } + } +#endif + void value_semantic_codecvt_helper<char>:: @@ -140,5 +158,5 @@ namespace boost { namespace program_options { v = any(false); else - boost::throw_exception(validation_error(validation_error::invalid_bool_value, s)); + boost::throw_exception(invalid_bool_value(s)); } @@ -162,5 +180,5 @@ namespace boost { namespace program_options { v = any(false); else - boost::throw_exception(validation_error(validation_error::invalid_bool_value)); + boost::throw_exception(invalid_bool_value(convert_value(s))); } #endif @@ -195,98 +213,189 @@ namespace boost { namespace program_options { invalid_option_value:: invalid_option_value(const std::string& bad_value) - : validation_error(validation_error::invalid_option_value, bad_value) - {} - -#ifndef BOOST_NO_STD_WSTRING - namespace - { - std::string convert_value(const std::wstring& s) + : validation_error(validation_error::invalid_option_value) { - try { - return to_local_8_bit(s); - } - catch(const std::exception&) { - return "<unrepresentable unicode string>"; - } - } + set_substitute("value", bad_value); } +#ifndef BOOST_NO_STD_WSTRING invalid_option_value:: invalid_option_value(const std::wstring& bad_value) - : validation_error(validation_error::invalid_option_value, convert_value(bad_value)) - {} -#endif - const std::string& - unknown_option::get_option_name() const throw() + : validation_error(validation_error::invalid_option_value) { - return m_option_name; + set_substitute("value", convert_value(bad_value)); } +#endif + - const std::string& - ambiguous_option::get_option_name() const throw() + + invalid_bool_value:: + invalid_bool_value(const std::string& bad_value) + : validation_error(validation_error::invalid_bool_value) { - return m_option_name; + set_substitute("value", bad_value); } - const std::vector<std::string>& - ambiguous_option::alternatives() const throw() + + + + + + error_with_option_name::error_with_option_name( const std::string& template_, + const std::string& option_name, + const std::string& original_token, + int option_style) : + error(template_), + m_option_style(option_style), + m_error_template(template_) { - return m_alternatives; + // parameter | placeholder | value + // --------- | ----------- | ----- + set_substitute_default("canonical_option", "option '%canonical_option%'", "option"); + set_substitute_default("value", "argument ('%value%')", "argument"); + set_substitute_default("prefix", "%prefix%", ""); + m_substitutions["option"] = option_name; + m_substitutions["original_token"] = original_token; } - void - multiple_values::set_option_name(const std::string& option_name) + + const char* error_with_option_name::what() const throw() { - m_option_name = option_name; + // will substitute tokens each time what is run() + substitute_placeholders(m_error_template); + + return m_message.c_str(); } - const std::string& - multiple_values::get_option_name() const throw() + void error_with_option_name::replace_token(const string& from, const string& to) const + { + while (1) { - return m_option_name; + std::size_t pos = m_message.find(from.c_str(), 0, from.length()); + // not found: all replaced + if (pos == std::string::npos) + return; + m_message.replace(pos, from.length(), to); + } } - void - multiple_occurrences::set_option_name(const std::string& option_name) + string error_with_option_name::get_canonical_option_prefix() const { - m_option_name = option_name; + switch (m_option_style) + { + case command_line_style::allow_dash_for_short: + return "-"; + case command_line_style::allow_slash_for_short: + return "/"; + case command_line_style::allow_long_disguise: + return "-"; + case command_line_style::allow_long: + return "--"; + case 0: + return ""; + } + throw std::logic_error("error_with_option_name::m_option_style can only be " + "one of [0, allow_dash_for_short, allow_slash_for_short, " + "allow_long_disguise or allow_long]"); } - const std::string& - multiple_occurrences::get_option_name() const throw() + + string error_with_option_name::get_canonical_option_name() const { - return m_option_name; + if (!m_substitutions.find("option")->second.length()) + return m_substitutions.find("original_token")->second; + + string original_token = strip_prefixes(m_substitutions.find("original_token")->second); + string option_name = strip_prefixes(m_substitutions.find("option")->second); + + // For long options, use option name + if (m_option_style == command_line_style::allow_long || + m_option_style == command_line_style::allow_long_disguise) + return get_canonical_option_prefix() + option_name; + + // For short options use first letter of original_token + if (m_option_style && original_token.length()) + return get_canonical_option_prefix() + original_token[0]; + + // no prefix + return option_name; } - validation_error:: - validation_error(kind_t kind, - const std::string& option_value, - const std::string& option_name) - : error("") - , m_kind(kind) - , m_option_name(option_name) - , m_option_value(option_value) - , m_message(error_message(kind)) + + void error_with_option_name::substitute_placeholders(const string& error_template) const { - if (!option_value.empty()) + m_message = error_template; + std::map<std::string, std::string> substitutions(m_substitutions); + substitutions["canonical_option"] = get_canonical_option_name(); + substitutions["prefix"] = get_canonical_option_prefix(); + + + // + // replace placeholder with defaults if values are missing + // + for (map<string, string_pair>::const_iterator iter = m_substitution_defaults.begin(); + iter != m_substitution_defaults.end(); ++iter) { - m_message.append(std::string("'") + option_value + std::string("'")); + // missing parameter: use default + if (substitutions.count(iter->first) == 0 || + substitutions[iter->first].length() == 0) + replace_token(iter->second.first, iter->second.second); } + + + // + // replace placeholder with values + // placeholder are denoted by surrounding '%' + // + for (map<string, string>::iterator iter = substitutions.begin(); + iter != substitutions.end(); ++iter) + replace_token('%' + iter->first + '%', iter->second); } - void - validation_error::set_option_name(const std::string& option_name) + + void ambiguous_option::substitute_placeholders(const string& original_error_template) const + { + // For short forms, all alternatives must be identical, by + // definition, to the specified option, so we don't need to + // display alternatives + if (m_option_style == command_line_style::allow_dash_for_short || + m_option_style == command_line_style::allow_slash_for_short) { - m_option_name = option_name; + error_with_option_name::substitute_placeholders(original_error_template); + return; } - const std::string& - validation_error::get_option_name() const throw() + + string error_template = original_error_template; + // remove duplicates using std::set + std::set<std::string> alternatives_set (m_alternatives.begin(), m_alternatives.end()); + std::vector<std::string> alternatives_vec (alternatives_set.begin(), alternatives_set.end()); + + error_template += " and matches "; + // Being very cautious: should be > 1 alternative! + if (alternatives_vec.size() > 1) { - return m_option_name; + for (unsigned i = 0; i < alternatives_vec.size() - 1; ++i) + error_template += "'%prefix%" + alternatives_vec[i] + "', "; + error_template += "and "; } - std::string - validation_error::error_message(kind_t kind) + // there is a programming error if multiple options have the same name... + if (m_alternatives.size() > 1 && alternatives_vec.size() == 1) + error_template += "different versions of "; + + error_template += "'%prefix%" + alternatives_vec.back() + "'"; + + + // use inherited logic + error_with_option_name::substitute_placeholders(error_template); + } + + + + + + + string + validation_error::get_template(kind_t kind) { // Initially, store the message in 'const char*' variable, @@ -295,18 +404,19 @@ namespace boost { namespace program_options { switch(kind) { - case multiple_values_not_allowed: - msg = "multiple values not allowed"; - break; - case at_least_one_value_required: - msg = "at least one value required"; - break; case invalid_bool_value: - msg = "invalid bool value"; + msg = "the argument ('%value%') for option '%canonical_option%' is invalid. Valid choices are 'on|off', 'yes|no', '1|0' and 'true|false'"; break; case invalid_option_value: - msg = "invalid option value"; + msg = "the argument ('%value%') for option '%canonical_option%' is invalid"; + break; + case multiple_values_not_allowed: + msg = "option '%canonical_option%' only takes a single argument"; break; + case at_least_one_value_required: + msg = "option '%canonical_option%' requires at least one argument"; + break; + // currently unused case invalid_option: - msg = "invalid option"; + msg = "option '%canonical_option%' is not valid"; break; default: @@ -316,20 +426,3 @@ namespace boost { namespace program_options { } - const char* - validation_error::what() const throw() - { - if (!m_option_name.empty()) - { - m_message = "in option '" + m_option_name + "': " - + error_message(m_kind); - } - return m_message.c_str(); - } - - const std::string& - required_option::get_option_name() const throw() - { - return m_option_name; - } - }} diff --git a/3rdParty/Boost/src/libs/program_options/src/variables_map.cpp b/3rdParty/Boost/src/libs/program_options/src/variables_map.cpp index 29b1de9..caf354e 100644 --- a/3rdParty/Boost/src/libs/program_options/src/variables_map.cpp +++ b/3rdParty/Boost/src/libs/program_options/src/variables_map.cpp @@ -39,10 +39,20 @@ namespace boost { namespace program_options { unsigned i; + // Declared here so can be used to provide context for exceptions + string option_name; + string original_token; + + try + { + // First, convert/store all given options for (i = 0; i < options.options.size(); ++i) { - const string& name = options.options[i].string_key; + option_name = options.options[i].string_key; + original_token = options.options[i].original_tokens.size() ? + options.options[i].original_tokens[0] : + option_name; // Skip positional options without name - if (name.empty()) + if (option_name.empty()) continue; @@ -56,11 +66,13 @@ namespace boost { namespace program_options { // If option has final value, skip this assignment - if (xm.m_final.count(name)) + if (xm.m_final.count(option_name)) continue; - const option_description& d = desc.find(name, false, + string original_token = options.options[i].original_tokens.size() ? + options.options[i].original_tokens[0] : ""; + const option_description& d = desc.find(option_name, false, false, false); - variable_value& v = m[name]; + variable_value& v = m[option_name]; if (v.defaulted()) { // Explicit assignment here erases defaulted value @@ -68,24 +80,6 @@ namespace boost { namespace program_options { } - try { d.semantic()->parse(v.value(), options.options[i].value, utf8); - } -#ifndef BOOST_NO_EXCEPTIONS - catch(validation_error& e) - { - e.set_option_name(name); - throw; - } - catch(multiple_occurrences& e) - { - e.set_option_name(name); - throw; - } - catch(multiple_values& e) - { - e.set_option_name(name); - throw; - } -#endif + v.m_value_semantic = d.semantic(); @@ -96,6 +90,15 @@ namespace boost { namespace program_options { // are allowed. if (!d.semantic()->is_composing()) - new_final.insert(name); + new_final.insert(option_name); + } } +#ifndef BOOST_NO_EXCEPTIONS + catch(error_with_option_name& e) + { + // add context and rethrow + e.add_context(option_name, original_token, options.m_options_prefix); + throw; + } +#endif xm.m_final.insert(new_final.begin(), new_final.end()); @@ -128,5 +131,12 @@ namespace boost { namespace program_options { // add empty value if this is an required option if (d.semantic()->is_required()) { - xm.m_required.insert(key); + + // For option names specified in multiple ways, e.g. on the command line, + // config file etc, the following precedence rules apply: + // "--" > ("-" or "/") > "" + // Precedence is set conveniently by a single call to length() + string canonical_name = d.canonical_display_name(options.m_options_prefix); + if (canonical_name.length() > xm.m_required[key].length()) + xm.m_required[key] = canonical_name; } } @@ -183,4 +193,11 @@ namespace boost { namespace program_options { {} + void variables_map::clear() + { + std::map<std::string, variable_value>::clear(); + m_final.clear(); + m_required.clear(); + } + const variable_value& variables_map::get(const std::string& name) const @@ -198,13 +215,14 @@ namespace boost { namespace program_options { { // This checks if all required options occur - for (set<string>::const_iterator r = m_required.begin(); + for (map<string, string>::const_iterator r = m_required.begin(); r != m_required.end(); ++r) { - const string& opt = *r; + const string& opt = r->first; + const string& display_opt = r->second; map<string, variable_value>::const_iterator iter = find(opt); if (iter == end() || iter->second.empty()) { - boost::throw_exception(required_option(opt)); + boost::throw_exception(required_option(display_opt)); } diff --git a/3rdParty/Boost/src/libs/program_options/src/winmain.cpp b/3rdParty/Boost/src/libs/program_options/src/winmain.cpp index 8a7c43f..6220043 100644 --- a/3rdParty/Boost/src/libs/program_options/src/winmain.cpp +++ b/3rdParty/Boost/src/libs/program_options/src/winmain.cpp @@ -8,4 +8,6 @@ #include <cctype> +using std::size_t; + #ifdef _WIN32 namespace boost { namespace program_options { @@ -90,5 +92,5 @@ namespace boost { namespace program_options { std::vector<std::wstring> result; std::vector<std::string> aux = split_winmain(to_internal(cmdline)); - for (unsigned i = 0, e = aux.size(); i < e; ++i) + for (size_t i = 0, e = aux.size(); i < e; ++i) result.push_back(from_utf8(aux[i])); return result; 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 a99de14..23ec324 100644 --- a/3rdParty/Boost/src/libs/regex/src/c_regex_traits.cpp +++ b/3rdParty/Boost/src/libs/regex/src/c_regex_traits.cpp @@ -22,4 +22,5 @@ #include <boost/config.hpp> #include <boost/detail/workaround.hpp> +#include "internals.hpp" #if !BOOST_WORKAROUND(__BORLANDC__, < 0x560) @@ -54,4 +55,17 @@ c_regex_traits<char>::string_type BOOST_REGEX_CALL c_regex_traits<char>::transfo while(s < (r = std::strxfrm(&*result.begin(), src.c_str(), s))) { +#if defined(_CPPLIB_VER) + // + // A bug in VC11 and 12 causes the program to hang if we pass a null-string + // to std::strxfrm, but only for certain locales :-( + // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware). + // + if(r == INT_MAX) + { + result.erase(); + result.insert(result.begin(), static_cast<char>(0)); + return result; + } +#endif result.append(r - s + 3, ' '); s = result.size(); @@ -108,24 +122,4 @@ c_regex_traits<char>::string_type BOOST_REGEX_CALL c_regex_traits<char>::transfo } -enum -{ - char_class_space=1<<0, - char_class_print=1<<1, - char_class_cntrl=1<<2, - char_class_upper=1<<3, - char_class_lower=1<<4, - char_class_alpha=1<<5, - char_class_digit=1<<6, - char_class_punct=1<<7, - char_class_xdigit=1<<8, - char_class_alnum=char_class_alpha|char_class_digit, - char_class_graph=char_class_alnum|char_class_punct, - char_class_blank=1<<9, - char_class_word=1<<10, - char_class_unicode=1<<11, - char_class_horizontal=1<<12, - char_class_vertical=1<<13 -}; - c_regex_traits<char>::char_class_type BOOST_REGEX_CALL c_regex_traits<char>::lookup_classname(const char* p1, const char* p2) { diff --git a/3rdParty/Boost/src/libs/regex/src/cregex.cpp b/3rdParty/Boost/src/libs/regex/src/cregex.cpp index 5c27330..8d69139 100644 --- a/3rdParty/Boost/src/libs/regex/src/cregex.cpp +++ b/3rdParty/Boost/src/libs/regex/src/cregex.cpp @@ -362,9 +362,22 @@ void BuildFileList(std::list<std::string>* pl, const char* files, bool recurse) while(dstart != dend) { + // Verify that sprintf will not overflow: + if(std::strlen(dstart.path()) + std::strlen(directory_iterator::separator()) + std::strlen(ptr) >= MAX_PATH) + { + // Oops overflow, skip this item: + ++dstart; + continue; + } #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE) - (::sprintf_s)(buf, sizeof(buf), "%s%s%s", dstart.path(), directory_iterator::separator(), ptr); + int r = (::sprintf_s)(buf, sizeof(buf), "%s%s%s", dstart.path(), directory_iterator::separator(), ptr); #else - (std::sprintf)(buf, "%s%s%s", dstart.path(), directory_iterator::separator(), ptr); + int r = (std::sprintf)(buf, "%s%s%s", dstart.path(), directory_iterator::separator(), ptr); #endif + if(r < 0) + { + // sprintf failed, skip this item: + ++dstart; + continue; + } BuildFileList(pl, buf, recurse); ++dstart; diff --git a/3rdParty/Boost/src/libs/regex/src/fileiter.cpp b/3rdParty/Boost/src/libs/regex/src/fileiter.cpp index ff1d111..780a12f 100644 --- a/3rdParty/Boost/src/libs/regex/src/fileiter.cpp +++ b/3rdParty/Boost/src/libs/regex/src/fileiter.cpp @@ -20,4 +20,5 @@ #define BOOST_REGEX_SOURCE +#include <boost/config.hpp> #include <climits> #include <stdexcept> @@ -848,8 +849,14 @@ unsigned _fi_attributes(const char* root, const char* name) { char buf[MAX_PATH]; + // verify that we can not overflow: + if(std::strlen(root) + std::strlen(_fi_sep) + std::strlen(name) >= MAX_PATH) + return 0; + int r; if( ( (root[0] == *_fi_sep) || (root[0] == *_fi_sep_alt) ) && (root[1] == '\0') ) - (std::sprintf)(buf, "%s%s", root, name); + r = (std::sprintf)(buf, "%s%s", root, name); else - (std::sprintf)(buf, "%s%s%s", root, _fi_sep, name); + r = (std::sprintf)(buf, "%s%s%s", root, _fi_sep, name); + if(r < 0) + return 0; // sprintf failed DIR* d = opendir(buf); if(d) @@ -871,4 +878,5 @@ _fi_find_handle _fi_FindFirstFile(const char* lpFileName, _fi_find_data* lpFindF if(_fi_FindNextFile(dat, lpFindFileData)) return dat; + closedir(h); } delete dat; diff --git a/3rdParty/Boost/src/libs/regex/src/internals.hpp b/3rdParty/Boost/src/libs/regex/src/internals.hpp new file mode 100644 index 0000000..3a15cc6 --- /dev/null +++ b/3rdParty/Boost/src/libs/regex/src/internals.hpp @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2011 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#ifndef BOOST_REGEX_SRC_INTERNALS_HPP +#define BOOST_REGEX_SRC_INTERNALS_HPP + +enum +{ + char_class_space=1<<0, + char_class_print=1<<1, + char_class_cntrl=1<<2, + char_class_upper=1<<3, + char_class_lower=1<<4, + char_class_alpha=1<<5, + char_class_digit=1<<6, + char_class_punct=1<<7, + char_class_xdigit=1<<8, + char_class_alnum=char_class_alpha|char_class_digit, + char_class_graph=char_class_alnum|char_class_punct, + char_class_blank=1<<9, + char_class_word=1<<10, + char_class_unicode=1<<11, + char_class_horizontal=1<<12, + char_class_vertical=1<<13 +}; + +#endif // BOOST_REGEX_SRC_INTERNALS_HPP diff --git a/3rdParty/Boost/src/libs/regex/src/posix_api.cpp b/3rdParty/Boost/src/libs/regex/src/posix_api.cpp index 37ed422..8a803b3 100644 --- a/3rdParty/Boost/src/libs/regex/src/posix_api.cpp +++ b/3rdParty/Boost/src/libs/regex/src/posix_api.cpp @@ -19,4 +19,5 @@ #define BOOST_REGEX_SOURCE +#include <boost/config.hpp> #include <cstdio> #include <boost/regex.hpp> @@ -125,5 +126,5 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompA(regex_tA* expression, const char expression->re_magic = magic_value; static_cast<c_regex_type*>(expression->guts)->set_expression(ptr, p2, flags); - expression->re_nsub = static_cast<c_regex_type*>(expression->guts)->mark_count() - 1; + expression->re_nsub = static_cast<c_regex_type*>(expression->guts)->mark_count(); result = static_cast<c_regex_type*>(expression->guts)->error_code(); #ifndef BOOST_NO_EXCEPTIONS @@ -168,9 +169,15 @@ BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int code, const regex_tA* if(std::strcmp(e->re_endp, names[i]) == 0) { + // + // We're converting an integer i to a string, and since i <= REG_E_UNKNOWN + // a five character string is *always* large enough: + // #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE) - (::sprintf_s)(localbuf, 5, "%d", i); + int r = (::sprintf_s)(localbuf, 5, "%d", i); #else - (std::sprintf)(localbuf, "%d", i); + int r = (std::sprintf)(localbuf, "%d", i); #endif + if(r < 0) + return 0; // sprintf failed if(std::strlen(localbuf) < buf_size) re_detail::strcpy_s(buf, buf_size, localbuf); diff --git a/3rdParty/Boost/src/libs/regex/src/regex.cpp b/3rdParty/Boost/src/libs/regex/src/regex.cpp index 27ac43c..ea20a06 100644 --- a/3rdParty/Boost/src/libs/regex/src/regex.cpp +++ b/3rdParty/Boost/src/libs/regex/src/regex.cpp @@ -20,4 +20,5 @@ #define BOOST_REGEX_SOURCE +#include <boost/config.hpp> #include <new> #include <boost/regex.hpp> diff --git a/3rdParty/Boost/src/libs/regex/src/regex_raw_buffer.cpp b/3rdParty/Boost/src/libs/regex/src/regex_raw_buffer.cpp index 7a8de80..f75f0a5 100644 --- a/3rdParty/Boost/src/libs/regex/src/regex_raw_buffer.cpp +++ b/3rdParty/Boost/src/libs/regex/src/regex_raw_buffer.cpp @@ -19,4 +19,5 @@ #define BOOST_REGEX_SOURCE +#include <boost/config.hpp> #include <memory> #include <cstring> @@ -46,4 +47,5 @@ void BOOST_REGEX_CALL raw_storage::resize(size_type n) register pointer ptr = static_cast<pointer>(::operator new(newsize)); BOOST_REGEX_NOEH_ASSERT(ptr) + if(start) std::memcpy(ptr, start, datasize); diff --git a/3rdParty/Boost/src/libs/regex/src/static_mutex.cpp b/3rdParty/Boost/src/libs/regex/src/static_mutex.cpp index d14feb1..d02b01f 100644 --- a/3rdParty/Boost/src/libs/regex/src/static_mutex.cpp +++ b/3rdParty/Boost/src/libs/regex/src/static_mutex.cpp @@ -19,4 +19,5 @@ #define BOOST_REGEX_SOURCE #include <boost/config.hpp> +#include <boost/assert.hpp> #ifdef BOOST_HAS_THREADS @@ -55,6 +56,6 @@ void scoped_static_mutex_lock::lock() if(0 == m_have_lock) { - pthread_mutex_lock(&(m_mutex.m_mutex)); - m_have_lock = true; + // Client code will throw if this fails: + m_have_lock = (pthread_mutex_lock(&(m_mutex.m_mutex)) == 0); } } @@ -64,5 +65,8 @@ void scoped_static_mutex_lock::unlock() if(m_have_lock) { - pthread_mutex_unlock(&(m_mutex.m_mutex)); + // If this fails there's nothing we can do except assert, + // exceptions are out of the question as this code is called + // from the lock's destructor: + BOOST_VERIFY(pthread_mutex_unlock(&(m_mutex.m_mutex)) == 0); m_have_lock = false; } @@ -158,5 +162,5 @@ void scoped_static_mutex_lock::lock() boost::call_once(static_mutex::m_once,&static_mutex::init); if(0 == m_plock) - m_plock = new boost::recursive_mutex::scoped_lock(*static_mutex::m_pmutex, boost::defer_lock); + m_plock = new boost::unique_lock<boost::recursive_mutex>(*static_mutex::m_pmutex, boost::defer_lock); m_plock->lock(); m_have_lock = true; 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 8c22214..cf4dc10 100644 --- a/3rdParty/Boost/src/libs/regex/src/w32_regex_traits.cpp +++ b/3rdParty/Boost/src/libs/regex/src/w32_regex_traits.cpp @@ -284,7 +284,9 @@ BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, l return def; - LPSTR buf = (LPSTR)_alloca( (r + 1) * 2 ); - if (::WideCharToMultiByte(CP_ACP, 0, wbuf, r, buf, (r + 1) * 2, NULL, NULL) == 0) - return def; + + int buf_size = 1 + ::WideCharToMultiByte(CP_ACP, 0, wbuf, r, NULL, 0, NULL, NULL); + LPSTR buf = (LPSTR)_alloca(buf_size); + if (::WideCharToMultiByte(CP_ACP, 0, wbuf, r, buf, buf_size, NULL, NULL) == 0) + return def; // failed conversion. #endif return std::string(buf); @@ -486,5 +488,5 @@ BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_tolower(char c, lcid_type idx) if (::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0) - return c; + return c; // No single byte lower case equivalent available #endif return result[0]; @@ -557,5 +559,5 @@ BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_toupper(char c, lcid_type idx) if (::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0) - return c; + return c; // No single byte upper case equivalent available. #endif return result[0]; 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 a9e96d9..7815a09 100644 --- a/3rdParty/Boost/src/libs/regex/src/wc_regex_traits.cpp +++ b/3rdParty/Boost/src/libs/regex/src/wc_regex_traits.cpp @@ -23,4 +23,5 @@ #include <memory> #include <string> +#include "internals.hpp" #if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE) && defined(_NATIVE_WCHAR_T_DEFINED) \ @@ -94,4 +95,17 @@ c_regex_traits<wchar_t>::string_type BOOST_REGEX_CALL c_regex_traits<wchar_t>::t while(s < (r = std::wcsxfrm(&*result.begin(), src.c_str(), s))) { +#if defined(_CPPLIB_VER) + // + // A bug in VC11 and 12 causes the program to hang if we pass a null-string + // to std::strxfrm, but only for certain locales :-( + // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware). + // + if(r == INT_MAX) + { + result.erase(); + result.insert(result.begin(), static_cast<wchar_t>(0)); + return result; + } +#endif result.append(r - s + 3, L' '); s = result.size(); @@ -148,24 +162,4 @@ c_regex_traits<wchar_t>::string_type BOOST_REGEX_CALL c_regex_traits<wchar_t>::t } -enum -{ - char_class_space=1<<0, - char_class_print=1<<1, - char_class_cntrl=1<<2, - char_class_upper=1<<3, - char_class_lower=1<<4, - char_class_alpha=1<<5, - char_class_digit=1<<6, - char_class_punct=1<<7, - char_class_xdigit=1<<8, - char_class_alnum=char_class_alpha|char_class_digit, - char_class_graph=char_class_alnum|char_class_punct, - char_class_blank=1<<9, - char_class_word=1<<10, - char_class_unicode=1<<11, - char_class_horizontal=1<<12, - char_class_vertical=1<<13 -}; - c_regex_traits<wchar_t>::char_class_type BOOST_REGEX_CALL c_regex_traits<wchar_t>::lookup_classname(const wchar_t* p1, const wchar_t* p2) { 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 3c693c6..41704cd 100644 --- a/3rdParty/Boost/src/libs/regex/src/wide_posix_api.cpp +++ b/3rdParty/Boost/src/libs/regex/src/wide_posix_api.cpp @@ -75,5 +75,5 @@ const wchar_t* wnames[] = { } -typedef boost::basic_regex<wchar_t, c_regex_traits<wchar_t> > c_regex_type; +typedef boost::basic_regex<wchar_t, c_regex_traits<wchar_t> > wc_regex_type; BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wchar_t* ptr, int f) @@ -85,5 +85,5 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wcha try{ #endif - expression->guts = new c_regex_type(); + expression->guts = new wc_regex_type(); #ifndef BOOST_NO_EXCEPTIONS } catch(...) @@ -135,7 +135,7 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wcha #endif expression->re_magic = wmagic_value; - static_cast<c_regex_type*>(expression->guts)->set_expression(ptr, p2, flags); - expression->re_nsub = static_cast<c_regex_type*>(expression->guts)->mark_count() - 1; - result = static_cast<c_regex_type*>(expression->guts)->error_code(); + static_cast<wc_regex_type*>(expression->guts)->set_expression(ptr, p2, flags); + expression->re_nsub = static_cast<wc_regex_type*>(expression->guts)->mark_count(); + result = static_cast<wc_regex_type*>(expression->guts)->error_code(); #ifndef BOOST_NO_EXCEPTIONS } @@ -216,5 +216,5 @@ BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorW(int code, const regex_tW* std::string p; if((e) && (e->re_magic == wmagic_value)) - p = static_cast<c_regex_type*>(e->guts)->get_traits().error_string(static_cast< ::boost::regex_constants::error_type>(code)); + p = static_cast<wc_regex_type*>(e->guts)->get_traits().error_string(static_cast< ::boost::regex_constants::error_type>(code)); else { @@ -265,5 +265,5 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecW(const regex_tW* expression, cons if(expression->re_magic == wmagic_value) { - result = regex_search(start, end, m, *static_cast<c_regex_type*>(expression->guts), flags); + result = regex_search(start, end, m, *static_cast<wc_regex_type*>(expression->guts), flags); } else @@ -302,5 +302,5 @@ BOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeW(regex_tW* expression) if(expression->re_magic == wmagic_value) { - delete static_cast<c_regex_type*>(expression->guts); + delete static_cast<wc_regex_type*>(expression->guts); } expression->re_magic = 0; diff --git a/3rdParty/Boost/src/libs/serialization/src/archive_exception.cpp b/3rdParty/Boost/src/libs/serialization/src/archive_exception.cpp new file mode 100644 index 0000000..d06303f --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/archive_exception.cpp @@ -0,0 +1,127 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// archive_exception.cpp: + +// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#include <exception> +//#include <boost/assert.hpp> +#include <string> + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/archive_exception.hpp> + +namespace boost { +namespace archive { + +unsigned int +archive_exception::append(unsigned int l, const char * a){ + while(l < (sizeof(m_buffer) - 1)){ + char c = *a++; + if('\0' == c) + break; + m_buffer[l++] = c; + } + m_buffer[l] = '\0'; + return l; +} + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +archive_exception::archive_exception( + exception_code c, + const char * e1, + const char * e2 +) : + code(c) +{ + unsigned int length = 0; + switch(code){ + case no_exception: + length = append(length, "uninitialized exception"); + break; + case unregistered_class: + length = append(length, "unregistered class"); + if(NULL != e1){ + length = append(length, " - "); + length = append(length, e1); + } + break; + case invalid_signature: + length = append(length, "invalid signature"); + break; + case unsupported_version: + length = append(length, "unsupported version"); + break; + case pointer_conflict: + length = append(length, "pointer conflict"); + break; + case incompatible_native_format: + length = append(length, "incompatible native format"); + if(NULL != e1){ + length = append(length, " - "); + length = append(length, e1); + } + break; + case array_size_too_short: + length = append(length, "array size too short"); + break; + case input_stream_error: + length = append(length, "input stream error"); + break; + case invalid_class_name: + length = append(length, "class name too long"); + break; + case unregistered_cast: + length = append(length, "unregistered void cast "); + length = append(length, (NULL != e1) ? e1 : "?"); + length = append(length, "<-"); + length = append(length, (NULL != e2) ? e2 : "?"); + break; + case unsupported_class_version: + length = append(length, "class version "); + length = append(length, (NULL != e1) ? e1 : "<unknown class>"); + break; + case other_exception: + // if get here - it indicates a derived exception + // was sliced by passing by value in catch + length = append(length, "unknown derived exception"); + break; + case multiple_code_instantiation: + length = append(length, "code instantiated in more than one module"); + if(NULL != e1){ + length = append(length, " - "); + length = append(length, e1); + } + break; + case output_stream_error: + length = append(length, "output stream error"); + break; + default: + BOOST_ASSERT(false); + length = append(length, "programming error"); + break; + } +} +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +archive_exception::~archive_exception() throw() {} + +BOOST_ARCHIVE_DECL(const char *) +archive_exception::what( ) const throw() +{ + return m_buffer; +} +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +archive_exception::archive_exception() : + code(no_exception) +{} + +} // archive +} // boost diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_archive.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_archive.cpp new file mode 100644 index 0000000..8baf178 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_archive.cpp @@ -0,0 +1,81 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_archive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +////////////////////////////////////////////////////////////////////// +// +// objects are stored as +// +// class_id* // -1 for a null pointer +// if a new class id +// [ +// exported key - class name* +// tracking level - always/never +// class version +// ] +// +// if tracking +// [ +// object_id +// ] +// +// [ // if a new object id +// data... +// ] +// +// * required only for pointers - optional for objects + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/basic_archive.hpp> + +namespace boost { +namespace archive { + +/////////////////////////////////////////////////////////////////////// +// constants used in archive signature +//This should never ever change. note that is not an std::string +// string. +BOOST_ARCHIVE_DECL(const char *) +BOOST_ARCHIVE_SIGNATURE(){ + return "serialization::archive"; +} + +// this should change if the capabilities are added to the library +// such that archives can be created which can't be read by previous +// versions of this library +// 1 - initial version +// 2 - made address tracking optional +// 3 - numerous changes - can't guarentee compatibility with previous versions +// 4 - Boost 1.34 +// added item_version to properly support versioning for collections +// 5 - Boost 1.36 +// changed serialization of collections: adding version even for primitive +// types caused backwards compatibility breaking change in 1.35 +// 6 - Boost 1.41 17 Nov 2009 +// serializing collection sizes as std::size_t +// 7 Boost 1.42 2 Feb 2010 +// error - changed binary version to 16 bits w/o changing library version # +// That is - binary archives are recorded with #6 even though they are +// different from the previous versions. This means that binary archives +// created with versions 1.42 and 1.43 will have to be fixed with a special +// program which fixes the library version # in the header +// Boost 1.43 6 May 2010 +// no change +// 8 - Boost 1.44 +// separated version_type into library_version_type and class_version_type +// changed version_type to be stored as 8 bits. +// 10- fixed base64 output/input. + +BOOST_ARCHIVE_DECL(library_version_type) +BOOST_ARCHIVE_VERSION(){ + return library_version_type(11); +} + +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_iarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_iarchive.cpp new file mode 100644 index 0000000..3a24690 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_iarchive.cpp @@ -0,0 +1,596 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_archive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> // msvc 6.0 needs this to suppress warnings + +#include <boost/assert.hpp> +#include <set> +#include <list> +#include <vector> +#include <cstddef> // size_t, NULL + +#include <boost/config.hpp> +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include <boost/integer_traits.hpp> +#include <boost/serialization/state_saver.hpp> +#include <boost/serialization/throw_exception.hpp> +#include <boost/serialization/tracking.hpp> + +#define BOOST_ARCHIVE_SOURCE +// include this to prevent linker errors when the +// same modules are marked export and import. +#define BOOST_SERIALIZATION_SOURCE + +#include <boost/archive/archive_exception.hpp> + +#include <boost/archive/detail/decl.hpp> +#include <boost/archive/basic_archive.hpp> +#include <boost/archive/detail/basic_iserializer.hpp> +#include <boost/archive/detail/basic_pointer_iserializer.hpp> +#include <boost/archive/detail/basic_iarchive.hpp> + +#include <boost/archive/detail/auto_link_archive.hpp> + +using namespace boost::serialization; + +namespace boost { +namespace archive { +namespace detail { + +class basic_iarchive_impl { + friend class basic_iarchive; + library_version_type m_archive_library_version; + unsigned int m_flags; + + ////////////////////////////////////////////////////////////////////// + // information about each serialized object loaded + // indexed on object_id + struct aobject + { + void * address; + bool loaded_as_pointer; + class_id_type class_id; + aobject( + void *a, + class_id_type class_id_ + ) : + address(a), + loaded_as_pointer(false), + class_id(class_id_) + {} + aobject() : + address(NULL), + loaded_as_pointer(false), + class_id(-2) + {} + }; + typedef std::vector<aobject> object_id_vector_type; + object_id_vector_type object_id_vector; + + ////////////////////////////////////////////////////////////////////// + // used to implement the reset_object_address operation. + struct moveable_objects { + object_id_type start; + object_id_type end; + object_id_type recent; + bool is_pointer; + moveable_objects() : + start(0), + end(0), + recent(0), + is_pointer(false) + {} + } m_moveable_objects; + + void reset_object_address( + const void * new_address, + const void *old_address + ); + + ////////////////////////////////////////////////////////////////////// + // used by load object to look up class id given basic_serializer + struct cobject_type + { + const basic_iserializer * m_bis; + const class_id_type m_class_id; + cobject_type( + std::size_t class_id, + const basic_iserializer & bis + ) : + m_bis(& bis), + m_class_id(class_id) + {} + cobject_type(const cobject_type & rhs) : + m_bis(rhs.m_bis), + m_class_id(rhs.m_class_id) + {} + // the following cannot be defined because of the const + // member. This will generate a link error if an attempt + // is made to assign. This should never be necessary + cobject_type & operator=(const cobject_type & rhs); + bool operator<(const cobject_type &rhs) const + { + return *m_bis < *(rhs.m_bis); + } + }; + typedef std::set<cobject_type> cobject_info_set_type; + cobject_info_set_type cobject_info_set; + + ////////////////////////////////////////////////////////////////////// + // information about each serialized class indexed on class_id + class cobject_id + { + public: + cobject_id & operator=(const cobject_id & rhs){ + bis_ptr = rhs.bis_ptr; + bpis_ptr = rhs.bpis_ptr; + file_version = rhs.file_version; + tracking_level = rhs.tracking_level; + initialized = rhs.initialized; + return *this; + } + const basic_iserializer * bis_ptr; + const basic_pointer_iserializer * bpis_ptr; + version_type file_version; + tracking_type tracking_level; + bool initialized; + + cobject_id(const basic_iserializer & bis_) : + bis_ptr(& bis_), + bpis_ptr(NULL), + file_version(0), + tracking_level(track_never), + initialized(false) + {} + cobject_id(const cobject_id &rhs): + bis_ptr(rhs.bis_ptr), + bpis_ptr(rhs.bpis_ptr), + file_version(rhs.file_version), + tracking_level(rhs.tracking_level), + initialized(rhs.initialized) + {} + }; + typedef std::vector<cobject_id> cobject_id_vector_type; + cobject_id_vector_type cobject_id_vector; + + ////////////////////////////////////////////////////////////////////// + // address of the most recent object serialized as a poiner + // whose data itself is now pending serialization + struct pending { + void * object; + const basic_iserializer * bis; + version_type version; + pending() : + object(NULL), + bis(NULL), + version(0) + {} + } m_pending; + + basic_iarchive_impl(unsigned int flags) : + m_archive_library_version(BOOST_ARCHIVE_VERSION()), + m_flags(flags) + {} + ~basic_iarchive_impl(){} + void set_library_version(library_version_type archive_library_version){ + m_archive_library_version = archive_library_version; + } + bool + track( + basic_iarchive & ar, + void * & t + ); + void + load_preamble( + basic_iarchive & ar, + cobject_id & co + ); + class_id_type register_type( + const basic_iserializer & bis + ); + + // redirect through virtual functions to load functions for this archive + template<class T> + void load(basic_iarchive & ar, T & t){ + ar.vload(t); + } + +//public: + void + next_object_pointer(void * t){ + m_pending.object = t; + } + void delete_created_pointers(); + class_id_type register_type( + const basic_pointer_iserializer & bpis + ); + void load_object( + basic_iarchive & ar, + void * t, + const basic_iserializer & bis + ); + const basic_pointer_iserializer * load_pointer( + basic_iarchive & ar, + void * & t, + const basic_pointer_iserializer * bpis, + const basic_pointer_iserializer * (*finder)( + const boost::serialization::extended_type_info & type + ) + + ); +}; + +inline void +basic_iarchive_impl::reset_object_address( + void const * const new_address, + void const * const old_address +){ + if(m_moveable_objects.is_pointer) + return; + + // this code handles a couple of situations. + // a) where reset_object_address is applied to an untracked object. + // In such a case the call is really superfluous and its really an + // an error. But we don't have access to the types here so we can't + // know that. However, this code will effectively turn this situation + // into a no-op and every thing will work fine - albeat with a small + // execution time penalty. + // b) where the call to reset_object_address doesn't immediatly follow + // the << operator to which it corresponds. This would be a bad idea + // but the code may work anyway. Naturally, a bad practice on the part + // of the programmer but we can't detect it - as above. So maybe we + // can save a few more people from themselves as above. + object_id_type i; + for(i = m_moveable_objects.recent; i < m_moveable_objects.end; ++i){ + if(old_address == object_id_vector[i].address) + break; + } + for(; i < m_moveable_objects.end; ++i){ + void const * const this_address = object_id_vector[i].address; + // calculate displacement from this level + // warning - pointer arithmetic on void * is in herently non-portable + // but expected to work on all platforms in current usage + if(this_address > old_address){ + std::size_t member_displacement + = reinterpret_cast<std::size_t>(this_address) + - reinterpret_cast<std::size_t>(old_address); + object_id_vector[i].address = reinterpret_cast<void *>( + reinterpret_cast<std::size_t>(new_address) + member_displacement + ); + } + else{ + std::size_t member_displacement + = reinterpret_cast<std::size_t>(old_address) + - reinterpret_cast<std::size_t>(this_address); + object_id_vector[i].address = reinterpret_cast<void *>( + reinterpret_cast<std::size_t>(new_address) - member_displacement + ); + } + } +} + +inline void +basic_iarchive_impl::delete_created_pointers() +{ + object_id_vector_type::iterator i; + for( + i = object_id_vector.begin(); + i != object_id_vector.end(); + ++i + ){ + if(i->loaded_as_pointer){ + // borland complains without this minor hack + const int j = i->class_id; + const cobject_id & co = cobject_id_vector[j]; + //const cobject_id & co = cobject_id_vector[i->class_id]; + // with the appropriate input serializer, + // delete the indicated object + co.bis_ptr->destroy(i->address); + } + } +} + +inline class_id_type +basic_iarchive_impl::register_type( + const basic_iserializer & bis +){ + class_id_type cid(cobject_info_set.size()); + cobject_type co(cid, bis); + std::pair<cobject_info_set_type::const_iterator, bool> + result = cobject_info_set.insert(co); + + if(result.second){ + cobject_id_vector.push_back(cobject_id(bis)); + BOOST_ASSERT(cobject_info_set.size() == cobject_id_vector.size()); + } + cid = result.first->m_class_id; + // borland complains without this minor hack + const int tid = cid; + cobject_id & coid = cobject_id_vector[tid]; + coid.bpis_ptr = bis.get_bpis_ptr(); + return cid; +} + +void +basic_iarchive_impl::load_preamble( + basic_iarchive & ar, + cobject_id & co +){ + if(! co.initialized){ + if(co.bis_ptr->class_info()){ + class_id_optional_type cid(class_id_type(0)); + load(ar, cid); // to be thrown away + load(ar, co.tracking_level); + load(ar, co.file_version); + } + else{ + // override tracking with indicator from class information + co.tracking_level = co.bis_ptr->tracking(m_flags); + co.file_version = version_type( + co.bis_ptr->version() + ); + } + co.initialized = true; + } +} + +bool +basic_iarchive_impl::track( + basic_iarchive & ar, + void * & t +){ + object_id_type oid; + load(ar, oid); + + // if its a reference to a old object + if(object_id_type(object_id_vector.size()) > oid){ + // we're done + t = object_id_vector[oid].address; + return false; + } + return true; +} + +inline void +basic_iarchive_impl::load_object( + basic_iarchive & ar, + void * t, + const basic_iserializer & bis +){ + m_moveable_objects.is_pointer = false; + serialization::state_saver<bool> ss_is_pointer(m_moveable_objects.is_pointer); + // if its been serialized through a pointer and the preamble's been done + if(t == m_pending.object && & bis == m_pending.bis){ + // read data + (bis.load_object_data)(ar, t, m_pending.version); + return; + } + + const class_id_type cid = register_type(bis); + const int i = cid; + cobject_id & co = cobject_id_vector[i]; + + load_preamble(ar, co); + + // save the current move stack position in case we want to truncate it + boost::serialization::state_saver<object_id_type> ss_start(m_moveable_objects.start); + + // note: extra line used to evade borland issue + const bool tracking = co.tracking_level; + + object_id_type this_id; + m_moveable_objects.start = + this_id = object_id_type(object_id_vector.size()); + + // if we tracked this object when the archive was saved + if(tracking){ + // if it was already read + if(!track(ar, t)) + // we're done + return; + // add a new enty into the tracking list + object_id_vector.push_back(aobject(t, cid)); + // and add an entry for this object + m_moveable_objects.end = object_id_type(object_id_vector.size()); + } + // read data + (bis.load_object_data)(ar, t, co.file_version); + m_moveable_objects.recent = this_id; +} + +inline const basic_pointer_iserializer * +basic_iarchive_impl::load_pointer( + basic_iarchive &ar, + void * & t, + const basic_pointer_iserializer * bpis_ptr, + const basic_pointer_iserializer * (*finder)( + const boost::serialization::extended_type_info & type_ + ) +){ + m_moveable_objects.is_pointer = true; + serialization::state_saver<bool> w(m_moveable_objects.is_pointer); + + class_id_type cid; + load(ar, cid); + + if(NULL_POINTER_TAG == cid){ + t = NULL; + return bpis_ptr; + } + + // if its a new class type - i.e. never been registered + if(class_id_type(cobject_info_set.size()) <= cid){ + // if its either abstract + if(NULL == bpis_ptr + // or polymorphic + || bpis_ptr->get_basic_serializer().is_polymorphic()){ + // is must have been exported + char key[BOOST_SERIALIZATION_MAX_KEY_SIZE]; + class_name_type class_name(key); + load(ar, class_name); + // if it has a class name + const serialization::extended_type_info *eti = NULL; + if(0 != key[0]) + eti = serialization::extended_type_info::find(key); + if(NULL == eti) + boost::serialization::throw_exception( + archive_exception(archive_exception::unregistered_class) + ); + bpis_ptr = (*finder)(*eti); + } + BOOST_ASSERT(NULL != bpis_ptr); + // class_id_type new_cid = register_type(bpis_ptr->get_basic_serializer()); + BOOST_VERIFY(register_type(bpis_ptr->get_basic_serializer()) == cid); + int i = cid; + cobject_id_vector[i].bpis_ptr = bpis_ptr; + } + int i = cid; + cobject_id & co = cobject_id_vector[i]; + bpis_ptr = co.bpis_ptr; + + load_preamble(ar, co); + + // extra line to evade borland issue + const bool tracking = co.tracking_level; + // if we're tracking and the pointer has already been read + if(tracking && ! track(ar, t)) + // we're done + return bpis_ptr; + + // save state + serialization::state_saver<object_id_type> w_start(m_moveable_objects.start); + + // allocate space on the heap for the object - to be constructed later + t = bpis_ptr->heap_allocation(); + BOOST_ASSERT(NULL != t); + + if(! tracking){ + bpis_ptr->load_object_ptr(ar, t, co.file_version); + } + else{ + serialization::state_saver<void *> x(m_pending.object); + serialization::state_saver<const basic_iserializer *> y(m_pending.bis); + serialization::state_saver<version_type> z(m_pending.version); + + m_pending.bis = & bpis_ptr->get_basic_serializer(); + m_pending.version = co.file_version; + + // predict next object id to be created + const unsigned int ui = object_id_vector.size(); + + serialization::state_saver<object_id_type> w_end(m_moveable_objects.end); + + + // add to list of serialized objects so that we can properly handle + // cyclic strucures + object_id_vector.push_back(aobject(t, cid)); + + // remember that that the address of these elements could change + // when we make another call so don't use the address + bpis_ptr->load_object_ptr( + ar, + t, + m_pending.version + ); + object_id_vector[ui].loaded_as_pointer = true; + } + + return bpis_ptr; +} + +} // namespace detail +} // namespace archive +} // namespace boost + +////////////////////////////////////////////////////////////////////// +// implementation of basic_iarchive functions +namespace boost { +namespace archive { +namespace detail { + +BOOST_ARCHIVE_DECL(void) +basic_iarchive::next_object_pointer(void *t){ + pimpl->next_object_pointer(t); +} + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_iarchive::basic_iarchive(unsigned int flags) : + pimpl(new basic_iarchive_impl(flags)) +{} + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_iarchive::~basic_iarchive() +{ + delete pimpl; +} + +BOOST_ARCHIVE_DECL(void) +basic_iarchive::set_library_version(library_version_type archive_library_version){ + pimpl->set_library_version(archive_library_version); +} + +BOOST_ARCHIVE_DECL(void) +basic_iarchive::reset_object_address( + const void * new_address, + const void * old_address +){ + pimpl->reset_object_address(new_address, old_address); +} + +BOOST_ARCHIVE_DECL(void) +basic_iarchive::load_object( + void *t, + const basic_iserializer & bis +){ + pimpl->load_object(*this, t, bis); +} + +// load a pointer object +BOOST_ARCHIVE_DECL(const basic_pointer_iserializer *) +basic_iarchive::load_pointer( + void * &t, + const basic_pointer_iserializer * bpis_ptr, + const basic_pointer_iserializer * (*finder)( + const boost::serialization::extended_type_info & type_ + ) + +){ + return pimpl->load_pointer(*this, t, bpis_ptr, finder); +} + +BOOST_ARCHIVE_DECL(void) +basic_iarchive::register_basic_serializer(const basic_iserializer & bis){ + pimpl->register_type(bis); +} + +BOOST_ARCHIVE_DECL(void) +basic_iarchive::delete_created_pointers() +{ + pimpl->delete_created_pointers(); +} + +BOOST_ARCHIVE_DECL(boost::archive::library_version_type) +basic_iarchive::get_library_version() const{ + return pimpl->m_archive_library_version; +} + +BOOST_ARCHIVE_DECL(unsigned int) +basic_iarchive::get_flags() const{ + return pimpl->m_flags; +} + +} // namespace detail +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_iserializer.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_iserializer.cpp new file mode 100644 index 0000000..e18e16f --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_iserializer.cpp @@ -0,0 +1,33 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_iserializer.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <cstddef> // NULL + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/detail/basic_iserializer.hpp> + +namespace boost { +namespace archive { +namespace detail { + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_iserializer::basic_iserializer( + const boost::serialization::extended_type_info & eti +) : + basic_serializer(eti), + m_bpis(NULL) +{} + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_iserializer::~basic_iserializer(){} + +} // namespace detail +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_oarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_oarchive.cpp new file mode 100644 index 0000000..840955b --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_oarchive.cpp @@ -0,0 +1,465 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_oarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> // msvc 6.0 needs this for warning suppression + +#include <boost/assert.hpp> +#include <set> +#include <cstddef> // NULL + +#include <boost/limits.hpp> +#include <boost/serialization/state_saver.hpp> +#include <boost/serialization/throw_exception.hpp> + +// including this here to work around an ICC in intel 7.0 +// normally this would be part of basic_oarchive.hpp below. +#define BOOST_ARCHIVE_SOURCE +// include this to prevent linker errors when the +// same modules are marked export and import. +#define BOOST_SERIALIZATION_SOURCE + +#include <boost/archive/detail/decl.hpp> +#include <boost/archive/basic_archive.hpp> +#include <boost/archive/detail/basic_oserializer.hpp> +#include <boost/archive/detail/basic_pointer_oserializer.hpp> +#include <boost/archive/detail/basic_oarchive.hpp> +#include <boost/archive/archive_exception.hpp> +#include <boost/serialization/extended_type_info.hpp> + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275) +#endif + +using namespace boost::serialization; + +namespace boost { +namespace archive { +namespace detail { + +class basic_oarchive_impl { + friend class basic_oarchive; + unsigned int m_flags; + + ////////////////////////////////////////////////////////////////////// + // information about each serialized object saved + // keyed on address, class_id + struct aobject + { + const void * address; + class_id_type class_id; + object_id_type object_id; + + bool operator<(const aobject &rhs) const + { + BOOST_ASSERT(NULL != address); + BOOST_ASSERT(NULL != rhs.address); + if( address < rhs.address ) + return true; + if( address > rhs.address ) + return false; + return class_id < rhs.class_id; + } + aobject & operator=(const aobject & rhs) + { + address = rhs.address; + class_id = rhs.class_id; + object_id = rhs.object_id; + return *this; + } + aobject( + const void *a, + class_id_type class_id_, + object_id_type object_id_ + ) : + address(a), + class_id(class_id_), + object_id(object_id_) + {} + aobject() : address(NULL){} + }; + // keyed on class_id, address + typedef std::set<aobject> object_set_type; + object_set_type object_set; + + ////////////////////////////////////////////////////////////////////// + // information about each serialized class saved + // keyed on type_info + struct cobject_type + { + const basic_oserializer * m_bos_ptr; + const class_id_type m_class_id; + bool m_initialized; + cobject_type( + std::size_t class_id, + const basic_oserializer & bos + ) : + m_bos_ptr(& bos), + m_class_id(class_id), + m_initialized(false) + {} + cobject_type(const basic_oserializer & bos) + : m_bos_ptr(& bos) + {} + cobject_type( + const cobject_type & rhs + ) : + m_bos_ptr(rhs.m_bos_ptr), + m_class_id(rhs.m_class_id), + m_initialized(rhs.m_initialized) + {} + // the following cannot be defined because of the const + // member. This will generate a link error if an attempt + // is made to assign. This should never be necessary + // use this only for lookup argument + cobject_type & operator=(const cobject_type &rhs); + bool operator<(const cobject_type &rhs) const { + return *m_bos_ptr < *(rhs.m_bos_ptr); + } + }; + // keyed on type_info + typedef std::set<cobject_type> cobject_info_set_type; + cobject_info_set_type cobject_info_set; + + // list of objects initially stored as pointers - used to detect errors + // keyed on object id + std::set<object_id_type> stored_pointers; + + // address of the most recent object serialized as a poiner + // whose data itself is now pending serialization + const void * pending_object; + const basic_oserializer * pending_bos; + + basic_oarchive_impl(unsigned int flags) : + m_flags(flags), + pending_object(NULL), + pending_bos(NULL) + {} + + const cobject_type & + find(const basic_oserializer & bos); + const basic_oserializer * + find(const serialization::extended_type_info &ti) const; + +//public: + const cobject_type & + register_type(const basic_oserializer & bos); + void save_object( + basic_oarchive & ar, + const void *t, + const basic_oserializer & bos + ); + void save_pointer( + basic_oarchive & ar, + const void * t, + const basic_pointer_oserializer * bpos + ); +}; + +////////////////////////////////////////////////////////////////////// +// basic_oarchive implementation functions + +// given a type_info - find its bos +// return NULL if not found +inline const basic_oserializer * +basic_oarchive_impl::find(const serialization::extended_type_info & ti) const { + #ifdef BOOST_MSVC + # pragma warning(push) + # pragma warning(disable : 4511 4512) + #endif + class bosarg : + public basic_oserializer + { + bool class_info() const { + BOOST_ASSERT(false); + return false; + } + // returns true if objects should be tracked + bool tracking(const unsigned int) const { + BOOST_ASSERT(false); + return false; + } + // returns class version + version_type version() const { + BOOST_ASSERT(false); + return version_type(0); + } + // returns true if this class is polymorphic + bool is_polymorphic() const{ + BOOST_ASSERT(false); + return false; + } + void save_object_data( + basic_oarchive & /*ar*/, const void * /*x*/ + ) const { + BOOST_ASSERT(false); + } + public: + bosarg(const serialization::extended_type_info & eti) : + boost::archive::detail::basic_oserializer(eti) + {} + }; + #ifdef BOOST_MSVC + #pragma warning(pop) + #endif + bosarg bos(ti); + cobject_info_set_type::const_iterator cit + = cobject_info_set.find(cobject_type(bos)); + // it should already have been "registered" - see below + if(cit == cobject_info_set.end()){ + // if an entry is not found in the table it is because a pointer + // of a derived class has been serialized through its base class + // but the derived class hasn't been "registered" + return NULL; + } + // return pointer to the real class + return cit->m_bos_ptr; +} + +inline const basic_oarchive_impl::cobject_type & +basic_oarchive_impl::find(const basic_oserializer & bos) +{ + std::pair<cobject_info_set_type::iterator, bool> cresult = + cobject_info_set.insert(cobject_type(cobject_info_set.size(), bos)); + return *(cresult.first); +} + +inline const basic_oarchive_impl::cobject_type & +basic_oarchive_impl::register_type( + const basic_oserializer & bos +){ + cobject_type co(cobject_info_set.size(), bos); + std::pair<cobject_info_set_type::const_iterator, bool> + result = cobject_info_set.insert(co); + return *(result.first); +} + +inline void +basic_oarchive_impl::save_object( + basic_oarchive & ar, + const void *t, + const basic_oserializer & bos +){ + // if its been serialized through a pointer and the preamble's been done + if(t == pending_object && pending_bos == & bos){ + // just save the object data + ar.end_preamble(); + (bos.save_object_data)(ar, t); + return; + } + + // get class information for this object + const cobject_type & co = register_type(bos); + if(bos.class_info()){ + if( ! co.m_initialized){ + ar.vsave(class_id_optional_type(co.m_class_id)); + ar.vsave(tracking_type(bos.tracking(m_flags))); + ar.vsave(version_type(bos.version())); + (const_cast<cobject_type &>(co)).m_initialized = true; + } + } + + // we're not tracking this type of object + if(! bos.tracking(m_flags)){ + // just windup the preamble - no object id to write + ar.end_preamble(); + // and save the data + (bos.save_object_data)(ar, t); + return; + } + + // look for an existing object id + object_id_type oid(object_set.size()); + // lookup to see if this object has already been written to the archive + basic_oarchive_impl::aobject ao(t, co.m_class_id, oid); + std::pair<basic_oarchive_impl::object_set_type::const_iterator, bool> + aresult = object_set.insert(ao); + oid = aresult.first->object_id; + + // if its a new object + if(aresult.second){ + // write out the object id + ar.vsave(oid); + ar.end_preamble(); + // and data + (bos.save_object_data)(ar, t); + return; + } + + // check that it wasn't originally stored through a pointer + if(stored_pointers.end() != stored_pointers.find(oid)){ + // this has to be a user error. loading such an archive + // would create duplicate objects + boost::serialization::throw_exception( + archive_exception(archive_exception::pointer_conflict) + ); + } + // just save the object id + ar.vsave(object_reference_type(oid)); + ar.end_preamble(); + return; +} + +// save a pointer to an object instance +inline void +basic_oarchive_impl::save_pointer( + basic_oarchive & ar, + const void * t, + const basic_pointer_oserializer * bpos_ptr +){ + const basic_oserializer & bos = bpos_ptr->get_basic_serializer(); + std::size_t original_count = cobject_info_set.size(); + const cobject_type & co = register_type(bos); + if(! co.m_initialized){ + ar.vsave(co.m_class_id); + // if its a previously unregistered class + if((cobject_info_set.size() > original_count)){ + if(bos.is_polymorphic()){ + const serialization::extended_type_info *eti = & bos.get_eti(); + const char * key = NULL; + if(NULL != eti) + key = eti->get_key(); + if(NULL != key){ + // the following is required by IBM C++ compiler which + // makes a copy when passing a non-const to a const. This + // is permitted by the standard but rarely seen in practice + const class_name_type cn(key); + if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) + boost::serialization::throw_exception( + boost::archive::archive_exception( + boost::archive::archive_exception:: + invalid_class_name) + ); + // write out the external class identifier + ar.vsave(cn); + } + else + // without an external class name + // we won't be able to de-serialize it so bail now + boost::serialization::throw_exception( + archive_exception(archive_exception::unregistered_class) + ); + } + } + if(bos.class_info()){ + ar.vsave(tracking_type(bos.tracking(m_flags))); + ar.vsave(version_type(bos.version())); + } + (const_cast<cobject_type &>(co)).m_initialized = true; + } + else{ + ar.vsave(class_id_reference_type(co.m_class_id)); + } + + // if we're not tracking + if(! bos.tracking(m_flags)){ + // just save the data itself + ar.end_preamble(); + serialization::state_saver<const void *> x(pending_object); + serialization::state_saver<const basic_oserializer *> y(pending_bos); + pending_object = t; + pending_bos = & bpos_ptr->get_basic_serializer(); + bpos_ptr->save_object_ptr(ar, t); + return; + } + + object_id_type oid(object_set.size()); + // lookup to see if this object has already been written to the archive + basic_oarchive_impl::aobject ao(t, co.m_class_id, oid); + std::pair<basic_oarchive_impl::object_set_type::const_iterator, bool> + aresult = object_set.insert(ao); + oid = aresult.first->object_id; + // if the saved object already exists + if(! aresult.second){ + // append the object id to he preamble + ar.vsave(object_reference_type(oid)); + // and windup. + ar.end_preamble(); + return; + } + + // append id of this object to preamble + ar.vsave(oid); + ar.end_preamble(); + + // and save the object itself + serialization::state_saver<const void *> x(pending_object); + serialization::state_saver<const basic_oserializer *> y(pending_bos); + pending_object = t; + pending_bos = & bpos_ptr->get_basic_serializer(); + bpos_ptr->save_object_ptr(ar, t); + // add to the set of object initially stored through pointers + stored_pointers.insert(oid); +} + +} // namespace detail +} // namespace archive +} // namespace boost + +////////////////////////////////////////////////////////////////////// +// implementation of basic_oarchive functions + +namespace boost { +namespace archive { +namespace detail { + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_oarchive::basic_oarchive(unsigned int flags) + : pimpl(new basic_oarchive_impl(flags)) +{} + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_oarchive::~basic_oarchive() +{ + delete pimpl; +} + +BOOST_ARCHIVE_DECL(void) +basic_oarchive::save_object( + const void *x, + const basic_oserializer & bos +){ + pimpl->save_object(*this, x, bos); +} + +BOOST_ARCHIVE_DECL(void) +basic_oarchive::save_pointer( + const void * t, + const basic_pointer_oserializer * bpos_ptr +){ + pimpl->save_pointer(*this, t, bpos_ptr); +} + +BOOST_ARCHIVE_DECL(void) +basic_oarchive::register_basic_serializer(const basic_oserializer & bos){ + pimpl->register_type(bos); +} + +BOOST_ARCHIVE_DECL(library_version_type) +basic_oarchive::get_library_version() const{ + return BOOST_ARCHIVE_VERSION(); +} + +BOOST_ARCHIVE_DECL(unsigned int) +basic_oarchive::get_flags() const{ + return pimpl->m_flags; +} + +BOOST_ARCHIVE_DECL(void) +basic_oarchive::end_preamble(){ +} + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_oserializer.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_oserializer.cpp new file mode 100644 index 0000000..0e21806 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_oserializer.cpp @@ -0,0 +1,33 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_oserializer.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <cstddef> // NULL + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/detail/basic_oserializer.hpp> + +namespace boost { +namespace archive { +namespace detail { + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_oserializer::basic_oserializer( + const boost::serialization::extended_type_info & eti +) : + basic_serializer(eti), + m_bpos(NULL) +{} + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_oserializer::~basic_oserializer(){} + +} // namespace detail +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_pointer_iserializer.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_pointer_iserializer.cpp new file mode 100644 index 0000000..fac766f --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_pointer_iserializer.cpp @@ -0,0 +1,30 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_pointer_iserializer.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/detail/basic_pointer_iserializer.hpp> + +namespace boost { +namespace archive { +namespace detail { + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_pointer_iserializer::basic_pointer_iserializer( + const boost::serialization::extended_type_info & eti +) : + basic_serializer(eti) +{} + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_pointer_iserializer::~basic_pointer_iserializer() {} + +} // namespace detail +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_pointer_oserializer.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_pointer_oserializer.cpp new file mode 100644 index 0000000..9e9f1dd --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_pointer_oserializer.cpp @@ -0,0 +1,30 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_pointer_oserializer.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/detail/basic_pointer_oserializer.hpp> + +namespace boost { +namespace archive { +namespace detail { + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_pointer_oserializer::basic_pointer_oserializer( + const boost::serialization::extended_type_info & eti +) : + basic_serializer(eti) +{} + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +basic_pointer_oserializer::~basic_pointer_oserializer() {} + +} // namespace detail +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_serializer_map.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_serializer_map.cpp new file mode 100644 index 0000000..7df0b3d --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_serializer_map.cpp @@ -0,0 +1,112 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serializer_map.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#include <set> +#include <utility> + +#define BOOST_ARCHIVE_SOURCE +// include this to prevent linker errors when the +// same modules are marked export and import. +#define BOOST_SERIALIZATION_SOURCE + +#include <boost/archive/archive_exception.hpp> +#include <boost/serialization/throw_exception.hpp> + +#include <boost/archive/detail/basic_serializer.hpp> +#include <boost/archive/detail/basic_serializer_map.hpp> + +namespace boost { + namespace serialization { + class extended_type_info; + } +namespace archive { +namespace detail { + +bool +basic_serializer_map::type_info_pointer_compare::operator()( + const basic_serializer * lhs, const basic_serializer * rhs +) const { + return *lhs < *rhs; +} + +BOOST_ARCHIVE_DECL(bool) +basic_serializer_map::insert(const basic_serializer * bs){ + // attempt to insert serializer into it's map + // the following is commented out - rather than being just + // deleted as a reminder not to try this. + + // const std::pair<map_type::iterator, bool> result = + m_map.insert(bs); + + // At first it seemed like a good idea. It enforced the + // idea that a type be exported from at most one code module + // (DLL or mainline). This would enforce a "one definition rule" + // across code modules. This seems a good idea to me. + // But it seems that it's just too hard for many users to implement. + + // Ideally, I would like to make this exception a warning - + // but there isn't anyway to do that. + + // if this fails, it's because it's been instantiated + // in multiple modules - DLLS - a recipe for problems. + // So trap this here + // if(!result.second){ + // boost::serialization::throw_exception( + // archive_exception( + // archive_exception::multiple_code_instantiation, + // bs->get_debug_info() + // ) + // ); + // } + return true; +} + +BOOST_ARCHIVE_DECL(void) +basic_serializer_map::erase(const basic_serializer * bs){ + map_type::iterator it = m_map.begin(); + map_type::iterator it_end = m_map.end(); + + while(it != it_end){ + // note item 9 from Effective STL !!! it++ + if(*it == bs) + m_map.erase(it++); + else + it++; + } + // note: we can't do this since some of the eti records + // we're pointing to might be expired and the comparison + // won't work. Leave this as a reminder not to "optimize" this. + //it = m_map.find(bs); + //assert(it != m_map.end()); + //if(*it == bs) + // m_map.erase(it); +} +BOOST_ARCHIVE_DECL(const basic_serializer *) +basic_serializer_map::find( + const boost::serialization::extended_type_info & eti +) const { + const basic_serializer_arg bs(eti); + map_type::const_iterator it; + it = m_map.find(& bs); + if(it == m_map.end()){ + BOOST_ASSERT(false); + return 0; + } + return *it; +} + +} // namespace detail +} // namespace archive +} // namespace boost + diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_text_iprimitive.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_text_iprimitive.cpp new file mode 100644 index 0000000..c67a942 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_text_iprimitive.cpp @@ -0,0 +1,28 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_iprimitive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#include <istream> + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/detail/auto_link_archive.hpp> +#include <boost/archive/impl/basic_text_iprimitive.ipp> + +namespace boost { +namespace archive { + +// explicitly instantiate for this type of text stream +template class basic_text_iprimitive<std::istream> ; + +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_text_oprimitive.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_text_oprimitive.cpp new file mode 100644 index 0000000..d8d98d6 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_text_oprimitive.cpp @@ -0,0 +1,28 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_oprimitive.cpp: + +// (C) Copyright 2004 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#include <ostream> + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/detail/auto_link_archive.hpp> +#include <boost/archive/impl/basic_text_oprimitive.ipp> + +namespace boost { +namespace archive { + +// explicitly instantiate for this type of text stream +template class basic_text_oprimitive<std::ostream> ; + +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_text_wiprimitive.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_text_wiprimitive.cpp new file mode 100644 index 0000000..4797485 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_text_wiprimitive.cpp @@ -0,0 +1,35 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_wiprimitive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> + +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#include <istream> + +#define BOOST_WARCHIVE_SOURCE +#include <boost/archive/detail/auto_link_warchive.hpp> +#include <boost/archive/impl/basic_text_iprimitive.ipp> + +namespace boost { +namespace archive { + +template class basic_text_iprimitive<std::wistream> ; + +} // namespace archive +} // namespace boost + +#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_text_woprimitive.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_text_woprimitive.cpp new file mode 100644 index 0000000..e13294e --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_text_woprimitive.cpp @@ -0,0 +1,35 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_woprimitive.cpp: + +// (C) Copyright 2004 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> + +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#include <ostream> + +#define BOOST_WARCHIVE_SOURCE +#include <boost/archive/detail/auto_link_warchive.hpp> +#include <boost/archive/impl/basic_text_oprimitive.ipp> + +namespace boost { +namespace archive { + +template class basic_text_oprimitive<std::wostream> ; + +} // namespace archive +} // namespace boost + +#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_xml_archive.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_xml_archive.cpp new file mode 100644 index 0000000..e71aaef --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_xml_archive.cpp @@ -0,0 +1,51 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_archive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/basic_xml_archive.hpp> + +namespace boost { +namespace archive { + +BOOST_ARCHIVE_DECL(const char *) +BOOST_ARCHIVE_XML_OBJECT_ID(){ + return "object_id"; +} +BOOST_ARCHIVE_DECL(const char *) +BOOST_ARCHIVE_XML_OBJECT_REFERENCE(){ + return "object_id_reference"; +} +BOOST_ARCHIVE_DECL(const char *) +BOOST_ARCHIVE_XML_CLASS_ID(){ + return "class_id"; +} +BOOST_ARCHIVE_DECL(const char *) +BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(){ + return "class_id_reference"; +} +BOOST_ARCHIVE_DECL(const char *) +BOOST_ARCHIVE_XML_CLASS_NAME(){ + return "class_name"; +} +BOOST_ARCHIVE_DECL(const char *) +BOOST_ARCHIVE_XML_TRACKING(){ + return "tracking_level"; +} +BOOST_ARCHIVE_DECL(const char *) +BOOST_ARCHIVE_XML_VERSION(){ + return "version"; +} +BOOST_ARCHIVE_DECL(const char *) +BOOST_ARCHIVE_XML_SIGNATURE(){ + return "signature"; +} + +}// namespace archive +}// namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_xml_grammar.ipp b/3rdParty/Boost/src/libs/serialization/src/basic_xml_grammar.ipp new file mode 100644 index 0000000..011bba7 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/basic_xml_grammar.ipp @@ -0,0 +1,468 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_grammar.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#include <istream> +#include <algorithm> +#include <boost/config.hpp> // BOOST_DEDUCED_TYPENAME + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +// spirit stuff +#include <boost/spirit/include/classic_operators.hpp> +#include <boost/spirit/include/classic_actions.hpp> +#include <boost/spirit/include/classic_numerics.hpp> + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +// for head_iterator test +//#include <boost/bind.hpp> +#include <boost/function.hpp> +#include <boost/serialization/pfto.hpp> + +#include <boost/io/ios_state.hpp> +#include <boost/serialization/throw_exception.hpp> +#include <boost/archive/impl/basic_xml_grammar.hpp> +#include <boost/archive/xml_archive_exception.hpp> +#include <boost/archive/basic_xml_archive.hpp> +#include <boost/archive/iterators/xml_unescape.hpp> + +using namespace boost::spirit::classic; + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// template code for basic_xml_grammar of both wchar_t and char types + +namespace xml { // anonymous + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +template<class T> +struct assign_impl { + T & t; + void operator()(const T t_) const { + t = t_; + } + assign_impl(T & t_) + : t(t_) + {} +}; + +template<> +struct assign_impl<std::string> { + std::string & t; + void operator()( + std::string::const_iterator b, + std::string::const_iterator e + ) const { + t.resize(0); + while(b != e){ + t += * b; + ++b; + } + } + assign_impl<std::string> & operator=( + assign_impl<std::string> & rhs + ); + assign_impl(std::string & t_) + : t(t_) + {} +}; + +#ifndef BOOST_NO_STD_WSTRING +template<> +struct assign_impl<std::wstring> { + std::wstring & t; + void operator()( + std::wstring::const_iterator b, + std::wstring::const_iterator e + ) const { + t.resize(0); + while(b != e){ + t += * b; + ++b; + } + } + assign_impl(std::wstring & t_) + : t(t_) + {} +}; +#endif + +template<class T> +assign_impl<T> assign_object(T &t){ + return assign_impl<T>(t); +} + +struct assign_level { + tracking_type & tracking_level; + void operator()(const unsigned int tracking_level_) const { + tracking_level = (0 == tracking_level_) ? false : true; + } + assign_level(tracking_type & tracking_level_) + : tracking_level(tracking_level_) + {} +}; + +template<class String, class Iterator> +struct append_string { + String & contents; + void operator()(Iterator start, Iterator end) const { + #if 0 + typedef boost::archive::iterators::xml_unescape<Iterator> translator; + contents.append( + translator(BOOST_MAKE_PFTO_WRAPPER(start)), + translator(BOOST_MAKE_PFTO_WRAPPER(end)) + ); + #endif + contents.append(start, end); + } + append_string(String & contents_) + : contents(contents_) + {} +}; + +template<class String> +struct append_char { + String & contents; + void operator()(const unsigned int char_value) const { + const BOOST_DEDUCED_TYPENAME String::value_type z = char_value; + contents += z; + } + append_char(String & contents_) + : contents(contents_) + {} +}; + +template<class String, unsigned int c> +struct append_lit { + String & contents; + template<class X, class Y> + void operator()(const X & /*x*/, const Y & /*y*/) const { + const BOOST_DEDUCED_TYPENAME String::value_type z = c; + contents += z; + } + append_lit(String & contents_) + : contents(contents_) + {} +}; + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +} // namespace anonymous + +template<class CharType> +bool basic_xml_grammar<CharType>::my_parse( + BOOST_DEDUCED_TYPENAME basic_xml_grammar<CharType>::IStream & is, + const rule_t & rule_, + CharType delimiter +) const { + if(is.fail()){ + boost::serialization::throw_exception( + archive_exception(archive_exception::input_stream_error) + ); + } + + boost::io::ios_flags_saver ifs(is); + is >> std::noskipws; + + std::basic_string<CharType> arg; + + CharType val; + do{ + BOOST_DEDUCED_TYPENAME basic_xml_grammar<CharType>::IStream::int_type + result = is.get(); + if(is.fail()) + return false; + val = static_cast<CharType>(result); + arg += val; + } + while(val != delimiter); + + // read just one more character. This will be the newline after the tag + // this is so that the next operation will return fail if the archive + // is terminated. This will permit the archive to be used for debug + // and transaction data logging in the standard way. + + parse_info<BOOST_DEDUCED_TYPENAME std::basic_string<CharType>::iterator> + result = boost::spirit::classic::parse(arg.begin(), arg.end(), rule_); + return result.hit; +} + +template<class CharType> +bool basic_xml_grammar<CharType>::parse_start_tag( + BOOST_DEDUCED_TYPENAME basic_xml_grammar<CharType>::IStream & is +){ + rv.class_name.resize(0); + return my_parse(is, STag); +} + +template<class CharType> +bool basic_xml_grammar<CharType>::parse_end_tag(IStream & is) const { + return my_parse(is, ETag); +} + +template<class CharType> +bool basic_xml_grammar<CharType>::parse_string(IStream & is, StringType & s){ + rv.contents.resize(0); + bool result = my_parse(is, content, '<'); + // note: unget caused a problem with dinkumware. replace with + // is.unget(); + // putback another dilimiter instead + is.putback('<'); + if(result) + s = rv.contents; + return result; +} + +template<class CharType> +basic_xml_grammar<CharType>::basic_xml_grammar(){ + init_chset(); + + S = + +(Sch) + ; + + // refactoring to workaround template depth on darwin + NameHead = (Letter | '_' | ':'); + NameTail = *NameChar ; + Name = + NameHead >> NameTail + ; + + Eq = + !S >> '=' >> !S + ; + + AttributeList = + *(S >> Attribute) + ; + + STag = + !S + >> '<' + >> Name [xml::assign_object(rv.object_name)] + >> AttributeList + >> !S + >> '>' + ; + + ETag = + !S + >> "</" + >> Name [xml::assign_object(rv.object_name)] + >> !S + >> '>' + ; + + // refactoring to workaround template depth on darwin + CharDataChars = +(anychar_p - chset_p(L"&<")); + CharData = + CharDataChars [ + xml::append_string< + StringType, + BOOST_DEDUCED_TYPENAME std::basic_string<CharType>::const_iterator + >(rv.contents) + ] + ; + + // slight factoring works around ICE in msvc 6.0 + CharRef1 = + str_p(L"&#") >> uint_p [xml::append_char<StringType>(rv.contents)] >> L';' + ; + CharRef2 = + str_p(L"&#x") >> hex_p [xml::append_char<StringType>(rv.contents)] >> L';' + ; + CharRef = CharRef1 | CharRef2 ; + + AmpRef = str_p(L"&")[xml::append_lit<StringType, L'&'>(rv.contents)]; + LTRef = str_p(L"<")[xml::append_lit<StringType, L'<'>(rv.contents)]; + GTRef = str_p(L">")[xml::append_lit<StringType, L'>'>(rv.contents)]; + AposRef = str_p(L"'")[xml::append_lit<StringType, L'\''>(rv.contents)]; + QuoteRef = str_p(L""")[xml::append_lit<StringType, L'"'>(rv.contents)]; + + Reference = + AmpRef + | LTRef + | GTRef + | AposRef + | QuoteRef + | CharRef + ; + + content = + L"<" // should be end_p + | +(Reference | CharData) >> L"<" + ; + + ClassIDAttribute = + str_p(BOOST_ARCHIVE_XML_CLASS_ID()) >> NameTail + >> Eq + >> L'"' + >> int_p [xml::assign_object(rv.class_id)] + >> L'"' + ; + + ObjectIDAttribute = ( + str_p(BOOST_ARCHIVE_XML_OBJECT_ID()) + | + str_p(BOOST_ARCHIVE_XML_OBJECT_REFERENCE()) + ) + >> NameTail + >> Eq + >> L'"' + >> L'_' + >> uint_p [xml::assign_object(rv.object_id)] + >> L'"' + ; + + AmpName = str_p(L"&")[xml::append_lit<StringType, L'&'>(rv.class_name)]; + LTName = str_p(L"<")[xml::append_lit<StringType, L'<'>(rv.class_name)]; + GTName = str_p(L">")[xml::append_lit<StringType, L'>'>(rv.class_name)]; + ClassNameChar = + AmpName + | LTName + | GTName + | (anychar_p - chset_p(L"\"")) [xml::append_char<StringType>(rv.class_name)] + ; + + ClassName = + * ClassNameChar + ; + + ClassNameAttribute = + str_p(BOOST_ARCHIVE_XML_CLASS_NAME()) + >> Eq + >> L'"' + >> ClassName + >> L'"' + ; + + TrackingAttribute = + str_p(BOOST_ARCHIVE_XML_TRACKING()) + >> Eq + >> L'"' + >> uint_p [xml::assign_level(rv.tracking_level)] + >> L'"' + ; + + VersionAttribute = + str_p(BOOST_ARCHIVE_XML_VERSION()) + >> Eq + >> L'"' + >> uint_p [xml::assign_object(rv.version)] + >> L'"' + ; + + UnusedAttribute = + Name + >> Eq + >> L'"' + >> !CharData + >> L'"' + ; + + Attribute = + ClassIDAttribute + | ObjectIDAttribute + | ClassNameAttribute + | TrackingAttribute + | VersionAttribute + | UnusedAttribute + ; + + XMLDeclChars = *(anychar_p - chset_p(L"?>")); + XMLDecl = + !S + >> str_p(L"<?xml") + >> S + >> str_p(L"version") + >> Eq + >> str_p(L"\"1.0\"") + >> XMLDeclChars + >> !S + >> str_p(L"?>") + ; + + DocTypeDeclChars = *(anychar_p - chset_p(L">")); + DocTypeDecl = + !S + >> str_p(L"<!DOCTYPE") + >> DocTypeDeclChars + >> L'>' + ; + + SignatureAttribute = + str_p(L"signature") + >> Eq + >> L'"' + >> Name [xml::assign_object(rv.class_name)] + >> L'"' + ; + + SerializationWrapper = + !S + >> str_p(L"<boost_serialization") + >> S + >> ( (SignatureAttribute >> S >> VersionAttribute) + | (VersionAttribute >> S >> SignatureAttribute) + ) + >> !S + >> L'>' + ; +} + +template<class CharType> +void basic_xml_grammar<CharType>::init(IStream & is){ + init_chset(); + if(! my_parse(is, XMLDecl)) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + if(! my_parse(is, DocTypeDecl)) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + if(! my_parse(is, SerializationWrapper)) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + if(! std::equal(rv.class_name.begin(), rv.class_name.end(), BOOST_ARCHIVE_SIGNATURE())) + boost::serialization::throw_exception( + archive_exception(archive_exception::invalid_signature) + ); +} + +template<class CharType> +void basic_xml_grammar<CharType>::windup(IStream & is){ + if(is.fail()) + return; + // uh-oh - don't throw exception from code called by a destructor ! + // so just ignore any failure. + my_parse(is, ETag); +} + +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/binary_iarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/binary_iarchive.cpp new file mode 100644 index 0000000..c1117e9 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/binary_iarchive.cpp @@ -0,0 +1,39 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_iarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <istream> + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/binary_iarchive.hpp> +#include <boost/archive/detail/archive_serializer_map.hpp> + +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_binary_iprimitive.ipp> +#include <boost/archive/impl/basic_binary_iarchive.ipp> + +namespace boost { +namespace archive { + +// explicitly instantiate for this type of stream +template class detail::archive_serializer_map<binary_iarchive>; +template class basic_binary_iprimitive< + binary_iarchive, + std::istream::char_type, + std::istream::traits_type +>; +template class basic_binary_iarchive<binary_iarchive> ; +template class binary_iarchive_impl< + binary_iarchive, + std::istream::char_type, + std::istream::traits_type +>; + +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/binary_oarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/binary_oarchive.cpp new file mode 100644 index 0000000..e7ab904 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/binary_oarchive.cpp @@ -0,0 +1,39 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_oarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <ostream> + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/binary_oarchive.hpp> +#include <boost/archive/detail/archive_serializer_map.hpp> + +// explicitly instantiate for this type of binary stream +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_binary_oprimitive.ipp> +#include <boost/archive/impl/basic_binary_oarchive.ipp> + +namespace boost { +namespace archive { + +template class detail::archive_serializer_map<binary_oarchive>; +template class basic_binary_oprimitive< + binary_oarchive, + std::ostream::char_type, + std::ostream::traits_type +>; +template class basic_binary_oarchive<binary_oarchive> ; +template class binary_oarchive_impl< + binary_oarchive, + std::ostream::char_type, + std::ostream::traits_type +>; + +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/binary_wiarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/binary_wiarchive.cpp new file mode 100644 index 0000000..720d469 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/binary_wiarchive.cpp @@ -0,0 +1,47 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_wiarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> + +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#define BOOST_WARCHIVE_SOURCE +#include <boost/archive/binary_wiarchive.hpp> +#include <boost/archive/detail/archive_serializer_map.hpp> + +// explicitly instantiate for this type of text stream +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_binary_iprimitive.ipp> +#include <boost/archive/impl/basic_binary_iarchive.ipp> + +namespace boost { +namespace archive { + +// explicitly instantiate for this type of text stream +template class detail::archive_serializer_map<binary_wiarchive>; +template class basic_binary_iprimitive< + binary_wiarchive, + wchar_t, + std::char_traits<wchar_t> +>; +template class basic_binary_iarchive<binary_wiarchive> ; +template class binary_iarchive_impl< + binary_wiarchive, + wchar_t, + std::char_traits<wchar_t> +>; + +} // namespace archive +} // namespace boost + +#endif // BOOST_NO_STD_WSTREAMBUF + diff --git a/3rdParty/Boost/src/libs/serialization/src/binary_woarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/binary_woarchive.cpp new file mode 100644 index 0000000..905a319 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/binary_woarchive.cpp @@ -0,0 +1,44 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_woarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> + +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#define BOOST_WARCHIVE_SOURCE +#include <boost/archive/binary_woarchive.hpp> + +// explicitly instantiate for this type of text stream +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_binary_oprimitive.ipp> +#include <boost/archive/impl/basic_binary_oarchive.ipp> + +namespace boost { +namespace archive { + +template class detail::archive_serializer_map<binary_woarchive>; +template class basic_binary_oprimitive< + binary_woarchive, + wchar_t, + std::char_traits<wchar_t> +>; +template class basic_binary_oarchive<binary_woarchive> ; +template class binary_oarchive_impl< + binary_woarchive, + wchar_t, + std::char_traits<wchar_t> +>; + +} // namespace archive +} // namespace boost + +#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/3rdParty/Boost/src/libs/serialization/src/codecvt_null.cpp b/3rdParty/Boost/src/libs/serialization/src/codecvt_null.cpp new file mode 100644 index 0000000..80ba2a3 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/codecvt_null.cpp @@ -0,0 +1,83 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// codecvt_null.cpp + +// Copyright (c) 2004 Robert Ramey, Indiana University (garcia@osl.iu.edu) +// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). +// 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) + +#define BOOST_WARCHIVE_SOURCE +#include <boost/archive/codecvt_null.hpp> + +// codecvt implementation for passing wchar_t objects to char output +// without any translation whatever. Used to implement binary output +// of wchar_t objects. + +namespace boost { +namespace archive { + +BOOST_WARCHIVE_DECL(std::codecvt_base::result) +codecvt_null<wchar_t>::do_out( + std::mbstate_t & /*state*/, + const wchar_t * first1, + const wchar_t * last1, + const wchar_t * & next1, + char * first2, + char * last2, + char * & next2 +) const { + while(first1 != last1){ + // Per std::22.2.1.5.2/2, we can store no more that + // last2-first2 characters. If we need to more encode + // next internal char type, return 'partial'. + if(static_cast<int>(sizeof(wchar_t)) > (last2 - first2)){ + next1 = first1; + next2 = first2; + return std::codecvt_base::partial; + } + * reinterpret_cast<wchar_t *>(first2) = * first1++; + first2 += sizeof(wchar_t); + + } + next1 = first1; + next2 = first2; + return std::codecvt_base::ok; +} + +BOOST_WARCHIVE_DECL(std::codecvt_base::result) +codecvt_null<wchar_t>::do_in( + std::mbstate_t & /*state*/, + const char * first1, + const char * last1, + const char * & next1, + wchar_t * first2, + wchar_t * last2, + wchar_t * & next2 +) const { + // Process input characters until we've run of them, + // or the number of remaining characters is not + // enough to construct another output character, + // or we've run out of place for output characters. + while(first2 != last2){ + // Have we converted all input characters? + // Return with 'ok', if so. + if (first1 == last1) + break; + // Do we have less input characters than needed + // for a single output character? + if(static_cast<int>(sizeof(wchar_t)) > (last1 - first1)){ + next1 = first1; + next2 = first2; + return std::codecvt_base::partial; + } + *first2++ = * reinterpret_cast<const wchar_t *>(first1); + first1 += sizeof(wchar_t); + } + next1 = first1; + next2 = first2; + return std::codecvt_base::ok; +} + +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/extended_type_info.cpp b/3rdParty/Boost/src/libs/serialization/src/extended_type_info.cpp new file mode 100644 index 0000000..2efbefc --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/extended_type_info.cpp @@ -0,0 +1,188 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// extended_type_info.cpp: implementation for portable version of type_info + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#include <algorithm> +#include <set> +#include <utility> +#include <boost/assert.hpp> +#include <cstddef> // NULL + +#include <boost/config.hpp> // msvc needs this to suppress warning + +#include <cstring> +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ using ::strcmp; } +#endif + +#include <boost/detail/no_exceptions_support.hpp> +#include <boost/serialization/singleton.hpp> +#include <boost/serialization/force_include.hpp> + +#define BOOST_SERIALIZATION_SOURCE +#include <boost/serialization/extended_type_info.hpp> + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace serialization { +namespace detail { + +struct key_compare +{ + bool + operator()( + const extended_type_info * lhs, + const extended_type_info * rhs + ) const { + // performance shortcut + if(lhs == rhs) + return false; + const char * l = lhs->get_key(); + BOOST_ASSERT(NULL != l); + const char * r = rhs->get_key(); + BOOST_ASSERT(NULL != r); + // performance shortcut + // shortcut to exploit string pooling + if(l == r) + return false; + // for exported types, use the string key so that + // multiple instances in different translation units + // can be matched up + return std::strcmp(l, r) < 0; + } +}; + +typedef std::multiset<const extended_type_info *, key_compare> ktmap; + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +class extended_type_info_arg : public extended_type_info +{ + virtual bool + is_less_than(const extended_type_info & /*rhs*/) const { + BOOST_ASSERT(false); + return false; + }; + virtual bool + is_equal(const extended_type_info & /*rhs*/) const { + BOOST_ASSERT(false); + return false; + }; + virtual const char * get_debug_info() const { + return get_key(); + } + virtual void * construct(unsigned int /*count*/, ...) const{ + BOOST_ASSERT(false); + return NULL; + } + virtual void destroy(void const * const /*p*/) const { + BOOST_ASSERT(false); + } +public: + extended_type_info_arg(const char * key) : + extended_type_info(0, key) + {} + + ~extended_type_info_arg(){ + } +}; + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +} // namespace detail + +BOOST_SERIALIZATION_DECL(void) +extended_type_info::key_register() const{ + if(NULL == get_key()) + return; + singleton<detail::ktmap>::get_mutable_instance().insert(this); +} + +BOOST_SERIALIZATION_DECL(void) +extended_type_info::key_unregister() const{ + if(NULL == get_key()) + return; + if(! singleton<detail::ktmap>::is_destroyed()){ + detail::ktmap & x = singleton<detail::ktmap>::get_mutable_instance(); + detail::ktmap::iterator start = x.lower_bound(this); + detail::ktmap::iterator end = x.upper_bound(this); + // remove entry in map which corresponds to this type + for(;start != end; ++start){ + if(this == *start){ + x.erase(start); + break; + } + } + } +} + +BOOST_SERIALIZATION_DECL(const extended_type_info *) +extended_type_info::find(const char *key) { + BOOST_ASSERT(NULL != key); + const detail::ktmap & k = singleton<detail::ktmap>::get_const_instance(); + const detail::extended_type_info_arg eti_key(key); + const detail::ktmap::const_iterator it = k.find(& eti_key); + if(k.end() == it) + return NULL; + return *(it); +} + +BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) +extended_type_info::extended_type_info( + const unsigned int type_info_key, + const char * key +) : + m_type_info_key(type_info_key), + m_key(key) +{ +} + +BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) +extended_type_info::~extended_type_info(){ +} + +BOOST_SERIALIZATION_DECL(bool) +extended_type_info::operator<(const extended_type_info &rhs) const { + // short cut for a common cases + if(this == & rhs) + return false; + if(m_type_info_key == rhs.m_type_info_key){ + return is_less_than(rhs); + } + if(m_type_info_key < rhs.m_type_info_key) + return true; + return false; +} + +BOOST_SERIALIZATION_DECL(bool) +extended_type_info::operator==(const extended_type_info &rhs) const { + // short cut for a common cases + if(this == & rhs) + return true; + if(m_type_info_key != rhs.m_type_info_key){ + return false; + } + return is_equal(rhs); +} + +} // namespace serialization +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/extended_type_info_no_rtti.cpp b/3rdParty/Boost/src/libs/serialization/src/extended_type_info_no_rtti.cpp new file mode 100644 index 0000000..3b2a888 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/extended_type_info_no_rtti.cpp @@ -0,0 +1,85 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// extended_type_info_no_rtti.cpp: specific implementation of type info +// that is NOT based on typeid + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <cstring> +#include <cstddef> // NULL +#include <boost/assert.hpp> + +#include <boost/config.hpp> +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ using ::strcmp; } +#endif + +#define BOOST_SERIALIZATION_SOURCE +#include <boost/serialization/extended_type_info_no_rtti.hpp> + +#define EXTENDED_TYPE_INFO_NO_RTTI_KEY 2 + +namespace boost { +namespace serialization { +namespace no_rtti_system { + +BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) +extended_type_info_no_rtti_0::extended_type_info_no_rtti_0( + const char * key +) : + extended_type_info(EXTENDED_TYPE_INFO_NO_RTTI_KEY, key) +{} + +BOOST_SERIALIZATION_DECL(bool) +extended_type_info_no_rtti_0::is_less_than( + const boost::serialization::extended_type_info &rhs) const +{ + // shortcut for common case + if(this == & rhs) + return false; + const char * l = get_key(); + const char * r = rhs.get_key(); + // if this assertion is triggered, it could mean one of the following + // a) This class was never exported - make sure all calls which use + // this method of type id are in fact exported. + // b) This class was used (e.g. serialized through a pointer) before + // it was exported. Make sure that classes which use this method + // of type id are NOT "automatically" registered by serializating + // through a pointer to the to most derived class. OR make sure + // that the BOOST_CLASS_EXPORT is included in every file + // which does this. + BOOST_ASSERT(NULL != l); + BOOST_ASSERT(NULL != r); + return std::strcmp(l, r) < 0; +} + +BOOST_SERIALIZATION_DECL(bool) +extended_type_info_no_rtti_0::is_equal( + const boost::serialization::extended_type_info &rhs) const +{ + // shortcut for common case + if(this == & rhs) + return true; + // null keys don't match with anything + const char * l = get_key(); + BOOST_ASSERT(NULL != l); + if(NULL == l) + return false; + const char * r = rhs.get_key(); + BOOST_ASSERT(NULL != r); + if(NULL == r) + return false; + return 0 == std::strcmp(l, r); +} + +BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) +extended_type_info_no_rtti_0::~extended_type_info_no_rtti_0() +{} + +} // namespece detail +} // namespace serialization +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/extended_type_info_typeid.cpp b/3rdParty/Boost/src/libs/serialization/src/extended_type_info_typeid.cpp new file mode 100644 index 0000000..463287a --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/extended_type_info_typeid.cpp @@ -0,0 +1,161 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// extended_type_info_typeid.cpp: specific implementation of type info +// that is based on typeid + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <algorithm> +#include <set> +#include <boost/assert.hpp> +#include <typeinfo> +#include <cstddef> // NULL + +#include <boost/detail/no_exceptions_support.hpp> + +#include <boost/serialization/singleton.hpp> + +#define BOOST_SERIALIZATION_SOURCE +#include <boost/serialization/extended_type_info_typeid.hpp> + +namespace boost { +namespace serialization { +namespace typeid_system { + +#define EXTENDED_TYPE_INFO_TYPE_KEY 1 + +struct type_compare +{ + bool + operator()( + const extended_type_info_typeid_0 * lhs, + const extended_type_info_typeid_0 * rhs + ) const { + return lhs->is_less_than(*rhs); + } +}; + +typedef std::multiset< + const extended_type_info_typeid_0 *, + type_compare +> tkmap; + +BOOST_SERIALIZATION_DECL(bool) +extended_type_info_typeid_0::is_less_than( + const boost::serialization::extended_type_info & rhs +) const { + // shortcut for common case + if(this == & rhs) + return false; + return 0 != m_ti->before( + *(static_cast<const extended_type_info_typeid_0 &>(rhs).m_ti) + ); +} + +BOOST_SERIALIZATION_DECL(bool) +extended_type_info_typeid_0::is_equal( + const boost::serialization::extended_type_info & rhs +) const { + return + // note: std::type_info == operator returns an int !!! + // the following permits conversion to bool without a warning. + ! ( + * m_ti + != *(static_cast<const extended_type_info_typeid_0 &>(rhs).m_ti) + ) + ; +} + +BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) +extended_type_info_typeid_0::extended_type_info_typeid_0( + const char * key +) : + extended_type_info(EXTENDED_TYPE_INFO_TYPE_KEY, key), + m_ti(NULL) +{} + +BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY()) +extended_type_info_typeid_0::~extended_type_info_typeid_0() +{} + +BOOST_SERIALIZATION_DECL(void) +extended_type_info_typeid_0::type_register(const std::type_info & ti){ + m_ti = & ti; + singleton<tkmap>::get_mutable_instance().insert(this); +} + +BOOST_SERIALIZATION_DECL(void) +extended_type_info_typeid_0::type_unregister() +{ + if(NULL != m_ti){ + if(! singleton<tkmap>::is_destroyed()){ + tkmap & x = singleton<tkmap>::get_mutable_instance(); + tkmap::iterator start = x.lower_bound(this); + tkmap::iterator end = x.upper_bound(this); + BOOST_ASSERT(start != end); + + // remove entry in map which corresponds to this type + do{ + if(this == *start) + x.erase(start++); + else + ++start; + }while(start != end); + } + } + m_ti = NULL; +} + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +// this derivation is used for creating search arguments +class extended_type_info_typeid_arg : + public extended_type_info_typeid_0 +{ + virtual void * construct(unsigned int /*count*/, ...) const{ + BOOST_ASSERT(false); + return NULL; + } + virtual void destroy(void const * const /*p*/) const { + BOOST_ASSERT(false); + } +public: + extended_type_info_typeid_arg(const std::type_info & ti) : + extended_type_info_typeid_0(NULL) + { + // note absense of self register and key as this is used only as + // search argument given a type_info reference and is not to + // be added to the map. + m_ti = & ti; + } + ~extended_type_info_typeid_arg(){ + m_ti = NULL; + } +}; + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +BOOST_SERIALIZATION_DECL(const extended_type_info *) +extended_type_info_typeid_0::get_extended_type_info( + const std::type_info & ti +) const { + typeid_system::extended_type_info_typeid_arg etia(ti); + const tkmap & t = singleton<tkmap>::get_const_instance(); + const tkmap::const_iterator it = t.find(& etia); + if(t.end() == it) + return NULL; + return *(it); +} + +} // namespace detail +} // namespace serialization +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/polymorphic_iarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/polymorphic_iarchive.cpp new file mode 100644 index 0000000..5e8c986 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/polymorphic_iarchive.cpp @@ -0,0 +1,29 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_iarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/detail/archive_serializer_map.hpp> + +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/polymorphic_iarchive.hpp> + +namespace boost { +namespace archive { +namespace detail { + +template class archive_serializer_map<polymorphic_iarchive>; + +} // detail +} // archive +} // boost diff --git a/3rdParty/Boost/src/libs/serialization/src/polymorphic_oarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/polymorphic_oarchive.cpp new file mode 100644 index 0000000..b85895e --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/polymorphic_oarchive.cpp @@ -0,0 +1,29 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_oarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/detail/archive_serializer_map.hpp> + +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/polymorphic_oarchive.hpp> + +namespace boost { +namespace archive { +namespace detail { + +template class archive_serializer_map<polymorphic_oarchive>; + +} // detail +} // archive +} // boost diff --git a/3rdParty/Boost/src/libs/serialization/src/shared_ptr_helper.cpp b/3rdParty/Boost/src/libs/serialization/src/shared_ptr_helper.cpp new file mode 100644 index 0000000..15102e2 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/shared_ptr_helper.cpp @@ -0,0 +1,63 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// shared_ptr_helper.hpp: serialization for boost shared pointern + +// (C) Copyright 2004-2009 Robert Ramey, Martin Ecker and Takatoshi Kondo +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <map> +#include <list> +#include <utility> +#include <cstddef> // NULL +#include <cassert> + +#define BOOST_ARCHIVE_SOURCE +// include this to prevent linker errors when the +// same modules are marked export and import. +#define BOOST_SERIALIZATION_SOURCE + +#include <boost/serialization/throw_exception.hpp> +#include <boost/serialization/void_cast.hpp> +#include <boost/serialization/extended_type_info.hpp> +#include <boost/serialization/shared_ptr_helper.hpp> +#include <boost/archive/archive_exception.hpp> + +namespace boost { +namespace serialization { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// a common class for holding various types of shared pointers + +// #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP +BOOST_ARCHIVE_DECL(void) +shared_ptr_helper_base::append(const boost_132::shared_ptr<const void> & t){ + if(NULL == m_pointers_132) + m_pointers_132 = new std::list<boost_132::shared_ptr<const void> >; + m_pointers_132->push_back(t); +} +// #endif + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +shared_ptr_helper_base::shared_ptr_helper_base() : + m_o_sp(NULL) + #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP + , m_pointers_132(NULL) + #endif +{} + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +shared_ptr_helper_base::~shared_ptr_helper_base(){ + if(NULL != m_o_sp) + delete m_o_sp; + #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP + if(NULL != m_pointers_132) + delete m_pointers_132; + #endif +} + +} // namespace serialization +} // namespace boost + diff --git a/3rdParty/Boost/src/libs/serialization/src/stl_port.cpp b/3rdParty/Boost/src/libs/serialization/src/stl_port.cpp new file mode 100644 index 0000000..e5378bc --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/stl_port.cpp @@ -0,0 +1,43 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// stl_port.cpp: implementation of run-time casting of void pointers + +// (C) Copyright 2005 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +// this befuddles the msvc 6 compiler so we can't use it +#if ! ((defined _MSC_VER) && (_MSC_VER <= 1300)) \ +&& ! defined(__BORLANDC__) + +#include <boost/config.hpp> + +#if defined(__SGI_STL_PORT) && (__SGI_STL_PORT < 0x500) + +#include <boost/archive/codecvt_null.hpp> + +// explicit instantiation + +namespace std { + +template +locale::locale( + const locale& __loc, boost::archive::codecvt_null<char> * __f +); + +template +locale::locale( + const locale& __loc, boost::archive::codecvt_null<wchar_t> * __f +); + +} // namespace std + +#endif + +#endif diff --git a/3rdParty/Boost/src/libs/serialization/src/text_iarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/text_iarchive.cpp new file mode 100644 index 0000000..9520ca2 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/text_iarchive.cpp @@ -0,0 +1,32 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_iarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/text_iarchive.hpp> +#include <boost/archive/detail/archive_serializer_map.hpp> + +// explicitly instantiate for this type of text stream +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_text_iarchive.ipp> +#include <boost/archive/impl/text_iarchive_impl.ipp> + +namespace boost { +namespace archive { + +template class detail::archive_serializer_map<text_iarchive>; +template class basic_text_iarchive<text_iarchive> ; +template class text_iarchive_impl<text_iarchive> ; + +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/text_oarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/text_oarchive.cpp new file mode 100644 index 0000000..19165d6 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/text_oarchive.cpp @@ -0,0 +1,33 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_oarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/text_oarchive.hpp> +#include <boost/archive/detail/archive_serializer_map.hpp> + +// explicitly instantiate for this type of text stream +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_text_oarchive.ipp> +#include <boost/archive/impl/text_oarchive_impl.ipp> + +namespace boost { +namespace archive { + +//template class basic_text_oprimitive<std::ostream> ; +template class detail::archive_serializer_map<text_oarchive>; +template class basic_text_oarchive<text_oarchive> ; +template class text_oarchive_impl<text_oarchive> ; + +} // namespace serialization +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/text_wiarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/text_wiarchive.cpp new file mode 100644 index 0000000..a0c68a8 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/text_wiarchive.cpp @@ -0,0 +1,37 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_wiarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> + +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#define BOOST_WARCHIVE_SOURCE +#include <boost/archive/text_wiarchive.hpp> +#include <boost/archive/detail/archive_serializer_map.hpp> + +// explicitly instantiate for this type of text stream +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_text_iarchive.ipp> +#include <boost/archive/impl/text_wiarchive_impl.ipp> + +namespace boost { +namespace archive { + +template class detail::archive_serializer_map<text_wiarchive>; +template class basic_text_iarchive<text_wiarchive> ; +template class text_wiarchive_impl<text_wiarchive> ; + +} // namespace archive +} // namespace boost + +#endif // BOOST_NO_STD_WSTREAMBUF + diff --git a/3rdParty/Boost/src/libs/serialization/src/text_woarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/text_woarchive.cpp new file mode 100644 index 0000000..54b4a0d --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/text_woarchive.cpp @@ -0,0 +1,35 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_woarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#define BOOST_WARCHIVE_SOURCE +#include <boost/archive/text_woarchive.hpp> +#include <boost/archive/detail/archive_serializer_map.hpp> + +// explicitly instantiate for this type of text stream +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_text_oarchive.ipp> +#include <boost/archive/impl/text_woarchive_impl.ipp> + +namespace boost { +namespace archive { + +template class detail::archive_serializer_map<text_woarchive>; +template class basic_text_oarchive<text_woarchive> ; +template class text_woarchive_impl<text_woarchive> ; + +} // namespace archive +} // namespace boost + +#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/3rdParty/Boost/src/libs/serialization/src/utf8_codecvt_facet.cpp b/3rdParty/Boost/src/libs/serialization/src/utf8_codecvt_facet.cpp new file mode 100644 index 0000000..07deada --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/utf8_codecvt_facet.cpp @@ -0,0 +1,20 @@ +// Copyright Vladimir Prus 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) + +#include <boost/config.hpp> +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + #ifdef BOOST_NO_CXX11_HDR_CODECVT + #define BOOST_UTF8_BEGIN_NAMESPACE \ + namespace boost { namespace archive { namespace detail { + #define BOOST_UTF8_DECL + #define BOOST_UTF8_END_NAMESPACE }}} + #include <boost/detail/utf8_codecvt_facet.ipp> + #undef BOOST_UTF8_END_NAMESPACE + #undef BOOST_UTF8_DECL + #undef BOOST_UTF8_BEGIN_NAMESPACE + #endif // BOOST_NO_CXX11_HDR_CODECVT +#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/3rdParty/Boost/src/libs/serialization/src/void_cast.cpp b/3rdParty/Boost/src/libs/serialization/src/void_cast.cpp new file mode 100644 index 0000000..df31235 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/void_cast.cpp @@ -0,0 +1,360 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// void_cast.cpp: implementation of run-time casting of void pointers + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// 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) +// <gennadiy.rozental@tfn.com> + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#include <boost/assert.hpp> +#include <cstddef> // NULL +#ifdef BOOST_SERIALIZATION_LOG +#include <iostream> +#endif + +// STL +#include <set> +#include <functional> +#include <algorithm> +#include <boost/assert.hpp> + +// BOOST +#define BOOST_SERIALIZATION_SOURCE +#include <boost/serialization/singleton.hpp> +#include <boost/serialization/extended_type_info.hpp> +#include <boost/serialization/void_cast.hpp> + +namespace boost { +namespace serialization { +namespace void_cast_detail { + +// note that void_casters are keyed on value of +// member extended type info records - NOT their +// addresses. This is necessary in order for the +// void cast operations to work across dll and exe +// module boundries. +bool void_caster::operator<(const void_caster & rhs) const { + // include short cut to save time and eliminate + // problems when when base class aren't virtual + if(m_derived != rhs.m_derived){ + if(*m_derived < *rhs.m_derived) + return true; + if(*rhs.m_derived < *m_derived) + return false; + } + // m_derived == rhs.m_derived + if(m_base != rhs.m_base) + return *m_base < *rhs.m_base; + else + return false; +} + +struct void_caster_compare { + bool operator()(const void_caster * lhs, const void_caster * rhs) const { + return *lhs < *rhs; + } +}; + +typedef std::set<const void_caster *, void_caster_compare> set_type; +typedef boost::serialization::singleton<set_type> void_caster_registry; + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +// implementation of shortcut void caster +class void_caster_shortcut : public void_caster +{ + bool m_includes_virtual_base; + + void const * + vbc_upcast( + void const * const t + ) const; + void const * + vbc_downcast( + void const * const t + ) const; + virtual void const * + upcast(void const * const t) const{ + if(m_includes_virtual_base) + return vbc_upcast(t); + return static_cast<const char *> ( t ) - m_difference; + } + virtual void const * + downcast(void const * const t) const{ + if(m_includes_virtual_base) + return vbc_downcast(t); + return static_cast<const char *> ( t ) + m_difference; + } + virtual bool is_shortcut() const { + return true; + } + virtual bool has_virtual_base() const { + return m_includes_virtual_base; + } +public: + void_caster_shortcut( + extended_type_info const * derived, + extended_type_info const * base, + std::ptrdiff_t difference, + bool includes_virtual_base, + void_caster const * const parent + ) : + void_caster(derived, base, difference, parent), + m_includes_virtual_base(includes_virtual_base) + { + recursive_register(includes_virtual_base); + } + virtual ~void_caster_shortcut(){ + recursive_unregister(); + } +}; + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +void const * +void_caster_shortcut::vbc_downcast( + void const * const t +) const { + // try to find a chain that gives us what we want + const void_cast_detail::set_type & s + = void_cast_detail::void_caster_registry::get_const_instance(); + void_cast_detail::set_type::const_iterator it; + for(it = s.begin(); it != s.end(); ++it){ + // if the current candidate casts to the desired target type + if ((*it)->m_derived == m_derived){ + // and if it's not us + if ((*it)->m_base != m_base){ + // try to cast from the candidate base to our base + const void * t_new; + t_new = void_downcast(*(*it)->m_base, *m_base, t); + // if we were successful + if(NULL != t_new){ + // recast to our derived + const void_caster * vc = *it; + return vc->downcast(t_new); + } + } + } + } + return NULL; +} + +void const * +void_caster_shortcut::vbc_upcast( + void const * const t +) const { + // try to find a chain that gives us what we want + const void_cast_detail::set_type & s + = void_cast_detail::void_caster_registry::get_const_instance(); + void_cast_detail::set_type::const_iterator it; + for(it = s.begin(); it != s.end(); ++it){ + // if the current candidate casts from the desired base type + if((*it)->m_base == m_base){ + // and if it's not us + if ((*it)->m_derived != m_derived){ + // try to cast from the candidate derived to our our derived + const void * t_new; + t_new = void_upcast(*m_derived, *(*it)->m_derived, t); + if(NULL != t_new) + return (*it)->upcast(t_new); + } + } + } + return NULL; +} + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +// just used as a search key +class void_caster_argument : public void_caster +{ + virtual void const * + upcast(void const * const /*t*/) const { + BOOST_ASSERT(false); + return NULL; + } + virtual void const * + downcast( void const * const /*t*/) const { + BOOST_ASSERT(false); + return NULL; + } + virtual bool has_virtual_base() const { + BOOST_ASSERT(false); + return false; + } +public: + void_caster_argument( + extended_type_info const * derived, + extended_type_info const * base + ) : + void_caster(derived, base) + {} + virtual ~void_caster_argument(){}; +}; + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +// implementation of void caster base class +BOOST_SERIALIZATION_DECL(void) +void_caster::recursive_register(bool includes_virtual_base) const { + void_cast_detail::set_type & s + = void_cast_detail::void_caster_registry::get_mutable_instance(); + + #ifdef BOOST_SERIALIZATION_LOG + std::clog << "recursive_register\n"; + std::clog << m_derived->get_debug_info(); + std::clog << "<-"; + std::clog << m_base->get_debug_info(); + std::clog << "\n"; + #endif + + std::pair<void_cast_detail::set_type::const_iterator, bool> result; + // comment this out for now. + result = s.insert(this); + //assert(result.second); + + // generate all implied void_casts. + void_cast_detail::set_type::const_iterator it; + for(it = s.begin(); it != s.end(); ++it){ + if(* m_derived == * (*it)->m_base){ + const void_caster_argument vca( + (*it)->m_derived, + m_base + ); + void_cast_detail::set_type::const_iterator i; + i = s.find(& vca); + if(i == s.end()){ + new void_caster_shortcut( + (*it)->m_derived, + m_base, + m_difference + (*it)->m_difference, + (*it)->has_virtual_base() || includes_virtual_base, + this + ); + } + } + if(* (*it)->m_derived == * m_base){ + const void_caster_argument vca( + m_derived, + (*it)->m_base + ); + void_cast_detail::set_type::const_iterator i; + i = s.find(& vca); + if(i == s.end()){ + new void_caster_shortcut( + m_derived, + (*it)->m_base, + m_difference + (*it)->m_difference, + (*it)->has_virtual_base() || includes_virtual_base, + this + ); + } + } + } +} + +BOOST_SERIALIZATION_DECL(void) +void_caster::recursive_unregister() const { + if(void_caster_registry::is_destroyed()) + return; + + #ifdef BOOST_SERIALIZATION_LOG + std::clog << "recursive_unregister\n"; + std::clog << m_derived->get_debug_info(); + std::clog << "<-"; + std::clog << m_base->get_debug_info(); + std::clog << "\n"; + #endif + + void_cast_detail::set_type & s + = void_caster_registry::get_mutable_instance(); + + // delete all shortcuts which use this primitive + void_cast_detail::set_type::iterator it; + for(it = s.begin(); it != s.end();){ + const void_caster * vc = *it; + if(vc == this){ + s.erase(it++); + } + else + if(vc->m_parent == this){ + s.erase(it); + delete vc; + it = s.begin(); + } + else + it++; + } +} + +} // namespace void_cast_detail + +// Given a void *, assume that it really points to an instance of one type +// and alter it so that it would point to an instance of a related type. +// Return the altered pointer. If there exists no sequence of casts that +// can transform from_type to to_type, return a NULL. +BOOST_SERIALIZATION_DECL(void const *) +void_upcast( + extended_type_info const & derived, + extended_type_info const & base, + void const * const t +){ + // same types - trivial case + if (derived == base) + return t; + + // check to see if base/derived pair is found in the registry + const void_cast_detail::set_type & s + = void_cast_detail::void_caster_registry::get_const_instance(); + const void_cast_detail::void_caster_argument ca(& derived, & base); + + void_cast_detail::set_type::const_iterator it; + it = s.find(& ca); + if (s.end() != it) + return (*it)->upcast(t); + + return NULL; +} + +BOOST_SERIALIZATION_DECL(void const *) +void_downcast( + extended_type_info const & derived, + extended_type_info const & base, + void const * const t +){ + // same types - trivial case + if (derived == base) + return t; + + // check to see if base/derived pair is found in the registry + const void_cast_detail::set_type & s + = void_cast_detail::void_caster_registry::get_const_instance(); + const void_cast_detail::void_caster_argument ca(& derived, & base); + + void_cast_detail::set_type::const_iterator it; + it = s.find(&ca); + if (s.end() != it) + return(*it)->downcast(t); + + return NULL; +} + +} // namespace serialization +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/xml_archive_exception.cpp b/3rdParty/Boost/src/libs/serialization/src/xml_archive_exception.cpp new file mode 100644 index 0000000..41d33fd --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/xml_archive_exception.cpp @@ -0,0 +1,56 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_archive_exception.cpp: + +// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + + +#include <exception> +#include <boost/assert.hpp> +#include <string> + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/xml_archive_exception.hpp> + +namespace boost { +namespace archive { + +BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) +xml_archive_exception::xml_archive_exception( + exception_code c, + const char * e1, + const char * e2 + ) : + archive_exception(other_exception, e1, e2) + { + switch(c){ + case xml_archive_parsing_error: + archive_exception::append(0, "unrecognized XML syntax"); + break; + case xml_archive_tag_mismatch: + archive_exception::append(0, "XML start/end tag mismatch"); + if(NULL != e1){ + archive_exception::append(0, " - "); + archive_exception::append(0, e1); + } + break; + case xml_archive_tag_name_error: + archive_exception::append(0, "Invalid XML tag name"); + break; + default: + BOOST_ASSERT(false); + archive_exception::append(0, "programming error"); + break; + } + } + +} // archive +} // boost diff --git a/3rdParty/Boost/src/libs/serialization/src/xml_grammar.cpp b/3rdParty/Boost/src/libs/serialization/src/xml_grammar.cpp new file mode 100644 index 0000000..05904f4 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/xml_grammar.cpp @@ -0,0 +1,73 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_grammar.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/impl/basic_xml_grammar.hpp> + +using namespace boost::spirit::classic; + +#include <boost/config.hpp> + +// fixup for borland +// The following code will be put into Boost.Config in a later revision +#if ! defined(__SGI_STL_PORT) \ +&& defined(BOOST_RWSTD_VER) && BOOST_RWSTD_VER<=0x020101 +#include <string> +namespace std { + template<> + inline string & + string::replace ( + char * first1, + char * last1, + const char * first2, + const char * last2 + ){ + replace(first1-begin(),last1-first1,first2,last2-first2,0,last2-first2); + return *this; + } +} // namespace std +#endif + +namespace boost { +namespace archive { + +typedef basic_xml_grammar<char> xml_grammar; + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// specific definitions for char based XML + +template<> +void xml_grammar::init_chset(){ + Char = chset_t("\x9\xA\xD\x20-\x7f\x80\x81-\xFF"); + Letter = chset_t("\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF"); + Digit = chset_t("0-9"); + Extender = chset_t('\xB7'); + Sch = chset_t("\x20\x9\xD\xA"); + NameChar = Letter | Digit | chset_p("._:-") | Extender ; +} + +} // namespace archive +} // namespace boost + +#include "basic_xml_grammar.ipp" + +namespace boost { +namespace archive { + +// explicit instantiation of xml for 8 bit characters +template class basic_xml_grammar<char>; + +} // namespace archive +} // namespace boost + diff --git a/3rdParty/Boost/src/libs/serialization/src/xml_iarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/xml_iarchive.cpp new file mode 100644 index 0000000..4311893 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/xml_iarchive.cpp @@ -0,0 +1,42 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_iarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#define BOOST_ARCHIVE_SOURCE + +// the following works around an issue between spirit 1.61 and borland. +// it turns out the the certain spirit stuff must be defined before +// certain parts of mpl. including this here makes sure that happens +#include <boost/config.hpp> +#include <boost/detail/workaround.hpp> +#if BOOST_WORKAROUND(__BORLANDC__, <= 0x560 ) +#include <boost/archive/impl/basic_xml_grammar.hpp> +#endif + +#include <boost/archive/xml_iarchive.hpp> +#include <boost/archive/detail/archive_serializer_map.hpp> + +// explicitly instantiate for this type of xml stream +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_xml_iarchive.ipp> +#include <boost/archive/impl/xml_iarchive_impl.ipp> + +namespace boost { +namespace archive { + +template class detail::archive_serializer_map<xml_iarchive>; +template class basic_xml_iarchive<xml_iarchive> ; +template class xml_iarchive_impl<xml_iarchive> ; + +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/xml_oarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/xml_oarchive.cpp new file mode 100644 index 0000000..88bcdd6 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/xml_oarchive.cpp @@ -0,0 +1,32 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_oarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#define BOOST_ARCHIVE_SOURCE +#include <boost/archive/xml_oarchive.hpp> +#include <boost/archive/detail/archive_serializer_map.hpp> + +// explicitly instantiate for this type of xml stream +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_xml_oarchive.ipp> +#include <boost/archive/impl/xml_oarchive_impl.ipp> + +namespace boost { +namespace archive { + +template class detail::archive_serializer_map<xml_oarchive>; +template class basic_xml_oarchive<xml_oarchive> ; +template class xml_oarchive_impl<xml_oarchive> ; + +} // namespace archive +} // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/xml_wgrammar.cpp b/3rdParty/Boost/src/libs/serialization/src/xml_wgrammar.cpp new file mode 100644 index 0000000..d3dd844 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/xml_wgrammar.cpp @@ -0,0 +1,157 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_wgrammar.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> + +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#define BOOST_WARCHIVE_SOURCE +#include <boost/archive/impl/basic_xml_grammar.hpp> + +using namespace boost::spirit::classic; + +// fixup for RogueWave +#include <boost/config.hpp> +#if ! defined(__SGI_STL_PORT) \ +&& defined(BOOST_RWSTD_VER) && BOOST_RWSTD_VER<=0x020101 +#include <string> +namespace std { + template<> + inline wstring & + wstring::replace ( + wchar_t * first1, + wchar_t * last1, + const wchar_t * first2, + const wchar_t * last2 + ){ + replace(first1-begin(),last1-first1,first2,last2-first2,0,last2-first2); + return *this; + } +} // namespace std +#endif + +namespace boost { +namespace archive { + +typedef basic_xml_grammar<wchar_t> xml_wgrammar; + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// specific definitions for wchar_t based XML + +template<> +void xml_wgrammar::init_chset(){ + Char = chset_t( + #if defined(__GNUC__) && defined(linux) + L"\x9\xA\xD\x20-\xD7FF\xE000-\xFFFD\x10000-\x10FFFF" + #else + L"\x9\xA\xD\x20-\xD7FF\xE000-\xFFFD" + #endif + ); + + Sch = chset_t(L"\x20\x9\xD\xA"); + + BaseChar = chset_t( + L"\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF\x100-\x131\x134-\x13E" + L"\x141-\x148\x14A-\x17E\x180-\x1C3\x1CD-\x1F0\x1F4-\x1F5\x1FA-\x217" + L"\x250-\x2A8\x2BB-\x2C1\x386\x388-\x38A\x38C\x38E-\x3A1\x3A3-\x3CE" + L"\x3D0-\x3D6\x3DA\x3DC\x3DE\x3E0\x3E2-\x3F3\x401-\x40C\x40E-\x44F" + L"\x451-\x45C\x45E-\x481\x490-\x4C4\x4C7-\x4C8\x4CB-\x4CC\x4D0-\x4EB" + L"\x4EE-\x4F5\x4F8-\x4F9\x531-\x556\x559\x561-\x586\x5D0-\x5EA" + L"\x5F0-\x5F2\x621-\x63A\x641-\x64A\x671-\x6B7\x6BA-\x6BE\x6C0-\x6CE" + L"\x6D0-\x6D3\x6D5\x6E5-\x6E6\x905-\x939\x93D\x958-\x961\x985-\x98C" + L"\x98F-\x990\x993-\x9A8\x9AA-\x9B0\x9B2\x9B6-\x9B9\x9DC-\x9DD" + L"\x9DF-\x9E1\x9F0-\x9F1\xA05-\xA0A\xA0F-\xA10\xA13-\xA28\xA2A-\xA30" + L"\xA32-\xA33\xA35-\xA36\xA38-\xA39\xA59-\xA5C\xA5E\xA72-\xA74" + L"\xA85-\xA8B\xA8D\xA8F-\xA91\xA93-\xAA8\xAAA-\xAB0\xAB2-\xAB3" + L"\xAB5-\xAB9\xABD\xAE0\xB05-\xB0C\xB0F-\xB10\xB13-\xB28\xB2A-\xB30" + L"\xB32-\xB33\xB36-\xB39\xB3D\xB5C-\xB5D\xB5F-\xB61\xB85-\xB8A" + L"\xB8E-\xB90\xB92-\xB95\xB99-\xB9A\xB9C\xB9E-\xB9F\xBA3-\xBA4" + L"\xBA8-\xBAA\xBAE-\xBB5\xBB7-\xBB9\xC05-\xC0C\xC0E-\xC10\xC12-\xC28" + L"\xC2A-\xC33\xC35-\xC39\xC60-\xC61\xC85-\xC8C\xC8E-\xC90\xC92-\xCA8" + L"\xCAA-\xCB3\xCB5-\xCB9\xCDE\xCE0-\xCE1\xD05-\xD0C\xD0E-\xD10" + L"\xD12-\xD28\xD2A-\xD39\xD60-\xD61\xE01-\xE2E\xE30\xE32-\xE33" + L"\xE40-\xE45\xE81-\xE82\xE84\xE87-\xE88\xE8A\xE8D\xE94-\xE97" + L"\xE99-\xE9F\xEA1-\xEA3\xEA5\xEA7\xEAA-\xEAB\xEAD-\xEAE\xEB0" + L"\xEB2-\xEB3\xEBD\xEC0-\xEC4\xF40-\xF47\xF49-\xF69\x10A0-\x10C5" + L"\x10D0-\x10F6\x1100\x1102-\x1103\x1105-\x1107\x1109\x110B-\x110C" + L"\x110E-\x1112\x113C\x113E\x1140\x114C\x114E\x1150\x1154-\x1155" + L"\x1159\x115F-\x1161\x1163\x1165\x1167\x1169\x116D-\x116E" + L"\x1172-\x1173\x1175\x119E\x11A8\x11AB\x11AE-\x11AF\x11B7-\x11B8" + L"\x11BA\x11BC-\x11C2\x11EB\x11F0\x11F9\x1E00-\x1E9B\x1EA0-\x1EF9" + L"\x1F00-\x1F15\x1F18-\x1F1D\x1F20-\x1F45\x1F48-\x1F4D\x1F50-\x1F57" + L"\x1F59\x1F5B\x1F5D\x1F5F-\x1F7D\x1F80-\x1FB4\x1FB6-\x1FBC\x1FBE" + L"\x1FC2-\x1FC4\x1FC6-\x1FCC\x1FD0-\x1FD3\x1FD6-\x1FDB\x1FE0-\x1FEC" + L"\x1FF2-\x1FF4\x1FF6-\x1FFC\x2126\x212A-\x212B\x212E\x2180-\x2182" + L"\x3041-\x3094\x30A1-\x30FA\x3105-\x312C\xAC00-\xD7A3" + ); + + Ideographic = chset_t(L"\x4E00-\x9FA5\x3007\x3021-\x3029"); + + Letter = BaseChar | Ideographic; + + CombiningChar = chset_t( + L"\x0300-\x0345\x0360-\x0361\x0483-\x0486\x0591-\x05A1\x05A3-\x05B9" + L"\x05BB-\x05BD\x05BF\x05C1-\x05C2\x05C4\x064B-\x0652\x0670" + L"\x06D6-\x06DC\x06DD-\x06DF\x06E0-\x06E4\x06E7-\x06E8\x06EA-\x06ED" + L"\x0901-\x0903\x093C\x093E-\x094C\x094D\x0951-\x0954\x0962-\x0963" + L"\x0981-\x0983\x09BC\x09BE\x09BF\x09C0-\x09C4\x09C7-\x09C8" + L"\x09CB-\x09CD\x09D7\x09E2-\x09E3\x0A02\x0A3C\x0A3E\x0A3F" + L"\x0A40-\x0A42\x0A47-\x0A48\x0A4B-\x0A4D\x0A70-\x0A71\x0A81-\x0A83" + L"\x0ABC\x0ABE-\x0AC5\x0AC7-\x0AC9\x0ACB-\x0ACD\x0B01-\x0B03\x0B3C" + L"\x0B3E-\x0B43\x0B47-\x0B48\x0B4B-\x0B4D\x0B56-\x0B57\x0B82-\x0B83" + L"\x0BBE-\x0BC2\x0BC6-\x0BC8\x0BCA-\x0BCD\x0BD7\x0C01-\x0C03" + L"\x0C3E-\x0C44\x0C46-\x0C48\x0C4A-\x0C4D\x0C55-\x0C56\x0C82-\x0C83" + L"\x0CBE-\x0CC4\x0CC6-\x0CC8\x0CCA-\x0CCD\x0CD5-\x0CD6\x0D02-\x0D03" + L"\x0D3E-\x0D43\x0D46-\x0D48\x0D4A-\x0D4D\x0D57\x0E31\x0E34-\x0E3A" + L"\x0E47-\x0E4E\x0EB1\x0EB4-\x0EB9\x0EBB-\x0EBC\x0EC8-\x0ECD" + L"\x0F18-\x0F19\x0F35\x0F37\x0F39\x0F3E\x0F3F\x0F71-\x0F84" + L"\x0F86-\x0F8B\x0F90-\x0F95\x0F97\x0F99-\x0FAD\x0FB1-\x0FB7\x0FB9" + L"\x20D0-\x20DC\x20E1\x302A-\x302F\x3099\x309A" + ); + + Digit = chset_t( + L"\x0030-\x0039\x0660-\x0669\x06F0-\x06F9\x0966-\x096F\x09E6-\x09EF" + L"\x0A66-\x0A6F\x0AE6-\x0AEF\x0B66-\x0B6F\x0BE7-\x0BEF\x0C66-\x0C6F" + L"\x0CE6-\x0CEF\x0D66-\x0D6F\x0E50-\x0E59\x0ED0-\x0ED9\x0F20-\x0F29" + ); + + Extender = chset_t( + L"\x00B7\x02D0\x02D1\x0387\x0640\x0E46\x0EC6\x3005\x3031-\x3035" + L"\x309D-\x309E\x30FC-\x30FE" + ); + + NameChar = + Letter + | Digit + | L'.' + | L'-' + | L'_' + | L':' + | CombiningChar + | Extender + ; +} +} // namespace archive +} // namespace boost + +#include "basic_xml_grammar.ipp" + +namespace boost { +namespace archive { + +// explicit instantiation of xml for wide characters +template class basic_xml_grammar<wchar_t>; + +} // namespace archive +} // namespace boost + +#endif diff --git a/3rdParty/Boost/src/libs/serialization/src/xml_wiarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/xml_wiarchive.cpp new file mode 100644 index 0000000..0266548 --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/xml_wiarchive.cpp @@ -0,0 +1,49 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_wiarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include <boost/detail/workaround.hpp> + +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#define BOOST_WARCHIVE_SOURCE + +// the following works around an issue between spirit 1.61 and borland. +// it turns out the the certain spirit stuff must be defined before +// certain parts of mpl. including this here makes sure that happens +#if BOOST_WORKAROUND(__BORLANDC__, <= 0x560 ) +#include <boost/archive/impl/basic_xml_grammar.hpp> +#endif + +#include <boost/archive/xml_wiarchive.hpp> +#include <boost/archive/detail/archive_serializer_map.hpp> + +// explicitly instantiate for this type of xml stream +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_xml_iarchive.ipp> +#include <boost/archive/impl/xml_wiarchive_impl.ipp> + +namespace boost { +namespace archive { + +template class detail::archive_serializer_map<xml_wiarchive>; +template class basic_xml_iarchive<xml_wiarchive> ; +template class xml_wiarchive_impl<xml_wiarchive> ; + +} // namespace archive +} // namespace boost + +#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/3rdParty/Boost/src/libs/serialization/src/xml_woarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/xml_woarchive.cpp new file mode 100644 index 0000000..e71daaf --- /dev/null +++ b/3rdParty/Boost/src/libs/serialization/src/xml_woarchive.cpp @@ -0,0 +1,35 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_woarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include <boost/config.hpp> +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#define BOOST_WARCHIVE_SOURCE +#include <boost/archive/xml_woarchive.hpp> +#include <boost/archive/detail/archive_serializer_map.hpp> + +// explicitly instantiate for this type of text stream +#include <boost/archive/impl/archive_serializer_map.ipp> +#include <boost/archive/impl/basic_xml_oarchive.ipp> +#include <boost/archive/impl/xml_woarchive_impl.ipp> + +namespace boost { +namespace archive { + +template class detail::archive_serializer_map<xml_woarchive>; +template class basic_xml_oarchive<xml_woarchive> ; +template class xml_woarchive_impl<xml_woarchive> ; + +} // namespace archive +} // namespace boost + +#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/3rdParty/Boost/src/libs/signals/src/named_slot_map.cpp b/3rdParty/Boost/src/libs/signals/src/named_slot_map.cpp index 1ddde63..2fe2790 100644 --- a/3rdParty/Boost/src/libs/signals/src/named_slot_map.cpp +++ b/3rdParty/Boost/src/libs/signals/src/named_slot_map.cpp @@ -25,5 +25,5 @@ typedef slot_container_type::const_iterator const_group_iterator; -#if BOOST_WORKAROUND(_MSC_VER, <= 1600) +#if BOOST_WORKAROUND(_MSC_VER, <= 1900) void named_slot_map_iterator::decrement() { assert(false); } void named_slot_map_iterator::advance(difference_type) { assert(false); } @@ -103,5 +103,5 @@ void named_slot_map::disconnect(const stored_group& name) i = next; } - groups.erase(group); + groups.erase((const_group_iterator) group); } } @@ -126,5 +126,5 @@ void named_slot_map::remove_disconnected_slots() // Clear out empty groups - if (empty(g)) groups.erase(g++); + if (empty(g)) groups.erase((const_group_iterator) g++); else ++g; } diff --git a/3rdParty/Boost/src/libs/system/src/error_code.cpp b/3rdParty/Boost/src/libs/system/src/error_code.cpp index bcdbea9..aa628ab 100644 --- a/3rdParty/Boost/src/libs/system/src/error_code.cpp +++ b/3rdParty/Boost/src/libs/system/src/error_code.cpp @@ -10,420 +10,11 @@ //----------------------------------------------------------------------------// -#include <boost/config/warning_disable.hpp> - // define BOOST_SYSTEM_SOURCE so that <boost/system/config.hpp> knows // the library is being built (possibly exporting rather than importing code) #define BOOST_SYSTEM_SOURCE -#include <boost/system/config.hpp> #include <boost/system/error_code.hpp> -#include <boost/cerrno.hpp> -#include <vector> -#include <cstdlib> -#include <cassert> - -using namespace boost::system; -using namespace boost::system::errc; - -#include <cstring> // for strerror/strerror_r - -# 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 -# endif -# endif - -//----------------------------------------------------------------------------// -namespace -{ -#if defined(__PGI) - using boost::system::errc::invalid_argument; +#ifndef BOOST_ERROR_CODE_HEADER_ONLY +#include <boost/system/detail/error_code.ipp> #endif - // standard error categories ---------------------------------------------// - - class generic_error_category : public error_category - { - public: - generic_error_category(){} - const char * name() const; - std::string message( int ev ) const; - }; - - class system_error_category : public error_category - { - public: - system_error_category(){} - const char * name() const; - std::string message( int ev ) const; - error_condition default_error_condition( int ev ) const; - }; - - // generic_error_category implementation ---------------------------------// - - const char * generic_error_category::name() const - { - return "generic"; - } - - std::string generic_error_category::message( int ev ) const - { - static std::string unknown_err( "Unknown error" ); - // strerror_r is preferred because it is always thread safe, - // however, we fallback to strerror in certain cases because: - // -- Windows doesn't provide strerror_r. - // -- HP and Sundo provide strerror_r on newer systems, but there is - // no way to tell if is available at runtime and in any case their - // versions of strerror are thread safe anyhow. - // -- Linux only sometimes provides strerror_r. - // -- Tru64 provides strerror_r only when compiled -pthread. - // -- VMS doesn't provide strerror_r, but on this platform, strerror is - // thread safe. - # if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\ - || (defined(__linux) && (!defined(__USE_XOPEN2K) || defined(BOOST_SYSTEM_USE_STRERROR)))\ - || (defined(__osf__) && !defined(_REENTRANT))\ - || (defined(__vms))\ - || (defined(__QNXNTO__)) - const char * c_str = std::strerror( ev ); - return c_str - ? std::string( c_str ) - : unknown_err; - # else // use strerror_r - char buf[64]; - char * bp = buf; - std::size_t sz = sizeof(buf); - # if defined(__CYGWIN__) || defined(__USE_GNU) - // Oddball version of strerror_r - const char * c_str = strerror_r( ev, bp, sz ); - return c_str - ? std::string( c_str ) - : unknown_err; - # else - // POSIX version of strerror_r - int result; - for (;;) - { - // strerror_r returns 0 on success, otherwise ERANGE if buffer too small, - // invalid_argument if ev not a valid error number - # if defined (__sgi) - const char * c_str = strerror( ev ); - result = 0; - return c_str - ? std::string( c_str ) - : unknown_err; - # else - result = strerror_r( ev, bp, sz ); - # endif - if (result == 0 ) - break; - else - { - # if defined(__linux) - // Linux strerror_r returns -1 on error, with error number in errno - result = errno; - # endif - if ( result != ERANGE ) break; - if ( sz > sizeof(buf) ) std::free( bp ); - sz *= 2; - if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 ) - return std::string( "ENOMEM" ); - } - } - std::string msg; - try - { - msg = ( ( result == invalid_argument ) ? "Unknown error" : bp ); - } - -# ifndef BOOST_NO_EXCEPTIONS - // See ticket #2098 - catch(...) - { - // just eat the exception - } -# endif - - if ( sz > sizeof(buf) ) std::free( bp ); - sz = 0; - return msg; - # endif // else POSIX version of strerror_r - # endif // else use strerror_r - } - // system_error_category implementation --------------------------------// - - const char * system_error_category::name() const - { - return "system"; - } - - error_condition system_error_category::default_error_condition( int ev ) const - { - switch ( ev ) - { - case 0: return make_error_condition( success ); -# 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 ); - case EADDRINUSE: return make_error_condition( address_in_use ); - case EADDRNOTAVAIL: return make_error_condition( address_not_available ); - case EAFNOSUPPORT: return make_error_condition( address_family_not_supported ); - case EAGAIN: return make_error_condition( resource_unavailable_try_again ); -# if EALREADY != EBUSY // EALREADY and EBUSY are the same on QNX Neutrino - case EALREADY: return make_error_condition( connection_already_in_progress ); -# endif - case EBADF: return make_error_condition( bad_file_descriptor ); - case EBADMSG: return make_error_condition( bad_message ); - case EBUSY: return make_error_condition( device_or_resource_busy ); - case ECANCELED: return make_error_condition( operation_canceled ); - case ECHILD: return make_error_condition( no_child_process ); - case ECONNABORTED: return make_error_condition( connection_aborted ); - case ECONNREFUSED: return make_error_condition( connection_refused ); - case ECONNRESET: return make_error_condition( connection_reset ); - case EDEADLK: return make_error_condition( resource_deadlock_would_occur ); - case EDESTADDRREQ: return make_error_condition( destination_address_required ); - case EDOM: return make_error_condition( argument_out_of_domain ); - case EEXIST: return make_error_condition( file_exists ); - case EFAULT: return make_error_condition( bad_address ); - case EFBIG: return make_error_condition( file_too_large ); - case EHOSTUNREACH: return make_error_condition( host_unreachable ); - case EIDRM: return make_error_condition( identifier_removed ); - case EILSEQ: return make_error_condition( illegal_byte_sequence ); - case EINPROGRESS: return make_error_condition( operation_in_progress ); - case EINTR: return make_error_condition( interrupted ); - case EINVAL: return make_error_condition( invalid_argument ); - case EIO: return make_error_condition( io_error ); - case EISCONN: return make_error_condition( already_connected ); - case EISDIR: return make_error_condition( is_a_directory ); - case ELOOP: return make_error_condition( too_many_symbolic_link_levels ); - case EMFILE: return make_error_condition( too_many_files_open ); - case EMLINK: return make_error_condition( too_many_links ); - case EMSGSIZE: return make_error_condition( message_size ); - case ENAMETOOLONG: return make_error_condition( filename_too_long ); - case ENETDOWN: return make_error_condition( network_down ); - case ENETRESET: return make_error_condition( network_reset ); - case ENETUNREACH: return make_error_condition( network_unreachable ); - case ENFILE: return make_error_condition( too_many_files_open_in_system ); - case ENOBUFS: return make_error_condition( no_buffer_space ); - case ENODATA: return make_error_condition( no_message_available ); - case ENODEV: return make_error_condition( no_such_device ); - case ENOENT: return make_error_condition( no_such_file_or_directory ); - case ENOEXEC: return make_error_condition( executable_format_error ); - case ENOLCK: return make_error_condition( no_lock_available ); - case ENOLINK: return make_error_condition( no_link ); - case ENOMEM: return make_error_condition( not_enough_memory ); - case ENOMSG: return make_error_condition( no_message ); - case ENOPROTOOPT: return make_error_condition( no_protocol_option ); - case ENOSPC: return make_error_condition( no_space_on_device ); - case ENOSR: return make_error_condition( no_stream_resources ); - case ENOSTR: return make_error_condition( not_a_stream ); - case ENOSYS: return make_error_condition( function_not_supported ); - case ENOTCONN: return make_error_condition( not_connected ); - case ENOTDIR: return make_error_condition( not_a_directory ); - # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value - case ENOTEMPTY: return make_error_condition( directory_not_empty ); - # endif // ENOTEMPTY != EEXIST - # 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 ); - case ENXIO: return make_error_condition( no_such_device_or_address ); - # if EOPNOTSUPP != ENOTSUP - case EOPNOTSUPP: return make_error_condition( operation_not_supported ); - # endif // EOPNOTSUPP != ENOTSUP - case EOVERFLOW: return make_error_condition( value_too_large ); - # 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 ); - case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); - case EPROTOTYPE: return make_error_condition( wrong_protocol_type ); - case ERANGE: return make_error_condition( result_out_of_range ); - case EROFS: return make_error_condition( read_only_file_system ); - case ESPIPE: return make_error_condition( invalid_seek ); - case ESRCH: return make_error_condition( no_such_process ); - case ETIME: return make_error_condition( stream_timeout ); - case ETIMEDOUT: return make_error_condition( timed_out ); - case ETXTBSY: return make_error_condition( text_file_busy ); - # if EAGAIN != EWOULDBLOCK - case EWOULDBLOCK: return make_error_condition( operation_would_block ); - # endif // EAGAIN != EWOULDBLOCK - case EXDEV: return make_error_condition( cross_device_link ); - #else - // Windows system -> posix_errno decode table ---------------------------// - // see WinError.h comments for descriptions of errors - case ERROR_ACCESS_DENIED: return make_error_condition( permission_denied ); - case ERROR_ALREADY_EXISTS: return make_error_condition( file_exists ); - case ERROR_BAD_UNIT: return make_error_condition( no_such_device ); - case ERROR_BUFFER_OVERFLOW: return make_error_condition( filename_too_long ); - case ERROR_BUSY: return make_error_condition( device_or_resource_busy ); - case ERROR_BUSY_DRIVE: return make_error_condition( device_or_resource_busy ); - case ERROR_CANNOT_MAKE: return make_error_condition( permission_denied ); - case ERROR_CANTOPEN: return make_error_condition( io_error ); - case ERROR_CANTREAD: return make_error_condition( io_error ); - case ERROR_CANTWRITE: return make_error_condition( io_error ); - case ERROR_CURRENT_DIRECTORY: return make_error_condition( permission_denied ); - case ERROR_DEV_NOT_EXIST: return make_error_condition( no_such_device ); - case ERROR_DEVICE_IN_USE: return make_error_condition( device_or_resource_busy ); - case ERROR_DIR_NOT_EMPTY: return make_error_condition( directory_not_empty ); - case ERROR_DIRECTORY: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid" - case ERROR_DISK_FULL: return make_error_condition( no_space_on_device ); - case ERROR_FILE_EXISTS: return make_error_condition( file_exists ); - case ERROR_FILE_NOT_FOUND: return make_error_condition( no_such_file_or_directory ); - case ERROR_HANDLE_DISK_FULL: return make_error_condition( no_space_on_device ); - case ERROR_INVALID_ACCESS: return make_error_condition( permission_denied ); - case ERROR_INVALID_DRIVE: return make_error_condition( no_such_device ); - case ERROR_INVALID_FUNCTION: return make_error_condition( function_not_supported ); - case ERROR_INVALID_HANDLE: return make_error_condition( invalid_argument ); - case ERROR_INVALID_NAME: return make_error_condition( invalid_argument ); - case ERROR_LOCK_VIOLATION: return make_error_condition( no_lock_available ); - case ERROR_LOCKED: return make_error_condition( no_lock_available ); - case ERROR_NEGATIVE_SEEK: return make_error_condition( invalid_argument ); - case ERROR_NOACCESS: return make_error_condition( permission_denied ); - case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition( not_enough_memory ); - case ERROR_NOT_READY: return make_error_condition( resource_unavailable_try_again ); - case ERROR_NOT_SAME_DEVICE: return make_error_condition( cross_device_link ); - case ERROR_OPEN_FAILED: return make_error_condition( io_error ); - case ERROR_OPEN_FILES: return make_error_condition( device_or_resource_busy ); - case ERROR_OPERATION_ABORTED: return make_error_condition( operation_canceled ); - case ERROR_OUTOFMEMORY: return make_error_condition( not_enough_memory ); - case ERROR_PATH_NOT_FOUND: return make_error_condition( no_such_file_or_directory ); - case ERROR_READ_FAULT: return make_error_condition( io_error ); - case ERROR_RETRY: return make_error_condition( resource_unavailable_try_again ); - case ERROR_SEEK: return make_error_condition( io_error ); - case ERROR_SHARING_VIOLATION: return make_error_condition( permission_denied ); - case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition( too_many_files_open ); - case ERROR_WRITE_FAULT: return make_error_condition( io_error ); - case ERROR_WRITE_PROTECT: return make_error_condition( permission_denied ); - case WSAEACCES: return make_error_condition( permission_denied ); - case WSAEADDRINUSE: return make_error_condition( address_in_use ); - case WSAEADDRNOTAVAIL: return make_error_condition( address_not_available ); - case WSAEAFNOSUPPORT: return make_error_condition( address_family_not_supported ); - case WSAEALREADY: return make_error_condition( connection_already_in_progress ); - case WSAEBADF: return make_error_condition( bad_file_descriptor ); - case WSAECONNABORTED: return make_error_condition( connection_aborted ); - case WSAECONNREFUSED: return make_error_condition( connection_refused ); - case WSAECONNRESET: return make_error_condition( connection_reset ); - case WSAEDESTADDRREQ: return make_error_condition( destination_address_required ); - case WSAEFAULT: return make_error_condition( bad_address ); - case WSAEHOSTUNREACH: return make_error_condition( host_unreachable ); - case WSAEINPROGRESS: return make_error_condition( operation_in_progress ); - case WSAEINTR: return make_error_condition( interrupted ); - case WSAEINVAL: return make_error_condition( invalid_argument ); - case WSAEISCONN: return make_error_condition( already_connected ); - case WSAEMFILE: return make_error_condition( too_many_files_open ); - case WSAEMSGSIZE: return make_error_condition( message_size ); - case WSAENAMETOOLONG: return make_error_condition( filename_too_long ); - case WSAENETDOWN: return make_error_condition( network_down ); - case WSAENETRESET: return make_error_condition( network_reset ); - case WSAENETUNREACH: return make_error_condition( network_unreachable ); - case WSAENOBUFS: return make_error_condition( no_buffer_space ); - case WSAENOPROTOOPT: return make_error_condition( no_protocol_option ); - case WSAENOTCONN: return make_error_condition( not_connected ); - case WSAENOTSOCK: return make_error_condition( not_a_socket ); - case WSAEOPNOTSUPP: return make_error_condition( operation_not_supported ); - case WSAEPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); - case WSAEPROTOTYPE: return make_error_condition( wrong_protocol_type ); - 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() ); - } - } - -# if !defined( BOOST_WINDOWS_API ) - - std::string system_error_category::message( int ev ) const - { - return generic_category().message( ev ); - } -# else - - std::string system_error_category::message( int ev ) const - { -# ifndef BOOST_NO_ANSI_APIS - LPVOID lpMsgBuf = 0; - DWORD retval = ::FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - ev, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPSTR) &lpMsgBuf, - 0, - NULL - ); - detail::local_free_on_destruction lfod(lpMsgBuf); - if (retval == 0) - return std::string("Unknown error"); - - std::string str( static_cast<LPCSTR>(lpMsgBuf) ); -# else // WinCE workaround - LPVOID lpMsgBuf = 0; - DWORD retval = ::FormatMessageW( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - ev, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPWSTR) &lpMsgBuf, - 0, - NULL - ); - detail::local_free_on_destruction lfod(lpMsgBuf); - if (retval == 0) - return std::string("Unknown error"); - - int num_chars = (wcslen( static_cast<LPCWSTR>(lpMsgBuf) ) + 1) * 2; - LPSTR narrow_buffer = (LPSTR)_alloca( num_chars ); - if (::WideCharToMultiByte(CP_ACP, 0, static_cast<LPCWSTR>(lpMsgBuf), -1, narrow_buffer, num_chars, NULL, NULL) == 0) - return std::string("Unknown error"); - - std::string str( narrow_buffer ); -# endif - while ( str.size() - && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) - str.erase( str.size()-1 ); - if ( str.size() && str[str.size()-1] == '.' ) - { str.erase( str.size()-1 ); } - return str; - } -# endif - -} // unnamed namespace - -namespace boost -{ - namespace system - { - -# ifndef BOOST_SYSTEM_NO_DEPRECATED - BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code; - // note that it doesn't matter if this - // isn't initialized before use since - // the only use is to take its - // address for comparison purposes -# endif - - 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 & generic_category() - { - static const generic_error_category generic_category_const; - return generic_category_const; - } - - } // namespace system -} // namespace boost 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 deleted file mode 100644 index 110024f..0000000 --- a/3rdParty/Boost/src/libs/system/src/local_free_on_destruction.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// 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/future.cpp b/3rdParty/Boost/src/libs/thread/src/future.cpp new file mode 100644 index 0000000..0b990c1 --- /dev/null +++ b/3rdParty/Boost/src/libs/thread/src/future.cpp @@ -0,0 +1,64 @@ +// (C) Copyright 2012 Vicente J. Botet Escriba +// 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) + +#include <boost/thread/detail/config.hpp> +#ifndef BOOST_NO_EXCEPTIONS + + +#include <boost/thread/future_error_code.hpp> +#include <string> + +namespace boost +{ + + namespace thread_detail + { + + class future_error_category : + public boost::system::error_category + { + public: + virtual const char* name() const BOOST_NOEXCEPT; + virtual std::string message(int ev) const; + }; + + const char* + future_error_category::name() const BOOST_NOEXCEPT + { + return "future"; + } + + std::string + future_error_category::message(int ev) const + { + switch (BOOST_SCOPED_ENUM_NATIVE(future_errc)(ev)) + { + case future_errc::broken_promise: + return std::string("The associated promise has been destructed prior " + "to the associated state becoming ready."); + case future_errc::future_already_retrieved: + return std::string("The future has already been retrieved from " + "the promise or packaged_task."); + case future_errc::promise_already_satisfied: + return std::string("The state of the promise has already been set."); + case future_errc::no_state: + return std::string("Operation not permitted on an object without " + "an associated state."); + } + return std::string("unspecified future_errc value\n"); + } + future_error_category future_error_category_var; + } + + BOOST_THREAD_DECL + const system::error_category& + future_category() BOOST_NOEXCEPT + { + return thread_detail::future_error_category_var; + } + +} +#endif + diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp b/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp index 6e3722a..2cfe7cd 100644 --- a/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp +++ b/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp @@ -4,15 +4,22 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#include <boost/thread/detail/config.hpp> +#ifdef BOOST_THREAD_ONCE_ATOMIC +#include "./once_atomic.cpp" +#else #define __STDC_CONSTANT_MACROS +#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> #include <boost/thread/once.hpp> #include <boost/assert.hpp> +#include <boost/throw_exception.hpp> #include <pthread.h> #include <stdlib.h> +#include <memory> namespace boost { - namespace detail + namespace thread_detail { - BOOST_THREAD_DECL boost::uintmax_t once_global_epoch=UINTMAX_C(~0); + BOOST_THREAD_DECL uintmax_atomic_t once_global_epoch=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C; BOOST_THREAD_DECL pthread_mutex_t once_epoch_mutex=PTHREAD_MUTEX_INITIALIZER; BOOST_THREAD_DECL pthread_cond_t once_epoch_cv = PTHREAD_COND_INITIALIZER; @@ -23,17 +30,37 @@ namespace boost pthread_once_t epoch_tss_key_flag=PTHREAD_ONCE_INIT; - extern "C" void delete_epoch_tss_data(void* data) + extern "C" + { + static void delete_epoch_tss_data(void* data) { free(data); } - extern "C" void create_epoch_tss_key() + static void create_epoch_tss_key() { BOOST_VERIFY(!pthread_key_create(&epoch_tss_key,delete_epoch_tss_data)); } + } +#if defined BOOST_THREAD_PATCH + const pthread_once_t pthread_once_init_value=PTHREAD_ONCE_INIT; + struct BOOST_THREAD_DECL delete_epoch_tss_key_on_dlclose_t + { + delete_epoch_tss_key_on_dlclose_t() + { + } + ~delete_epoch_tss_key_on_dlclose_t() + { + if(memcmp(&epoch_tss_key_flag, &pthread_once_init_value, sizeof(pthread_once_t))) + { + pthread_key_delete(epoch_tss_key); + } + } + }; + delete_epoch_tss_key_on_dlclose_t delete_epoch_tss_key_on_dlclose; +#endif } - boost::uintmax_t& get_once_per_thread_epoch() + uintmax_atomic_t& get_once_per_thread_epoch() { BOOST_VERIFY(!pthread_once(&epoch_tss_key_flag,create_epoch_tss_key)); @@ -41,11 +68,13 @@ namespace boost if(!data) { - data=malloc(sizeof(boost::uintmax_t)); + data=malloc(sizeof(thread_detail::uintmax_atomic_t)); + if(!data) BOOST_THROW_EXCEPTION(std::bad_alloc()); BOOST_VERIFY(!pthread_setspecific(epoch_tss_key,data)); - *static_cast<boost::uintmax_t*>(data)=UINTMAX_C(~0); + *static_cast<thread_detail::uintmax_atomic_t*>(data)=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C; } - return *static_cast<boost::uintmax_t*>(data); + return *static_cast<thread_detail::uintmax_atomic_t*>(data); } } } +#endif // diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/once_atomic.cpp b/3rdParty/Boost/src/libs/thread/src/pthread/once_atomic.cpp new file mode 100644 index 0000000..b7ee1dc --- /dev/null +++ b/3rdParty/Boost/src/libs/thread/src/pthread/once_atomic.cpp @@ -0,0 +1,90 @@ +// (C) Copyright 2013 Andrey Semashev +// (C) Copyright 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +//#define __STDC_CONSTANT_MACROS +#include <boost/thread/detail/config.hpp> +#include <boost/thread/once.hpp> +#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> +#include <boost/assert.hpp> +#include <boost/static_assert.hpp> +#include <boost/atomic.hpp> +#include <boost/memory_order.hpp> +#include <pthread.h> + +namespace boost +{ + namespace thread_detail + { + + enum flag_states + { + uninitialized, in_progress, initialized + }; + + +#ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11 + BOOST_STATIC_ASSERT_MSG(sizeof(atomic_int_type) == sizeof(atomic_type), "Boost.Thread: unsupported platform"); +#endif + + static pthread_mutex_t once_mutex = PTHREAD_MUTEX_INITIALIZER; + static pthread_cond_t once_cv = PTHREAD_COND_INITIALIZER; + + BOOST_THREAD_DECL bool enter_once_region(once_flag& flag) BOOST_NOEXCEPT + { + atomic_type& f = get_atomic_storage(flag); + if (f.load(memory_order_acquire) != initialized) + { + pthread::pthread_mutex_scoped_lock lk(&once_mutex); + if (f.load(memory_order_acquire) != initialized) + { + while (true) + { + atomic_int_type expected = uninitialized; + if (f.compare_exchange_strong(expected, in_progress, memory_order_acq_rel, memory_order_acquire)) + { + // We have set the flag to in_progress + return true; + } + else if (expected == initialized) + { + // Another thread managed to complete the initialization + return false; + } + else + { + // Wait until the initialization is complete + //pthread::pthread_mutex_scoped_lock lk(&once_mutex); + BOOST_VERIFY(!pthread_cond_wait(&once_cv, &once_mutex)); + } + } + } + } + return false; + } + + BOOST_THREAD_DECL void commit_once_region(once_flag& flag) BOOST_NOEXCEPT + { + atomic_type& f = get_atomic_storage(flag); + { + pthread::pthread_mutex_scoped_lock lk(&once_mutex); + f.store(initialized, memory_order_release); + } + BOOST_VERIFY(!pthread_cond_broadcast(&once_cv)); + } + + BOOST_THREAD_DECL void rollback_once_region(once_flag& flag) BOOST_NOEXCEPT + { + atomic_type& f = get_atomic_storage(flag); + { + pthread::pthread_mutex_scoped_lock lk(&once_mutex); + f.store(uninitialized, memory_order_release); + } + BOOST_VERIFY(!pthread_cond_broadcast(&once_cv)); + } + + } // namespace thread_detail + +} // namespace boost diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp b/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp index 187c024..f218fa8 100644 --- a/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp +++ b/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp @@ -2,4 +2,5 @@ // William E. Kempf // Copyright (C) 2007-8 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba // // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -8,12 +9,15 @@ #include <boost/thread/detail/config.hpp> -#include <boost/thread/thread.hpp> +#include <boost/thread/thread_only.hpp> +#if defined BOOST_THREAD_USES_DATETIME #include <boost/thread/xtime.hpp> -#include <boost/thread/condition.hpp> +#endif +#include <boost/thread/condition_variable.hpp> #include <boost/thread/locks.hpp> #include <boost/thread/once.hpp> #include <boost/thread/tss.hpp> -#include <boost/throw_exception.hpp> -#ifdef __linux__ +#include <boost/thread/future.hpp> + +#ifdef __GLIBC__ #include <sys/sysinfo.h> #elif defined(__APPLE__) || defined(__FreeBSD__) @@ -24,5 +28,16 @@ #endif -#include "timeconv.inl" +#include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/trim.hpp> +#include <boost/lexical_cast.hpp> + +#include <fstream> +#include <string> +#include <set> +#include <vector> + +#include "./timeconv.inl" + +#pragma GCC diagnostic ignored "-Wreturn-type" namespace boost @@ -31,5 +46,17 @@ namespace boost { thread_data_base::~thread_data_base() - {} + { + for (notify_list_t::iterator i = notify.begin(), e = notify.end(); + i != e; ++i) + { + i->second->unlock(); + i->first->notify_all(); + } + for (async_states_t::iterator i = async_states_.begin(), e = async_states_.end(); + i != e; ++i) + { + (*i)->make_ready(); + } + } struct thread_exit_callback_node @@ -46,10 +73,14 @@ namespace boost namespace { +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 + boost::once_flag current_thread_tls_init_flag; +#else boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT; +#endif pthread_key_t current_thread_tls_key; extern "C" { - void tls_destructor(void* data) + static void tls_destructor(void* data) { boost::detail::thread_data_base* thread_info=static_cast<boost::detail::thread_data_base*>(data); @@ -58,4 +89,5 @@ namespace boost while(!thread_info->tss_data.empty() || thread_info->thread_exit_callbacks) { + while(thread_info->thread_exit_callbacks) { @@ -83,9 +115,29 @@ namespace boost } } + if (thread_info) // fixme: should we test this? + { thread_info->self.reset(); } } } + } +#if defined BOOST_THREAD_PATCH + + struct delete_current_thread_tls_key_on_dlclose_t + { + delete_current_thread_tls_key_on_dlclose_t() + { + } + ~delete_current_thread_tls_key_on_dlclose_t() + { + if (current_thread_tls_init_flag.epoch!=BOOST_ONCE_INITIAL_FLAG_VALUE) + { + pthread_key_delete(current_thread_tls_key); + } + } + }; + delete_current_thread_tls_key_on_dlclose_t delete_current_thread_tls_key_on_dlclose; +#endif void create_current_thread_tls_key() @@ -112,23 +164,30 @@ namespace boost extern "C" { - void* thread_proxy(void* param) + static void* thread_proxy(void* param) { boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(param)->self; thread_info->self.reset(); detail::set_current_thread_data(thread_info.get()); - try +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS + BOOST_TRY { +#endif thread_info->run(); +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS + } - catch(thread_interrupted const&) + BOOST_CATCH (thread_interrupted const&) { } // Removed as it stops the debugger identifying the cause of the exception // Unhandled exceptions still cause the application to terminate -// catch(...) +// BOOST_CATCH(...) // { +// throw; +// // std::terminate(); // } - + BOOST_CATCH_END +#endif detail::tls_destructor(thread_info.get()); detail::set_current_thread_data(0); @@ -136,8 +195,11 @@ namespace boost thread_info->done=true; thread_info->done_condition.notify_all(); + return 0; } } - + } + namespace detail + { struct externally_launched_thread: detail::thread_data_base @@ -145,9 +207,18 @@ namespace boost externally_launched_thread() { +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS interrupt_enabled=false; +#endif + } + ~externally_launched_thread() { + BOOST_ASSERT(notify.empty()); + notify.clear(); + BOOST_ASSERT(async_states_.empty()); + async_states_.clear(); } - void run() {} + void notify_all_at_thread_exit(condition_variable*, mutex*) + {} private: @@ -156,7 +227,7 @@ namespace boost }; - detail::thread_data_base* make_external_thread_data() + thread_data_base* make_external_thread_data() { - detail::thread_data_base* const me(new externally_launched_thread()); + thread_data_base* const me(detail::heap_new<externally_launched_thread>()); me->self.reset(me); set_current_thread_data(me); @@ -165,7 +236,7 @@ namespace boost - detail::thread_data_base* get_or_make_current_thread_data() + thread_data_base* get_or_make_current_thread_data() { - detail::thread_data_base* current_thread_data(detail::get_current_thread_data()); + thread_data_base* current_thread_data(get_current_thread_data()); if(!current_thread_data) { @@ -178,8 +249,8 @@ namespace boost - thread::thread() + thread::thread() BOOST_NOEXCEPT {} - void thread::start_thread() + bool thread::start_thread_noexcept() { thread_info->self=thread_info; @@ -188,12 +259,49 @@ namespace boost { thread_info->self.reset(); - boost::throw_exception(thread_resource_error()); + return false; +// boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_create")); } + return true; } - thread::~thread() + bool thread::start_thread_noexcept(const attributes& attr) + { + thread_info->self=thread_info; + const attributes::native_handle_type* h = attr.native_handle(); + int res = pthread_create(&thread_info->thread_handle, h, &thread_proxy, thread_info.get()); + if (res != 0) { - detach(); + thread_info->self.reset(); + return false; +// boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_create")); } + int detached_state; + res = pthread_attr_getdetachstate(h, &detached_state); + if (res != 0) + { + thread_info->self.reset(); + return false; +// boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_attr_getdetachstate")); + } + if (PTHREAD_CREATE_DETACHED==detached_state) + { + detail::thread_data_ptr local_thread_info; + thread_info.swap(local_thread_info); + + if(local_thread_info) + { + //lock_guard<mutex> lock(local_thread_info->data_mutex); + if(!local_thread_info->join_started) + { + //BOOST_VERIFY(!pthread_detach(local_thread_info->thread_handle)); + local_thread_info->join_started=true; + local_thread_info->joined=true; + } + } + } + return true; + } + + detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const @@ -202,5 +310,5 @@ namespace boost } - void thread::join() + bool thread::join_noexcept() { detail::thread_data_ptr const local_thread_info=(get_thread_info)(); @@ -242,8 +350,13 @@ namespace boost thread_info.reset(); } + return true; + } + else + { + return false; } } - bool thread::timed_join(system_time const& wait_until) + bool thread::do_try_join_until_noexcept(struct timespec const &timeout, bool& res) { detail::thread_data_ptr const local_thread_info=(get_thread_info)(); @@ -256,7 +369,8 @@ namespace boost while(!local_thread_info->done) { - if(!local_thread_info->done_condition.timed_wait(lock,wait_until)) + if(!local_thread_info->done_condition.do_wait_until(lock,timeout)) { - return false; + res=false; + return true; } } @@ -288,11 +402,16 @@ namespace boost thread_info.reset(); } - } + res=true; return true; } + else + { + return false; + } + } - bool thread::joinable() const + bool thread::joinable() const BOOST_NOEXCEPT { - return (get_thread_info)(); + return (get_thread_info)()?true:false; } @@ -317,28 +436,21 @@ namespace boost namespace this_thread { - - void sleep(const system_time& st) + namespace no_interruption_point { - detail::thread_data_base* const thread_info=detail::get_current_thread_data(); - - if(thread_info) + namespace hiden { - unique_lock<mutex> lk(thread_info->sleep_mutex); - while(thread_info->sleep_condition.timed_wait(lk,st)); - } - else + void BOOST_THREAD_DECL sleep_for(const timespec& ts) { - xtime const xt=get_xtime(st); - for (int foo=0; foo < 5; ++foo) + if (boost::detail::timespec_ge(ts, boost::detail::timespec_zero())) { + # if defined(BOOST_HAS_PTHREAD_DELAY_NP) - timespec ts; - to_timespec_duration(xt, ts); + # if defined(__IBMCPP__) || defined(_AIX) + BOOST_VERIFY(!pthread_delay_np(const_cast<timespec*>(&ts))); + # else BOOST_VERIFY(!pthread_delay_np(&ts)); + # endif # elif defined(BOOST_HAS_NANOSLEEP) - timespec ts; - to_timespec_duration(xt, ts); - // nanosleep takes a timespec that is an offset, not // an absolute time. @@ -346,17 +458,81 @@ namespace boost # else mutex mx; - mutex::scoped_lock lock(mx); - condition cond; - cond.timed_wait(lock, xt); + unique_lock<mutex> lock(mx); + condition_variable cond; + cond.do_wait_for(lock, ts); # endif - xtime cur; - xtime_get(&cur, TIME_UTC); - if (xtime_cmp(xt, cur) <= 0) + } + } + + void BOOST_THREAD_DECL sleep_until(const timespec& ts) + { + timespec now = boost::detail::timespec_now(); + if (boost::detail::timespec_gt(ts, now)) + { + for (int foo=0; foo < 5; ++foo) + { + + # if defined(BOOST_HAS_PTHREAD_DELAY_NP) + timespec d = boost::detail::timespec_minus(ts, now); + BOOST_VERIFY(!pthread_delay_np(&d)); + # elif defined(BOOST_HAS_NANOSLEEP) + // nanosleep takes a timespec that is an offset, not + // an absolute time. + timespec d = boost::detail::timespec_minus(ts, now); + nanosleep(&d, 0); + # else + mutex mx; + unique_lock<mutex> lock(mx); + condition_variable cond; + cond.do_wait_until(lock, ts); + # endif + timespec now2 = boost::detail::timespec_now(); + if (boost::detail::timespec_ge(now2, ts)) + { return; } } } + } + + } + } + namespace hiden + { + void BOOST_THREAD_DECL sleep_for(const timespec& ts) + { + boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data(); - void yield() + if(thread_info) + { + unique_lock<mutex> lk(thread_info->sleep_mutex); + while( thread_info->sleep_condition.do_wait_for(lk,ts)) {} + } + else + { + boost::this_thread::no_interruption_point::hiden::sleep_for(ts); + } + } + + void BOOST_THREAD_DECL sleep_until(const timespec& ts) + { + boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data(); + + if(thread_info) + { + unique_lock<mutex> lk(thread_info->sleep_mutex); + while(thread_info->sleep_condition.do_wait_until(lk,ts)) {} + } + else + { + boost::this_thread::no_interruption_point::hiden::sleep_until(ts); + } + } + } // hiden + } // this_thread + + namespace this_thread + { + void yield() BOOST_NOEXCEPT { # if defined(BOOST_HAS_SCHED_YIELD) @@ -364,13 +540,19 @@ namespace boost # elif defined(BOOST_HAS_PTHREAD_YIELD) BOOST_VERIFY(!pthread_yield()); +//# elif defined BOOST_THREAD_USES_DATETIME +// xtime xt; +// xtime_get(&xt, TIME_UTC_); +// sleep(xt); +// sleep_for(chrono::milliseconds(0)); # else - xtime xt; - xtime_get(&xt, TIME_UTC); - sleep(xt); +#error + timespec ts; + ts.tv_sec= 0; + ts.tv_nsec= 0; + hiden::sleep_for(ts); # endif } } - - unsigned thread::hardware_concurrency() + unsigned thread::hardware_concurrency() BOOST_NOEXCEPT { #if defined(PTW32_VERSION) || defined(__hpux) @@ -383,5 +565,5 @@ namespace boost int const count=sysconf(_SC_NPROCESSORS_ONLN); return (count>0)?count:0; -#elif defined(_GNU_SOURCE) +#elif defined(__GLIBC__) return get_nprocs(); #else @@ -390,17 +572,63 @@ namespace boost } - thread::id thread::get_id() const - { - detail::thread_data_ptr const local_thread_info=(get_thread_info)(); - if(local_thread_info) + unsigned thread::physical_concurrency() BOOST_NOEXCEPT { - return id(local_thread_info); +#ifdef __linux__ + try { + using namespace std; + + ifstream proc_cpuinfo ("/proc/cpuinfo"); + + const string physical_id("physical id"), core_id("core id"); + + typedef std::pair<unsigned, unsigned> core_entry; // [physical ID, core id] + + std::set<core_entry> cores; + + core_entry current_core_entry; + + string line; + while ( getline(proc_cpuinfo, line) ) { + if (line.empty()) + continue; + + vector<string> key_val(2); + boost::split(key_val, line, boost::is_any_of(":")); + + if (key_val.size() != 2) + return hardware_concurrency(); + + string key = key_val[0]; + string value = key_val[1]; + boost::trim(key); + boost::trim(value); + + if (key == physical_id) { + current_core_entry.first = boost::lexical_cast<unsigned>(value); + continue; + } + + if (key == core_id) { + current_core_entry.second = boost::lexical_cast<unsigned>(value); + cores.insert(current_core_entry); + continue; } - else - { - return id(); } + // Fall back to hardware_concurrency() in case + // /proc/cpuinfo is formatted differently than we expect. + return cores.size() != 0 ? cores.size() : hardware_concurrency(); + } catch(...) { + return hardware_concurrency(); + } +#elif defined(__APPLE__) + int count; + size_t size=sizeof(count); + return sysctlbyname("hw.physicalcpu",&count,&size,NULL,0)?0:count; +#else + return hardware_concurrency(); +#endif } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS void thread::interrupt() { @@ -418,5 +646,5 @@ namespace boost } - bool thread::interruption_requested() const + bool thread::interruption_requested() const BOOST_NOEXCEPT { detail::thread_data_ptr const local_thread_info=(get_thread_info)(); @@ -431,4 +659,5 @@ namespace boost } } +#endif thread::native_handle_type thread::native_handle() @@ -448,14 +677,10 @@ namespace boost +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS namespace this_thread { - thread::id get_id() - { - boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data(); - return thread::id(thread_info?thread_info->shared_from_this():detail::thread_data_ptr()); - } - void interruption_point() { +#ifndef BOOST_NO_EXCEPTIONS boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data(); if(thread_info && thread_info->interrupt_enabled) @@ -468,7 +693,8 @@ namespace boost } } +#endif } - bool interruption_enabled() + bool interruption_enabled() BOOST_NOEXCEPT { boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data(); @@ -476,5 +702,5 @@ namespace boost } - bool interruption_requested() + bool interruption_requested() BOOST_NOEXCEPT { boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data(); @@ -490,5 +716,5 @@ namespace boost } - disable_interruption::disable_interruption(): + disable_interruption::disable_interruption() BOOST_NOEXCEPT: interruption_was_enabled(interruption_enabled()) { @@ -499,5 +725,5 @@ namespace boost } - disable_interruption::~disable_interruption() + disable_interruption::~disable_interruption() BOOST_NOEXCEPT { if(detail::get_current_thread_data()) @@ -507,5 +733,5 @@ namespace boost } - restore_interruption::restore_interruption(disable_interruption& d) + restore_interruption::restore_interruption(disable_interruption& d) BOOST_NOEXCEPT { if(d.interruption_was_enabled) @@ -515,5 +741,5 @@ namespace boost } - restore_interruption::~restore_interruption() + restore_interruption::~restore_interruption() BOOST_NOEXCEPT { if(detail::get_current_thread_data()) @@ -523,4 +749,5 @@ namespace boost } } +#endif namespace detail @@ -530,5 +757,5 @@ namespace boost detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); thread_exit_callback_node* const new_node= - 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; } @@ -546,5 +773,5 @@ namespace boost } } - return NULL; + return 0; } @@ -555,5 +782,5 @@ namespace boost return current_node->value; } - return NULL; + return 0; } @@ -568,7 +795,10 @@ namespace boost void erase_tss_node(void const* key) { - detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); + detail::thread_data_base* const current_thread_data(get_current_thread_data()); + if(current_thread_data) + { current_thread_data->tss_data.erase(key); } + } void set_tss_data(void const* key, @@ -592,5 +822,5 @@ namespace boost } } - else + else if(func || (tss_data!=0)) { add_new_tss_node(key,func,tss_data); @@ -599,4 +829,25 @@ namespace boost } + BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk) + { + detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); + if(current_thread_data) + { + current_thread_data->notify_all_at_thread_exit(&cond, lk.release()); + } + } +namespace detail { + + void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr<shared_state_base> as) + { + detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); + if(current_thread_data) + { + current_thread_data->make_ready_at_thread_exit(as); + } + } +} + + } diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl b/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl index b75a135..d81f31b 100644 --- a/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl +++ b/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl @@ -18,9 +18,10 @@ const int MICROSECONDS_PER_SECOND = 1000000; const int NANOSECONDS_PER_MICROSECOND = 1000; +#if defined BOOST_THREAD_USES_DATETIME inline void to_time(int milliseconds, boost::xtime& xt) { int res = 0; - res = boost::xtime_get(&xt, boost::TIME_UTC); - BOOST_ASSERT(res == boost::TIME_UTC); + res = boost::xtime_get(&xt, boost::TIME_UTC_); + BOOST_ASSERT(res == boost::TIME_UTC_); (void)res; xt.sec += (milliseconds / MILLISECONDS_PER_SECOND); @@ -34,6 +35,7 @@ inline void to_time(int milliseconds, boost::xtime& xt) } } - +#endif #if defined(BOOST_HAS_PTHREADS) +#if defined BOOST_THREAD_USES_DATETIME inline void to_timespec(const boost::xtime& xt, timespec& ts) { @@ -46,18 +48,31 @@ inline void to_timespec(const boost::xtime& xt, timespec& ts) } } - +#endif inline void to_time(int milliseconds, timespec& ts) { +#if defined BOOST_THREAD_USES_DATETIME boost::xtime xt; to_time(milliseconds, xt); to_timespec(xt, ts); +#else + ts.tv_sec += (milliseconds / MILLISECONDS_PER_SECOND); + ts.tv_nsec += ((milliseconds % MILLISECONDS_PER_SECOND) * + NANOSECONDS_PER_MILLISECOND); + + if (ts.tv_nsec >= NANOSECONDS_PER_SECOND) + { + ++ts.tv_sec; + ts.tv_nsec -= NANOSECONDS_PER_SECOND; + } +#endif } +#if defined BOOST_THREAD_USES_DATETIME inline void to_timespec_duration(const boost::xtime& xt, timespec& ts) { boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - BOOST_ASSERT(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + BOOST_ASSERT(res == boost::TIME_UTC_); (void)res; if (boost::xtime_cmp(xt, cur) <= 0) @@ -84,11 +99,13 @@ inline void to_timespec_duration(const boost::xtime& xt, timespec& ts) } #endif +#endif +#if defined BOOST_THREAD_USES_DATETIME inline void to_duration(boost::xtime xt, int& milliseconds) { boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - BOOST_ASSERT(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + BOOST_ASSERT(res == boost::TIME_UTC_); (void)res; if (boost::xtime_cmp(xt, cur) <= 0) @@ -111,6 +128,6 @@ inline void to_microduration(boost::xtime xt, int& microseconds) boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - BOOST_ASSERT(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + BOOST_ASSERT(res == boost::TIME_UTC_); (void)res; if (boost::xtime_cmp(xt, cur) <= 0) @@ -128,4 +145,5 @@ inline void to_microduration(boost::xtime xt, int& microseconds) } } +#endif } diff --git a/3rdParty/Boost/src/libs/thread/src/tss_null.cpp b/3rdParty/Boost/src/libs/thread/src/tss_null.cpp index e93ba0f..b5029f1 100644 --- a/3rdParty/Boost/src/libs/thread/src/tss_null.cpp +++ b/3rdParty/Boost/src/libs/thread/src/tss_null.cpp diff --git a/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp b/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp index 05c7a6c..54ebbf3 100644 --- a/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp +++ b/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp @@ -4,28 +4,67 @@ // (C) Copyright 2007 Anthony Williams // (C) Copyright 2007 David Deakins +// (C) Copyright 2011-2013 Vicente J. Botet Escriba +#ifndef _WIN32_WINNT #define _WIN32_WINNT 0x400 +#endif + +#ifndef WINVER #define WINVER 0x400 +#endif +//#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/thread_only.hpp> +#include <boost/thread/once.hpp> +#include <boost/thread/tss.hpp> +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/detail/tss_hooks.hpp> +#include <boost/thread/future.hpp> -#include <boost/thread/thread.hpp> +#include <boost/assert.hpp> +#include <boost/cstdint.hpp> +#if defined BOOST_THREAD_USES_DATETIME +#include <boost/date_time/posix_time/conversion.hpp> +#endif +#include <memory> #include <algorithm> -#include <windows.h> #ifndef UNDER_CE #include <process.h> #endif #include <stdio.h> -#include <boost/thread/once.hpp> -#include <boost/thread/tss.hpp> -#include <boost/assert.hpp> -#include <boost/throw_exception.hpp> -#include <boost/thread/detail/tss_hooks.hpp> -#include <boost/date_time/posix_time/conversion.hpp> +#include <windows.h> namespace boost { + namespace detail + { + thread_data_base::~thread_data_base() + { + for (notify_list_t::iterator i = notify.begin(), e = notify.end(); + i != e; ++i) + { + i->second->unlock(); + i->first->notify_all(); + } + for (async_states_t::iterator i = async_states_.begin(), e = async_states_.end(); + i != e; ++i) + { + (*i)->make_ready(); + } + } + } + namespace { +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 + boost::once_flag current_thread_tls_init_flag; +#else boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT; - DWORD current_thread_tls_key=0; +#endif +#if defined(UNDER_CE) + // Windows CE does not define the TLS_OUT_OF_INDEXES constant. +#define TLS_OUT_OF_INDEXES 0xFFFFFFFF +#endif + DWORD current_thread_tls_key=TLS_OUT_OF_INDEXES; void create_current_thread_tls_key() @@ -38,30 +77,40 @@ namespace boost void cleanup_tls_key() { - if(current_thread_tls_key) + if(current_thread_tls_key!=TLS_OUT_OF_INDEXES) { TlsFree(current_thread_tls_key); - current_thread_tls_key=0; + current_thread_tls_key=TLS_OUT_OF_INDEXES; } } - detail::thread_data_base* get_current_thread_data() - { - if(!current_thread_tls_key) - { - return 0; - } - return (detail::thread_data_base*)TlsGetValue(current_thread_tls_key); - } - void set_current_thread_data(detail::thread_data_base* new_data) { boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key); - if(current_thread_tls_key) + if (current_thread_tls_key!=TLS_OUT_OF_INDEXES) + { BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data)); + } else - boost::throw_exception(thread_resource_error()); + { + BOOST_VERIFY(false); + //boost::throw_exception(thread_resource_error()); + } } -#ifdef BOOST_NO_THREADEX + } + namespace detail + { + thread_data_base* get_current_thread_data() + { + if(current_thread_tls_key==TLS_OUT_OF_INDEXES) + { + return 0; + } + return (detail::thread_data_base*)TlsGetValue(current_thread_tls_key); + } + } + namespace + { +#ifndef BOOST_HAS_THREADEX // Windows CE doesn't define _beginthreadex @@ -76,19 +125,22 @@ namespace boost DWORD WINAPI ThreadProxy(LPVOID args) { - ThreadProxyData* data=reinterpret_cast<ThreadProxyData*>(args); + std::auto_ptr<ThreadProxyData> data(reinterpret_cast<ThreadProxyData*>(args)); DWORD ret=data->start_address_(data->arglist_); - delete data; return ret; } - typedef void* uintptr_t; + //typedef void* uintptr_t; - inline uintptr_t const _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*), + inline uintptr_t _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*), void* arglist, unsigned initflag, unsigned* thrdaddr) { DWORD threadID; + ThreadProxyData* data = new ThreadProxyData(start_address,arglist); HANDLE hthread=CreateThread(static_cast<LPSECURITY_ATTRIBUTES>(security),stack_size,ThreadProxy, - new ThreadProxyData(start_address,arglist),initflag,&threadID); - if (hthread!=0) + data,initflag,&threadID); + if (hthread==0) { + delete data; + return 0; + } *thrdaddr=threadID; return reinterpret_cast<uintptr_t const>(hthread); @@ -112,17 +164,4 @@ namespace boost }; - struct tss_data_node - { - void const* key; - boost::shared_ptr<boost::detail::tss_cleanup_function> func; - void* value; - tss_data_node* next; - - tss_data_node(void const* key_,boost::shared_ptr<boost::detail::tss_cleanup_function> func_,void* value_, - tss_data_node* next_): - key(key_),func(func_),value(value_),next(next_) - {} - }; - } @@ -131,8 +170,8 @@ namespace boost void run_thread_exit_callbacks() { - detail::thread_data_ptr current_thread_data(get_current_thread_data(),false); + detail::thread_data_ptr current_thread_data(detail::get_current_thread_data(),false); if(current_thread_data) { - while(current_thread_data->tss_data || current_thread_data->thread_exit_callbacks) + while(! current_thread_data->tss_data.empty() || current_thread_data->thread_exit_callbacks) { while(current_thread_data->thread_exit_callbacks) @@ -147,13 +186,16 @@ namespace boost boost::detail::heap_delete(current_node); } - while(current_thread_data->tss_data) + for(std::map<void const*,detail::tss_data_node>::iterator next=current_thread_data->tss_data.begin(), + current, + end=current_thread_data->tss_data.end(); + next!=end;) { - detail::tss_data_node* const current_node=current_thread_data->tss_data; - current_thread_data->tss_data=current_node->next; - if(current_node->func) + current=next; + ++next; + if(current->second.func && (current->second.value!=0)) { - (*current_node->func)(current_node->value); + (*current->second.func)(current->second.value); } - boost::detail::heap_delete(current_node); + current_thread_data->tss_data.erase(current); } } @@ -167,17 +209,22 @@ namespace boost detail::thread_data_base* const thread_info(reinterpret_cast<detail::thread_data_base*>(param)); set_current_thread_data(thread_info); - try +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS + BOOST_TRY { +#endif thread_info->run(); +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS } - catch(thread_interrupted const&) + BOOST_CATCH(thread_interrupted const&) { } // Removed as it stops the debugger identifying the cause of the exception // Unhandled exceptions still cause the application to terminate -// catch(...) +// BOOST_CATCH(...) // { // std::terminate(); // } + BOOST_CATCH_END +#endif run_thread_exit_callbacks(); return 0; @@ -185,17 +232,34 @@ namespace boost } - thread::thread() + thread::thread() BOOST_NOEXCEPT {} - void thread::start_thread() + bool thread::start_thread_noexcept() { uintptr_t const new_thread=_beginthreadex(0,0,&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id); if(!new_thread) { - boost::throw_exception(thread_resource_error()); + return false; +// boost::throw_exception(thread_resource_error()); + } + intrusive_ptr_add_ref(thread_info.get()); + thread_info->thread_handle=(detail::win32::handle)(new_thread); + ResumeThread(thread_info->thread_handle); + return true; + } + + bool thread::start_thread_noexcept(const attributes& attr) + { + //uintptr_t const new_thread=_beginthreadex(attr.get_security(),attr.get_stack_size(),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id); + uintptr_t const new_thread=_beginthreadex(0,static_cast<unsigned int>(attr.get_stack_size()),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id); + if(!new_thread) + { + return false; +// boost::throw_exception(thread_resource_error()); } intrusive_ptr_add_ref(thread_info.get()); thread_info->thread_handle=(detail::win32::handle)(new_thread); ResumeThread(thread_info->thread_handle); + return true; } @@ -212,9 +276,20 @@ namespace boost { ++count; +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS interruption_enabled=false; +#endif + } + ~externally_launched_thread() { + BOOST_ASSERT(notify.empty()); + notify.clear(); + BOOST_ASSERT(async_states_.empty()); + async_states_.clear(); } void run() {} + void notify_all_at_thread_exit(condition_variable*, mutex*) + {} + private: externally_launched_thread(externally_launched_thread&); @@ -225,22 +300,23 @@ namespace boost { externally_launched_thread* me=detail::heap_new<externally_launched_thread>(); - try + BOOST_TRY { set_current_thread_data(me); } - catch(...) + BOOST_CATCH(...) { detail::heap_delete(me); - throw; + BOOST_RETHROW } + BOOST_CATCH_END } detail::thread_data_base* get_or_make_current_thread_data() { - detail::thread_data_base* current_thread_data(get_current_thread_data()); + detail::thread_data_base* current_thread_data(detail::get_current_thread_data()); if(!current_thread_data) { make_external_thread_data(); - current_thread_data=get_current_thread_data(); + current_thread_data=detail::get_current_thread_data(); } return current_thread_data; @@ -249,21 +325,22 @@ namespace boost } - thread::~thread() - { - detach(); - } - - thread::id thread::get_id() const + thread::id thread::get_id() const BOOST_NOEXCEPT { + #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID + detail::thread_data_ptr local_thread_info=(get_thread_info)(); + return local_thread_info?local_thread_info->id:0; + //return const_cast<thread*>(this)->native_handle(); + #else return thread::id((get_thread_info)()); + #endif } - bool thread::joinable() const + bool thread::joinable() const BOOST_NOEXCEPT { - return (get_thread_info)(); + return (get_thread_info)() ? true : false; } - - void thread::join() + bool thread::join_noexcept() { + detail::thread_data_ptr local_thread_info=(get_thread_info)(); if(local_thread_info) @@ -271,20 +348,37 @@ namespace boost this_thread::interruptible_wait(local_thread_info->thread_handle,detail::timeout::sentinel()); release_handle(); + return true; + } + else + { + return false; } } +#if defined BOOST_THREAD_USES_DATETIME bool thread::timed_join(boost::system_time const& wait_until) { + return do_try_join_until(get_milliseconds_until(wait_until)); + } +#endif + bool thread::do_try_join_until_noexcept(uintmax_t milli, bool& res) + { 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))) + if(!this_thread::interruptible_wait(local_thread_info->thread_handle,milli)) { - return false; + res=false; + return true; } release_handle(); - } + res=true; return true; } + else + { + return false; + } + } void thread::detach() @@ -298,4 +392,5 @@ namespace boost } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS void thread::interrupt() { @@ -307,5 +402,5 @@ namespace boost } - bool thread::interruption_requested() const + bool thread::interruption_requested() const BOOST_NOEXCEPT { detail::thread_data_ptr local_thread_info=(get_thread_info)(); @@ -313,11 +408,38 @@ namespace boost } - unsigned thread::hardware_concurrency() +#endif + + unsigned thread::hardware_concurrency() BOOST_NOEXCEPT { - SYSTEM_INFO info={{0}}; + //SYSTEM_INFO info={{0}}; + SYSTEM_INFO info; GetSystemInfo(&info); return info.dwNumberOfProcessors; } + unsigned thread::physical_concurrency() BOOST_NOEXCEPT + { + unsigned cores = 0; +#if !(defined(__MINGW32__) || defined (__MINGW64__)) + DWORD size = 0; + + GetLogicalProcessorInformation(NULL, &size); + if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) + return 0; + + std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(size); + if (GetLogicalProcessorInformation(&buffer.front(), &size) == FALSE) + return 0; + + const size_t Elements = size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); + + for (size_t i = 0; i < Elements; ++i) { + if (buffer[i].Relationship == RelationProcessorCore) + ++cores; + } +#endif + return cores; + } + thread::native_handle_type thread::native_handle() { @@ -337,8 +459,8 @@ namespace boost LARGE_INTEGER get_due_time(detail::timeout const& target_time) { - LARGE_INTEGER due_time={{0}}; + LARGE_INTEGER due_time={{0,0}}; if(target_time.relative) { - unsigned long const elapsed_milliseconds=GetTickCount()-target_time.start; + detail::win32::ticks_type const elapsed_milliseconds=detail::win32::GetTickCount64()()-target_time.start; LONGLONG const remaining_milliseconds=(target_time.milliseconds-elapsed_milliseconds); LONGLONG const hundred_nanoseconds_in_one_millisecond=10000; @@ -351,5 +473,5 @@ namespace boost else { - SYSTEMTIME target_system_time={0}; + SYSTEMTIME target_system_time={0,0,0,0,0,0,0,0}; target_system_time.wYear=target_time.abs_time.date().year(); target_system_time.wMonth=target_time.abs_time.date().month(); @@ -395,5 +517,7 @@ namespace boost unsigned handle_count=0; unsigned wait_handle_index=~0U; +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS unsigned interruption_index=~0U; +#endif unsigned timeout_index=~0U; if(handle_to_wait_for!=detail::win32::invalid_handle_value) @@ -402,10 +526,11 @@ namespace boost handles[handle_count++]=handle_to_wait_for; } - if(get_current_thread_data() && get_current_thread_data()->interruption_enabled) +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS + if(detail::get_current_thread_data() && detail::get_current_thread_data()->interruption_enabled) { interruption_index=handle_count; - handles[handle_count++]=get_current_thread_data()->interruption_handle; + handles[handle_count++]=detail::get_current_thread_data()->interruption_handle; } - +#endif detail::win32::handle_manager timer_handle; @@ -459,9 +584,11 @@ namespace boost return true; } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS else if(notified_index==interruption_index) { - detail::win32::ResetEvent(get_current_thread_data()->interruption_handle); + detail::win32::ResetEvent(detail::get_current_thread_data()->interruption_handle); throw thread_interrupted(); } +#endif else if(notified_index==timeout_index) { @@ -483,65 +610,157 @@ namespace boost } - thread::id get_id() + namespace no_interruption_point + { + bool non_interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time) + { + detail::win32::handle handles[3]={0}; + unsigned handle_count=0; + unsigned wait_handle_index=~0U; + unsigned timeout_index=~0U; + if(handle_to_wait_for!=detail::win32::invalid_handle_value) + { + wait_handle_index=handle_count; + handles[handle_count++]=handle_to_wait_for; + } + detail::win32::handle_manager timer_handle; + +#ifndef UNDER_CE + unsigned const min_timer_wait_period=20; + + if(!target_time.is_sentinel()) + { + detail::timeout::remaining_time const time_left=target_time.remaining_milliseconds(); + if(time_left.milliseconds > min_timer_wait_period) + { + // for a long-enough timeout, use a waitable timer (which tracks clock changes) + timer_handle=CreateWaitableTimer(NULL,false,NULL); + if(timer_handle!=0) + { + LARGE_INTEGER due_time=get_due_time(target_time); + + bool const set_time_succeeded=SetWaitableTimer(timer_handle,&due_time,0,0,0,false)!=0; + if(set_time_succeeded) + { + timeout_index=handle_count; + handles[handle_count++]=timer_handle; + } + } + } + else if(!target_time.relative) + { + // convert short absolute-time timeouts into relative ones, so we don't race against clock changes + target_time=detail::timeout(time_left.milliseconds); + } + } +#endif + + bool const using_timer=timeout_index!=~0u; + detail::timeout::remaining_time time_left(0); + + do + { + if(!using_timer) + { + time_left=target_time.remaining_milliseconds(); + } + + if(handle_count) { + unsigned long const notified_index=detail::win32::WaitForMultipleObjects(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds); + if(notified_index<handle_count) + { + if(notified_index==wait_handle_index) + { + return true; + } + else if(notified_index==timeout_index) + { + return false; + } + } + } + else + { + detail::win32::Sleep(time_left.milliseconds); + } + if(target_time.relative) + { + target_time.milliseconds-=detail::timeout::max_non_infinite_wait; + } + } + while(time_left.more); + return false; + } + } + + thread::id get_id() BOOST_NOEXCEPT + { + #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID + return detail::win32::GetCurrentThreadId(); + #else return thread::id(get_or_make_current_thread_data()); + #endif } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS void interruption_point() { if(interruption_enabled() && interruption_requested()) { - detail::win32::ResetEvent(get_current_thread_data()->interruption_handle); + detail::win32::ResetEvent(detail::get_current_thread_data()->interruption_handle); throw thread_interrupted(); } } - bool interruption_enabled() + bool interruption_enabled() BOOST_NOEXCEPT { - return get_current_thread_data() && get_current_thread_data()->interruption_enabled; + return detail::get_current_thread_data() && detail::get_current_thread_data()->interruption_enabled; } - bool interruption_requested() + bool interruption_requested() BOOST_NOEXCEPT { - return get_current_thread_data() && (detail::win32::WaitForSingleObject(get_current_thread_data()->interruption_handle,0)==0); + return detail::get_current_thread_data() && (detail::win32::WaitForSingleObject(detail::get_current_thread_data()->interruption_handle,0)==0); } +#endif - void yield() + void yield() BOOST_NOEXCEPT { detail::win32::Sleep(0); } - disable_interruption::disable_interruption(): +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS + disable_interruption::disable_interruption() BOOST_NOEXCEPT: interruption_was_enabled(interruption_enabled()) { if(interruption_was_enabled) { - get_current_thread_data()->interruption_enabled=false; + detail::get_current_thread_data()->interruption_enabled=false; } } - disable_interruption::~disable_interruption() + disable_interruption::~disable_interruption() BOOST_NOEXCEPT { - if(get_current_thread_data()) + if(detail::get_current_thread_data()) { - get_current_thread_data()->interruption_enabled=interruption_was_enabled; + detail::get_current_thread_data()->interruption_enabled=interruption_was_enabled; } } - restore_interruption::restore_interruption(disable_interruption& d) + restore_interruption::restore_interruption(disable_interruption& d) BOOST_NOEXCEPT { if(d.interruption_was_enabled) { - get_current_thread_data()->interruption_enabled=true; + detail::get_current_thread_data()->interruption_enabled=true; } } - restore_interruption::~restore_interruption() + restore_interruption::~restore_interruption() BOOST_NOEXCEPT { - if(get_current_thread_data()) + if(detail::get_current_thread_data()) { - get_current_thread_data()->interruption_enabled=false; + detail::get_current_thread_data()->interruption_enabled=false; } } +#endif } @@ -562,12 +781,9 @@ namespace boost if(current_thread_data) { - detail::tss_data_node* current_node=current_thread_data->tss_data; - while(current_node) + std::map<void const*,tss_data_node>::iterator current_node= + current_thread_data->tss_data.find(key); + if(current_node!=current_thread_data->tss_data.end()) { - if(current_node->key==key) - { - return current_node; - } - current_node=current_node->next; + return ¤t_node->second; } } @@ -584,21 +800,41 @@ namespace boost } - void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing) + void add_new_tss_node(void const* key, + boost::shared_ptr<tss_cleanup_function> func, + void* tss_data) + { + detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); + current_thread_data->tss_data.insert(std::make_pair(key,tss_data_node(func,tss_data))); + } + + void erase_tss_node(void const* key) + { + detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); + current_thread_data->tss_data.erase(key); + } + + void set_tss_data(void const* key, + boost::shared_ptr<tss_cleanup_function> func, + void* tss_data,bool cleanup_existing) { if(tss_data_node* const current_node=find_tss_data(key)) { - if(cleanup_existing && current_node->func.get() && current_node->value) + if(cleanup_existing && current_node->func && (current_node->value!=0)) { (*current_node->func)(current_node->value); } + if(func || (tss_data!=0)) + { current_node->func=func; current_node->value=tss_data; } - else if(func && tss_data) + else { - 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); - current_thread_data->tss_data=new_node; + erase_tss_node(key); + } + } + else if(func || (tss_data!=0)) + { + add_new_tss_node(key,func,tss_data); } } @@ -620,5 +856,23 @@ namespace boost } + BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk) + { + detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); + if(current_thread_data) + { + current_thread_data->notify_all_at_thread_exit(&cond, lk.release()); + } + } +//namespace detail { +// +// void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr<shared_state_base> as) +// { +// detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); +// if(current_thread_data) +// { +// current_thread_data->make_ready_at_thread_exit(as); +// } +// } +//} } - diff --git a/3rdParty/Boost/src/libs/thread/src/win32/timeconv.inl b/3rdParty/Boost/src/libs/thread/src/win32/timeconv.inl index 5ec3b17..c646783 100644 --- a/3rdParty/Boost/src/libs/thread/src/win32/timeconv.inl +++ b/3rdParty/Boost/src/libs/thread/src/win32/timeconv.inl @@ -18,6 +18,6 @@ inline void to_time(int milliseconds, boost::xtime& xt) { int res = 0; - res = boost::xtime_get(&xt, boost::TIME_UTC); - assert(res == boost::TIME_UTC); + res = boost::xtime_get(&xt, boost::TIME_UTC_); + assert(res == boost::TIME_UTC_); xt.sec += (milliseconds / MILLISECONDS_PER_SECOND); @@ -55,6 +55,6 @@ inline void to_timespec_duration(const boost::xtime& xt, timespec& ts) boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - assert(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + assert(res == boost::TIME_UTC_); if (boost::xtime_cmp(xt, cur) <= 0) @@ -86,6 +86,6 @@ inline void to_duration(boost::xtime xt, int& milliseconds) boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - assert(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + assert(res == boost::TIME_UTC_); if (boost::xtime_cmp(xt, cur) <= 0) @@ -108,6 +108,6 @@ inline void to_microduration(boost::xtime xt, int& microseconds) boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - assert(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + assert(res == boost::TIME_UTC_); if (boost::xtime_cmp(xt, cur) <= 0) 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 9699a12..2dc019f 100644 --- a/3rdParty/Boost/src/libs/thread/src/win32/tss_dll.cpp +++ b/3rdParty/Boost/src/libs/thread/src/win32/tss_dll.cpp @@ -6,4 +6,5 @@ #include <boost/thread/detail/config.hpp> + #if 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 8ef045b..5fd53b6 100644 --- a/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp +++ b/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp @@ -1,3 +1,3 @@ -// $Id: tss_pe.cpp 66259 2010-10-29 23:27:00Z anthonyw $ +// $Id$ // (C) Copyright Aaron W. LaFramboise, Roland Schwarz, Michael Glassford 2004. // (C) Copyright 2007 Roland Schwarz @@ -12,5 +12,5 @@ #if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) -#if defined(__MINGW32__) && !defined(_WIN64) +#if (defined(__MINGW32__) && !defined(_WIN64)) || defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR) #include <boost/thread/detail/tss_hooks.hpp> @@ -26,5 +26,5 @@ namespace boost namespace { - void NTAPI on_tls_callback(void* h, DWORD dwReason, PVOID pv) + void NTAPI on_tls_callback(void* , DWORD dwReason, PVOID ) { switch (dwReason) @@ -39,5 +39,6 @@ namespace { } -#if (__MINGW32_MAJOR_VERSION >3) || ((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18)) +#if defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR) || (__MINGW32_MAJOR_VERSION >3) || \ + ((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18)) extern "C" { @@ -80,4 +81,34 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata #include <windows.h> + +// _pRawDllMainOrig can be defined by including boost/thread/win32/mfc_thread_init.hpp +// into your dll; it ensures that MFC-Dll-initialization will be done properly +// The following code is adapted from the MFC-Dll-init code +/* + * _pRawDllMainOrig MUST be an extern const variable, which will be aliased to + * _pDefaultRawDllMainOrig if no real user definition is present, thanks to the + * alternatename directive. + */ + +// work at least with _MSC_VER 1500 (MSVC++ 9.0, VS 2008) +#if (_MSC_VER >= 1500) + +extern "C" { +extern BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID); +extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NULL; +#if defined (_M_IX86) +#pragma comment(linker, "/alternatename:__pRawDllMainOrig=__pDefaultRawDllMainOrig") +#elif defined (_M_X64) || defined (_M_ARM) +#pragma comment(linker, "/alternatename:_pRawDllMainOrig=_pDefaultRawDllMainOrig") +#else /* defined (_M_X64) || defined (_M_ARM) */ +#error Unsupported platform +#endif /* defined (_M_X64) || defined (_M_ARM) */ +} + +#endif + + + + //Definitions required by implementation @@ -240,5 +271,9 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata } +#if (_MSC_VER >= 1500) + BOOL WINAPI dll_callback(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved) +#else BOOL WINAPI dll_callback(HANDLE, DWORD dwReason, LPVOID) +#endif { switch (dwReason) @@ -251,4 +286,11 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata break; } + +#if (_MSC_VER >= 1500) + if( _pRawDllMainOrig ) + { + return _pRawDllMainOrig(hInstance, dwReason, lpReserved); + } +#endif return true; } |