summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2009-06-01 08:48:42 (GMT)
committerRemko Tronçon <git@el-tramo.be>2009-06-01 09:24:28 (GMT)
commit2812bddd81f8a1b804c7460f4e14cd0aa393d129 (patch)
treed46294f35150c4f0f43deaf2d31fceaf945ae715 /3rdParty/Boost/libs
downloadswift-contrib-2812bddd81f8a1b804c7460f4e14cd0aa393d129.zip
swift-contrib-2812bddd81f8a1b804c7460f4e14cd0aa393d129.tar.bz2
Import.
Diffstat (limited to '3rdParty/Boost/libs')
-rw-r--r--3rdParty/Boost/libs/date_time/src/gregorian/date_generators.cpp38
-rw-r--r--3rdParty/Boost/libs/date_time/src/gregorian/greg_month.cpp173
-rw-r--r--3rdParty/Boost/libs/date_time/src/gregorian/greg_names.hpp43
-rw-r--r--3rdParty/Boost/libs/date_time/src/gregorian/greg_weekday.cpp50
-rw-r--r--3rdParty/Boost/libs/date_time/src/gregorian/gregorian_types.cpp62
-rw-r--r--3rdParty/Boost/libs/date_time/src/posix_time/posix_time_types.cpp35
-rw-r--r--3rdParty/Boost/libs/detail/utf8_codecvt_facet.cpp269
-rw-r--r--3rdParty/Boost/libs/filesystem/src/operations.cpp1367
-rw-r--r--3rdParty/Boost/libs/filesystem/src/path.cpp163
-rw-r--r--3rdParty/Boost/libs/filesystem/src/portability.cpp115
-rw-r--r--3rdParty/Boost/libs/filesystem/src/utf8_codecvt_facet.cpp20
-rw-r--r--3rdParty/Boost/libs/filesystem/src/utf8_codecvt_facet.hpp24
-rw-r--r--3rdParty/Boost/libs/signals/src/connection.cpp155
-rw-r--r--3rdParty/Boost/libs/signals/src/named_slot_map.cpp134
-rw-r--r--3rdParty/Boost/libs/signals/src/signal_base.cpp189
-rw-r--r--3rdParty/Boost/libs/signals/src/slot.cpp71
-rw-r--r--3rdParty/Boost/libs/signals/src/trackable.cpp59
-rw-r--r--3rdParty/Boost/libs/system/src/error_code.cpp433
-rw-r--r--3rdParty/Boost/libs/thread/src/pthread/exceptions.cpp124
-rw-r--r--3rdParty/Boost/libs/thread/src/pthread/once.cpp51
-rw-r--r--3rdParty/Boost/libs/thread/src/pthread/thread.cpp678
-rw-r--r--3rdParty/Boost/libs/thread/src/pthread/timeconv.inl130
-rw-r--r--3rdParty/Boost/libs/thread/src/tss_null.cpp34
-rw-r--r--3rdParty/Boost/libs/thread/src/win32/exceptions.cpp124
-rw-r--r--3rdParty/Boost/libs/thread/src/win32/thread.cpp597
-rw-r--r--3rdParty/Boost/libs/thread/src/win32/timeconv.inl130
-rw-r--r--3rdParty/Boost/libs/thread/src/win32/tss_dll.cpp72
-rw-r--r--3rdParty/Boost/libs/thread/src/win32/tss_pe.cpp287
28 files changed, 5627 insertions, 0 deletions
diff --git a/3rdParty/Boost/libs/date_time/src/gregorian/date_generators.cpp b/3rdParty/Boost/libs/date_time/src/gregorian/date_generators.cpp
new file mode 100644
index 0000000..bbef7f6
--- /dev/null
+++ b/3rdParty/Boost/libs/date_time/src/gregorian/date_generators.cpp
@@ -0,0 +1,38 @@
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+
+#ifndef BOOST_DATE_TIME_SOURCE
+#define BOOST_DATE_TIME_SOURCE
+#endif
+#include "boost/date_time/date_generators.hpp"
+
+namespace boost {
+namespace date_time {
+
+ const char* const _nth_as_str[] = {"out of range", "first", "second",
+ "third", "fourth", "fifth"};
+
+ //! Returns nth arg as string. 1 -> "first", 2 -> "second", max is 5.
+ BOOST_DATE_TIME_DECL const char* nth_as_str(int ele)
+ {
+ if(ele >= 1 || ele <= 5) {
+ return _nth_as_str[ele];
+ }
+ else {
+ return _nth_as_str[0];
+ }
+ }
+
+} } //namespace date_time
+
+
+
+
+
diff --git a/3rdParty/Boost/libs/date_time/src/gregorian/greg_month.cpp b/3rdParty/Boost/libs/date_time/src/gregorian/greg_month.cpp
new file mode 100644
index 0000000..efca973
--- /dev/null
+++ b/3rdParty/Boost/libs/date_time/src/gregorian/greg_month.cpp
@@ -0,0 +1,173 @@
+/* Copyright (c) 2002-2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-23 06:13:35 -0500 (Sun, 23 Nov 2008) $
+ */
+
+
+
+#ifndef BOOST_DATE_TIME_SOURCE
+#define BOOST_DATE_TIME_SOURCE
+#endif
+#include "boost/date_time/gregorian/greg_month.hpp"
+#include "boost/date_time/gregorian/greg_facet.hpp"
+#include "boost/date_time/date_format_simple.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
+#include "boost/date_time/gregorian/formatters_limited.hpp"
+#else
+#include "boost/date_time/gregorian/formatters.hpp"
+#endif
+#include "boost/date_time/date_parsing.hpp"
+#include "boost/date_time/gregorian/parsers.hpp"
+
+#include "greg_names.hpp"
+namespace boost {
+namespace gregorian {
+
+ /*! Returns a shared pointer to a map of Month strings & numbers.
+ * Strings are both full names and abbreviations.
+ * Ex. ("jan",1), ("february",2), etc...
+ * Note: All characters are lowercase - for case insensitivity
+ */
+ greg_month::month_map_ptr_type greg_month::get_month_map_ptr()
+ {
+ static month_map_ptr_type month_map_ptr(new greg_month::month_map_type());
+
+ if(month_map_ptr->empty()) {
+ std::string s("");
+ for(unsigned short i = 1; i <= 12; ++i) {
+ greg_month m(static_cast<month_enum>(i));
+ s = m.as_long_string();
+ s = date_time::convert_to_lower(s);
+ month_map_ptr->insert(std::make_pair(s, i));
+ s = m.as_short_string();
+ s = date_time::convert_to_lower(s);
+ month_map_ptr->insert(std::make_pair(s, i));
+ }
+ }
+ return month_map_ptr;
+ }
+
+
+ //! Returns 3 char english string for the month ex: Jan, Feb, Mar, Apr
+ const char*
+ greg_month::as_short_string() const
+ {
+ return short_month_names[value_-1];
+ }
+
+ //! Returns full name of month as string in english ex: January, February
+ const char*
+ greg_month::as_long_string() const
+ {
+ return long_month_names[value_-1];
+ }
+
+ //! Return special_value from string argument
+ /*! Return special_value from string argument. If argument is
+ * not one of the special value names (defined in names.hpp),
+ * return 'not_special' */
+ special_values special_value_from_string(const std::string& s) {
+ short i = date_time::find_match(special_value_names,
+ special_value_names,
+ date_time::NumSpecialValues,
+ s);
+ if(i >= date_time::NumSpecialValues) { // match not found
+ return not_special;
+ }
+ else {
+ return static_cast<special_values>(i);
+ }
+ }
+
+
+#ifndef BOOST_NO_STD_WSTRING
+ //! Returns 3 wchar_t english string for the month ex: Jan, Feb, Mar, Apr
+ const wchar_t*
+ greg_month::as_short_wstring() const
+ {
+ return w_short_month_names[value_-1];
+ }
+
+ //! Returns full name of month as wchar_t string in english ex: January, February
+ const wchar_t*
+ greg_month::as_long_wstring() const
+ {
+ return w_long_month_names[value_-1];
+ }
+#endif // BOOST_NO_STD_WSTRING
+
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+ /*! creates an all_date_names_put object with the correct set of names.
+ * This function is only called in the event of an exception where
+ * the imbued locale containing the needed facet is for some reason
+ * unreachable.
+ */
+ BOOST_DATE_TIME_DECL
+ boost::date_time::all_date_names_put<greg_facet_config, char>*
+ create_facet_def(char type)
+ {
+ typedef
+ boost::date_time::all_date_names_put<greg_facet_config, char> facet_def;
+
+ return new facet_def(short_month_names,
+ long_month_names,
+ special_value_names,
+ short_weekday_names,
+ long_weekday_names);
+ }
+
+ //! 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){
+ typedef boost::date_time::all_date_names_put<greg_facet_config, char> facet_def;
+ return std::locale(loc, new facet_def(short_month_names,
+ long_month_names,
+ special_value_names,
+ short_weekday_names,
+ long_weekday_names)
+ );
+ }
+
+#ifndef BOOST_NO_STD_WSTRING
+ /*! creates an all_date_names_put object with the correct set of names.
+ * This function is only called in the event of an exception where
+ * the imbued locale containing the needed facet is for some reason
+ * unreachable.
+ */
+ BOOST_DATE_TIME_DECL
+ boost::date_time::all_date_names_put<greg_facet_config, wchar_t>*
+ create_facet_def(wchar_t type)
+ {
+ typedef
+ boost::date_time::all_date_names_put<greg_facet_config,wchar_t> facet_def;
+
+ return new facet_def(w_short_month_names,
+ w_long_month_names,
+ w_special_value_names,
+ w_short_weekday_names,
+ w_long_weekday_names);
+ }
+
+ //! 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){
+ 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,
+ w_long_month_names,
+ w_special_value_names,
+ w_short_weekday_names,
+ w_long_weekday_names)
+ );
+ }
+#endif // BOOST_NO_STD_WSTRING
+#endif // BOOST_DATE_TIME_NO_LOCALE
+
+} } //namespace gregorian
+
+
+
+
+
+
diff --git a/3rdParty/Boost/libs/date_time/src/gregorian/greg_names.hpp b/3rdParty/Boost/libs/date_time/src/gregorian/greg_names.hpp
new file mode 100644
index 0000000..76a1a24
--- /dev/null
+++ b/3rdParty/Boost/libs/date_time/src/gregorian/greg_names.hpp
@@ -0,0 +1,43 @@
+/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+
+#ifndef DATE_TIME_SRC_GREG_NAMES_HPP___
+#define DATE_TIME_SRC_GREG_NAMES_HPP___
+
+#include "boost/date_time/gregorian/greg_month.hpp"
+#include "boost/date_time/special_defs.hpp"
+namespace boost {
+namespace gregorian {
+
+
+ const char* const short_month_names[NumMonths]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec", "NAM"};
+ const char* const long_month_names[NumMonths]={"January","February","March","April","May","June","July","August","September","October","November","December","NotAMonth"};
+ const char* const special_value_names[date_time::NumSpecialValues]={"not-a-date-time","-infinity","+infinity","min_date_time","max_date_time","not_special"};
+
+
+ const char* const short_weekday_names[]={"Sun", "Mon", "Tue",
+ "Wed", "Thu", "Fri", "Sat"};
+ const char* const long_weekday_names[]= {"Sunday","Monday","Tuesday",
+ "Wednesday", "Thursday",
+ "Friday", "Saturday"};
+
+#ifndef BOOST_NO_STD_WSTRING
+ const wchar_t* const w_short_month_names[NumMonths]={L"Jan",L"Feb",L"Mar",L"Apr",L"May",L"Jun",L"Jul",L"Aug",L"Sep",L"Oct",L"Nov",L"Dec",L"NAM"};
+ const wchar_t* const w_long_month_names[NumMonths]={L"January",L"February",L"March",L"April",L"May",L"June",L"July",L"August",L"September",L"October",L"November",L"December",L"NotAMonth"};
+ const wchar_t* const w_special_value_names[date_time::NumSpecialValues]={L"not-a-date-time",L"-infinity",L"+infinity",L"min_date_time",L"max_date_time",L"not_special"};
+
+ const wchar_t* const w_short_weekday_names[]={L"Sun", L"Mon", L"Tue",
+ L"Wed", L"Thu", L"Fri", L"Sat"};
+ const wchar_t* const w_long_weekday_names[]= {L"Sunday",L"Monday",L"Tuesday",
+ L"Wednesday", L"Thursday",
+ L"Friday", L"Saturday"};
+#endif // BOOST_NO_STD_WSTRING
+} } // boost::gregorian
+#endif // DATE_TIME_SRC_GREG_NAMES_HPP___
diff --git a/3rdParty/Boost/libs/date_time/src/gregorian/greg_weekday.cpp b/3rdParty/Boost/libs/date_time/src/gregorian/greg_weekday.cpp
new file mode 100644
index 0000000..4057d29
--- /dev/null
+++ b/3rdParty/Boost/libs/date_time/src/gregorian/greg_weekday.cpp
@@ -0,0 +1,50 @@
+/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+
+#ifndef BOOST_DATE_TIME_SOURCE
+#define BOOST_DATE_TIME_SOURCE
+#endif
+#include "boost/date_time/gregorian/greg_weekday.hpp"
+
+#include "greg_names.hpp"
+
+namespace boost {
+namespace gregorian {
+
+ //! Return a 3 digit english string of the day of week (eg: Sun)
+ const char*
+ greg_weekday::as_short_string() const
+ {
+ return short_weekday_names[value_];
+ }
+ //! Return a point to a long english string representing day of week
+ const char*
+ greg_weekday::as_long_string() const
+ {
+ return long_weekday_names[value_];
+ }
+
+#ifndef BOOST_NO_STD_WSTRING
+ //! Return a 3 digit english wchar_t string of the day of week (eg: Sun)
+ const wchar_t*
+ greg_weekday::as_short_wstring() const
+ {
+ return w_short_weekday_names[value_];
+ }
+ //! Return a point to a long english wchar_t string representing day of week
+ const wchar_t*
+ greg_weekday::as_long_wstring() const
+ {
+ return w_long_weekday_names[value_];
+ }
+#endif // BOOST_NO_STD_WSTRING
+
+} } //namespace gregorian
+
diff --git a/3rdParty/Boost/libs/date_time/src/gregorian/gregorian_types.cpp b/3rdParty/Boost/libs/date_time/src/gregorian/gregorian_types.cpp
new file mode 100644
index 0000000..a856e79
--- /dev/null
+++ b/3rdParty/Boost/libs/date_time/src/gregorian/gregorian_types.cpp
@@ -0,0 +1,62 @@
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+/** @defgroup date_basics Date Basics
+ This page summarizes some of the key user types and functions needed
+ to write programs using the gregorian date system. This is not a
+ comprehensive list, but rather some key types to start exploring.
+
+
+**/
+
+/** @defgroup date_alg Date Algorithms / Generators
+ Date algorithms or generators are tools for generating other dates or
+ schedules of dates. A generator function starts with some part of a
+ date such as a month and day and is supplied another part to then
+ generate a final date.
+
+**/
+
+/** @defgroup date_format Date Formatting
+ The functions on these page are some of the key formatting functions
+ for dates.
+**/
+
+
+//File doesn't have a current purpose except to generate docs
+//and keep it changeable without recompiles
+/*! @example days_alive.cpp
+ Calculate the number of days you have been living using durations and dates.
+*/
+/*! @example days_till_new_year.cpp
+ Calculate the number of days till new years
+*/
+/*! @example print_month.cpp
+ Simple utility to print out days of the month with the days of a month. Demontstrates date iteration (date_time::date_itr).
+*/
+/*! @example localization.cpp
+ An example showing localized stream-based I/O.
+*/
+/*! @example dates_as_strings.cpp
+ Various parsing and output of strings (mostly supported for
+ compilers that do not support localized streams).
+*/
+/*! @example period_calc.cpp
+ Calculates if a date is in an 'irregular' collection of periods using
+ period calculation functions.
+*/
+/*! @example print_holidays.cpp
+ This is an example of using functors to define a holiday schedule
+ */
+/*! @example localization.cpp
+ Demonstrates the use of facets to localize date output for Gregorian dates.
+ */
+
+
+
diff --git a/3rdParty/Boost/libs/date_time/src/posix_time/posix_time_types.cpp b/3rdParty/Boost/libs/date_time/src/posix_time/posix_time_types.cpp
new file mode 100644
index 0000000..06ef563
--- /dev/null
+++ b/3rdParty/Boost/libs/date_time/src/posix_time/posix_time_types.cpp
@@ -0,0 +1,35 @@
+
+/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+//File doesn't have a current purpose except to generate docs
+//and keep it changeable without recompiles
+
+/** @defgroup time_basics Time Basics
+
+**/
+
+/** @defgroup time_format Time Formatting
+
+**/
+
+
+
+/*! @example local_utc_conversion.cpp
+ Demonstrate utc to local and local to utc calculations including dst.
+*/
+/*! @example time_periods.cpp Demonstrate some simple uses of time periods.
+*/
+/*! @example print_hours.cpp Demonstrate time iteration, clock retrieval, and simple calculation.
+ */
+/*! @example time_math.cpp Various types of calculations with times and time durations.
+ */
+
+
+
diff --git a/3rdParty/Boost/libs/detail/utf8_codecvt_facet.cpp b/3rdParty/Boost/libs/detail/utf8_codecvt_facet.cpp
new file mode 100644
index 0000000..658ab6a
--- /dev/null
+++ b/3rdParty/Boost/libs/detail/utf8_codecvt_facet.cpp
@@ -0,0 +1,269 @@
+/////////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;
+}
+
+// note the following code will generate on some platforms where
+// wchar_t is defined as UCS2. The warnings are superfluous as
+// the specialization is never instantitiated with such compilers.
+template<>
+int get_cont_octet_out_count_impl<4>(wchar_t word){
+ if (word < 0x80) {
+ return 0;
+ }
+ if (word < 0x800) {
+ return 1;
+ }
+ if (word < 0x10000) {
+ return 2;
+ }
+ if (word < 0x200000) {
+ return 3;
+ }
+ if (word < 0x4000000) {
+ return 4;
+ }
+ return 5;
+}
+
+} // 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/libs/filesystem/src/operations.cpp b/3rdParty/Boost/libs/filesystem/src/operations.cpp
new file mode 100644
index 0000000..0c74504
--- /dev/null
+++ b/3rdParty/Boost/libs/filesystem/src/operations.cpp
@@ -0,0 +1,1367 @@
+// 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
+
+#define _POSIX_PTHREAD_SEMANTICS // Sun readdir_r() needs this
+
+// enable the XPG-compliant version of readdir_r() on AIX
+#if defined(_AIX)
+# define _LINUX_SOURCE_COMPAT
+#endif
+
+#if !(defined(__HP_aCC) && defined(_ILP32) && \
+ !defined(_STATVFS_ACPP_PROBLEMS_FIXED))
+#define _FILE_OFFSET_BITS 64 // at worst, these defines may have no effect,
+#endif
+#define __USE_FILE_OFFSET64 // but that is harmless on Windows and on POSIX
+ // 64-bit systems or on 32-bit systems which don't have files larger
+ // than can be represented by a traditional POSIX/UNIX off_t type.
+ // OTOH, defining them should kick in 64-bit off_t's (and thus
+ // st_size) on 32-bit systems that provide the Large File
+ // Support (LFS) interface, such as Linux, Solaris, and IRIX.
+ // The defines are given before any headers are included to
+ // ensure that they are available to all included headers.
+ // That is required at least on Solaris, and possibly on other
+ // systems as well.
+
+// 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/operations.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/detail/workaround.hpp>
+
+namespace fs = boost::filesystem;
+using boost::system::error_code;
+using boost::system::system_category;
+
+# if defined(BOOST_WINDOWS_API)
+# include <windows.h>
+# if defined(__BORLANDC__) || defined(__MWERKS__)
+# if defined(__BORLANDC__)
+ using std::time_t;
+# endif
+# include <utime.h>
+# else
+# include <sys/utime.h>
+# endif
+
+# 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 <cassert>
+// #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_FILESYSTEM_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_FILESYSTEM_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_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::filesystem::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::filesystem::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 ); }
+ 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::filesystem::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::filesystem::detail::space_pair
+ space_template( String & ph )
+ {
+ ULARGE_INTEGER avail, total, free;
+ boost::filesystem::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::filesystem::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::filesystem::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 filesystem
+ {
+ 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_FILESYSTEM_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 )
+ {
+ return error_code( ::CopyFileW( from.c_str(), to.c_str(), /*fail_if_exists=*/true )
+ ? 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 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_FILESYSTEM_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 )
+ {
+ return error_code( ::CopyFileA( from.c_str(), to.c_str(), /*fail_if_exists=*/true )
+ ? 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
+ ? 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 )
+ {
+ 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
+ struct stat from_stat;
+
+ if ( ::stat( from_file_ph.c_str(), &from_stat ) != 0
+ || (infile = ::open( from_file_ph.c_str(),
+ O_RDONLY )) < 0
+ || (outfile = ::open( to_file_ph.c_str(),
+ O_WRONLY | O_CREAT | O_EXCL,
+ from_stat.st_mode )) < 0 )
+ {
+ if ( infile >= 0 ) ::close( infile );
+ return error_code( 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;
+ 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(__hpux) && defined(_REENTRANT)))
+ 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 filesystem
+} // namespace boost
diff --git a/3rdParty/Boost/libs/filesystem/src/path.cpp b/3rdParty/Boost/libs/filesystem/src/path.cpp
new file mode 100644
index 0000000..6d7d40c
--- /dev/null
+++ b/3rdParty/Boost/libs/filesystem/src/path.cpp
@@ -0,0 +1,163 @@
+// 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
+
+#include <boost/filesystem/config.hpp>
+
+#ifndef BOOST_FILESYSTEM_NARROW_ONLY
+
+#include <boost/filesystem/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
+
+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
+ static std::locale lc = std::locale(); // Mac OS doesn't support locale("")
+#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 filesystem
+ {
+ 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::throw_exception(
+ wfilesystem_error(
+ "boost::filesystem::wpath_traits::imbue() after lockdown",
+ make_error_code( system::posix::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::throw_exception( boost::filesystem::wfilesystem_error(
+ "boost::filesystem::wpath::to_external conversion error",
+ ph, system::error_code( system::posix::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::throw_exception( boost::filesystem::wfilesystem_error(
+ "boost::filesystem::wpath::to_internal conversion error",
+ system::error_code( system::posix::invalid_argument, system::system_category ) ) );
+ *to_next = L'\0';
+ return internal_string_type( work.get() );
+ }
+# endif // BOOST_POSIX_API
+
+ } // namespace filesystem
+} // namespace boost
+
+#endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY
diff --git a/3rdParty/Boost/libs/filesystem/src/portability.cpp b/3rdParty/Boost/libs/filesystem/src/portability.cpp
new file mode 100644
index 0000000..347180a
--- /dev/null
+++ b/3rdParty/Boost/libs/filesystem/src/portability.cpp
@@ -0,0 +1,115 @@
+// 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
+
+#include <boost/filesystem/config.hpp>
+#include <boost/filesystem/path.hpp>
+
+namespace fs = boost::filesystem;
+
+#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 filesystem
+ {
+
+ // 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 filesystem
+} // namespace boost
diff --git a/3rdParty/Boost/libs/filesystem/src/utf8_codecvt_facet.cpp b/3rdParty/Boost/libs/filesystem/src/utf8_codecvt_facet.cpp
new file mode 100644
index 0000000..3fe3e95
--- /dev/null
+++ b/3rdParty/Boost/libs/filesystem/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)
+
+#define BOOST_FILESYSTEM_SOURCE
+#include <boost/filesystem/config.hpp>
+
+#define BOOST_UTF8_BEGIN_NAMESPACE \
+ namespace boost { namespace filesystem { namespace detail {
+
+#define BOOST_UTF8_END_NAMESPACE }}}
+#define BOOST_UTF8_DECL BOOST_FILESYSTEM_DECL
+
+#include "libs/detail/utf8_codecvt_facet.cpp"
+
+
+#undef BOOST_UTF8_BEGIN_NAMESPACE
+#undef BOOST_UTF8_END_NAMESPACE
+#undef BOOST_UTF8_DECL
diff --git a/3rdParty/Boost/libs/filesystem/src/utf8_codecvt_facet.hpp b/3rdParty/Boost/libs/filesystem/src/utf8_codecvt_facet.hpp
new file mode 100644
index 0000000..3b78fb1
--- /dev/null
+++ b/3rdParty/Boost/libs/filesystem/src/utf8_codecvt_facet.hpp
@@ -0,0 +1,24 @@
+// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
+// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu).
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FILESYSTEM_UTF8_CODECVT_FACET_HPP
+#define BOOST_FILESYSTEM_UTF8_CODECVT_FACET_HPP
+
+#include <boost/filesystem/config.hpp>
+
+#define BOOST_UTF8_BEGIN_NAMESPACE \
+ namespace boost { namespace filesystem { namespace detail {
+
+#define BOOST_UTF8_END_NAMESPACE }}}
+#define BOOST_UTF8_DECL BOOST_FILESYSTEM_DECL
+
+#include <boost/detail/utf8_codecvt_facet.hpp>
+
+#undef BOOST_UTF8_BEGIN_NAMESPACE
+#undef BOOST_UTF8_END_NAMESPACE
+#undef BOOST_UTF8_DECL
+
+#endif
diff --git a/3rdParty/Boost/libs/signals/src/connection.cpp b/3rdParty/Boost/libs/signals/src/connection.cpp
new file mode 100644
index 0000000..b4ed8b4
--- /dev/null
+++ b/3rdParty/Boost/libs/signals/src/connection.cpp
@@ -0,0 +1,155 @@
+// Boost.Signals library
+
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_SIGNALS_SOURCE
+
+#include <boost/signals/connection.hpp>
+#include <cassert>
+
+namespace boost {
+ namespace BOOST_SIGNALS_NAMESPACE {
+
+ connection::connection(const connection& other) :
+ con(other.con), controlling_connection(other.controlling_connection)
+ {
+ }
+
+ connection::~connection()
+ {
+ if (controlling_connection) {
+ disconnect();
+ }
+ }
+
+ void
+ connection::reset(BOOST_SIGNALS_NAMESPACE::detail::basic_connection* new_con)
+ {
+ con.reset(new_con);
+ }
+
+ bool connection::operator==(const connection& other) const
+ {
+ return con.get() == other.con.get();
+ }
+
+ bool connection::operator<(const connection& other) const
+ {
+ return con.get() < other.con.get();
+ }
+
+ connection& connection::operator=(const connection& other)
+ {
+ connection(other).swap(*this);
+ return *this;
+ }
+
+ void connection::swap(connection& other)
+ {
+ this->con.swap(other.con);
+ std::swap(this->controlling_connection, other.controlling_connection);
+ }
+
+ void swap(connection& c1, connection& c2)
+ {
+ c1.swap(c2);
+ }
+
+ scoped_connection::scoped_connection(const connection& other) :
+ connection(other),
+ released(false)
+ {
+ }
+
+ scoped_connection::scoped_connection(const scoped_connection& other) :
+ connection(other),
+ released(other.released)
+ {
+ }
+
+ scoped_connection::~scoped_connection()
+ {
+ if (!released) {
+ this->disconnect();
+ }
+ }
+
+ connection scoped_connection::release()
+ {
+ released = true;
+ return *this;
+ }
+
+ void scoped_connection::swap(scoped_connection& other)
+ {
+ this->connection::swap(other);
+ bool other_released = other.released;
+ other.released = this->released;
+ this->released = other_released;
+ }
+
+ void swap(scoped_connection& c1, scoped_connection& c2)
+ {
+ c1.swap(c2);
+ }
+
+ scoped_connection&
+ scoped_connection::operator=(const connection& other)
+ {
+ scoped_connection(other).swap(*this);
+ return *this;
+ }
+
+ scoped_connection&
+ scoped_connection::operator=(const scoped_connection& other)
+ {
+ scoped_connection(other).swap(*this);
+ return *this;
+ }
+
+ void
+ connection::add_bound_object(const BOOST_SIGNALS_NAMESPACE::detail::bound_object& b)
+ {
+ assert(con.get() != 0);
+ con->bound_objects.push_back(b);
+ }
+
+
+ void connection::disconnect() const
+ {
+ if (this->connected()) {
+ // Make sure we have a reference to the basic_connection object,
+ // because 'this' may disappear
+ shared_ptr<detail::basic_connection> local_con = con;
+
+ void (*signal_disconnect)(void*, void*) = local_con->signal_disconnect;
+
+ // Note that this connection no longer exists
+ // Order is important here: we could get into an infinite loop if this
+ // isn't cleared before we try the disconnect.
+ local_con->signal_disconnect = 0;
+
+ // Disconnect signal
+ signal_disconnect(local_con->signal, local_con->signal_data);
+
+ // Disconnect all bound objects
+ typedef std::list<BOOST_SIGNALS_NAMESPACE::detail::bound_object>::iterator iterator;
+ for (iterator i = local_con->bound_objects.begin();
+ i != local_con->bound_objects.end(); ++i) {
+ assert(i->disconnect != 0);
+ i->disconnect(i->obj, i->data);
+ }
+ }
+ }
+ } // end namespace boost
+} // end namespace boost
+
+#ifndef BOOST_MSVC
+// Explicit instantiations to keep everything in the library
+template class std::list<boost::BOOST_SIGNALS_NAMESPACE::detail::bound_object>;
+#endif
diff --git a/3rdParty/Boost/libs/signals/src/named_slot_map.cpp b/3rdParty/Boost/libs/signals/src/named_slot_map.cpp
new file mode 100644
index 0000000..85a4bda
--- /dev/null
+++ b/3rdParty/Boost/libs/signals/src/named_slot_map.cpp
@@ -0,0 +1,134 @@
+// Boost.Signals library
+
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_SIGNALS_SOURCE
+
+#include <boost/signals/detail/named_slot_map.hpp>
+#include <cassert>
+#include <map>
+#include <list>
+#include <typeinfo>
+
+namespace boost { namespace BOOST_SIGNALS_NAMESPACE { namespace detail {
+
+typedef std::list<connection_slot_pair> group_list;
+typedef group_list::iterator slot_pair_iterator;
+typedef std::map<stored_group, group_list, compare_type> slot_container_type;
+typedef slot_container_type::iterator group_iterator;
+typedef slot_container_type::const_iterator const_group_iterator;
+
+
+#if BOOST_WORKAROUND(_MSC_VER, <= 1500)
+void named_slot_map_iterator::decrement() { assert(false); }
+void named_slot_map_iterator::advance(difference_type) { assert(false); }
+#endif
+
+named_slot_map::named_slot_map(const compare_type& compare) : groups(compare)
+{
+ clear();
+}
+
+void named_slot_map::clear()
+{
+ groups.clear();
+ groups[stored_group(stored_group::sk_front)];
+ groups[stored_group(stored_group::sk_back)];
+ back = groups.end();
+ --back;
+}
+
+named_slot_map::iterator named_slot_map::begin()
+{
+ return named_slot_map::iterator(groups.begin(), groups.end());
+}
+
+named_slot_map::iterator named_slot_map::end()
+{
+ return named_slot_map::iterator(groups.end(), groups.end());
+}
+
+named_slot_map::iterator
+named_slot_map::insert(const stored_group& name, const connection& con,
+ const any& slot, connect_position at)
+{
+ group_iterator group;
+ if (name.empty()) {
+ switch (at) {
+ case at_front: group = groups.begin(); break;
+ case at_back: group = back; break;
+ }
+ } else {
+ group = groups.find(name);
+ if (group == groups.end()) {
+ slot_container_type::value_type v(name, group_list());
+ group = groups.insert(v).first;
+ }
+ }
+ iterator it;
+ it.group = group;
+ it.last_group = groups.end();
+
+ switch (at) {
+ case at_back:
+ group->second.push_back(connection_slot_pair(con, slot));
+ it.slot_ = group->second.end();
+ it.slot_assigned = true;
+ --(it.slot_);
+ break;
+
+ case at_front:
+ group->second.push_front(connection_slot_pair(con, slot));
+ it.slot_ = group->second.begin();
+ it.slot_assigned = true;
+ break;
+ }
+ return it;
+}
+
+void named_slot_map::disconnect(const stored_group& name)
+{
+ group_iterator group = groups.find(name);
+ if (group != groups.end()) {
+ slot_pair_iterator i = group->second.begin();
+ while (i != group->second.end()) {
+ slot_pair_iterator next = i;
+ ++next;
+ i->first.disconnect();
+ i = next;
+ }
+ groups.erase(group);
+ }
+}
+
+void named_slot_map::erase(iterator pos)
+{
+ // Erase the slot
+ pos.slot_->first.disconnect();
+ pos.group->second.erase(pos.slot_);
+}
+
+void named_slot_map::remove_disconnected_slots()
+{
+ // Remove any disconnected slots
+ group_iterator g = groups.begin();
+ while (g != groups.end()) {
+ slot_pair_iterator s = g->second.begin();
+ while (s != g->second.end()) {
+ if (s->first.connected()) ++s;
+ else g->second.erase(s++);
+ }
+
+ // Clear out empty groups
+ if (empty(g)) groups.erase(g++);
+ else ++g;
+ }
+}
+
+
+} } }
diff --git a/3rdParty/Boost/libs/signals/src/signal_base.cpp b/3rdParty/Boost/libs/signals/src/signal_base.cpp
new file mode 100644
index 0000000..759672d
--- /dev/null
+++ b/3rdParty/Boost/libs/signals/src/signal_base.cpp
@@ -0,0 +1,189 @@
+// Boost.Signals library
+
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_SIGNALS_SOURCE
+
+#include <boost/signals/detail/signal_base.hpp>
+#include <cassert>
+
+namespace boost {
+ namespace BOOST_SIGNALS_NAMESPACE {
+ namespace detail {
+ signal_base_impl::signal_base_impl(const compare_type& comp,
+ const any& combiner)
+ : call_depth(0),
+ slots_(comp),
+ combiner_(combiner)
+ {
+ flags.delayed_disconnect = false;
+ flags.clearing = false;
+ }
+
+ signal_base_impl::~signal_base_impl()
+ {
+ // Set the "clearing" flag to ignore extraneous disconnect requests,
+ // because all slots will be disconnected on destruction anyway.
+ flags.clearing = true;
+ }
+
+ void signal_base_impl::disconnect_all_slots()
+ {
+ // Do nothing if we're already clearing the slot list
+ if (flags.clearing)
+ return;
+
+ if (call_depth == 0) {
+ // Clearing the slot list will disconnect all slots automatically
+ temporarily_set_clearing set_clearing(this);
+ slots_.clear();
+ }
+ else {
+ // We can't actually remove elements from the slot list because there
+ // are still iterators into the slot list that must not be
+ // invalidated by this operation. So just disconnect each slot
+ // without removing it from the slot list. When the call depth does
+ // reach zero, the call list will be cleared.
+ flags.delayed_disconnect = true;
+ temporarily_set_clearing set_clearing(this);
+ for (iterator i = slots_.begin(); i != slots_.end(); ++i) {
+ i->first.disconnect();
+ }
+ }
+ }
+
+ connection
+ signal_base_impl::
+ connect_slot(const any& slot_,
+ const stored_group& name,
+ shared_ptr<slot_base::data_t> data,
+ connect_position at)
+ {
+ // Transfer the burden of ownership to a local, scoped
+ // connection.
+ data->watch_bound_objects.set_controlling(false);
+ scoped_connection safe_connection(data->watch_bound_objects);
+
+ // Allocate storage for an iterator that will hold the point of
+ // insertion of the slot into the list. This is used to later remove
+ // the slot when it is disconnected.
+ std::auto_ptr<iterator> saved_iter(new iterator);
+
+ // Add the slot to the list.
+ iterator pos =
+ slots_.insert(name, data->watch_bound_objects, slot_, at);
+
+ // The assignment operation here absolutely must not throw, which
+ // intuitively makes sense (because any container's insert method
+ // becomes impossible to use in an exception-safe manner without this
+ // assumption), but doesn't appear to be mentioned in the standard.
+ *saved_iter = pos;
+
+ // Fill out the connection object appropriately. None of these
+ // operations can throw
+ data->watch_bound_objects.get_connection()->signal = this;
+ data->watch_bound_objects.get_connection()->signal_data =
+ saved_iter.release();
+ data->watch_bound_objects.get_connection()->signal_disconnect =
+ &signal_base_impl::slot_disconnected;
+
+ // Make the copy of the connection in the list disconnect when it is
+ // destroyed. The local, scoped connection is then released
+ // because ownership has been transferred.
+ pos->first.set_controlling();
+ return safe_connection.release();
+ }
+
+ bool signal_base_impl::empty() const
+ {
+ // Disconnected slots may still be in the list of slots if
+ // a) this is called while slots are being invoked (call_depth > 0)
+ // b) an exception was thrown in remove_disconnected_slots
+ for (iterator i = slots_.begin(); i != slots_.end(); ++i) {
+ if (i->first.connected())
+ return false;
+ }
+
+ return true;
+ }
+
+ std::size_t signal_base_impl::num_slots() const
+ {
+ // Disconnected slots may still be in the list of slots if
+ // a) this is called while slots are being invoked (call_depth > 0)
+ // b) an exception was thrown in remove_disconnected_slots
+ std::size_t count = 0;
+ for (iterator i = slots_.begin(); i != slots_.end(); ++i) {
+ if (i->first.connected())
+ ++count;
+ }
+ return count;
+ }
+
+ void signal_base_impl::disconnect(const stored_group& group)
+ { slots_.disconnect(group); }
+
+ void signal_base_impl::slot_disconnected(void* obj, void* data)
+ {
+ signal_base_impl* self = reinterpret_cast<signal_base_impl*>(obj);
+
+ // We won't need the slot iterator after this
+ std::auto_ptr<iterator> slot(reinterpret_cast<iterator*>(data));
+
+ // If we're flags.clearing, we don't bother updating the list of slots
+ if (!self->flags.clearing) {
+ // If we're in a call, note the fact that a slot has been deleted so
+ // we can come back later to remove the iterator
+ if (self->call_depth > 0) {
+ self->flags.delayed_disconnect = true;
+ }
+ else {
+ // Just remove the slot now, it's safe
+ self->slots_.erase(*slot);
+ }
+ }
+ }
+
+ void signal_base_impl::remove_disconnected_slots() const
+ { slots_.remove_disconnected_slots(); }
+
+ call_notification::
+ call_notification(const shared_ptr<signal_base_impl>& b) :
+ impl(b)
+ {
+ // A call will be made, so increment the call depth as a notification
+ impl->call_depth++;
+ }
+
+ call_notification::~call_notification()
+ {
+ impl->call_depth--;
+
+ // If the call depth is zero and we have some slots that have been
+ // disconnected during the calls, remove those slots from the list
+ if (impl->call_depth == 0 &&
+ impl->flags.delayed_disconnect) {
+ impl->remove_disconnected_slots();
+ impl->flags.delayed_disconnect = false;
+ }
+ }
+
+ signal_base::signal_base(const compare_type& comp, const any& combiner)
+ : impl()
+ {
+ impl.reset(new signal_base_impl(comp, combiner));
+ }
+
+ signal_base::~signal_base()
+ {
+ }
+
+ } // namespace detail
+ } // namespace BOOST_SIGNALS_NAMESPACE
+} // namespace boost
+
diff --git a/3rdParty/Boost/libs/signals/src/slot.cpp b/3rdParty/Boost/libs/signals/src/slot.cpp
new file mode 100644
index 0000000..7c296d6
--- /dev/null
+++ b/3rdParty/Boost/libs/signals/src/slot.cpp
@@ -0,0 +1,71 @@
+// Boost.Signals library
+
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_SIGNALS_SOURCE
+
+#include <boost/signals/slot.hpp>
+
+namespace boost {
+ namespace BOOST_SIGNALS_NAMESPACE {
+ namespace detail {
+ void slot_base::create_connection()
+ {
+ // Create a new connection object
+ basic_connection* con = new basic_connection();
+
+ /* nothrow */ {
+ // The signal portion isn't really necessary, except that we need a
+ // signal for the connection to be connected.
+ con->signal = static_cast<void*>(this);
+ con->signal_data = 0;
+ con->blocked_ = false ;
+ con->signal_disconnect = &bound_object_destructed;
+ }
+
+ // This connection watches for destruction of bound objects. Note
+ // that the reset routine will delete con if an allocation throws
+ data->watch_bound_objects.reset(con);
+
+ // We create a scoped connection, so that exceptions thrown while
+ // adding bound objects will cause a cleanup of the bound objects
+ // already connected.
+ scoped_connection safe_connection(data->watch_bound_objects);
+
+ // Now notify each of the bound objects that they are connected to this
+ // slot.
+ for(std::vector<const trackable*>::iterator i =
+ data->bound_objects.begin();
+ i != data->bound_objects.end(); ++i) {
+ // Notify the object that the slot is connecting to it
+ BOOST_SIGNALS_NAMESPACE::detail::bound_object binding;
+ (*i)->signal_connected(data->watch_bound_objects, binding);
+
+ // This will notify the bound object that the connection just made
+ // should be disconnected if an exception is thrown before the
+ // end of this iteration
+ BOOST_SIGNALS_NAMESPACE::detail::auto_disconnect_bound_object
+ disconnector(binding);
+
+ // Add the binding to the list of bindings for the connection
+ con->bound_objects.push_back(binding);
+
+ // The connection object now knows about the bound object, so if an
+ // exception is thrown later the connection object will notify the
+ // bound object of the disconnection automatically
+ disconnector.release();
+ }
+
+ // No exceptions will be thrown past this point.
+ safe_connection.release();
+
+ data->watch_bound_objects.set_controlling(true);
+ }
+ } // end namespace detail
+ } // end namespace BOOST_SIGNALS_NAMESPACE
+} // end namespace boost
diff --git a/3rdParty/Boost/libs/signals/src/trackable.cpp b/3rdParty/Boost/libs/signals/src/trackable.cpp
new file mode 100644
index 0000000..4f63586
--- /dev/null
+++ b/3rdParty/Boost/libs/signals/src/trackable.cpp
@@ -0,0 +1,59 @@
+// Boost.Signals library
+
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_SIGNALS_SOURCE
+
+#include <boost/signals/trackable.hpp>
+#include <algorithm>
+
+namespace boost {
+ namespace BOOST_SIGNALS_NAMESPACE {
+ void trackable::signal_disconnected(void* obj, void* data)
+ {
+ trackable* self = reinterpret_cast<trackable*>(obj);
+ connection_iterator* signal =
+ reinterpret_cast<connection_iterator*>(data);
+
+ // If we're dying, don't bother erasing the connection from the list;
+ // it'll be gone anyway
+ if (!self->dying) {
+ self->connected_signals.erase(*signal);
+ }
+
+ // This iterator pointer won't ever be used again
+ delete signal;
+ }
+
+ void
+ trackable::signal_connected(connection c,
+ BOOST_SIGNALS_NAMESPACE::detail::bound_object& binding) const
+ {
+ // Insert the connection
+ connection_iterator pos =
+ connected_signals.insert(connected_signals.end(), c);
+
+ // Make this copy of the object disconnect when destroyed
+ pos->set_controlling();
+
+ binding.obj = const_cast<void*>(reinterpret_cast<const void*>(this));
+ binding.data = reinterpret_cast<void*>(new connection_iterator(pos));
+ binding.disconnect = &signal_disconnected;
+ }
+
+ trackable::~trackable()
+ {
+ dying = true;
+ }
+ } // end namespace BOOST_SIGNALS_NAMESPACE
+}
+
+#ifndef BOOST_MSVC
+// Explicit instantiations to keep in the library
+template class std::list<boost::BOOST_SIGNALS_NAMESPACE::connection>;
+#endif
diff --git a/3rdParty/Boost/libs/system/src/error_code.cpp b/3rdParty/Boost/libs/system/src/error_code.cpp
new file mode 100644
index 0000000..030ab70
--- /dev/null
+++ b/3rdParty/Boost/libs/system/src/error_code.cpp
@@ -0,0 +1,433 @@
+// error_code support implementation file ----------------------------------//
+
+// Copyright Beman Dawes 2002, 2006
+
+// 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/system
+
+//----------------------------------------------------------------------------//
+
+#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::posix_error;
+
+#include <cstring> // for strerror/strerror_r
+
+# if defined( BOOST_WINDOWS_API )
+# include <windows.h>
+# ifndef ERROR_INCORRECT_SIZE
+# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS
+# endif
+# endif
+
+//----------------------------------------------------------------------------//
+
+namespace
+{
+ // 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_synbolic_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
+ case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable );
+ 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 );
+ case EOWNERDEAD: return make_error_condition( owner_dead );
+ 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
+// TODO:
+
+//Some quick notes on the implementation (sorry for the noise if
+//someone has already mentioned them):
+//
+//- The ::LocalFree() usage isn't exception safe.
+//
+//See:
+//
+//<http://boost.cvs.sourceforge.net/boost/boost/boost/asio/system_exception.hpp?revision=1.1&view=markup>
+//
+//in the implementation of what() for an example.
+//
+//Cheers,
+//Chris
+ std::string system_error_category::message( int ev ) const
+ {
+# ifndef BOOST_NO_ANSI_APIS
+ LPVOID lpMsgBuf;
+ 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
+ );
+ if (retval == 0)
+ return std::string("Unknown error");
+
+ std::string str( static_cast<LPCSTR>(lpMsgBuf) );
+ ::LocalFree( lpMsgBuf ); // free the buffer
+# else // WinCE workaround
+ LPVOID lpMsgBuf;
+ 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
+ );
+ 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 );
+ ::LocalFree( lpMsgBuf ); // free the 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
+ {
+
+ 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
+
+ BOOST_SYSTEM_DECL const error_category & get_system_category()
+ {
+ static const system_error_category system_category_const;
+ return system_category_const;
+ }
+
+ BOOST_SYSTEM_DECL const error_category & get_generic_category()
+ {
+ static const generic_error_category generic_category_const;
+ return generic_category_const;
+ }
+
+ } // namespace system
+} // namespace boost
diff --git a/3rdParty/Boost/libs/thread/src/pthread/exceptions.cpp b/3rdParty/Boost/libs/thread/src/pthread/exceptions.cpp
new file mode 100644
index 0000000..8881303
--- /dev/null
+++ b/3rdParty/Boost/libs/thread/src/pthread/exceptions.cpp
@@ -0,0 +1,124 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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/thread/detail/config.hpp>
+
+#include <boost/thread/exceptions.hpp>
+#include <cstring>
+#include <string>
+
+namespace boost {
+
+thread_exception::thread_exception()
+ : m_sys_err(0)
+{
+}
+
+thread_exception::thread_exception(int sys_err_code)
+ : m_sys_err(sys_err_code)
+{
+}
+
+thread_exception::~thread_exception() throw()
+{
+}
+
+int thread_exception::native_error() const
+{
+ return m_sys_err;
+}
+
+lock_error::lock_error()
+{
+}
+
+lock_error::lock_error(int sys_err_code)
+ : thread_exception(sys_err_code)
+{
+}
+
+lock_error::~lock_error() throw()
+{
+}
+
+const char* lock_error::what() const throw()
+{
+ return "boost::lock_error";
+}
+
+thread_resource_error::thread_resource_error()
+{
+}
+
+thread_resource_error::thread_resource_error(int sys_err_code)
+ : thread_exception(sys_err_code)
+{
+}
+
+thread_resource_error::~thread_resource_error() throw()
+{
+}
+
+const char* thread_resource_error::what() const throw()
+{
+ return "boost::thread_resource_error";
+}
+
+unsupported_thread_option::unsupported_thread_option()
+{
+}
+
+unsupported_thread_option::unsupported_thread_option(int sys_err_code)
+ : thread_exception(sys_err_code)
+{
+}
+
+unsupported_thread_option::~unsupported_thread_option() throw()
+{
+}
+
+const char* unsupported_thread_option::what() const throw()
+{
+ return "boost::unsupported_thread_option";
+}
+
+invalid_thread_argument::invalid_thread_argument()
+{
+}
+
+invalid_thread_argument::invalid_thread_argument(int sys_err_code)
+ : thread_exception(sys_err_code)
+{
+}
+
+invalid_thread_argument::~invalid_thread_argument() throw()
+{
+}
+
+const char* invalid_thread_argument::what() const throw()
+{
+ return "boost::invalid_thread_argument";
+}
+
+thread_permission_error::thread_permission_error()
+{
+}
+
+thread_permission_error::thread_permission_error(int sys_err_code)
+ : thread_exception(sys_err_code)
+{
+}
+
+thread_permission_error::~thread_permission_error() throw()
+{
+}
+
+const char* thread_permission_error::what() const throw()
+{
+ return "boost::thread_permission_error";
+}
+
+} // namespace boost
diff --git a/3rdParty/Boost/libs/thread/src/pthread/once.cpp b/3rdParty/Boost/libs/thread/src/pthread/once.cpp
new file mode 100644
index 0000000..6e3722a
--- /dev/null
+++ b/3rdParty/Boost/libs/thread/src/pthread/once.cpp
@@ -0,0 +1,51 @@
+// Copyright (C) 2007 Anthony Williams
+//
+// 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/once.hpp>
+#include <boost/assert.hpp>
+#include <pthread.h>
+#include <stdlib.h>
+
+namespace boost
+{
+ namespace detail
+ {
+ BOOST_THREAD_DECL boost::uintmax_t once_global_epoch=UINTMAX_C(~0);
+ BOOST_THREAD_DECL pthread_mutex_t once_epoch_mutex=PTHREAD_MUTEX_INITIALIZER;
+ BOOST_THREAD_DECL pthread_cond_t once_epoch_cv = PTHREAD_COND_INITIALIZER;
+
+ namespace
+ {
+ pthread_key_t epoch_tss_key;
+ pthread_once_t epoch_tss_key_flag=PTHREAD_ONCE_INIT;
+
+ extern "C" void delete_epoch_tss_data(void* data)
+ {
+ free(data);
+ }
+
+ extern "C" void create_epoch_tss_key()
+ {
+ BOOST_VERIFY(!pthread_key_create(&epoch_tss_key,delete_epoch_tss_data));
+ }
+
+ }
+
+ boost::uintmax_t& get_once_per_thread_epoch()
+ {
+ BOOST_VERIFY(!pthread_once(&epoch_tss_key_flag,create_epoch_tss_key));
+ void* data=pthread_getspecific(epoch_tss_key);
+ if(!data)
+ {
+ data=malloc(sizeof(boost::uintmax_t));
+ BOOST_VERIFY(!pthread_setspecific(epoch_tss_key,data));
+ *static_cast<boost::uintmax_t*>(data)=UINTMAX_C(~0);
+ }
+ return *static_cast<boost::uintmax_t*>(data);
+ }
+ }
+
+}
diff --git a/3rdParty/Boost/libs/thread/src/pthread/thread.cpp b/3rdParty/Boost/libs/thread/src/pthread/thread.cpp
new file mode 100644
index 0000000..cc71d97
--- /dev/null
+++ b/3rdParty/Boost/libs/thread/src/pthread/thread.cpp
@@ -0,0 +1,678 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2007-8 Anthony Williams
+//
+// 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/thread/detail/config.hpp>
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/once.hpp>
+#include <boost/thread/tss.hpp>
+#ifdef __linux__
+#include <sys/sysinfo.h>
+#elif defined(__APPLE__) || defined(__FreeBSD__)
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#elif defined BOOST_HAS_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "timeconv.inl"
+
+namespace boost
+{
+ namespace detail
+ {
+ thread_data_base::~thread_data_base()
+ {}
+
+ struct thread_exit_callback_node
+ {
+ boost::detail::thread_exit_function_base* func;
+ thread_exit_callback_node* next;
+
+ thread_exit_callback_node(boost::detail::thread_exit_function_base* func_,
+ thread_exit_callback_node* next_):
+ func(func_),next(next_)
+ {}
+ };
+
+ 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_)
+ {}
+ };
+
+ namespace
+ {
+ boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT;
+ pthread_key_t current_thread_tls_key;
+
+ extern "C"
+ {
+ void tls_destructor(void* data)
+ {
+ boost::detail::thread_data_base* thread_info=static_cast<boost::detail::thread_data_base*>(data);
+ if(thread_info)
+ {
+ while(thread_info->tss_data || thread_info->thread_exit_callbacks)
+ {
+ while(thread_info->thread_exit_callbacks)
+ {
+ detail::thread_exit_callback_node* const current_node=thread_info->thread_exit_callbacks;
+ thread_info->thread_exit_callbacks=current_node->next;
+ if(current_node->func)
+ {
+ (*current_node->func)();
+ delete current_node->func;
+ }
+ delete current_node;
+ }
+ while(thread_info->tss_data)
+ {
+ detail::tss_data_node* const current_node=thread_info->tss_data;
+ thread_info->tss_data=current_node->next;
+ if(current_node->func)
+ {
+ (*current_node->func)(current_node->value);
+ }
+ delete current_node;
+ }
+ }
+ thread_info->self.reset();
+ }
+ }
+ }
+
+
+ void create_current_thread_tls_key()
+ {
+ BOOST_VERIFY(!pthread_key_create(&current_thread_tls_key,&tls_destructor));
+ }
+ }
+
+ boost::detail::thread_data_base* get_current_thread_data()
+ {
+ boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key);
+ return (boost::detail::thread_data_base*)pthread_getspecific(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);
+ BOOST_VERIFY(!pthread_setspecific(current_thread_tls_key,new_data));
+ }
+ }
+
+ namespace
+ {
+ extern "C"
+ {
+ 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
+ {
+ thread_info->run();
+ }
+ 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(...)
+// {
+// std::terminate();
+// }
+
+ detail::tls_destructor(thread_info.get());
+ detail::set_current_thread_data(0);
+ boost::lock_guard<boost::mutex> lock(thread_info->data_mutex);
+ thread_info->done=true;
+ thread_info->done_condition.notify_all();
+ return 0;
+ }
+ }
+
+ struct externally_launched_thread:
+ detail::thread_data_base
+ {
+ externally_launched_thread()
+ {
+ interrupt_enabled=false;
+ }
+
+ void run()
+ {}
+
+ private:
+ externally_launched_thread(externally_launched_thread&);
+ void operator=(externally_launched_thread&);
+ };
+
+ detail::thread_data_base* make_external_thread_data()
+ {
+ detail::thread_data_base* const me(new externally_launched_thread());
+ me->self.reset(me);
+ set_current_thread_data(me);
+ return me;
+ }
+
+
+ detail::thread_data_base* get_or_make_current_thread_data()
+ {
+ detail::thread_data_base* current_thread_data(detail::get_current_thread_data());
+ if(!current_thread_data)
+ {
+ current_thread_data=make_external_thread_data();
+ }
+ return current_thread_data;
+ }
+
+ }
+
+
+ thread::thread()
+ {}
+
+ void thread::start_thread()
+ {
+ thread_info->self=thread_info;
+ int const res = pthread_create(&thread_info->thread_handle, 0, &thread_proxy, thread_info.get());
+ if (res != 0)
+ {
+ thread_info->self.reset();
+ throw thread_resource_error();
+ }
+ }
+
+ thread::~thread()
+ {
+ detach();
+ }
+
+ detail::thread_data_ptr thread::get_thread_info() const
+ {
+ lock_guard<mutex> l(thread_info_mutex);
+ return thread_info;
+ }
+
+ void thread::join()
+ {
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
+ if(local_thread_info)
+ {
+ bool do_join=false;
+
+ {
+ unique_lock<mutex> lock(local_thread_info->data_mutex);
+ while(!local_thread_info->done)
+ {
+ local_thread_info->done_condition.wait(lock);
+ }
+ do_join=!local_thread_info->join_started;
+
+ if(do_join)
+ {
+ local_thread_info->join_started=true;
+ }
+ else
+ {
+ while(!local_thread_info->joined)
+ {
+ local_thread_info->done_condition.wait(lock);
+ }
+ }
+ }
+ if(do_join)
+ {
+ void* result=0;
+ BOOST_VERIFY(!pthread_join(local_thread_info->thread_handle,&result));
+ lock_guard<mutex> lock(local_thread_info->data_mutex);
+ local_thread_info->joined=true;
+ local_thread_info->done_condition.notify_all();
+ }
+
+ lock_guard<mutex> l1(thread_info_mutex);
+ if(thread_info==local_thread_info)
+ {
+ thread_info.reset();
+ }
+ }
+ }
+
+ bool thread::timed_join(system_time const& wait_until)
+ {
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
+ if(local_thread_info)
+ {
+ bool do_join=false;
+
+ {
+ unique_lock<mutex> lock(local_thread_info->data_mutex);
+ while(!local_thread_info->done)
+ {
+ if(!local_thread_info->done_condition.timed_wait(lock,wait_until))
+ {
+ return false;
+ }
+ }
+ do_join=!local_thread_info->join_started;
+
+ if(do_join)
+ {
+ local_thread_info->join_started=true;
+ }
+ else
+ {
+ while(!local_thread_info->joined)
+ {
+ local_thread_info->done_condition.wait(lock);
+ }
+ }
+ }
+ if(do_join)
+ {
+ void* result=0;
+ BOOST_VERIFY(!pthread_join(local_thread_info->thread_handle,&result));
+ lock_guard<mutex> lock(local_thread_info->data_mutex);
+ local_thread_info->joined=true;
+ local_thread_info->done_condition.notify_all();
+ }
+
+ lock_guard<mutex> l1(thread_info_mutex);
+ if(thread_info==local_thread_info)
+ {
+ thread_info.reset();
+ }
+ }
+ return true;
+ }
+
+ bool thread::joinable() const
+ {
+ return get_thread_info();
+ }
+
+
+ void thread::detach()
+ {
+ detail::thread_data_ptr local_thread_info;
+ {
+ lock_guard<mutex> l1(thread_info_mutex);
+ thread_info.swap(local_thread_info);
+ }
+
+ 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;
+ }
+ }
+ }
+
+ namespace this_thread
+ {
+
+ void sleep(const system_time& st)
+ {
+ detail::thread_data_base* const thread_info=detail::get_current_thread_data();
+
+ if(thread_info)
+ {
+ unique_lock<mutex> lk(thread_info->sleep_mutex);
+ while(thread_info->sleep_condition.timed_wait(lk,st));
+ }
+ else
+ {
+ xtime const xt=get_xtime(st);
+
+ for (int foo=0; foo < 5; ++foo)
+ {
+# if defined(BOOST_HAS_PTHREAD_DELAY_NP)
+ timespec ts;
+ to_timespec_duration(xt, ts);
+ BOOST_VERIFY(!pthread_delay_np(&ts));
+# elif defined(BOOST_HAS_NANOSLEEP)
+ timespec ts;
+ to_timespec_duration(xt, ts);
+
+ // nanosleep takes a timespec that is an offset, not
+ // an absolute time.
+ nanosleep(&ts, 0);
+# else
+ mutex mx;
+ mutex::scoped_lock lock(mx);
+ condition cond;
+ cond.timed_wait(lock, xt);
+# endif
+ xtime cur;
+ xtime_get(&cur, TIME_UTC);
+ if (xtime_cmp(xt, cur) <= 0)
+ return;
+ }
+ }
+ }
+
+ void yield()
+ {
+# if defined(BOOST_HAS_SCHED_YIELD)
+ BOOST_VERIFY(!sched_yield());
+# elif defined(BOOST_HAS_PTHREAD_YIELD)
+ BOOST_VERIFY(!pthread_yield());
+# else
+ xtime xt;
+ xtime_get(&xt, TIME_UTC);
+ sleep(xt);
+# endif
+ }
+ }
+
+ unsigned thread::hardware_concurrency()
+ {
+#if defined(PTW32_VERSION) || defined(__hpux)
+ return pthread_num_processors_np();
+#elif defined(__linux__)
+ return get_nprocs();
+#elif defined(__APPLE__) || defined(__FreeBSD__)
+ int count;
+ size_t size=sizeof(count);
+ return sysctlbyname("hw.ncpu",&count,&size,NULL,0)?0:count;
+#elif defined(BOOST_HAS_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN)
+ int const count=sysconf(_SC_NPROCESSORS_ONLN);
+ return (count>0)?count:0;
+#else
+ return 0;
+#endif
+ }
+
+ thread::id thread::get_id() const
+ {
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
+ if(local_thread_info)
+ {
+ return id(local_thread_info);
+ }
+ else
+ {
+ return id();
+ }
+ }
+
+ void thread::interrupt()
+ {
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
+ if(local_thread_info)
+ {
+ lock_guard<mutex> lk(local_thread_info->data_mutex);
+ local_thread_info->interrupt_requested=true;
+ if(local_thread_info->current_cond)
+ {
+ BOOST_VERIFY(!pthread_cond_broadcast(local_thread_info->current_cond));
+ }
+ }
+ }
+
+ bool thread::interruption_requested() const
+ {
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
+ if(local_thread_info)
+ {
+ lock_guard<mutex> lk(local_thread_info->data_mutex);
+ return local_thread_info->interrupt_requested;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ thread::native_handle_type thread::native_handle()
+ {
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
+ if(local_thread_info)
+ {
+ lock_guard<mutex> lk(local_thread_info->data_mutex);
+ return local_thread_info->thread_handle;
+ }
+ else
+ {
+ return pthread_t();
+ }
+ }
+
+
+
+ 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()
+ {
+ boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
+ if(thread_info && thread_info->interrupt_enabled)
+ {
+ lock_guard<mutex> lg(thread_info->data_mutex);
+ if(thread_info->interrupt_requested)
+ {
+ thread_info->interrupt_requested=false;
+ throw thread_interrupted();
+ }
+ }
+ }
+
+ bool interruption_enabled()
+ {
+ boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
+ return thread_info && thread_info->interrupt_enabled;
+ }
+
+ bool interruption_requested()
+ {
+ boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
+ if(!thread_info)
+ {
+ return false;
+ }
+ else
+ {
+ lock_guard<mutex> lg(thread_info->data_mutex);
+ return thread_info->interrupt_requested;
+ }
+ }
+
+ disable_interruption::disable_interruption():
+ interruption_was_enabled(interruption_enabled())
+ {
+ if(interruption_was_enabled)
+ {
+ detail::get_current_thread_data()->interrupt_enabled=false;
+ }
+ }
+
+ disable_interruption::~disable_interruption()
+ {
+ if(detail::get_current_thread_data())
+ {
+ detail::get_current_thread_data()->interrupt_enabled=interruption_was_enabled;
+ }
+ }
+
+ restore_interruption::restore_interruption(disable_interruption& d)
+ {
+ if(d.interruption_was_enabled)
+ {
+ detail::get_current_thread_data()->interrupt_enabled=true;
+ }
+ }
+
+ restore_interruption::~restore_interruption()
+ {
+ if(detail::get_current_thread_data())
+ {
+ detail::get_current_thread_data()->interrupt_enabled=false;
+ }
+ }
+ }
+
+ namespace detail
+ {
+ void add_thread_exit_function(thread_exit_function_base* func)
+ {
+ 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);
+ current_thread_data->thread_exit_callbacks=new_node;
+ }
+
+ tss_data_node* find_tss_data(void const* key)
+ {
+ detail::thread_data_base* const current_thread_data(get_current_thread_data());
+ if(current_thread_data)
+ {
+ detail::tss_data_node* current_node=current_thread_data->tss_data;
+ while(current_node)
+ {
+ if(current_node->key==key)
+ {
+ return current_node;
+ }
+ current_node=current_node->next;
+ }
+ }
+ return NULL;
+ }
+
+ void* get_tss_data(void const* key)
+ {
+ if(tss_data_node* const current_node=find_tss_data(key))
+ {
+ return current_node->value;
+ }
+ return NULL;
+ }
+
+ 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)
+ {
+ (*current_node->func)(current_node->value);
+ }
+ current_node->func=func;
+ current_node->value=tss_data;
+ }
+ else
+ {
+ detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
+ tss_data_node* const new_node=new tss_data_node(key,func,tss_data,current_thread_data->tss_data);
+ current_thread_data->tss_data=new_node;
+ }
+ }
+ }
+
+// thread_group::thread_group()
+// {
+// }
+
+// thread_group::~thread_group()
+// {
+// // We shouldn't have to scoped_lock here, since referencing this object
+// // from another thread while we're deleting it in the current thread is
+// // going to lead to undefined behavior any way.
+// for (std::list<thread*>::iterator it = m_threads.begin();
+// it != m_threads.end(); ++it)
+// {
+// delete (*it);
+// }
+// }
+
+// thread* thread_group::create_thread(const function0<void>& threadfunc)
+// {
+// // No scoped_lock required here since the only "shared data" that's
+// // modified here occurs inside add_thread which does scoped_lock.
+// std::auto_ptr<thread> thrd(new thread(threadfunc));
+// add_thread(thrd.get());
+// return thrd.release();
+// }
+
+// void thread_group::add_thread(thread* thrd)
+// {
+// mutex::scoped_lock scoped_lock(m_mutex);
+
+// // For now we'll simply ignore requests to add a thread object multiple
+// // times. Should we consider this an error and either throw or return an
+// // error value?
+// std::list<thread*>::iterator it = std::find(m_threads.begin(),
+// m_threads.end(), thrd);
+// BOOST_ASSERT(it == m_threads.end());
+// if (it == m_threads.end())
+// m_threads.push_back(thrd);
+// }
+
+// void thread_group::remove_thread(thread* thrd)
+// {
+// mutex::scoped_lock scoped_lock(m_mutex);
+
+// // For now we'll simply ignore requests to remove a thread object that's
+// // not in the group. Should we consider this an error and either throw or
+// // return an error value?
+// std::list<thread*>::iterator it = std::find(m_threads.begin(),
+// m_threads.end(), thrd);
+// BOOST_ASSERT(it != m_threads.end());
+// if (it != m_threads.end())
+// m_threads.erase(it);
+// }
+
+// void thread_group::join_all()
+// {
+// mutex::scoped_lock scoped_lock(m_mutex);
+// for (std::list<thread*>::iterator it = m_threads.begin();
+// it != m_threads.end(); ++it)
+// {
+// (*it)->join();
+// }
+// }
+
+// void thread_group::interrupt_all()
+// {
+// boost::lock_guard<mutex> guard(m_mutex);
+
+// for(std::list<thread*>::iterator it=m_threads.begin(),end=m_threads.end();
+// it!=end;
+// ++it)
+// {
+// (*it)->interrupt();
+// }
+// }
+
+
+// size_t thread_group::size() const
+// {
+// return m_threads.size();
+// }
+
+}
diff --git a/3rdParty/Boost/libs/thread/src/pthread/timeconv.inl b/3rdParty/Boost/libs/thread/src/pthread/timeconv.inl
new file mode 100644
index 0000000..5ec3b17
--- /dev/null
+++ b/3rdParty/Boost/libs/thread/src/pthread/timeconv.inl
@@ -0,0 +1,130 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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)
+
+// boostinspect:nounnamed
+
+namespace {
+const int MILLISECONDS_PER_SECOND = 1000;
+const int NANOSECONDS_PER_SECOND = 1000000000;
+const int NANOSECONDS_PER_MILLISECOND = 1000000;
+
+const int MICROSECONDS_PER_SECOND = 1000000;
+const int NANOSECONDS_PER_MICROSECOND = 1000;
+
+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);
+
+ xt.sec += (milliseconds / MILLISECONDS_PER_SECOND);
+ xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
+ NANOSECONDS_PER_MILLISECOND);
+
+ if (xt.nsec >= NANOSECONDS_PER_SECOND)
+ {
+ ++xt.sec;
+ xt.nsec -= NANOSECONDS_PER_SECOND;
+ }
+}
+
+#if defined(BOOST_HAS_PTHREADS)
+inline void to_timespec(const boost::xtime& xt, timespec& ts)
+{
+ ts.tv_sec = static_cast<int>(xt.sec);
+ ts.tv_nsec = static_cast<int>(xt.nsec);
+ if(ts.tv_nsec >= NANOSECONDS_PER_SECOND)
+ {
+ ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
+ ts.tv_nsec %= NANOSECONDS_PER_SECOND;
+ }
+}
+
+inline void to_time(int milliseconds, timespec& ts)
+{
+ boost::xtime xt;
+ to_time(milliseconds, xt);
+ to_timespec(xt, ts);
+}
+
+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);
+
+ if (boost::xtime_cmp(xt, cur) <= 0)
+ {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ }
+ else
+ {
+ ts.tv_sec = xt.sec - cur.sec;
+ ts.tv_nsec = xt.nsec - cur.nsec;
+
+ if( ts.tv_nsec < 0 )
+ {
+ ts.tv_sec -= 1;
+ ts.tv_nsec += NANOSECONDS_PER_SECOND;
+ }
+ if(ts.tv_nsec >= NANOSECONDS_PER_SECOND)
+ {
+ ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
+ ts.tv_nsec %= NANOSECONDS_PER_SECOND;
+ }
+ }
+}
+#endif
+
+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);
+
+ if (boost::xtime_cmp(xt, cur) <= 0)
+ milliseconds = 0;
+ else
+ {
+ if (cur.nsec > xt.nsec)
+ {
+ xt.nsec += NANOSECONDS_PER_SECOND;
+ --xt.sec;
+ }
+ milliseconds = (int)((xt.sec - cur.sec) * MILLISECONDS_PER_SECOND) +
+ (((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MILLISECOND/2)) /
+ NANOSECONDS_PER_MILLISECOND);
+ }
+}
+
+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);
+
+ if (boost::xtime_cmp(xt, cur) <= 0)
+ microseconds = 0;
+ else
+ {
+ if (cur.nsec > xt.nsec)
+ {
+ xt.nsec += NANOSECONDS_PER_SECOND;
+ --xt.sec;
+ }
+ microseconds = (int)((xt.sec - cur.sec) * MICROSECONDS_PER_SECOND) +
+ (((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MICROSECOND/2)) /
+ NANOSECONDS_PER_MICROSECOND);
+ }
+}
+}
+
+// Change Log:
+// 1 Jun 01 Initial creation.
diff --git a/3rdParty/Boost/libs/thread/src/tss_null.cpp b/3rdParty/Boost/libs/thread/src/tss_null.cpp
new file mode 100644
index 0000000..ff13b30
--- /dev/null
+++ b/3rdParty/Boost/libs/thread/src/tss_null.cpp
@@ -0,0 +1,34 @@
+// (C) Copyright Michael Glassford 2004.
+// (C) Copyright 2007 Anthony Williams
+// 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>
+
+#if defined(BOOST_HAS_WINTHREADS) && (defined(BOOST_THREAD_BUILD_LIB) || defined(BOOST_THREAD_TEST) || defined(UNDER_CE)) && (!defined(_MSC_VER) || defined(UNDER_CE))
+
+ /*
+ This file is a "null" implementation of tss cleanup; it's
+ purpose is to to eliminate link errors in cases
+ where it is known that tss cleanup is not needed.
+ */
+
+ extern "C" void tss_cleanup_implemented(void)
+ {
+ /*
+ This function's sole purpose is to cause a link error in cases where
+ automatic tss cleanup is not implemented by Boost.Threads as a
+ reminder that user code is responsible for calling the necessary
+ functions at the appropriate times (and for implementing an a
+ tss_cleanup_implemented() function to eliminate the linker's
+ missing symbol error).
+
+ If Boost.Threads later implements automatic tss cleanup in cases
+ where it currently doesn't (which is the plan), the duplicate
+ symbol error will warn the user that their custom solution is no
+ longer needed and can be removed.
+ */
+ }
+
+#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) && !defined(_MSC_VER)
diff --git a/3rdParty/Boost/libs/thread/src/win32/exceptions.cpp b/3rdParty/Boost/libs/thread/src/win32/exceptions.cpp
new file mode 100644
index 0000000..8881303
--- /dev/null
+++ b/3rdParty/Boost/libs/thread/src/win32/exceptions.cpp
@@ -0,0 +1,124 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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/thread/detail/config.hpp>
+
+#include <boost/thread/exceptions.hpp>
+#include <cstring>
+#include <string>
+
+namespace boost {
+
+thread_exception::thread_exception()
+ : m_sys_err(0)
+{
+}
+
+thread_exception::thread_exception(int sys_err_code)
+ : m_sys_err(sys_err_code)
+{
+}
+
+thread_exception::~thread_exception() throw()
+{
+}
+
+int thread_exception::native_error() const
+{
+ return m_sys_err;
+}
+
+lock_error::lock_error()
+{
+}
+
+lock_error::lock_error(int sys_err_code)
+ : thread_exception(sys_err_code)
+{
+}
+
+lock_error::~lock_error() throw()
+{
+}
+
+const char* lock_error::what() const throw()
+{
+ return "boost::lock_error";
+}
+
+thread_resource_error::thread_resource_error()
+{
+}
+
+thread_resource_error::thread_resource_error(int sys_err_code)
+ : thread_exception(sys_err_code)
+{
+}
+
+thread_resource_error::~thread_resource_error() throw()
+{
+}
+
+const char* thread_resource_error::what() const throw()
+{
+ return "boost::thread_resource_error";
+}
+
+unsupported_thread_option::unsupported_thread_option()
+{
+}
+
+unsupported_thread_option::unsupported_thread_option(int sys_err_code)
+ : thread_exception(sys_err_code)
+{
+}
+
+unsupported_thread_option::~unsupported_thread_option() throw()
+{
+}
+
+const char* unsupported_thread_option::what() const throw()
+{
+ return "boost::unsupported_thread_option";
+}
+
+invalid_thread_argument::invalid_thread_argument()
+{
+}
+
+invalid_thread_argument::invalid_thread_argument(int sys_err_code)
+ : thread_exception(sys_err_code)
+{
+}
+
+invalid_thread_argument::~invalid_thread_argument() throw()
+{
+}
+
+const char* invalid_thread_argument::what() const throw()
+{
+ return "boost::invalid_thread_argument";
+}
+
+thread_permission_error::thread_permission_error()
+{
+}
+
+thread_permission_error::thread_permission_error(int sys_err_code)
+ : thread_exception(sys_err_code)
+{
+}
+
+thread_permission_error::~thread_permission_error() throw()
+{
+}
+
+const char* thread_permission_error::what() const throw()
+{
+ return "boost::thread_permission_error";
+}
+
+} // namespace boost
diff --git a/3rdParty/Boost/libs/thread/src/win32/thread.cpp b/3rdParty/Boost/libs/thread/src/win32/thread.cpp
new file mode 100644
index 0000000..a72f053
--- /dev/null
+++ b/3rdParty/Boost/libs/thread/src/win32/thread.cpp
@@ -0,0 +1,597 @@
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007 David Deakins
+
+#define _WIN32_WINNT 0x400
+#define WINVER 0x400
+
+#include <boost/thread/thread.hpp>
+#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/thread/detail/tss_hooks.hpp>
+#include <boost/date_time/posix_time/conversion.hpp>
+
+namespace boost
+{
+ namespace
+ {
+ boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT;
+ DWORD current_thread_tls_key=0;
+
+ void create_current_thread_tls_key()
+ {
+ tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in
+ current_thread_tls_key=TlsAlloc();
+ BOOST_ASSERT(current_thread_tls_key!=TLS_OUT_OF_INDEXES);
+ }
+
+ void cleanup_tls_key()
+ {
+ if(current_thread_tls_key)
+ {
+ TlsFree(current_thread_tls_key);
+ current_thread_tls_key=0;
+ }
+ }
+
+ 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);
+ BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data));
+ }
+
+#ifdef BOOST_NO_THREADEX
+// Windows CE doesn't define _beginthreadex
+
+ struct ThreadProxyData
+ {
+ typedef unsigned (__stdcall* func)(void*);
+ func start_address_;
+ void* arglist_;
+ ThreadProxyData(func start_address,void* arglist) : start_address_(start_address), arglist_(arglist) {}
+ };
+
+ DWORD WINAPI ThreadProxy(LPVOID args)
+ {
+ ThreadProxyData* data=reinterpret_cast<ThreadProxyData*>(args);
+ DWORD ret=data->start_address_(data->arglist_);
+ delete data;
+ return ret;
+ }
+
+ typedef void* uintptr_t;
+
+ inline uintptr_t const _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*),
+ void* arglist, unsigned initflag, unsigned* thrdaddr)
+ {
+ DWORD threadID;
+ HANDLE hthread=CreateThread(static_cast<LPSECURITY_ATTRIBUTES>(security),stack_size,ThreadProxy,
+ new ThreadProxyData(start_address,arglist),initflag,&threadID);
+ if (hthread!=0)
+ *thrdaddr=threadID;
+ return reinterpret_cast<uintptr_t const>(hthread);
+ }
+
+#endif
+
+ }
+
+ namespace detail
+ {
+ struct thread_exit_callback_node
+ {
+ boost::detail::thread_exit_function_base* func;
+ thread_exit_callback_node* next;
+
+ thread_exit_callback_node(boost::detail::thread_exit_function_base* func_,
+ thread_exit_callback_node* next_):
+ func(func_),next(next_)
+ {}
+ };
+
+ 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_)
+ {}
+ };
+
+ }
+
+ namespace
+ {
+ void run_thread_exit_callbacks()
+ {
+ detail::thread_data_ptr current_thread_data(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->thread_exit_callbacks)
+ {
+ detail::thread_exit_callback_node* const current_node=current_thread_data->thread_exit_callbacks;
+ current_thread_data->thread_exit_callbacks=current_node->next;
+ if(current_node->func)
+ {
+ (*current_node->func)();
+ boost::detail::heap_delete(current_node->func);
+ }
+ boost::detail::heap_delete(current_node);
+ }
+ while(current_thread_data->tss_data)
+ {
+ 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_node->func)(current_node->value);
+ }
+ boost::detail::heap_delete(current_node);
+ }
+ }
+
+ set_current_thread_data(0);
+ }
+ }
+
+ unsigned __stdcall thread_start_function(void* param)
+ {
+ detail::thread_data_base* const thread_info(reinterpret_cast<detail::thread_data_base*>(param));
+ set_current_thread_data(thread_info);
+ try
+ {
+ thread_info->run();
+ }
+ 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(...)
+// {
+// std::terminate();
+// }
+ run_thread_exit_callbacks();
+ return 0;
+ }
+ }
+
+ thread::thread()
+ {}
+
+ void thread::start_thread()
+ {
+ uintptr_t const new_thread=_beginthreadex(0,0,&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
+ if(!new_thread)
+ {
+ throw thread_resource_error();
+ }
+ intrusive_ptr_add_ref(thread_info.get());
+ thread_info->thread_handle=(detail::win32::handle)(new_thread);
+ ResumeThread(thread_info->thread_handle);
+ }
+
+ thread::thread(detail::thread_data_ptr data):
+ thread_info(data)
+ {}
+
+ namespace
+ {
+ struct externally_launched_thread:
+ detail::thread_data_base
+ {
+ externally_launched_thread()
+ {
+ ++count;
+ interruption_enabled=false;
+ }
+
+ void run()
+ {}
+ private:
+ externally_launched_thread(externally_launched_thread&);
+ void operator=(externally_launched_thread&);
+ };
+
+ void make_external_thread_data()
+ {
+ externally_launched_thread* me=detail::heap_new<externally_launched_thread>();
+ set_current_thread_data(me);
+ }
+
+ detail::thread_data_base* get_or_make_current_thread_data()
+ {
+ detail::thread_data_base* current_thread_data(get_current_thread_data());
+ if(!current_thread_data)
+ {
+ make_external_thread_data();
+ current_thread_data=get_current_thread_data();
+ }
+ return current_thread_data;
+ }
+
+ }
+
+ thread::~thread()
+ {
+ detach();
+ }
+
+ thread::id thread::get_id() const
+ {
+ return thread::id(get_thread_info());
+ }
+
+ bool thread::joinable() const
+ {
+ return get_thread_info();
+ }
+
+ void thread::join()
+ {
+ detail::thread_data_ptr local_thread_info=get_thread_info();
+ if(local_thread_info)
+ {
+ this_thread::interruptible_wait(local_thread_info->thread_handle,detail::timeout::sentinel());
+ release_handle();
+ }
+ }
+
+ bool thread::timed_join(boost::system_time const& wait_until)
+ {
+ 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)))
+ {
+ return false;
+ }
+ release_handle();
+ }
+ return true;
+ }
+
+ void thread::detach()
+ {
+ release_handle();
+ }
+
+ void thread::release_handle()
+ {
+ lock_guard<mutex> l1(thread_info_mutex);
+ thread_info=0;
+ }
+
+ void thread::interrupt()
+ {
+ detail::thread_data_ptr local_thread_info=get_thread_info();
+ if(local_thread_info)
+ {
+ local_thread_info->interrupt();
+ }
+ }
+
+ bool thread::interruption_requested() const
+ {
+ detail::thread_data_ptr local_thread_info=get_thread_info();
+ return local_thread_info.get() && (detail::win32::WaitForSingleObject(local_thread_info->interruption_handle,0)==0);
+ }
+
+ unsigned thread::hardware_concurrency()
+ {
+ SYSTEM_INFO info={0};
+ GetSystemInfo(&info);
+ return info.dwNumberOfProcessors;
+ }
+
+ thread::native_handle_type thread::native_handle()
+ {
+ detail::thread_data_ptr local_thread_info=get_thread_info();
+ return local_thread_info?(detail::win32::handle)local_thread_info->thread_handle:detail::win32::invalid_handle_value;
+ }
+
+ detail::thread_data_ptr thread::get_thread_info() const
+ {
+ boost::mutex::scoped_lock l(thread_info_mutex);
+ return thread_info;
+ }
+
+ namespace this_thread
+ {
+ namespace
+ {
+ LARGE_INTEGER get_due_time(detail::timeout const& target_time)
+ {
+ LARGE_INTEGER due_time={0};
+ if(target_time.relative)
+ {
+ unsigned long const elapsed_milliseconds=GetTickCount()-target_time.start;
+ LONGLONG const remaining_milliseconds=(target_time.milliseconds-elapsed_milliseconds);
+ LONGLONG const hundred_nanoseconds_in_one_millisecond=10000;
+
+ if(remaining_milliseconds>0)
+ {
+ due_time.QuadPart=-(remaining_milliseconds*hundred_nanoseconds_in_one_millisecond);
+ }
+ }
+ else
+ {
+ SYSTEMTIME target_system_time={0};
+ target_system_time.wYear=target_time.abs_time.date().year();
+ target_system_time.wMonth=target_time.abs_time.date().month();
+ target_system_time.wDay=target_time.abs_time.date().day();
+ target_system_time.wHour=(WORD)target_time.abs_time.time_of_day().hours();
+ target_system_time.wMinute=(WORD)target_time.abs_time.time_of_day().minutes();
+ target_system_time.wSecond=(WORD)target_time.abs_time.time_of_day().seconds();
+
+ if(!SystemTimeToFileTime(&target_system_time,((FILETIME*)&due_time)))
+ {
+ due_time.QuadPart=0;
+ }
+ else
+ {
+ long const hundred_nanoseconds_in_one_second=10000000;
+ due_time.QuadPart+=target_time.abs_time.time_of_day().fractional_seconds()*(hundred_nanoseconds_in_one_second/target_time.abs_time.time_of_day().ticks_per_second());
+ }
+ }
+ return due_time;
+ }
+ }
+
+
+ bool 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 interruption_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;
+ }
+ if(get_current_thread_data() && get_current_thread_data()->interruption_enabled)
+ {
+ interruption_index=handle_count;
+ handles[handle_count++]=get_current_thread_data()->interruption_handle;
+ }
+
+ 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==interruption_index)
+ {
+ detail::win32::ResetEvent(get_current_thread_data()->interruption_handle);
+ throw thread_interrupted();
+ }
+ 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()
+ {
+ return thread::id(get_or_make_current_thread_data());
+ }
+
+ void interruption_point()
+ {
+ if(interruption_enabled() && interruption_requested())
+ {
+ detail::win32::ResetEvent(get_current_thread_data()->interruption_handle);
+ throw thread_interrupted();
+ }
+ }
+
+ bool interruption_enabled()
+ {
+ return get_current_thread_data() && get_current_thread_data()->interruption_enabled;
+ }
+
+ bool interruption_requested()
+ {
+ return get_current_thread_data() && (detail::win32::WaitForSingleObject(get_current_thread_data()->interruption_handle,0)==0);
+ }
+
+ void yield()
+ {
+ detail::win32::Sleep(0);
+ }
+
+ disable_interruption::disable_interruption():
+ interruption_was_enabled(interruption_enabled())
+ {
+ if(interruption_was_enabled)
+ {
+ get_current_thread_data()->interruption_enabled=false;
+ }
+ }
+
+ disable_interruption::~disable_interruption()
+ {
+ if(get_current_thread_data())
+ {
+ get_current_thread_data()->interruption_enabled=interruption_was_enabled;
+ }
+ }
+
+ restore_interruption::restore_interruption(disable_interruption& d)
+ {
+ if(d.interruption_was_enabled)
+ {
+ get_current_thread_data()->interruption_enabled=true;
+ }
+ }
+
+ restore_interruption::~restore_interruption()
+ {
+ if(get_current_thread_data())
+ {
+ get_current_thread_data()->interruption_enabled=false;
+ }
+ }
+ }
+
+ namespace detail
+ {
+ void add_thread_exit_function(thread_exit_function_base* func)
+ {
+ detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
+ thread_exit_callback_node* const new_node=
+ heap_new<thread_exit_callback_node>(func,
+ current_thread_data->thread_exit_callbacks);
+ current_thread_data->thread_exit_callbacks=new_node;
+ }
+
+ tss_data_node* find_tss_data(void const* key)
+ {
+ detail::thread_data_base* const current_thread_data(get_current_thread_data());
+ if(current_thread_data)
+ {
+ detail::tss_data_node* current_node=current_thread_data->tss_data;
+ while(current_node)
+ {
+ if(current_node->key==key)
+ {
+ return current_node;
+ }
+ current_node=current_node->next;
+ }
+ }
+ return NULL;
+ }
+
+ void* get_tss_data(void const* key)
+ {
+ if(tss_data_node* const current_node=find_tss_data(key))
+ {
+ return current_node->value;
+ }
+ return NULL;
+ }
+
+ 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->func)(current_node->value);
+ }
+ current_node->func=func;
+ current_node->value=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;
+ }
+ }
+ }
+}
+
+
+extern "C" BOOST_THREAD_DECL void on_process_enter()
+{}
+
+extern "C" BOOST_THREAD_DECL void on_thread_enter()
+{}
+
+extern "C" BOOST_THREAD_DECL void on_process_exit()
+{
+ boost::cleanup_tls_key();
+}
+
+extern "C" BOOST_THREAD_DECL void on_thread_exit()
+{
+ boost::run_thread_exit_callbacks();
+}
+
diff --git a/3rdParty/Boost/libs/thread/src/win32/timeconv.inl b/3rdParty/Boost/libs/thread/src/win32/timeconv.inl
new file mode 100644
index 0000000..5ec3b17
--- /dev/null
+++ b/3rdParty/Boost/libs/thread/src/win32/timeconv.inl
@@ -0,0 +1,130 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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)
+
+// boostinspect:nounnamed
+
+namespace {
+const int MILLISECONDS_PER_SECOND = 1000;
+const int NANOSECONDS_PER_SECOND = 1000000000;
+const int NANOSECONDS_PER_MILLISECOND = 1000000;
+
+const int MICROSECONDS_PER_SECOND = 1000000;
+const int NANOSECONDS_PER_MICROSECOND = 1000;
+
+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);
+
+ xt.sec += (milliseconds / MILLISECONDS_PER_SECOND);
+ xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
+ NANOSECONDS_PER_MILLISECOND);
+
+ if (xt.nsec >= NANOSECONDS_PER_SECOND)
+ {
+ ++xt.sec;
+ xt.nsec -= NANOSECONDS_PER_SECOND;
+ }
+}
+
+#if defined(BOOST_HAS_PTHREADS)
+inline void to_timespec(const boost::xtime& xt, timespec& ts)
+{
+ ts.tv_sec = static_cast<int>(xt.sec);
+ ts.tv_nsec = static_cast<int>(xt.nsec);
+ if(ts.tv_nsec >= NANOSECONDS_PER_SECOND)
+ {
+ ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
+ ts.tv_nsec %= NANOSECONDS_PER_SECOND;
+ }
+}
+
+inline void to_time(int milliseconds, timespec& ts)
+{
+ boost::xtime xt;
+ to_time(milliseconds, xt);
+ to_timespec(xt, ts);
+}
+
+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);
+
+ if (boost::xtime_cmp(xt, cur) <= 0)
+ {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ }
+ else
+ {
+ ts.tv_sec = xt.sec - cur.sec;
+ ts.tv_nsec = xt.nsec - cur.nsec;
+
+ if( ts.tv_nsec < 0 )
+ {
+ ts.tv_sec -= 1;
+ ts.tv_nsec += NANOSECONDS_PER_SECOND;
+ }
+ if(ts.tv_nsec >= NANOSECONDS_PER_SECOND)
+ {
+ ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
+ ts.tv_nsec %= NANOSECONDS_PER_SECOND;
+ }
+ }
+}
+#endif
+
+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);
+
+ if (boost::xtime_cmp(xt, cur) <= 0)
+ milliseconds = 0;
+ else
+ {
+ if (cur.nsec > xt.nsec)
+ {
+ xt.nsec += NANOSECONDS_PER_SECOND;
+ --xt.sec;
+ }
+ milliseconds = (int)((xt.sec - cur.sec) * MILLISECONDS_PER_SECOND) +
+ (((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MILLISECOND/2)) /
+ NANOSECONDS_PER_MILLISECOND);
+ }
+}
+
+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);
+
+ if (boost::xtime_cmp(xt, cur) <= 0)
+ microseconds = 0;
+ else
+ {
+ if (cur.nsec > xt.nsec)
+ {
+ xt.nsec += NANOSECONDS_PER_SECOND;
+ --xt.sec;
+ }
+ microseconds = (int)((xt.sec - cur.sec) * MICROSECONDS_PER_SECOND) +
+ (((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MICROSECOND/2)) /
+ NANOSECONDS_PER_MICROSECOND);
+ }
+}
+}
+
+// Change Log:
+// 1 Jun 01 Initial creation.
diff --git a/3rdParty/Boost/libs/thread/src/win32/tss_dll.cpp b/3rdParty/Boost/libs/thread/src/win32/tss_dll.cpp
new file mode 100644
index 0000000..0522a12
--- /dev/null
+++ b/3rdParty/Boost/libs/thread/src/win32/tss_dll.cpp
@@ -0,0 +1,72 @@
+// (C) Copyright Michael Glassford 2004.
+// 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>
+
+#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)
+
+ #include <boost/thread/detail/tss_hooks.hpp>
+
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+
+ #if defined(__BORLANDC__)
+ extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/)
+ #elif defined(_WIN32_WCE)
+ extern "C" BOOL WINAPI DllMain(HANDLE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/)
+ #else
+ extern "C" BOOL WINAPI DllMain(HINSTANCE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/)
+ #endif
+ {
+ switch(dwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ on_process_enter();
+ on_thread_enter();
+ break;
+ }
+
+ case DLL_THREAD_ATTACH:
+ {
+ on_thread_enter();
+ break;
+ }
+
+ case DLL_THREAD_DETACH:
+ {
+ on_thread_exit();
+ break;
+ }
+
+ case DLL_PROCESS_DETACH:
+ {
+ on_thread_exit();
+ on_process_exit();
+ break;
+ }
+ }
+
+ return TRUE;
+ }
+
+ extern "C" void tss_cleanup_implemented(void)
+ {
+ /*
+ This function's sole purpose is to cause a link error in cases where
+ automatic tss cleanup is not implemented by Boost.Threads as a
+ reminder that user code is responsible for calling the necessary
+ functions at the appropriate times (and for implementing an a
+ tss_cleanup_implemented() function to eliminate the linker's
+ missing symbol error).
+
+ If Boost.Threads later implements automatic tss cleanup in cases
+ where it currently doesn't (which is the plan), the duplicate
+ symbol error will warn the user that their custom solution is no
+ longer needed and can be removed.
+ */
+ }
+
+#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)
diff --git a/3rdParty/Boost/libs/thread/src/win32/tss_pe.cpp b/3rdParty/Boost/libs/thread/src/win32/tss_pe.cpp
new file mode 100644
index 0000000..ae89bc4
--- /dev/null
+++ b/3rdParty/Boost/libs/thread/src/win32/tss_pe.cpp
@@ -0,0 +1,287 @@
+// $Id: tss_pe.cpp 49324 2008-10-13 20:30:13Z anthonyw $
+// (C) Copyright Aaron W. LaFramboise, Roland Schwarz, Michael Glassford 2004.
+// (C) Copyright 2007 Roland Schwarz
+// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007 David Deakins
+// 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>
+
+#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)
+
+#if defined(__MINGW32__) && !defined(_WIN64)
+
+#include <boost/thread/detail/tss_hooks.hpp>
+
+#include <windows.h>
+
+#include <cstdlib>
+
+extern "C" void tss_cleanup_implemented(void) {}
+
+namespace {
+ void NTAPI on_tls_callback(void* h, DWORD dwReason, PVOID pv)
+ {
+ switch (dwReason)
+ {
+ case DLL_THREAD_DETACH:
+ {
+ on_thread_exit();
+ break;
+ }
+ }
+ }
+
+ void on_after_ctors(void)
+ {
+ on_process_enter();
+ }
+
+ void on_before_dtors(void)
+ {
+ on_thread_exit();
+ }
+
+ void on_after_dtors(void)
+ {
+ on_process_exit();
+ }
+}
+
+extern "C" {
+
+ void (* after_ctors )(void) __attribute__((section(".ctors"))) = on_after_ctors;
+ void (* before_dtors)(void) __attribute__((section(".dtors"))) = on_before_dtors;
+ void (* after_dtors )(void) __attribute__((section(".dtors.zzz"))) = on_after_dtors;
+
+ ULONG __tls_index__ = 0;
+ char __tls_end__ __attribute__((section(".tls$zzz"))) = 0;
+ char __tls_start__ __attribute__((section(".tls"))) = 0;
+
+
+ PIMAGE_TLS_CALLBACK __crt_xl_start__ __attribute__ ((section(".CRT$XLA"))) = 0;
+ PIMAGE_TLS_CALLBACK __crt_xl_tls_callback__ __attribute__ ((section(".CRT$XLB"))) = on_tls_callback;
+ PIMAGE_TLS_CALLBACK __crt_xl_end__ __attribute__ ((section(".CRT$XLZ"))) = 0;
+}
+
+extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata$T"))) =
+{
+ (DWORD) &__tls_start__,
+ (DWORD) &__tls_end__,
+ (DWORD) &__tls_index__,
+ (DWORD) (&__crt_xl_start__+1),
+ (DWORD) 0,
+ (DWORD) 0
+};
+
+
+#elif defined(_MSC_VER) && !defined(UNDER_CE)
+
+ #include <boost/thread/detail/tss_hooks.hpp>
+
+ #include <stdlib.h>
+
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+
+ //Definitions required by implementation
+
+ #if (_MSC_VER < 1300) // 1300 == VC++ 7.0
+ typedef void (__cdecl *_PVFV)(void);
+ #define INIRETSUCCESS
+ #define PVAPI void
+ #else
+ typedef int (__cdecl *_PVFV)(void);
+ #define INIRETSUCCESS 0
+ #define PVAPI int
+ #endif
+
+ typedef void (NTAPI* _TLSCB)(HINSTANCE, DWORD, PVOID);
+
+ //Symbols for connection to the runtime environment
+
+ extern "C"
+ {
+ extern DWORD _tls_used; //the tls directory (located in .rdata segment)
+ extern _TLSCB __xl_a[], __xl_z[]; //tls initializers */
+ }
+
+ namespace
+ {
+ //Forward declarations
+
+ static PVAPI on_tls_prepare(void);
+ static PVAPI on_process_init(void);
+ static PVAPI on_process_term(void);
+ static void NTAPI on_tls_callback(HINSTANCE, DWORD, PVOID);
+
+ //The .CRT$Xxx information is taken from Codeguru:
+ //http://www.codeguru.com/Cpp/misc/misc/threadsprocesses/article.php/c6945__2/
+
+#if (_MSC_VER >= 1400)
+#pragma section(".CRT$XIU",long,read)
+#pragma section(".CRT$XCU",long,read)
+#pragma section(".CRT$XTU",long,read)
+#pragma section(".CRT$XLC",long,read)
+ __declspec(allocate(".CRT$XLC")) _TLSCB __xl_ca=on_tls_callback;
+ __declspec(allocate(".CRT$XIU"))_PVFV p_tls_prepare = on_tls_prepare;
+ __declspec(allocate(".CRT$XCU"))_PVFV p_process_init = on_process_init;
+ __declspec(allocate(".CRT$XTU"))_PVFV p_process_term = on_process_term;
+#else
+ #if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
+ # pragma data_seg(push, old_seg)
+ #endif
+ //Callback to run tls glue code first.
+ //I don't think it is necessary to run it
+ //at .CRT$XIB level, since we are only
+ //interested in thread detachement. But
+ //this could be changed easily if required.
+
+ #pragma data_seg(".CRT$XIU")
+ static _PVFV p_tls_prepare = on_tls_prepare;
+ #pragma data_seg()
+
+ //Callback after all global ctors.
+
+ #pragma data_seg(".CRT$XCU")
+ static _PVFV p_process_init = on_process_init;
+ #pragma data_seg()
+
+ //Callback for tls notifications.
+
+ #pragma data_seg(".CRT$XLB")
+ _TLSCB p_thread_callback = on_tls_callback;
+ #pragma data_seg()
+ //Callback for termination.
+
+ #pragma data_seg(".CRT$XTU")
+ static _PVFV p_process_term = on_process_term;
+ #pragma data_seg()
+ #if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
+ # pragma data_seg(pop, old_seg)
+ #endif
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4189)
+#endif
+
+ PVAPI on_tls_prepare(void)
+ {
+ //The following line has an important side effect:
+ //if the TLS directory is not already there, it will
+ //be created by the linker. In other words, it forces a tls
+ //directory to be generated by the linker even when static tls
+ //(i.e. __declspec(thread)) is not used.
+ //The volatile should prevent the optimizer
+ //from removing the reference.
+
+ DWORD volatile dw = _tls_used;
+
+ #if (_MSC_VER < 1300) // 1300 == VC++ 7.0
+ _TLSCB* pfbegin = __xl_a;
+ _TLSCB* pfend = __xl_z;
+ _TLSCB* pfdst = pfbegin;
+ //pfdst = (_TLSCB*)_tls_used.AddressOfCallBacks;
+
+ //The following loop will merge the address pointers
+ //into a contiguous area, since the tlssup code seems
+ //to require this (at least on MSVC 6)
+
+ while (pfbegin < pfend)
+ {
+ if (*pfbegin != 0)
+ {
+ *pfdst = *pfbegin;
+ ++pfdst;
+ }
+ ++pfbegin;
+ }
+
+ *pfdst = 0;
+ #endif
+
+ return INIRETSUCCESS;
+ }
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+ PVAPI on_process_init(void)
+ {
+ //Schedule on_thread_exit() to be called for the main
+ //thread before destructors of global objects have been
+ //called.
+
+ //It will not be run when 'quick' exiting the
+ //library; however, this is the standard behaviour
+ //for destructors of global objects, so that
+ //shouldn't be a problem.
+
+ atexit(on_thread_exit);
+
+ //Call Boost process entry callback here
+
+ on_process_enter();
+
+ return INIRETSUCCESS;
+ }
+
+ PVAPI on_process_term(void)
+ {
+ on_process_exit();
+ return INIRETSUCCESS;
+ }
+
+ void NTAPI on_tls_callback(HINSTANCE /*h*/, DWORD dwReason, PVOID /*pv*/)
+ {
+ switch (dwReason)
+ {
+ case DLL_THREAD_DETACH:
+ on_thread_exit();
+ break;
+ }
+ }
+
+ BOOL WINAPI dll_callback(HANDLE, DWORD dwReason, LPVOID)
+ {
+ switch (dwReason)
+ {
+ case DLL_THREAD_DETACH:
+ on_thread_exit();
+ break;
+ case DLL_PROCESS_DETACH:
+ on_process_exit();
+ break;
+ }
+ return true;
+ }
+ } //namespace
+
+extern "C"
+{
+ extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID)=&dll_callback;
+}
+
+ extern "C" void tss_cleanup_implemented(void)
+ {
+ /*
+ This function's sole purpose is to cause a link error in cases where
+ automatic tss cleanup is not implemented by Boost.Threads as a
+ reminder that user code is responsible for calling the necessary
+ functions at the appropriate times (and for implementing an a
+ tss_cleanup_implemented() function to eliminate the linker's
+ missing symbol error).
+
+ If Boost.Threads later implements automatic tss cleanup in cases
+ where it currently doesn't (which is the plan), the duplicate
+ symbol error will warn the user that their custom solution is no
+ longer needed and can be removed.
+ */
+ }
+#endif //defined(_MSC_VER) && !defined(UNDER_CE)
+
+#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)