summaryrefslogtreecommitdiffstats
path: root/ext
diff options
context:
space:
mode:
authorJINMEI Tatuya <jinmei@isc.org>2010-03-08 20:21:25 +0100
committerJINMEI Tatuya <jinmei@isc.org>2010-03-08 20:21:25 +0100
commit64593f39e0058ee7db459341db9f5050729eec2d (patch)
tree56f3d41d866bab1fb41fb7b2c4db5d2ee187501d /ext
parentsync with trunk (diff)
downloadkea-64593f39e0058ee7db459341db9f5050729eec2d.tar.xz
kea-64593f39e0058ee7db459341db9f5050729eec2d.zip
added more dependency for asio
git-svn-id: svn://bind10.isc.org/svn/bind10/branches/jinmei-asio@1212 e5f2f494-b856-4b98-b285-d166d9295462
Diffstat (limited to 'ext')
-rw-r--r--ext/boost/date_time/adjust_functors.hpp178
-rw-r--r--ext/boost/date_time/c_local_time_adjustor.hpp66
-rw-r--r--ext/boost/date_time/c_time.hpp105
-rw-r--r--ext/boost/date_time/compiler_config.hpp171
-rw-r--r--ext/boost/date_time/constrained_value.hpp121
-rw-r--r--ext/boost/date_time/date.hpp197
-rw-r--r--ext/boost/date_time/date_clock_device.hpp77
-rw-r--r--ext/boost/date_time/date_defs.hpp26
-rw-r--r--ext/boost/date_time/date_duration.hpp146
-rw-r--r--ext/boost/date_time/date_duration_types.hpp269
-rw-r--r--ext/boost/date_time/date_facet.hpp764
-rw-r--r--ext/boost/date_time/date_format_simple.hpp159
-rw-r--r--ext/boost/date_time/date_formatting.hpp127
-rw-r--r--ext/boost/date_time/date_formatting_limited.hpp121
-rw-r--r--ext/boost/date_time/date_formatting_locales.hpp233
-rw-r--r--ext/boost/date_time/date_generator_formatter.hpp265
-rw-r--r--ext/boost/date_time/date_generator_parser.hpp330
-rw-r--r--ext/boost/date_time/date_generators.hpp509
-rw-r--r--ext/boost/date_time/date_iterator.hpp101
-rw-r--r--ext/boost/date_time/date_names_put.hpp320
-rw-r--r--ext/boost/date_time/date_parsing.hpp316
-rw-r--r--ext/boost/date_time/dst_rules.hpp391
-rw-r--r--ext/boost/date_time/dst_transition_generators.hpp75
-rw-r--r--ext/boost/date_time/filetime_functions.hpp170
-rw-r--r--ext/boost/date_time/format_date_parser.hpp743
-rw-r--r--ext/boost/date_time/gregorian/conversion.hpp66
-rw-r--r--ext/boost/date_time/gregorian/formatters.hpp162
-rw-r--r--ext/boost/date_time/gregorian/formatters_limited.hpp81
-rw-r--r--ext/boost/date_time/gregorian/greg_calendar.hpp47
-rw-r--r--ext/boost/date_time/gregorian/greg_date.hpp136
-rw-r--r--ext/boost/date_time/gregorian/greg_day.hpp57
-rw-r--r--ext/boost/date_time/gregorian/greg_day_of_year.hpp38
-rw-r--r--ext/boost/date_time/gregorian/greg_duration.hpp134
-rw-r--r--ext/boost/date_time/gregorian/greg_duration_types.hpp43
-rw-r--r--ext/boost/date_time/gregorian/greg_facet.hpp354
-rw-r--r--ext/boost/date_time/gregorian/greg_month.hpp105
-rw-r--r--ext/boost/date_time/gregorian/greg_serialize.hpp489
-rw-r--r--ext/boost/date_time/gregorian/greg_weekday.hpp66
-rw-r--r--ext/boost/date_time/gregorian/greg_year.hpp53
-rw-r--r--ext/boost/date_time/gregorian/greg_ymd.hpp33
-rw-r--r--ext/boost/date_time/gregorian/gregorian.hpp38
-rw-r--r--ext/boost/date_time/gregorian/gregorian_io.hpp784
-rw-r--r--ext/boost/date_time/gregorian/gregorian_types.hpp109
-rw-r--r--ext/boost/date_time/gregorian/parsers.hpp91
-rw-r--r--ext/boost/date_time/gregorian_calendar.hpp70
-rw-r--r--ext/boost/date_time/gregorian_calendar.ipp219
-rw-r--r--ext/boost/date_time/int_adapter.hpp509
-rw-r--r--ext/boost/date_time/iso_format.hpp303
-rw-r--r--ext/boost/date_time/local_time/conversion.hpp34
-rw-r--r--ext/boost/date_time/local_time/custom_time_zone.hpp169
-rw-r--r--ext/boost/date_time/local_time/date_duration_operators.hpp115
-rw-r--r--ext/boost/date_time/local_time/dst_transition_day_rules.hpp77
-rw-r--r--ext/boost/date_time/local_time/local_date_time.hpp527
-rw-r--r--ext/boost/date_time/local_time/local_time.hpp24
-rw-r--r--ext/boost/date_time/local_time/local_time_io.hpp186
-rw-r--r--ext/boost/date_time/local_time/local_time_types.hpp52
-rw-r--r--ext/boost/date_time/local_time/posix_time_zone.hpp464
-rw-r--r--ext/boost/date_time/local_time/tz_database.hpp32
-rw-r--r--ext/boost/date_time/local_time_adjustor.hpp218
-rw-r--r--ext/boost/date_time/local_timezone_defs.hpp193
-rw-r--r--ext/boost/date_time/locale_config.hpp31
-rw-r--r--ext/boost/date_time/microsec_time_clock.hpp127
-rw-r--r--ext/boost/date_time/parse_format_base.hpp29
-rw-r--r--ext/boost/date_time/period.hpp377
-rw-r--r--ext/boost/date_time/period_formatter.hpp196
-rw-r--r--ext/boost/date_time/period_parser.hpp198
-rw-r--r--ext/boost/date_time/posix_time/conversion.hpp91
-rw-r--r--ext/boost/date_time/posix_time/date_duration_operators.hpp114
-rw-r--r--ext/boost/date_time/posix_time/posix_time.hpp39
-rw-r--r--ext/boost/date_time/posix_time/posix_time_config.hpp178
-rw-r--r--ext/boost/date_time/posix_time/posix_time_duration.hpp82
-rw-r--r--ext/boost/date_time/posix_time/posix_time_io.hpp239
-rw-r--r--ext/boost/date_time/posix_time/posix_time_legacy_io.hpp153
-rw-r--r--ext/boost/date_time/posix_time/posix_time_system.hpp68
-rw-r--r--ext/boost/date_time/posix_time/posix_time_types.hpp55
-rw-r--r--ext/boost/date_time/posix_time/ptime.hpp65
-rw-r--r--ext/boost/date_time/posix_time/time_formatters.hpp289
-rw-r--r--ext/boost/date_time/posix_time/time_formatters_limited.hpp211
-rw-r--r--ext/boost/date_time/posix_time/time_parsers.hpp44
-rw-r--r--ext/boost/date_time/posix_time/time_period.hpp29
-rw-r--r--ext/boost/date_time/posix_time/time_serialize.hpp200
-rw-r--r--ext/boost/date_time/special_defs.hpp25
-rw-r--r--ext/boost/date_time/special_values_formatter.hpp96
-rw-r--r--ext/boost/date_time/special_values_parser.hpp159
-rw-r--r--ext/boost/date_time/string_convert.hpp33
-rw-r--r--ext/boost/date_time/string_parse_tree.hpp278
-rw-r--r--ext/boost/date_time/strings_from_facet.hpp125
-rw-r--r--ext/boost/date_time/time.hpp191
-rw-r--r--ext/boost/date_time/time_clock.hpp83
-rw-r--r--ext/boost/date_time/time_defs.hpp43
-rw-r--r--ext/boost/date_time/time_duration.hpp282
-rw-r--r--ext/boost/date_time/time_facet.hpp1327
-rw-r--r--ext/boost/date_time/time_formatting_streams.hpp122
-rw-r--r--ext/boost/date_time/time_iterator.hpp52
-rw-r--r--ext/boost/date_time/time_parsing.hpp321
-rw-r--r--ext/boost/date_time/time_resolution_traits.hpp144
-rw-r--r--ext/boost/date_time/time_system_counted.hpp254
-rw-r--r--ext/boost/date_time/time_system_split.hpp207
-rw-r--r--ext/boost/date_time/time_zone_base.hpp99
-rw-r--r--ext/boost/date_time/time_zone_names.hpp98
-rw-r--r--ext/boost/date_time/tz_db_base.hpp378
-rw-r--r--ext/boost/date_time/wrapping_int.hpp169
-rw-r--r--ext/boost/date_time/year_month_day.hpp45
-rw-r--r--ext/boost/functional/detail/container_fwd.hpp19
-rw-r--r--ext/boost/functional/hash.hpp7
-rw-r--r--ext/boost/functional/hash/detail/float_functions.hpp246
-rw-r--r--ext/boost/functional/hash/detail/hash_float.hpp101
-rw-r--r--ext/boost/functional/hash/detail/hash_float_generic.hpp93
-rw-r--r--ext/boost/functional/hash/detail/hash_float_x86.hpp56
-rw-r--r--ext/boost/functional/hash/detail/limits.hpp61
-rw-r--r--ext/boost/functional/hash/extensions.hpp286
-rw-r--r--ext/boost/functional/hash/hash.hpp478
-rw-r--r--ext/boost/functional/hash/hash_fwd.hpp40
-rw-r--r--ext/boost/functional/hash_fwd.hpp7
-rw-r--r--ext/boost/integer/integer_mask.hpp93
-rw-r--r--ext/boost/integer/static_log2.hpp132
-rw-r--r--ext/boost/integer/static_min_max.hpp55
-rw-r--r--ext/boost/optional/optional.hpp922
-rw-r--r--ext/boost/optional/optional_fwd.hpp22
-rw-r--r--ext/boost/optional/optional_io.hpp84
-rw-r--r--ext/boost/regex/concepts.hpp906
-rw-r--r--ext/boost/regex/config.hpp417
-rw-r--r--ext/boost/regex/config/borland.hpp72
-rw-r--r--ext/boost/regex/config/cwchar.hpp207
-rw-r--r--ext/boost/regex/icu.hpp1021
-rw-r--r--ext/boost/regex/mfc.hpp190
-rw-r--r--ext/boost/regex/pattern_except.hpp100
-rw-r--r--ext/boost/regex/pending/object_cache.hpp163
-rw-r--r--ext/boost/regex/pending/static_mutex.hpp184
-rw-r--r--ext/boost/regex/pending/unicode_iterator.hpp692
-rw-r--r--ext/boost/regex/regex_traits.hpp35
-rw-r--r--ext/boost/regex/user.hpp90
-rw-r--r--ext/boost/regex/v4/basic_regex.hpp825
-rw-r--r--ext/boost/regex/v4/basic_regex_creator.hpp1436
-rw-r--r--ext/boost/regex/v4/basic_regex_parser.hpp2571
-rw-r--r--ext/boost/regex/v4/c_regex_traits.hpp211
-rw-r--r--ext/boost/regex/v4/char_regex_traits.hpp81
-rw-r--r--ext/boost/regex/v4/cpp_regex_traits.hpp1086
-rw-r--r--ext/boost/regex/v4/cregex.hpp329
-rw-r--r--ext/boost/regex/v4/error_type.hpp58
-rw-r--r--ext/boost/regex/v4/fileiter.hpp455
-rw-r--r--ext/boost/regex/v4/instances.hpp215
-rw-r--r--ext/boost/regex/v4/iterator_category.hpp91
-rw-r--r--ext/boost/regex/v4/iterator_traits.hpp135
-rw-r--r--ext/boost/regex/v4/match_flags.hpp138
-rw-r--r--ext/boost/regex/v4/match_results.hpp579
-rw-r--r--ext/boost/regex/v4/mem_block_cache.hpp99
-rw-r--r--ext/boost/regex/v4/perl_matcher.hpp580
-rw-r--r--ext/boost/regex/v4/perl_matcher_common.hpp949
-rw-r--r--ext/boost/regex/v4/perl_matcher_non_recursive.hpp1635
-rw-r--r--ext/boost/regex/v4/perl_matcher_recursive.hpp992
-rw-r--r--ext/boost/regex/v4/primary_transform.hpp146
-rw-r--r--ext/boost/regex/v4/protected_call.hpp81
-rw-r--r--ext/boost/regex/v4/regbase.hpp180
-rw-r--r--ext/boost/regex/v4/regex.hpp202
-rw-r--r--ext/boost/regex/v4/regex_format.hpp829
-rw-r--r--ext/boost/regex/v4/regex_fwd.hpp73
-rw-r--r--ext/boost/regex/v4/regex_grep.hpp155
-rw-r--r--ext/boost/regex/v4/regex_iterator.hpp201
-rw-r--r--ext/boost/regex/v4/regex_match.hpp382
-rw-r--r--ext/boost/regex/v4/regex_merge.hpp93
-rw-r--r--ext/boost/regex/v4/regex_raw_buffer.hpp210
-rw-r--r--ext/boost/regex/v4/regex_replace.hpp122
-rw-r--r--ext/boost/regex/v4/regex_search.hpp217
-rw-r--r--ext/boost/regex/v4/regex_split.hpp172
-rw-r--r--ext/boost/regex/v4/regex_token_iterator.hpp342
-rw-r--r--ext/boost/regex/v4/regex_traits.hpp189
-rw-r--r--ext/boost/regex/v4/regex_traits_defaults.hpp371
-rw-r--r--ext/boost/regex/v4/regex_workaround.hpp202
-rw-r--r--ext/boost/regex/v4/states.hpp293
-rw-r--r--ext/boost/regex/v4/sub_match.hpp509
-rw-r--r--ext/boost/regex/v4/syntax_type.hpp105
-rw-r--r--ext/boost/regex/v4/u32regex_iterator.hpp193
-rw-r--r--ext/boost/regex/v4/u32regex_token_iterator.hpp377
-rw-r--r--ext/boost/regex/v4/w32_regex_traits.hpp741
175 files changed, 45033 insertions, 0 deletions
diff --git a/ext/boost/date_time/adjust_functors.hpp b/ext/boost/date_time/adjust_functors.hpp
new file mode 100644
index 0000000000..7854ae4b76
--- /dev/null
+++ b/ext/boost/date_time/adjust_functors.hpp
@@ -0,0 +1,178 @@
+#ifndef _DATE_TIME_ADJUST_FUNCTORS_HPP___
+#define _DATE_TIME_ADJUST_FUNCTORS_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/date.hpp"
+#include "boost/date_time/wrapping_int.hpp"
+
+namespace boost {
+namespace date_time {
+
+
+ //! Functor to iterate a fixed number of days
+ template<class date_type>
+ class day_functor
+ {
+ public:
+ typedef typename date_type::duration_type duration_type;
+ day_functor(int f) : f_(f) {}
+ duration_type get_offset(const date_type& d) const
+ {
+ // why is 'd' a parameter???
+ // fix compiler warnings
+ d.year();
+ return duration_type(f_);
+ }
+ duration_type get_neg_offset(const date_type& d) const
+ {
+ // fix compiler warnings
+ d.year();
+ return duration_type(-f_);
+ }
+ private:
+ int f_;
+ };
+
+
+ //! Provides calculation to find next nth month given a date
+ /*! This adjustment function provides the logic for 'month-based'
+ * advancement on a ymd based calendar. The policy it uses
+ * to handle the non existant end of month days is to back
+ * up to the last day of the month. Also, if the starting
+ * date is the last day of a month, this functor will attempt
+ * to adjust to the end of the month.
+
+ */
+ template<class date_type>
+ class month_functor
+ {
+ public:
+ typedef typename date_type::duration_type duration_type;
+ typedef typename date_type::calendar_type cal_type;
+ typedef typename cal_type::ymd_type ymd_type;
+ typedef typename cal_type::day_type day_type;
+
+ month_functor(int f) : f_(f), origDayOfMonth_(0) {}
+ duration_type get_offset(const date_type& d) const
+ {
+ ymd_type ymd(d.year_month_day());
+ if (origDayOfMonth_ == 0) {
+ origDayOfMonth_ = ymd.day;
+ day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month));
+ if (endOfMonthDay == ymd.day) {
+ origDayOfMonth_ = -1; //force the value to the end of month
+ }
+ }
+ typedef date_time::wrapping_int2<short,1,12> wrap_int2;
+ typedef typename wrap_int2::int_type int_type;
+ wrap_int2 wi(ymd.month);
+ //calc the year wrap around, add() returns 0 or 1 if wrapped
+ int_type year = wi.add(static_cast<int_type>(f_));
+ year = static_cast<int_type>(year + ymd.year); //calculate resulting year
+// std::cout << "trace wi: " << wi.as_int() << std::endl;
+// std::cout << "trace year: " << year << std::endl;
+ //find the last day for the new month
+ day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int()));
+ //original was the end of month -- force to last day of month
+ if (origDayOfMonth_ == -1) {
+ return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d;
+ }
+ day_type dayOfMonth = origDayOfMonth_;
+ if (dayOfMonth > resultingEndOfMonthDay) {
+ dayOfMonth = resultingEndOfMonthDay;
+ }
+ return date_type(year, wi.as_int(), dayOfMonth) - d;
+ }
+ //! Returns a negative duration_type
+ duration_type get_neg_offset(const date_type& d) const
+ {
+ ymd_type ymd(d.year_month_day());
+ if (origDayOfMonth_ == 0) {
+ origDayOfMonth_ = ymd.day;
+ day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month));
+ if (endOfMonthDay == ymd.day) {
+ origDayOfMonth_ = -1; //force the value to the end of month
+ }
+ }
+ typedef date_time::wrapping_int2<short,1,12> wrap_int2;
+ typedef typename wrap_int2::int_type int_type;
+ wrap_int2 wi(ymd.month);
+ //calc the year wrap around, add() returns 0 or 1 if wrapped
+ int_type year = wi.subtract(static_cast<int_type>(f_));
+ year = static_cast<int_type>(year + ymd.year); //calculate resulting year
+ //find the last day for the new month
+ day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int()));
+ //original was the end of month -- force to last day of month
+ if (origDayOfMonth_ == -1) {
+ return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d;
+ }
+ day_type dayOfMonth = origDayOfMonth_;
+ if (dayOfMonth > resultingEndOfMonthDay) {
+ dayOfMonth = resultingEndOfMonthDay;
+ }
+ return date_type(year, wi.as_int(), dayOfMonth) - d;
+ }
+ private:
+ int f_;
+ mutable short origDayOfMonth_;
+ };
+
+
+ //! Functor to iterate a over weeks
+ template<class date_type>
+ class week_functor
+ {
+ public:
+ typedef typename date_type::duration_type duration_type;
+ typedef typename date_type::calendar_type calendar_type;
+ week_functor(int f) : f_(f) {}
+ duration_type get_offset(const date_type& d) const
+ {
+ // why is 'd' a parameter???
+ // fix compiler warnings
+ d.year();
+ return duration_type(f_*calendar_type::days_in_week());
+ }
+ duration_type get_neg_offset(const date_type& d) const
+ {
+ // fix compiler warnings
+ d.year();
+ return duration_type(-f_*calendar_type::days_in_week());
+ }
+ private:
+ int f_;
+ };
+
+ //! Functor to iterate by a year adjusting for leap years
+ template<class date_type>
+ class year_functor
+ {
+ public:
+ //typedef typename date_type::year_type year_type;
+ typedef typename date_type::duration_type duration_type;
+ year_functor(int f) : _mf(f * 12) {}
+ duration_type get_offset(const date_type& d) const
+ {
+ return _mf.get_offset(d);
+ }
+ duration_type get_neg_offset(const date_type& d) const
+ {
+ return _mf.get_neg_offset(d);
+ }
+ private:
+ month_functor<date_type> _mf;
+ };
+
+
+} }//namespace date_time
+
+
+#endif
+
diff --git a/ext/boost/date_time/c_local_time_adjustor.hpp b/ext/boost/date_time/c_local_time_adjustor.hpp
new file mode 100644
index 0000000000..f8025828f7
--- /dev/null
+++ b/ext/boost/date_time/c_local_time_adjustor.hpp
@@ -0,0 +1,66 @@
+#ifndef DATE_TIME_C_LOCAL_TIME_ADJUSTOR_HPP__
+#define DATE_TIME_C_LOCAL_TIME_ADJUSTOR_HPP__
+
+/* Copyright (c) 2002,2003,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-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+/*! @file c_local_time_adjustor.hpp
+ Time adjustment calculations based on machine
+*/
+
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/c_time.hpp>
+
+namespace boost {
+namespace date_time {
+
+ //! Adjust to / from utc using the C API
+ /*! Warning!!! This class assumes that timezone settings of the
+ * machine are correct. This can be a very dangerous assumption.
+ */
+ template<class time_type>
+ class c_local_adjustor {
+ public:
+ typedef typename time_type::time_duration_type time_duration_type;
+ typedef typename time_type::date_type date_type;
+ typedef typename date_type::duration_type date_duration_type;
+ //! Convert a utc time to local time
+ static time_type utc_to_local(const time_type& t)
+ {
+ date_type time_t_start_day(1970,1,1);
+ time_type time_t_start_time(time_t_start_day,time_duration_type(0,0,0));
+ if (t < time_t_start_time) {
+ boost::throw_exception(std::out_of_range("Cannot convert dates prior to Jan 1, 1970"));
+ BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return time_t_start_time); // should never reach
+ }
+ date_duration_type dd = t.date() - time_t_start_day;
+ time_duration_type td = t.time_of_day();
+ std::time_t t2 = dd.days()*86400 + td.hours()*3600 + td.minutes()*60 + td.seconds();
+ std::tm tms, *tms_ptr;
+ tms_ptr = c_time::localtime(&t2, &tms);
+ date_type d(static_cast<unsigned short>(tms_ptr->tm_year + 1900),
+ static_cast<unsigned short>(tms_ptr->tm_mon + 1),
+ static_cast<unsigned short>(tms_ptr->tm_mday));
+ time_duration_type td2(tms_ptr->tm_hour,
+ tms_ptr->tm_min,
+ tms_ptr->tm_sec,
+ t.time_of_day().fractional_seconds());
+
+ return time_type(d,td2);
+ }
+ };
+
+
+
+} } //namespace date_time
+
+
+
+#endif
diff --git a/ext/boost/date_time/c_time.hpp b/ext/boost/date_time/c_time.hpp
new file mode 100644
index 0000000000..42902a533b
--- /dev/null
+++ b/ext/boost/date_time/c_time.hpp
@@ -0,0 +1,105 @@
+#ifndef DATE_TIME_C_TIME_HPP___
+#define DATE_TIME_C_TIME_HPP___
+
+/* Copyright (c) 2002,2003,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-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+/*! @file c_time.hpp
+ Provide workarounds related to the ctime header
+*/
+
+#include <ctime>
+#include <string> // to be able to convert from string literals to exceptions
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/compiler_config.hpp>
+
+//Work around libraries that don't put time_t and time in namespace std
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std { using ::time_t; using ::time; using ::localtime;
+ using ::tm; using ::gmtime; }
+#endif // BOOST_NO_STDC_NAMESPACE
+
+//The following is used to support high precision time clocks
+#ifdef BOOST_HAS_GETTIMEOFDAY
+#include <sys/time.h>
+#endif
+
+#ifdef BOOST_HAS_FTIME
+#include <time.h>
+#endif
+
+namespace boost {
+namespace date_time {
+ //! Provides a uniform interface to some 'ctime' functions
+ /*! Provides a uniform interface to some ctime functions and
+ * their '_r' counterparts. The '_r' functions require a pointer to a
+ * user created std::tm struct whereas the regular functions use a
+ * staticly created struct and return a pointer to that. These wrapper
+ * functions require the user to create a std::tm struct and send in a
+ * pointer to it. A pointer to the user created struct will be returned.
+ * All functions do proper checking of the C function results and throw
+ * exceptions on error. Therefore the functions will never return NULL.
+ */
+ struct c_time {
+ public:
+#if defined(BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS)
+ //! requires a pointer to a user created std::tm struct
+ inline
+ static std::tm* localtime(const std::time_t* t, std::tm* result)
+ {
+ // localtime_r() not in namespace std???
+ result = localtime_r(t, result);
+ if (!result)
+ boost::throw_exception(std::runtime_error("could not convert calendar time to local time"));
+ return result;
+ }
+ //! requires a pointer to a user created std::tm struct
+ inline
+ static std::tm* gmtime(const std::time_t* t, std::tm* result)
+ {
+ // gmtime_r() not in namespace std???
+ result = gmtime_r(t, result);
+ if (!result)
+ boost::throw_exception(std::runtime_error("could not convert calendar time to UTC time"));
+ return result;
+ }
+#else // BOOST_HAS_THREADS
+
+#if (defined(_MSC_VER) && (_MSC_VER >= 1400))
+#pragma warning(push) // preserve warning settings
+#pragma warning(disable : 4996) // disable depricated localtime/gmtime warning on vc8
+#endif // _MSC_VER >= 1400
+ //! requires a pointer to a user created std::tm struct
+ inline
+ static std::tm* localtime(const std::time_t* t, std::tm* result)
+ {
+ result = std::localtime(t);
+ if (!result)
+ boost::throw_exception(std::runtime_error("could not convert calendar time to local time"));
+ return result;
+ }
+ //! requires a pointer to a user created std::tm struct
+ inline
+ static std::tm* gmtime(const std::time_t* t, std::tm* result)
+ {
+ result = std::gmtime(t);
+ if (!result)
+ boost::throw_exception(std::runtime_error("could not convert calendar time to UTC time"));
+ return result;
+ }
+#if (defined(_MSC_VER) && (_MSC_VER >= 1400))
+#pragma warning(pop) // restore warnings to previous state
+#endif // _MSC_VER >= 1400
+
+#endif // BOOST_HAS_THREADS
+ };
+}} // namespaces
+
+#endif // DATE_TIME_C_TIME_HPP___
diff --git a/ext/boost/date_time/compiler_config.hpp b/ext/boost/date_time/compiler_config.hpp
new file mode 100644
index 0000000000..0dc893f9fb
--- /dev/null
+++ b/ext/boost/date_time/compiler_config.hpp
@@ -0,0 +1,171 @@
+#ifndef DATE_TIME_COMPILER_CONFIG_HPP___
+#define DATE_TIME_COMPILER_CONFIG_HPP___
+
+/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
+ * 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-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <cstdlib>
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+// With boost release 1.33, date_time will be using a different,
+// more flexible, IO system. This new system is not compatible with
+// old compilers. The original date_time IO system remains for those
+// compilers. They must define this macro to use the legacy IO.
+// (defined(__BORLANDC__) && (__BORLANDC__ <= 0x0581) ) ) &&
+ #if( BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) \
+ || BOOST_WORKAROUND( __GNUC__, < 3) \
+ || (BOOST_WORKAROUND( _MSC_VER, <= 1300) ) \
+ ) \
+ && !defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+# define USE_DATE_TIME_PRE_1_33_FACET_IO
+#endif
+
+
+// This file performs some local compiler configurations
+
+#include <boost/date_time/locale_config.hpp> //set up locale configurations
+
+//Set up a configuration parameter for platforms that have
+//GetTimeOfDay
+#if defined(BOOST_HAS_GETTIMEOFDAY) || defined(BOOST_HAS_FTIME)
+#define BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
+#endif
+
+// To Force no default constructors for date & ptime, un-comment following
+//#define DATE_TIME_NO_DEFAULT_CONSTRUCTOR
+
+// Include extensions to date_duration - comment out to remove this feature
+#define BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES
+// these extensions are known to cause problems with gcc295
+#if defined(__GNUC__) && (__GNUC__ < 3)
+#undef BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES
+#endif
+
+#if (defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) || BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) )
+#define BOOST_DATE_TIME_NO_MEMBER_INIT
+#endif
+
+// include these types before we try to re-define them
+#include <boost/cstdint.hpp>
+
+//Define INT64_C for compilers that don't have it
+#if (!defined(INT64_C))
+#define INT64_C(value) int64_t(value)
+#endif
+
+
+/* Workaround for Borland iterator error. Error was "Cannot convert 'istream *' to 'wistream *' in function istream_iterator<>::istream_iterator() */
+#if defined(__BORLANDC__) && defined(BOOST_BCB_WITH_RW_LIB)
+#define BOOST_DATE_TIME_NO_WISTREAM_ITERATOR
+#endif
+
+
+// Borland v5.64 does not have the following in std namespace; v5.5.1 does
+#if defined(__BORLANDC__) && defined(BOOST_BCB_WITH_STLPORT)
+#include <locale>
+namespace std {
+ using stlport::tolower;
+ using stlport::ctype;
+ using stlport::use_facet;
+}
+#endif
+
+// workaround for errors associated with output for date classes
+// modifications and input streaming for time classes.
+// Compilers affected are:
+// gcc295, msvc (neither with STLPort), any borland
+//
+#if (((defined(__GNUC__) && (__GNUC__ < 3)) || \
+ (defined(_MSC_VER) && (_MSC_VER < 1300)) ) && \
+ !defined(_STLP_OWN_IOSTREAMS) ) || \
+ BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) )
+#define BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS
+#endif
+
+// The macro marks up places where compiler complains for missing return statement or
+// uninitialized variables after calling to boost::throw_exception.
+// BOOST_UNREACHABLE_RETURN doesn't work since even compilers that support
+// unreachable statements detection emit such warnings.
+#if defined(_MSC_VER)
+// Use special MSVC extension to markup unreachable code
+# define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) __assume(false)
+#elif !defined(BOOST_NO_UNREACHABLE_RETURN_DETECTION)
+// Call to a non-returning function should suppress the warning
+# if defined(BOOST_NO_STDC_NAMESPACE)
+namespace std {
+ using ::abort;
+}
+# endif // defined(BOOST_NO_STDC_NAMESPACE)
+# define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) std::abort()
+#else
+// For other poor compilers the specified expression is compiled. Usually, this would be a return statement.
+# define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) x
+#endif
+
+/* The following handles the definition of the necessary macros
+ * for dll building on Win32 platforms.
+ *
+ * For code that will be placed in the date_time .dll,
+ * it must be properly prefixed with BOOST_DATE_TIME_DECL.
+ * The corresponding .cpp file must have BOOST_DATE_TIME_SOURCE
+ * defined before including its header. For examples see:
+ * greg_month.hpp & greg_month.cpp
+ *
+ */
+
+#ifdef BOOST_HAS_DECLSPEC // defined in config system
+ // we need to import/export our code only if the user has specifically
+ // asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
+ // libraries to be dynamically linked, or BOOST_DATE_TIME_DYN_LINK
+ // if they want just this one to be dynamically liked:
+# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK)
+ // export if this is our own source, otherwise import:
+# ifdef BOOST_DATE_TIME_SOURCE
+# define BOOST_DATE_TIME_DECL __declspec(dllexport)
+# else
+# define BOOST_DATE_TIME_DECL __declspec(dllimport)
+# endif // BOOST_DATE_TIME_SOURCE
+# endif // DYN_LINK
+#endif // BOOST_HAS_DECLSPEC
+//
+// if BOOST_WHATEVER_DECL isn't defined yet define it now:
+#ifndef BOOST_DATE_TIME_DECL
+# define BOOST_DATE_TIME_DECL
+#endif
+
+//
+// Automatically link to the correct build variant where possible.
+//
+#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_DATE_TIME_NO_LIB) && !defined(BOOST_DATE_TIME_SOURCE)
+//
+// Set the name of our library, this will get undef'ed by auto_link.hpp
+// once it's done with it:
+//
+#define BOOST_LIB_NAME boost_date_time
+//
+// If we're importing code from a dll, then tell auto_link.hpp about it:
+//
+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK)
+# define BOOST_DYN_LINK
+#endif
+//
+// And include the header that does the work:
+//
+#include <boost/config/auto_link.hpp>
+#endif // auto-linking disabled
+
+#if defined(BOOST_HAS_THREADS)
+# if defined(_MSC_VER) || defined(__MWERKS__) || defined(__MINGW32__) || defined(__BORLANDC__)
+ //no reentrant posix functions (eg: localtime_r)
+# elif (!defined(__hpux) || (defined(__hpux) && defined(_REENTRANT)))
+# define BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS
+# endif
+#endif
+
+
+#endif
diff --git a/ext/boost/date_time/constrained_value.hpp b/ext/boost/date_time/constrained_value.hpp
new file mode 100644
index 0000000000..b273dd5aa8
--- /dev/null
+++ b/ext/boost/date_time/constrained_value.hpp
@@ -0,0 +1,121 @@
+#ifndef CONSTRAINED_VALUE_HPP___
+#define CONSTRAINED_VALUE_HPP___
+
+/* 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-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <exception>
+#include <stdexcept>
+#include <boost/config.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+namespace boost {
+
+//! Namespace containing constrained_value template and types
+namespace CV {
+ //! Represent a min or max violation type
+ enum violation_enum {min_violation, max_violation};
+
+ //! A template to specify a constrained basic value type
+ /*! This template provides a quick way to generate
+ * an integer type with a constrained range. The type
+ * provides for the ability to specify the min, max, and
+ * and error handling policy.
+ *
+ * <b>value policies</b>
+ * A class that provides the range limits via the min and
+ * max functions as well as a function on_error that
+ * determines how errors are handled. A common strategy
+ * would be to assert or throw and exception. The on_error
+ * is passed both the current value and the new value that
+ * is in error.
+ *
+ */
+ template<class value_policies>
+ class constrained_value {
+ public:
+ typedef typename value_policies::value_type value_type;
+ // typedef except_type exception_type;
+ constrained_value(value_type value) : value_((min)())
+ {
+ assign(value);
+ }
+ constrained_value& operator=(value_type v)
+ {
+ assign(v);
+ return *this;
+ }
+ //! Return the max allowed value (traits method)
+ static value_type max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::max)();}
+ //! Return the min allowed value (traits method)
+ static value_type min BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::min)();}
+ //! Coerce into the representation type
+ operator value_type() const {return value_;}
+ protected:
+ value_type value_;
+ private:
+ void assign(value_type value)
+ {
+ //adding 1 below gets rid of a compiler warning which occurs when the
+ //min_value is 0 and the type is unsigned....
+ if (value+1 < (min)()+1) {
+ value_policies::on_error(value_, value, min_violation);
+ return;
+ }
+ if (value > (max)()) {
+ value_policies::on_error(value_, value, max_violation);
+ return;
+ }
+ value_ = value;
+ }
+};
+
+ //! Template to shortcut the constrained_value policy creation process
+ template<typename rep_type, rep_type min_value,
+ rep_type max_value, class exception_type>
+ class simple_exception_policy
+ {
+ struct exception_wrapper : public exception_type
+ {
+ // In order to support throw_exception mechanism in the BOOST_NO_EXCEPTIONS mode,
+ // we'll have to provide a way to acquire std::exception from the exception being thrown.
+ // However, we cannot derive from it, since it would make it interceptable by this class,
+ // which might not be what the user wanted.
+ operator std::out_of_range () const
+ {
+ // TODO: Make the message more descriptive by using arguments to on_error
+ return std::out_of_range("constrained value boundary has been violated");
+ }
+ };
+
+ typedef typename mpl::if_<
+ is_base_of< std::exception, exception_type >,
+ exception_type,
+ exception_wrapper
+ >::type actual_exception_type;
+
+ public:
+ typedef rep_type value_type;
+ static rep_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return min_value; }
+ static rep_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return max_value; }
+ static void on_error(rep_type, rep_type, violation_enum)
+ {
+ boost::throw_exception(actual_exception_type());
+ }
+ };
+
+
+
+} } //namespace CV
+
+
+
+
+#endif
diff --git a/ext/boost/date_time/date.hpp b/ext/boost/date_time/date.hpp
new file mode 100644
index 0000000000..beab047700
--- /dev/null
+++ b/ext/boost/date_time/date.hpp
@@ -0,0 +1,197 @@
+#ifndef DATE_TIME_DATE_HPP___
+#define DATE_TIME_DATE_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/year_month_day.hpp"
+#include "boost/date_time/special_defs.hpp"
+#include "boost/operators.hpp"
+
+namespace boost {
+namespace date_time {
+
+ //!Representation of timepoint at the one day level resolution.
+ /*!
+ The date template represents an interface shell for a date class
+ that is based on a year-month-day system such as the gregorian
+ or iso systems. It provides basic operations to enable calculation
+ and comparisons.
+
+ <b>Theory</b>
+
+ This date representation fundamentally departs from the C tm struct
+ approach. The goal for this type is to provide efficient date
+ operations (add, subtract) and storage (minimize space to represent)
+ in a concrete class. Thus, the date uses a count internally to
+ represent a particular date. The calendar parameter defines
+ the policies for converting the the year-month-day and internal
+ counted form here. Applications that need to perform heavy
+ formatting of the same date repeatedly will perform better
+ by using the year-month-day representation.
+
+ Internally the date uses a day number to represent the date.
+ This is a monotonic time representation. This representation
+ allows for fast comparison as well as simplifying
+ the creation of writing numeric operations. Essentially, the
+ internal day number is like adjusted julian day. The adjustment
+ is determined by the Epoch date which is represented as day 1 of
+ the calendar. Day 0 is reserved for negative infinity so that
+ any actual date is automatically greater than negative infinity.
+ When a date is constructed from a date or formatted for output,
+ the appropriate conversions are applied to create the year, month,
+ day representations.
+ */
+
+
+ template<class T, class calendar, class duration_type_>
+ class date : private
+ boost::less_than_comparable<T
+ , boost::equality_comparable<T
+ > >
+ {
+ public:
+ typedef T date_type;
+ typedef calendar calendar_type;
+ typedef typename calendar::date_traits_type traits_type;
+ typedef duration_type_ duration_type;
+ typedef typename calendar::year_type year_type;
+ typedef typename calendar::month_type month_type;
+ typedef typename calendar::day_type day_type;
+ typedef typename calendar::ymd_type ymd_type;
+ typedef typename calendar::date_rep_type date_rep_type;
+ typedef typename calendar::date_int_type date_int_type;
+ typedef typename calendar::day_of_week_type day_of_week_type;
+ date(year_type y, month_type m, day_type d)
+ : days_(calendar::day_number(ymd_type(y, m, d)))
+ {}
+ date(const ymd_type& ymd)
+ : days_(calendar::day_number(ymd))
+ {}
+ //let the compiler write copy, assignment, and destructor
+ year_type year() const
+ {
+ ymd_type ymd = calendar::from_day_number(days_);
+ return ymd.year;
+ }
+ month_type month() const
+ {
+ ymd_type ymd = calendar::from_day_number(days_);
+ return ymd.month;
+ }
+ day_type day() const
+ {
+ ymd_type ymd = calendar::from_day_number(days_);
+ return ymd.day;
+ }
+ day_of_week_type day_of_week() const
+ {
+ ymd_type ymd = calendar::from_day_number(days_);
+ return calendar::day_of_week(ymd);
+ }
+ ymd_type year_month_day() const
+ {
+ return calendar::from_day_number(days_);
+ }
+ bool operator<(const date_type& rhs) const
+ {
+ return days_ < rhs.days_;
+ }
+ bool operator==(const date_type& rhs) const
+ {
+ return days_ == rhs.days_;
+ }
+ //! check to see if date is a special value
+ bool is_special()const
+ {
+ return(is_not_a_date() || is_infinity());
+ }
+ //! check to see if date is not a value
+ bool is_not_a_date() const
+ {
+ return traits_type::is_not_a_number(days_);
+ }
+ //! check to see if date is one of the infinity values
+ bool is_infinity() const
+ {
+ return traits_type::is_inf(days_);
+ }
+ //! check to see if date is greater than all possible dates
+ bool is_pos_infinity() const
+ {
+ return traits_type::is_pos_inf(days_);
+ }
+ //! check to see if date is greater than all possible dates
+ bool is_neg_infinity() const
+ {
+ return traits_type::is_neg_inf(days_);
+ }
+ //! return as a special value or a not_special if a normal date
+ special_values as_special() const
+ {
+ return traits_type::to_special(days_);
+ }
+ duration_type operator-(const date_type& d) const
+ {
+ date_rep_type val = date_rep_type(days_) - date_rep_type(d.days_);
+ return duration_type(val.as_number());
+ }
+
+ date_type operator-(const duration_type& dd) const
+ {
+ if(dd.is_special())
+ {
+ return date_type(date_rep_type(days_) - dd.get_rep());
+ }
+ return date_type(date_rep_type(days_) - dd.days());
+ }
+ date_type operator-=(const duration_type& dd)
+ {
+ *this = *this - dd;
+ return date_type(days_);
+ }
+ date_rep_type day_count() const
+ {
+ return days_;
+ };
+ //allow internal access from operators
+ date_type operator+(const duration_type& dd) const
+ {
+ if(dd.is_special())
+ {
+ return date_type(date_rep_type(days_) + dd.get_rep());
+ }
+ return date_type(date_rep_type(days_) + dd.days());
+ }
+ date_type operator+=(const duration_type& dd)
+ {
+ *this = *this + dd;
+ return date_type(days_);
+ }
+
+ //see reference
+ protected:
+ /*! This is a private constructor which allows for the creation of new
+ dates. It is not exposed to users since that would require class
+ users to understand the inner workings of the date class.
+ */
+ explicit date(date_int_type days) : days_(days) {};
+ explicit date(date_rep_type days) : days_(days.as_number()) {};
+ date_int_type days_;
+
+ };
+
+
+
+
+} } // namespace date_time
+
+
+
+
+#endif
diff --git a/ext/boost/date_time/date_clock_device.hpp b/ext/boost/date_time/date_clock_device.hpp
new file mode 100644
index 0000000000..6ccb26e254
--- /dev/null
+++ b/ext/boost/date_time/date_clock_device.hpp
@@ -0,0 +1,77 @@
+#ifndef DATE_CLOCK_DEVICE_HPP___
+#define DATE_CLOCK_DEVICE_HPP___
+
+/* Copyright (c) 2002,2003,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-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/c_time.hpp"
+
+
+namespace boost {
+namespace date_time {
+
+ //! A clock providing day level services based on C time_t capabilities
+ /*! This clock uses Posix interfaces as its implementation and hence
+ * uses the timezone settings of the operating system. Incorrect
+ * user settings will result in incorrect results for the calls
+ * to local_day.
+ */
+ template<class date_type>
+ class day_clock
+ {
+ public:
+ typedef typename date_type::ymd_type ymd_type;
+ //! Get the local day as a date type
+ static date_type local_day()
+ {
+ return date_type(local_day_ymd());
+ }
+ //! Get the local day as a ymd_type
+ static typename date_type::ymd_type local_day_ymd()
+ {
+ ::std::tm result;
+ ::std::tm* curr = get_local_time(result);
+ return ymd_type(curr->tm_year + 1900,
+ curr->tm_mon + 1,
+ curr->tm_mday);
+ }
+ //! Get the current day in universal date as a ymd_type
+ static typename date_type::ymd_type universal_day_ymd()
+ {
+ ::std::tm result;
+ ::std::tm* curr = get_universal_time(result);
+ return ymd_type(curr->tm_year + 1900,
+ curr->tm_mon + 1,
+ curr->tm_mday);
+ }
+ //! Get the UTC day as a date type
+ static date_type universal_day()
+ {
+ return date_type(universal_day_ymd());
+ }
+
+ private:
+ static ::std::tm* get_local_time(std::tm& result)
+ {
+ ::std::time_t t;
+ ::std::time(&t);
+ return c_time::localtime(&t, &result);
+ }
+ static ::std::tm* get_universal_time(std::tm& result)
+ {
+ ::std::time_t t;
+ ::std::time(&t);
+ return c_time::gmtime(&t, &result);
+ }
+
+ };
+
+} } //namespace date_time
+
+
+#endif
diff --git a/ext/boost/date_time/date_defs.hpp b/ext/boost/date_time/date_defs.hpp
new file mode 100644
index 0000000000..bc25b56c0d
--- /dev/null
+++ b/ext/boost/date_time/date_defs.hpp
@@ -0,0 +1,26 @@
+#ifndef DATE_TIME_DATE_DEFS_HPP
+#define DATE_TIME_DATE_DEFS_HPP
+
+/* 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) $
+ */
+
+
+namespace boost {
+namespace date_time {
+
+ //! An enumeration of weekday names
+ enum weekdays {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};
+
+ //! Simple enum to allow for nice programming with Jan, Feb, etc
+ enum months_of_year {Jan=1,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec,NotAMonth,NumMonths};
+
+} } //namespace date_time
+
+
+
+#endif
diff --git a/ext/boost/date_time/date_duration.hpp b/ext/boost/date_time/date_duration.hpp
new file mode 100644
index 0000000000..3871aac0ce
--- /dev/null
+++ b/ext/boost/date_time/date_duration.hpp
@@ -0,0 +1,146 @@
+#ifndef DATE_TIME_DATE_DURATION__
+#define DATE_TIME_DATE_DURATION__
+
+/* 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-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+#include <boost/operators.hpp>
+#include <boost/date_time/special_defs.hpp>
+
+namespace boost {
+namespace date_time {
+
+
+ //! Duration type with date level resolution
+ template<class duration_rep_traits>
+ class date_duration : private
+ boost::less_than_comparable1< date_duration< duration_rep_traits >
+ , boost::equality_comparable1< date_duration< duration_rep_traits >
+ , boost::addable1< date_duration< duration_rep_traits >
+ , boost::subtractable1< date_duration< duration_rep_traits >
+ , boost::dividable2< date_duration< duration_rep_traits >, int
+ > > > > >
+ {
+ public:
+ typedef typename duration_rep_traits::int_type duration_rep_type;
+ typedef typename duration_rep_traits::impl_type duration_rep;
+
+ //! Construct from a day count
+ explicit date_duration(duration_rep day_count) : days_(day_count) {};
+
+ /*! construct from special_values - only works when
+ * instantiated with duration_traits_adapted */
+ date_duration(special_values sv) :
+ days_(duration_rep::from_special(sv))
+ {}
+
+ // copy constructor required for addable<> & subtractable<>
+ //! Construct from another date_duration (Copy Constructor)
+ date_duration(const date_duration<duration_rep_traits>& other) :
+ days_(other.days_)
+ {}
+
+ //! returns days_ as it's instantiated type - used for streaming
+ duration_rep get_rep()const
+ {
+ return days_;
+ }
+ bool is_special()const
+ {
+ return days_.is_special();
+ }
+ //! returns days as value, not object.
+ duration_rep_type days() const
+ {
+ return duration_rep_traits::as_number(days_);
+ }
+ //! Returns the smallest duration -- used by to calculate 'end'
+ static date_duration unit()
+ {
+ return date_duration<duration_rep_traits>(1);
+ }
+ //! Equality
+ bool operator==(const date_duration& rhs) const
+ {
+ return days_ == rhs.days_;
+ }
+ //! Less
+ bool operator<(const date_duration& rhs) const
+ {
+ return days_ < rhs.days_;
+ }
+
+ /* For shortcut operators (+=, -=, etc) simply using
+ * "days_ += days_" may not work. If instantiated with
+ * an int_adapter, shortcut operators are not present,
+ * so this will not compile */
+
+ //! Subtract another duration -- result is signed
+ date_duration& operator-=(const date_duration& rhs)
+ {
+ //days_ -= rhs.days_;
+ days_ = days_ - rhs.days_;
+ return *this;
+ }
+ //! Add a duration -- result is signed
+ date_duration& operator+=(const date_duration& rhs)
+ {
+ days_ = days_ + rhs.days_;
+ return *this;
+ }
+
+ //! unary- Allows for dd = -date_duration(2); -> dd == -2
+ date_duration operator-() const
+ {
+ return date_duration<duration_rep_traits>(get_rep() * (-1));
+ }
+ //! Division operations on a duration with an integer.
+ date_duration& operator/=(int divisor)
+ {
+ days_ = days_ / divisor;
+ return *this;
+ }
+
+ //! return sign information
+ bool is_negative() const
+ {
+ return days_ < 0;
+ }
+
+ private:
+ duration_rep days_;
+ };
+
+
+ /*! Struct for instantiating date_duration with <b>NO</b> special values
+ * functionality. Allows for transparent implementation of either
+ * date_duration<long> or date_duration<int_adapter<long> > */
+ struct duration_traits_long
+ {
+ typedef long int_type;
+ typedef long impl_type;
+ static int_type as_number(impl_type i) { return i; };
+ };
+
+ /*! Struct for instantiating date_duration <b>WITH</b> special values
+ * functionality. Allows for transparent implementation of either
+ * date_duration<long> or date_duration<int_adapter<long> > */
+ struct duration_traits_adapted
+ {
+ typedef long int_type;
+ typedef boost::date_time::int_adapter<long> impl_type;
+ static int_type as_number(impl_type i) { return i.as_number(); };
+ };
+
+
+} } //namspace date_time
+
+
+#endif
+
diff --git a/ext/boost/date_time/date_duration_types.hpp b/ext/boost/date_time/date_duration_types.hpp
new file mode 100644
index 0000000000..1512c0ef20
--- /dev/null
+++ b/ext/boost/date_time/date_duration_types.hpp
@@ -0,0 +1,269 @@
+#ifndef DATE_DURATION_TYPES_HPP___
+#define DATE_DURATION_TYPES_HPP___
+
+/* Copyright (c) 2004 CrystalClear Software, Inc.
+ * 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) $
+ */
+
+#include <boost/date_time/int_adapter.hpp>
+#include <boost/date_time/special_defs.hpp>
+#include <boost/date_time/date_duration.hpp>
+
+namespace boost {
+namespace date_time {
+
+
+ //! Additional duration type that represents a number of n*7 days
+ template <class duration_config>
+ class weeks_duration : public date_duration<duration_config> {
+ public:
+ weeks_duration(typename duration_config::impl_type w)
+ : date_duration<duration_config>(w * 7) {}
+ weeks_duration(special_values sv)
+ : date_duration<duration_config>(sv) {}
+ };
+
+ // predeclare
+ template<class t>
+ class years_duration;
+
+ //! additional duration type that represents a logical month
+ /*! A logical month enables things like: "date(2002,Mar,2) + months(2) ->
+ * 2002-May2". If the date is a last day-of-the-month, the result will
+ * also be a last-day-of-the-month.
+ */
+ template<class base_config>
+ class months_duration
+ {
+ private:
+ typedef typename base_config::int_rep int_rep;
+ typedef typename int_rep::int_type int_type;
+ typedef typename base_config::date_type date_type;
+ typedef typename date_type::duration_type duration_type;
+ typedef typename base_config::month_adjustor_type month_adjustor_type;
+ typedef months_duration<base_config> months_type;
+ typedef years_duration<base_config> years_type;
+ public:
+ months_duration(int_rep num) : _m(num) {}
+ months_duration(special_values sv) : _m(sv)
+ {
+ _m = int_rep::from_special(sv);
+ }
+ int_rep number_of_months() const { return _m; }
+ //! returns a negative duration
+ duration_type get_neg_offset(const date_type& d) const
+ {
+ month_adjustor_type m_adj(_m.as_number());
+ return duration_type(m_adj.get_neg_offset(d));
+ }
+ duration_type get_offset(const date_type& d) const
+ {
+ month_adjustor_type m_adj(_m.as_number());
+ return duration_type(m_adj.get_offset(d));
+ }
+ bool operator==(const months_type& rhs) const
+ {
+ return(_m == rhs._m);
+ }
+ bool operator!=(const months_type& rhs) const
+ {
+ return(_m != rhs._m);
+ }
+ months_type operator+(const months_type& rhs)const
+ {
+ return months_type(_m + rhs._m);
+ }
+ months_type& operator+=(const months_type& rhs)
+ {
+ _m = _m + rhs._m;
+ return *this;
+ }
+ months_type operator-(const months_type& rhs)const
+ {
+ return months_type(_m - rhs._m);
+ }
+ months_type& operator-=(const months_type& rhs)
+ {
+ _m = _m - rhs._m;
+ return *this;
+ }
+ months_type operator*(const int_type rhs)const
+ {
+ return months_type(_m * rhs);
+ }
+ months_type& operator*=(const int_type rhs)
+ {
+ _m = _m * rhs;
+ return *this;
+ }
+ months_type operator/(const int_type rhs)const
+ {
+ return months_type(_m / rhs);
+ }
+ months_type& operator/=(const int_type rhs)
+ {
+ _m = _m / rhs;
+ return *this;
+ }
+ months_type operator+(const years_type& y)const
+ {
+ return months_type(y.number_of_years() * 12 + _m);
+ }
+ months_type& operator+=(const years_type& y)
+ {
+ _m = y.number_of_years() * 12 + _m;
+ return *this;
+ }
+ months_type operator-(const years_type& y) const
+ {
+ return months_type(_m - y.number_of_years() * 12);
+ }
+ months_type& operator-=(const years_type& y)
+ {
+ _m = _m - y.number_of_years() * 12;
+ return *this;
+ }
+
+ //
+ friend date_type operator+(const date_type& d, const months_type& m)
+ {
+ return d + m.get_offset(d);
+ }
+ friend date_type operator+=(date_type& d, const months_type& m)
+ {
+ return d += m.get_offset(d);
+ }
+ friend date_type operator-(const date_type& d, const months_type& m)
+ {
+ // get_neg_offset returns a negative duration, so we add
+ return d + m.get_neg_offset(d);
+ }
+ friend date_type operator-=(date_type& d, const months_type& m)
+ {
+ // get_neg_offset returns a negative duration, so we add
+ return d += m.get_neg_offset(d);
+ }
+
+ private:
+ int_rep _m;
+ };
+
+ //! additional duration type that represents a logical year
+ /*! A logical year enables things like: "date(2002,Mar,2) + years(2) ->
+ * 2004-Mar-2". If the date is a last day-of-the-month, the result will
+ * also be a last-day-of-the-month (ie date(2001-Feb-28) + years(3) ->
+ * 2004-Feb-29).
+ */
+ template<class base_config>
+ class years_duration
+ {
+ private:
+ typedef typename base_config::int_rep int_rep;
+ typedef typename int_rep::int_type int_type;
+ typedef typename base_config::date_type date_type;
+ typedef typename date_type::duration_type duration_type;
+ typedef typename base_config::month_adjustor_type month_adjustor_type;
+ typedef years_duration<base_config> years_type;
+ typedef months_duration<base_config> months_type;
+ public:
+ years_duration(int_rep num) : _y(num) {}
+ years_duration(special_values sv) : _y(sv)
+ {
+ _y = int_rep::from_special(sv);
+ }
+ int_rep number_of_years() const { return _y; }
+ //! returns a negative duration
+ duration_type get_neg_offset(const date_type& d) const
+ {
+ month_adjustor_type m_adj(_y.as_number() * 12);
+ return duration_type(m_adj.get_neg_offset(d));
+ }
+ duration_type get_offset(const date_type& d) const
+ {
+ month_adjustor_type m_adj(_y.as_number() * 12);
+ return duration_type(m_adj.get_offset(d));
+ }
+ bool operator==(const years_type& rhs) const
+ {
+ return(_y == rhs._y);
+ }
+ bool operator!=(const years_type& rhs) const
+ {
+ return(_y != rhs._y);
+ }
+ years_type operator+(const years_type& rhs)const
+ {
+ return years_type(_y + rhs._y);
+ }
+ years_type& operator+=(const years_type& rhs)
+ {
+ _y = _y + rhs._y;
+ return *this;
+ }
+ years_type operator-(const years_type& rhs)const
+ {
+ return years_type(_y - rhs._y);
+ }
+ years_type& operator-=(const years_type& rhs)
+ {
+ _y = _y - rhs._y;
+ return *this;
+ }
+ years_type operator*(const int_type rhs)const
+ {
+ return years_type(_y * rhs);
+ }
+ years_type& operator*=(const int_type rhs)
+ {
+ _y = _y * rhs;
+ return *this;
+ }
+ years_type operator/(const int_type rhs)const
+ {
+ return years_type(_y / rhs);
+ }
+ years_type& operator/=(const int_type rhs)
+ {
+ _y = _y / rhs;
+ return *this;
+ }
+ months_type operator+(const months_type& m) const
+ {
+ return(months_type(_y * 12 + m.number_of_months()));
+ }
+ months_type operator-(const months_type& m) const
+ {
+ return(months_type(_y * 12 - m.number_of_months()));
+ }
+
+ //
+ friend date_type operator+(const date_type& d, const years_type& y)
+ {
+ return d + y.get_offset(d);
+ }
+ friend date_type operator+=(date_type& d, const years_type& y)
+ {
+ return d += y.get_offset(d);
+ }
+ friend date_type operator-(const date_type& d, const years_type& y)
+ {
+ // get_neg_offset returns a negative duration, so we add
+ return d + y.get_neg_offset(d);
+ }
+ friend date_type operator-=(date_type& d, const years_type& y)
+ {
+ // get_neg_offset returns a negative duration, so we add
+ return d += y.get_neg_offset(d);
+ }
+
+ private:
+ int_rep _y;
+ };
+
+}} // namespace boost::date_time
+
+#endif // DATE_DURATION_TYPES_HPP___
diff --git a/ext/boost/date_time/date_facet.hpp b/ext/boost/date_time/date_facet.hpp
new file mode 100644
index 0000000000..3eda4c7d09
--- /dev/null
+++ b/ext/boost/date_time/date_facet.hpp
@@ -0,0 +1,764 @@
+#ifndef _DATE_TIME_DATE_FACET__HPP___
+#define _DATE_TIME_DATE_FACET__HPP___
+
+/* Copyright (c) 2004-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: Martin Andrian, Jeff Garland, Bart Garst
+ * $Date: 2009-06-04 07:40:18 -0400 (Thu, 04 Jun 2009) $
+ */
+
+#include <locale>
+#include <string>
+#include <vector>
+#include <iterator> // ostreambuf_iterator
+#include <boost/throw_exception.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/period.hpp>
+#include <boost/date_time/special_defs.hpp>
+#include <boost/date_time/special_values_formatter.hpp>
+#include <boost/date_time/period_formatter.hpp>
+#include <boost/date_time/period_parser.hpp>
+#include <boost/date_time/date_generator_formatter.hpp>
+#include <boost/date_time/date_generator_parser.hpp>
+#include <boost/date_time/format_date_parser.hpp>
+
+namespace boost { namespace date_time {
+
+
+ /*! Class that provides format based I/O facet for date types.
+ *
+ * This class allows the formatting of dates by using format string.
+ * Format strings are:
+ *
+ * - %A => long_weekday_format - Full name Ex: Tuesday
+ * - %a => short_weekday_format - Three letter abbreviation Ex: Tue
+ * - %B => long_month_format - Full name Ex: October
+ * - %b => short_month_format - Three letter abbreviation Ex: Oct
+ * - %x => standard_format_specifier - defined by the locale
+ * - %Y-%b-%d => default_date_format - YYYY-Mon-dd
+ *
+ * Default month format == %b
+ * Default weekday format == %a
+ */
+ template <class date_type,
+ class CharT,
+ class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
+ class date_facet : public std::locale::facet {
+ public:
+ typedef typename date_type::duration_type duration_type;
+ // greg_weekday is gregorian_calendar::day_of_week_type
+ typedef typename date_type::day_of_week_type day_of_week_type;
+ typedef typename date_type::day_type day_type;
+ typedef typename date_type::month_type month_type;
+ typedef boost::date_time::period<date_type,duration_type> period_type;
+ typedef std::basic_string<CharT> string_type;
+ typedef CharT char_type;
+ typedef boost::date_time::period_formatter<CharT> period_formatter_type;
+ typedef boost::date_time::special_values_formatter<CharT> special_values_formatter_type;
+ typedef std::vector<std::basic_string<CharT> > input_collection_type;
+ // used for the output of the date_generators
+ typedef date_generator_formatter<date_type, CharT> date_gen_formatter_type;
+ typedef partial_date<date_type> partial_date_type;
+ typedef nth_kday_of_month<date_type> nth_kday_type;
+ typedef first_kday_of_month<date_type> first_kday_type;
+ typedef last_kday_of_month<date_type> last_kday_type;
+ typedef first_kday_after<date_type> kday_after_type;
+ typedef first_kday_before<date_type> kday_before_type;
+ static const char_type long_weekday_format[3];
+ static const char_type short_weekday_format[3];
+ static const char_type long_month_format[3];
+ static const char_type short_month_format[3];
+ static const char_type default_period_separator[4];
+ static const char_type standard_format_specifier[3];
+ static const char_type iso_format_specifier[7];
+ static const char_type iso_format_extended_specifier[9];
+ static const char_type default_date_format[9]; // YYYY-Mon-DD
+ static std::locale::id id;
+
+#if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
+ std::locale::id& __get_id (void) const { return id; }
+#endif
+
+ explicit date_facet(::size_t a_ref = 0)
+ : std::locale::facet(a_ref),
+ //m_format(standard_format_specifier)
+ m_format(default_date_format),
+ m_month_format(short_month_format),
+ m_weekday_format(short_weekday_format)
+ {}
+
+ explicit date_facet(const char_type* format_str,
+ const input_collection_type& short_names,
+ ::size_t ref_count = 0)
+ : std::locale::facet(ref_count),
+ m_format(format_str),
+ m_month_format(short_month_format),
+ m_weekday_format(short_weekday_format),
+ m_month_short_names(short_names)
+ {}
+
+
+ explicit date_facet(const char_type* format_str,
+ period_formatter_type per_formatter = period_formatter_type(),
+ special_values_formatter_type sv_formatter = special_values_formatter_type(),
+ date_gen_formatter_type dg_formatter = date_gen_formatter_type(),
+ ::size_t ref_count = 0)
+ : std::locale::facet(ref_count),
+ m_format(format_str),
+ m_month_format(short_month_format),
+ m_weekday_format(short_weekday_format),
+ m_period_formatter(per_formatter),
+ m_date_gen_formatter(dg_formatter),
+ m_special_values_formatter(sv_formatter)
+ {}
+ void format(const char_type* const format_str) {
+ m_format = format_str;
+ }
+ virtual void set_iso_format()
+ {
+ m_format = iso_format_specifier;
+ }
+ virtual void set_iso_extended_format()
+ {
+ m_format = iso_format_extended_specifier;
+ }
+ void month_format(const char_type* const format_str) {
+ m_month_format = format_str;
+ }
+ void weekday_format(const char_type* const format_str) {
+ m_weekday_format = format_str;
+ }
+
+ void period_formatter(period_formatter_type per_formatter) {
+ m_period_formatter= per_formatter;
+ }
+ void special_values_formatter(const special_values_formatter_type& svf)
+ {
+ m_special_values_formatter = svf;
+ }
+ void short_weekday_names(const input_collection_type& short_names)
+ {
+ m_weekday_short_names = short_names;
+ }
+ void long_weekday_names(const input_collection_type& long_names)
+ {
+ m_weekday_long_names = long_names;
+ }
+
+ void short_month_names(const input_collection_type& short_names)
+ {
+ m_month_short_names = short_names;
+ }
+
+ void long_month_names(const input_collection_type& long_names)
+ {
+ m_month_long_names = long_names;
+ }
+
+ void date_gen_phrase_strings(const input_collection_type& new_strings,
+ typename date_gen_formatter_type::phrase_elements beg_pos=date_gen_formatter_type::first)
+ {
+ m_date_gen_formatter.elements(new_strings, beg_pos);
+ }
+
+ OutItrT put(OutItrT next,
+ std::ios_base& a_ios,
+ char_type fill_char,
+ const date_type& d) const
+ {
+ if (d.is_special()) {
+ return do_put_special(next, a_ios, fill_char, d.as_special());
+ }
+ //The following line of code required the date to support a to_tm function
+ return do_put_tm(next, a_ios, fill_char, to_tm(d), m_format);
+ }
+
+ OutItrT put(OutItrT next,
+ std::ios_base& a_ios,
+ char_type fill_char,
+ const duration_type& dd) const
+ {
+ if (dd.is_special()) {
+ return do_put_special(next, a_ios, fill_char, dd.get_rep().as_special());
+ }
+
+ typedef std::num_put<CharT, OutItrT> num_put;
+ if (std::has_facet<num_put>(a_ios.getloc())) {
+ return std::use_facet<num_put>(a_ios.getloc()).put(next, a_ios, fill_char, dd.get_rep().as_number());
+ }
+ else {
+ num_put* f = new num_put();
+ std::locale l = std::locale(a_ios.getloc(), f);
+ a_ios.imbue(l);
+ return f->put(next, a_ios, fill_char, dd.get_rep().as_number());
+ }
+
+ }
+
+
+ OutItrT put(OutItrT next,
+ std::ios_base& a_ios,
+ char_type fill_char,
+ const month_type& m) const
+ {
+ //if (d.is_special()) {
+ // return do_put_special(next, a_ios, fill_char, d.as_special());
+ //}
+ //The following line of code required the date to support a to_tm function
+ std::tm dtm = {};
+ dtm.tm_mon = m - 1;
+ return do_put_tm(next, a_ios, fill_char, dtm, m_month_format);
+ }
+
+ //! puts the day of month
+ OutItrT put(OutItrT next,
+ std::ios_base& a_ios,
+ char_type fill_char,
+ const day_type& day) const
+ {
+ std::tm dtm = {};
+ dtm.tm_mday = day.as_number();
+ char_type tmp[3] = {'%','d'};
+ string_type temp_format(tmp);
+ return do_put_tm(next, a_ios, fill_char, dtm, temp_format);
+ }
+
+ OutItrT put(OutItrT next,
+ std::ios_base& a_ios,
+ char_type fill_char,
+ const day_of_week_type& dow) const
+ {
+ //if (d.is_special()) {
+ // return do_put_special(next, a_ios, fill_char, d.as_special());
+ //}
+ //The following line of code required the date to support a to_tm function
+ std::tm dtm = {};
+ dtm.tm_wday = dow;
+ return do_put_tm(next, a_ios, fill_char, dtm, m_weekday_format);
+ }
+
+
+ OutItrT put(OutItrT next,
+ std::ios_base& a_ios,
+ char_type fill_char,
+ const period_type& p) const
+ {
+ return m_period_formatter.put_period(next, a_ios, fill_char, p, *this);
+ }
+
+ OutItrT put(OutItrT next,
+ std::ios_base& a_ios,
+ char_type fill_char,
+ const partial_date_type& pd) const
+ {
+ return m_date_gen_formatter.put_partial_date(next, a_ios, fill_char, pd, *this);
+ }
+
+ OutItrT put(OutItrT next,
+ std::ios_base& a_ios,
+ char_type fill_char,
+ const nth_kday_type& nkd) const
+ {
+ return m_date_gen_formatter.put_nth_kday(next, a_ios, fill_char, nkd, *this);
+ }
+
+ OutItrT put(OutItrT next,
+ std::ios_base& a_ios,
+ char_type fill_char,
+ const first_kday_type& fkd) const
+ {
+ return m_date_gen_formatter.put_first_kday(next, a_ios, fill_char, fkd, *this);
+ }
+
+ OutItrT put(OutItrT next,
+ std::ios_base& a_ios,
+ char_type fill_char,
+ const last_kday_type& lkd) const
+ {
+ return m_date_gen_formatter.put_last_kday(next, a_ios, fill_char, lkd, *this);
+ }
+
+ OutItrT put(OutItrT next,
+ std::ios_base& a_ios,
+ char_type fill_char,
+ const kday_before_type& fkb) const
+ {
+ return m_date_gen_formatter.put_kday_before(next, a_ios, fill_char, fkb, *this);
+ }
+
+ OutItrT put(OutItrT next,
+ std::ios_base& a_ios,
+ char_type fill_char,
+ const kday_after_type& fka) const
+ {
+ return m_date_gen_formatter.put_kday_after(next, a_ios, fill_char, fka, *this);
+ }
+
+ protected:
+ virtual OutItrT do_put_special(OutItrT next,
+ std::ios_base& /*a_ios*/,
+ char_type /*fill_char*/,
+ const boost::date_time::special_values sv) const
+ {
+ m_special_values_formatter.put_special(next, sv);
+ return next;
+ }
+ virtual OutItrT do_put_tm(OutItrT next,
+ std::ios_base& a_ios,
+ char_type fill_char,
+ const tm& tm_value,
+ string_type a_format) const
+ {
+ // update format string with custom names
+ if (m_weekday_long_names.size()) {
+ boost::algorithm::replace_all(a_format,
+ long_weekday_format,
+ m_weekday_long_names[tm_value.tm_wday]);
+ }
+ if (m_weekday_short_names.size()) {
+ boost::algorithm::replace_all(a_format,
+ short_weekday_format,
+ m_weekday_short_names[tm_value.tm_wday]);
+
+ }
+ if (m_month_long_names.size()) {
+ boost::algorithm::replace_all(a_format,
+ long_month_format,
+ m_month_long_names[tm_value.tm_mon]);
+ }
+ if (m_month_short_names.size()) {
+ boost::algorithm::replace_all(a_format,
+ short_month_format,
+ m_month_short_names[tm_value.tm_mon]);
+ }
+ // use time_put facet to create final string
+ const char_type* p_format = a_format.c_str();
+ return std::use_facet<std::time_put<CharT> >(a_ios.getloc()).put(next, a_ios,
+ fill_char,
+ &tm_value,
+ p_format,
+ p_format + a_format.size());
+ }
+ protected:
+ string_type m_format;
+ string_type m_month_format;
+ string_type m_weekday_format;
+ period_formatter_type m_period_formatter;
+ date_gen_formatter_type m_date_gen_formatter;
+ special_values_formatter_type m_special_values_formatter;
+ input_collection_type m_month_short_names;
+ input_collection_type m_month_long_names;
+ input_collection_type m_weekday_short_names;
+ input_collection_type m_weekday_long_names;
+ private:
+ };
+
+ template <class date_type, class CharT, class OutItrT>
+ std::locale::id date_facet<date_type, CharT, OutItrT>::id;
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_facet<date_type, CharT, OutItrT>::char_type
+ date_facet<date_type, CharT, OutItrT>::long_weekday_format[3] = {'%','A'};
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_facet<date_type, CharT, OutItrT>::char_type
+ date_facet<date_type, CharT, OutItrT>::short_weekday_format[3] = {'%','a'};
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_facet<date_type, CharT, OutItrT>::char_type
+ date_facet<date_type, CharT, OutItrT>::long_month_format[3] = {'%','B'};
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_facet<date_type, CharT, OutItrT>::char_type
+ date_facet<date_type, CharT, OutItrT>::short_month_format[3] = {'%','b'};
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_facet<date_type, CharT, OutItrT>::char_type
+ date_facet<date_type, CharT, OutItrT>::default_period_separator[4] = { ' ', '/', ' '};
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_facet<date_type, CharT, OutItrT>::char_type
+ date_facet<date_type, CharT, OutItrT>::standard_format_specifier[3] =
+ {'%', 'x' };
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_facet<date_type, CharT, OutItrT>::char_type
+ date_facet<date_type, CharT, OutItrT>::iso_format_specifier[7] =
+ {'%', 'Y', '%', 'm', '%', 'd' };
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_facet<date_type, CharT, OutItrT>::char_type
+ date_facet<date_type, CharT, OutItrT>::iso_format_extended_specifier[9] =
+ {'%', 'Y', '-', '%', 'm', '-', '%', 'd' };
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_facet<date_type, CharT, OutItrT>::char_type
+ date_facet<date_type, CharT, OutItrT>::default_date_format[9] =
+ {'%','Y','-','%','b','-','%','d'};
+
+
+
+ //! Input facet
+ template <class date_type,
+ class CharT,
+ class InItrT = std::istreambuf_iterator<CharT, std::char_traits<CharT> > >
+ class date_input_facet : public std::locale::facet {
+ public:
+ typedef typename date_type::duration_type duration_type;
+ // greg_weekday is gregorian_calendar::day_of_week_type
+ typedef typename date_type::day_of_week_type day_of_week_type;
+ typedef typename date_type::day_type day_type;
+ typedef typename date_type::month_type month_type;
+ typedef typename date_type::year_type year_type;
+ typedef boost::date_time::period<date_type,duration_type> period_type;
+ typedef std::basic_string<CharT> string_type;
+ typedef CharT char_type;
+ typedef boost::date_time::period_parser<date_type, CharT> period_parser_type;
+ typedef boost::date_time::special_values_parser<date_type,CharT> special_values_parser_type;
+ typedef std::vector<std::basic_string<CharT> > input_collection_type;
+ typedef format_date_parser<date_type, CharT> format_date_parser_type;
+ // date_generators stuff goes here
+ typedef date_generator_parser<date_type, CharT> date_gen_parser_type;
+ typedef partial_date<date_type> partial_date_type;
+ typedef nth_kday_of_month<date_type> nth_kday_type;
+ typedef first_kday_of_month<date_type> first_kday_type;
+ typedef last_kday_of_month<date_type> last_kday_type;
+ typedef first_kday_after<date_type> kday_after_type;
+ typedef first_kday_before<date_type> kday_before_type;
+
+ static const char_type long_weekday_format[3];
+ static const char_type short_weekday_format[3];
+ static const char_type long_month_format[3];
+ static const char_type short_month_format[3];
+ static const char_type four_digit_year_format[3];
+ static const char_type two_digit_year_format[3];
+ static const char_type default_period_separator[4];
+ static const char_type standard_format_specifier[3];
+ static const char_type iso_format_specifier[7];
+ static const char_type iso_format_extended_specifier[9];
+ static const char_type default_date_format[9]; // YYYY-Mon-DD
+ static std::locale::id id;
+
+ explicit date_input_facet(::size_t a_ref = 0)
+ : std::locale::facet(a_ref),
+ m_format(default_date_format),
+ m_month_format(short_month_format),
+ m_weekday_format(short_weekday_format),
+ m_year_format(four_digit_year_format),
+ m_parser(m_format, std::locale::classic())
+ // default period_parser & special_values_parser used
+ {}
+
+ explicit date_input_facet(const string_type& format_str,
+ ::size_t a_ref = 0)
+ : std::locale::facet(a_ref),
+ m_format(format_str),
+ m_month_format(short_month_format),
+ m_weekday_format(short_weekday_format),
+ m_year_format(four_digit_year_format),
+ m_parser(m_format, std::locale::classic())
+ // default period_parser & special_values_parser used
+ {}
+
+ explicit date_input_facet(const string_type& format_str,
+ const format_date_parser_type& date_parser,
+ const special_values_parser_type& sv_parser,
+ const period_parser_type& per_parser,
+ const date_gen_parser_type& date_gen_parser,
+ ::size_t ref_count = 0)
+ : std::locale::facet(ref_count),
+ m_format(format_str),
+ m_month_format(short_month_format),
+ m_weekday_format(short_weekday_format),
+ m_year_format(four_digit_year_format),
+ m_parser(date_parser),
+ m_date_gen_parser(date_gen_parser),
+ m_period_parser(per_parser),
+ m_sv_parser(sv_parser)
+ {}
+
+
+ void format(const char_type* const format_str) {
+ m_format = format_str;
+ }
+ virtual void set_iso_format()
+ {
+ m_format = iso_format_specifier;
+ }
+ virtual void set_iso_extended_format()
+ {
+ m_format = iso_format_extended_specifier;
+ }
+ void month_format(const char_type* const format_str) {
+ m_month_format = format_str;
+ }
+ void weekday_format(const char_type* const format_str) {
+ m_weekday_format = format_str;
+ }
+ void year_format(const char_type* const format_str) {
+ m_year_format = format_str;
+ }
+
+ void period_parser(period_parser_type per_parser) {
+ m_period_parser = per_parser;
+ }
+ void short_weekday_names(const input_collection_type& weekday_names)
+ {
+ m_parser.short_weekday_names(weekday_names);
+ }
+ void long_weekday_names(const input_collection_type& weekday_names)
+ {
+ m_parser.long_weekday_names(weekday_names);
+ }
+
+ void short_month_names(const input_collection_type& month_names)
+ {
+ m_parser.short_month_names(month_names);
+ }
+
+ void long_month_names(const input_collection_type& month_names)
+ {
+ m_parser.long_month_names(month_names);
+ }
+
+ void date_gen_element_strings(const input_collection_type& col)
+ {
+ m_date_gen_parser.element_strings(col);
+ }
+ void date_gen_element_strings(const string_type& first,
+ const string_type& second,
+ const string_type& third,
+ const string_type& fourth,
+ const string_type& fifth,
+ const string_type& last,
+ const string_type& before,
+ const string_type& after,
+ const string_type& of)
+
+ {
+ m_date_gen_parser.element_strings(first,second,third,fourth,fifth,last,before,after,of);
+ }
+
+ void special_values_parser(special_values_parser_type sv_parser)
+ {
+ m_sv_parser = sv_parser;
+ }
+
+ InItrT get(InItrT& from,
+ InItrT& to,
+ std::ios_base& /*a_ios*/,
+ date_type& d) const
+ {
+ d = m_parser.parse_date(from, to, m_format, m_sv_parser);
+ return from;
+ }
+ InItrT get(InItrT& from,
+ InItrT& to,
+ std::ios_base& /*a_ios*/,
+ month_type& m) const
+ {
+ m = m_parser.parse_month(from, to, m_month_format);
+ return from;
+ }
+ InItrT get(InItrT& from,
+ InItrT& to,
+ std::ios_base& /*a_ios*/,
+ day_of_week_type& wd) const
+ {
+ wd = m_parser.parse_weekday(from, to, m_weekday_format);
+ return from;
+ }
+ //! Expects 1 or 2 digit day range: 1-31
+ InItrT get(InItrT& from,
+ InItrT& to,
+ std::ios_base& /*a_ios*/,
+ day_type& d) const
+ {
+ d = m_parser.parse_var_day_of_month(from, to);
+ return from;
+ }
+ InItrT get(InItrT& from,
+ InItrT& to,
+ std::ios_base& /*a_ios*/,
+ year_type& y) const
+ {
+ y = m_parser.parse_year(from, to, m_year_format);
+ return from;
+ }
+ InItrT get(InItrT& from,
+ InItrT& to,
+ std::ios_base& a_ios,
+ duration_type& dd) const
+ {
+ // skip leading whitespace
+ while(std::isspace(*from) && from != to) { ++from; }
+
+ /* num_get.get() will always consume the first character if it
+ * is a sign indicator (+/-). Special value strings may begin
+ * with one of these signs so we'll need a copy of it
+ * in case num_get.get() fails. */
+ char_type c = '\0';
+ // TODO Are these characters somewhere in the locale?
+ if(*from == '-' || *from == '+') {
+ c = *from;
+ }
+ typedef std::num_get<CharT, InItrT> num_get;
+ typename duration_type::duration_rep_type val = 0;
+ std::ios_base::iostate err = std::ios_base::goodbit;
+
+ if (std::has_facet<num_get>(a_ios.getloc())) {
+ from = std::use_facet<num_get>(a_ios.getloc()).get(from, to, a_ios, err, val);
+ }
+ else {
+ num_get* ng = new num_get();
+ std::locale l = std::locale(a_ios.getloc(), ng);
+ a_ios.imbue(l);
+ from = ng->get(from, to, a_ios, err, val);
+ }
+ if(err & std::ios_base::failbit){
+ typedef typename special_values_parser_type::match_results match_results;
+ match_results mr;
+ if(c == '-' || c == '+') { // was the first character consumed?
+ mr.cache += c;
+ }
+ m_sv_parser.match(from, to, mr);
+ if(mr.current_match == match_results::PARSE_ERROR) {
+ boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"));
+ BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return from); // should never reach
+ }
+ dd = duration_type(static_cast<special_values>(mr.current_match));
+ }
+ else {
+ dd = duration_type(val);
+ }
+ return from;
+ }
+ InItrT get(InItrT& from,
+ InItrT& to,
+ std::ios_base& a_ios,
+ period_type& p) const
+ {
+ p = m_period_parser.get_period(from, to, a_ios, p, duration_type::unit(), *this);
+ return from;
+ }
+ InItrT get(InItrT& from,
+ InItrT& to,
+ std::ios_base& a_ios,
+ nth_kday_type& nkd) const
+ {
+ nkd = m_date_gen_parser.get_nth_kday_type(from, to, a_ios, *this);
+ return from;
+ }
+ InItrT get(InItrT& from,
+ InItrT& to,
+ std::ios_base& a_ios,
+ partial_date_type& pd) const
+ {
+
+ pd = m_date_gen_parser.get_partial_date_type(from, to, a_ios, *this);
+ return from;
+ }
+ InItrT get(InItrT& from,
+ InItrT& to,
+ std::ios_base& a_ios,
+ first_kday_type& fkd) const
+ {
+ fkd = m_date_gen_parser.get_first_kday_type(from, to, a_ios, *this);
+ return from;
+ }
+ InItrT get(InItrT& from,
+ InItrT& to,
+ std::ios_base& a_ios,
+ last_kday_type& lkd) const
+ {
+ lkd = m_date_gen_parser.get_last_kday_type(from, to, a_ios, *this);
+ return from;
+ }
+ InItrT get(InItrT& from,
+ InItrT& to,
+ std::ios_base& a_ios,
+ kday_before_type& fkb) const
+ {
+ fkb = m_date_gen_parser.get_kday_before_type(from, to, a_ios, *this);
+ return from;
+ }
+ InItrT get(InItrT& from,
+ InItrT& to,
+ std::ios_base& a_ios,
+ kday_after_type& fka) const
+ {
+ fka = m_date_gen_parser.get_kday_after_type(from, to, a_ios, *this);
+ return from;
+ }
+
+ protected:
+ string_type m_format;
+ string_type m_month_format;
+ string_type m_weekday_format;
+ string_type m_year_format;
+ format_date_parser_type m_parser;
+ date_gen_parser_type m_date_gen_parser;
+ period_parser_type m_period_parser;
+ special_values_parser_type m_sv_parser;
+ private:
+ };
+
+
+ template <class date_type, class CharT, class OutItrT>
+ std::locale::id date_input_facet<date_type, CharT, OutItrT>::id;
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+ date_input_facet<date_type, CharT, OutItrT>::long_weekday_format[3] = {'%','A'};
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+ date_input_facet<date_type, CharT, OutItrT>::short_weekday_format[3] = {'%','a'};
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+ date_input_facet<date_type, CharT, OutItrT>::long_month_format[3] = {'%','B'};
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+ date_input_facet<date_type, CharT, OutItrT>::short_month_format[3] = {'%','b'};
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+ date_input_facet<date_type, CharT, OutItrT>::four_digit_year_format[3] = {'%','Y'};
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+ date_input_facet<date_type, CharT, OutItrT>::two_digit_year_format[3] = {'%','y'};
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+ date_input_facet<date_type, CharT, OutItrT>::default_period_separator[4] = { ' ', '/', ' '};
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+ date_input_facet<date_type, CharT, OutItrT>::standard_format_specifier[3] =
+ {'%', 'x' };
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+ date_input_facet<date_type, CharT, OutItrT>::iso_format_specifier[7] =
+ {'%', 'Y', '%', 'm', '%', 'd' };
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+ date_input_facet<date_type, CharT, OutItrT>::iso_format_extended_specifier[9] =
+ {'%', 'Y', '-', '%', 'm', '-', '%', 'd' };
+
+ template <class date_type, class CharT, class OutItrT>
+ const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+ date_input_facet<date_type, CharT, OutItrT>::default_date_format[9] =
+ {'%','Y','-','%','b','-','%','d'};
+
+} } // namespaces
+
+
+#endif
diff --git a/ext/boost/date_time/date_format_simple.hpp b/ext/boost/date_time/date_format_simple.hpp
new file mode 100644
index 0000000000..be21ce4a57
--- /dev/null
+++ b/ext/boost/date_time/date_format_simple.hpp
@@ -0,0 +1,159 @@
+#ifndef DATE_TIME_SIMPLE_FORMAT_HPP___
+#define DATE_TIME_SIMPLE_FORMAT_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/parse_format_base.hpp"
+
+namespace boost {
+namespace date_time {
+
+//! Class to provide simple basic formatting rules
+template<class charT>
+class simple_format {
+public:
+
+ //! String used printed is date is invalid
+ static const charT* not_a_date()
+ {
+ return "not-a-date-time";
+ }
+ //! String used to for positive infinity value
+ static const charT* pos_infinity()
+ {
+ return "+infinity";
+ }
+ //! String used to for positive infinity value
+ static const charT* neg_infinity()
+ {
+ return "-infinity";
+ }
+ //! Describe month format
+ static month_format_spec month_format()
+ {
+ return month_as_short_string;
+ }
+ static ymd_order_spec date_order()
+ {
+ return ymd_order_iso; //YYYY-MM-DD
+ }
+ //! This format uses '-' to separate date elements
+ static bool has_date_sep_chars()
+ {
+ return true;
+ }
+ //! Char to sep?
+ static charT year_sep_char()
+ {
+ return '-';
+ }
+ //! char between year-month
+ static charT month_sep_char()
+ {
+ return '-';
+ }
+ //! Char to separate month-day
+ static charT day_sep_char()
+ {
+ return '-';
+ }
+ //! char between date-hours
+ static charT hour_sep_char()
+ {
+ return ' ';
+ }
+ //! char between hour and minute
+ static charT minute_sep_char()
+ {
+ return ':';
+ }
+ //! char for second
+ static charT second_sep_char()
+ {
+ return ':';
+ }
+
+};
+
+#ifndef BOOST_NO_STD_WSTRING
+
+//! Specialization of formmating rules for wchar_t
+template<>
+class simple_format<wchar_t> {
+public:
+
+ //! String used printed is date is invalid
+ static const wchar_t* not_a_date()
+ {
+ return L"not-a-date-time";
+ }
+ //! String used to for positive infinity value
+ static const wchar_t* pos_infinity()
+ {
+ return L"+infinity";
+ }
+ //! String used to for positive infinity value
+ static const wchar_t* neg_infinity()
+ {
+ return L"-infinity";
+ }
+ //! Describe month format
+ static month_format_spec month_format()
+ {
+ return month_as_short_string;
+ }
+ static ymd_order_spec date_order()
+ {
+ return ymd_order_iso; //YYYY-MM-DD
+ }
+ //! This format uses '-' to separate date elements
+ static bool has_date_sep_chars()
+ {
+ return true;
+ }
+ //! Char to sep?
+ static wchar_t year_sep_char()
+ {
+ return '-';
+ }
+ //! char between year-month
+ static wchar_t month_sep_char()
+ {
+ return '-';
+ }
+ //! Char to separate month-day
+ static wchar_t day_sep_char()
+ {
+ return '-';
+ }
+ //! char between date-hours
+ static wchar_t hour_sep_char()
+ {
+ return ' ';
+ }
+ //! char between hour and minute
+ static wchar_t minute_sep_char()
+ {
+ return ':';
+ }
+ //! char for second
+ static wchar_t second_sep_char()
+ {
+ return ':';
+ }
+
+};
+
+#endif // BOOST_NO_STD_WSTRING
+} } //namespace date_time
+
+
+
+
+#endif
diff --git a/ext/boost/date_time/date_formatting.hpp b/ext/boost/date_time/date_formatting.hpp
new file mode 100644
index 0000000000..abe547a5f7
--- /dev/null
+++ b/ext/boost/date_time/date_formatting.hpp
@@ -0,0 +1,127 @@
+#ifndef DATE_TIME_DATE_FORMATTING_HPP___
+#define DATE_TIME_DATE_FORMATTING_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+/* NOTE: "formatter" code for older compilers, ones that define
+ * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in
+ * date_formatting_limited.hpp
+ */
+
+namespace boost {
+namespace date_time {
+
+ //! Formats a month as as string into an ostream
+ template<class month_type, class format_type, class charT=char>
+ class month_formatter
+ {
+ typedef std::basic_ostream<charT> ostream_type;
+ public:
+ //! Formats a month as as string into an ostream
+ /*! This function demands that month_type provide
+ * functions for converting to short and long strings
+ * if that capability is used.
+ */
+ static ostream_type& format_month(const month_type& month,
+ ostream_type &os)
+ {
+ switch (format_type::month_format())
+ {
+ case month_as_short_string:
+ {
+ os << month.as_short_string();
+ break;
+ }
+ case month_as_long_string:
+ {
+ os << month.as_long_string();
+ break;
+ }
+ case month_as_integer:
+ {
+ os << std::setw(2) << std::setfill(os.widen('0')) << month.as_number();
+ break;
+ }
+
+ }
+ return os;
+ } // format_month
+ };
+
+
+ //! Convert ymd to a standard string formatting policies
+ template<class ymd_type, class format_type, class charT=char>
+ class ymd_formatter
+ {
+ public:
+ //! Convert ymd to a standard string formatting policies
+ /*! This is standard code for handling date formatting with
+ * year-month-day based date information. This function
+ * uses the format_type to control whether the string will
+ * contain separator characters, and if so what the character
+ * will be. In addtion, it can format the month as either
+ * an integer or a string as controled by the formatting
+ * policy
+ */
+ static std::basic_string<charT> ymd_to_string(ymd_type ymd)
+ {
+ typedef typename ymd_type::month_type month_type;
+ std::basic_ostringstream<charT> ss;
+ ss << ymd.year;
+ if (format_type::has_date_sep_chars()) {
+ ss << format_type::month_sep_char();
+ }
+ //this name is a bit ugly, oh well....
+ month_formatter<month_type,format_type,charT>::format_month(ymd.month, ss);
+ if (format_type::has_date_sep_chars()) {
+ ss << format_type::day_sep_char();
+ }
+ ss << std::setw(2) << std::setfill(ss.widen('0'))
+ << ymd.day;
+ return ss.str();
+ }
+ };
+
+
+ //! Convert a date to string using format policies
+ template<class date_type, class format_type, class charT=char>
+ class date_formatter
+ {
+ public:
+ typedef std::basic_string<charT> string_type;
+ //! Convert to a date to standard string using format policies
+ static string_type date_to_string(date_type d)
+ {
+ typedef typename date_type::ymd_type ymd_type;
+ if (d.is_not_a_date()) {
+ return string_type(format_type::not_a_date());
+ }
+ if (d.is_neg_infinity()) {
+ return string_type(format_type::neg_infinity());
+ }
+ if (d.is_pos_infinity()) {
+ return string_type(format_type::pos_infinity());
+ }
+ ymd_type ymd = d.year_month_day();
+ return ymd_formatter<ymd_type, format_type, charT>::ymd_to_string(ymd);
+ }
+ };
+
+
+} } //namespace date_time
+
+
+#endif
+
diff --git a/ext/boost/date_time/date_formatting_limited.hpp b/ext/boost/date_time/date_formatting_limited.hpp
new file mode 100644
index 0000000000..38fee07b91
--- /dev/null
+++ b/ext/boost/date_time/date_formatting_limited.hpp
@@ -0,0 +1,121 @@
+#ifndef DATE_TIME_DATE_FORMATTING_LIMITED_HPP___
+#define DATE_TIME_DATE_FORMATTING_LIMITED_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+
+namespace boost {
+namespace date_time {
+
+ //! Formats a month as as string into an ostream
+ template<class month_type, class format_type>
+ class month_formatter
+ {
+ public:
+ //! Formats a month as as string into an ostream
+ /*! This function demands that month_type provide
+ * functions for converting to short and long strings
+ * if that capability is used.
+ */
+ static std::ostream& format_month(const month_type& month,
+ std::ostream& os)
+ {
+ switch (format_type::month_format())
+ {
+ case month_as_short_string:
+ {
+ os << month.as_short_string();
+ break;
+ }
+ case month_as_long_string:
+ {
+ os << month.as_long_string();
+ break;
+ }
+ case month_as_integer:
+ {
+ os << std::setw(2) << std::setfill('0') << month.as_number();
+ break;
+ }
+
+ }
+ return os;
+ } // format_month
+ };
+
+
+ //! Convert ymd to a standard string formatting policies
+ template<class ymd_type, class format_type>
+ class ymd_formatter
+ {
+ public:
+ //! Convert ymd to a standard string formatting policies
+ /*! This is standard code for handling date formatting with
+ * year-month-day based date information. This function
+ * uses the format_type to control whether the string will
+ * contain separator characters, and if so what the character
+ * will be. In addtion, it can format the month as either
+ * an integer or a string as controled by the formatting
+ * policy
+ */
+ static std::string ymd_to_string(ymd_type ymd)
+ {
+ typedef typename ymd_type::month_type month_type;
+ std::ostringstream ss;
+ ss << ymd.year;
+ if (format_type::has_date_sep_chars()) {
+ ss << format_type::month_sep_char();
+ }
+ //this name is a bit ugly, oh well....
+ month_formatter<month_type,format_type>::format_month(ymd.month, ss);
+ if (format_type::has_date_sep_chars()) {
+ ss << format_type::day_sep_char();
+ }
+ ss << std::setw(2) << std::setfill('0')
+ << ymd.day;
+ return ss.str();
+ }
+ };
+
+
+ //! Convert a date to string using format policies
+ template<class date_type, class format_type>
+ class date_formatter
+ {
+ public:
+ //! Convert to a date to standard string using format policies
+ static std::string date_to_string(date_type d)
+ {
+ typedef typename date_type::ymd_type ymd_type;
+ if (d.is_not_a_date()) {
+ return format_type::not_a_date();
+ }
+ if (d.is_neg_infinity()) {
+ return format_type::neg_infinity();
+ }
+ if (d.is_pos_infinity()) {
+ return format_type::pos_infinity();
+ }
+ ymd_type ymd = d.year_month_day();
+ return ymd_formatter<ymd_type, format_type>::ymd_to_string(ymd);
+ }
+ };
+
+
+} } //namespace date_time
+
+
+#endif
+
diff --git a/ext/boost/date_time/date_formatting_locales.hpp b/ext/boost/date_time/date_formatting_locales.hpp
new file mode 100644
index 0000000000..4ac9c4e401
--- /dev/null
+++ b/ext/boost/date_time/date_formatting_locales.hpp
@@ -0,0 +1,233 @@
+#ifndef DATE_TIME_DATE_FORMATTING_LOCALES_HPP___
+#define DATE_TIME_DATE_FORMATTING_LOCALES_HPP___
+
+/* 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) $
+ */
+
+
+#include "boost/date_time/locale_config.hpp" // set BOOST_DATE_TIME_NO_LOCALE
+
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/date_names_put.hpp"
+#include "boost/date_time/parse_format_base.hpp"
+//#include <string>
+#include <sstream>
+#include <iomanip>
+
+
+namespace boost {
+namespace date_time {
+
+ //! Formats a month as as string into an ostream
+ template<class facet_type,
+ class charT = char>
+ class ostream_month_formatter
+ {
+ public:
+ typedef typename facet_type::month_type month_type;
+ typedef std::basic_ostream<charT> ostream_type;
+
+ //! Formats a month as as string into an output iterator
+ static void format_month(const month_type& month,
+ ostream_type& os,
+ const facet_type& f)
+ {
+
+ switch (f.month_format())
+ {
+ case month_as_short_string:
+ {
+ std::ostreambuf_iterator<charT> oitr(os);
+ f.put_month_short(oitr, month.as_enum());
+ break;
+ }
+ case month_as_long_string:
+ {
+ std::ostreambuf_iterator<charT> oitr(os);
+ f.put_month_long(oitr, month.as_enum());
+ break;
+ }
+ case month_as_integer:
+ {
+ charT fill_char = '0';
+ os << std::setw(2) << std::setfill(fill_char) << month.as_number();
+ break;
+ }
+
+ }
+ } // format_month
+
+ };
+
+
+ //! Formats a weekday
+ template<class weekday_type,
+ class facet_type,
+ class charT = char>
+ class ostream_weekday_formatter
+ {
+ public:
+ typedef typename facet_type::month_type month_type;
+ typedef std::basic_ostream<charT> ostream_type;
+
+ //! Formats a month as as string into an output iterator
+ static void format_weekday(const weekday_type& wd,
+ ostream_type& os,
+ const facet_type& f,
+ bool as_long_string)
+ {
+
+ std::ostreambuf_iterator<charT> oitr(os);
+ if (as_long_string) {
+ f.put_weekday_long(oitr, wd.as_enum());
+ }
+ else {
+ f.put_weekday_short(oitr, wd.as_enum());
+ }
+
+ } // format_weekday
+
+ };
+
+
+ //! Convert ymd to a standard string formatting policies
+ template<class ymd_type,
+ class facet_type,
+ class charT = char>
+ class ostream_ymd_formatter
+ {
+ public:
+ typedef typename ymd_type::month_type month_type;
+ typedef ostream_month_formatter<facet_type, charT> month_formatter_type;
+ typedef std::basic_ostream<charT> ostream_type;
+ typedef std::basic_string<charT> foo_type;
+
+ //! Convert ymd to a standard string formatting policies
+ /*! This is standard code for handling date formatting with
+ * year-month-day based date information. This function
+ * uses the format_type to control whether the string will
+ * contain separator characters, and if so what the character
+ * will be. In addtion, it can format the month as either
+ * an integer or a string as controled by the formatting
+ * policy
+ */
+ // static string_type ymd_to_string(ymd_type ymd)
+// {
+// std::ostringstream ss;
+// facet_type dnp;
+// ymd_put(ymd, ss, dnp);
+// return ss.str();
+// }
+
+
+ // Put ymd to ostream -- part of ostream refactor
+ static void ymd_put(ymd_type ymd,
+ ostream_type& os,
+ const facet_type& f)
+ {
+ std::ostreambuf_iterator<charT> oitr(os);
+ charT fill_char = '0';
+ switch (f.date_order()) {
+ case ymd_order_iso: {
+ os << ymd.year;
+ if (f.has_date_sep_chars()) {
+ f.month_sep_char(oitr);
+ }
+ month_formatter_type::format_month(ymd.month, os, f);
+ if (f.has_date_sep_chars()) {
+ f.day_sep_char(oitr);
+ }
+ os << std::setw(2) << std::setfill(fill_char)
+ << ymd.day;
+ break;
+ }
+ case ymd_order_us: {
+ month_formatter_type::format_month(ymd.month, os, f);
+ if (f.has_date_sep_chars()) {
+ f.day_sep_char(oitr);
+ }
+ os << std::setw(2) << std::setfill(fill_char)
+ << ymd.day;
+ if (f.has_date_sep_chars()) {
+ f.month_sep_char(oitr);
+ }
+ os << ymd.year;
+ break;
+ }
+ case ymd_order_dmy: {
+ os << std::setw(2) << std::setfill(fill_char)
+ << ymd.day;
+ if (f.has_date_sep_chars()) {
+ f.day_sep_char(oitr);
+ }
+ month_formatter_type::format_month(ymd.month, os, f);
+ if (f.has_date_sep_chars()) {
+ f.month_sep_char(oitr);
+ }
+ os << ymd.year;
+ break;
+ }
+ }
+ }
+ };
+
+
+ //! Convert a date to string using format policies
+ template<class date_type,
+ class facet_type,
+ class charT = char>
+ class ostream_date_formatter
+ {
+ public:
+ typedef std::basic_ostream<charT> ostream_type;
+ typedef typename date_type::ymd_type ymd_type;
+
+ //! Put date into an ostream
+ static void date_put(const date_type& d,
+ ostream_type& os,
+ const facet_type& f)
+ {
+ special_values sv = d.as_special();
+ if (sv == not_special) {
+ ymd_type ymd = d.year_month_day();
+ ostream_ymd_formatter<ymd_type, facet_type, charT>::ymd_put(ymd, os, f);
+ }
+ else { // output a special value
+ std::ostreambuf_iterator<charT> coi(os);
+ f.put_special_value(coi, sv);
+ }
+ }
+
+
+ //! Put date into an ostream
+ static void date_put(const date_type& d,
+ ostream_type& os)
+ {
+ //retrieve the local from the ostream
+ std::locale locale = os.getloc();
+ if (std::has_facet<facet_type>(locale)) {
+ const facet_type& f = std::use_facet<facet_type>(locale);
+ date_put(d, os, f);
+ }
+ else {
+ //default to something sensible if no facet installed
+ facet_type default_facet;
+ date_put(d, os, default_facet);
+ }
+ } // date_to_ostream
+ }; //class date_formatter
+
+
+} } //namespace date_time
+
+#endif
+
+#endif
+
diff --git a/ext/boost/date_time/date_generator_formatter.hpp b/ext/boost/date_time/date_generator_formatter.hpp
new file mode 100644
index 0000000000..88cd7e1aba
--- /dev/null
+++ b/ext/boost/date_time/date_generator_formatter.hpp
@@ -0,0 +1,265 @@
+#ifndef _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___
+#define _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___
+
+/* Copyright (c) 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-11-13 14:05:31 -0500 (Thu, 13 Nov 2008) $
+ */
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <algorithm>
+#include "boost/date_time/date_generators.hpp"
+
+namespace boost {
+namespace date_time {
+
+ //! Formats date_generators for output
+ /*! Formatting of date_generators follows specific orders for the
+ * various types of date_generators.
+ * - partial_date => "dd Month"
+ * - nth_day_of_the_week_in_month => "nth weekday of month"
+ * - first_day_of_the_week_in_month => "first weekday of month"
+ * - last_day_of_the_week_in_month => "last weekday of month"
+ * - first_day_of_the_week_after => "weekday after"
+ * - first_day_of_the_week_before => "weekday before"
+ * While the order of the elements in these phrases cannot be changed,
+ * the elements themselves can be. Weekday and Month get their formats
+ * and names from the date_facet. The remaining elements are stored in
+ * the date_generator_formatter and can be customized upon construction
+ * or via a member function. The default elements are those shown in the
+ * examples above.
+ */
+ template <class date_type, class CharT, class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
+ class date_generator_formatter {
+ public:
+ typedef partial_date<date_type> partial_date_type;
+ typedef nth_kday_of_month<date_type> nth_kday_type;
+ typedef first_kday_of_month<date_type> first_kday_type;
+ typedef last_kday_of_month<date_type> last_kday_type;
+ typedef first_kday_after<date_type> kday_after_type;
+ typedef first_kday_before<date_type> kday_before_type;
+
+ typedef CharT char_type;
+ typedef std::basic_string<char_type> string_type;
+ typedef std::vector<string_type> collection_type;
+ static const char_type first_string[6];
+ static const char_type second_string[7];
+ static const char_type third_string[6];
+ static const char_type fourth_string[7];
+ static const char_type fifth_string[6];
+ static const char_type last_string[5];
+ static const char_type before_string[8];
+ static const char_type after_string[6];
+ static const char_type of_string[3];
+
+ enum phrase_elements {first=0, second, third, fourth, fifth, last,
+ before, after, of, number_of_phrase_elements};
+
+ //! Default format elements used
+ date_generator_formatter()
+ {
+ phrase_strings.reserve(number_of_phrase_elements);
+ phrase_strings.push_back(string_type(first_string));
+ phrase_strings.push_back(string_type(second_string));
+ phrase_strings.push_back(string_type(third_string));
+ phrase_strings.push_back(string_type(fourth_string));
+ phrase_strings.push_back(string_type(fifth_string));
+ phrase_strings.push_back(string_type(last_string));
+ phrase_strings.push_back(string_type(before_string));
+ phrase_strings.push_back(string_type(after_string));
+ phrase_strings.push_back(string_type(of_string));
+ }
+
+ //! Constructor that allows for a custom set of phrase elements
+ date_generator_formatter(const string_type& first_str,
+ const string_type& second_str,
+ const string_type& third_str,
+ const string_type& fourth_str,
+ const string_type& fifth_str,
+ const string_type& last_str,
+ const string_type& before_str,
+ const string_type& after_str,
+ const string_type& of_str)
+ {
+ phrase_strings.reserve(number_of_phrase_elements);
+ phrase_strings.push_back(first_str);
+ phrase_strings.push_back(second_str);
+ phrase_strings.push_back(third_str);
+ phrase_strings.push_back(fourth_str);
+ phrase_strings.push_back(fifth_str);
+ phrase_strings.push_back(last_str);
+ phrase_strings.push_back(before_str);
+ phrase_strings.push_back(after_str);
+ phrase_strings.push_back(of_str);
+ }
+
+ //! Replace the set of phrase elements with those contained in new_strings
+ /*! The order of the strings in the given collection is important.
+ * They must follow:
+ * - first, second, third, fourth, fifth, last, before, after, of.
+ *
+ * It is not necessary to send in a complete set if only a few
+ * elements are to be replaced as long as the correct beg_pos is used.
+ *
+ * Ex: To keep the default first through fifth elements, but replace
+ * the rest with a collection of:
+ * - "final", "prior", "following", "in".
+ * The beg_pos of date_generator_formatter::last would be used.
+ */
+ void elements(const collection_type& new_strings,
+ phrase_elements beg_pos=first)
+ {
+ if(beg_pos < number_of_phrase_elements) {
+ typename collection_type::iterator itr = phrase_strings.begin();
+ itr += beg_pos;
+ std::copy(new_strings.begin(), new_strings.end(),
+ itr);
+ //phrase_strings.begin());
+ }
+ }
+
+ //!Put a partial_date => "dd Month"
+ template<class facet_type>
+ OutItrT put_partial_date(OutItrT next, std::ios_base& a_ios,
+ CharT a_fill, const partial_date_type& pd,
+ const facet_type& facet) const
+ {
+ facet.put(next, a_ios, a_fill, pd.day());
+ next = a_fill; //TODO change this ???
+ facet.put(next, a_ios, a_fill, pd.month());
+ return next;
+ }
+
+ //! Put an nth_day_of_the_week_in_month => "nth weekday of month"
+ template<class facet_type>
+ OutItrT put_nth_kday(OutItrT next, std::ios_base& a_ios,
+ CharT a_fill, const nth_kday_type& nkd,
+ const facet_type& facet) const
+ {
+ put_string(next, phrase_strings[nkd.nth_week() -1]);
+ next = a_fill; //TODO change this ???
+ facet.put(next, a_ios, a_fill, nkd.day_of_week());
+ next = a_fill; //TODO change this ???
+ put_string(next, string_type(of_string));
+ next = a_fill; //TODO change this ???
+ facet.put(next, a_ios, a_fill, nkd.month());
+ return next;
+ }
+
+ //! Put a first_day_of_the_week_in_month => "first weekday of month"
+ template<class facet_type>
+ OutItrT put_first_kday(OutItrT next, std::ios_base& a_ios,
+ CharT a_fill, const first_kday_type& fkd,
+ const facet_type& facet) const
+ {
+ put_string(next, phrase_strings[first]);
+ next = a_fill; //TODO change this ???
+ facet.put(next, a_ios, a_fill, fkd.day_of_week());
+ next = a_fill; //TODO change this ???
+ put_string(next, string_type(of_string));
+ next = a_fill; //TODO change this ???
+ facet.put(next, a_ios, a_fill, fkd.month());
+ return next;
+ }
+
+ //! Put a last_day_of_the_week_in_month => "last weekday of month"
+ template<class facet_type>
+ OutItrT put_last_kday(OutItrT next, std::ios_base& a_ios,
+ CharT a_fill, const last_kday_type& lkd,
+ const facet_type& facet) const
+ {
+ put_string(next, phrase_strings[last]);
+ next = a_fill; //TODO change this ???
+ facet.put(next, a_ios, a_fill, lkd.day_of_week());
+ next = a_fill; //TODO change this ???
+ put_string(next, string_type(of_string));
+ next = a_fill; //TODO change this ???
+ facet.put(next, a_ios, a_fill, lkd.month());
+ return next;
+ }
+
+ //! Put a first_day_of_the_week_before => "weekday before"
+ template<class facet_type>
+ OutItrT put_kday_before(OutItrT next, std::ios_base& a_ios,
+ CharT a_fill, const kday_before_type& fkb,
+ const facet_type& facet) const
+ {
+ facet.put(next, a_ios, a_fill, fkb.day_of_week());
+ next = a_fill; //TODO change this ???
+ put_string(next, phrase_strings[before]);
+ return next;
+ }
+
+ //! Put a first_day_of_the_week_after => "weekday after"
+ template<class facet_type>
+ OutItrT put_kday_after(OutItrT next, std::ios_base& a_ios,
+ CharT a_fill, const kday_after_type& fka,
+ const facet_type& facet) const
+ {
+ facet.put(next, a_ios, a_fill, fka.day_of_week());
+ next = a_fill; //TODO change this ???
+ put_string(next, phrase_strings[after]);
+ return next;
+ }
+
+
+ private:
+ collection_type phrase_strings;
+
+ //! helper function to put the various member string into stream
+ OutItrT put_string(OutItrT next, const string_type& str) const
+ {
+ typename string_type::const_iterator itr = str.begin();
+ while(itr != str.end()) {
+ *next = *itr;
+ ++itr;
+ ++next;
+ }
+ return next;
+ }
+ };
+
+ template<class date_type, class CharT, class OutItrT>
+ const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+ date_generator_formatter<date_type, CharT, OutItrT>::first_string[6] =
+ {'f','i','r','s','t'};
+ template<class date_type, class CharT, class OutItrT>
+ const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+ date_generator_formatter<date_type, CharT, OutItrT>::second_string[7] =
+ {'s','e','c','o','n','d'};
+ template<class date_type, class CharT, class OutItrT>
+ const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+ date_generator_formatter<date_type, CharT, OutItrT>::third_string[6] =
+ {'t','h','i','r','d'};
+ template<class date_type, class CharT, class OutItrT>
+ const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+ date_generator_formatter<date_type, CharT, OutItrT>::fourth_string[7] =
+ {'f','o','u','r','t','h'};
+ template<class date_type, class CharT, class OutItrT>
+ const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+ date_generator_formatter<date_type, CharT, OutItrT>::fifth_string[6] =
+ {'f','i','f','t','h'};
+ template<class date_type, class CharT, class OutItrT>
+ const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+ date_generator_formatter<date_type, CharT, OutItrT>::last_string[5] =
+ {'l','a','s','t'};
+ template<class date_type, class CharT, class OutItrT>
+ const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+ date_generator_formatter<date_type, CharT, OutItrT>::before_string[8] =
+ {'b','e','f','o','r','e'};
+ template<class date_type, class CharT, class OutItrT>
+ const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+ date_generator_formatter<date_type, CharT, OutItrT>::after_string[6] =
+ {'a','f','t','e','r'};
+ template<class date_type, class CharT, class OutItrT>
+ const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+ date_generator_formatter<date_type, CharT, OutItrT>::of_string[3] =
+ {'o','f'};
+} } // namespaces
+
+#endif // _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___
diff --git a/ext/boost/date_time/date_generator_parser.hpp b/ext/boost/date_time/date_generator_parser.hpp
new file mode 100644
index 0000000000..f11eb42d52
--- /dev/null
+++ b/ext/boost/date_time/date_generator_parser.hpp
@@ -0,0 +1,330 @@
+
+#ifndef DATE_TIME_DATE_GENERATOR_PARSER_HPP__
+#define DATE_TIME_DATE_GENERATOR_PARSER_HPP__
+
+/* Copyright (c) 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-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <string>
+#include <vector>
+#include <iterator> // istreambuf_iterator
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/string_parse_tree.hpp>
+#include <boost/date_time/date_generators.hpp>
+#include <boost/date_time/format_date_parser.hpp>
+
+namespace boost { namespace date_time {
+
+ //! Class for date_generator parsing
+ /*! The elements of a date_generator "phrase" are parsed from the input stream in a
+ * particular order. All elements are required and the order in which they appear
+ * cannot change, however, the elements themselves can be changed. The default
+ * elements and their order are as follows:
+ *
+ * - partial_date => "dd Month"
+ * - nth_day_of_the_week_in_month => "nth weekday of month"
+ * - first_day_of_the_week_in_month => "first weekday of month"
+ * - last_day_of_the_week_in_month => "last weekday of month"
+ * - first_day_of_the_week_after => "weekday after"
+ * - first_day_of_the_week_before => "weekday before"
+ *
+ * Weekday and Month names and formats are handled via the date_input_facet.
+ *
+ */
+ template<class date_type, typename charT>
+ class date_generator_parser
+ {
+ public:
+ typedef std::basic_string<charT> string_type;
+ typedef std::istreambuf_iterator<charT> stream_itr_type;
+
+ typedef typename date_type::month_type month_type;
+ typedef typename date_type::day_of_week_type day_of_week_type;
+ typedef typename date_type::day_type day_type;
+
+ typedef string_parse_tree<charT> parse_tree_type;
+ typedef typename parse_tree_type::parse_match_result_type match_results;
+ typedef std::vector<std::basic_string<charT> > collection_type;
+
+ typedef partial_date<date_type> partial_date_type;
+ typedef nth_kday_of_month<date_type> nth_kday_type;
+ typedef first_kday_of_month<date_type> first_kday_type;
+ typedef last_kday_of_month<date_type> last_kday_type;
+ typedef first_kday_after<date_type> kday_after_type;
+ typedef first_kday_before<date_type> kday_before_type;
+
+ typedef charT char_type;
+ static const char_type first_string[6];
+ static const char_type second_string[7];
+ static const char_type third_string[6];
+ static const char_type fourth_string[7];
+ static const char_type fifth_string[6];
+ static const char_type last_string[5];
+ static const char_type before_string[8];
+ static const char_type after_string[6];
+ static const char_type of_string[3];
+
+ enum phrase_elements {first=0, second, third, fourth, fifth, last,
+ before, after, of, number_of_phrase_elements};
+
+ //! Creates a date_generator_parser with the default set of "element_strings"
+ date_generator_parser()
+ {
+ element_strings(string_type(first_string),
+ string_type(second_string),
+ string_type(third_string),
+ string_type(fourth_string),
+ string_type(fifth_string),
+ string_type(last_string),
+ string_type(before_string),
+ string_type(after_string),
+ string_type(of_string));
+ }
+
+ //! Creates a date_generator_parser using a user defined set of element strings
+ date_generator_parser(const string_type& first_str,
+ const string_type& second_str,
+ const string_type& third_str,
+ const string_type& fourth_str,
+ const string_type& fifth_str,
+ const string_type& last_str,
+ const string_type& before_str,
+ const string_type& after_str,
+ const string_type& of_str)
+ {
+ element_strings(first_str, second_str, third_str, fourth_str, fifth_str,
+ last_str, before_str, after_str, of_str);
+ }
+
+ //! Replace strings that determine nth week for generator
+ void element_strings(const string_type& first_str,
+ const string_type& second_str,
+ const string_type& third_str,
+ const string_type& fourth_str,
+ const string_type& fifth_str,
+ const string_type& last_str,
+ const string_type& before_str,
+ const string_type& after_str,
+ const string_type& of_str)
+ {
+ collection_type phrases;
+ phrases.push_back(first_str);
+ phrases.push_back(second_str);
+ phrases.push_back(third_str);
+ phrases.push_back(fourth_str);
+ phrases.push_back(fifth_str);
+ phrases.push_back(last_str);
+ phrases.push_back(before_str);
+ phrases.push_back(after_str);
+ phrases.push_back(of_str);
+ m_element_strings = parse_tree_type(phrases, this->first); // enum first
+ }
+
+ void element_strings(const collection_type& col)
+ {
+ m_element_strings = parse_tree_type(col, this->first); // enum first
+ }
+
+ //! returns partial_date parsed from stream
+ template<class facet_type>
+ partial_date_type
+ get_partial_date_type(stream_itr_type& sitr,
+ stream_itr_type& stream_end,
+ std::ios_base& a_ios,
+ const facet_type& facet) const
+ {
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+ day_type d(1);
+ month_type m(1);
+ facet.get(sitr, stream_end, a_ios, d);
+ facet.get(sitr, stream_end, a_ios, m);
+
+ return partial_date_type(d,m);
+ }
+
+ //! returns nth_kday_of_week parsed from stream
+ template<class facet_type>
+ nth_kday_type
+ get_nth_kday_type(stream_itr_type& sitr,
+ stream_itr_type& stream_end,
+ std::ios_base& a_ios,
+ const facet_type& facet) const
+ {
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+ typename nth_kday_type::week_num wn;
+ day_of_week_type wd(0); // no default constructor
+ month_type m(1); // no default constructor
+
+ match_results mr = m_element_strings.match(sitr, stream_end);
+ switch(mr.current_match) {
+ case first : { wn = nth_kday_type::first; break; }
+ case second : { wn = nth_kday_type::second; break; }
+ case third : { wn = nth_kday_type::third; break; }
+ case fourth : { wn = nth_kday_type::fourth; break; }
+ case fifth : { wn = nth_kday_type::fifth; break; }
+ default:
+ {
+ boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"));
+ BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(wn = nth_kday_type::first);
+ }
+ } // week num
+ facet.get(sitr, stream_end, a_ios, wd); // day_of_week
+ extract_element(sitr, stream_end, of); // "of" element
+ facet.get(sitr, stream_end, a_ios, m); // month
+
+ return nth_kday_type(wn, wd, m);
+ }
+
+ //! returns first_kday_of_week parsed from stream
+ template<class facet_type>
+ first_kday_type
+ get_first_kday_type(stream_itr_type& sitr,
+ stream_itr_type& stream_end,
+ std::ios_base& a_ios,
+ const facet_type& facet) const
+ {
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+ day_of_week_type wd(0); // no default constructor
+ month_type m(1); // no default constructor
+
+ extract_element(sitr, stream_end, first); // "first" element
+ facet.get(sitr, stream_end, a_ios, wd); // day_of_week
+ extract_element(sitr, stream_end, of); // "of" element
+ facet.get(sitr, stream_end, a_ios, m); // month
+
+
+ return first_kday_type(wd, m);
+ }
+
+ //! returns last_kday_of_week parsed from stream
+ template<class facet_type>
+ last_kday_type
+ get_last_kday_type(stream_itr_type& sitr,
+ stream_itr_type& stream_end,
+ std::ios_base& a_ios,
+ const facet_type& facet) const
+ {
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+ day_of_week_type wd(0); // no default constructor
+ month_type m(1); // no default constructor
+
+ extract_element(sitr, stream_end, last); // "last" element
+ facet.get(sitr, stream_end, a_ios, wd); // day_of_week
+ extract_element(sitr, stream_end, of); // "of" element
+ facet.get(sitr, stream_end, a_ios, m); // month
+
+
+ return last_kday_type(wd, m);
+ }
+
+ //! returns first_kday_of_week parsed from stream
+ template<class facet_type>
+ kday_before_type
+ get_kday_before_type(stream_itr_type& sitr,
+ stream_itr_type& stream_end,
+ std::ios_base& a_ios,
+ const facet_type& facet) const
+ {
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+ day_of_week_type wd(0); // no default constructor
+
+ facet.get(sitr, stream_end, a_ios, wd); // day_of_week
+ extract_element(sitr, stream_end, before);// "before" element
+
+ return kday_before_type(wd);
+ }
+
+ //! returns first_kday_of_week parsed from stream
+ template<class facet_type>
+ kday_after_type
+ get_kday_after_type(stream_itr_type& sitr,
+ stream_itr_type& stream_end,
+ std::ios_base& a_ios,
+ const facet_type& facet) const
+ {
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+ day_of_week_type wd(0); // no default constructor
+
+ facet.get(sitr, stream_end, a_ios, wd); // day_of_week
+ extract_element(sitr, stream_end, after); // "after" element
+
+ return kday_after_type(wd);
+ }
+
+ private:
+ parse_tree_type m_element_strings;
+
+ //! Extracts phrase element from input. Throws ios_base::failure on error.
+ void extract_element(stream_itr_type& sitr,
+ stream_itr_type& stream_end,
+ typename date_generator_parser::phrase_elements ele) const
+ {
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+ match_results mr = m_element_strings.match(sitr, stream_end);
+ if(mr.current_match != ele) {
+ boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"));
+ }
+ }
+
+ };
+
+ template<class date_type, class CharT>
+ const typename date_generator_parser<date_type, CharT>::char_type
+ date_generator_parser<date_type, CharT>::first_string[6] =
+ {'f','i','r','s','t'};
+ template<class date_type, class CharT>
+ const typename date_generator_parser<date_type, CharT>::char_type
+ date_generator_parser<date_type, CharT>::second_string[7] =
+ {'s','e','c','o','n','d'};
+ template<class date_type, class CharT>
+ const typename date_generator_parser<date_type, CharT>::char_type
+ date_generator_parser<date_type, CharT>::third_string[6] =
+ {'t','h','i','r','d'};
+ template<class date_type, class CharT>
+ const typename date_generator_parser<date_type, CharT>::char_type
+ date_generator_parser<date_type, CharT>::fourth_string[7] =
+ {'f','o','u','r','t','h'};
+ template<class date_type, class CharT>
+ const typename date_generator_parser<date_type, CharT>::char_type
+ date_generator_parser<date_type, CharT>::fifth_string[6] =
+ {'f','i','f','t','h'};
+ template<class date_type, class CharT>
+ const typename date_generator_parser<date_type, CharT>::char_type
+ date_generator_parser<date_type, CharT>::last_string[5] =
+ {'l','a','s','t'};
+ template<class date_type, class CharT>
+ const typename date_generator_parser<date_type, CharT>::char_type
+ date_generator_parser<date_type, CharT>::before_string[8] =
+ {'b','e','f','o','r','e'};
+ template<class date_type, class CharT>
+ const typename date_generator_parser<date_type, CharT>::char_type
+ date_generator_parser<date_type, CharT>::after_string[6] =
+ {'a','f','t','e','r'};
+ template<class date_type, class CharT>
+ const typename date_generator_parser<date_type, CharT>::char_type
+ date_generator_parser<date_type, CharT>::of_string[3] =
+ {'o','f'};
+
+} } //namespace
+
+#endif // DATE_TIME_DATE_GENERATOR_PARSER_HPP__
+
diff --git a/ext/boost/date_time/date_generators.hpp b/ext/boost/date_time/date_generators.hpp
new file mode 100644
index 0000000000..1f1a34a667
--- /dev/null
+++ b/ext/boost/date_time/date_generators.hpp
@@ -0,0 +1,509 @@
+#ifndef DATE_TIME_DATE_GENERATORS_HPP__
+#define DATE_TIME_DATE_GENERATORS_HPP__
+
+/* Copyright (c) 2002,2003,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-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+/*! @file date_generators.hpp
+ Definition and implementation of date algorithm templates
+*/
+
+#include <stdexcept>
+#include <sstream>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/date.hpp>
+#include <boost/date_time/compiler_config.hpp>
+
+namespace boost {
+namespace date_time {
+
+ //! Base class for all generators that take a year and produce a date.
+ /*! This class is a base class for polymorphic function objects that take
+ a year and produce a concrete date.
+ @param date_type The type representing a date. This type must
+ export a calender_type which defines a year_type.
+ */
+ template<class date_type>
+ class year_based_generator
+ {
+ public:
+ typedef typename date_type::calendar_type calendar_type;
+ typedef typename calendar_type::year_type year_type;
+ year_based_generator() {};
+ virtual ~year_based_generator() {};
+ virtual date_type get_date(year_type y) const = 0;
+ //! Returns a string for use in a POSIX time_zone string
+ virtual std::string to_string() const =0;
+ };
+
+ //! Generates a date by applying the year to the given month and day.
+ /*!
+ Example usage:
+ @code
+ partial_date pd(1, Jan);
+ partial_date pd2(70);
+ date d = pd.get_date(2002); //2002-Jan-01
+ date d2 = pd2.get_date(2002); //2002-Mar-10
+ @endcode
+ \ingroup date_alg
+ */
+ template<class date_type>
+ class partial_date : public year_based_generator<date_type>
+ {
+ public:
+ typedef typename date_type::calendar_type calendar_type;
+ typedef typename calendar_type::day_type day_type;
+ typedef typename calendar_type::month_type month_type;
+ typedef typename calendar_type::year_type year_type;
+ typedef typename date_type::duration_type duration_type;
+ typedef typename duration_type::duration_rep duration_rep;
+ partial_date(day_type d, month_type m) :
+ day_(d),
+ month_(m)
+ {}
+ //! Partial date created from number of days into year. Range 1-366
+ /*! Allowable values range from 1 to 366. 1=Jan1, 366=Dec31. If argument
+ * exceeds range, partial_date will be created with closest in-range value.
+ * 60 will always be Feb29, if get_date() is called with a non-leap year
+ * an exception will be thrown */
+ partial_date(duration_rep days) :
+ day_(1), // default values
+ month_(1)
+ {
+ date_type d1(2000,1,1);
+ if(days > 1) {
+ if(days > 366) // prevents wrapping
+ {
+ days = 366;
+ }
+ days = days - 1;
+ duration_type dd(days);
+ d1 = d1 + dd;
+ }
+ day_ = d1.day();
+ month_ = d1.month();
+ }
+ //! Return a concrete date when provided with a year specific year.
+ /*! Will throw an 'invalid_argument' exception if a partial_date object,
+ * instantiated with Feb-29, has get_date called with a non-leap year.
+ * Example:
+ * @code
+ * partial_date pd(29, Feb);
+ * pd.get_date(2003); // throws invalid_argument exception
+ * pg.get_date(2000); // returns 2000-2-29
+ * @endcode
+ */
+ date_type get_date(year_type y) const
+ {
+ if((day_ == 29) && (month_ == 2) && !(calendar_type::is_leap_year(y))) {
+ std::ostringstream ss;
+ ss << "No Feb 29th in given year of " << y << ".";
+ boost::throw_exception(std::invalid_argument(ss.str()));
+ }
+ return date_type(y, month_, day_);
+ }
+ date_type operator()(year_type y) const
+ {
+ return get_date(y);
+ //return date_type(y, month_, day_);
+ }
+ bool operator==(const partial_date& rhs) const
+ {
+ return (month_ == rhs.month_) && (day_ == rhs.day_);
+ }
+ bool operator<(const partial_date& rhs) const
+ {
+ if (month_ < rhs.month_) return true;
+ if (month_ > rhs.month_) return false;
+ //months are equal
+ return (day_ < rhs.day_);
+ }
+
+ // added for streaming purposes
+ month_type month() const
+ {
+ return month_;
+ }
+ day_type day() const
+ {
+ return day_;
+ }
+
+ //! Returns string suitable for use in POSIX time zone string
+ /*! Returns string formatted with up to 3 digits:
+ * Jan-01 == "0"
+ * Feb-29 == "58"
+ * Dec-31 == "365" */
+ virtual std::string to_string() const
+ {
+ std::ostringstream ss;
+ date_type d(2004, month_, day_);
+ unsigned short c = d.day_of_year();
+ c--; // numbered 0-365 while day_of_year is 1 based...
+ ss << c;
+ return ss.str();
+ }
+ private:
+ day_type day_;
+ month_type month_;
+ };
+
+
+ //! Returns nth arg as string. 1 -> "first", 2 -> "second", max is 5.
+ BOOST_DATE_TIME_DECL const char* nth_as_str(int n);
+
+ //! Useful generator functor for finding holidays
+ /*! Based on the idea in Cal. Calc. for finding holidays that are
+ * the 'first Monday of September'. When instantiated with
+ * 'fifth' kday of month, the result will be the last kday of month
+ * which can be the fourth or fifth depending on the structure of
+ * the month.
+ *
+ * The algorithm here basically guesses for the first
+ * day of the month. Then finds the first day of the correct
+ * type. That is, if the first of the month is a Tuesday
+ * and it needs Wenesday then we simply increment by a day
+ * and then we can add the length of a week until we get
+ * to the 'nth kday'. There are probably more efficient
+ * algorithms based on using a mod 7, but this one works
+ * reasonably well for basic applications.
+ * \ingroup date_alg
+ */
+ template<class date_type>
+ class nth_kday_of_month : public year_based_generator<date_type>
+ {
+ public:
+ typedef typename date_type::calendar_type calendar_type;
+ typedef typename calendar_type::day_of_week_type day_of_week_type;
+ typedef typename calendar_type::month_type month_type;
+ typedef typename calendar_type::year_type year_type;
+ typedef typename date_type::duration_type duration_type;
+ enum week_num {first=1, second, third, fourth, fifth};
+ nth_kday_of_month(week_num week_no,
+ day_of_week_type dow,
+ month_type m) :
+ month_(m),
+ wn_(week_no),
+ dow_(dow)
+ {}
+ //! Return a concrete date when provided with a year specific year.
+ date_type get_date(year_type y) const
+ {
+ date_type d(y, month_, 1); //first day of month
+ duration_type one_day(1);
+ duration_type one_week(7);
+ while (dow_ != d.day_of_week()) {
+ d = d + one_day;
+ }
+ int week = 1;
+ while (week < wn_) {
+ d = d + one_week;
+ week++;
+ }
+ // remove wrapping to next month behavior
+ if(d.month() != month_) {
+ d = d - one_week;
+ }
+ return d;
+ }
+ // added for streaming
+ month_type month() const
+ {
+ return month_;
+ }
+ week_num nth_week() const
+ {
+ return wn_;
+ }
+ day_of_week_type day_of_week() const
+ {
+ return dow_;
+ }
+ const char* nth_week_as_str() const
+ {
+ return nth_as_str(wn_);
+ }
+ //! Returns string suitable for use in POSIX time zone string
+ /*! Returns a string formatted as "M4.3.0" ==> 3rd Sunday in April. */
+ virtual std::string to_string() const
+ {
+ std::ostringstream ss;
+ ss << 'M'
+ << static_cast<int>(month_) << '.'
+ << static_cast<int>(wn_) << '.'
+ << static_cast<int>(dow_);
+ return ss.str();
+ }
+ private:
+ month_type month_;
+ week_num wn_;
+ day_of_week_type dow_;
+ };
+
+ //! Useful generator functor for finding holidays and daylight savings
+ /*! Similar to nth_kday_of_month, but requires less paramters
+ * \ingroup date_alg
+ */
+ template<class date_type>
+ class first_kday_of_month : public year_based_generator<date_type>
+ {
+ public:
+ typedef typename date_type::calendar_type calendar_type;
+ typedef typename calendar_type::day_of_week_type day_of_week_type;
+ typedef typename calendar_type::month_type month_type;
+ typedef typename calendar_type::year_type year_type;
+ typedef typename date_type::duration_type duration_type;
+ //!Specify the first 'Sunday' in 'April' spec
+ /*!@param dow The day of week, eg: Sunday, Monday, etc
+ * @param m The month of the year, eg: Jan, Feb, Mar, etc
+ */
+ first_kday_of_month(day_of_week_type dow, month_type m) :
+ month_(m),
+ dow_(dow)
+ {}
+ //! Return a concrete date when provided with a year specific year.
+ date_type get_date(year_type year) const
+ {
+ date_type d(year, month_,1);
+ duration_type one_day(1);
+ while (dow_ != d.day_of_week()) {
+ d = d + one_day;
+ }
+ return d;
+ }
+ // added for streaming
+ month_type month() const
+ {
+ return month_;
+ }
+ day_of_week_type day_of_week() const
+ {
+ return dow_;
+ }
+ //! Returns string suitable for use in POSIX time zone string
+ /*! Returns a string formatted as "M4.1.0" ==> 1st Sunday in April. */
+ virtual std::string to_string() const
+ {
+ std::ostringstream ss;
+ ss << 'M'
+ << static_cast<int>(month_) << '.'
+ << 1 << '.'
+ << static_cast<int>(dow_);
+ return ss.str();
+ }
+ private:
+ month_type month_;
+ day_of_week_type dow_;
+ };
+
+
+
+ //! Calculate something like Last Sunday of January
+ /*! Useful generator functor for finding holidays and daylight savings
+ * Get the last day of the month and then calculate the difference
+ * to the last previous day.
+ * @param date_type A date class that exports day_of_week, month_type, etc.
+ * \ingroup date_alg
+ */
+ template<class date_type>
+ class last_kday_of_month : public year_based_generator<date_type>
+ {
+ public:
+ typedef typename date_type::calendar_type calendar_type;
+ typedef typename calendar_type::day_of_week_type day_of_week_type;
+ typedef typename calendar_type::month_type month_type;
+ typedef typename calendar_type::year_type year_type;
+ typedef typename date_type::duration_type duration_type;
+ //!Specify the date spec like last 'Sunday' in 'April' spec
+ /*!@param dow The day of week, eg: Sunday, Monday, etc
+ * @param m The month of the year, eg: Jan, Feb, Mar, etc
+ */
+ last_kday_of_month(day_of_week_type dow, month_type m) :
+ month_(m),
+ dow_(dow)
+ {}
+ //! Return a concrete date when provided with a year specific year.
+ date_type get_date(year_type year) const
+ {
+ date_type d(year, month_, calendar_type::end_of_month_day(year,month_));
+ duration_type one_day(1);
+ while (dow_ != d.day_of_week()) {
+ d = d - one_day;
+ }
+ return d;
+ }
+ // added for streaming
+ month_type month() const
+ {
+ return month_;
+ }
+ day_of_week_type day_of_week() const
+ {
+ return dow_;
+ }
+ //! Returns string suitable for use in POSIX time zone string
+ /*! Returns a string formatted as "M4.5.0" ==> last Sunday in April. */
+ virtual std::string to_string() const
+ {
+ std::ostringstream ss;
+ ss << 'M'
+ << static_cast<int>(month_) << '.'
+ << 5 << '.'
+ << static_cast<int>(dow_);
+ return ss.str();
+ }
+ private:
+ month_type month_;
+ day_of_week_type dow_;
+ };
+
+
+ //! Calculate something like "First Sunday after Jan 1,2002
+ /*! Date generator that takes a date and finds kday after
+ *@code
+ typedef boost::date_time::first_kday_after<date> firstkdayafter;
+ firstkdayafter fkaf(Monday);
+ fkaf.get_date(date(2002,Feb,1));
+ @endcode
+ * \ingroup date_alg
+ */
+ template<class date_type>
+ class first_kday_after
+ {
+ public:
+ typedef typename date_type::calendar_type calendar_type;
+ typedef typename calendar_type::day_of_week_type day_of_week_type;
+ typedef typename date_type::duration_type duration_type;
+ first_kday_after(day_of_week_type dow) :
+ dow_(dow)
+ {}
+ //! Return next kday given.
+ date_type get_date(date_type start_day) const
+ {
+ duration_type one_day(1);
+ date_type d = start_day + one_day;
+ while (dow_ != d.day_of_week()) {
+ d = d + one_day;
+ }
+ return d;
+ }
+ // added for streaming
+ day_of_week_type day_of_week() const
+ {
+ return dow_;
+ }
+ private:
+ day_of_week_type dow_;
+ };
+
+ //! Calculate something like "First Sunday before Jan 1,2002
+ /*! Date generator that takes a date and finds kday after
+ *@code
+ typedef boost::date_time::first_kday_before<date> firstkdaybefore;
+ firstkdaybefore fkbf(Monday);
+ fkbf.get_date(date(2002,Feb,1));
+ @endcode
+ * \ingroup date_alg
+ */
+ template<class date_type>
+ class first_kday_before
+ {
+ public:
+ typedef typename date_type::calendar_type calendar_type;
+ typedef typename calendar_type::day_of_week_type day_of_week_type;
+ typedef typename date_type::duration_type duration_type;
+ first_kday_before(day_of_week_type dow) :
+ dow_(dow)
+ {}
+ //! Return next kday given.
+ date_type get_date(date_type start_day) const
+ {
+ duration_type one_day(1);
+ date_type d = start_day - one_day;
+ while (dow_ != d.day_of_week()) {
+ d = d - one_day;
+ }
+ return d;
+ }
+ // added for streaming
+ day_of_week_type day_of_week() const
+ {
+ return dow_;
+ }
+ private:
+ day_of_week_type dow_;
+ };
+
+ //! Calculates the number of days until the next weekday
+ /*! Calculates the number of days until the next weekday.
+ * If the date given falls on a Sunday and the given weekday
+ * is Tuesday the result will be 2 days */
+ template<typename date_type, class weekday_type>
+ inline
+ typename date_type::duration_type days_until_weekday(const date_type& d, const weekday_type& wd)
+ {
+ typedef typename date_type::duration_type duration_type;
+ duration_type wks(0);
+ duration_type dd(wd.as_number() - d.day_of_week().as_number());
+ if(dd.is_negative()){
+ wks = duration_type(7);
+ }
+ return dd + wks;
+ }
+
+ //! Calculates the number of days since the previous weekday
+ /*! Calculates the number of days since the previous weekday
+ * If the date given falls on a Sunday and the given weekday
+ * is Tuesday the result will be 5 days. The answer will be a positive
+ * number because Tuesday is 5 days before Sunday, not -5 days before. */
+ template<typename date_type, class weekday_type>
+ inline
+ typename date_type::duration_type days_before_weekday(const date_type& d, const weekday_type& wd)
+ {
+ typedef typename date_type::duration_type duration_type;
+ duration_type wks(0);
+ duration_type dd(wd.as_number() - d.day_of_week().as_number());
+ if(dd.days() > 0){
+ wks = duration_type(7);
+ }
+ // we want a number of days, not an offset. The value returned must
+ // be zero or larger.
+ return (-dd + wks);
+ }
+
+ //! Generates a date object representing the date of the following weekday from the given date
+ /*! Generates a date object representing the date of the following
+ * weekday from the given date. If the date given is 2004-May-9
+ * (a Sunday) and the given weekday is Tuesday then the resulting date
+ * will be 2004-May-11. */
+ template<class date_type, class weekday_type>
+ inline
+ date_type next_weekday(const date_type& d, const weekday_type& wd)
+ {
+ return d + days_until_weekday(d, wd);
+ }
+
+ //! Generates a date object representing the date of the previous weekday from the given date
+ /*! Generates a date object representing the date of the previous
+ * weekday from the given date. If the date given is 2004-May-9
+ * (a Sunday) and the given weekday is Tuesday then the resulting date
+ * will be 2004-May-4. */
+ template<class date_type, class weekday_type>
+ inline
+ date_type previous_weekday(const date_type& d, const weekday_type& wd)
+ {
+ return d - days_before_weekday(d, wd);
+ }
+
+} } //namespace date_time
+
+
+
+
+#endif
+
diff --git a/ext/boost/date_time/date_iterator.hpp b/ext/boost/date_time/date_iterator.hpp
new file mode 100644
index 0000000000..284dc749d0
--- /dev/null
+++ b/ext/boost/date_time/date_iterator.hpp
@@ -0,0 +1,101 @@
+#ifndef DATE_ITERATOR_HPP___
+#define DATE_ITERATOR_HPP___
+
+/* 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) $
+ */
+
+#include <iterator>
+
+namespace boost {
+namespace date_time {
+ //! An iterator over dates with varying resolution (day, week, month, year, etc)
+ enum date_resolutions {day, week, months, year, decade, century, NumDateResolutions};
+
+ //! Base date iterator type
+ /*! This class provides the skeleton for the creation of iterators.
+ * New and interesting interators can be created by plugging in a new
+ * function that derives the next value from the current state.
+ * generation of various types of -based information.
+ *
+ * <b>Template Parameters</b>
+ *
+ * <b>date_type</b>
+ *
+ * The date_type is a concrete date_type. The date_type must
+ * define a duration_type and a calendar_type.
+ */
+ template<class date_type>
+ class date_itr_base {
+ // works, but benefit unclear at the moment
+ // class date_itr_base : public std::iterator<std::input_iterator_tag,
+ // date_type, void, void, void>{
+ public:
+ typedef typename date_type::duration_type duration_type;
+ typedef date_type value_type;
+ typedef std::input_iterator_tag iterator_category;
+
+ date_itr_base(date_type d) : current_(d) {}
+ virtual ~date_itr_base() {};
+ date_itr_base& operator++()
+ {
+ current_ = current_ + get_offset(current_);
+ return *this;
+ }
+ date_itr_base& operator--()
+ {
+ current_ = current_ + get_neg_offset(current_);
+ return *this;
+ }
+ virtual duration_type get_offset(const date_type& current) const=0;
+ virtual duration_type get_neg_offset(const date_type& current) const=0;
+ date_type operator*() {return current_;};
+ date_type* operator->() {return &current_;};
+ bool operator< (const date_type& d) {return current_ < d;}
+ bool operator<= (const date_type& d) {return current_ <= d;}
+ bool operator> (const date_type& d) {return current_ > d;}
+ bool operator>= (const date_type& d) {return current_ >= d;}
+ bool operator== (const date_type& d) {return current_ == d;}
+ bool operator!= (const date_type& d) {return current_ != d;}
+ private:
+ date_type current_;
+ };
+
+ //! Overrides the base date iterator providing hook for functors
+ /*
+ * <b>offset_functor</b>
+ *
+ * The offset functor must define a get_offset function that takes the
+ * current point in time and calculates and offset.
+ *
+ */
+ template<class offset_functor, class date_type>
+ class date_itr : public date_itr_base<date_type> {
+ public:
+ typedef typename date_type::duration_type duration_type;
+ date_itr(date_type d, int factor=1) :
+ date_itr_base<date_type>(d),
+ of_(factor)
+ {}
+ private:
+ virtual duration_type get_offset(const date_type& current) const
+ {
+ return of_.get_offset(current);
+ }
+ virtual duration_type get_neg_offset(const date_type& current) const
+ {
+ return of_.get_neg_offset(current);
+ }
+ offset_functor of_;
+ };
+
+
+
+} } //namespace date_time
+
+
+#endif
diff --git a/ext/boost/date_time/date_names_put.hpp b/ext/boost/date_time/date_names_put.hpp
new file mode 100644
index 0000000000..c6f0ce2a6f
--- /dev/null
+++ b/ext/boost/date_time/date_names_put.hpp
@@ -0,0 +1,320 @@
+#ifndef DATE_TIME_DATE_NAMES_PUT_HPP___
+#define DATE_TIME_DATE_NAMES_PUT_HPP___
+
+/* 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-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+#include "boost/date_time/locale_config.hpp" // set BOOST_DATE_TIME_NO_LOCALE
+
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+
+#include "boost/date_time/special_defs.hpp"
+#include "boost/date_time/date_defs.hpp"
+#include "boost/date_time/parse_format_base.hpp"
+#include "boost/lexical_cast.hpp"
+#include <locale>
+
+
+namespace boost {
+namespace date_time {
+
+ //! Output facet base class for gregorian dates.
+ /*! This class is a base class for date facets used to localize the
+ * names of months and the names of days in the week.
+ *
+ * Requirements of Config
+ * - define an enumeration month_enum that enumerates the months.
+ * The enumeration should be '1' based eg: Jan==1
+ * - define as_short_string and as_long_string
+ *
+ * (see langer & kreft p334).
+ *
+ */
+ template<class Config,
+ class charT = char,
+ class OutputIterator = std::ostreambuf_iterator<charT> >
+ class date_names_put : public std::locale::facet
+ {
+ public:
+ date_names_put() {};
+ typedef OutputIterator iter_type;
+ typedef typename Config::month_type month_type;
+ typedef typename Config::month_enum month_enum;
+ typedef typename Config::weekday_enum weekday_enum;
+ typedef typename Config::special_value_enum special_value_enum;
+ //typedef typename Config::format_type format_type;
+ typedef std::basic_string<charT> string_type;
+ typedef charT char_type;
+ static const char_type default_special_value_names[3][17];
+ static const char_type separator[2];
+
+ static std::locale::id id;
+
+#if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
+ std::locale::id& __get_id (void) const { return id; }
+#endif
+
+ void put_special_value(iter_type& oitr, special_value_enum sv) const
+ {
+ do_put_special_value(oitr, sv);
+ }
+ void put_month_short(iter_type& oitr, month_enum moy) const
+ {
+ do_put_month_short(oitr, moy);
+ }
+ void put_month_long(iter_type& oitr, month_enum moy) const
+ {
+ do_put_month_long(oitr, moy);
+ }
+ void put_weekday_short(iter_type& oitr, weekday_enum wd) const
+ {
+ do_put_weekday_short(oitr, wd);
+ }
+ void put_weekday_long(iter_type& oitr, weekday_enum wd) const
+ {
+ do_put_weekday_long(oitr, wd);
+ }
+ bool has_date_sep_chars() const
+ {
+ return do_has_date_sep_chars();
+ }
+ void year_sep_char(iter_type& oitr) const
+ {
+ do_year_sep_char(oitr);
+ }
+ //! char between year-month
+ void month_sep_char(iter_type& oitr) const
+ {
+ do_month_sep_char(oitr);
+ }
+ //! Char to separate month-day
+ void day_sep_char(iter_type& oitr) const
+ {
+ do_day_sep_char(oitr);
+ }
+ //! Determines the order to put the date elements
+ ymd_order_spec date_order() const
+ {
+ return do_date_order();
+ }
+ //! Determines if month is displayed as integer, short or long string
+ month_format_spec month_format() const
+ {
+ return do_month_format();
+ }
+
+ protected:
+ //! Default facet implementation uses month_type defaults
+ virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
+ {
+ month_type gm(moy);
+ charT c = '\0';
+ put_string(oitr, gm.as_short_string(c));
+ }
+ //! Default facet implementation uses month_type defaults
+ virtual void do_put_month_long(iter_type& oitr,
+ month_enum moy) const
+ {
+ month_type gm(moy);
+ charT c = '\0';
+ put_string(oitr, gm.as_long_string(c));
+ }
+ //! Default facet implementation for special value types
+ virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
+ {
+ if(sv <= 2) { // only output not_a_date_time, neg_infin, or pos_infin
+ string_type s(default_special_value_names[sv]);
+ put_string(oitr, s);
+ }
+ }
+ virtual void do_put_weekday_short(iter_type&, weekday_enum) const
+ {
+ }
+ virtual void do_put_weekday_long(iter_type&, weekday_enum) const
+ {
+ }
+ virtual bool do_has_date_sep_chars() const
+ {
+ return true;
+ }
+ virtual void do_year_sep_char(iter_type& oitr) const
+ {
+ string_type s(separator);
+ put_string(oitr, s);
+ }
+ //! char between year-month
+ virtual void do_month_sep_char(iter_type& oitr) const
+ {
+ string_type s(separator);
+ put_string(oitr, s);
+ }
+ //! Char to separate month-day
+ virtual void do_day_sep_char(iter_type& oitr) const
+ {
+ string_type s(separator); //put in '-'
+ put_string(oitr, s);
+ }
+ //! Default for date order
+ virtual ymd_order_spec do_date_order() const
+ {
+ return ymd_order_iso;
+ }
+ //! Default month format
+ virtual month_format_spec do_month_format() const
+ {
+ return month_as_short_string;
+ }
+ void put_string(iter_type& oi, const charT* const s) const
+ {
+ string_type s1(boost::lexical_cast<string_type>(s));
+ typename string_type::iterator si,end;
+ for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
+ *oi = *si;
+ }
+ }
+ void put_string(iter_type& oi, const string_type& s1) const
+ {
+ typename string_type::const_iterator si,end;
+ for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
+ *oi = *si;
+ }
+ }
+ };
+
+ template<class Config, class charT, class OutputIterator>
+ const typename date_names_put<Config, charT, OutputIterator>::char_type
+ date_names_put<Config, charT, OutputIterator>::default_special_value_names[3][17] = {
+ {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'},
+ {'-','i','n','f','i','n','i','t','y'},
+ {'+','i','n','f','i','n','i','t','y'} };
+
+ template<class Config, class charT, class OutputIterator>
+ const typename date_names_put<Config, charT, OutputIterator>::char_type
+ date_names_put<Config, charT, OutputIterator>::separator[2] =
+ {'-', '\0'} ;
+
+
+ //! Generate storage location for a std::locale::id
+ template<class Config, class charT, class OutputIterator>
+ std::locale::id date_names_put<Config, charT, OutputIterator>::id;
+
+ //! A date name output facet that takes an array of char* to define strings
+ template<class Config,
+ class charT = char,
+ class OutputIterator = std::ostreambuf_iterator<charT> >
+ class all_date_names_put : public date_names_put<Config, charT, OutputIterator>
+ {
+ public:
+ all_date_names_put(const charT* const month_short_names[],
+ const charT* const month_long_names[],
+ const charT* const special_value_names[],
+ const charT* const weekday_short_names[],
+ const charT* const weekday_long_names[],
+ charT separator_char = '-',
+ ymd_order_spec order_spec = ymd_order_iso,
+ month_format_spec month_format = month_as_short_string) :
+ month_short_names_(month_short_names),
+ month_long_names_(month_long_names),
+ special_value_names_(special_value_names),
+ weekday_short_names_(weekday_short_names),
+ weekday_long_names_(weekday_long_names),
+ order_spec_(order_spec),
+ month_format_spec_(month_format)
+ {
+ separator_char_[0] = separator_char;
+ separator_char_[1] = '\0';
+
+ };
+ typedef OutputIterator iter_type;
+ typedef typename Config::month_enum month_enum;
+ typedef typename Config::weekday_enum weekday_enum;
+ typedef typename Config::special_value_enum special_value_enum;
+
+ const charT* const* get_short_month_names() const
+ {
+ return month_short_names_;
+ }
+ const charT* const* get_long_month_names() const
+ {
+ return month_long_names_;
+ }
+ const charT* const* get_special_value_names() const
+ {
+ return special_value_names_;
+ }
+ const charT* const* get_short_weekday_names()const
+ {
+ return weekday_short_names_;
+ }
+ const charT* const* get_long_weekday_names()const
+ {
+ return weekday_long_names_;
+ }
+
+ protected:
+ //! Generic facet that takes array of chars
+ virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
+ {
+ this->put_string(oitr, month_short_names_[moy-1]);
+ }
+ //! Long month names
+ virtual void do_put_month_long(iter_type& oitr, month_enum moy) const
+ {
+ this->put_string(oitr, month_long_names_[moy-1]);
+ }
+ //! Special values names
+ virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
+ {
+ this->put_string(oitr, special_value_names_[sv]);
+ }
+ virtual void do_put_weekday_short(iter_type& oitr, weekday_enum wd) const
+ {
+ this->put_string(oitr, weekday_short_names_[wd]);
+ }
+ virtual void do_put_weekday_long(iter_type& oitr, weekday_enum wd) const
+ {
+ this->put_string(oitr, weekday_long_names_[wd]);
+ }
+ //! char between year-month
+ virtual void do_month_sep_char(iter_type& oitr) const
+ {
+ this->put_string(oitr, separator_char_);
+ }
+ //! Char to separate month-day
+ virtual void do_day_sep_char(iter_type& oitr) const
+ {
+ this->put_string(oitr, separator_char_);
+ }
+ //! Set the date ordering
+ virtual ymd_order_spec do_date_order() const
+ {
+ return order_spec_;
+ }
+ //! Set the date ordering
+ virtual month_format_spec do_month_format() const
+ {
+ return month_format_spec_;
+ }
+
+ private:
+ const charT* const* month_short_names_;
+ const charT* const* month_long_names_;
+ const charT* const* special_value_names_;
+ const charT* const* weekday_short_names_;
+ const charT* const* weekday_long_names_;
+ charT separator_char_[2];
+ ymd_order_spec order_spec_;
+ month_format_spec month_format_spec_;
+ };
+
+} } //namespace boost::date_time
+
+#endif //BOOST_NO_STD_LOCALE
+
+#endif
diff --git a/ext/boost/date_time/date_parsing.hpp b/ext/boost/date_time/date_parsing.hpp
new file mode 100644
index 0000000000..f361bc8096
--- /dev/null
+++ b/ext/boost/date_time/date_parsing.hpp
@@ -0,0 +1,316 @@
+#ifndef _DATE_TIME_DATE_PARSING_HPP___
+#define _DATE_TIME_DATE_PARSING_HPP___
+
+/* Copyright (c) 2002,2003,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: 2009-06-04 04:24:49 -0400 (Thu, 04 Jun 2009) $
+ */
+
+#include <string>
+#include <iterator>
+#include <algorithm>
+#include <boost/tokenizer.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/parse_format_base.hpp>
+
+#if defined(BOOST_DATE_TIME_NO_LOCALE)
+#include <cctype> // ::tolower(int)
+#else
+#include <locale> // std::tolower(char, locale)
+#endif
+
+namespace boost {
+namespace date_time {
+
+ //! A function to replace the std::transform( , , ,tolower) construct
+ /*! This function simply takes a string, and changes all the characters
+ * in that string to lowercase (according to the default system locale).
+ * In the event that a compiler does not support locales, the old
+ * C style tolower() is used.
+ */
+ inline
+ std::string
+ convert_to_lower(std::string inp)
+ {
+#if !defined(BOOST_DATE_TIME_NO_LOCALE)
+ const std::locale loc(std::locale::classic());
+#endif
+ std::string::size_type i = 0, n = inp.length();
+ for (; i < n; ++i) {
+ inp[i] =
+#if defined(BOOST_DATE_TIME_NO_LOCALE)
+ static_cast<char>(std::tolower(inp[i]));
+#else
+ // tolower and others were brought in to std for borland >= v564
+ // in compiler_config.hpp
+ std::tolower(inp[i], loc);
+#endif
+ }
+ return inp;
+ }
+
+ //! Helper function for parse_date.
+ /* Used by-value parameter because we change the string and may
+ * want to preserve the original argument */
+ template<class month_type>
+ inline unsigned short
+ month_str_to_ushort(std::string const& s) {
+ if((s.at(0) >= '0') && (s.at(0) <= '9')) {
+ return boost::lexical_cast<unsigned short>(s);
+ }
+ else {
+ std::string str = convert_to_lower(s);
+ typename month_type::month_map_ptr_type ptr = month_type::get_month_map_ptr();
+ typename month_type::month_map_type::iterator iter = ptr->find(str);
+ if(iter != ptr->end()) { // required for STLport
+ return iter->second;
+ }
+ }
+ return 13; // intentionally out of range - name not found
+ }
+
+ //! Find index of a string in either of 2 arrays
+ /*! find_match searches both arrays for a match to 's'. Both arrays
+ * must contain 'size' elements. The index of the match is returned.
+ * If no match is found, 'size' is returned.
+ * Ex. "Jan" returns 0, "Dec" returns 11, "Tue" returns 2.
+ * 'size' can be sent in with: (greg_month::max)() (which 12),
+ * (greg_weekday::max)() + 1 (which is 7) or date_time::NumSpecialValues */
+ template<class charT>
+ short find_match(const charT* const* short_names,
+ const charT* const* long_names,
+ short size,
+ const std::basic_string<charT>& s) {
+ for(short i = 0; i < size; ++i){
+ if(short_names[i] == s || long_names[i] == s){
+ return i;
+ }
+ }
+ return size; // not-found, return a value out of range
+ }
+
+ //! Generic function to parse a delimited date (eg: 2002-02-10)
+ /*! Accepted formats are: "2003-02-10" or " 2003-Feb-10" or
+ * "2003-Feburary-10"
+ * The order in which the Month, Day, & Year appear in the argument
+ * string can be accomodated by passing in the appropriate ymd_order_spec
+ */
+ template<class date_type>
+ date_type
+ parse_date(const std::string& s, int order_spec = ymd_order_iso) {
+ std::string spec_str;
+ if(order_spec == ymd_order_iso) {
+ spec_str = "ymd";
+ }
+ else if(order_spec == ymd_order_dmy) {
+ spec_str = "dmy";
+ }
+ else { // (order_spec == ymd_order_us)
+ spec_str = "mdy";
+ }
+
+ typedef typename date_type::year_type year_type;
+ typedef typename date_type::month_type month_type;
+ unsigned pos = 0;
+ unsigned short year(0), month(0), day(0);
+ typedef typename std::basic_string<char>::traits_type traits_type;
+ typedef boost::char_separator<char, traits_type> char_separator_type;
+ typedef boost::tokenizer<char_separator_type,
+ std::basic_string<char>::const_iterator,
+ std::basic_string<char> > tokenizer;
+ typedef boost::tokenizer<char_separator_type,
+ std::basic_string<char>::const_iterator,
+ std::basic_string<char> >::iterator tokenizer_iterator;
+ // may need more delimiters, these work for the regression tests
+ const char sep_char[] = {',','-','.',' ','/','\0'};
+ char_separator_type sep(sep_char);
+ tokenizer tok(s,sep);
+ for(tokenizer_iterator beg=tok.begin();
+ beg!=tok.end() && pos < spec_str.size();
+ ++beg, ++pos) {
+ switch(spec_str.at(pos)) {
+ case 'y':
+ {
+ year = boost::lexical_cast<unsigned short>(*beg);
+ break;
+ }
+ case 'm':
+ {
+ month = month_str_to_ushort<month_type>(*beg);
+ break;
+ }
+ case 'd':
+ {
+ day = boost::lexical_cast<unsigned short>(*beg);
+ break;
+ }
+ } //switch
+ }
+ return date_type(year, month, day);
+ }
+
+ //! Generic function to parse undelimited date (eg: 20020201)
+ template<class date_type>
+ date_type
+ parse_undelimited_date(const std::string& s) {
+ int offsets[] = {4,2,2};
+ int pos = 0;
+ typedef typename date_type::year_type year_type;
+ //typename date_type::ymd_type ymd((year_type::min)(),1,1);
+ unsigned short y = 0, m = 0, d = 0;
+
+ /* The two bool arguments state that parsing will not wrap
+ * (only the first 8 characters will be parsed) and partial
+ * strings will not be parsed.
+ * Ex:
+ * "2005121" will parse 2005 & 12, but not the "1" */
+ boost::offset_separator osf(offsets, offsets+3, false, false);
+
+ typedef typename boost::tokenizer<boost::offset_separator,
+ std::basic_string<char>::const_iterator,
+ std::basic_string<char> > tokenizer_type;
+ tokenizer_type tok(s, osf);
+ for(typename tokenizer_type::iterator ti=tok.begin(); ti!=tok.end();++ti) {
+ unsigned short i = boost::lexical_cast<unsigned short>(*ti);
+ switch(pos) {
+ case 0: y = i; break;
+ case 1: m = i; break;
+ case 2: d = i; break;
+ }
+ pos++;
+ }
+ return date_type(y,m,d);
+ }
+
+ //! Helper function for 'date gregorian::from_stream()'
+ /*! Creates a string from the iterators that reference the
+ * begining & end of a char[] or string. All elements are
+ * used in output string */
+ template<class date_type, class iterator_type>
+ inline
+ date_type
+ from_stream_type(iterator_type& beg,
+ iterator_type const& end,
+ char)
+ {
+ std::ostringstream ss;
+ while(beg != end) {
+ ss << *beg++;
+ }
+ return parse_date<date_type>(ss.str());
+ }
+
+ //! Helper function for 'date gregorian::from_stream()'
+ /*! Returns the first string found in the stream referenced by the
+ * begining & end iterators */
+ template<class date_type, class iterator_type>
+ inline
+ date_type
+ from_stream_type(iterator_type& beg,
+ iterator_type const& /* end */,
+ std::string const&)
+ {
+ return parse_date<date_type>(*beg);
+ }
+
+ /* I believe the wchar stuff would be best elsewhere, perhaps in
+ * parse_date<>()? In the mean time this gets us started... */
+ //! Helper function for 'date gregorian::from_stream()'
+ /*! Creates a string from the iterators that reference the
+ * begining & end of a wstring. All elements are
+ * used in output string */
+ template<class date_type, class iterator_type>
+ inline
+ date_type from_stream_type(iterator_type& beg,
+ iterator_type const& end,
+ wchar_t)
+ {
+ std::ostringstream ss;
+#if !defined(BOOST_DATE_TIME_NO_LOCALE)
+ std::locale loc;
+ std::ctype<wchar_t> const& fac = std::use_facet<std::ctype<wchar_t> >(loc);
+ while(beg != end) {
+ ss << fac.narrow(*beg++, 'X'); // 'X' will cause exception to be thrown
+ }
+#else
+ while(beg != end) {
+ char c = 'X'; // 'X' will cause exception to be thrown
+ const wchar_t wc = *beg++;
+ if (wc >= 0 && wc <= 127)
+ c = static_cast< char >(wc);
+ ss << c;
+ }
+#endif
+ return parse_date<date_type>(ss.str());
+ }
+#ifndef BOOST_NO_STD_WSTRING
+ //! Helper function for 'date gregorian::from_stream()'
+ /*! Creates a string from the first wstring found in the stream
+ * referenced by the begining & end iterators */
+ template<class date_type, class iterator_type>
+ inline
+ date_type
+ from_stream_type(iterator_type& beg,
+ iterator_type const& /* end */,
+ std::wstring const&) {
+ std::wstring ws = *beg;
+ std::ostringstream ss;
+ std::wstring::iterator wsb = ws.begin(), wse = ws.end();
+#if !defined(BOOST_DATE_TIME_NO_LOCALE)
+ std::locale loc;
+ std::ctype<wchar_t> const& fac = std::use_facet<std::ctype<wchar_t> >(loc);
+ while(wsb != wse) {
+ ss << fac.narrow(*wsb++, 'X'); // 'X' will cause exception to be thrown
+ }
+#else
+ while(wsb != wse) {
+ char c = 'X'; // 'X' will cause exception to be thrown
+ const wchar_t wc = *wsb++;
+ if (wc >= 0 && wc <= 127)
+ c = static_cast< char >(wc);
+ ss << c;
+ }
+#endif
+ return parse_date<date_type>(ss.str());
+ }
+#endif // BOOST_NO_STD_WSTRING
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+ // This function cannot be compiled with MSVC 6.0 due to internal compiler shorcomings
+#else
+ //! function called by wrapper functions: date_period_from_(w)string()
+ template<class date_type, class charT>
+ period<date_type, typename date_type::duration_type>
+ from_simple_string_type(const std::basic_string<charT>& s){
+ typedef typename std::basic_string<charT>::traits_type traits_type;
+ typedef typename boost::char_separator<charT, traits_type> char_separator;
+ typedef typename boost::tokenizer<char_separator,
+ typename std::basic_string<charT>::const_iterator,
+ std::basic_string<charT> > tokenizer;
+ const charT sep_list[4] = {'[','/',']','\0'};
+ char_separator sep(sep_list);
+ tokenizer tokens(s, sep);
+ typename tokenizer::iterator tok_it = tokens.begin();
+ std::basic_string<charT> date_string = *tok_it;
+ // get 2 string iterators and generate a date from them
+ typename std::basic_string<charT>::iterator date_string_start = date_string.begin(),
+ date_string_end = date_string.end();
+ typedef typename std::iterator_traits<typename std::basic_string<charT>::iterator>::value_type value_type;
+ date_type d1 = from_stream_type<date_type>(date_string_start, date_string_end, value_type());
+ date_string = *(++tok_it); // next token
+ date_string_start = date_string.begin(), date_string_end = date_string.end();
+ date_type d2 = from_stream_type<date_type>(date_string_start, date_string_end, value_type());
+ return period<date_type, typename date_type::duration_type>(d1, d2);
+ }
+#endif
+
+} } //namespace date_time
+
+
+
+
+#endif
+
diff --git a/ext/boost/date_time/dst_rules.hpp b/ext/boost/date_time/dst_rules.hpp
new file mode 100644
index 0000000000..20cb40b676
--- /dev/null
+++ b/ext/boost/date_time/dst_rules.hpp
@@ -0,0 +1,391 @@
+#ifndef DATE_TIME_DST_RULES_HPP__
+#define DATE_TIME_DST_RULES_HPP__
+
+/* Copyright (c) 2002,2003, 2007 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) $
+ */
+
+/*! @file dst_rules.hpp
+ Contains template class to provide static dst rule calculations
+*/
+
+#include "boost/date_time/date_generators.hpp"
+#include "boost/date_time/period.hpp"
+#include "boost/date_time/date_defs.hpp"
+#include <stdexcept>
+
+namespace boost {
+ namespace date_time {
+
+ enum time_is_dst_result {is_not_in_dst, is_in_dst,
+ ambiguous, invalid_time_label};
+
+
+ //! Dynamic class used to caluclate dst transition information
+ template<class date_type_,
+ class time_duration_type_>
+ class dst_calculator
+ {
+ public:
+ typedef time_duration_type_ time_duration_type;
+ typedef date_type_ date_type;
+
+ //! Check the local time offset when on dst start day
+ /*! On this dst transition, the time label between
+ * the transition boundary and the boudary + the offset
+ * are invalid times. If before the boundary then still
+ * not in dst.
+ *@param time_of_day Time offset in the day for the local time
+ *@param dst_start_offset_minutes Local day offset for start of dst
+ *@param dst_length_minutes Number of minutes to adjust clock forward
+ *@retval status of time label w.r.t. dst
+ */
+ static time_is_dst_result
+ process_local_dst_start_day(const time_duration_type& time_of_day,
+ unsigned int dst_start_offset_minutes,
+ long dst_length_minutes)
+ {
+ //std::cout << "here" << std::endl;
+ if (time_of_day < time_duration_type(0,dst_start_offset_minutes,0)) {
+ return is_not_in_dst;
+ }
+ long offset = dst_start_offset_minutes + dst_length_minutes;
+ if (time_of_day >= time_duration_type(0,offset,0)) {
+ return is_in_dst;
+ }
+ return invalid_time_label;
+ }
+
+ //! Check the local time offset when on the last day of dst
+ /*! This is the calculation for the DST end day. On that day times
+ * prior to the conversion time - dst_length (1 am in US) are still
+ * in dst. Times between the above and the switch time are
+ * ambiguous. Times after the start_offset are not in dst.
+ *@param time_of_day Time offset in the day for the local time
+ *@param dst_end_offset_minutes Local time of day for end of dst
+ *@retval status of time label w.r.t. dst
+ */
+ static time_is_dst_result
+ process_local_dst_end_day(const time_duration_type& time_of_day,
+ unsigned int dst_end_offset_minutes,
+ long dst_length_minutes)
+ {
+ //in US this will be 60 so offset in day is 1,0,0
+ int offset = dst_end_offset_minutes-dst_length_minutes;
+ if (time_of_day < time_duration_type(0,offset,0)) {
+ return is_in_dst;
+ }
+ if (time_of_day >= time_duration_type(0,dst_end_offset_minutes,0)) {
+ return is_not_in_dst;
+ }
+ return ambiguous;
+ }
+
+ //! Calculates if the given local time is dst or not
+ /*! Determines if the time is really in DST or not. Also checks for
+ * invalid and ambiguous.
+ * @param current_day The day to check for dst
+ * @param time_of_day Time offset within the day to check
+ * @param dst_start_day Starting day of dst for the given locality
+ * @param dst_start_offset Time offset within day for dst boundary
+ * @param dst_end_day Ending day of dst for the given locality
+ * @param dst_end_offset Time offset within day given in dst for dst boundary
+ * @param dst_length lenght of dst adjusment
+ * @retval The time is either ambiguous, invalid, in dst, or not in dst
+ */
+ static time_is_dst_result
+ local_is_dst(const date_type& current_day,
+ const time_duration_type& time_of_day,
+ const date_type& dst_start_day,
+ const time_duration_type& dst_start_offset,
+ const date_type& dst_end_day,
+ const time_duration_type& dst_end_offset,
+ const time_duration_type& dst_length_minutes)
+ {
+ unsigned int start_minutes =
+ dst_start_offset.hours() * 60 + dst_start_offset.minutes();
+ unsigned int end_minutes =
+ dst_end_offset.hours() * 60 + dst_end_offset.minutes();
+ long length_minutes =
+ dst_length_minutes.hours() * 60 + dst_length_minutes.minutes();
+
+ return local_is_dst(current_day, time_of_day,
+ dst_start_day, start_minutes,
+ dst_end_day, end_minutes,
+ length_minutes);
+ }
+
+ //! Calculates if the given local time is dst or not
+ /*! Determines if the time is really in DST or not. Also checks for
+ * invalid and ambiguous.
+ * @param current_day The day to check for dst
+ * @param time_of_day Time offset within the day to check
+ * @param dst_start_day Starting day of dst for the given locality
+ * @param dst_start_offset_minutes Offset within day for dst
+ * boundary (eg 120 for US which is 02:00:00)
+ * @param dst_end_day Ending day of dst for the given locality
+ * @param dst_end_offset_minutes Offset within day given in dst for dst
+ * boundary (eg 120 for US which is 02:00:00)
+ * @param dst_length_minutes Length of dst adjusment (eg: 60 for US)
+ * @retval The time is either ambiguous, invalid, in dst, or not in dst
+ */
+ static time_is_dst_result
+ local_is_dst(const date_type& current_day,
+ const time_duration_type& time_of_day,
+ const date_type& dst_start_day,
+ unsigned int dst_start_offset_minutes,
+ const date_type& dst_end_day,
+ unsigned int dst_end_offset_minutes,
+ long dst_length_minutes)
+ {
+ //in northern hemisphere dst is in the middle of the year
+ if (dst_start_day < dst_end_day) {
+ if ((current_day > dst_start_day) && (current_day < dst_end_day)) {
+ return is_in_dst;
+ }
+ if ((current_day < dst_start_day) || (current_day > dst_end_day)) {
+ return is_not_in_dst;
+ }
+ }
+ else {//southern hemisphere dst is at begining /end of year
+ if ((current_day < dst_start_day) && (current_day > dst_end_day)) {
+ return is_not_in_dst;
+ }
+ if ((current_day > dst_start_day) || (current_day < dst_end_day)) {
+ return is_in_dst;
+ }
+ }
+
+ if (current_day == dst_start_day) {
+ return process_local_dst_start_day(time_of_day,
+ dst_start_offset_minutes,
+ dst_length_minutes);
+ }
+
+ if (current_day == dst_end_day) {
+ return process_local_dst_end_day(time_of_day,
+ dst_end_offset_minutes,
+ dst_length_minutes);
+ }
+ //you should never reach this statement
+ return invalid_time_label;
+ }
+
+ };
+
+
+ //! Compile-time configurable daylight savings time calculation engine
+ /* This template provides the ability to configure a daylight savings
+ * calculation at compile time covering all the cases. Unfortunately
+ * because of the number of dimensions related to daylight savings
+ * calculation the number of parameters is high. In addition, the
+ * start and end transition rules are complex types that specify
+ * an algorithm for calculation of the starting day and ending
+ * day of daylight savings time including the month and day
+ * specifications (eg: last sunday in October).
+ *
+ * @param date_type A type that represents dates, typically gregorian::date
+ * @param time_duration_type Used for the offset in the day calculations
+ * @param dst_traits A set of traits that define the rules of dst
+ * calculation. The dst_trait must include the following:
+ * start_rule_functor - Rule to calculate the starting date of a
+ * dst transition (eg: last_kday_of_month).
+ * start_day - static function that returns month of dst start for
+ * start_rule_functor
+ * start_month -static function that returns day or day of week for
+ * dst start of dst
+ * end_rule_functor - Rule to calculate the end of dst day.
+ * end_day - static fucntion that returns end day for end_rule_functor
+ * end_month - static function that returns end month for end_rule_functor
+ * dst_start_offset_minutes - number of minutes from start of day to transition to dst -- 120 (or 2:00 am) is typical for the U.S. and E.U.
+ * dst_start_offset_minutes - number of minutes from start of day to transition off of dst -- 180 (or 3:00 am) is typical for E.U.
+ * dst_length_minutes - number of minutes that dst shifts clock
+ */
+ template<class date_type,
+ class time_duration_type,
+ class dst_traits>
+ class dst_calc_engine
+ {
+ public:
+ typedef typename date_type::year_type year_type;
+ typedef typename date_type::calendar_type calendar_type;
+ typedef dst_calculator<date_type, time_duration_type> dstcalc;
+
+ //! Calculates if the given local time is dst or not
+ /*! Determines if the time is really in DST or not. Also checks for
+ * invalid and ambiguous.
+ * @retval The time is either ambiguous, invalid, in dst, or not in dst
+ */
+ static time_is_dst_result local_is_dst(const date_type& d,
+ const time_duration_type& td)
+ {
+
+ year_type y = d.year();
+ date_type dst_start = local_dst_start_day(y);
+ date_type dst_end = local_dst_end_day(y);
+ return dstcalc::local_is_dst(d,td,
+ dst_start,
+ dst_traits::dst_start_offset_minutes(),
+ dst_end,
+ dst_traits::dst_end_offset_minutes(),
+ dst_traits::dst_shift_length_minutes());
+
+ }
+
+ static bool is_dst_boundary_day(date_type d)
+ {
+ year_type y = d.year();
+ return ((d == local_dst_start_day(y)) ||
+ (d == local_dst_end_day(y)));
+ }
+
+ //! The time of day for the dst transition (eg: typically 01:00:00 or 02:00:00)
+ static time_duration_type dst_offset()
+ {
+ return time_duration_type(0,dst_traits::dst_shift_length_minutes(),0);
+ }
+
+ static date_type local_dst_start_day(year_type year)
+ {
+ return dst_traits::local_dst_start_day(year);
+ }
+
+ static date_type local_dst_end_day(year_type year)
+ {
+ return dst_traits::local_dst_end_day(year);
+ }
+
+
+ };
+
+ //! Depricated: Class to calculate dst boundaries for US time zones
+ /* Use dst_calc_engine instead.
+ * In 2007 US/Canada DST rules changed
+ * (http://en.wikipedia.org/wiki/Energy_Policy_Act_of_2005#Change_to_daylight_saving_time).
+ */
+ template<class date_type_,
+ class time_duration_type_,
+ unsigned int dst_start_offset_minutes=120, //from start of day
+ short dst_length_minutes=60> //1 hour == 60 min in US
+ class us_dst_rules
+ {
+ public:
+ typedef time_duration_type_ time_duration_type;
+ typedef date_type_ date_type;
+ typedef typename date_type::year_type year_type;
+ typedef typename date_type::calendar_type calendar_type;
+ typedef date_time::last_kday_of_month<date_type> lkday;
+ typedef date_time::first_kday_of_month<date_type> fkday;
+ typedef date_time::nth_kday_of_month<date_type> nkday;
+ typedef dst_calculator<date_type, time_duration_type> dstcalc;
+
+ //! Calculates if the given local time is dst or not
+ /*! Determines if the time is really in DST or not. Also checks for
+ * invalid and ambiguous.
+ * @retval The time is either ambiguous, invalid, in dst, or not in dst
+ */
+ static time_is_dst_result local_is_dst(const date_type& d,
+ const time_duration_type& td)
+ {
+
+ year_type y = d.year();
+ date_type dst_start = local_dst_start_day(y);
+ date_type dst_end = local_dst_end_day(y);
+ return dstcalc::local_is_dst(d,td,
+ dst_start,dst_start_offset_minutes,
+ dst_end, dst_start_offset_minutes,
+ dst_length_minutes);
+
+ }
+
+
+ static bool is_dst_boundary_day(date_type d)
+ {
+ year_type y = d.year();
+ return ((d == local_dst_start_day(y)) ||
+ (d == local_dst_end_day(y)));
+ }
+
+ static date_type local_dst_start_day(year_type year)
+ {
+ if (year >= year_type(2007)) {
+ //second sunday in march
+ nkday ssim(nkday::second, Sunday, gregorian::Mar);
+ return ssim.get_date(year);
+ } else {
+ //first sunday in april
+ fkday fsia(Sunday, gregorian::Apr);
+ return fsia.get_date(year);
+ }
+ }
+
+ static date_type local_dst_end_day(year_type year)
+ {
+ if (year >= year_type(2007)) {
+ //first sunday in november
+ fkday fsin(Sunday, gregorian::Nov);
+ return fsin.get_date(year);
+ } else {
+ //last sunday in october
+ lkday lsio(Sunday, gregorian::Oct);
+ return lsio.get_date(year);
+ }
+ }
+
+ static time_duration_type dst_offset()
+ {
+ return time_duration_type(0,dst_length_minutes,0);
+ }
+
+ private:
+
+
+ };
+
+ //! Used for local time adjustments in places that don't use dst
+ template<class date_type_, class time_duration_type_>
+ class null_dst_rules
+ {
+ public:
+ typedef time_duration_type_ time_duration_type;
+ typedef date_type_ date_type;
+
+
+ //! Calculates if the given local time is dst or not
+ /*! @retval Always is_not_in_dst since this is for zones without dst
+ */
+ static time_is_dst_result local_is_dst(const date_type&,
+ const time_duration_type&)
+ {
+ return is_not_in_dst;
+ }
+
+ //! Calculates if the given utc time is in dst
+ static time_is_dst_result utc_is_dst(const date_type&,
+ const time_duration_type&)
+ {
+ return is_not_in_dst;
+ }
+
+ static bool is_dst_boundary_day(date_type d)
+ {
+ return false;
+ }
+
+ static time_duration_type dst_offset()
+ {
+ return time_duration_type(0,0,0);
+ }
+
+ };
+
+
+ } } //namespace date_time
+
+
+
+#endif
diff --git a/ext/boost/date_time/dst_transition_generators.hpp b/ext/boost/date_time/dst_transition_generators.hpp
new file mode 100644
index 0000000000..6c4da1c3c9
--- /dev/null
+++ b/ext/boost/date_time/dst_transition_generators.hpp
@@ -0,0 +1,75 @@
+/* Copyright (c) 2002,2003,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
+ */
+#ifndef DATE_TIME_DATE_DST_TRANSITION_DAY_GEN_HPP__
+#define DATE_TIME_DATE_DST_TRANSITION_DAY_GEN_HPP__
+
+
+
+namespace boost {
+namespace date_time {
+
+ //! Defines base interface for calculating start and end date of daylight savings
+ template<class date_type>
+ class dst_day_calc_rule
+ {
+ public:
+ typedef typename date_type::year_type year_type;
+ virtual ~dst_day_calc_rule() {};
+ virtual date_type start_day(year_type y) const=0;
+ virtual std::string start_rule_as_string() const=0;
+ virtual date_type end_day(year_type y) const=0;
+ virtual std::string end_rule_as_string() const=0;
+
+ };
+
+ //! Canonical form for a class that provides day rule calculation
+ /*! This class is used to generate specific sets of dst rules
+ *
+ *@param spec Provides a specifiction of the function object types used
+ * to generate start and end days of daylight savings as well
+ * as the date type.
+ */
+ template<class spec>
+ class day_calc_dst_rule : public dst_day_calc_rule<typename spec::date_type>
+ {
+ public:
+ typedef typename spec::date_type date_type;
+ typedef typename date_type::year_type year_type;
+ typedef typename spec::start_rule start_rule;
+ typedef typename spec::end_rule end_rule;
+ day_calc_dst_rule(start_rule dst_start,
+ end_rule dst_end) :
+ dst_start_(dst_start),
+ dst_end_(dst_end)
+ {}
+ virtual date_type start_day(year_type y) const
+ {
+ return dst_start_.get_date(y);
+ }
+ virtual std::string start_rule_as_string() const
+ {
+ return dst_start_.to_string();
+ }
+ virtual date_type end_day(year_type y) const
+ {
+ return dst_end_.get_date(y);
+ }
+ virtual std::string end_rule_as_string() const
+ {
+ return dst_end_.to_string();
+ }
+ private:
+ start_rule dst_start_;
+ end_rule dst_end_;
+ };
+
+
+} }//namespace
+
+
+
+#endif
diff --git a/ext/boost/date_time/filetime_functions.hpp b/ext/boost/date_time/filetime_functions.hpp
new file mode 100644
index 0000000000..27ed754f74
--- /dev/null
+++ b/ext/boost/date_time/filetime_functions.hpp
@@ -0,0 +1,170 @@
+#ifndef DATE_TIME_FILETIME_FUNCTIONS_HPP__
+#define DATE_TIME_FILETIME_FUNCTIONS_HPP__
+
+/* Copyright (c) 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: 2009-06-06 07:24:09 -0400 (Sat, 06 Jun 2009) $
+ */
+
+/*! @file filetime_functions.hpp
+ * Function(s) for converting between a FILETIME structure and a
+ * time object. This file is only available on systems that have
+ * BOOST_HAS_FTIME defined.
+ */
+
+#include <boost/date_time/compiler_config.hpp>
+
+#if defined(BOOST_HAS_FTIME) // skip this file if no FILETIME
+
+#if defined(BOOST_USE_WINDOWS_H)
+# include <windows.h>
+#endif
+
+#include <boost/cstdint.hpp>
+#include <boost/date_time/time.hpp>
+#include <boost/date_time/date_defs.hpp>
+
+namespace boost {
+
+namespace date_time {
+
+namespace winapi {
+
+#if !defined(BOOST_USE_WINDOWS_H)
+
+ extern "C" {
+
+ struct FILETIME
+ {
+ boost::uint32_t dwLowDateTime;
+ boost::uint32_t dwHighDateTime;
+ };
+ struct SYSTEMTIME
+ {
+ boost::uint16_t wYear;
+ boost::uint16_t wMonth;
+ boost::uint16_t wDayOfWeek;
+ boost::uint16_t wDay;
+ boost::uint16_t wHour;
+ boost::uint16_t wMinute;
+ boost::uint16_t wSecond;
+ boost::uint16_t wMilliseconds;
+ };
+
+ __declspec(dllimport) void __stdcall GetSystemTimeAsFileTime(FILETIME* lpFileTime);
+ __declspec(dllimport) int __stdcall FileTimeToLocalFileTime(const FILETIME* lpFileTime, FILETIME* lpLocalFileTime);
+ __declspec(dllimport) void __stdcall GetSystemTime(SYSTEMTIME* lpSystemTime);
+ __declspec(dllimport) int __stdcall SystemTimeToFileTime(const SYSTEMTIME* lpSystemTime, FILETIME* lpFileTime);
+
+ } // extern "C"
+
+#endif // defined(BOOST_USE_WINDOWS_H)
+
+ typedef FILETIME file_time;
+ typedef SYSTEMTIME system_time;
+
+ inline void get_system_time_as_file_time(file_time& ft)
+ {
+#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
+ // Some runtime library implementations expect local times as the norm for ctime.
+ file_time ft_utc;
+ GetSystemTimeAsFileTime(&ft_utc);
+ FileTimeToLocalFileTime(&ft_utc, &ft);
+#elif defined(BOOST_NO_GETSYSTEMTIMEASFILETIME)
+ system_time st;
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &ft);
+#else
+ GetSystemTimeAsFileTime(&ft);
+#endif
+ }
+
+ /*!
+ * The function converts file_time into number of microseconds elapsed since 1970-Jan-01
+ *
+ * \note Only dates after 1970-Jan-01 are supported. Dates before will be wrapped.
+ *
+ * \note The function is templated on the FILETIME type, so that
+ * it can be used with both native FILETIME and the ad-hoc
+ * boost::date_time::winapi::file_time type.
+ */
+ template< typename FileTimeT >
+ inline boost::uint64_t file_time_to_microseconds(FileTimeT const& ft)
+ {
+ /* shift is difference between 1970-Jan-01 & 1601-Jan-01
+ * in 100-nanosecond intervals */
+ const uint64_t shift = 116444736000000000ULL; // (27111902 << 32) + 3577643008
+
+ union {
+ FileTimeT as_file_time;
+ uint64_t as_integer; // 100-nanos since 1601-Jan-01
+ } caster;
+ caster.as_file_time = ft;
+
+ caster.as_integer -= shift; // filetime is now 100-nanos since 1970-Jan-01
+ return (caster.as_integer / 10); // truncate to microseconds
+ }
+
+} // namespace winapi
+
+//! Create a time object from an initialized FILETIME struct.
+/*!
+ * Create a time object from an initialized FILETIME struct.
+ * A FILETIME struct holds 100-nanosecond units (0.0000001). When
+ * built with microsecond resolution the file_time's sub second value
+ * will be truncated. Nanosecond resolution has no truncation.
+ *
+ * \note The function is templated on the FILETIME type, so that
+ * it can be used with both native FILETIME and the ad-hoc
+ * boost::date_time::winapi::file_time type.
+ */
+template< typename TimeT, typename FileTimeT >
+inline
+TimeT time_from_ftime(const FileTimeT& ft)
+{
+ typedef typename TimeT::date_type date_type;
+ typedef typename TimeT::date_duration_type date_duration_type;
+ typedef typename TimeT::time_duration_type time_duration_type;
+
+ // https://svn.boost.org/trac/boost/ticket/2523
+ // Since this function can be called with arbitrary times, including ones that
+ // are before 1970-Jan-01, we'll have to cast the time a bit differently,
+ // than it is done in the file_time_to_microseconds function. This allows to
+ // avoid integer wrapping for dates before 1970-Jan-01.
+ union {
+ FileTimeT as_file_time;
+ uint64_t as_integer; // 100-nanos since 1601-Jan-01
+ } caster;
+ caster.as_file_time = ft;
+
+ uint64_t sec = caster.as_integer / 10000000UL;
+ uint32_t sub_sec = (caster.as_integer % 10000000UL) // 100-nanoseconds since the last second
+#if !defined(BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG)
+ / 10; // microseconds since the last second
+#else
+ * 100; // nanoseconds since the last second
+#endif
+
+ // split sec into usable chunks: days, hours, minutes, & seconds
+ const uint32_t sec_per_day = 86400; // seconds per day
+ uint32_t days = static_cast< uint32_t >(sec / sec_per_day);
+ uint32_t tmp = static_cast< uint32_t >(sec % sec_per_day);
+ uint32_t hours = tmp / 3600; // sec_per_hour
+ tmp %= 3600;
+ uint32_t minutes = tmp / 60; // sec_per_min
+ tmp %= 60;
+ uint32_t seconds = tmp; // seconds
+
+ date_duration_type dd(days);
+ date_type d = date_type(1601, Jan, 01) + dd;
+ return TimeT(d, time_duration_type(hours, minutes, seconds, sub_sec));
+}
+
+}} // boost::date_time
+
+#endif // BOOST_HAS_FTIME
+
+#endif // DATE_TIME_FILETIME_FUNCTIONS_HPP__
diff --git a/ext/boost/date_time/format_date_parser.hpp b/ext/boost/date_time/format_date_parser.hpp
new file mode 100644
index 0000000000..a4a4d0dfbe
--- /dev/null
+++ b/ext/boost/date_time/format_date_parser.hpp
@@ -0,0 +1,743 @@
+
+#ifndef DATE_TIME_FORMAT_DATE_PARSER_HPP__
+#define DATE_TIME_FORMAT_DATE_PARSER_HPP__
+
+/* Copyright (c) 2004-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: 2009-06-04 04:24:49 -0400 (Thu, 04 Jun 2009) $
+ */
+
+
+#include "boost/lexical_cast.hpp"
+#include "boost/date_time/string_parse_tree.hpp"
+#include "boost/date_time/strings_from_facet.hpp"
+#include "boost/date_time/special_values_parser.hpp"
+#include <string>
+#include <vector>
+#include <sstream>
+#include <iterator>
+#ifndef BOOST_NO_STDC_NAMESPACE
+# include <cctype>
+#else
+# include <ctype.h>
+#endif
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std {
+ using ::isspace;
+ using ::isdigit;
+}
+#endif
+namespace boost { namespace date_time {
+
+//! Helper function for parsing fixed length strings into integers
+/*! Will consume 'length' number of characters from stream. Consumed
+ * character are transfered to parse_match_result struct.
+ * Returns '-1' if no number can be parsed or incorrect number of
+ * digits in stream. */
+template<typename int_type, typename charT>
+inline
+int_type
+fixed_string_to_int(std::istreambuf_iterator<charT>& itr,
+ std::istreambuf_iterator<charT>& stream_end,
+ parse_match_result<charT>& mr,
+ unsigned int length,
+ const charT& fill_char)
+{
+ //typedef std::basic_string<charT> string_type;
+ unsigned int j = 0;
+ //string_type s;
+ while (j < length && itr != stream_end &&
+ (std::isdigit(*itr) || *itr == fill_char)) {
+ if(*itr == fill_char) {
+ /* Since a fill_char can be anything, we convert it to a zero.
+ * lexical_cast will behave predictably when zero is used as fill. */
+ mr.cache += ('0');
+ }
+ else {
+ mr.cache += (*itr);
+ }
+ itr++;
+ j++;
+ }
+ int_type i = -1;
+ // mr.cache will hold leading zeros. size() tells us when input is too short.
+ if(mr.cache.size() < length) {
+ return i;
+ }
+ try {
+ i = boost::lexical_cast<int_type>(mr.cache);
+ }catch(bad_lexical_cast&){
+ // we want to return -1 if the cast fails so nothing to do here
+ }
+ return i;
+}
+
+//! Helper function for parsing fixed length strings into integers
+/*! Will consume 'length' number of characters from stream. Consumed
+ * character are transfered to parse_match_result struct.
+ * Returns '-1' if no number can be parsed or incorrect number of
+ * digits in stream. */
+template<typename int_type, typename charT>
+inline
+int_type
+fixed_string_to_int(std::istreambuf_iterator<charT>& itr,
+ std::istreambuf_iterator<charT>& stream_end,
+ parse_match_result<charT>& mr,
+ unsigned int length)
+{
+ return fixed_string_to_int<int_type, charT>(itr, stream_end, mr, length, '0');
+}
+
+//! Helper function for parsing varied length strings into integers
+/*! Will consume 'max_length' characters from stream only if those
+ * characters are digits. Returns '-1' if no number can be parsed.
+ * Will not parse a number preceeded by a '+' or '-'. */
+template<typename int_type, typename charT>
+inline
+int_type
+var_string_to_int(std::istreambuf_iterator<charT>& itr,
+ const std::istreambuf_iterator<charT>& stream_end,
+ unsigned int max_length)
+{
+ typedef std::basic_string<charT> string_type;
+ unsigned int j = 0;
+ string_type s;
+ while (itr != stream_end && (j < max_length) && std::isdigit(*itr)) {
+ s += (*itr);
+ ++itr;
+ ++j;
+ }
+ int_type i = -1;
+ if(!s.empty()) {
+ i = boost::lexical_cast<int_type>(s);
+ }
+ return i;
+}
+
+
+//! Class with generic date parsing using a format string
+/*! The following is the set of recognized format specifiers
+ - %a - Short weekday name
+ - %A - Long weekday name
+ - %b - Abbreviated month name
+ - %B - Full month name
+ - %d - Day of the month as decimal 01 to 31
+ - %j - Day of year as decimal from 001 to 366
+ - %m - Month name as a decimal 01 to 12
+ - %U - Week number 00 to 53 with first Sunday as the first day of week 1?
+ - %w - Weekday as decimal number 0 to 6 where Sunday == 0
+ - %W - Week number 00 to 53 where Monday is first day of week 1
+ - %x - facet default date representation
+ - %y - Year without the century - eg: 04 for 2004
+ - %Y - Year with century
+
+ The weekday specifiers (%a and %A) do not add to the date construction,
+ but they provide a way to skip over the weekday names for formats that
+ provide them.
+
+ todo -- Another interesting feature that this approach could provide is
+ an option to fill in any missing fields with the current values
+ from the clock. So if you have %m-%d the parser would detect
+ the missing year value and fill it in using the clock.
+
+ todo -- What to do with the %x. %x in the classic facet is just bad...
+
+ */
+template<class date_type, typename charT>
+class format_date_parser
+{
+ public:
+ typedef std::basic_string<charT> string_type;
+ typedef std::basic_istringstream<charT> stringstream_type;
+ typedef std::istreambuf_iterator<charT> stream_itr_type;
+ typedef typename string_type::const_iterator const_itr;
+ typedef typename date_type::year_type year_type;
+ typedef typename date_type::month_type month_type;
+ typedef typename date_type::day_type day_type;
+ typedef typename date_type::duration_type duration_type;
+ typedef typename date_type::day_of_week_type day_of_week_type;
+ typedef typename date_type::day_of_year_type day_of_year_type;
+ typedef string_parse_tree<charT> parse_tree_type;
+ typedef typename parse_tree_type::parse_match_result_type match_results;
+ typedef std::vector<std::basic_string<charT> > input_collection_type;
+
+ // TODO sv_parser uses its default constructor - write the others
+
+ format_date_parser(const string_type& format_str,
+ const input_collection_type& month_short_names,
+ const input_collection_type& month_long_names,
+ const input_collection_type& weekday_short_names,
+ const input_collection_type& weekday_long_names) :
+ m_format(format_str),
+ m_month_short_names(month_short_names, 1),
+ m_month_long_names(month_long_names, 1),
+ m_weekday_short_names(weekday_short_names),
+ m_weekday_long_names(weekday_long_names)
+ {}
+
+ format_date_parser(const string_type& format_str,
+ const std::locale& locale) :
+ m_format(format_str),
+ m_month_short_names(gather_month_strings<charT>(locale), 1),
+ m_month_long_names(gather_month_strings<charT>(locale, false), 1),
+ m_weekday_short_names(gather_weekday_strings<charT>(locale)),
+ m_weekday_long_names(gather_weekday_strings<charT>(locale, false))
+ {}
+
+ format_date_parser(const format_date_parser<date_type,charT>& fdp)
+ {
+ this->m_format = fdp.m_format;
+ this->m_month_short_names = fdp.m_month_short_names;
+ this->m_month_long_names = fdp.m_month_long_names;
+ this->m_weekday_short_names = fdp.m_weekday_short_names;
+ this->m_weekday_long_names = fdp.m_weekday_long_names;
+ }
+
+ string_type format() const
+ {
+ return m_format;
+ }
+
+ void format(string_type format_str)
+ {
+ m_format = format_str;
+ }
+
+ void short_month_names(const input_collection_type& month_names)
+ {
+ m_month_short_names = parse_tree_type(month_names, 1);
+ }
+ void long_month_names(const input_collection_type& month_names)
+ {
+ m_month_long_names = parse_tree_type(month_names, 1);
+ }
+ void short_weekday_names(const input_collection_type& weekday_names)
+ {
+ m_weekday_short_names = parse_tree_type(weekday_names);
+ }
+ void long_weekday_names(const input_collection_type& weekday_names)
+ {
+ m_weekday_long_names = parse_tree_type(weekday_names);
+ }
+
+ date_type
+ parse_date(const string_type& value,
+ const string_type& format_str,
+ const special_values_parser<date_type,charT>& sv_parser) const
+ {
+ stringstream_type ss(value);
+ stream_itr_type sitr(ss);
+ stream_itr_type stream_end;
+ return parse_date(sitr, stream_end, format_str, sv_parser);
+ }
+
+ date_type
+ parse_date(std::istreambuf_iterator<charT>& sitr,
+ std::istreambuf_iterator<charT>& stream_end,
+ const special_values_parser<date_type,charT>& sv_parser) const
+ {
+ return parse_date(sitr, stream_end, m_format, sv_parser);
+ }
+
+ /*! Of all the objects that the format_date_parser can parse, only a
+ * date can be a special value. Therefore, only parse_date checks
+ * for special_values. */
+ date_type
+ parse_date(std::istreambuf_iterator<charT>& sitr,
+ std::istreambuf_iterator<charT>& stream_end,
+ string_type format_str,
+ const special_values_parser<date_type,charT>& sv_parser) const
+ {
+ bool use_current_char = false;
+
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+ charT current_char = *sitr;
+
+ short year(0), month(0), day(0), day_of_year(0);// wkday(0);
+ /* Initialized the following to their minimum values. These intermediate
+ * objects are used so we get specific exceptions when part of the input
+ * is unparsable.
+ * Ex: "205-Jan-15" will throw a bad_year, "2005-Jsn-15"- bad_month, etc.*/
+ year_type t_year(1400);
+ month_type t_month(1);
+ day_type t_day(1);
+ day_of_week_type wkday(0);
+
+
+ const_itr itr(format_str.begin());
+ while (itr != format_str.end() && (sitr != stream_end)) {
+ if (*itr == '%') {
+ itr++;
+ if (*itr != '%') {
+ switch(*itr) {
+ case 'a':
+ {
+ //this value is just throw away. It could be used for
+ //error checking potentially, but it isn't helpful in
+ //actually constructing the date - we just need to get it
+ //out of the stream
+ match_results mr = m_weekday_short_names.match(sitr, stream_end);
+ if(mr.current_match == match_results::PARSE_ERROR) {
+ // check special_values
+ if(sv_parser.match(sitr, stream_end, mr)) {
+ return date_type(static_cast<special_values>(mr.current_match));
+ }
+ }
+ wkday = mr.current_match;
+ if (mr.has_remaining()) {
+ current_char = mr.last_char();
+ use_current_char = true;
+ }
+ break;
+ }
+ case 'A':
+ {
+ //this value is just throw away. It could be used for
+ //error checking potentially, but it isn't helpful in
+ //actually constructing the date - we just need to get it
+ //out of the stream
+ match_results mr = m_weekday_long_names.match(sitr, stream_end);
+ if(mr.current_match == match_results::PARSE_ERROR) {
+ // check special_values
+ if(sv_parser.match(sitr, stream_end, mr)) {
+ return date_type(static_cast<special_values>(mr.current_match));
+ }
+ }
+ wkday = mr.current_match;
+ if (mr.has_remaining()) {
+ current_char = mr.last_char();
+ use_current_char = true;
+ }
+ break;
+ }
+ case 'b':
+ {
+ match_results mr = m_month_short_names.match(sitr, stream_end);
+ if(mr.current_match == match_results::PARSE_ERROR) {
+ // check special_values
+ if(sv_parser.match(sitr, stream_end, mr)) {
+ return date_type(static_cast<special_values>(mr.current_match));
+ }
+ }
+ t_month = month_type(mr.current_match);
+ if (mr.has_remaining()) {
+ current_char = mr.last_char();
+ use_current_char = true;
+ }
+ break;
+ }
+ case 'B':
+ {
+ match_results mr = m_month_long_names.match(sitr, stream_end);
+ if(mr.current_match == match_results::PARSE_ERROR) {
+ // check special_values
+ if(sv_parser.match(sitr, stream_end, mr)) {
+ return date_type(static_cast<special_values>(mr.current_match));
+ }
+ }
+ t_month = month_type(mr.current_match);
+ if (mr.has_remaining()) {
+ current_char = mr.last_char();
+ use_current_char = true;
+ }
+ break;
+ }
+ case 'd':
+ {
+ match_results mr;
+ day = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2);
+ if(day == -1) {
+ if(sv_parser.match(sitr, stream_end, mr)) {
+ return date_type(static_cast<special_values>(mr.current_match));
+ }
+ }
+ t_day = day_type(day);
+ break;
+ }
+ case 'e':
+ {
+ match_results mr;
+ day = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2, ' ');
+ if(day == -1) {
+ if(sv_parser.match(sitr, stream_end, mr)) {
+ return date_type(static_cast<special_values>(mr.current_match));
+ }
+ }
+ t_day = day_type(day);
+ break;
+ }
+ case 'j':
+ {
+ match_results mr;
+ day_of_year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 3);
+ if(day_of_year == -1) {
+ if(sv_parser.match(sitr, stream_end, mr)) {
+ return date_type(static_cast<special_values>(mr.current_match));
+ }
+ }
+ // these next two lines are so we get an exception with bad input
+ day_of_year_type t_day_of_year(1);
+ t_day_of_year = day_of_year_type(day_of_year);
+ break;
+ }
+ case 'm':
+ {
+ match_results mr;
+ month = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2);
+ if(month == -1) {
+ if(sv_parser.match(sitr, stream_end, mr)) {
+ return date_type(static_cast<special_values>(mr.current_match));
+ }
+ }
+ t_month = month_type(month);
+ break;
+ }
+ case 'Y':
+ {
+ match_results mr;
+ year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 4);
+ if(year == -1) {
+ if(sv_parser.match(sitr, stream_end, mr)) {
+ return date_type(static_cast<special_values>(mr.current_match));
+ }
+ }
+ t_year = year_type(year);
+ break;
+ }
+ case 'y':
+ {
+ match_results mr;
+ year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2);
+ if(year == -1) {
+ if(sv_parser.match(sitr, stream_end, mr)) {
+ return date_type(static_cast<special_values>(mr.current_match));
+ }
+ }
+ year += 2000; //make 2 digit years in this century
+ t_year = year_type(year);
+ break;
+ }
+ default:
+ {} //ignore those we don't understand
+
+ }//switch
+
+ }
+ else { // itr == '%', second consecutive
+ sitr++;
+ }
+
+ itr++; //advance past format specifier
+ }
+ else { //skip past chars in format and in buffer
+ itr++;
+ if (use_current_char) {
+ use_current_char = false;
+ current_char = *sitr;
+ }
+ else {
+ sitr++;
+ }
+ }
+ }
+
+ if (day_of_year > 0) {
+ date_type d(static_cast<unsigned short>(year-1),12,31); //end of prior year
+ return d + duration_type(day_of_year);
+ }
+
+ return date_type(t_year, t_month, t_day); // exceptions were thrown earlier
+ // if input was no good
+ }
+
+ //! Throws bad_month if unable to parse
+ month_type
+ parse_month(std::istreambuf_iterator<charT>& sitr,
+ std::istreambuf_iterator<charT>& stream_end,
+ string_type format_str) const
+ {
+ match_results mr;
+ return parse_month(sitr, stream_end, format_str, mr);
+ }
+
+ //! Throws bad_month if unable to parse
+ month_type
+ parse_month(std::istreambuf_iterator<charT>& sitr,
+ std::istreambuf_iterator<charT>& stream_end,
+ string_type format_str,
+ match_results& mr) const
+ {
+ bool use_current_char = false;
+
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+ charT current_char = *sitr;
+
+ short month(0);
+
+ const_itr itr(format_str.begin());
+ while (itr != format_str.end() && (sitr != stream_end)) {
+ if (*itr == '%') {
+ itr++;
+ if (*itr != '%') {
+ switch(*itr) {
+ case 'b':
+ {
+ mr = m_month_short_names.match(sitr, stream_end);
+ month = mr.current_match;
+ if (mr.has_remaining()) {
+ current_char = mr.last_char();
+ use_current_char = true;
+ }
+ break;
+ }
+ case 'B':
+ {
+ mr = m_month_long_names.match(sitr, stream_end);
+ month = mr.current_match;
+ if (mr.has_remaining()) {
+ current_char = mr.last_char();
+ use_current_char = true;
+ }
+ break;
+ }
+ case 'm':
+ {
+ month = var_string_to_int<short, charT>(sitr, stream_end, 2);
+ // var_string_to_int returns -1 if parse failed. That will
+ // cause a bad_month exception to be thrown so we do nothing here
+ break;
+ }
+ default:
+ {} //ignore those we don't understand
+
+ }//switch
+
+ }
+ else { // itr == '%', second consecutive
+ sitr++;
+ }
+
+ itr++; //advance past format specifier
+ }
+ else { //skip past chars in format and in buffer
+ itr++;
+ if (use_current_char) {
+ use_current_char = false;
+ current_char = *sitr;
+ }
+ else {
+ sitr++;
+ }
+ }
+ }
+
+ return month_type(month); // throws bad_month exception when values are zero
+ }
+
+ //! Expects 1 or 2 digits 1-31. Throws bad_day_of_month if unable to parse
+ day_type
+ parse_var_day_of_month(std::istreambuf_iterator<charT>& sitr,
+ std::istreambuf_iterator<charT>& stream_end) const
+ {
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+ return day_type(var_string_to_int<short, charT>(sitr, stream_end, 2));
+ }
+ //! Expects 2 digits 01-31. Throws bad_day_of_month if unable to parse
+ day_type
+ parse_day_of_month(std::istreambuf_iterator<charT>& sitr,
+ std::istreambuf_iterator<charT>& stream_end) const
+ {
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+ //return day_type(var_string_to_int<short, charT>(sitr, stream_end, 2));
+ match_results mr;
+ return day_type(fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2));
+ }
+
+ day_of_week_type
+ parse_weekday(std::istreambuf_iterator<charT>& sitr,
+ std::istreambuf_iterator<charT>& stream_end,
+ string_type format_str) const
+ {
+ match_results mr;
+ return parse_weekday(sitr, stream_end, format_str, mr);
+ }
+ day_of_week_type
+ parse_weekday(std::istreambuf_iterator<charT>& sitr,
+ std::istreambuf_iterator<charT>& stream_end,
+ string_type format_str,
+ match_results& mr) const
+ {
+ bool use_current_char = false;
+
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+ charT current_char = *sitr;
+
+ short wkday(0);
+
+ const_itr itr(format_str.begin());
+ while (itr != format_str.end() && (sitr != stream_end)) {
+ if (*itr == '%') {
+ itr++;
+ if (*itr != '%') {
+ switch(*itr) {
+ case 'a':
+ {
+ //this value is just throw away. It could be used for
+ //error checking potentially, but it isn't helpful in
+ //actually constructing the date - we just need to get it
+ //out of the stream
+ mr = m_weekday_short_names.match(sitr, stream_end);
+ wkday = mr.current_match;
+ if (mr.has_remaining()) {
+ current_char = mr.last_char();
+ use_current_char = true;
+ }
+ break;
+ }
+ case 'A':
+ {
+ //this value is just throw away. It could be used for
+ //error checking potentially, but it isn't helpful in
+ //actually constructing the date - we just need to get it
+ //out of the stream
+ mr = m_weekday_long_names.match(sitr, stream_end);
+ wkday = mr.current_match;
+ if (mr.has_remaining()) {
+ current_char = mr.last_char();
+ use_current_char = true;
+ }
+ break;
+ }
+ case 'w':
+ {
+ // weekday as number 0-6, Sunday == 0
+ wkday = var_string_to_int<short, charT>(sitr, stream_end, 2);
+ break;
+ }
+ default:
+ {} //ignore those we don't understand
+
+ }//switch
+
+ }
+ else { // itr == '%', second consecutive
+ sitr++;
+ }
+
+ itr++; //advance past format specifier
+ }
+ else { //skip past chars in format and in buffer
+ itr++;
+ if (use_current_char) {
+ use_current_char = false;
+ current_char = *sitr;
+ }
+ else {
+ sitr++;
+ }
+ }
+ }
+
+ return day_of_week_type(wkday); // throws bad_day_of_month exception
+ // when values are zero
+ }
+
+ //! throws bad_year if unable to parse
+ year_type
+ parse_year(std::istreambuf_iterator<charT>& sitr,
+ std::istreambuf_iterator<charT>& stream_end,
+ string_type format_str) const
+ {
+ match_results mr;
+ return parse_year(sitr, stream_end, format_str, mr);
+ }
+
+ //! throws bad_year if unable to parse
+ year_type
+ parse_year(std::istreambuf_iterator<charT>& sitr,
+ std::istreambuf_iterator<charT>& stream_end,
+ string_type format_str,
+ match_results& mr) const
+ {
+ bool use_current_char = false;
+
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+ charT current_char = *sitr;
+
+ unsigned short year(0);
+
+ const_itr itr(format_str.begin());
+ while (itr != format_str.end() && (sitr != stream_end)) {
+ if (*itr == '%') {
+ itr++;
+ if (*itr != '%') {
+ //match_results mr;
+ switch(*itr) {
+ case 'Y':
+ {
+ // year from 4 digit string
+ year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 4);
+ break;
+ }
+ case 'y':
+ {
+ // year from 2 digit string (no century)
+ year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2);
+ year += 2000; //make 2 digit years in this century
+ break;
+ }
+ default:
+ {} //ignore those we don't understand
+
+ }//switch
+
+ }
+ else { // itr == '%', second consecutive
+ sitr++;
+ }
+
+ itr++; //advance past format specifier
+ }
+ else { //skip past chars in format and in buffer
+ itr++;
+ if (use_current_char) {
+ use_current_char = false;
+ current_char = *sitr;
+ }
+ else {
+ sitr++;
+ }
+ }
+ }
+
+ return year_type(year); // throws bad_year exception when values are zero
+ }
+
+
+ private:
+ string_type m_format;
+ parse_tree_type m_month_short_names;
+ parse_tree_type m_month_long_names;
+ parse_tree_type m_weekday_short_names;
+ parse_tree_type m_weekday_long_names;
+
+};
+
+} } //namespace
+
+#endif
+
+
+
diff --git a/ext/boost/date_time/gregorian/conversion.hpp b/ext/boost/date_time/gregorian/conversion.hpp
new file mode 100644
index 0000000000..f35796ee7f
--- /dev/null
+++ b/ext/boost/date_time/gregorian/conversion.hpp
@@ -0,0 +1,66 @@
+#ifndef _GREGORIAN__CONVERSION_HPP___
+#define _GREGORIAN__CONVERSION_HPP___
+
+/* Copyright (c) 2004-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: 2009-06-06 07:27:35 -0400 (Sat, 06 Jun 2009) $
+ */
+
+#include <string>
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/c_time.hpp>
+#include <boost/date_time/special_defs.hpp>
+#include <boost/date_time/gregorian/gregorian_types.hpp>
+
+namespace boost {
+
+namespace gregorian {
+
+ //! Converts a date to a tm struct. Throws out_of_range exception if date is a special value
+ inline
+ std::tm to_tm(const date& d)
+ {
+ if (d.is_special())
+ {
+ std::string s = "tm unable to handle ";
+ switch (d.as_special())
+ {
+ case date_time::not_a_date_time:
+ s += "not-a-date-time value"; break;
+ case date_time::neg_infin:
+ s += "-infinity date value"; break;
+ case date_time::pos_infin:
+ s += "+infinity date value"; break;
+ default:
+ s += "a special date value"; break;
+ }
+ boost::throw_exception(std::out_of_range(s));
+ }
+
+ std::tm datetm = {}; // zero initialization is needed for extension members, like tm_zone
+ boost::gregorian::date::ymd_type ymd = d.year_month_day();
+ datetm.tm_year = ymd.year - 1900;
+ datetm.tm_mon = ymd.month - 1;
+ datetm.tm_mday = ymd.day;
+ datetm.tm_wday = d.day_of_week();
+ datetm.tm_yday = d.day_of_year() - 1;
+ datetm.tm_isdst = -1; // negative because not enough info to set tm_isdst
+ return datetm;
+ }
+
+ //! Converts a tm structure into a date dropping the any time values.
+ inline
+ date date_from_tm(const std::tm& datetm)
+ {
+ return date(static_cast<unsigned short>(datetm.tm_year+1900),
+ static_cast<unsigned short>(datetm.tm_mon+1),
+ static_cast<unsigned short>(datetm.tm_mday));
+ }
+
+} } //namespace boost::gregorian
+
+#endif
diff --git a/ext/boost/date_time/gregorian/formatters.hpp b/ext/boost/date_time/gregorian/formatters.hpp
new file mode 100644
index 0000000000..786e79f2c1
--- /dev/null
+++ b/ext/boost/date_time/gregorian/formatters.hpp
@@ -0,0 +1,162 @@
+#ifndef GREGORIAN_FORMATTERS_HPP___
+#define GREGORIAN_FORMATTERS_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
+#include "boost/date_time/date_formatting_limited.hpp"
+#else
+#include "boost/date_time/date_formatting.hpp"
+#endif
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/date_format_simple.hpp"
+
+/* NOTE: "to_*_string" code for older compilers, ones that define
+ * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in
+ * formatters_limited.hpp
+ */
+
+namespace boost {
+namespace gregorian {
+
+ // wrapper function for to_simple_(w)string(date)
+ template<class charT>
+ inline
+ std::basic_string<charT> to_simple_string_type(const date& d) {
+ return date_time::date_formatter<date,date_time::simple_format<charT>,charT>::date_to_string(d);
+ }
+ //! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01
+ /*!\ingroup date_format
+ */
+ inline std::string to_simple_string(const date& d) {
+ return to_simple_string_type<char>(d);
+ }
+
+
+ // wrapper function for to_simple_(w)string(date_period)
+ template<class charT>
+ inline std::basic_string<charT> to_simple_string_type(const date_period& d) {
+ typedef std::basic_string<charT> string_type;
+ charT b = '[', m = '/', e=']';
+
+ string_type d1(date_time::date_formatter<date,date_time::simple_format<charT>,charT>::date_to_string(d.begin()));
+ string_type d2(date_time::date_formatter<date,date_time::simple_format<charT>,charT>::date_to_string(d.last()));
+ return string_type(b + d1 + m + d2 + e);
+ }
+ //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02]
+ /*!\ingroup date_format
+ */
+ inline std::string to_simple_string(const date_period& d) {
+ return to_simple_string_type<char>(d);
+ }
+
+ // wrapper function for to_iso_(w)string(date_period)
+ template<class charT>
+ inline std::basic_string<charT> to_iso_string_type(const date_period& d) {
+ charT sep = '/';
+ std::basic_string<charT> s(date_time::date_formatter<date,date_time::iso_format<charT>,charT>::date_to_string(d.begin()));
+ return s + sep + date_time::date_formatter<date,date_time::iso_format<charT>,charT>::date_to_string(d.last());
+ }
+ //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231
+ /*!\ingroup date_format
+ */
+ inline std::string to_iso_string(const date_period& d) {
+ return to_iso_string_type<char>(d);
+ }
+
+
+ // wrapper function for to_iso_extended_(w)string(date)
+ template<class charT>
+ inline std::basic_string<charT> to_iso_extended_string_type(const date& d) {
+ return date_time::date_formatter<date,date_time::iso_extended_format<charT>,charT>::date_to_string(d);
+ }
+ //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31
+ /*!\ingroup date_format
+ */
+ inline std::string to_iso_extended_string(const date& d) {
+ return to_iso_extended_string_type<char>(d);
+ }
+
+ // wrapper function for to_iso_(w)string(date)
+ template<class charT>
+ inline std::basic_string<charT> to_iso_string_type(const date& d) {
+ return date_time::date_formatter<date,date_time::iso_format<charT>,charT>::date_to_string(d);
+ }
+ //! Convert to iso standard string YYYYMMDD. Example: 20021231
+ /*!\ingroup date_format
+ */
+ inline std::string to_iso_string(const date& d) {
+ return to_iso_string_type<char>(d);
+ }
+
+
+
+
+ // wrapper function for to_sql_(w)string(date)
+ template<class charT>
+ inline std::basic_string<charT> to_sql_string_type(const date& d)
+ {
+ date::ymd_type ymd = d.year_month_day();
+ std::basic_ostringstream<charT> ss;
+ ss << ymd.year << "-"
+ << std::setw(2) << std::setfill(ss.widen('0'))
+ << ymd.month.as_number() //solves problem with gcc 3.1 hanging
+ << "-"
+ << std::setw(2) << std::setfill(ss.widen('0'))
+ << ymd.day;
+ return ss.str();
+ }
+ inline std::string to_sql_string(const date& d) {
+ return to_sql_string_type<char>(d);
+ }
+
+
+#if !defined(BOOST_NO_STD_WSTRING)
+ //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02]
+ /*!\ingroup date_format
+ */
+ inline std::wstring to_simple_wstring(const date_period& d) {
+ return to_simple_string_type<wchar_t>(d);
+ }
+ //! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01
+ /*!\ingroup date_format
+ */
+ inline std::wstring to_simple_wstring(const date& d) {
+ return to_simple_string_type<wchar_t>(d);
+ }
+ //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231
+ /*!\ingroup date_format
+ */
+ inline std::wstring to_iso_wstring(const date_period& d) {
+ return to_iso_string_type<wchar_t>(d);
+ }
+ //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31
+ /*!\ingroup date_format
+ */
+ inline std::wstring to_iso_extended_wstring(const date& d) {
+ return to_iso_extended_string_type<wchar_t>(d);
+ }
+ //! Convert to iso standard string YYYYMMDD. Example: 20021231
+ /*!\ingroup date_format
+ */
+ inline std::wstring to_iso_wstring(const date& d) {
+ return to_iso_string_type<wchar_t>(d);
+ }
+ inline std::wstring to_sql_wstring(const date& d) {
+ return to_sql_string_type<wchar_t>(d);
+ }
+#endif // BOOST_NO_STD_WSTRING
+
+} } //namespace gregorian
+
+
+#endif
+
diff --git a/ext/boost/date_time/gregorian/formatters_limited.hpp b/ext/boost/date_time/gregorian/formatters_limited.hpp
new file mode 100644
index 0000000000..4531ebec13
--- /dev/null
+++ b/ext/boost/date_time/gregorian/formatters_limited.hpp
@@ -0,0 +1,81 @@
+#ifndef GREGORIAN_FORMATTERS_LIMITED_HPP___
+#define GREGORIAN_FORMATTERS_LIMITED_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#include "boost/date_time/date_formatting_limited.hpp"
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/date_format_simple.hpp"
+#include "boost/date_time/compiler_config.hpp"
+
+namespace boost {
+namespace gregorian {
+
+ //! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01
+ /*!\ingroup date_format
+ */
+ inline std::string to_simple_string(const date& d) {
+ return date_time::date_formatter<date,date_time::simple_format<char> >::date_to_string(d);
+ }
+
+ //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02]
+ /*!\ingroup date_format
+ */
+ inline std::string to_simple_string(const date_period& d) {
+ std::string s("[");
+ std::string d1(date_time::date_formatter<date,date_time::simple_format<char> >::date_to_string(d.begin()));
+ std::string d2(date_time::date_formatter<date,date_time::simple_format<char> >::date_to_string(d.last()));
+ return std::string("[" + d1 + "/" + d2 + "]");
+ }
+
+ //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231
+ /*!\ingroup date_format
+ */
+ inline std::string to_iso_string(const date_period& d) {
+ std::string s(date_time::date_formatter<date,date_time::iso_format<char> >::date_to_string(d.begin()));
+ return s + "/" + date_time::date_formatter<date,date_time::iso_format<char> >::date_to_string(d.last());
+ }
+
+
+ //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31
+ /*!\ingroup date_format
+ */
+ inline std::string to_iso_extended_string(const date& d) {
+ return date_time::date_formatter<date,date_time::iso_extended_format<char> >::date_to_string(d);
+ }
+
+ //! Convert to iso standard string YYYYMMDD. Example: 20021231
+ /*!\ingroup date_format
+ */
+ inline std::string to_iso_string(const date& d) {
+ return date_time::date_formatter<date,date_time::iso_format<char> >::date_to_string(d);
+ }
+
+
+
+ inline std::string to_sql_string(const date& d)
+ {
+ date::ymd_type ymd = d.year_month_day();
+ std::ostringstream ss;
+ ss << ymd.year << "-"
+ << std::setw(2) << std::setfill('0')
+ << ymd.month.as_number() //solves problem with gcc 3.1 hanging
+ << "-"
+ << std::setw(2) << std::setfill('0')
+ << ymd.day;
+ return ss.str();
+ }
+
+
+} } //namespace gregorian
+
+
+#endif
+
diff --git a/ext/boost/date_time/gregorian/greg_calendar.hpp b/ext/boost/date_time/gregorian/greg_calendar.hpp
new file mode 100644
index 0000000000..b8b1f5a69d
--- /dev/null
+++ b/ext/boost/date_time/gregorian/greg_calendar.hpp
@@ -0,0 +1,47 @@
+#ifndef GREGORIAN_GREGORIAN_CALENDAR_HPP__
+#define GREGORIAN_GREGORIAN_CALENDAR_HPP__
+
+/* 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) $
+ */
+
+#include "boost/date_time/gregorian/greg_weekday.hpp"
+#include "boost/date_time/gregorian/greg_day_of_year.hpp"
+#include "boost/date_time/gregorian_calendar.hpp"
+#include "boost/date_time/gregorian/greg_ymd.hpp"
+#include "boost/date_time/int_adapter.hpp"
+
+namespace boost {
+namespace gregorian {
+
+ //!An internal date representation that includes infinities, not a date
+ typedef date_time::int_adapter<unsigned long> fancy_date_rep;
+
+ //! Gregorian calendar for this implementation, hard work in the base
+ class gregorian_calendar :
+ public date_time::gregorian_calendar_base<greg_year_month_day, fancy_date_rep::int_type> {
+ public:
+ //! Type to hold a weekday (eg: Sunday, Monday,...)
+ typedef greg_weekday day_of_week_type;
+ //! Counter type from 1 to 366 for gregorian dates.
+ typedef greg_day_of_year_rep day_of_year_type;
+ //! Internal date representation that handles infinity, not a date
+ typedef fancy_date_rep date_rep_type;
+ //! Date rep implements the traits stuff as well
+ typedef fancy_date_rep date_traits_type;
+
+
+ private:
+ };
+
+} } //namespace gregorian
+
+
+
+
+#endif
+
diff --git a/ext/boost/date_time/gregorian/greg_date.hpp b/ext/boost/date_time/gregorian/greg_date.hpp
new file mode 100644
index 0000000000..56d576fe2d
--- /dev/null
+++ b/ext/boost/date_time/gregorian/greg_date.hpp
@@ -0,0 +1,136 @@
+#ifndef GREG_DATE_HPP___
+#define GREG_DATE_HPP___
+
+/* 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-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/date.hpp>
+#include <boost/date_time/special_defs.hpp>
+#include <boost/date_time/gregorian/greg_calendar.hpp>
+#include <boost/date_time/gregorian/greg_duration.hpp>
+
+namespace boost {
+namespace gregorian {
+
+ //bring special enum values into the namespace
+ using date_time::special_values;
+ using date_time::not_special;
+ using date_time::neg_infin;
+ using date_time::pos_infin;
+ using date_time::not_a_date_time;
+ using date_time::max_date_time;
+ using date_time::min_date_time;
+
+ //! A date type based on gregorian_calendar
+ /*! This class is the primary interface for programming with
+ greogorian dates. The is a lightweight type that can be
+ freely passed by value. All comparison operators are
+ supported.
+ \ingroup date_basics
+ */
+ class date : public date_time::date<date, gregorian_calendar, date_duration>
+ {
+ public:
+ typedef gregorian_calendar::year_type year_type;
+ typedef gregorian_calendar::month_type month_type;
+ typedef gregorian_calendar::day_type day_type;
+ typedef gregorian_calendar::day_of_year_type day_of_year_type;
+ typedef gregorian_calendar::ymd_type ymd_type;
+ typedef gregorian_calendar::date_rep_type date_rep_type;
+ typedef gregorian_calendar::date_int_type date_int_type;
+ typedef date_duration duration_type;
+#if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR)
+ //! Default constructor constructs with not_a_date_time
+ date():
+ date_time::date<date, gregorian_calendar, date_duration>(date_rep_type::from_special(not_a_date_time))
+ {}
+#endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR
+ //! Main constructor with year, month, day
+ date(year_type y, month_type m, day_type d)
+ : date_time::date<date, gregorian_calendar, date_duration>(y, m, d)
+ {
+ if (gregorian_calendar::end_of_month_day(y, m) < d) {
+ boost::throw_exception(bad_day_of_month(std::string("Day of month is not valid for year")));
+ }
+ }
+ //! Constructor from a ymd_type structure
+ explicit date(const ymd_type& ymd)
+ : date_time::date<date, gregorian_calendar, date_duration>(ymd)
+ {}
+ //! Needed copy constructor
+ explicit date(const date_int_type& rhs):
+ date_time::date<date,gregorian_calendar, date_duration>(rhs)
+ {}
+ //! Needed copy constructor
+ explicit date(date_rep_type rhs):
+ date_time::date<date,gregorian_calendar, date_duration>(rhs)
+ {}
+ //! Constructor for infinities, not a date, max and min date
+ explicit date(special_values sv):
+ date_time::date<date, gregorian_calendar, date_duration>(date_rep_type::from_special(sv))
+ {
+ if (sv == min_date_time)
+ {
+ *this = date(1400, 1, 1);
+ }
+ if (sv == max_date_time)
+ {
+ *this = date(9999, 12, 31);
+ }
+
+ }
+ //!Return the Julian Day number for the date.
+ date_int_type julian_day() const
+ {
+ ymd_type ymd = year_month_day();
+ return gregorian_calendar::julian_day_number(ymd);
+ }
+ //!Return the day of year 1..365 or 1..366 (for leap year)
+ day_of_year_type day_of_year() const
+ {
+ date start_of_year(year(), 1, 1);
+ unsigned short doy = static_cast<unsigned short>((*this-start_of_year).days() + 1);
+ return day_of_year_type(doy);
+ }
+ //!Return the Modified Julian Day number for the date.
+ long modjulian_day() const
+ {
+ ymd_type ymd = year_month_day();
+ return gregorian_calendar::modjulian_day_number(ymd);
+ }
+ //!Return the iso 8601 week number 1..53
+ int week_number() const
+ {
+ ymd_type ymd = year_month_day();
+ return gregorian_calendar::week_number(ymd);
+ }
+ //! Return the day number from the calendar
+ date_int_type day_number() const
+ {
+ return days_;
+ }
+ //! Return the last day of the current month
+ date end_of_month() const
+ {
+ ymd_type ymd = year_month_day();
+ short eom_day = gregorian_calendar::end_of_month_day(ymd.year, ymd.month);
+ return date(ymd.year, ymd.month, eom_day);
+ }
+
+ private:
+
+ };
+
+
+
+} } //namespace gregorian
+
+
+
+#endif
diff --git a/ext/boost/date_time/gregorian/greg_day.hpp b/ext/boost/date_time/gregorian/greg_day.hpp
new file mode 100644
index 0000000000..92ea6ab07e
--- /dev/null
+++ b/ext/boost/date_time/gregorian/greg_day.hpp
@@ -0,0 +1,57 @@
+#ifndef GREG_DAY_HPP___
+#define GREG_DAY_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/constrained_value.hpp"
+#include <stdexcept>
+#include <string>
+
+namespace boost {
+namespace gregorian {
+
+ //! Exception type for gregorian day of month (1..31)
+ struct bad_day_of_month : public std::out_of_range
+ {
+ bad_day_of_month() :
+ std::out_of_range(std::string("Day of month value is out of range 1..31"))
+ {}
+ //! Allow other classes to throw with unique string for bad day like Feb 29
+ bad_day_of_month(const std::string& s) :
+ std::out_of_range(s)
+ {}
+ };
+ //! Policy class that declares error handling and day of month ranges
+ typedef CV::simple_exception_policy<unsigned short, 1, 31, bad_day_of_month> greg_day_policies;
+
+ //! Generated represetation for gregorian day of month
+ typedef CV::constrained_value<greg_day_policies> greg_day_rep;
+
+ //! Represent a day of the month (range 1 - 31)
+ /*! This small class allows for simple conversion an integer value into
+ a day of the month for a standard gregorian calendar. The type
+ is automatically range checked so values outside of the range 1-31
+ will cause a bad_day_of_month exception
+ */
+ class greg_day : public greg_day_rep {
+ public:
+ greg_day(unsigned short day_of_month) : greg_day_rep(day_of_month) {}
+ unsigned short as_number() const {return value_;}
+ operator unsigned short() const {return value_;}
+ private:
+
+ };
+
+
+
+} } //namespace gregorian
+
+
+
+#endif
diff --git a/ext/boost/date_time/gregorian/greg_day_of_year.hpp b/ext/boost/date_time/gregorian/greg_day_of_year.hpp
new file mode 100644
index 0000000000..36b22c2b75
--- /dev/null
+++ b/ext/boost/date_time/gregorian/greg_day_of_year.hpp
@@ -0,0 +1,38 @@
+#ifndef GREG_DAY_OF_YEAR_HPP___
+#define GREG_DAY_OF_YEAR_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/constrained_value.hpp"
+#include <stdexcept>
+#include <string>
+
+namespace boost {
+namespace gregorian {
+
+ //! Exception type for day of year (1..366)
+ struct bad_day_of_year : public std::out_of_range
+ {
+ bad_day_of_year() :
+ std::out_of_range(std::string("Day of year value is out of range 1..366"))
+ {}
+ };
+
+ //! A day of the year range (1..366)
+ typedef CV::simple_exception_policy<unsigned short,1,366,bad_day_of_year> greg_day_of_year_policies;
+
+ //! Define a range representation type for the day of the year 1..366
+ typedef CV::constrained_value<greg_day_of_year_policies> greg_day_of_year_rep;
+
+
+} } //namespace gregorian
+
+
+
+#endif
diff --git a/ext/boost/date_time/gregorian/greg_duration.hpp b/ext/boost/date_time/gregorian/greg_duration.hpp
new file mode 100644
index 0000000000..fd7554201e
--- /dev/null
+++ b/ext/boost/date_time/gregorian/greg_duration.hpp
@@ -0,0 +1,134 @@
+#ifndef GREG_DURATION_HPP___
+#define GREG_DURATION_HPP___
+
+/* 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-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <boost/date_time/date_duration.hpp>
+#include <boost/date_time/int_adapter.hpp>
+#include <boost/date_time/special_defs.hpp>
+
+namespace boost {
+namespace gregorian {
+
+ //!An internal date representation that includes infinities, not a date
+ typedef boost::date_time::duration_traits_adapted date_duration_rep;
+
+ //! Durations in days for gregorian system
+ /*! \ingroup date_basics
+ */
+ class date_duration :
+ public boost::date_time::date_duration< date_duration_rep >
+ {
+ typedef boost::date_time::date_duration< date_duration_rep > base_type;
+
+ public:
+ typedef base_type::duration_rep duration_rep;
+
+ //! Construct from a day count
+ explicit date_duration(duration_rep day_count = 0) : base_type(day_count) {}
+
+ //! construct from special_values
+ date_duration(date_time::special_values sv) : base_type(sv) {}
+
+ //! Copy constructor
+ date_duration(const date_duration& other) : base_type(static_cast< base_type const& >(other))
+ {}
+
+ //! Construct from another date_duration
+ date_duration(const base_type& other) : base_type(other)
+ {}
+
+ // Relational operators
+ // NOTE: Because of date_time::date_duration< T > design choice we don't use Boost.Operators here,
+ // because we need the class to be a direct base. Either lose EBO, or define operators by hand.
+ // The latter is more effecient.
+ bool operator== (const date_duration& rhs) const
+ {
+ return base_type::operator== (rhs);
+ }
+ bool operator!= (const date_duration& rhs) const
+ {
+ return !operator== (rhs);
+ }
+ bool operator< (const date_duration& rhs) const
+ {
+ return base_type::operator< (rhs);
+ }
+ bool operator> (const date_duration& rhs) const
+ {
+ return !(base_type::operator< (rhs) || base_type::operator== (rhs));
+ }
+ bool operator<= (const date_duration& rhs) const
+ {
+ return (base_type::operator< (rhs) || base_type::operator== (rhs));
+ }
+ bool operator>= (const date_duration& rhs) const
+ {
+ return !base_type::operator< (rhs);
+ }
+
+ //! Subtract another duration -- result is signed
+ date_duration& operator-= (const date_duration& rhs)
+ {
+ base_type::operator-= (rhs);
+ return *this;
+ }
+ friend date_duration operator- (date_duration rhs, date_duration const& lhs)
+ {
+ rhs -= lhs;
+ return rhs;
+ }
+
+ //! Add a duration -- result is signed
+ date_duration& operator+= (const date_duration& rhs)
+ {
+ base_type::operator+= (rhs);
+ return *this;
+ }
+ friend date_duration operator+ (date_duration rhs, date_duration const& lhs)
+ {
+ rhs += lhs;
+ return rhs;
+ }
+
+ //! unary- Allows for dd = -date_duration(2); -> dd == -2
+ date_duration operator- ()const
+ {
+ return date_duration(get_rep() * (-1));
+ }
+
+ //! Division operations on a duration with an integer.
+ date_duration& operator/= (int divisor)
+ {
+ base_type::operator/= (divisor);
+ return *this;
+ }
+ friend date_duration operator/ (date_duration rhs, int lhs)
+ {
+ rhs /= lhs;
+ return rhs;
+ }
+
+ //! Returns the smallest duration -- used by to calculate 'end'
+ static date_duration unit()
+ {
+ return date_duration(base_type::unit().get_rep());
+ }
+ };
+
+ //! Shorthand for date_duration
+ typedef date_duration days;
+
+} } //namespace gregorian
+
+#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
+#include <boost/date_time/date_duration_types.hpp>
+#endif
+
+#endif
diff --git a/ext/boost/date_time/gregorian/greg_duration_types.hpp b/ext/boost/date_time/gregorian/greg_duration_types.hpp
new file mode 100644
index 0000000000..3d1ce62183
--- /dev/null
+++ b/ext/boost/date_time/gregorian/greg_duration_types.hpp
@@ -0,0 +1,43 @@
+#ifndef GREG_DURATION_TYPES_HPP___
+#define GREG_DURATION_TYPES_HPP___
+
+/* Copyright (c) 2004 CrystalClear Software, Inc.
+ * Subject to 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-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+#include <boost/date_time/gregorian/greg_date.hpp>
+#include <boost/date_time/int_adapter.hpp>
+#include <boost/date_time/adjust_functors.hpp>
+#include <boost/date_time/date_duration_types.hpp>
+#include <boost/date_time/gregorian/greg_duration.hpp>
+
+namespace boost {
+namespace gregorian {
+
+ //! config struct for additional duration types (ie months_duration<> & years_duration<>)
+ struct greg_durations_config {
+ typedef date date_type;
+ typedef date_time::int_adapter<int> int_rep;
+ typedef date_time::month_functor<date_type> month_adjustor_type;
+ };
+
+ typedef date_time::months_duration<greg_durations_config> months;
+ typedef date_time::years_duration<greg_durations_config> years;
+
+ class weeks_duration : public date_duration {
+ public:
+ weeks_duration(duration_rep w)
+ : date_duration(w * 7) {}
+ weeks_duration(date_time::special_values sv)
+ : date_duration(sv) {}
+ };
+
+ typedef weeks_duration weeks;
+
+}} // namespace boost::gregorian
+
+#endif // GREG_DURATION_TYPES_HPP___
diff --git a/ext/boost/date_time/gregorian/greg_facet.hpp b/ext/boost/date_time/gregorian/greg_facet.hpp
new file mode 100644
index 0000000000..9c3877ed03
--- /dev/null
+++ b/ext/boost/date_time/gregorian/greg_facet.hpp
@@ -0,0 +1,354 @@
+#ifndef GREGORIAN_FACET_HPP___
+#define GREGORIAN_FACET_HPP___
+
+/* 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-11-23 06:13:35 -0500 (Sun, 23 Nov 2008) $
+ */
+
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#include "boost/date_time/date_formatting_locales.hpp" // sets BOOST_DATE_TIME_NO_LOCALE
+#include "boost/date_time/gregorian/parsers.hpp"
+
+//This file is basically commented out if locales are not supported
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+
+#include <string>
+#include <memory>
+#include <locale>
+#include <iostream>
+#include <exception>
+
+namespace boost {
+namespace gregorian {
+
+ //! Configuration of the output facet template
+ struct greg_facet_config
+ {
+ typedef boost::gregorian::greg_month month_type;
+ typedef boost::date_time::special_values special_value_enum;
+ typedef boost::gregorian::months_of_year month_enum;
+ typedef boost::date_time::weekdays weekday_enum;
+ };
+
+#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+ //! Create the base facet type for gregorian::date
+ typedef boost::date_time::date_names_put<greg_facet_config> greg_base_facet;
+
+ //! ostream operator for gregorian::date
+ /*! Uses the date facet to determine various output parameters including:
+ * - string values for the month (eg: Jan, Feb, Mar) (default: English)
+ * - string values for special values (eg: not-a-date-time) (default: English)
+ * - selection of long, short strings, or numerical month representation (default: short string)
+ * - month day year order (default yyyy-mmm-dd)
+ */
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os, const date& d)
+ {
+ typedef boost::date_time::date_names_put<greg_facet_config, charT> facet_def;
+ typedef boost::date_time::ostream_date_formatter<date, facet_def, charT> greg_ostream_formatter;
+ greg_ostream_formatter::date_put(d, os);
+ return os;
+ }
+
+ //! operator<< for gregorian::greg_month typically streaming: Jan, Feb, Mar...
+ /*! Uses the date facet to determine output string as well as selection of long or short strings.
+ * Default if no facet is installed is to output a 2 wide numeric value for the month
+ * eg: 01 == Jan, 02 == Feb, ... 12 == Dec.
+ */
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os, const greg_month& m)
+ {
+ typedef boost::date_time::date_names_put<greg_facet_config, charT> facet_def;
+ typedef boost::date_time::ostream_month_formatter<facet_def, charT> greg_month_formatter;
+ std::locale locale = os.getloc();
+ if (std::has_facet<facet_def>(locale)) {
+ const facet_def& f = std::use_facet<facet_def>(locale);
+ greg_month_formatter::format_month(m, os, f);
+
+ }
+ else { //default to numeric
+ charT fill_char = '0';
+ os << std::setw(2) << std::setfill(fill_char) << m.as_number();
+ }
+
+ return os;
+ }
+
+ //! operator<< for gregorian::greg_weekday typically streaming: Sun, Mon, Tue, ...
+ /*! Uses the date facet to determine output string as well as selection of long or short string.
+ * Default if no facet is installed is to output a 3 char english string for the
+ * day of the week.
+ */
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os, const greg_weekday& wd)
+ {
+ typedef boost::date_time::date_names_put<greg_facet_config, charT> facet_def;
+ typedef boost::date_time::ostream_weekday_formatter<greg_weekday, facet_def, charT> greg_weekday_formatter;
+ std::locale locale = os.getloc();
+ if (std::has_facet<facet_def>(locale)) {
+ const facet_def& f = std::use_facet<facet_def>(locale);
+ greg_weekday_formatter::format_weekday(wd.as_enum(), os, f, true);
+ }
+ else { //default to short English string eg: Sun, Mon, Tue, Wed...
+ os << wd.as_short_string();
+ }
+
+ return os;
+ }
+
+ //! operator<< for gregorian::date_period typical output: [2002-Jan-01/2002-Jan-31]
+ /*! Uses the date facet to determine output string as well as selection of long
+ * or short string fr dates.
+ * Default if no facet is installed is to output a 3 char english string for the
+ * day of the week.
+ */
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os, const date_period& dp)
+ {
+ os << '['; //TODO: facet or manipulator for periods?
+ os << dp.begin();
+ os << '/'; //TODO: facet or manipulator for periods?
+ os << dp.last();
+ os << ']';
+ return os;
+ }
+
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os, const date_duration& dd)
+ {
+ //os << dd.days();
+ os << dd.get_rep();
+ return os;
+ }
+
+ //! operator<< for gregorian::partial_date. Output: "Jan 1"
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os, const partial_date& pd)
+ {
+ os << std::setw(2) << std::setfill('0') << pd.day() << ' '
+ << pd.month().as_short_string() ;
+ return os;
+ }
+
+ //! operator<< for gregorian::nth_kday_of_month. Output: "first Mon of Jun"
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os,
+ const nth_kday_of_month& nkd)
+ {
+ os << nkd.nth_week_as_str() << ' '
+ << nkd.day_of_week() << " of "
+ << nkd.month().as_short_string() ;
+ return os;
+ }
+
+ //! operator<< for gregorian::first_kday_of_month. Output: "first Mon of Jun"
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os,
+ const first_kday_of_month& fkd)
+ {
+ os << "first " << fkd.day_of_week() << " of "
+ << fkd.month().as_short_string() ;
+ return os;
+ }
+
+ //! operator<< for gregorian::last_kday_of_month. Output: "last Mon of Jun"
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os,
+ const last_kday_of_month& lkd)
+ {
+ os << "last " << lkd.day_of_week() << " of "
+ << lkd.month().as_short_string() ;
+ return os;
+ }
+
+ //! operator<< for gregorian::first_kday_after. Output: "first Mon after"
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os,
+ const first_kday_after& fka)
+ {
+ os << fka.day_of_week() << " after";
+ return os;
+ }
+
+ //! operator<< for gregorian::first_kday_before. Output: "first Mon before"
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os,
+ const first_kday_before& fkb)
+ {
+ os << fkb.day_of_week() << " before";
+ return os;
+ }
+#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
+ /**************** Input Streaming ******************/
+
+#if !defined(BOOST_NO_STD_ITERATOR_TRAITS)
+ //! operator>> for gregorian::date
+ template<class charT>
+ inline
+ std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, date& d)
+ {
+ std::istream_iterator<std::basic_string<charT>, charT> beg(is), eos;
+
+ typedef boost::date_time::all_date_names_put<greg_facet_config, charT> facet_def;
+ d = from_stream(beg, eos);
+ return is;
+ }
+#endif // BOOST_NO_STD_ITERATOR_TRAITS
+
+ //! operator>> for gregorian::date_duration
+ template<class charT>
+ inline
+ std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is,
+ date_duration& dd)
+ {
+ long v;
+ is >> v;
+ dd = date_duration(v);
+ return is;
+ }
+
+ //! operator>> for gregorian::date_period
+ template<class charT>
+ inline
+ std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is,
+ date_period& dp)
+ {
+ std::basic_string<charT> s;
+ is >> s;
+ dp = date_time::from_simple_string_type<date>(s);
+ return is;
+ }
+
+ //! 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);
+
+ //! Returns a pointer to a facet with a default set of names (English)
+ /* Necessary in the event an exception is thrown from op>> for
+ * weekday or month. See comments in those functions for more info */
+ BOOST_DATE_TIME_DECL boost::date_time::all_date_names_put<greg_facet_config, char>* create_facet_def(char type);
+
+#ifndef BOOST_NO_STD_WSTRING
+ //! 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);
+ //! Returns a pointer to a facet with a default set of names (English)
+ /* Necessary in the event an exception is thrown from op>> for
+ * weekday or month. See comments in those functions for more info */
+ BOOST_DATE_TIME_DECL boost::date_time::all_date_names_put<greg_facet_config, wchar_t>* create_facet_def(wchar_t type);
+#endif // BOOST_NO_STD_WSTRING
+
+ //! operator>> for gregorian::greg_month - throws exception if invalid month given
+ template<class charT>
+ inline
+ std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is,greg_month& m)
+ {
+ typedef boost::date_time::all_date_names_put<greg_facet_config, charT> facet_def;
+
+ std::basic_string<charT> s;
+ is >> s;
+
+ if(!std::has_facet<facet_def>(is.getloc())) {
+ std::locale loc = is.getloc();
+ charT a = '\0';
+ is.imbue(generate_locale(loc, a));
+ }
+
+ short num = 0;
+
+ try{
+ const facet_def& f = std::use_facet<facet_def>(is.getloc());
+ num = date_time::find_match(f.get_short_month_names(),
+ f.get_long_month_names(),
+ (greg_month::max)(), s); // greg_month spans 1..12, so max returns the array size,
+ // which is needed by find_match
+ }
+ /* bad_cast will be thrown if the desired facet is not accessible
+ * so we can generate the facet. This has the drawback of using english
+ * names as a default. */
+ catch(std::bad_cast&){
+ charT a = '\0';
+ std::auto_ptr< const facet_def > f(create_facet_def(a));
+ num = date_time::find_match(f->get_short_month_names(),
+ f->get_long_month_names(),
+ (greg_month::max)(), s); // greg_month spans 1..12, so max returns the array size,
+ // which is needed by find_match
+ }
+
+ ++num; // months numbered 1-12
+ m = greg_month(num);
+
+ return is;
+ }
+
+ //! operator>> for gregorian::greg_weekday - throws exception if invalid weekday given
+ template<class charT>
+ inline
+ std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is,greg_weekday& wd)
+ {
+ typedef boost::date_time::all_date_names_put<greg_facet_config, charT> facet_def;
+
+ std::basic_string<charT> s;
+ is >> s;
+
+ if(!std::has_facet<facet_def>(is.getloc())) {
+ std::locale loc = is.getloc();
+ charT a = '\0';
+ is.imbue(generate_locale(loc, a));
+ }
+
+ short num = 0;
+ try{
+ const facet_def& f = std::use_facet<facet_def>(is.getloc());
+ num = date_time::find_match(f.get_short_weekday_names(),
+ f.get_long_weekday_names(),
+ (greg_weekday::max)() + 1, s); // greg_weekday spans 0..6, so increment is needed
+ // to form the array size which is needed by find_match
+ }
+ /* bad_cast will be thrown if the desired facet is not accessible
+ * so we can generate the facet. This has the drawback of using english
+ * names as a default. */
+ catch(std::bad_cast&){
+ charT a = '\0';
+ std::auto_ptr< const facet_def > f(create_facet_def(a));
+ num = date_time::find_match(f->get_short_weekday_names(),
+ f->get_long_weekday_names(),
+ (greg_weekday::max)() + 1, s); // greg_weekday spans 0..6, so increment is needed
+ // to form the array size which is needed by find_match
+ }
+
+ wd = greg_weekday(num); // weekdays numbered 0-6
+ return is;
+ }
+
+} } //namespace gregorian
+
+#endif
+
+
+#endif
+
diff --git a/ext/boost/date_time/gregorian/greg_month.hpp b/ext/boost/date_time/gregorian/greg_month.hpp
new file mode 100644
index 0000000000..fc9c86148d
--- /dev/null
+++ b/ext/boost/date_time/gregorian/greg_month.hpp
@@ -0,0 +1,105 @@
+#ifndef GREG_MONTH_HPP___
+#define GREG_MONTH_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/constrained_value.hpp"
+#include "boost/date_time/date_defs.hpp"
+#include "boost/shared_ptr.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include <stdexcept>
+#include <string>
+#include <map>
+#include <algorithm>
+#include <cctype>
+
+namespace boost {
+namespace gregorian {
+
+ typedef date_time::months_of_year months_of_year;
+
+ //bring enum values into the namespace
+ using date_time::Jan;
+ using date_time::Feb;
+ using date_time::Mar;
+ using date_time::Apr;
+ using date_time::May;
+ using date_time::Jun;
+ using date_time::Jul;
+ using date_time::Aug;
+ using date_time::Sep;
+ using date_time::Oct;
+ using date_time::Nov;
+ using date_time::Dec;
+ using date_time::NotAMonth;
+ using date_time::NumMonths;
+
+ //! Exception thrown if a greg_month is constructed with a value out of range
+ struct bad_month : public std::out_of_range
+ {
+ bad_month() : std::out_of_range(std::string("Month number is out of range 1..12")) {}
+ };
+ //! Build a policy class for the greg_month_rep
+ typedef CV::simple_exception_policy<unsigned short, 1, 12, bad_month> greg_month_policies;
+ //! A constrained range that implements the gregorian_month rules
+ typedef CV::constrained_value<greg_month_policies> greg_month_rep;
+
+
+ //! Wrapper class to represent months in gregorian based calendar
+ class BOOST_DATE_TIME_DECL greg_month : public greg_month_rep {
+ public:
+ typedef date_time::months_of_year month_enum;
+ typedef std::map<std::string, unsigned short> month_map_type;
+ typedef boost::shared_ptr<month_map_type> month_map_ptr_type;
+ //! Construct a month from the months_of_year enumeration
+ greg_month(month_enum theMonth) :
+ greg_month_rep(static_cast<greg_month_rep::value_type>(theMonth)) {}
+ //! Construct from a short value
+ greg_month(unsigned short theMonth) : greg_month_rep(theMonth) {}
+ //! Convert the value back to a short
+ operator unsigned short() const {return value_;}
+ //! Returns month as number from 1 to 12
+ unsigned short as_number() const {return value_;}
+ month_enum as_enum() const {return static_cast<month_enum>(value_);}
+ const char* as_short_string() const;
+ const char* as_long_string() const;
+#ifndef BOOST_NO_STD_WSTRING
+ const wchar_t* as_short_wstring() const;
+ const wchar_t* as_long_wstring() const;
+#endif // BOOST_NO_STD_WSTRING
+ //! Shared pointer to a map of Month strings (Names & Abbrev) & numbers
+ static month_map_ptr_type get_month_map_ptr();
+
+ /* parameterized as_*_string functions are intended to be called
+ * from a template function: "... as_short_string(charT c='\0');" */
+ const char* as_short_string(char) const
+ {
+ return as_short_string();
+ }
+ const char* as_long_string(char) const
+ {
+ return as_long_string();
+ }
+#ifndef BOOST_NO_STD_WSTRING
+ const wchar_t* as_short_string(wchar_t) const
+ {
+ return as_short_wstring();
+ }
+ const wchar_t* as_long_string(wchar_t) const
+ {
+ return as_long_wstring();
+ }
+#endif // BOOST_NO_STD_WSTRING
+ };
+
+} } //namespace gregorian
+
+
+
+#endif
diff --git a/ext/boost/date_time/gregorian/greg_serialize.hpp b/ext/boost/date_time/gregorian/greg_serialize.hpp
new file mode 100644
index 0000000000..c48cc0ae37
--- /dev/null
+++ b/ext/boost/date_time/gregorian/greg_serialize.hpp
@@ -0,0 +1,489 @@
+#ifndef GREGORIAN_SERIALIZE_HPP___
+#define GREGORIAN_SERIALIZE_HPP___
+
+/* Copyright (c) 2004-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-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#include "boost/date_time/gregorian/parsers.hpp"
+#include "boost/serialization/split_free.hpp"
+
+
+// macros to split serialize functions into save & load functions
+// An expanded version is below for gregorian::date
+// NOTE: these macros define template functions in the boost::serialization namespace.
+// They must be expanded *outside* of any namespace
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_duration)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_duration::duration_rep)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_period)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_month)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_day)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_weekday)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::partial_date)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::nth_kday_of_month)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_of_month)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::last_kday_of_month)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_before)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_after)
+
+namespace boost {
+namespace serialization {
+
+/*! Method that does serialization for gregorian::date -- splits to load/save
+ */
+template<class Archive>
+inline void serialize(Archive & ar,
+ ::boost::gregorian::date & d,
+ const unsigned int file_version)
+{
+ split_free(ar, d, file_version);
+}
+
+//! Function to save gregorian::date objects using serialization lib
+/*! Dates are serialized into a string for transport and storage.
+ * While it would be more efficient to store the internal
+ * integer used to manipulate the dates, it is an unstable solution.
+ */
+template<class Archive>
+void save(Archive & ar,
+ const ::boost::gregorian::date & d,
+ unsigned int /* version */)
+{
+ std::string ds = to_iso_string(d);
+ ar & make_nvp("date", ds);
+}
+
+//! Function to load gregorian::date objects using serialization lib
+/*! Dates are serialized into a string for transport and storage.
+ * While it would be more efficient to store the internal
+ * integer used to manipulate the dates, it is an unstable solution.
+ */
+template<class Archive>
+void load(Archive & ar,
+ ::boost::gregorian::date & d,
+ unsigned int /*version*/)
+{
+ std::string ds;
+ ar & make_nvp("date", ds);
+ try{
+ d = ::boost::gregorian::from_undelimited_string(ds);
+ }catch(bad_lexical_cast&) {
+ gregorian::special_values sv = gregorian::special_value_from_string(ds);
+ if(sv == gregorian::not_special) {
+ throw; // no match found, rethrow original exception
+ }
+ else {
+ d = gregorian::date(sv);
+ }
+ }
+}
+
+
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar,
+ ::boost::gregorian::date* dp,
+ const unsigned int /*file_version*/)
+{
+ // retrieve data from archive required to construct new
+ // invoke inplace constructor to initialize instance of date
+ ::new(dp) ::boost::gregorian::date(::boost::gregorian::not_a_date_time);
+}
+
+/**** date_duration ****/
+
+//! Function to save gregorian::date_duration objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::date_duration & dd,
+ unsigned int /*version*/)
+{
+ typename gregorian::date_duration::duration_rep dr = dd.get_rep();
+ ar & make_nvp("date_duration", dr);
+}
+//! Function to load gregorian::date_duration objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::date_duration & dd, unsigned int /*version*/)
+{
+ typename gregorian::date_duration::duration_rep dr(0);
+ ar & make_nvp("date_duration", dr);
+ dd = gregorian::date_duration(dr);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::date_duration* dd,
+ const unsigned int /*file_version*/)
+{
+ ::new(dd) gregorian::date_duration(gregorian::not_a_date_time);
+}
+
+/**** date_duration::duration_rep (most likely int_adapter) ****/
+
+//! helper unction to save date_duration objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::date_duration::duration_rep & dr,
+ unsigned int /*version*/)
+{
+ typename gregorian::date_duration::duration_rep::int_type it = dr.as_number();
+ ar & make_nvp("date_duration_duration_rep", it);
+}
+//! helper function to load date_duration objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::date_duration::duration_rep & dr, unsigned int /*version*/)
+{
+ typename gregorian::date_duration::duration_rep::int_type it(0);
+ ar & make_nvp("date_duration_duration_rep", it);
+ dr = gregorian::date_duration::duration_rep::int_type(it);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::date_duration::duration_rep* dr,
+ const unsigned int /*file_version*/)
+{
+ ::new(dr) gregorian::date_duration::duration_rep(0);
+}
+
+/**** date_period ****/
+
+//! Function to save gregorian::date_period objects using serialization lib
+/*! date_period objects are broken down into 2 parts for serialization:
+ * the begining date object and the end date object
+ */
+template<class Archive>
+void save(Archive & ar, const gregorian::date_period& dp,
+ unsigned int /*version*/)
+{
+ gregorian::date d1 = dp.begin();
+ gregorian::date d2 = dp.end();
+ ar & make_nvp("date_period_begin_date", d1);
+ ar & make_nvp("date_period_end_date", d2);
+}
+//! Function to load gregorian::date_period objects using serialization lib
+/*! date_period objects are broken down into 2 parts for serialization:
+ * the begining date object and the end date object
+ */
+template<class Archive>
+void load(Archive & ar, gregorian::date_period& dp, unsigned int /*version*/)
+{
+ gregorian::date d1(gregorian::not_a_date_time);
+ gregorian::date d2(gregorian::not_a_date_time);
+ ar & make_nvp("date_period_begin_date", d1);
+ ar & make_nvp("date_period_end_date", d2);
+ dp = gregorian::date_period(d1,d2);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::date_period* dp,
+ const unsigned int /*file_version*/)
+{
+ gregorian::date d(gregorian::not_a_date_time);
+ gregorian::date_duration dd(1);
+ ::new(dp) gregorian::date_period(d,dd);
+}
+
+/**** greg_month ****/
+
+//! Function to save gregorian::greg_month objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::greg_month& gm,
+ unsigned int /*version*/)
+{
+ unsigned short us = gm.as_number();
+ ar & make_nvp("greg_month", us);
+}
+//! Function to load gregorian::greg_month objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::greg_month& gm, unsigned int /*version*/)
+{
+ unsigned short us;
+ ar & make_nvp("greg_month", us);
+ gm = gregorian::greg_month(us);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::greg_month* gm,
+ const unsigned int /*file_version*/)
+{
+ ::new(gm) gregorian::greg_month(1);
+}
+
+/**** greg_day ****/
+
+//! Function to save gregorian::greg_day objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::greg_day& gd,
+ unsigned int /*version*/)
+{
+ unsigned short us = gd.as_number();
+ ar & make_nvp("greg_day", us);
+}
+//! Function to load gregorian::greg_day objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::greg_day& gd, unsigned int /*version*/)
+{
+ unsigned short us;
+ ar & make_nvp("greg_day", us);
+ gd = gregorian::greg_day(us);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::greg_day* gd,
+ const unsigned int /*file_version*/)
+{
+ ::new(gd) gregorian::greg_day(1);
+}
+
+/**** greg_weekday ****/
+
+//! Function to save gregorian::greg_weekday objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::greg_weekday& gd,
+ unsigned int /*version*/)
+{
+ unsigned short us = gd.as_number();
+ ar & make_nvp("greg_weekday", us);
+}
+//! Function to load gregorian::greg_weekday objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::greg_weekday& gd, unsigned int /*version*/)
+{
+ unsigned short us;
+ ar & make_nvp("greg_weekday", us);
+ gd = gregorian::greg_weekday(us);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::greg_weekday* gd,
+ const unsigned int /*file_version*/)
+{
+ ::new(gd) gregorian::greg_weekday(1);
+}
+
+/**** date_generators ****/
+
+/**** partial_date ****/
+
+//! Function to save gregorian::partial_date objects using serialization lib
+/*! partial_date objects are broken down into 2 parts for serialization:
+ * the day (typically greg_day) and month (typically greg_month) objects
+ */
+template<class Archive>
+void save(Archive & ar, const gregorian::partial_date& pd,
+ unsigned int /*version*/)
+{
+ gregorian::greg_day gd(pd.day());
+ gregorian::greg_month gm(pd.month().as_number());
+ ar & make_nvp("partial_date_day", gd);
+ ar & make_nvp("partial_date_month", gm);
+}
+//! Function to load gregorian::partial_date objects using serialization lib
+/*! partial_date objects are broken down into 2 parts for serialization:
+ * the day (greg_day) and month (greg_month) objects
+ */
+template<class Archive>
+void load(Archive & ar, gregorian::partial_date& pd, unsigned int /*version*/)
+{
+ gregorian::greg_day gd(1);
+ gregorian::greg_month gm(1);
+ ar & make_nvp("partial_date_day", gd);
+ ar & make_nvp("partial_date_month", gm);
+ pd = gregorian::partial_date(gd,gm);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::partial_date* pd,
+ const unsigned int /*file_version*/)
+{
+ gregorian::greg_month gm(1);
+ gregorian::greg_day gd(1);
+ ::new(pd) gregorian::partial_date(gd,gm);
+}
+
+/**** nth_kday_of_month ****/
+
+//! Function to save nth_day_of_the_week_in_month objects using serialization lib
+/*! nth_day_of_the_week_in_month objects are broken down into 3 parts for
+ * serialization: the week number, the day of the week, and the month
+ */
+template<class Archive>
+void save(Archive & ar, const gregorian::nth_kday_of_month& nkd,
+ unsigned int /*version*/)
+{
+ typename gregorian::nth_kday_of_month::week_num wn(nkd.nth_week());
+ typename gregorian::nth_kday_of_month::day_of_week_type d(nkd.day_of_week().as_number());
+ typename gregorian::nth_kday_of_month::month_type m(nkd.month().as_number());
+ ar & make_nvp("nth_kday_of_month_week_num", wn);
+ ar & make_nvp("nth_kday_of_month_day_of_week", d);
+ ar & make_nvp("nth_kday_of_month_month", m);
+}
+//! Function to load nth_day_of_the_week_in_month objects using serialization lib
+/*! nth_day_of_the_week_in_month objects are broken down into 3 parts for
+ * serialization: the week number, the day of the week, and the month
+ */
+template<class Archive>
+void load(Archive & ar, gregorian::nth_kday_of_month& nkd, unsigned int /*version*/)
+{
+ typename gregorian::nth_kday_of_month::week_num wn(gregorian::nth_kday_of_month::first);
+ typename gregorian::nth_kday_of_month::day_of_week_type d(gregorian::Monday);
+ typename gregorian::nth_kday_of_month::month_type m(gregorian::Jan);
+ ar & make_nvp("nth_kday_of_month_week_num", wn);
+ ar & make_nvp("nth_kday_of_month_day_of_week", d);
+ ar & make_nvp("nth_kday_of_month_month", m);
+
+ nkd = gregorian::nth_kday_of_month(wn,d,m);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar,
+ gregorian::nth_kday_of_month* nkd,
+ const unsigned int /*file_version*/)
+{
+ // values used are not significant
+ ::new(nkd) gregorian::nth_kday_of_month(gregorian::nth_kday_of_month::first,
+ gregorian::Monday,gregorian::Jan);
+}
+
+/**** first_kday_of_month ****/
+
+//! Function to save first_day_of_the_week_in_month objects using serialization lib
+/*! first_day_of_the_week_in_month objects are broken down into 2 parts for
+ * serialization: the day of the week, and the month
+ */
+template<class Archive>
+void save(Archive & ar, const gregorian::first_kday_of_month& fkd,
+ unsigned int /*version*/)
+{
+ typename gregorian::first_kday_of_month::day_of_week_type d(fkd.day_of_week().as_number());
+ typename gregorian::first_kday_of_month::month_type m(fkd.month().as_number());
+ ar & make_nvp("first_kday_of_month_day_of_week", d);
+ ar & make_nvp("first_kday_of_month_month", m);
+}
+//! Function to load first_day_of_the_week_in_month objects using serialization lib
+/*! first_day_of_the_week_in_month objects are broken down into 2 parts for
+ * serialization: the day of the week, and the month
+ */
+template<class Archive>
+void load(Archive & ar, gregorian::first_kday_of_month& fkd, unsigned int /*version*/)
+{
+ typename gregorian::first_kday_of_month::day_of_week_type d(gregorian::Monday);
+ typename gregorian::first_kday_of_month::month_type m(gregorian::Jan);
+ ar & make_nvp("first_kday_of_month_day_of_week", d);
+ ar & make_nvp("first_kday_of_month_month", m);
+
+ fkd = gregorian::first_kday_of_month(d,m);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar,
+ gregorian::first_kday_of_month* fkd,
+ const unsigned int /*file_version*/)
+{
+ // values used are not significant
+ ::new(fkd) gregorian::first_kday_of_month(gregorian::Monday,gregorian::Jan);
+}
+
+/**** last_kday_of_month ****/
+
+//! Function to save last_day_of_the_week_in_month objects using serialization lib
+/*! last_day_of_the_week_in_month objects are broken down into 2 parts for
+ * serialization: the day of the week, and the month
+ */
+template<class Archive>
+void save(Archive & ar, const gregorian::last_kday_of_month& lkd,
+ unsigned int /*version*/)
+{
+ typename gregorian::last_kday_of_month::day_of_week_type d(lkd.day_of_week().as_number());
+ typename gregorian::last_kday_of_month::month_type m(lkd.month().as_number());
+ ar & make_nvp("last_kday_of_month_day_of_week", d);
+ ar & make_nvp("last_kday_of_month_month", m);
+}
+//! Function to load last_day_of_the_week_in_month objects using serialization lib
+/*! last_day_of_the_week_in_month objects are broken down into 2 parts for
+ * serialization: the day of the week, and the month
+ */
+template<class Archive>
+void load(Archive & ar, gregorian::last_kday_of_month& lkd, unsigned int /*version*/)
+{
+ typename gregorian::last_kday_of_month::day_of_week_type d(gregorian::Monday);
+ typename gregorian::last_kday_of_month::month_type m(gregorian::Jan);
+ ar & make_nvp("last_kday_of_month_day_of_week", d);
+ ar & make_nvp("last_kday_of_month_month", m);
+
+ lkd = gregorian::last_kday_of_month(d,m);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar,
+ gregorian::last_kday_of_month* lkd,
+ const unsigned int /*file_version*/)
+{
+ // values used are not significant
+ ::new(lkd) gregorian::last_kday_of_month(gregorian::Monday,gregorian::Jan);
+}
+
+/**** first_kday_before ****/
+
+//! Function to save first_day_of_the_week_before objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::first_kday_before& fkdb,
+ unsigned int /*version*/)
+{
+ typename gregorian::first_kday_before::day_of_week_type d(fkdb.day_of_week().as_number());
+ ar & make_nvp("first_kday_before_day_of_week", d);
+}
+//! Function to load first_day_of_the_week_before objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::first_kday_before& fkdb, unsigned int /*version*/)
+{
+ typename gregorian::first_kday_before::day_of_week_type d(gregorian::Monday);
+ ar & make_nvp("first_kday_before_day_of_week", d);
+
+ fkdb = gregorian::first_kday_before(d);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar,
+ gregorian::first_kday_before* fkdb,
+ const unsigned int /*file_version*/)
+{
+ // values used are not significant
+ ::new(fkdb) gregorian::first_kday_before(gregorian::Monday);
+}
+
+/**** first_kday_after ****/
+
+//! Function to save first_day_of_the_week_after objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::first_kday_after& fkda,
+ unsigned int /*version*/)
+{
+ typename gregorian::first_kday_after::day_of_week_type d(fkda.day_of_week().as_number());
+ ar & make_nvp("first_kday_after_day_of_week", d);
+}
+//! Function to load first_day_of_the_week_after objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::first_kday_after& fkda, unsigned int /*version*/)
+{
+ typename gregorian::first_kday_after::day_of_week_type d(gregorian::Monday);
+ ar & make_nvp("first_kday_after_day_of_week", d);
+
+ fkda = gregorian::first_kday_after(d);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar,
+ gregorian::first_kday_after* fkda,
+ const unsigned int /*file_version*/)
+{
+ // values used are not significant
+ ::new(fkda) gregorian::first_kday_after(gregorian::Monday);
+}
+
+} // namespace serialization
+} // namespace boost
+
+#endif
diff --git a/ext/boost/date_time/gregorian/greg_weekday.hpp b/ext/boost/date_time/gregorian/greg_weekday.hpp
new file mode 100644
index 0000000000..9b566c440d
--- /dev/null
+++ b/ext/boost/date_time/gregorian/greg_weekday.hpp
@@ -0,0 +1,66 @@
+#ifndef GREG_WEEKDAY_HPP___
+#define GREG_WEEKDAY_HPP___
+
+/* 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-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include "boost/date_time/constrained_value.hpp"
+#include "boost/date_time/date_defs.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include <stdexcept>
+#include <string>
+
+namespace boost {
+namespace gregorian {
+
+ //bring enum values into the namespace
+ using date_time::Sunday;
+ using date_time::Monday;
+ using date_time::Tuesday;
+ using date_time::Wednesday;
+ using date_time::Thursday;
+ using date_time::Friday;
+ using date_time::Saturday;
+
+
+ //! Exception that flags that a weekday number is incorrect
+ struct bad_weekday : public std::out_of_range
+ {
+ bad_weekday() : std::out_of_range(std::string("Weekday is out of range 0..6")) {}
+ };
+ typedef CV::simple_exception_policy<unsigned short, 0, 6, bad_weekday> greg_weekday_policies;
+ typedef CV::constrained_value<greg_weekday_policies> greg_weekday_rep;
+
+
+ //! Represent a day within a week (range 0==Sun to 6==Sat)
+ class BOOST_DATE_TIME_DECL greg_weekday : public greg_weekday_rep {
+ public:
+ typedef boost::date_time::weekdays weekday_enum;
+ greg_weekday(unsigned short day_of_week_num) :
+ greg_weekday_rep(day_of_week_num)
+ {}
+
+ unsigned short as_number() const {return value_;}
+ const char* as_short_string() const;
+ const char* as_long_string() const;
+#ifndef BOOST_NO_STD_WSTRING
+ const wchar_t* as_short_wstring() const;
+ const wchar_t* as_long_wstring() const;
+#endif // BOOST_NO_STD_WSTRING
+ weekday_enum as_enum() const {return static_cast<weekday_enum>(value_);}
+
+
+ };
+
+
+
+} } //namespace gregorian
+
+
+
+#endif
diff --git a/ext/boost/date_time/gregorian/greg_year.hpp b/ext/boost/date_time/gregorian/greg_year.hpp
new file mode 100644
index 0000000000..ef1735f427
--- /dev/null
+++ b/ext/boost/date_time/gregorian/greg_year.hpp
@@ -0,0 +1,53 @@
+#ifndef GREG_YEAR_HPP___
+#define GREG_YEAR_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/constrained_value.hpp"
+#include <stdexcept>
+#include <string>
+
+namespace boost {
+namespace gregorian {
+
+ //! Exception type for gregorian year
+ struct bad_year : public std::out_of_range
+ {
+ bad_year() :
+ std::out_of_range(std::string("Year is out of valid range: 1400..10000"))
+ {}
+ };
+ //! Policy class that declares error handling gregorian year type
+ typedef CV::simple_exception_policy<unsigned short, 1400, 10000, bad_year> greg_year_policies;
+
+ //! Generated representation for gregorian year
+ typedef CV::constrained_value<greg_year_policies> greg_year_rep;
+
+ //! Represent a day of the month (range 1900 - 10000)
+ /*! This small class allows for simple conversion an integer value into
+ a year for the gregorian calendar. This currently only allows a
+ range of 1900 to 10000. Both ends of the range are a bit arbitrary
+ at the moment, but they are the limits of current testing of the
+ library. As such they may be increased in the future.
+ */
+ class greg_year : public greg_year_rep {
+ public:
+ greg_year(unsigned short year) : greg_year_rep(year) {}
+ operator unsigned short() const {return value_;}
+ private:
+
+ };
+
+
+
+} } //namespace gregorian
+
+
+
+#endif
diff --git a/ext/boost/date_time/gregorian/greg_ymd.hpp b/ext/boost/date_time/gregorian/greg_ymd.hpp
new file mode 100644
index 0000000000..086e73df4a
--- /dev/null
+++ b/ext/boost/date_time/gregorian/greg_ymd.hpp
@@ -0,0 +1,33 @@
+#ifndef DATE_TIME_GREG_YMD_HPP__
+#define DATE_TIME_GREG_YMD_HPP__
+
+/* 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) $
+ */
+
+#include "boost/date_time/year_month_day.hpp"
+#include "boost/date_time/special_defs.hpp"
+#include "boost/date_time/gregorian/greg_day.hpp"
+#include "boost/date_time/gregorian/greg_year.hpp"
+#include "boost/date_time/gregorian/greg_month.hpp"
+
+namespace boost {
+namespace gregorian {
+
+ typedef date_time::year_month_day_base<greg_year,
+ greg_month,
+ greg_day> greg_year_month_day;
+
+
+
+} } //namespace gregorian
+
+
+
+
+#endif
+
diff --git a/ext/boost/date_time/gregorian/gregorian.hpp b/ext/boost/date_time/gregorian/gregorian.hpp
new file mode 100644
index 0000000000..bfafa1b037
--- /dev/null
+++ b/ext/boost/date_time/gregorian/gregorian.hpp
@@ -0,0 +1,38 @@
+#ifndef GREGORIAN_HPP__
+#define GREGORIAN_HPP__
+
+/* 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) $
+ */
+
+/*! @file gregorian.hpp
+ Single file header that provides overall include for all elements of
+ the gregorian date-time system. This includes the various types
+ defined, but also other functions for formatting and parsing.
+*/
+
+
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#include "boost/date_time/gregorian/conversion.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
+
+#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+#include "boost/date_time/gregorian/greg_facet.hpp"
+#else
+#include "boost/date_time/gregorian/gregorian_io.hpp"
+#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
+
+#include "boost/date_time/gregorian/parsers.hpp"
+
+
+
+#endif
diff --git a/ext/boost/date_time/gregorian/gregorian_io.hpp b/ext/boost/date_time/gregorian/gregorian_io.hpp
new file mode 100644
index 0000000000..62a759f55c
--- /dev/null
+++ b/ext/boost/date_time/gregorian/gregorian_io.hpp
@@ -0,0 +1,784 @@
+#ifndef DATE_TIME_GREGORIAN_IO_HPP__
+#define DATE_TIME_GREGORIAN_IO_HPP__
+
+/* Copyright (c) 2004-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-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <locale>
+#include <iostream>
+#include <iterator> // i/ostreambuf_iterator
+#include <boost/io/ios_state.hpp>
+#include <boost/date_time/date_facet.hpp>
+#include <boost/date_time/period_parser.hpp>
+#include <boost/date_time/period_formatter.hpp>
+#include <boost/date_time/special_values_parser.hpp>
+#include <boost/date_time/special_values_formatter.hpp>
+#include <boost/date_time/gregorian/gregorian_types.hpp>
+#include <boost/date_time/gregorian/conversion.hpp> // to_tm will be needed in the facets
+
+namespace boost {
+namespace gregorian {
+
+
+ typedef boost::date_time::period_formatter<wchar_t> wperiod_formatter;
+ typedef boost::date_time::period_formatter<char> period_formatter;
+
+ typedef boost::date_time::date_facet<date,wchar_t> wdate_facet;
+ typedef boost::date_time::date_facet<date,char> date_facet;
+
+ typedef boost::date_time::period_parser<date,char> period_parser;
+ typedef boost::date_time::period_parser<date,wchar_t> wperiod_parser;
+
+ typedef boost::date_time::special_values_formatter<char> special_values_formatter;
+ typedef boost::date_time::special_values_formatter<wchar_t> wspecial_values_formatter;
+
+ typedef boost::date_time::special_values_parser<date,char> special_values_parser;
+ typedef boost::date_time::special_values_parser<date,wchar_t> wspecial_values_parser;
+
+ typedef boost::date_time::date_input_facet<date,char> date_input_facet;
+ typedef boost::date_time::date_input_facet<date,wchar_t> wdate_input_facet;
+
+ template <class CharT, class TraitsT>
+ inline std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date& d) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+ std::ostreambuf_iterator<CharT> output_itr(os);
+ if (std::has_facet<custom_date_facet>(os.getloc()))
+ std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), d);
+ else {
+ //instantiate a custom facet for dealing with dates since the user
+ //has not put one in the stream so far. This is for efficiency
+ //since we would always need to reconstruct for every date
+ //if the locale did not already exist. Of course this will be overridden
+ //if the user imbues at some later point. With the default settings
+ //for the facet the resulting format will be the same as the
+ //std::time_facet settings.
+ custom_date_facet* f = new custom_date_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(output_itr, os, os.fill(), d);
+ }
+ return os;
+ }
+
+ //! input operator for date
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, date& d)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<date_input_facet>(is.getloc())) {
+ std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, d);
+ }
+ else {
+ date_input_facet* f = new date_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, d);
+ }
+ }
+ catch(...) {
+ // mask tells us what exceptions are turned on
+ std::ios_base::iostate exception_mask = is.exceptions();
+ // if the user wants exceptions on failbit, we'll rethrow our
+ // date_time exception & set the failbit
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {} // ignore this one
+ throw; // rethrow original exception
+ }
+ else {
+ // if the user want's to fail quietly, we simply set the failbit
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+ template <class CharT, class TraitsT>
+ inline std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date_duration& dd) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+ std::ostreambuf_iterator<CharT> output_itr(os);
+ if (std::has_facet<custom_date_facet>(os.getloc()))
+ std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), dd);
+ else {
+ custom_date_facet* f = new custom_date_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(output_itr, os, os.fill(), dd);
+
+ }
+ return os;
+ }
+
+ //! input operator for date_duration
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, date_duration& dd)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<date_input_facet>(is.getloc())) {
+ std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, dd);
+ }
+ else {
+ date_input_facet* f = new date_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, dd);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+ template <class CharT, class TraitsT>
+ inline std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date_period& dp) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+ std::ostreambuf_iterator<CharT> output_itr(os);
+ if (std::has_facet<custom_date_facet>(os.getloc()))
+ std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), dp);
+ else {
+ //instantiate a custom facet for dealing with date periods since the user
+ //has not put one in the stream so far. This is for efficiency
+ //since we would always need to reconstruct for every time period
+ //if the local did not already exist. Of course this will be overridden
+ //if the user imbues at some later point. With the default settings
+ //for the facet the resulting format will be the same as the
+ //std::time_facet settings.
+ custom_date_facet* f = new custom_date_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(output_itr, os, os.fill(), dp);
+
+ }
+ return os;
+ }
+
+ //! input operator for date_period
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, date_period& dp)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<date_input_facet>(is.getloc())) {
+ std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, dp);
+ }
+ else {
+ date_input_facet* f = new date_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, dp);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+ /********** small gregorian types **********/
+
+ template <class CharT, class TraitsT>
+ inline std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::greg_month& gm) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+ std::ostreambuf_iterator<CharT> output_itr(os);
+ if (std::has_facet<custom_date_facet>(os.getloc()))
+ std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), gm);
+ else {
+ custom_date_facet* f = new custom_date_facet();//-> 10/1074199752/32 because year & day not initialized in put(...)
+ //custom_date_facet* f = new custom_date_facet("%B");
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(output_itr, os, os.fill(), gm);
+ }
+ return os;
+ }
+
+ //! input operator for greg_month
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, greg_month& m)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<date_input_facet>(is.getloc())) {
+ std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, m);
+ }
+ else {
+ date_input_facet* f = new date_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, m);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+
+ template <class CharT, class TraitsT>
+ inline std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::greg_weekday& gw) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+ std::ostreambuf_iterator<CharT> output_itr(os);
+ if (std::has_facet<custom_date_facet>(os.getloc()))
+ std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), gw);
+ else {
+ custom_date_facet* f = new custom_date_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(output_itr, os, os.fill(), gw);
+ }
+ return os;
+ }
+
+ //! input operator for greg_weekday
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, greg_weekday& wd)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<date_input_facet>(is.getloc())) {
+ std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, wd);
+ }
+ else {
+ date_input_facet* f = new date_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, wd);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+ //NOTE: output operator for greg_day was not necessary
+
+ //! input operator for greg_day
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, greg_day& gd)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<date_input_facet>(is.getloc())) {
+ std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, gd);
+ }
+ else {
+ date_input_facet* f = new date_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, gd);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+ //NOTE: output operator for greg_year was not necessary
+
+ //! input operator for greg_year
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, greg_year& gy)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<date_input_facet>(is.getloc())) {
+ std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, gy);
+ }
+ else {
+ date_input_facet* f = new date_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, gy);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+ /********** date generator types **********/
+
+ template <class CharT, class TraitsT>
+ inline std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::partial_date& pd) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+ std::ostreambuf_iterator<CharT> output_itr(os);
+ if (std::has_facet<custom_date_facet>(os.getloc()))
+ std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), pd);
+ else {
+ custom_date_facet* f = new custom_date_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(output_itr, os, os.fill(), pd);
+ }
+ return os;
+ }
+
+ //! input operator for partial_date
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, partial_date& pd)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<date_input_facet>(is.getloc())) {
+ std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, pd);
+ }
+ else {
+ date_input_facet* f = new date_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, pd);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+ template <class CharT, class TraitsT>
+ inline std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::nth_day_of_the_week_in_month& nkd) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+ std::ostreambuf_iterator<CharT> output_itr(os);
+ if (std::has_facet<custom_date_facet>(os.getloc()))
+ std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), nkd);
+ else {
+ custom_date_facet* f = new custom_date_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(output_itr, os, os.fill(), nkd);
+ }
+ return os;
+ }
+
+ //! input operator for nth_day_of_the_week_in_month
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is,
+ nth_day_of_the_week_in_month& nday)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<date_input_facet>(is.getloc())) {
+ std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, nday);
+ }
+ else {
+ date_input_facet* f = new date_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, nday);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+
+ template <class CharT, class TraitsT>
+ inline std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_in_month& fkd) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+ std::ostreambuf_iterator<CharT> output_itr(os);
+ if (std::has_facet<custom_date_facet>(os.getloc()))
+ std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), fkd);
+ else {
+ custom_date_facet* f = new custom_date_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(output_itr, os, os.fill(), fkd);
+ }
+ return os;
+ }
+
+ //! input operator for first_day_of_the_week_in_month
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is,
+ first_day_of_the_week_in_month& fkd)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<date_input_facet>(is.getloc())) {
+ std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, fkd);
+ }
+ else {
+ date_input_facet* f = new date_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, fkd);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+
+ template <class CharT, class TraitsT>
+ inline std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::last_day_of_the_week_in_month& lkd) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+ std::ostreambuf_iterator<CharT> output_itr(os);
+ if (std::has_facet<custom_date_facet>(os.getloc()))
+ std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), lkd);
+ else {
+ custom_date_facet* f = new custom_date_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(output_itr, os, os.fill(), lkd);
+ }
+ return os;
+ }
+
+ //! input operator for last_day_of_the_week_in_month
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is,
+ last_day_of_the_week_in_month& lkd)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<date_input_facet>(is.getloc())) {
+ std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, lkd);
+ }
+ else {
+ date_input_facet* f = new date_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, lkd);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+
+ template <class CharT, class TraitsT>
+ inline std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_after& fda) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+ std::ostreambuf_iterator<CharT> output_itr(os);
+ if (std::has_facet<custom_date_facet>(os.getloc())) {
+ std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), fda);
+ }
+ else {
+ custom_date_facet* f = new custom_date_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(output_itr, os, os.fill(), fda);
+ }
+ return os;
+ }
+
+ //! input operator for first_day_of_the_week_after
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is,
+ first_day_of_the_week_after& fka)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<date_input_facet>(is.getloc())) {
+ std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, fka);
+ }
+ else {
+ date_input_facet* f = new date_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, fka);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+
+ template <class CharT, class TraitsT>
+ inline std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_before& fdb) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+ std::ostreambuf_iterator<CharT> output_itr(os);
+ if (std::has_facet<custom_date_facet>(os.getloc())) {
+ std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), fdb);
+ }
+ else {
+ custom_date_facet* f = new custom_date_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(output_itr, os, os.fill(), fdb);
+ }
+ return os;
+ }
+
+ //! input operator for first_day_of_the_week_before
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is,
+ first_day_of_the_week_before& fkb)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<date_input_facet>(is.getloc())) {
+ std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, fkb);
+ }
+ else {
+ date_input_facet* f = new date_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, fkb);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+
+} } // namespaces
+
+#endif // DATE_TIME_GREGORIAN_IO_HPP__
diff --git a/ext/boost/date_time/gregorian/gregorian_types.hpp b/ext/boost/date_time/gregorian/gregorian_types.hpp
new file mode 100644
index 0000000000..0c74857a25
--- /dev/null
+++ b/ext/boost/date_time/gregorian/gregorian_types.hpp
@@ -0,0 +1,109 @@
+#ifndef _GREGORIAN_TYPES_HPP__
+#define _GREGORIAN_TYPES_HPP__
+
+/* 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) $
+ */
+
+/*! @file gregorian_types.hpp
+ Single file header that defines most of the types for the gregorian
+ date-time system.
+*/
+
+#include "boost/date_time/date.hpp"
+#include "boost/date_time/period.hpp"
+#include "boost/date_time/gregorian/greg_calendar.hpp"
+#include "boost/date_time/gregorian/greg_duration.hpp"
+#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
+#include "boost/date_time/gregorian/greg_duration_types.hpp"
+#endif
+#include "boost/date_time/gregorian/greg_date.hpp"
+#include "boost/date_time/date_generators.hpp"
+#include "boost/date_time/date_clock_device.hpp"
+#include "boost/date_time/date_iterator.hpp"
+#include "boost/date_time/adjust_functors.hpp"
+
+namespace boost {
+
+//! Gregorian date system based on date_time components
+/*! This date system defines a full complement of types including
+ * a date, date_duration, date_period, day_clock, and a
+ * day_iterator.
+ */
+namespace gregorian {
+ //! Date periods for the gregorian system
+ /*!\ingroup date_basics
+ */
+ typedef date_time::period<date, date_duration> date_period;
+
+ //! A unifying date_generator base type
+ /*! A unifying date_generator base type for:
+ * partial_date, nth_day_of_the_week_in_month,
+ * first_day_of_the_week_in_month, and last_day_of_the_week_in_month
+ */
+ typedef date_time::year_based_generator<date> year_based_generator;
+
+ //! A date generation object type
+ typedef date_time::partial_date<date> partial_date;
+
+ typedef date_time::nth_kday_of_month<date> nth_kday_of_month;
+ typedef nth_kday_of_month nth_day_of_the_week_in_month;
+
+ typedef date_time::first_kday_of_month<date> first_kday_of_month;
+ typedef first_kday_of_month first_day_of_the_week_in_month;
+
+ typedef date_time::last_kday_of_month<date> last_kday_of_month;
+ typedef last_kday_of_month last_day_of_the_week_in_month;
+
+ typedef date_time::first_kday_after<date> first_kday_after;
+ typedef first_kday_after first_day_of_the_week_after;
+
+ typedef date_time::first_kday_before<date> first_kday_before;
+ typedef first_kday_before first_day_of_the_week_before;
+
+ //! A clock to get the current day from the local computer
+ /*!\ingroup date_basics
+ */
+ typedef date_time::day_clock<date> day_clock;
+
+ //! Base date_iterator type for gregorian types.
+ /*!\ingroup date_basics
+ */
+ typedef date_time::date_itr_base<date> date_iterator;
+
+ //! A day level iterator
+ /*!\ingroup date_basics
+ */
+ typedef date_time::date_itr<date_time::day_functor<date>,
+ date> day_iterator;
+ //! A week level iterator
+ /*!\ingroup date_basics
+ */
+ typedef date_time::date_itr<date_time::week_functor<date>,
+ date> week_iterator;
+ //! A month level iterator
+ /*!\ingroup date_basics
+ */
+ typedef date_time::date_itr<date_time::month_functor<date>,
+ date> month_iterator;
+ //! A year level iterator
+ /*!\ingroup date_basics
+ */
+ typedef date_time::date_itr<date_time::year_functor<date>,
+ date> year_iterator;
+
+ // bring in these date_generator functions from date_time namespace
+ using date_time::days_until_weekday;
+ using date_time::days_before_weekday;
+ using date_time::next_weekday;
+ using date_time::previous_weekday;
+
+} } //namespace gregorian
+
+
+
+#endif
diff --git a/ext/boost/date_time/gregorian/parsers.hpp b/ext/boost/date_time/gregorian/parsers.hpp
new file mode 100644
index 0000000000..95d4f23dec
--- /dev/null
+++ b/ext/boost/date_time/gregorian/parsers.hpp
@@ -0,0 +1,91 @@
+#ifndef GREGORIAN_PARSERS_HPP___
+#define GREGORIAN_PARSERS_HPP___
+
+/* Copyright (c) 2002,2003,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-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#include "boost/date_time/date_parsing.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/parse_format_base.hpp"
+#include <string>
+#include <sstream>
+
+namespace boost {
+namespace gregorian {
+
+ //! Return special_value from string argument
+ /*! Return special_value from string argument. If argument is
+ * not one of the special value names (defined in src/gregorian/names.hpp),
+ * return 'not_special' */
+ BOOST_DATE_TIME_DECL special_values special_value_from_string(const std::string& s);
+
+ //! Deprecated: Use from_simple_string
+ inline date from_string(std::string s) {
+ return date_time::parse_date<date>(s);
+ }
+
+ //! From delimited date string where with order year-month-day eg: 2002-1-25 or 2003-Jan-25 (full month name is also accepted)
+ inline date from_simple_string(std::string s) {
+ return date_time::parse_date<date>(s, date_time::ymd_order_iso);
+ }
+
+ //! From delimited date string where with order year-month-day eg: 1-25-2003 or Jan-25-2003 (full month name is also accepted)
+ inline date from_us_string(std::string s) {
+ return date_time::parse_date<date>(s, date_time::ymd_order_us);
+ }
+
+ //! From delimited date string where with order day-month-year eg: 25-1-2002 or 25-Jan-2003 (full month name is also accepted)
+ inline date from_uk_string(std::string s) {
+ return date_time::parse_date<date>(s, date_time::ymd_order_dmy);
+ }
+
+ //! From iso type date string where with order year-month-day eg: 20020125
+ inline date from_undelimited_string(std::string s) {
+ return date_time::parse_undelimited_date<date>(s);
+ }
+
+ //! From iso type date string where with order year-month-day eg: 20020125
+ inline date date_from_iso_string(const std::string& s) {
+ return date_time::parse_undelimited_date<date>(s);
+ }
+
+#if !(defined(BOOST_NO_STD_ITERATOR_TRAITS))
+ //! Stream should hold a date in the form of: 2002-1-25. Month number, abbrev, or name are accepted
+ /* Arguments passed in by-value for convertability of char[]
+ * to iterator_type. Calls to from_stream_type are by-reference
+ * since conversion is already done */
+ template<class iterator_type>
+ inline date from_stream(iterator_type beg, iterator_type end) {
+ if(beg == end)
+ {
+ return date(not_a_date_time);
+ }
+ typedef typename std::iterator_traits<iterator_type>::value_type value_type;
+ return date_time::from_stream_type<date>(beg, end, value_type());
+ }
+#endif //BOOST_NO_STD_ITERATOR_TRAITS
+
+#if (defined(_MSC_VER) && (_MSC_VER < 1300))
+ // This function cannot be compiled with MSVC 6.0 due to internal compiler shorcomings
+#else
+ //! Function to parse a date_period from a string (eg: [2003-Oct-31/2003-Dec-25])
+ inline date_period date_period_from_string(const std::string& s){
+ return date_time::from_simple_string_type<date,char>(s);
+ }
+# if !defined(BOOST_NO_STD_WSTRING)
+ //! Function to parse a date_period from a wstring (eg: [2003-Oct-31/2003-Dec-25])
+ inline date_period date_period_from_wstring(const std::wstring& s){
+ return date_time::from_simple_string_type<date,wchar_t>(s);
+ }
+# endif // BOOST_NO_STD_WSTRING
+#endif
+
+} } //namespace gregorian
+
+#endif
diff --git a/ext/boost/date_time/gregorian_calendar.hpp b/ext/boost/date_time/gregorian_calendar.hpp
new file mode 100644
index 0000000000..6386008bea
--- /dev/null
+++ b/ext/boost/date_time/gregorian_calendar.hpp
@@ -0,0 +1,70 @@
+#ifndef DATE_TIME_GREGORIAN_CALENDAR_HPP__
+#define DATE_TIME_GREGORIAN_CALENDAR_HPP__
+
+/* 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) $
+ */
+
+
+namespace boost {
+namespace date_time {
+
+
+ //! An implementation of the Gregorian calendar
+ /*! This is a parameterized implementation of a proleptic Gregorian Calendar that
+ can be used in the creation of date systems or just to perform calculations.
+ All the methods of this class are static functions, so the intent is to
+ never create instances of this class.
+ @param ymd_type_ Struct type representing the year, month, day. The ymd_type must
+ define a of types for the year, month, and day. These types need to be
+ arithmetic types.
+ @param date_int_type_ Underlying type for the date count. Must be an arithmetic type.
+ */
+ template<typename ymd_type_, typename date_int_type_>
+ class gregorian_calendar_base {
+ public:
+ //! define a type a date split into components
+ typedef ymd_type_ ymd_type;
+ //! define a type for representing months
+ typedef typename ymd_type::month_type month_type;
+ //! define a type for representing days
+ typedef typename ymd_type::day_type day_type;
+ //! Type to hold a stand alone year value (eg: 2002)
+ typedef typename ymd_type::year_type year_type;
+ //! Define the integer type to use for internal calculations
+ typedef date_int_type_ date_int_type;
+
+
+ static unsigned short day_of_week(const ymd_type& ymd);
+ static int week_number(const ymd_type&ymd);
+ //static unsigned short day_of_year(date_int_type);
+ static date_int_type day_number(const ymd_type& ymd);
+ static date_int_type julian_day_number(const ymd_type& ymd);
+ static long modjulian_day_number(const ymd_type& ymd);
+ static ymd_type from_day_number(date_int_type);
+ static ymd_type from_julian_day_number(date_int_type);
+ static ymd_type from_modjulian_day_number(long);
+ static bool is_leap_year(year_type);
+ static unsigned short end_of_month_day(year_type y, month_type m);
+ static ymd_type epoch();
+ static unsigned short days_in_week();
+
+ };
+
+
+
+} } //namespace
+
+#ifndef NO_BOOST_DATE_TIME_INLINE
+#include "boost/date_time/gregorian_calendar.ipp"
+#endif
+
+
+
+#endif
+
+
diff --git a/ext/boost/date_time/gregorian_calendar.ipp b/ext/boost/date_time/gregorian_calendar.ipp
new file mode 100644
index 0000000000..b7628fc178
--- /dev/null
+++ b/ext/boost/date_time/gregorian_calendar.ipp
@@ -0,0 +1,219 @@
+/* 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-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#ifndef NO_BOOST_DATE_TIME_INLINE
+ #undef BOOST_DATE_TIME_INLINE
+ #define BOOST_DATE_TIME_INLINE inline
+#endif
+
+namespace boost {
+namespace date_time {
+ //! Return the day of the week (0==Sunday, 1==Monday, etc)
+ /*! Converts a year-month-day into a day of the week number
+ */
+ template<typename ymd_type_, typename date_int_type_>
+ BOOST_DATE_TIME_INLINE
+ unsigned short
+ gregorian_calendar_base<ymd_type_,date_int_type_>::day_of_week(const ymd_type& ymd) {
+ unsigned short a = static_cast<unsigned short>((14-ymd.month)/12);
+ unsigned short y = static_cast<unsigned short>(ymd.year - a);
+ unsigned short m = static_cast<unsigned short>(ymd.month + 12*a - 2);
+ unsigned short d = static_cast<unsigned short>((ymd.day + y + (y/4) - (y/100) + (y/400) + (31*m)/12) % 7);
+ //std::cout << year << "-" << month << "-" << day << " is day: " << d << "\n";
+ return d;
+ }
+
+ //!Return the iso week number for the date
+ /*!Implements the rules associated with the iso 8601 week number.
+ Basically the rule is that Week 1 of the year is the week that contains
+ January 4th or the week that contains the first Thursday in January.
+ Reference for this algorithm is the Calendar FAQ by Claus Tondering, April 2000.
+ */
+ template<typename ymd_type_, typename date_int_type_>
+ BOOST_DATE_TIME_INLINE
+ int
+ gregorian_calendar_base<ymd_type_,date_int_type_>::week_number(const ymd_type& ymd) {
+ unsigned long julianbegin = julian_day_number(ymd_type(ymd.year,1,1));
+ unsigned long juliantoday = julian_day_number(ymd);
+ unsigned long day = (julianbegin + 3) % 7;
+ unsigned long week = (juliantoday + day - julianbegin + 4)/7;
+
+ if ((week >= 1) && (week <= 52)) {
+ return week;
+ }
+
+ if ((week == 53)) {
+ if((day==6) ||(day == 5 && is_leap_year(ymd.year))) {
+ return week; //under these circumstances week == 53.
+ } else {
+ return 1; //monday - wednesday is in week 1 of next year
+ }
+ }
+ //if the week is not in current year recalculate using the previous year as the beginning year
+ else if (week == 0) {
+ julianbegin = julian_day_number(ymd_type(static_cast<unsigned short>(ymd.year-1),1,1));
+ juliantoday = julian_day_number(ymd);
+ day = (julianbegin + 3) % 7;
+ week = (juliantoday + day - julianbegin + 4)/7;
+ return week;
+ }
+
+ return week; //not reachable -- well except if day == 5 and is_leap_year != true
+
+ }
+
+ //! Convert a ymd_type into a day number
+ /*! The day number is an absolute number of days since the start of count
+ */
+ template<typename ymd_type_, typename date_int_type_>
+ BOOST_DATE_TIME_INLINE
+ date_int_type_
+ gregorian_calendar_base<ymd_type_,date_int_type_>::day_number(const ymd_type& ymd)
+ {
+ unsigned short a = static_cast<unsigned short>((14-ymd.month)/12);
+ unsigned short y = static_cast<unsigned short>(ymd.year + 4800 - a);
+ unsigned short m = static_cast<unsigned short>(ymd.month + 12*a - 3);
+ unsigned long d = ymd.day + ((153*m + 2)/5) + 365*y + (y/4) - (y/100) + (y/400) - 32045;
+ return d;
+ }
+
+ //! Convert a year-month-day into the julian day number
+ /*! Since this implementation uses julian day internally, this is the same as the day_number.
+ */
+ template<typename ymd_type_, typename date_int_type_>
+ BOOST_DATE_TIME_INLINE
+ date_int_type_
+ gregorian_calendar_base<ymd_type_,date_int_type_>::julian_day_number(const ymd_type& ymd)
+ {
+ return day_number(ymd);
+ }
+
+ //! Convert year-month-day into a modified julian day number
+ /*! The day number is an absolute number of days.
+ * MJD 0 thus started on 17 Nov 1858(Gregorian) at 00:00:00 UTC
+ */
+ template<typename ymd_type_, typename date_int_type_>
+ BOOST_DATE_TIME_INLINE
+ long
+ gregorian_calendar_base<ymd_type_,date_int_type_>::modjulian_day_number(const ymd_type& ymd)
+ {
+ return julian_day_number(ymd)-2400001; //prerounded
+ }
+
+ //! Change a day number into a year-month-day
+ template<typename ymd_type_, typename date_int_type_>
+ BOOST_DATE_TIME_INLINE
+ ymd_type_
+ gregorian_calendar_base<ymd_type_,date_int_type_>::from_day_number(date_int_type dayNumber)
+ {
+ date_int_type a = dayNumber + 32044;
+ date_int_type b = (4*a + 3)/146097;
+ date_int_type c = a-((146097*b)/4);
+ date_int_type d = (4*c + 3)/1461;
+ date_int_type e = c - (1461*d)/4;
+ date_int_type m = (5*e + 2)/153;
+ unsigned short day = static_cast<unsigned short>(e - ((153*m + 2)/5) + 1);
+ unsigned short month = static_cast<unsigned short>(m + 3 - 12 * (m/10));
+ year_type year = static_cast<unsigned short>(100*b + d - 4800 + (m/10));
+ //std::cout << year << "-" << month << "-" << day << "\n";
+
+ return ymd_type(static_cast<unsigned short>(year),month,day);
+ }
+
+ //! Change a day number into a year-month-day
+ template<typename ymd_type_, typename date_int_type_>
+ BOOST_DATE_TIME_INLINE
+ ymd_type_
+ gregorian_calendar_base<ymd_type_,date_int_type_>::from_julian_day_number(date_int_type dayNumber)
+ {
+ date_int_type a = dayNumber + 32044;
+ date_int_type b = (4*a+3)/146097;
+ date_int_type c = a - ((146097*b)/4);
+ date_int_type d = (4*c + 3)/1461;
+ date_int_type e = c - ((1461*d)/4);
+ date_int_type m = (5*e + 2)/153;
+ unsigned short day = static_cast<unsigned short>(e - ((153*m + 2)/5) + 1);
+ unsigned short month = static_cast<unsigned short>(m + 3 - 12 * (m/10));
+ year_type year = static_cast<year_type>(100*b + d - 4800 + (m/10));
+ //std::cout << year << "-" << month << "-" << day << "\n";
+
+ return ymd_type(year,month,day);
+ }
+
+ //! Change a modified julian day number into a year-month-day
+ template<typename ymd_type_, typename date_int_type_>
+ BOOST_DATE_TIME_INLINE
+ ymd_type_
+ gregorian_calendar_base<ymd_type_,date_int_type_>::from_modjulian_day_number(long dayNumber) {
+ date_int_type jd = dayNumber + 2400001; //is 2400000.5 prerounded
+ return from_julian_day_number(jd);
+ }
+
+ //! Determine if the provided year is a leap year
+ /*!
+ *@return true if year is a leap year, false otherwise
+ */
+ template<typename ymd_type_, typename date_int_type_>
+ BOOST_DATE_TIME_INLINE
+ bool
+ gregorian_calendar_base<ymd_type_,date_int_type_>::is_leap_year(year_type year)
+ {
+ //divisible by 4, not if divisible by 100, but true if divisible by 400
+ return (!(year % 4)) && ((year % 100) || (!(year % 400)));
+ }
+
+ //! Calculate the last day of the month
+ /*! Find the day which is the end of the month given year and month
+ * No error checking is performed.
+ */
+ template<typename ymd_type_, typename date_int_type_>
+ BOOST_DATE_TIME_INLINE
+ unsigned short
+ gregorian_calendar_base<ymd_type_,date_int_type_>::end_of_month_day(year_type year,
+ month_type month)
+ {
+ switch (month) {
+ case 2:
+ if (is_leap_year(year)) {
+ return 29;
+ } else {
+ return 28;
+ };
+ case 4:
+ case 6:
+ case 9:
+ case 11:
+ return 30;
+ default:
+ return 31;
+ };
+
+ }
+
+ //! Provide the ymd_type specification for the calandar start
+ template<typename ymd_type_, typename date_int_type_>
+ BOOST_DATE_TIME_INLINE
+ ymd_type_
+ gregorian_calendar_base<ymd_type_,date_int_type_>::epoch()
+ {
+ return ymd_type(1400,1,1);
+ }
+
+ //! Defines length of a week for week calculations
+ template<typename ymd_type_, typename date_int_type_>
+ BOOST_DATE_TIME_INLINE
+ unsigned short
+ gregorian_calendar_base<ymd_type_,date_int_type_>::days_in_week()
+ {
+ return 7;
+ }
+
+
+} } //namespace gregorian
+
+
diff --git a/ext/boost/date_time/int_adapter.hpp b/ext/boost/date_time/int_adapter.hpp
new file mode 100644
index 0000000000..fc98fc1278
--- /dev/null
+++ b/ext/boost/date_time/int_adapter.hpp
@@ -0,0 +1,509 @@
+#ifndef _DATE_TIME_INT_ADAPTER_HPP__
+#define _DATE_TIME_INT_ADAPTER_HPP__
+
+/* 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-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+#include "boost/config.hpp"
+#include "boost/limits.hpp" //work around compilers without limits
+#include "boost/date_time/special_defs.hpp"
+#include "boost/date_time/locale_config.hpp"
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+# include <ostream>
+#endif
+
+namespace boost {
+namespace date_time {
+
+
+//! Adapter to create integer types with +-infinity, and not a value
+/*! This class is used internally in counted date/time representations.
+ * It adds the floating point like features of infinities and
+ * not a number. It also provides mathmatical operations with
+ * consideration to special values following these rules:
+ *@code
+ * +infinity - infinity == Not A Number (NAN)
+ * infinity * non-zero == infinity
+ * infinity * zero == NAN
+ * +infinity * -integer == -infinity
+ * infinity / infinity == NAN
+ * infinity * infinity == infinity
+ *@endcode
+ */
+template<typename int_type_>
+class int_adapter {
+public:
+ typedef int_type_ int_type;
+ int_adapter(int_type v) :
+ value_(v)
+ {}
+ static bool has_infinity()
+ {
+ return true;
+ }
+ static const int_adapter pos_infinity()
+ {
+ return (::std::numeric_limits<int_type>::max)();
+ }
+ static const int_adapter neg_infinity()
+ {
+ return (::std::numeric_limits<int_type>::min)();
+ }
+ static const int_adapter not_a_number()
+ {
+ return (::std::numeric_limits<int_type>::max)()-1;
+ }
+ static int_adapter max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ {
+ return (::std::numeric_limits<int_type>::max)()-2;
+ }
+ static int_adapter min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+ {
+ return (::std::numeric_limits<int_type>::min)()+1;
+ }
+ static int_adapter from_special(special_values sv)
+ {
+ switch (sv) {
+ case not_a_date_time: return not_a_number();
+ case neg_infin: return neg_infinity();
+ case pos_infin: return pos_infinity();
+ case max_date_time: return (max)();
+ case min_date_time: return (min)();
+ default: return not_a_number();
+ }
+ }
+ static bool is_inf(int_type v)
+ {
+ return (v == neg_infinity().as_number() ||
+ v == pos_infinity().as_number());
+ }
+ static bool is_neg_inf(int_type v)
+ {
+ return (v == neg_infinity().as_number());
+ }
+ static bool is_pos_inf(int_type v)
+ {
+ return (v == pos_infinity().as_number());
+ }
+ static bool is_not_a_number(int_type v)
+ {
+ return (v == not_a_number().as_number());
+ }
+ //! Returns either special value type or is_not_special
+ static special_values to_special(int_type v)
+ {
+ if (is_not_a_number(v)) return not_a_date_time;
+ if (is_neg_inf(v)) return neg_infin;
+ if (is_pos_inf(v)) return pos_infin;
+ return not_special;
+ }
+
+ //-3 leaves room for representations of infinity and not a date
+ static int_type maxcount()
+ {
+ return (::std::numeric_limits<int_type>::max)()-3;
+ }
+ bool is_infinity() const
+ {
+ return (value_ == neg_infinity().as_number() ||
+ value_ == pos_infinity().as_number());
+ }
+ bool is_pos_infinity()const
+ {
+ return(value_ == pos_infinity().as_number());
+ }
+ bool is_neg_infinity()const
+ {
+ return(value_ == neg_infinity().as_number());
+ }
+ bool is_nan() const
+ {
+ return (value_ == not_a_number().as_number());
+ }
+ bool is_special() const
+ {
+ return(is_infinity() || is_nan());
+ }
+ bool operator==(const int_adapter& rhs) const
+ {
+ return (compare(rhs) == 0);
+ }
+ bool operator==(const int& rhs) const
+ {
+ // quiets compiler warnings
+ bool is_signed = std::numeric_limits<int_type>::is_signed;
+ if(!is_signed)
+ {
+ if(is_neg_inf(value_) && rhs == 0)
+ {
+ return false;
+ }
+ }
+ return (compare(rhs) == 0);
+ }
+ bool operator!=(const int_adapter& rhs) const
+ {
+ return (compare(rhs) != 0);
+ }
+ bool operator!=(const int& rhs) const
+ {
+ // quiets compiler warnings
+ bool is_signed = std::numeric_limits<int_type>::is_signed;
+ if(!is_signed)
+ {
+ if(is_neg_inf(value_) && rhs == 0)
+ {
+ return true;
+ }
+ }
+ return (compare(rhs) != 0);
+ }
+ bool operator<(const int_adapter& rhs) const
+ {
+ return (compare(rhs) == -1);
+ }
+ bool operator<(const int& rhs) const
+ {
+ // quiets compiler warnings
+ bool is_signed = std::numeric_limits<int_type>::is_signed;
+ if(!is_signed)
+ {
+ if(is_neg_inf(value_) && rhs == 0)
+ {
+ return true;
+ }
+ }
+ return (compare(rhs) == -1);
+ }
+ bool operator>(const int_adapter& rhs) const
+ {
+ return (compare(rhs) == 1);
+ }
+ int_type as_number() const
+ {
+ return value_;
+ }
+ //! Returns either special value type or is_not_special
+ special_values as_special() const
+ {
+ return int_adapter::to_special(value_);
+ }
+ //creates nasty ambiguities
+// operator int_type() const
+// {
+// return value_;
+// }
+
+ /*! Operator allows for adding dissimilar int_adapter types.
+ * The return type will match that of the the calling object's type */
+ template<class rhs_type>
+ inline
+ int_adapter operator+(const int_adapter<rhs_type>& rhs) const
+ {
+ if(is_special() || rhs.is_special())
+ {
+ if (is_nan() || rhs.is_nan())
+ {
+ return int_adapter::not_a_number();
+ }
+ if((is_pos_inf(value_) && rhs.is_neg_inf(rhs.as_number())) ||
+ (is_neg_inf(value_) && rhs.is_pos_inf(rhs.as_number())) )
+ {
+ return int_adapter::not_a_number();
+ }
+ if (is_infinity())
+ {
+ return *this;
+ }
+ if (rhs.is_pos_inf(rhs.as_number()))
+ {
+ return int_adapter::pos_infinity();
+ }
+ if (rhs.is_neg_inf(rhs.as_number()))
+ {
+ return int_adapter::neg_infinity();
+ }
+ }
+ return int_adapter<int_type>(value_ + rhs.as_number());
+ }
+
+ int_adapter operator+(const int_type rhs) const
+ {
+ if(is_special())
+ {
+ if (is_nan())
+ {
+ return int_adapter<int_type>(not_a_number());
+ }
+ if (is_infinity())
+ {
+ return *this;
+ }
+ }
+ return int_adapter<int_type>(value_ + rhs);
+ }
+
+ /*! Operator allows for subtracting dissimilar int_adapter types.
+ * The return type will match that of the the calling object's type */
+ template<class rhs_type>
+ inline
+ int_adapter operator-(const int_adapter<rhs_type>& rhs)const
+ {
+ if(is_special() || rhs.is_special())
+ {
+ if (is_nan() || rhs.is_nan())
+ {
+ return int_adapter::not_a_number();
+ }
+ if((is_pos_inf(value_) && rhs.is_pos_inf(rhs.as_number())) ||
+ (is_neg_inf(value_) && rhs.is_neg_inf(rhs.as_number())) )
+ {
+ return int_adapter::not_a_number();
+ }
+ if (is_infinity())
+ {
+ return *this;
+ }
+ if (rhs.is_pos_inf(rhs.as_number()))
+ {
+ return int_adapter::neg_infinity();
+ }
+ if (rhs.is_neg_inf(rhs.as_number()))
+ {
+ return int_adapter::pos_infinity();
+ }
+ }
+ return int_adapter<int_type>(value_ - rhs.as_number());
+ }
+ int_adapter operator-(const int_type rhs) const
+ {
+ if(is_special())
+ {
+ if (is_nan())
+ {
+ return int_adapter<int_type>(not_a_number());
+ }
+ if (is_infinity())
+ {
+ return *this;
+ }
+ }
+ return int_adapter<int_type>(value_ - rhs);
+ }
+
+ // should templatize this to be consistant with op +-
+ int_adapter operator*(const int_adapter& rhs)const
+ {
+ if(this->is_special() || rhs.is_special())
+ {
+ return mult_div_specials(rhs);
+ }
+ return int_adapter<int_type>(value_ * rhs.value_);
+ }
+ /*! Provided for cases when automatic conversion from
+ * 'int' to 'int_adapter' causes incorrect results. */
+ int_adapter operator*(const int rhs) const
+ {
+ if(is_special())
+ {
+ return mult_div_specials(rhs);
+ }
+ return int_adapter<int_type>(value_ * rhs);
+ }
+
+ // should templatize this to be consistant with op +-
+ int_adapter operator/(const int_adapter& rhs)const
+ {
+ if(this->is_special() || rhs.is_special())
+ {
+ if(is_infinity() && rhs.is_infinity())
+ {
+ return int_adapter<int_type>(not_a_number());
+ }
+ if(rhs != 0)
+ {
+ return mult_div_specials(rhs);
+ }
+ else { // let divide by zero blow itself up
+ return int_adapter<int_type>(value_ / rhs.value_);
+ }
+ }
+ return int_adapter<int_type>(value_ / rhs.value_);
+ }
+ /*! Provided for cases when automatic conversion from
+ * 'int' to 'int_adapter' causes incorrect results. */
+ int_adapter operator/(const int rhs) const
+ {
+ if(is_special() && rhs != 0)
+ {
+ return mult_div_specials(rhs);
+ }
+ return int_adapter<int_type>(value_ / rhs);
+ }
+
+ // should templatize this to be consistant with op +-
+ int_adapter operator%(const int_adapter& rhs)const
+ {
+ if(this->is_special() || rhs.is_special())
+ {
+ if(is_infinity() && rhs.is_infinity())
+ {
+ return int_adapter<int_type>(not_a_number());
+ }
+ if(rhs != 0)
+ {
+ return mult_div_specials(rhs);
+ }
+ else { // let divide by zero blow itself up
+ return int_adapter<int_type>(value_ % rhs.value_);
+ }
+ }
+ return int_adapter<int_type>(value_ % rhs.value_);
+ }
+ /*! Provided for cases when automatic conversion from
+ * 'int' to 'int_adapter' causes incorrect results. */
+ int_adapter operator%(const int rhs) const
+ {
+ if(is_special() && rhs != 0)
+ {
+ return mult_div_specials(rhs);
+ }
+ return int_adapter<int_type>(value_ % rhs);
+ }
+private:
+ int_type value_;
+
+ //! returns -1, 0, 1, or 2 if 'this' is <, ==, >, or 'nan comparison' rhs
+ int compare(const int_adapter& rhs)const
+ {
+ if(this->is_special() || rhs.is_special())
+ {
+ if(this->is_nan() || rhs.is_nan()) {
+ if(this->is_nan() && rhs.is_nan()) {
+ return 0; // equal
+ }
+ else {
+ return 2; // nan
+ }
+ }
+ if((is_neg_inf(value_) && !is_neg_inf(rhs.value_)) ||
+ (is_pos_inf(rhs.value_) && !is_pos_inf(value_)) )
+ {
+ return -1; // less than
+ }
+ if((is_pos_inf(value_) && !is_pos_inf(rhs.value_)) ||
+ (is_neg_inf(rhs.value_) && !is_neg_inf(value_)) ) {
+ return 1; // greater than
+ }
+ }
+ if(value_ < rhs.value_) return -1;
+ if(value_ > rhs.value_) return 1;
+ // implied-> if(value_ == rhs.value_)
+ return 0;
+ }
+ /* When multiplying and dividing with at least 1 special value
+ * very simmilar rules apply. In those cases where the rules
+ * are different, they are handled in the respective operator
+ * function. */
+ //! Assumes at least 'this' or 'rhs' is a special value
+ int_adapter mult_div_specials(const int_adapter& rhs)const
+ {
+ int min_value;
+ // quiets compiler warnings
+ bool is_signed = std::numeric_limits<int_type>::is_signed;
+ if(is_signed) {
+ min_value = 0;
+ }
+ else {
+ min_value = 1;// there is no zero with unsigned
+ }
+ if(this->is_nan() || rhs.is_nan()) {
+ return int_adapter<int_type>(not_a_number());
+ }
+ if((*this > 0 && rhs > 0) || (*this < min_value && rhs < min_value)) {
+ return int_adapter<int_type>(pos_infinity());
+ }
+ if((*this > 0 && rhs < min_value) || (*this < min_value && rhs > 0)) {
+ return int_adapter<int_type>(neg_infinity());
+ }
+ //implied -> if(this->value_ == 0 || rhs.value_ == 0)
+ return int_adapter<int_type>(not_a_number());
+ }
+ /* Overloaded function necessary because of special
+ * situation where int_adapter is instantiated with
+ * 'unsigned' and func is called with negative int.
+ * It would produce incorrect results since 'unsigned'
+ * wraps around when initialized with a negative value */
+ //! Assumes 'this' is a special value
+ int_adapter mult_div_specials(const int& rhs) const
+ {
+ int min_value;
+ // quiets compiler warnings
+ bool is_signed = std::numeric_limits<int_type>::is_signed;
+ if(is_signed) {
+ min_value = 0;
+ }
+ else {
+ min_value = 1;// there is no zero with unsigned
+ }
+ if(this->is_nan()) {
+ return int_adapter<int_type>(not_a_number());
+ }
+ if((*this > 0 && rhs > 0) || (*this < min_value && rhs < 0)) {
+ return int_adapter<int_type>(pos_infinity());
+ }
+ if((*this > 0 && rhs < 0) || (*this < min_value && rhs > 0)) {
+ return int_adapter<int_type>(neg_infinity());
+ }
+ //implied -> if(this->value_ == 0 || rhs.value_ == 0)
+ return int_adapter<int_type>(not_a_number());
+ }
+
+};
+
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+ /*! Expected output is either a numeric representation
+ * or a special values representation.<BR>
+ * Ex. "12", "+infinity", "not-a-number", etc. */
+ //template<class charT = char, class traits = std::traits<charT>, typename int_type>
+ template<class charT, class traits, typename int_type>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os, const int_adapter<int_type>& ia)
+ {
+ if(ia.is_special()) {
+ // switch copied from date_names_put.hpp
+ switch(ia.as_special())
+ {
+ case not_a_date_time:
+ os << "not-a-number";
+ break;
+ case pos_infin:
+ os << "+infinity";
+ break;
+ case neg_infin:
+ os << "-infinity";
+ break;
+ default:
+ os << "";
+ }
+ }
+ else {
+ os << ia.as_number();
+ }
+ return os;
+ }
+#endif
+
+
+} } //namespace date_time
+
+
+
+#endif
diff --git a/ext/boost/date_time/iso_format.hpp b/ext/boost/date_time/iso_format.hpp
new file mode 100644
index 0000000000..8262fa2117
--- /dev/null
+++ b/ext/boost/date_time/iso_format.hpp
@@ -0,0 +1,303 @@
+#ifndef ISO_FORMAT_HPP___
+#define ISO_FORMAT_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/parse_format_base.hpp"
+
+namespace boost {
+namespace date_time {
+
+//! Class to provide common iso formatting spec
+template<class charT>
+class iso_format_base {
+public:
+ //! Describe month format -- its an integer in iso format
+ static month_format_spec month_format()
+ {
+ return month_as_integer;
+ }
+
+ //! String used printed is date is invalid
+ static const charT* not_a_date()
+ {
+ return "not-a-date-time";
+ }
+ //! String used to for positive infinity value
+ static const charT* pos_infinity()
+ {
+ return "+infinity";
+ }
+ //! String used to for positive infinity value
+ static const charT* neg_infinity()
+ {
+ return "-infinity";
+ }
+
+ //! ISO char for a year -- used in durations
+ static charT year_sep_char()
+ {
+ return 'Y';
+ }
+ //! ISO char for a month
+ static charT month_sep_char()
+ {
+ return '-';
+ }
+ //! ISO char for a day
+ static charT day_sep_char()
+ {
+ return '-';
+ }
+ //! char for minute
+ static charT hour_sep_char()
+ {
+ return ':';
+ }
+ //! char for minute
+ static charT minute_sep_char()
+ {
+ return ':';
+ }
+ //! char for second
+ static charT second_sep_char()
+ {
+ return ':';
+ }
+ //! ISO char for a period
+ static charT period_start_char()
+ {
+ return 'P';
+ }
+ //! Used in time in mixed strings to set start of time
+ static charT time_start_char()
+ {
+ return 'T';
+ }
+
+ //! Used in mixed strings to identify start of a week number
+ static charT week_start_char()
+ {
+ return 'W';
+ }
+
+ //! Separators for periods
+ static charT period_sep_char()
+ {
+ return '/';
+ }
+ //! Separator for hh:mm:ss
+ static charT time_sep_char()
+ {
+ return ':';
+ }
+ //! Preferred Separator for hh:mm:ss,decimal_fraction
+ static charT fractional_time_sep_char()
+ {
+ return ',';
+ }
+
+ static bool is_component_sep(charT sep)
+ {
+ switch(sep) {
+ case 'H':
+ case 'M':
+ case 'S':
+ case 'W':
+ case 'T':
+ case 'Y':
+ case 'D':return true;
+ default:
+ return false;
+ }
+ }
+
+ static bool is_fractional_time_sep(charT sep)
+ {
+ switch(sep) {
+ case ',':
+ case '.': return true;
+ default: return false;
+ }
+ }
+ static bool is_timezone_sep(charT sep)
+ {
+ switch(sep) {
+ case '+':
+ case '-': return true;
+ default: return false;
+ }
+ }
+ static charT element_sep_char()
+ {
+ return '-';
+ }
+
+};
+
+#ifndef BOOST_NO_STD_WSTRING
+
+//! Class to provide common iso formatting spec
+template<>
+class iso_format_base<wchar_t> {
+public:
+ //! Describe month format -- its an integer in iso format
+ static month_format_spec month_format()
+ {
+ return month_as_integer;
+ }
+
+ //! String used printed is date is invalid
+ static const wchar_t* not_a_date()
+ {
+ return L"not-a-date-time";
+ }
+ //! String used to for positive infinity value
+ static const wchar_t* pos_infinity()
+ {
+ return L"+infinity";
+ }
+ //! String used to for positive infinity value
+ static const wchar_t* neg_infinity()
+ {
+ return L"-infinity";
+ }
+
+ //! ISO char for a year -- used in durations
+ static wchar_t year_sep_char()
+ {
+ return 'Y';
+ }
+ //! ISO char for a month
+ static wchar_t month_sep_char()
+ {
+ return '-';
+ }
+ //! ISO char for a day
+ static wchar_t day_sep_char()
+ {
+ return '-';
+ }
+ //! char for minute
+ static wchar_t hour_sep_char()
+ {
+ return ':';
+ }
+ //! char for minute
+ static wchar_t minute_sep_char()
+ {
+ return ':';
+ }
+ //! char for second
+ static wchar_t second_sep_char()
+ {
+ return ':';
+ }
+ //! ISO char for a period
+ static wchar_t period_start_char()
+ {
+ return 'P';
+ }
+ //! Used in time in mixed strings to set start of time
+ static wchar_t time_start_char()
+ {
+ return 'T';
+ }
+
+ //! Used in mixed strings to identify start of a week number
+ static wchar_t week_start_char()
+ {
+ return 'W';
+ }
+
+ //! Separators for periods
+ static wchar_t period_sep_char()
+ {
+ return '/';
+ }
+ //! Separator for hh:mm:ss
+ static wchar_t time_sep_char()
+ {
+ return ':';
+ }
+ //! Preferred Separator for hh:mm:ss,decimal_fraction
+ static wchar_t fractional_time_sep_char()
+ {
+ return ',';
+ }
+
+ static bool is_component_sep(wchar_t sep)
+ {
+ switch(sep) {
+ case 'H':
+ case 'M':
+ case 'S':
+ case 'W':
+ case 'T':
+ case 'Y':
+ case 'D':return true;
+ default:
+ return false;
+ }
+ }
+
+ static bool is_fractional_time_sep(wchar_t sep)
+ {
+ switch(sep) {
+ case ',':
+ case '.': return true;
+ default: return false;
+ }
+ }
+ static bool is_timezone_sep(wchar_t sep)
+ {
+ switch(sep) {
+ case '+':
+ case '-': return true;
+ default: return false;
+ }
+ }
+ static wchar_t element_sep_char()
+ {
+ return '-';
+ }
+
+};
+
+#endif // BOOST_NO_STD_WSTRING
+
+//! Format description for iso normal YYYYMMDD
+template<class charT>
+class iso_format : public iso_format_base<charT> {
+public:
+ //! The ios standard format doesn't use char separators
+ static bool has_date_sep_chars()
+ {
+ return false;
+ }
+};
+
+//! Extended format uses seperators YYYY-MM-DD
+template<class charT>
+class iso_extended_format : public iso_format_base<charT> {
+public:
+ //! Extended format needs char separators
+ static bool has_date_sep_chars()
+ {
+ return true;
+ }
+
+};
+
+} } //namespace date_time
+
+
+
+
+#endif
diff --git a/ext/boost/date_time/local_time/conversion.hpp b/ext/boost/date_time/local_time/conversion.hpp
new file mode 100644
index 0000000000..13e4d3eb5c
--- /dev/null
+++ b/ext/boost/date_time/local_time/conversion.hpp
@@ -0,0 +1,34 @@
+#ifndef DATE_TIME_LOCAL_TIME_CONVERSION_HPP__
+#define DATE_TIME_LOCAL_TIME_CONVERSION_HPP__
+
+/* Copyright (c) 2003-2004 CrystalClear Software, Inc.
+ * 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: 2009-06-04 04:24:49 -0400 (Thu, 04 Jun 2009) $
+ */
+
+
+#include "boost/date_time/posix_time/conversion.hpp"
+#include "boost/date_time/c_time.hpp"
+#include "boost/date_time/local_time/local_date_time.hpp"
+
+namespace boost {
+namespace local_time {
+
+//! Function that creates a tm struct from a local_date_time
+inline
+std::tm to_tm(const local_date_time& lt) {
+ std::tm lt_tm = posix_time::to_tm(lt.local_time());
+ if(lt.is_dst()){
+ lt_tm.tm_isdst = 1;
+ }
+ else{
+ lt_tm.tm_isdst = 0;
+ }
+ return lt_tm;
+}
+
+
+}} // namespaces
+#endif // DATE_TIME_LOCAL_TIME_CONVERSION_HPP__
diff --git a/ext/boost/date_time/local_time/custom_time_zone.hpp b/ext/boost/date_time/local_time/custom_time_zone.hpp
new file mode 100644
index 0000000000..a6c1d42055
--- /dev/null
+++ b/ext/boost/date_time/local_time/custom_time_zone.hpp
@@ -0,0 +1,169 @@
+#ifndef LOCAL_TIME_CUSTOM_TIME_ZONE_HPP__
+#define LOCAL_TIME_CUSTOM_TIME_ZONE_HPP__
+
+/* Copyright (c) 2003-2005 CrystalClear Software, Inc.
+ * 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) $
+ */
+
+#include "boost/date_time/time_zone_base.hpp"
+#include "boost/date_time/time_zone_names.hpp"
+#include "boost/date_time/posix_time/posix_time.hpp"
+#include "boost/date_time/local_time/dst_transition_day_rules.hpp"
+#include "boost/date_time/string_convert.hpp"
+//#include "boost/date_time/special_defs.hpp"
+#include "boost/shared_ptr.hpp"
+
+namespace boost {
+namespace local_time {
+
+ //typedef boost::date_time::time_zone_names time_zone_names;
+ typedef boost::date_time::dst_adjustment_offsets<boost::posix_time::time_duration> dst_adjustment_offsets;
+ //typedef boost::date_time::time_zone_base<boost::posix_time::ptime> time_zone;
+ typedef boost::shared_ptr<dst_calc_rule> dst_calc_rule_ptr;
+
+ //! A real time zone
+ template<class CharT>
+ class custom_time_zone_base : public date_time::time_zone_base<posix_time::ptime,CharT> {
+ public:
+ typedef boost::posix_time::time_duration time_duration_type;
+ typedef date_time::time_zone_base<posix_time::ptime,CharT> base_type;
+ typedef typename base_type::string_type string_type;
+ typedef typename base_type::stringstream_type stringstream_type;
+ typedef date_time::time_zone_names_base<CharT> time_zone_names;
+ typedef CharT char_type;
+
+ custom_time_zone_base(const time_zone_names& zone_names,
+ const time_duration_type& utc_offset,
+ const dst_adjustment_offsets& dst_shift,
+ boost::shared_ptr<dst_calc_rule> calc_rule) :
+ zone_names_(zone_names),
+ base_utc_offset_(utc_offset),
+ dst_offsets_(dst_shift),
+ dst_calc_rules_(calc_rule)
+ {};
+ virtual ~custom_time_zone_base() {};
+ virtual string_type dst_zone_abbrev() const
+ {
+ return zone_names_.dst_zone_abbrev();
+ }
+ virtual string_type std_zone_abbrev() const
+ {
+ return zone_names_.std_zone_abbrev();
+ }
+ virtual string_type dst_zone_name() const
+ {
+ return zone_names_.dst_zone_name();
+ }
+ virtual string_type std_zone_name() const
+ {
+ return zone_names_.std_zone_name();
+ }
+ //! True if zone uses daylight savings adjustments
+ virtual bool has_dst() const
+ {
+ return (dst_calc_rules_); //if calc_rule is set the tz has dst
+ }
+ //! Local time that DST starts -- NADT if has_dst is false
+ virtual posix_time::ptime dst_local_start_time(gregorian::greg_year y) const
+ {
+ gregorian::date d(gregorian::not_a_date_time);
+ if (dst_calc_rules_) {
+ d = dst_calc_rules_->start_day(y);
+ }
+ return posix_time::ptime(d, dst_offsets_.dst_start_offset_);
+ }
+ //! Local time that DST ends -- NADT if has_dst is false
+ virtual posix_time::ptime dst_local_end_time(gregorian::greg_year y) const
+ {
+ gregorian::date d(gregorian::not_a_date_time);
+ if (dst_calc_rules_) {
+ d = dst_calc_rules_->end_day(y);
+ }
+ return posix_time::ptime(d, dst_offsets_.dst_end_offset_);
+ }
+ //! Base offset from UTC for zone (eg: -07:30:00)
+ virtual time_duration_type base_utc_offset() const
+ {
+ return base_utc_offset_;
+ }
+ //! Adjustment forward or back made while DST is in effect
+ virtual time_duration_type dst_offset() const
+ {
+ return dst_offsets_.dst_adjust_;
+ }
+ //! Returns a POSIX time_zone string for this object
+ virtual string_type to_posix_string() const
+ {
+ // std offset dst [offset],start[/time],end[/time] - w/o spaces
+ stringstream_type ss;
+ ss.fill('0');
+ boost::shared_ptr<dst_calc_rule> no_rules;
+ // std
+ ss << std_zone_abbrev();
+ // offset
+ if(base_utc_offset().is_negative()) {
+ // inverting the sign guarantees we get two digits
+ ss << '-' << std::setw(2) << base_utc_offset().invert_sign().hours();
+ }
+ else {
+ ss << '+' << std::setw(2) << base_utc_offset().hours();
+ }
+ if(base_utc_offset().minutes() != 0 || base_utc_offset().seconds() != 0) {
+ ss << ':' << std::setw(2) << base_utc_offset().minutes();
+ if(base_utc_offset().seconds() != 0) {
+ ss << ':' << std::setw(2) << base_utc_offset().seconds();
+ }
+ }
+ if(dst_calc_rules_ != no_rules) {
+ // dst
+ ss << dst_zone_abbrev();
+ // dst offset
+ if(dst_offset().is_negative()) {
+ // inverting the sign guarantees we get two digits
+ ss << '-' << std::setw(2) << dst_offset().invert_sign().hours();
+ }
+ else {
+ ss << '+' << std::setw(2) << dst_offset().hours();
+ }
+ if(dst_offset().minutes() != 0 || dst_offset().seconds() != 0) {
+ ss << ':' << std::setw(2) << dst_offset().minutes();
+ if(dst_offset().seconds() != 0) {
+ ss << ':' << std::setw(2) << dst_offset().seconds();
+ }
+ }
+ // start/time
+ ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->start_rule_as_string()) << '/'
+ << std::setw(2) << dst_offsets_.dst_start_offset_.hours() << ':'
+ << std::setw(2) << dst_offsets_.dst_start_offset_.minutes();
+ if(dst_offsets_.dst_start_offset_.seconds() != 0) {
+ ss << ':' << std::setw(2) << dst_offsets_.dst_start_offset_.seconds();
+ }
+ // end/time
+ ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->end_rule_as_string()) << '/'
+ << std::setw(2) << dst_offsets_.dst_end_offset_.hours() << ':'
+ << std::setw(2) << dst_offsets_.dst_end_offset_.minutes();
+ if(dst_offsets_.dst_end_offset_.seconds() != 0) {
+ ss << ':' << std::setw(2) << dst_offsets_.dst_end_offset_.seconds();
+ }
+ }
+
+ return ss.str();
+ }
+ private:
+ time_zone_names zone_names_;
+ bool has_dst_;
+ time_duration_type base_utc_offset_;
+ dst_adjustment_offsets dst_offsets_;
+ boost::shared_ptr<dst_calc_rule> dst_calc_rules_;
+ };
+
+ typedef custom_time_zone_base<char> custom_time_zone;
+
+} }//namespace
+
+
+
+#endif
diff --git a/ext/boost/date_time/local_time/date_duration_operators.hpp b/ext/boost/date_time/local_time/date_duration_operators.hpp
new file mode 100644
index 0000000000..ee870227a9
--- /dev/null
+++ b/ext/boost/date_time/local_time/date_duration_operators.hpp
@@ -0,0 +1,115 @@
+#ifndef LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___
+#define LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___
+
+/* Copyright (c) 2004 CrystalClear Software, Inc.
+ * 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) $
+ */
+
+#include "boost/date_time/gregorian/greg_duration_types.hpp"
+#include "boost/date_time/local_time/local_date_time.hpp"
+
+namespace boost {
+namespace local_time {
+
+ /*!@file date_duration_operators.hpp Operators for local_date_time and
+ * optional gregorian types. Operators use snap-to-end-of-month behavior.
+ * Further details on this behavior can be found in reference for
+ * date_time/date_duration_types.hpp and documentation for
+ * month and year iterators.
+ */
+
+
+ /*! Adds a months object and a local_date_time. Result will be same
+ * day-of-month as local_date_time unless original day was the last day of month.
+ * see date_time::months_duration for more details */
+ inline
+ local_date_time
+ operator+(const local_date_time& t, const boost::gregorian::months& m)
+ {
+ return t + m.get_offset(t.utc_time().date());
+ }
+
+ /*! Adds a months object to a local_date_time. Result will be same
+ * day-of-month as local_date_time unless original day was the last day of month.
+ * see date_time::months_duration for more details */
+ inline
+ local_date_time
+ operator+=(local_date_time& t, const boost::gregorian::months& m)
+ {
+ return t += m.get_offset(t.utc_time().date());
+ }
+
+ /*! Subtracts a months object and a local_date_time. Result will be same
+ * day-of-month as local_date_time unless original day was the last day of month.
+ * see date_time::months_duration for more details */
+ inline
+ local_date_time
+ operator-(const local_date_time& t, const boost::gregorian::months& m)
+ {
+ // get_neg_offset returns a negative duration, so we add
+ return t + m.get_neg_offset(t.utc_time().date());
+ }
+
+ /*! Subtracts a months object from a local_date_time. Result will be same
+ * day-of-month as local_date_time unless original day was the last day of month.
+ * see date_time::months_duration for more details */
+ inline
+ local_date_time
+ operator-=(local_date_time& t, const boost::gregorian::months& m)
+ {
+ // get_neg_offset returns a negative duration, so we add
+ return t += m.get_neg_offset(t.utc_time().date());
+ }
+
+ // local_date_time & years
+
+ /*! Adds a years object and a local_date_time. Result will be same
+ * month and day-of-month as local_date_time unless original day was the
+ * last day of month. see date_time::years_duration for more details */
+ inline
+ local_date_time
+ operator+(const local_date_time& t, const boost::gregorian::years& y)
+ {
+ return t + y.get_offset(t.utc_time().date());
+ }
+
+ /*! Adds a years object to a local_date_time. Result will be same
+ * month and day-of-month as local_date_time unless original day was the
+ * last day of month. see date_time::years_duration for more details */
+ inline
+ local_date_time
+ operator+=(local_date_time& t, const boost::gregorian::years& y)
+ {
+ return t += y.get_offset(t.utc_time().date());
+ }
+
+ /*! Subtracts a years object and a local_date_time. Result will be same
+ * month and day-of-month as local_date_time unless original day was the
+ * last day of month. see date_time::years_duration for more details */
+ inline
+ local_date_time
+ operator-(const local_date_time& t, const boost::gregorian::years& y)
+ {
+ // get_neg_offset returns a negative duration, so we add
+ return t + y.get_neg_offset(t.utc_time().date());
+ }
+
+ /*! Subtracts a years object from a local_date_time. Result will be same
+ * month and day-of-month as local_date_time unless original day was the
+ * last day of month. see date_time::years_duration for more details */
+ inline
+ local_date_time
+ operator-=(local_date_time& t, const boost::gregorian::years& y)
+ {
+ // get_neg_offset returns a negative duration, so we add
+ return t += y.get_neg_offset(t.utc_time().date());
+ }
+
+
+}} // namespaces
+
+#endif // LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___
diff --git a/ext/boost/date_time/local_time/dst_transition_day_rules.hpp b/ext/boost/date_time/local_time/dst_transition_day_rules.hpp
new file mode 100644
index 0000000000..3d6cfbacf4
--- /dev/null
+++ b/ext/boost/date_time/local_time/dst_transition_day_rules.hpp
@@ -0,0 +1,77 @@
+#ifndef LOCAL_TIME_DST_TRANSITION_DAY_RULES_HPP__
+#define LOCAL_TIME_DST_TRANSITION_DAY_RULES_HPP__
+
+/* Copyright (c) 2003-2004 CrystalClear Software, Inc.
+ * 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) $
+ */
+
+
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#include "boost/date_time/dst_transition_generators.hpp"
+
+namespace boost {
+namespace local_time {
+
+ //! Provides rule of the form starting Apr 30 ending Oct 21
+ typedef date_time::dst_day_calc_rule<gregorian::date> dst_calc_rule;
+
+ struct partial_date_rule_spec
+ {
+ typedef gregorian::date date_type;
+ typedef gregorian::partial_date start_rule;
+ typedef gregorian::partial_date end_rule;
+ };
+
+ //! Provides rule of the form first Sunday in April, last Saturday in Oct
+ typedef date_time::day_calc_dst_rule<partial_date_rule_spec> partial_date_dst_rule;
+
+ struct first_last_rule_spec
+ {
+ typedef gregorian::date date_type;
+ typedef gregorian::first_kday_of_month start_rule;
+ typedef gregorian::last_kday_of_month end_rule;
+ };
+
+ //! Provides rule of the form first Sunday in April, last Saturday in Oct
+ typedef date_time::day_calc_dst_rule<first_last_rule_spec> first_last_dst_rule;
+
+ struct last_last_rule_spec
+ {
+ typedef gregorian::date date_type;
+ typedef gregorian::last_kday_of_month start_rule;
+ typedef gregorian::last_kday_of_month end_rule;
+ };
+
+ //! Provides rule of the form last Sunday in April, last Saturday in Oct
+ typedef date_time::day_calc_dst_rule<last_last_rule_spec> last_last_dst_rule;
+
+ struct nth_last_rule_spec
+ {
+ typedef gregorian::date date_type;
+ typedef gregorian::nth_kday_of_month start_rule;
+ typedef gregorian::last_kday_of_month end_rule;
+ };
+
+ //! Provides rule in form of [1st|2nd|3rd|4th] Sunday in April, last Sunday in Oct
+ typedef date_time::day_calc_dst_rule<nth_last_rule_spec> nth_last_dst_rule;
+
+ struct nth_kday_rule_spec
+ {
+ typedef gregorian::date date_type;
+ typedef gregorian::nth_kday_of_month start_rule;
+ typedef gregorian::nth_kday_of_month end_rule;
+ };
+
+ //! Provides rule in form of [1st|2nd|3rd|4th] Sunday in April/October
+ typedef date_time::day_calc_dst_rule<nth_kday_rule_spec> nth_kday_dst_rule;
+ //! Provides rule in form of [1st|2nd|3rd|4th] Sunday in April/October
+ typedef date_time::day_calc_dst_rule<nth_kday_rule_spec> nth_day_of_the_week_in_month_dst_rule;
+
+
+} }//namespace
+
+
+#endif
diff --git a/ext/boost/date_time/local_time/local_date_time.hpp b/ext/boost/date_time/local_time/local_date_time.hpp
new file mode 100644
index 0000000000..36609c3316
--- /dev/null
+++ b/ext/boost/date_time/local_time/local_date_time.hpp
@@ -0,0 +1,527 @@
+#ifndef LOCAL_TIME_LOCAL_DATE_TIME_HPP__
+#define LOCAL_TIME_LOCAL_DATE_TIME_HPP__
+
+/* Copyright (c) 2003-2005 CrystalClear Software, Inc.
+ * 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-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <string>
+#include <iomanip>
+#include <sstream>
+#include <stdexcept>
+#include <boost/shared_ptr.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/time.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp> //todo remove?
+#include <boost/date_time/dst_rules.hpp>
+#include <boost/date_time/time_zone_base.hpp>
+#include <boost/date_time/special_defs.hpp>
+
+namespace boost {
+namespace local_time {
+
+ //! simple exception for reporting when STD or DST cannot be determined
+ struct ambiguous_result : public std::logic_error
+ {
+ ambiguous_result (std::string const& msg = std::string()) :
+ std::logic_error(std::string("Daylight Savings Results are ambiguous: " + msg)) {}
+ };
+ //! simple exception for when time label given cannot exist
+ struct time_label_invalid : public std::logic_error
+ {
+ time_label_invalid (std::string const& msg = std::string()) :
+ std::logic_error(std::string("Time label given is invalid: " + msg)) {}
+ };
+ struct dst_not_valid: public std::logic_error
+ {
+ dst_not_valid(std::string const& msg = std::string()) :
+ std::logic_error(std::string("is_dst flag does not match resulting dst for time label given: " + msg)) {}
+ };
+
+ //TODO: I think these should be in local_date_time_base and not
+ // necessarily brought into the namespace
+ using date_time::time_is_dst_result;
+ using date_time::is_in_dst;
+ using date_time::is_not_in_dst;
+ using date_time::ambiguous;
+ using date_time::invalid_time_label;
+
+ //! Representation of "wall-clock" time in a particular time zone
+ /*! Representation of "wall-clock" time in a particular time zone
+ * Local_date_time_base holds a time value (date and time offset from 00:00)
+ * along with a time zone. The time value is stored as UTC and conversions
+ * to wall clock time are made as needed. This approach allows for
+ * operations between wall-clock times in different time zones, and
+ * daylight savings time considerations, to be made. Time zones are
+ * required to be in the form of a boost::shared_ptr<time_zone_base>.
+ */
+ template<class utc_time_=posix_time::ptime,
+ class tz_type=date_time::time_zone_base<utc_time_,char> >
+ class local_date_time_base : public date_time::base_time<utc_time_,
+ boost::posix_time::posix_time_system> {
+ public:
+ typedef utc_time_ utc_time_type;
+ typedef typename utc_time_type::time_duration_type time_duration_type;
+ typedef typename utc_time_type::date_type date_type;
+ typedef typename date_type::duration_type date_duration_type;
+ typedef typename utc_time_type::time_system_type time_system_type;
+ /*! This constructor interprets the passed time as a UTC time.
+ * So, for example, if the passed timezone is UTC-5 then the
+ * time will be adjusted back 5 hours. The time zone allows for
+ * automatic calculation of whether the particular time is adjusted for
+ * daylight savings, etc.
+ * If the time zone shared pointer is null then time stays unadjusted.
+ *@param t A UTC time
+ *@param tz Timezone for to adjust the UTC time to.
+ */
+ local_date_time_base(utc_time_type t,
+ boost::shared_ptr<tz_type> tz) :
+ date_time::base_time<utc_time_type, time_system_type>(t),
+ zone_(tz)
+ {
+ // param was already utc so nothing more to do
+ }
+
+ /*! This constructs a local time -- the passed time information
+ * understood to be in the passed tz. The DST flag must be passed
+ * to indicate whether the time is in daylight savings or not.
+ * @throws -- time_label_invalid if the time passed does not exist in
+ * the given locale. The non-existent case occurs typically
+ * during the shift-back from daylight savings time. When
+ * the clock is shifted forward a range of times
+ * (2 am to 3 am in the US) is skipped and hence is invalid.
+ * @throws -- dst_not_valid if the DST flag is passed for a period
+ * where DST is not active.
+ */
+ local_date_time_base(date_type d,
+ time_duration_type td,
+ boost::shared_ptr<tz_type> tz,
+ bool dst_flag) : //necessary for constr_adj()
+ date_time::base_time<utc_time_type,time_system_type>(construction_adjustment(utc_time_type(d, td), tz, dst_flag)),
+ zone_(tz)
+ {
+ if(tz != boost::shared_ptr<tz_type>() && tz->has_dst()){
+
+ // d & td are already local so we use them
+ time_is_dst_result result = check_dst(d, td, tz);
+ bool in_dst = (result == is_in_dst); // less processing than is_dst()
+
+ // ambig occurs at end, invalid at start
+ if(result == invalid_time_label){
+ // Ex: 2:15am local on trans-in day in nyc, dst_flag irrelevant
+ std::ostringstream ss;
+ ss << "time given: " << d << ' ' << td;
+ boost::throw_exception(time_label_invalid(ss.str()));
+ }
+ else if(result != ambiguous && in_dst != dst_flag){
+ // is dst_flag accurate?
+ // Ex: false flag in NYC in June
+ std::ostringstream ss;
+ ss.setf(std::ios_base::boolalpha);
+ ss << "flag given: dst=" << dst_flag << ", dst calculated: dst=" << in_dst;
+ boost::throw_exception(dst_not_valid(ss.str()));
+ }
+
+ // everything checks out and conversion to utc already done
+ }
+ }
+
+ //TODO maybe not the right set...Ignore the last 2 for now...
+ enum DST_CALC_OPTIONS { EXCEPTION_ON_ERROR, NOT_DATE_TIME_ON_ERROR };
+ //ASSUME_DST_ON_ERROR, ASSUME_NOT_DST_ON_ERROR };
+
+ /*! This constructs a local time -- the passed time information
+ * understood to be in the passed tz. The DST flag is calculated
+ * according to the specified rule.
+ */
+ local_date_time_base(date_type d,
+ time_duration_type td,
+ boost::shared_ptr<tz_type> tz,
+ DST_CALC_OPTIONS calc_option) :
+ // dummy value - time_ is set in constructor code
+ date_time::base_time<utc_time_type,time_system_type>(utc_time_type(d,td)),
+ zone_(tz)
+ {
+ time_is_dst_result result = check_dst(d, td, tz);
+ if(result == ambiguous) {
+ if(calc_option == EXCEPTION_ON_ERROR){
+ std::ostringstream ss;
+ ss << "time given: " << d << ' ' << td;
+ boost::throw_exception(ambiguous_result(ss.str()));
+ }
+ else{ // NADT on error
+ this->time_ = posix_time::posix_time_system::get_time_rep(date_type(date_time::not_a_date_time), time_duration_type(date_time::not_a_date_time));
+ }
+ }
+ else if(result == invalid_time_label){
+ if(calc_option == EXCEPTION_ON_ERROR){
+ std::ostringstream ss;
+ ss << "time given: " << d << ' ' << td;
+ boost::throw_exception(time_label_invalid(ss.str()));
+ }
+ else{ // NADT on error
+ this->time_ = posix_time::posix_time_system::get_time_rep(date_type(date_time::not_a_date_time), time_duration_type(date_time::not_a_date_time));
+ }
+ }
+ else if(result == is_in_dst){
+ utc_time_type t =
+ construction_adjustment(utc_time_type(d, td), tz, true);
+ this->time_ = posix_time::posix_time_system::get_time_rep(t.date(),
+ t.time_of_day());
+ }
+ else{
+ utc_time_type t =
+ construction_adjustment(utc_time_type(d, td), tz, false);
+ this->time_ = posix_time::posix_time_system::get_time_rep(t.date(),
+ t.time_of_day());
+ }
+ }
+
+
+ //! Determines if given time label is in daylight savings for given zone
+ /*! Determines if given time label is in daylight savings for given zone.
+ * Takes a date and time_duration representing a local time, along
+ * with time zone, and returns a time_is_dst_result object as result.
+ */
+ static time_is_dst_result check_dst(date_type d,
+ time_duration_type td,
+ boost::shared_ptr<tz_type> tz)
+ {
+ if(tz != boost::shared_ptr<tz_type>() && tz->has_dst()) {
+ typedef typename date_time::dst_calculator<date_type, time_duration_type> dst_calculator;
+ return dst_calculator::local_is_dst(
+ d, td,
+ tz->dst_local_start_time(d.year()).date(),
+ tz->dst_local_start_time(d.year()).time_of_day(),
+ tz->dst_local_end_time(d.year()).date(),
+ tz->dst_local_end_time(d.year()).time_of_day(),
+ tz->dst_offset()
+ );
+ }
+ else{
+ return is_not_in_dst;
+ }
+ }
+
+ //! Simple destructor, releases time zone if last referrer
+ ~local_date_time_base() {};
+
+ //! Copy constructor
+ local_date_time_base(const local_date_time_base& rhs) :
+ date_time::base_time<utc_time_type, time_system_type>(rhs),
+ zone_(rhs.zone_)
+ {}
+
+ //! Special values constructor
+ explicit local_date_time_base(const boost::date_time::special_values sv,
+ boost::shared_ptr<tz_type> tz = boost::shared_ptr<tz_type>()) :
+ date_time::base_time<utc_time_type, time_system_type>(utc_time_type(sv)),
+ zone_(tz)
+ {}
+
+ //! returns time zone associated with calling instance
+ boost::shared_ptr<tz_type> zone() const
+ {
+ return zone_;
+ }
+ //! returns false is time_zone is NULL and if time value is a special_value
+ bool is_dst() const
+ {
+ if(zone_ != boost::shared_ptr<tz_type>() && zone_->has_dst() && !this->is_special()) {
+ // check_dst takes a local time, *this is utc
+ utc_time_type lt(this->time_);
+ lt += zone_->base_utc_offset();
+ // dst_offset only needs to be considered with ambiguous time labels
+ // make that adjustment there
+
+ switch(check_dst(lt.date(), lt.time_of_day(), zone_)){
+ case is_not_in_dst:
+ return false;
+ case is_in_dst:
+ return true;
+ case ambiguous:
+ if(lt + zone_->dst_offset() < zone_->dst_local_end_time(lt.date().year())) {
+ return true;
+ }
+ break;
+ case invalid_time_label:
+ if(lt >= zone_->dst_local_start_time(lt.date().year())) {
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
+ }
+ //! Returns object's time value as a utc representation
+ utc_time_type utc_time() const
+ {
+ return utc_time_type(this->time_);
+ }
+ //! Returns object's time value as a local representation
+ utc_time_type local_time() const
+ {
+ if(zone_ != boost::shared_ptr<tz_type>()){
+ utc_time_type lt = this->utc_time() + zone_->base_utc_offset();
+ if (is_dst()) {
+ lt += zone_->dst_offset();
+ }
+ return lt;
+ }
+ return utc_time_type(this->time_);
+ }
+ //! Returns string in the form "2003-Aug-20 05:00:00 EDT"
+ /*! Returns string in the form "2003-Aug-20 05:00:00 EDT". If
+ * time_zone is NULL the time zone abbreviation will be "UTC". The time
+ * zone abbrev will not be included if calling object is a special_value*/
+ std::string to_string() const
+ {
+ //TODO is this a temporary function ???
+ std::ostringstream ss;
+ if(this->is_special()){
+ ss << utc_time();
+ return ss.str();
+ }
+ if(zone_ == boost::shared_ptr<tz_type>()) {
+ ss << utc_time() << " UTC";
+ return ss.str();
+ }
+ bool is_dst_ = is_dst();
+ utc_time_type lt = this->utc_time() + zone_->base_utc_offset();
+ if (is_dst_) {
+ lt += zone_->dst_offset();
+ }
+ ss << local_time() << " ";
+ if (is_dst()) {
+ ss << zone_->dst_zone_abbrev();
+ }
+ else {
+ ss << zone_->std_zone_abbrev();
+ }
+ return ss.str();
+ }
+ /*! returns a local_date_time_base in the given time zone with the
+ * optional time_duration added. */
+ local_date_time_base local_time_in(boost::shared_ptr<tz_type> new_tz,
+ time_duration_type td=time_duration_type(0,0,0)) const
+ {
+ return local_date_time_base(utc_time_type(this->time_) + td, new_tz);
+ }
+
+ //! Returns name of associated time zone or "Coordinated Universal Time".
+ /*! Optional bool parameter will return time zone as an offset
+ * (ie "+07:00" extended iso format). Empty string is returned for
+ * classes that do not use a time_zone */
+ std::string zone_name(bool as_offset=false) const
+ {
+ if(zone_ == boost::shared_ptr<tz_type>()) {
+ if(as_offset) {
+ return std::string("Z");
+ }
+ else {
+ return std::string("Coordinated Universal Time");
+ }
+ }
+ if (is_dst()) {
+ if(as_offset) {
+ time_duration_type td = zone_->base_utc_offset();
+ td += zone_->dst_offset();
+ return zone_as_offset(td, ":");
+ }
+ else {
+ return zone_->dst_zone_name();
+ }
+ }
+ else {
+ if(as_offset) {
+ time_duration_type td = zone_->base_utc_offset();
+ return zone_as_offset(td, ":");
+ }
+ else {
+ return zone_->std_zone_name();
+ }
+ }
+ }
+ //! Returns abbreviation of associated time zone or "UTC".
+ /*! Optional bool parameter will return time zone as an offset
+ * (ie "+0700" iso format). Empty string is returned for classes
+ * that do not use a time_zone */
+ std::string zone_abbrev(bool as_offset=false) const
+ {
+ if(zone_ == boost::shared_ptr<tz_type>()) {
+ if(as_offset) {
+ return std::string("Z");
+ }
+ else {
+ return std::string("UTC");
+ }
+ }
+ if (is_dst()) {
+ if(as_offset) {
+ time_duration_type td = zone_->base_utc_offset();
+ td += zone_->dst_offset();
+ return zone_as_offset(td, "");
+ }
+ else {
+ return zone_->dst_zone_abbrev();
+ }
+ }
+ else {
+ if(as_offset) {
+ time_duration_type td = zone_->base_utc_offset();
+ return zone_as_offset(td, "");
+ }
+ else {
+ return zone_->std_zone_abbrev();
+ }
+ }
+ }
+
+ //! returns a posix_time_zone string for the associated time_zone. If no time_zone, "UTC+00" is returned.
+ std::string zone_as_posix_string() const
+ {
+ if(zone_ == shared_ptr<tz_type>()) {
+ return std::string("UTC+00");
+ }
+ return zone_->to_posix_string();
+ }
+
+ //! Equality comparison operator
+ /*bool operator==(const date_time::base_time<boost::posix_time::ptime,boost::posix_time::posix_time_system>& rhs) const
+ { // fails due to rhs.time_ being protected
+ return date_time::base_time<boost::posix_time::ptime,boost::posix_time::posix_time_system>::operator==(rhs);
+ //return this->time_ == rhs.time_;
+ }*/
+ //! Equality comparison operator
+ bool operator==(const local_date_time_base& rhs) const
+ {
+ return time_system_type::is_equal(this->time_, rhs.time_);
+ }
+ //! Non-Equality comparison operator
+ bool operator!=(const local_date_time_base& rhs) const
+ {
+ return !(*this == rhs);
+ }
+ //! Less than comparison operator
+ bool operator<(const local_date_time_base& rhs) const
+ {
+ return time_system_type::is_less(this->time_, rhs.time_);
+ }
+ //! Less than or equal to comparison operator
+ bool operator<=(const local_date_time_base& rhs) const
+ {
+ return (*this < rhs || *this == rhs);
+ }
+ //! Greater than comparison operator
+ bool operator>(const local_date_time_base& rhs) const
+ {
+ return !(*this <= rhs);
+ }
+ //! Greater than or equal to comparison operator
+ bool operator>=(const local_date_time_base& rhs) const
+ {
+ return (*this > rhs || *this == rhs);
+ }
+
+ //! Local_date_time + date_duration
+ local_date_time_base operator+(const date_duration_type& dd) const
+ {
+ return local_date_time_base(time_system_type::add_days(this->time_,dd), zone_);
+ }
+ //! Local_date_time += date_duration
+ local_date_time_base operator+=(const date_duration_type& dd)
+ {
+ this->time_ = time_system_type::add_days(this->time_,dd);
+ return *this;
+ }
+ //! Local_date_time - date_duration
+ local_date_time_base operator-(const date_duration_type& dd) const
+ {
+ return local_date_time_base(time_system_type::subtract_days(this->time_,dd), zone_);
+ }
+ //! Local_date_time -= date_duration
+ local_date_time_base operator-=(const date_duration_type& dd)
+ {
+ this->time_ = time_system_type::subtract_days(this->time_,dd);
+ return *this;
+ }
+ //! Local_date_time + time_duration
+ local_date_time_base operator+(const time_duration_type& td) const
+ {
+ return local_date_time_base(time_system_type::add_time_duration(this->time_,td), zone_);
+ }
+ //! Local_date_time += time_duration
+ local_date_time_base operator+=(const time_duration_type& td)
+ {
+ this->time_ = time_system_type::add_time_duration(this->time_,td);
+ return *this;
+ }
+ //! Local_date_time - time_duration
+ local_date_time_base operator-(const time_duration_type& td) const
+ {
+ return local_date_time_base(time_system_type::subtract_time_duration(this->time_,td), zone_);
+ }
+ //! Local_date_time -= time_duration
+ local_date_time_base operator-=(const time_duration_type& td)
+ {
+ this->time_ = time_system_type::subtract_time_duration(this->time_,td);
+ return *this;
+ }
+ //! local_date_time -= local_date_time --> time_duration_type
+ time_duration_type operator-(const local_date_time_base& rhs) const
+ {
+ return utc_time_type(this->time_) - utc_time_type(rhs.time_);
+ }
+ private:
+ boost::shared_ptr<tz_type> zone_;
+ //bool is_dst_;
+
+ /*! Adjust the passed in time to UTC?
+ */
+ utc_time_type construction_adjustment(utc_time_type t,
+ boost::shared_ptr<tz_type> z,
+ bool dst_flag)
+ {
+ if(z != boost::shared_ptr<tz_type>()) {
+ if(dst_flag && z->has_dst()) {
+ t -= z->dst_offset();
+ } // else no adjust
+ t -= z->base_utc_offset();
+ }
+ return t;
+ }
+
+ /*! Simple formatting code -- todo remove this?
+ */
+ std::string zone_as_offset(const time_duration_type& td,
+ const std::string& separator) const
+ {
+ std::ostringstream ss;
+ if(td.is_negative()) {
+ // a negative duration is represented as "-[h]h:mm"
+ // we require two digits for the hour. A positive duration
+ // with the %H flag will always give two digits
+ ss << "-";
+ }
+ else {
+ ss << "+";
+ }
+ ss << std::setw(2) << std::setfill('0')
+ << date_time::absolute_value(td.hours())
+ << separator
+ << std::setw(2) << std::setfill('0')
+ << date_time::absolute_value(td.minutes());
+ return ss.str();
+ }
+ };
+
+ //!Use the default parameters to define local_date_time
+ typedef local_date_time_base<> local_date_time;
+
+} }
+
+
+#endif
diff --git a/ext/boost/date_time/local_time/local_time.hpp b/ext/boost/date_time/local_time/local_time.hpp
new file mode 100644
index 0000000000..f7d4cc68e3
--- /dev/null
+++ b/ext/boost/date_time/local_time/local_time.hpp
@@ -0,0 +1,24 @@
+#ifndef LOCAL_TIME_LOCAL_TIME_HPP__
+#define LOCAL_TIME_LOCAL_TIME_HPP__
+
+/* Copyright (c) 2003-2004 CrystalClear Software, Inc.
+ * 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) $
+ */
+
+#include "boost/date_time/posix_time/posix_time.hpp"
+#include "boost/date_time/local_time/local_date_time.hpp"
+#include "boost/date_time/local_time/local_time_types.hpp"
+#if !defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+#include "boost/date_time/local_time/local_time_io.hpp"
+#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
+#include "boost/date_time/local_time/posix_time_zone.hpp"
+#include "boost/date_time/local_time/custom_time_zone.hpp"
+#include "boost/date_time/local_time/tz_database.hpp"
+#include "boost/date_time/local_time/conversion.hpp"
+#include "boost/date_time/time_zone_base.hpp"
+
+
+#endif
diff --git a/ext/boost/date_time/local_time/local_time_io.hpp b/ext/boost/date_time/local_time/local_time_io.hpp
new file mode 100644
index 0000000000..c161ff7e23
--- /dev/null
+++ b/ext/boost/date_time/local_time/local_time_io.hpp
@@ -0,0 +1,186 @@
+#ifndef BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__
+#define BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__
+
+/* Copyright (c) 2003-2004 CrystalClear Software, Inc.
+ * 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-13 14:05:31 -0500 (Thu, 13 Nov 2008) $
+ */
+
+#include <locale>
+#include <iostream>
+#include <iterator> // i/ostreambuf_iterator
+#include <boost/io/ios_state.hpp>
+#include <boost/date_time/time_facet.hpp>
+#include <boost/date_time/string_convert.hpp>
+#include <boost/date_time/local_time/local_date_time.hpp>
+#include <boost/date_time/local_time/posix_time_zone.hpp>
+#include <boost/date_time/local_time/conversion.hpp> // to_tm will be needed in the facets
+
+namespace boost {
+namespace local_time {
+
+ typedef boost::date_time::time_facet<local_date_time, wchar_t> wlocal_time_facet;
+ typedef boost::date_time::time_facet<local_date_time, char> local_time_facet;
+
+ typedef boost::date_time::time_input_facet<local_date_time::utc_time_type,wchar_t> wlocal_time_input_facet;
+ typedef boost::date_time::time_input_facet<local_date_time::utc_time_type,char> local_time_input_facet;
+
+ //! operator<< for local_date_time - see local_time docs for formatting details
+ template<class CharT, class TraitsT>
+ inline
+ std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os, const local_date_time& ldt)
+ {
+ boost::io::ios_flags_saver iflags(os);
+ typedef local_date_time time_type;//::utc_time_type typename
+ typedef date_time::time_facet<time_type, CharT> custom_time_facet;
+ typedef std::time_put<CharT> std_time_facet;
+ std::ostreambuf_iterator<CharT> oitr(os);
+
+ if(std::has_facet<custom_time_facet>(os.getloc())) {
+ std::use_facet<custom_time_facet>(os.getloc()).put(oitr,
+ os,
+ os.fill(),
+ ldt);
+ }
+ else {
+ custom_time_facet* f = new custom_time_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(oitr, os, os.fill(), ldt);
+ }
+
+ return os;
+ }
+
+
+ //! input operator for local_date_time
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, local_date_time& ldt)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename local_date_time::utc_time_type utc_time_type;
+ typedef typename date_time::time_input_facet<utc_time_type, CharT> time_input_facet;
+
+ // intermediate objects
+ std::basic_string<CharT> tz_str;
+ utc_time_type pt(not_a_date_time);
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<time_input_facet>(is.getloc())) {
+ std::use_facet<time_input_facet>(is.getloc()).get_local_time(sit, str_end, is, pt, tz_str);
+ }
+ else {
+ time_input_facet* f = new time_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get_local_time(sit, str_end, is, pt, tz_str);
+ }
+ if(tz_str.empty()) {
+ time_zone_ptr null_ptr;
+ // a null time_zone_ptr creates a local_date_time that is UTC
+ ldt = local_date_time(pt, null_ptr);
+ }
+ else {
+ time_zone_ptr tz_ptr(new posix_time_zone(date_time::convert_string_type<CharT,char>(tz_str)));
+ // the "date & time" constructor expects the time label to *not* be utc.
+ // a posix_tz_string also expects the time label to *not* be utc.
+ ldt = local_date_time(pt.date(), pt.time_of_day(), tz_ptr, local_date_time::EXCEPTION_ON_ERROR);
+ }
+ }
+ catch(...) {
+ // mask tells us what exceptions are turned on
+ std::ios_base::iostate exception_mask = is.exceptions();
+ // if the user wants exceptions on failbit, we'll rethrow our
+ // date_time exception & set the failbit
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {} // ignore this one
+ throw; // rethrow original exception
+ }
+ else {
+ // if the user want's to fail quietly, we simply set the failbit
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+ //! output operator for local_time_period
+ template <class CharT, class TraitsT>
+ inline
+ std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os,
+ const boost::local_time::local_time_period& p) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::time_facet<local_date_time, CharT> custom_facet;
+ typedef std::time_put<CharT> std_time_facet;
+ std::ostreambuf_iterator<CharT> oitr(os);
+ if (std::has_facet<custom_facet>(os.getloc())) {
+ std::use_facet<custom_facet>(os.getloc()).put(oitr, os, os.fill(), p);
+ }
+ else {
+ //instantiate a custom facet for dealing with periods since the user
+ //has not put one in the stream so far. This is for efficiency
+ //since we would always need to reconstruct for every time period
+ //if the local did not already exist. Of course this will be overridden
+ //if the user imbues as some later point.
+ custom_facet* f = new custom_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(oitr, os, os.fill(), p);
+ }
+ return os;
+ }
+
+ //! input operator for local_time_period
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, boost::local_time::local_time_period& tp)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::time_input_facet<local_date_time, CharT> time_input_facet;
+
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<time_input_facet>(is.getloc())) {
+ std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, tp);
+ }
+ else {
+ time_input_facet* f = new time_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, tp);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+
+ }
+ }
+ return is;
+ }
+
+} } // namespaces
+
+#endif // BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__
diff --git a/ext/boost/date_time/local_time/local_time_types.hpp b/ext/boost/date_time/local_time/local_time_types.hpp
new file mode 100644
index 0000000000..ed58b8018a
--- /dev/null
+++ b/ext/boost/date_time/local_time/local_time_types.hpp
@@ -0,0 +1,52 @@
+#ifndef LOCAL_TIME_LOCAL_TIME_TYPES_HPP__
+#define LOCAL_TIME_LOCAL_TIME_TYPES_HPP__
+
+/* Copyright (c) 2003-2004 CrystalClear Software, Inc.
+ * 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) $
+ */
+
+#include "boost/date_time/local_time/local_date_time.hpp"
+#include "boost/date_time/period.hpp"
+#include "boost/date_time/time_iterator.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
+#include "boost/date_time/local_time/date_duration_operators.hpp"
+#endif //BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES
+#include "boost/date_time/local_time/custom_time_zone.hpp"
+
+namespace boost {
+namespace local_time {
+
+ typedef boost::date_time::period<local_date_time,
+ boost::posix_time::time_duration> local_time_period;
+
+ typedef date_time::time_itr<local_date_time> local_time_iterator;
+
+ typedef date_time::second_clock<local_date_time> local_sec_clock;
+ typedef date_time::microsec_clock<local_date_time> local_microsec_clock;
+
+ typedef date_time::time_zone_base<posix_time::ptime, char> time_zone;
+ typedef date_time::time_zone_base<posix_time::ptime, wchar_t> wtime_zone;
+
+ //! Shared Pointer for custom_time_zone and posix_time_zone objects
+ typedef boost::shared_ptr<time_zone> time_zone_ptr;
+ typedef boost::shared_ptr<wtime_zone> wtime_zone_ptr;
+
+ typedef date_time::time_zone_names_base<char> time_zone_names;
+ typedef date_time::time_zone_names_base<wchar_t> wtime_zone_names;
+
+ //bring special enum values into the namespace
+ using date_time::special_values;
+ using date_time::not_special;
+ using date_time::neg_infin;
+ using date_time::pos_infin;
+ using date_time::not_a_date_time;
+ using date_time::max_date_time;
+ using date_time::min_date_time;
+
+}} // namespaces
+
+#endif // LOCAL_TIME_LOCAL_TIME_TYPES_HPP__
diff --git a/ext/boost/date_time/local_time/posix_time_zone.hpp b/ext/boost/date_time/local_time/posix_time_zone.hpp
new file mode 100644
index 0000000000..f8d968aa4e
--- /dev/null
+++ b/ext/boost/date_time/local_time/posix_time_zone.hpp
@@ -0,0 +1,464 @@
+#ifndef _DATE_TIME_POSIX_TIME_ZONE__
+#define _DATE_TIME_POSIX_TIME_ZONE__
+
+/* Copyright (c) 2003-2005 CrystalClear Software, Inc.
+ * 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-26 10:39:19 -0500 (Wed, 26 Nov 2008) $
+ */
+
+#include <string>
+#include <sstream>
+#include <stdexcept>
+#include <boost/tokenizer.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/gregorian/gregorian.hpp>
+#include <boost/date_time/time_zone_names.hpp>
+#include <boost/date_time/time_zone_base.hpp>
+#include <boost/date_time/local_time/dst_transition_day_rules.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/date_time/string_convert.hpp>
+#include <boost/date_time/time_parsing.hpp>
+
+namespace boost{
+namespace local_time{
+
+ //! simple exception for UTC and Daylight savings start/end offsets
+ struct bad_offset : public std::out_of_range
+ {
+ bad_offset(std::string const& msg = std::string()) :
+ std::out_of_range(std::string("Offset out of range: " + msg)) {}
+ };
+ //! simple exception for UTC daylight savings adjustment
+ struct bad_adjustment : public std::out_of_range
+ {
+ bad_adjustment(std::string const& msg = std::string()) :
+ std::out_of_range(std::string("Adjustment out of range: " + msg)) {}
+ };
+
+ typedef boost::date_time::dst_adjustment_offsets<boost::posix_time::time_duration> dst_adjustment_offsets;
+
+ //! A time zone class constructed from a POSIX time zone string
+ /*! A POSIX time zone string takes the form of:<br>
+ * "std offset dst [offset],start[/time],end[/time]" (w/no spaces)
+ * 'std' specifies the abbrev of the time zone.<br>
+ * 'offset' is the offset from UTC.<br>
+ * 'dst' specifies the abbrev of the time zone during daylight savings time.<br>
+ * The second offset is how many hours changed during DST. Default=1<br>
+ * 'start' and'end' are the dates when DST goes into (and out of) effect.<br>
+ * 'offset' takes the form of: [+|-]hh[:mm[:ss]] {h=0-23, m/s=0-59}<br>
+ * 'time' and 'offset' take the same form. Time defaults=02:00:00<br>
+ * 'start' and 'end' can be one of three forms:<br>
+ * Mm.w.d {month=1-12, week=1-5 (5 is always last), day=0-6}<br>
+ * Jn {n=1-365 Feb29 is never counted}<br>
+ * n {n=0-365 Feb29 is counted in leap years}<br>
+ * Example "PST-5PDT01:00:00,M4.1.0/02:00:00,M10.1.0/02:00:00"
+ * <br>
+ * Exceptions will be thrown under these conditions:<br>
+ * An invalid date spec (see date class)<br>
+ * A boost::local_time::bad_offset exception will be thrown for:<br>
+ * A DST start or end offset that is negative or more than 24 hours<br>
+ * A UTC zone that is greater than +12 or less than -12 hours<br>
+ * A boost::local_time::bad_adjustment exception will be thrown for:<br>
+ * A DST adjustment that is 24 hours or more (positive or negative)<br>
+ */
+ template<class CharT>
+ class posix_time_zone_base : public date_time::time_zone_base<posix_time::ptime,CharT> {
+ public:
+ typedef boost::posix_time::time_duration time_duration_type;
+ typedef date_time::time_zone_names_base<CharT> time_zone_names;
+ typedef date_time::time_zone_base<posix_time::ptime,CharT> base_type;
+ typedef typename base_type::string_type string_type;
+ typedef CharT char_type;
+ typedef typename base_type::stringstream_type stringstream_type;
+ typedef boost::char_separator<char_type, std::char_traits<char_type> > char_separator_type;
+ typedef boost::tokenizer<char_separator_type,
+ typename string_type::const_iterator,
+ string_type> tokenizer_type;
+ typedef typename boost::tokenizer<char_separator_type,
+ typename string_type::const_iterator,
+ string_type>::iterator tokenizer_iterator_type;
+
+ //! Construct from a POSIX time zone string
+ posix_time_zone_base(const string_type& s) :
+ //zone_names_("std_name","std_abbrev","no-dst","no-dst"),
+ zone_names_(),
+ has_dst_(false),
+ base_utc_offset_(posix_time::hours(0)),
+ dst_offsets_(posix_time::hours(0),posix_time::hours(0),posix_time::hours(0)),
+ dst_calc_rules_()
+ {
+#ifdef __HP_aCC
+ // Work around bug in aC++ compiler: see QXCR1000880488 in the
+ // HP bug tracking system
+ const char_type sep_chars[2] = {',',0};
+#else
+ const char_type sep_chars[2] = {','};
+#endif
+ char_separator_type sep(sep_chars);
+ tokenizer_type tokens(s, sep);
+ tokenizer_iterator_type it = tokens.begin();
+ calc_zone(*it++);
+ if(has_dst_){
+ string_type tmp_str = *it++;
+ calc_rules(tmp_str, *it);
+ }
+ }
+ virtual ~posix_time_zone_base() {};
+ //!String for the zone when not in daylight savings (eg: EST)
+ virtual string_type std_zone_abbrev()const
+ {
+ return zone_names_.std_zone_abbrev();
+ }
+ //!String for the timezone when in daylight savings (eg: EDT)
+ /*! For those time zones that have no DST, an empty string is used */
+ virtual string_type dst_zone_abbrev() const
+ {
+ return zone_names_.dst_zone_abbrev();
+ }
+ //!String for the zone when not in daylight savings (eg: Eastern Standard Time)
+ /*! The full STD name is not extracted from the posix time zone string.
+ * Therefore, the STD abbreviation is used in it's place */
+ virtual string_type std_zone_name()const
+ {
+ return zone_names_.std_zone_name();
+ }
+ //!String for the timezone when in daylight savings (eg: Eastern Daylight Time)
+ /*! The full DST name is not extracted from the posix time zone string.
+ * Therefore, the STD abbreviation is used in it's place. For time zones
+ * that have no DST, an empty string is used */
+ virtual string_type dst_zone_name()const
+ {
+ return zone_names_.dst_zone_name();
+ }
+ //! True if zone uses daylight savings adjustments otherwise false
+ virtual bool has_dst()const
+ {
+ return has_dst_;
+ }
+ //! Local time that DST starts -- NADT if has_dst is false
+ virtual posix_time::ptime dst_local_start_time(gregorian::greg_year y)const
+ {
+ gregorian::date d(gregorian::not_a_date_time);
+ if(has_dst_)
+ {
+ d = dst_calc_rules_->start_day(y);
+ }
+ return posix_time::ptime(d, dst_offsets_.dst_start_offset_);
+ }
+ //! Local time that DST ends -- NADT if has_dst is false
+ virtual posix_time::ptime dst_local_end_time(gregorian::greg_year y)const
+ {
+ gregorian::date d(gregorian::not_a_date_time);
+ if(has_dst_)
+ {
+ d = dst_calc_rules_->end_day(y);
+ }
+ return posix_time::ptime(d, dst_offsets_.dst_end_offset_);
+ }
+ //! Base offset from UTC for zone (eg: -07:30:00)
+ virtual time_duration_type base_utc_offset()const
+ {
+ return base_utc_offset_;
+ }
+ //! Adjustment forward or back made while DST is in effect
+ virtual time_duration_type dst_offset()const
+ {
+ return dst_offsets_.dst_adjust_;
+ }
+
+ //! Returns a POSIX time_zone string for this object
+ virtual string_type to_posix_string() const
+ {
+ // std offset dst [offset],start[/time],end[/time] - w/o spaces
+ stringstream_type ss;
+ ss.fill('0');
+ boost::shared_ptr<dst_calc_rule> no_rules;
+ // std
+ ss << std_zone_abbrev();
+ // offset
+ if(base_utc_offset().is_negative()) {
+ // inverting the sign guarantees we get two digits
+ ss << '-' << std::setw(2) << base_utc_offset().invert_sign().hours();
+ }
+ else {
+ ss << '+' << std::setw(2) << base_utc_offset().hours();
+ }
+ if(base_utc_offset().minutes() != 0 || base_utc_offset().seconds() != 0) {
+ ss << ':' << std::setw(2) << base_utc_offset().minutes();
+ if(base_utc_offset().seconds() != 0) {
+ ss << ':' << std::setw(2) << base_utc_offset().seconds();
+ }
+ }
+ if(dst_calc_rules_ != no_rules) {
+ // dst
+ ss << dst_zone_abbrev();
+ // dst offset
+ if(dst_offset().is_negative()) {
+ // inverting the sign guarantees we get two digits
+ ss << '-' << std::setw(2) << dst_offset().invert_sign().hours();
+ }
+ else {
+ ss << '+' << std::setw(2) << dst_offset().hours();
+ }
+ if(dst_offset().minutes() != 0 || dst_offset().seconds() != 0) {
+ ss << ':' << std::setw(2) << dst_offset().minutes();
+ if(dst_offset().seconds() != 0) {
+ ss << ':' << std::setw(2) << dst_offset().seconds();
+ }
+ }
+ // start/time
+ ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->start_rule_as_string()) << '/'
+ << std::setw(2) << dst_offsets_.dst_start_offset_.hours() << ':'
+ << std::setw(2) << dst_offsets_.dst_start_offset_.minutes();
+ if(dst_offsets_.dst_start_offset_.seconds() != 0) {
+ ss << ':' << std::setw(2) << dst_offsets_.dst_start_offset_.seconds();
+ }
+ // end/time
+ ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->end_rule_as_string()) << '/'
+ << std::setw(2) << dst_offsets_.dst_end_offset_.hours() << ':'
+ << std::setw(2) << dst_offsets_.dst_end_offset_.minutes();
+ if(dst_offsets_.dst_end_offset_.seconds() != 0) {
+ ss << ':' << std::setw(2) << dst_offsets_.dst_end_offset_.seconds();
+ }
+ }
+
+ return ss.str();
+ }
+ private:
+ time_zone_names zone_names_;
+ bool has_dst_;
+ time_duration_type base_utc_offset_;
+ dst_adjustment_offsets dst_offsets_;
+ boost::shared_ptr<dst_calc_rule> dst_calc_rules_;
+
+ /*! Extract time zone abbreviations for STD & DST as well
+ * as the offsets for the time shift that occurs and how
+ * much of a shift. At this time full time zone names are
+ * NOT extracted so the abbreviations are used in their place */
+ void calc_zone(const string_type& obj){
+ const char_type empty_string[2] = {'\0'};
+ stringstream_type ss(empty_string);
+ typename string_type::const_pointer sit = obj.c_str(), obj_end = sit + obj.size();
+ string_type l_std_zone_abbrev, l_dst_zone_abbrev;
+
+ // get 'std' name/abbrev
+ while(std::isalpha(*sit)){
+ ss << *sit++;
+ }
+ l_std_zone_abbrev = ss.str();
+ ss.str(empty_string);
+
+ // get UTC offset
+ if(sit != obj_end){
+ // get duration
+ while(sit != obj_end && !std::isalpha(*sit)){
+ ss << *sit++;
+ }
+ base_utc_offset_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(ss.str());
+ ss.str(empty_string);
+
+ // base offset must be within range of -12 hours to +12 hours
+ if(base_utc_offset_ < time_duration_type(-12,0,0) ||
+ base_utc_offset_ > time_duration_type(12,0,0))
+ {
+ boost::throw_exception(bad_offset(posix_time::to_simple_string(base_utc_offset_)));
+ }
+ }
+
+ // get DST data if given
+ if(sit != obj_end){
+ has_dst_ = true;
+
+ // get 'dst' name/abbrev
+ while(sit != obj_end && std::isalpha(*sit)){
+ ss << *sit++;
+ }
+ l_dst_zone_abbrev = ss.str();
+ ss.str(empty_string);
+
+ // get DST offset if given
+ if(sit != obj_end){
+ // get duration
+ while(sit != obj_end && !std::isalpha(*sit)){
+ ss << *sit++;
+ }
+ dst_offsets_.dst_adjust_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(ss.str());
+ ss.str(empty_string);
+ }
+ else{ // default DST offset
+ dst_offsets_.dst_adjust_ = posix_time::hours(1);
+ }
+
+ // adjustment must be within +|- 1 day
+ if(dst_offsets_.dst_adjust_ <= time_duration_type(-24,0,0) ||
+ dst_offsets_.dst_adjust_ >= time_duration_type(24,0,0))
+ {
+ boost::throw_exception(bad_adjustment(posix_time::to_simple_string(dst_offsets_.dst_adjust_)));
+ }
+ }
+ // full names not extracted so abbrevs used in their place
+ zone_names_ = time_zone_names(l_std_zone_abbrev, l_std_zone_abbrev, l_dst_zone_abbrev, l_dst_zone_abbrev);
+ }
+
+ void calc_rules(const string_type& start, const string_type& end){
+#ifdef __HP_aCC
+ // Work around bug in aC++ compiler: see QXCR1000880488 in the
+ // HP bug tracking system
+ const char_type sep_chars[2] = {'/',0};
+#else
+ const char_type sep_chars[2] = {'/'};
+#endif
+ char_separator_type sep(sep_chars);
+ tokenizer_type st_tok(start, sep);
+ tokenizer_type et_tok(end, sep);
+ tokenizer_iterator_type sit = st_tok.begin();
+ tokenizer_iterator_type eit = et_tok.begin();
+
+ // generate date spec
+ char_type x = string_type(*sit).at(0);
+ if(x == 'M'){
+ M_func(*sit, *eit);
+ }
+ else if(x == 'J'){
+ julian_no_leap(*sit, *eit);
+ }
+ else{
+ julian_day(*sit, *eit);
+ }
+
+ ++sit;
+ ++eit;
+ // generate durations
+ // starting offset
+ if(sit != st_tok.end()){
+ dst_offsets_.dst_start_offset_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(*sit);
+ }
+ else{
+ // default
+ dst_offsets_.dst_start_offset_ = posix_time::hours(2);
+ }
+ // start/end offsets must fall on given date
+ if(dst_offsets_.dst_start_offset_ < time_duration_type(0,0,0) ||
+ dst_offsets_.dst_start_offset_ >= time_duration_type(24,0,0))
+ {
+ boost::throw_exception(bad_offset(posix_time::to_simple_string(dst_offsets_.dst_start_offset_)));
+ }
+
+ // ending offset
+ if(eit != et_tok.end()){
+ dst_offsets_.dst_end_offset_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(*eit);
+ }
+ else{
+ // default
+ dst_offsets_.dst_end_offset_ = posix_time::hours(2);
+ }
+ // start/end offsets must fall on given date
+ if(dst_offsets_.dst_end_offset_ < time_duration_type(0,0,0) ||
+ dst_offsets_.dst_end_offset_ >= time_duration_type(24,0,0))
+ {
+ boost::throw_exception(bad_offset(posix_time::to_simple_string(dst_offsets_.dst_end_offset_)));
+ }
+ }
+
+ /* Parses out a start/end date spec from a posix time zone string.
+ * Date specs come in three possible formats, this function handles
+ * the 'M' spec. Ex "M2.2.4" => 2nd month, 2nd week, 4th day .
+ */
+ void M_func(const string_type& s, const string_type& e){
+ typedef gregorian::nth_kday_of_month nkday;
+ unsigned short sm=0,sw=0,sd=0,em=0,ew=0,ed=0; // start/end month,week,day
+#ifdef __HP_aCC
+ // Work around bug in aC++ compiler: see QXCR1000880488 in the
+ // HP bug tracking system
+ const char_type sep_chars[3] = {'M','.',0};
+#else
+ const char_type sep_chars[3] = {'M','.'};
+#endif
+ char_separator_type sep(sep_chars);
+ tokenizer_type stok(s, sep), etok(e, sep);
+
+ tokenizer_iterator_type it = stok.begin();
+ sm = lexical_cast<unsigned short>(*it++);
+ sw = lexical_cast<unsigned short>(*it++);
+ sd = lexical_cast<unsigned short>(*it);
+
+ it = etok.begin();
+ em = lexical_cast<unsigned short>(*it++);
+ ew = lexical_cast<unsigned short>(*it++);
+ ed = lexical_cast<unsigned short>(*it);
+
+ dst_calc_rules_ = shared_ptr<dst_calc_rule>(
+ new nth_kday_dst_rule(
+ nth_last_dst_rule::start_rule(
+ static_cast<nkday::week_num>(sw),sd,sm),
+ nth_last_dst_rule::start_rule(
+ static_cast<nkday::week_num>(ew),ed,em)
+ )
+ );
+ }
+
+ //! Julian day. Feb29 is never counted, even in leap years
+ // expects range of 1-365
+ void julian_no_leap(const string_type& s, const string_type& e){
+ typedef gregorian::gregorian_calendar calendar;
+ const unsigned short year = 2001; // Non-leap year
+ unsigned short sm=1;
+ int sd=0;
+ sd = lexical_cast<int>(s.substr(1)); // skip 'J'
+ while(sd >= calendar::end_of_month_day(year,sm)){
+ sd -= calendar::end_of_month_day(year,sm++);
+ }
+ unsigned short em=1;
+ int ed=0;
+ ed = lexical_cast<int>(e.substr(1)); // skip 'J'
+ while(ed > calendar::end_of_month_day(year,em)){
+ ed -= calendar::end_of_month_day(year,em++);
+ }
+
+ dst_calc_rules_ = shared_ptr<dst_calc_rule>(
+ new partial_date_dst_rule(
+ partial_date_dst_rule::start_rule(
+ sd, static_cast<date_time::months_of_year>(sm)),
+ partial_date_dst_rule::end_rule(
+ ed, static_cast<date_time::months_of_year>(em))
+ )
+ );
+ }
+
+ //! Julian day. Feb29 is always counted, but exception thrown in non-leap years
+ // expects range of 0-365
+ void julian_day(const string_type& s, const string_type& e){
+ int sd=0, ed=0;
+ sd = lexical_cast<int>(s);
+ ed = lexical_cast<int>(e);
+ dst_calc_rules_ = shared_ptr<dst_calc_rule>(
+ new partial_date_dst_rule(
+ partial_date_dst_rule::start_rule(++sd),// args are 0-365
+ partial_date_dst_rule::end_rule(++ed) // pd expects 1-366
+ )
+ );
+ }
+
+ //! helper function used when throwing exceptions
+ static std::string td_as_string(const time_duration_type& td)
+ {
+ std::string s;
+#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+ s = posix_time::to_simple_string(td);
+#else
+ std::stringstream ss;
+ ss << td;
+ s = ss.str();
+#endif
+ return s;
+ }
+ };
+
+ typedef posix_time_zone_base<char> posix_time_zone;
+
+} } // namespace boost::local_time
+
+
+#endif // _DATE_TIME_POSIX_TIME_ZONE__
diff --git a/ext/boost/date_time/local_time/tz_database.hpp b/ext/boost/date_time/local_time/tz_database.hpp
new file mode 100644
index 0000000000..4cfca45c18
--- /dev/null
+++ b/ext/boost/date_time/local_time/tz_database.hpp
@@ -0,0 +1,32 @@
+#ifndef BOOST_DATE_TIME_TZ_DATABASE_HPP__
+#define BOOST_DATE_TIME_TZ_DATABASE_HPP__
+
+/* Copyright (c) 2003-2004 CrystalClear Software, Inc.
+ * 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) $
+ */
+
+#include <string>
+#include "boost/date_time/local_time/custom_time_zone.hpp"
+#include "boost/date_time/local_time/dst_transition_day_rules.hpp"
+#include "boost/date_time/tz_db_base.hpp"
+
+
+namespace boost {
+namespace local_time {
+
+ using date_time::data_not_accessible;
+ using date_time::bad_field_count;
+
+ //! Object populated with boost::shared_ptr<time_zone_base> objects
+ /*! Object populated with boost::shared_ptr<time_zone_base> objects
+ * Database is populated from specs stored in external csv file. See
+ * date_time::tz_db_base for greater detail */
+ typedef date_time::tz_db_base<custom_time_zone, nth_kday_dst_rule> tz_database;
+
+}} // namespace
+
+#endif // BOOST_DATE_TIME_TZ_DATABASE_HPP__
+
diff --git a/ext/boost/date_time/local_time_adjustor.hpp b/ext/boost/date_time/local_time_adjustor.hpp
new file mode 100644
index 0000000000..eea4d37ae3
--- /dev/null
+++ b/ext/boost/date_time/local_time_adjustor.hpp
@@ -0,0 +1,218 @@
+#ifndef DATE_TIME_LOCAL_TIME_ADJUSTOR_HPP__
+#define DATE_TIME_LOCAL_TIME_ADJUSTOR_HPP__
+
+/* 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-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+/*! @file local_time_adjustor.hpp
+ Time adjustment calculations for local times
+*/
+
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/date_generators.hpp>
+#include <boost/date_time/dst_rules.hpp>
+#include <boost/date_time/time_defs.hpp> // boost::date_time::dst_flags
+#include <boost/date_time/special_defs.hpp> // not_a_date_time
+
+namespace boost {
+ namespace date_time {
+
+
+ //! Provides a base offset adjustment from utc
+ template<class time_duration_type,
+ short hours, unsigned short minutes = 0>
+ class utc_adjustment
+ {
+ public:
+ static time_duration_type local_to_utc_base_offset()
+ {
+ time_duration_type td(hours,minutes,0);
+ return td.invert_sign();
+ }
+ static time_duration_type utc_to_local_base_offset()
+ {
+ return time_duration_type(hours,minutes,0);
+ }
+ };
+
+
+
+ //! Allow sliding utc adjustment with fixed dst rules
+ template<class time_type, class dst_rules>
+ class dynamic_local_time_adjustor : public dst_rules
+ {
+ public:
+ typedef typename time_type::time_duration_type time_duration_type;
+ typedef typename time_type::date_type date_type;
+
+ dynamic_local_time_adjustor(time_duration_type utc_offset) :
+ utc_offset_(utc_offset)
+ {}
+
+ //! Presumes local time
+ time_duration_type utc_offset(bool is_dst)
+ {
+ if (is_dst) {
+ return utc_offset_ + this->dst_offset();
+ }
+ else {
+ return utc_offset_;
+ }
+
+ }
+ private:
+ time_duration_type utc_offset_;
+
+ };
+
+
+
+ //! Embed the rules for local time adjustments at compile time
+ template<class time_type, class dst_rules, class utc_offset_rules>
+ class static_local_time_adjustor: public dst_rules, public utc_offset_rules
+ {
+ public:
+ typedef typename time_type::time_duration_type time_duration_type;
+ typedef typename time_type::date_type date_type;
+
+ //! Calculates the offset from a utc time to local based on dst and utc offset
+ /*! @param t UTC time to calculate offset to local time
+ * This adjustment depends on the following observations about the
+ * workings of the DST boundary offset. Since UTC time labels are
+ * monotonically increasing we can determine if a given local time
+ * is in DST or not and therefore adjust the offset appropriately.
+ *
+ * The logic is as follows. Starting with UTC time use the offset to
+ * create a label for an non-dst adjusted local time. Then call
+ * dst_rules::local_is_dst with the non adjust local time. The
+ * results of this function will either unabiguously decide that
+ * the initial local time is in dst or return an illegal or
+ * ambiguous result. An illegal result only occurs at the end
+ * of dst (where labels are skipped) and indicates that dst has
+ * ended. An ambiguous result means that we need to recheck by
+ * making a dst adjustment and then rechecking. If the dst offset
+ * is added to the utc time and the recheck proves non-ambiguous
+ * then we are past the boundary. If it is still ambiguous then
+ * we are ahead of the boundary and dst is still in effect.
+ *
+ * TODO -- check if all dst offsets are positive. If not then
+ * the algorithm needs to check for this and reverse the
+ * illegal/ambiguous logic.
+ */
+ static time_duration_type utc_to_local_offset(const time_type& t)
+ {
+ //get initial local time guess by applying utc offset
+ time_type initial = t + utc_offset_rules::utc_to_local_base_offset();
+ time_is_dst_result dst_flag =
+ dst_rules::local_is_dst(initial.date(), initial.time_of_day());
+ switch(dst_flag) {
+ case is_in_dst: return utc_offset_rules::utc_to_local_base_offset() + dst_rules::dst_offset();
+ case is_not_in_dst: return utc_offset_rules::utc_to_local_base_offset();
+ case invalid_time_label:return utc_offset_rules::utc_to_local_base_offset() + dst_rules::dst_offset();
+ case ambiguous: {
+ time_type retry = initial + dst_rules::dst_offset();
+ dst_flag = dst_rules::local_is_dst(retry.date(), retry.time_of_day());
+ //if still ambibuous then the utc time still translates to a dst time
+ if (dst_flag == ambiguous) {
+ return utc_offset_rules::utc_to_local_base_offset() + dst_rules::dst_offset();
+ }
+ // we are past the dst boundary
+ else {
+ return utc_offset_rules::utc_to_local_base_offset();
+ }
+ }
+ }//case
+ //TODO better exception type
+ boost::throw_exception(std::out_of_range("Unreachable case"));
+ BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return time_duration_type(not_a_date_time)); // should never reach
+ }
+
+ //! Get the offset to UTC given a local time
+ static time_duration_type local_to_utc_offset(const time_type& t,
+ date_time::dst_flags dst=date_time::calculate)
+ {
+ switch (dst) {
+ case is_dst:
+ return utc_offset_rules::local_to_utc_base_offset() - dst_rules::dst_offset();
+ case not_dst:
+ return utc_offset_rules::local_to_utc_base_offset();
+ case calculate:
+ time_is_dst_result res =
+ dst_rules::local_is_dst(t.date(), t.time_of_day());
+ switch(res) {
+ case is_in_dst: return utc_offset_rules::local_to_utc_base_offset() - dst_rules::dst_offset();
+ case is_not_in_dst: return utc_offset_rules::local_to_utc_base_offset();
+ case ambiguous: return utc_offset_rules::local_to_utc_base_offset();
+ case invalid_time_label: break;
+ }
+ }
+ boost::throw_exception(std::out_of_range("Time label invalid"));
+ BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return time_duration_type(not_a_date_time)); // should never reach
+ }
+
+
+ private:
+
+ };
+
+ void dummy_to_prevent_msvc6_ice(); //why ask why?
+
+ //! Template that simplifies the creation of local time calculator
+ /*! Use this template to create the timezone to utc convertors as required.
+ *
+ * This class will also work for other regions that don't use dst and
+ * have a utc offset which is an integral number of hours.
+ *
+ * <b>Template Parameters</b>
+ * -time_type -- Time class to use
+ * -utc_offset -- Number hours local time is adjust from utc
+ * -use_dst -- true (default) if region uses dst, false otherwise
+ * For example:
+ * @code
+ * //eastern timezone is utc-5
+ typedef date_time::local_adjustor<ptime, -5, us_dst> us_eastern;
+ typedef date_time::local_adjustor<ptime, -6, us_dst> us_central;
+ typedef date_time::local_adjustor<ptime, -7, us_dst> us_mountain;
+ typedef date_time::local_adjustor<ptime, -8, us_dst> us_pacific;
+ typedef date_time::local_adjustor<ptime, -7, no_dst> us_arizona;
+ @endcode
+
+ */
+ template<class time_type, short utc_offset, class dst_rule>
+ class local_adjustor
+ {
+ public:
+ typedef typename time_type::time_duration_type time_duration_type;
+ typedef typename time_type::date_type date_type;
+ typedef static_local_time_adjustor<time_type,
+ dst_rule,
+ utc_adjustment<time_duration_type,
+ utc_offset> > dst_adjustor;
+ //! Convert a utc time to local time
+ static time_type utc_to_local(const time_type& t)
+ {
+ time_duration_type td = dst_adjustor::utc_to_local_offset(t);
+ return t + td;
+ }
+ //! Convert a local time to utc
+ static time_type local_to_utc(const time_type& t,
+ date_time::dst_flags dst=date_time::calculate)
+ {
+ time_duration_type td = dst_adjustor::local_to_utc_offset(t, dst);
+ return t + td;
+ }
+ };
+
+
+ } } //namespace date_time
+
+
+
+#endif
diff --git a/ext/boost/date_time/local_timezone_defs.hpp b/ext/boost/date_time/local_timezone_defs.hpp
new file mode 100644
index 0000000000..fd6d3c2fab
--- /dev/null
+++ b/ext/boost/date_time/local_timezone_defs.hpp
@@ -0,0 +1,193 @@
+#ifndef DATE_TIME_LOCAL_TIMEZONE_DEFS_HPP__
+#define DATE_TIME_LOCAL_TIMEZONE_DEFS_HPP__
+
+/* 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-11-13 15:10:23 -0500 (Thu, 13 Nov 2008) $
+ */
+
+#include "boost/date_time/dst_rules.hpp"
+
+namespace boost {
+ namespace date_time {
+
+ // Configurations for common dst rules cases:
+ // See http://www.wharton.co.uk/Support/sup_dst.htm for more
+ // information on how various locales use dst rules
+
+ //! Specification for daylight savings start rules in US
+ /*! This class is used to configure dst_calc_engine template typically
+ as follows:
+ @code
+ using namespace boost::gregorian;
+ using namespace boost::posix_time;
+ typedef us_dst_trait<date> us_dst_traits;
+ typedef boost::date_time::dst_calc_engine<date, time_duration,
+ us_dst_traits>
+ us_dst_calc;
+ //calculate the 2002 transition day of USA April 7 2002
+ date dst_start = us_dst_calc::local_dst_start_day(2002);
+
+ //calculate the 2002 transition day of USA Oct 27 2002
+ date dst_end = us_dst_calc::local_dst_end_day(2002);
+
+ //check if a local time is in dst or not -- posible answers
+ //are yes, no, invalid time label, ambiguous
+ ptime t(...some time...);
+ if (us_dst::local_is_dst(t.date(), t.time_of_day())
+ == boost::date_time::is_not_in_dst)
+ {
+
+ }
+
+ @endcode
+ This generates a type suitable for the calculation of dst
+ transitions for the United States. Of course other templates
+ can be used for other locales.
+
+ */
+
+ template<class date_type>
+ struct us_dst_trait
+ {
+ typedef typename date_type::day_of_week_type day_of_week_type;
+ typedef typename date_type::month_type month_type;
+ typedef typename date_type::year_type year_type;
+ typedef date_time::nth_kday_of_month<date_type> start_rule_functor;
+ typedef date_time::first_kday_of_month<date_type> end_rule_functor;
+ typedef date_time::first_kday_of_month<date_type> start_rule_functor_pre2007;
+ typedef date_time::last_kday_of_month<date_type> end_rule_functor_pre2007;
+ static day_of_week_type start_day(year_type) {return Sunday;}
+ static month_type start_month(year_type y)
+ {
+ if (y < 2007) return Apr;
+ return Mar;
+ }
+ static day_of_week_type end_day(year_type) {return Sunday;}
+ static month_type end_month(year_type y)
+ {
+ if (y < 2007) return Oct;
+ return Nov;
+ }
+ static date_type local_dst_start_day(year_type year)
+ {
+ if (year < 2007) {
+ start_rule_functor_pre2007 start1(start_day(year),
+ start_month(year));
+ return start1.get_date(year);
+ }
+ start_rule_functor start(start_rule_functor::second,
+ start_day(year),
+ start_month(year));
+ return start.get_date(year);
+
+ }
+ static date_type local_dst_end_day(year_type year)
+ {
+ if (year < 2007) {
+ end_rule_functor_pre2007 end_rule(end_day(year),
+ end_month(year));
+ return end_rule.get_date(year);
+ }
+ end_rule_functor end(end_day(year),
+ end_month(year));
+ return end.get_date(year);
+ }
+ static int dst_start_offset_minutes() { return 120;}
+ static int dst_end_offset_minutes() { return 120; }
+ static int dst_shift_length_minutes() { return 60; }
+ };
+
+ //!Rules for daylight savings start in the EU (Last Sun in Mar)
+ /*!These amount to the following:
+ - Start of dst day is last Sunday in March
+ - End day of dst is last Sunday in Oct
+ - Going forward switch time is 2:00 am (offset 120 minutes)
+ - Going back switch time is 3:00 am (off set 180 minutes)
+ - Shift duration is one hour (60 minutes)
+ */
+ template<class date_type>
+ struct eu_dst_trait
+ {
+ typedef typename date_type::day_of_week_type day_of_week_type;
+ typedef typename date_type::month_type month_type;
+ typedef typename date_type::year_type year_type;
+ typedef date_time::last_kday_of_month<date_type> start_rule_functor;
+ typedef date_time::last_kday_of_month<date_type> end_rule_functor;
+ static day_of_week_type start_day(year_type) {return Sunday;}
+ static month_type start_month(year_type) {return Mar;}
+ static day_of_week_type end_day(year_type) {return Sunday;}
+ static month_type end_month(year_type) {return Oct;}
+ static int dst_start_offset_minutes() { return 120;}
+ static int dst_end_offset_minutes() { return 180; }
+ static int dst_shift_length_minutes() { return 60; }
+ static date_type local_dst_start_day(year_type year)
+ {
+ start_rule_functor start(start_day(year),
+ start_month(year));
+ return start.get_date(year);
+ }
+ static date_type local_dst_end_day(year_type year)
+ {
+ end_rule_functor end(end_day(year),
+ end_month(year));
+ return end.get_date(year);
+ }
+ };
+
+ //! Alternative dst traits for some parts of the United Kingdom
+ /* Several places in the UK use EU start and end rules for the
+ day, but different local conversion times (eg: forward change at 1:00
+ am local and backward change at 2:00 am dst instead of 2:00am
+ forward and 3:00am back for the EU).
+ */
+ template<class date_type>
+ struct uk_dst_trait : public eu_dst_trait<date_type>
+ {
+ static int dst_start_offset_minutes() { return 60;}
+ static int dst_end_offset_minutes() { return 120; }
+ static int dst_shift_length_minutes() { return 60; }
+ };
+
+ //Rules for Adelaide Australia
+ template<class date_type>
+ struct acst_dst_trait
+ {
+ typedef typename date_type::day_of_week_type day_of_week_type;
+ typedef typename date_type::month_type month_type;
+ typedef typename date_type::year_type year_type;
+ typedef date_time::last_kday_of_month<date_type> start_rule_functor;
+ typedef date_time::last_kday_of_month<date_type> end_rule_functor;
+ static day_of_week_type start_day(year_type) {return Sunday;}
+ static month_type start_month(year_type) {return Oct;}
+ static day_of_week_type end_day(year_type) {return Sunday;}
+ static month_type end_month(year_type) {return Mar;}
+ static int dst_start_offset_minutes() { return 120;}
+ static int dst_end_offset_minutes() { return 180; }
+ static int dst_shift_length_minutes() { return 60; }
+ static date_type local_dst_start_day(year_type year)
+ {
+ start_rule_functor start(start_day(year),
+ start_month(year));
+ return start.get_date(year);
+ }
+ static date_type local_dst_end_day(year_type year)
+ {
+ end_rule_functor end(end_day(year),
+ end_month(year));
+ return end.get_date(year);
+ }
+ };
+
+
+
+
+
+
+} } //namespace boost::date_time
+
+
+#endif
diff --git a/ext/boost/date_time/locale_config.hpp b/ext/boost/date_time/locale_config.hpp
new file mode 100644
index 0000000000..d01e008fea
--- /dev/null
+++ b/ext/boost/date_time/locale_config.hpp
@@ -0,0 +1,31 @@
+#ifndef DATE_TIME_LOCALE_CONFIG_HPP___
+#define DATE_TIME_LOCALE_CONFIG_HPP___
+
+/* Copyright (c) 2002-2006 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) $
+ */
+
+// This file configures whether the library will support locales and hence
+// iostream based i/o. Even if a compiler has some support for locales,
+// any failure to be compatible gets the compiler on the exclusion list.
+//
+// At the moment this is defined for MSVC 6 and any compiler that
+// defines BOOST_NO_STD_LOCALE (gcc 2.95.x)
+
+#include "boost/config.hpp" //sets BOOST_NO_STD_LOCALE
+#include "boost/detail/workaround.hpp"
+
+//This file basically becomes a noop if locales are not properly supported
+#if (defined(BOOST_NO_STD_LOCALE) \
+ || (BOOST_WORKAROUND( BOOST_MSVC, < 1300)) \
+ || (BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x581 )) ) )
+#define BOOST_DATE_TIME_NO_LOCALE
+#endif
+
+
+#endif
+
diff --git a/ext/boost/date_time/microsec_time_clock.hpp b/ext/boost/date_time/microsec_time_clock.hpp
new file mode 100644
index 0000000000..e6f3b8ecdf
--- /dev/null
+++ b/ext/boost/date_time/microsec_time_clock.hpp
@@ -0,0 +1,127 @@
+#ifndef DATE_TIME_HIGHRES_TIME_CLOCK_HPP___
+#define DATE_TIME_HIGHRES_TIME_CLOCK_HPP___
+
+/* Copyright (c) 2002,2003,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: 2009-06-04 07:36:43 -0400 (Thu, 04 Jun 2009) $
+ */
+
+
+/*! @file microsec_time_clock.hpp
+ This file contains a high resolution time clock implementation.
+*/
+
+#include <boost/cstdint.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/c_time.hpp>
+#include <boost/date_time/time_clock.hpp>
+#include <boost/date_time/filetime_functions.hpp>
+
+#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
+
+namespace boost {
+namespace date_time {
+
+ //! A clock providing microsecond level resolution
+ /*! A high precision clock that measures the local time
+ * at a resolution up to microseconds and adjusts to the
+ * resolution of the time system. For example, for the
+ * a library configuration with nano second resolution,
+ * the last 3 places of the fractional seconds will always
+ * be 000 since there are 1000 nano-seconds in a micro second.
+ */
+ template<class time_type>
+ class microsec_clock
+ {
+ private:
+ //! Type for the function used to convert time_t to tm
+ typedef std::tm* (*time_converter)(const std::time_t*, std::tm*);
+
+ public:
+ typedef typename time_type::date_type date_type;
+ typedef typename time_type::time_duration_type time_duration_type;
+ typedef typename time_duration_type::rep_type resolution_traits_type;
+
+ //! return a local time object for the given zone, based on computer clock
+ //JKG -- looks like we could rewrite this against universal_time
+ template<class time_zone_type>
+ static time_type local_time(shared_ptr<time_zone_type> tz_ptr)
+ {
+ typedef typename time_type::utc_time_type utc_time_type;
+ typedef second_clock<utc_time_type> second_clock;
+ // we'll need to know the utc_offset this machine has
+ // in order to get a utc_time_type set to utc
+ utc_time_type utc_time = second_clock::universal_time();
+ time_duration_type utc_offset = second_clock::local_time() - utc_time;
+ // use micro clock to get a local time with sub seconds
+ // and adjust it to get a true utc time reading with sub seconds
+ utc_time = microsec_clock<utc_time_type>::local_time() - utc_offset;
+ return time_type(utc_time, tz_ptr);
+ }
+
+ //! Returns the local time based on computer clock settings
+ static time_type local_time()
+ {
+ return create_time(&c_time::localtime);
+ }
+
+ //! Returns the UTC time based on computer settings
+ static time_type universal_time()
+ {
+ return create_time(&c_time::gmtime);
+ }
+
+ private:
+ static time_type create_time(time_converter converter)
+ {
+#ifdef BOOST_HAS_GETTIMEOFDAY
+ timeval tv;
+ gettimeofday(&tv, 0); //gettimeofday does not support TZ adjust on Linux.
+ std::time_t t = tv.tv_sec;
+ boost::uint32_t sub_sec = tv.tv_usec;
+#elif defined(BOOST_HAS_FTIME)
+ winapi::file_time ft;
+ winapi::get_system_time_as_file_time(ft);
+ uint64_t micros = winapi::file_time_to_microseconds(ft); // it will not wrap, since ft is the current time
+ // and cannot be before 1970-Jan-01
+ std::time_t t = static_cast<std::time_t>(micros / 1000000UL); // seconds since epoch
+ // microseconds -- static casts supress warnings
+ boost::uint32_t sub_sec = static_cast<boost::uint32_t>(micros % 1000000UL);
+#else
+#error Internal Boost.DateTime error: BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK is defined, however neither gettimeofday nor FILETIME support is detected.
+#endif
+
+ std::tm curr;
+ std::tm* curr_ptr = converter(&t, &curr);
+ date_type d(curr_ptr->tm_year + 1900,
+ curr_ptr->tm_mon + 1,
+ curr_ptr->tm_mday);
+
+ //The following line will adjust the fractional second tick in terms
+ //of the current time system. For example, if the time system
+ //doesn't support fractional seconds then res_adjust returns 0
+ //and all the fractional seconds return 0.
+ int adjust = static_cast< int >(resolution_traits_type::res_adjust() / 1000000);
+
+ time_duration_type td(curr_ptr->tm_hour,
+ curr_ptr->tm_min,
+ curr_ptr->tm_sec,
+ sub_sec * adjust);
+
+ return time_type(d,td);
+ }
+ };
+
+
+} } //namespace date_time
+
+#endif //BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
+
+
+#endif
+
diff --git a/ext/boost/date_time/parse_format_base.hpp b/ext/boost/date_time/parse_format_base.hpp
new file mode 100644
index 0000000000..b17a5c8e77
--- /dev/null
+++ b/ext/boost/date_time/parse_format_base.hpp
@@ -0,0 +1,29 @@
+#ifndef DATE_TIME_PARSE_FORMAT_BASE__
+#define DATE_TIME_PARSE_FORMAT_BASE__
+
+/* 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) $
+ */
+
+namespace boost {
+namespace date_time {
+
+ //! Enum for distinguishing parsing and formatting options
+ enum month_format_spec {month_as_integer, month_as_short_string,
+ month_as_long_string};
+
+ //! Enum for distinguishing the order of Month, Day, & Year.
+ /*! Enum for distinguishing the order in which Month, Day, & Year
+ * will appear in a date string */
+ enum ymd_order_spec {ymd_order_iso, //order is year-month-day
+ ymd_order_dmy, //day-month-year
+ ymd_order_us}; //order is month-day-year
+
+
+} }//namespace date_time
+
+#endif
diff --git a/ext/boost/date_time/period.hpp b/ext/boost/date_time/period.hpp
new file mode 100644
index 0000000000..c67bc36c65
--- /dev/null
+++ b/ext/boost/date_time/period.hpp
@@ -0,0 +1,377 @@
+#ifndef DATE_TIME_PERIOD_HPP___
+#define DATE_TIME_PERIOD_HPP___
+
+/* 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) $
+ */
+
+/*! \file period.hpp
+ This file contain the implementation of the period abstraction. This is
+ basically the same idea as a range. Although this class is intended for
+ use in the time library, it is pretty close to general enough for other
+ numeric uses.
+
+*/
+
+#include "boost/operators.hpp"
+
+
+namespace boost {
+namespace date_time {
+ //!Provides generalized period type useful in date-time systems
+ /*!This template uses a class to represent a time point within the period
+ and another class to represent a duration. As a result, this class is
+ not appropriate for use when the number and duration representation
+ are the same (eg: in the regular number domain).
+
+ A period can be specified by providing either the begining point and
+ a duration or the begining point and the end point( end is NOT part
+ of the period but 1 unit past it. A period will be "invalid" if either
+ end_point <= begin_point or the given duration is <= 0. Any valid period
+ will return false for is_null().
+
+ Zero length periods are also considered invalid. Zero length periods are
+ periods where the begining and end points are the same, or, the given
+ duration is zero. For a zero length period, the last point will be one
+ unit less than the begining point.
+
+ In the case that the begin and last are the same, the period has a
+ length of one unit.
+
+ The best way to handle periods is usually to provide a begining point and
+ a duration. So, day1 + 7 days is a week period which includes all of the
+ first day and 6 more days (eg: Sun to Sat).
+
+ */
+ template<class point_rep, class duration_rep>
+ class period : private
+ boost::less_than_comparable<period<point_rep, duration_rep>
+ , boost::equality_comparable< period<point_rep, duration_rep>
+ > >
+ {
+ public:
+ typedef point_rep point_type;
+ typedef duration_rep duration_type;
+
+ period(point_rep first_point, point_rep end_point);
+ period(point_rep first_point, duration_rep len);
+ point_rep begin() const;
+ point_rep end() const;
+ point_rep last() const;
+ duration_rep length() const;
+ bool is_null() const;
+ bool operator==(const period& rhs) const;
+ bool operator<(const period& rhs) const;
+ void shift(const duration_rep& d);
+ void expand(const duration_rep& d);
+ bool contains(const point_rep& point) const;
+ bool contains(const period& other) const;
+ bool intersects(const period& other) const;
+ bool is_adjacent(const period& other) const;
+ bool is_before(const point_rep& point) const;
+ bool is_after(const point_rep& point) const;
+ period intersection(const period& other) const;
+ period merge(const period& other) const;
+ period span(const period& other) const;
+ private:
+ point_rep begin_;
+ point_rep last_;
+ };
+
+ //! create a period from begin to last eg: [begin,end)
+ /*! If end <= begin then the period will be invalid
+ */
+ template<class point_rep, class duration_rep>
+ inline
+ period<point_rep,duration_rep>::period(point_rep first_point,
+ point_rep end_point) :
+ begin_(first_point),
+ last_(end_point - duration_rep::unit())
+ {}
+
+ //! create a period as [begin, begin+len)
+ /*! If len is <= 0 then the period will be invalid
+ */
+ template<class point_rep, class duration_rep>
+ inline
+ period<point_rep,duration_rep>::period(point_rep first_point, duration_rep len) :
+ begin_(first_point),
+ last_(first_point + len-duration_rep::unit())
+ { }
+
+
+ //! Return the first element in the period
+ template<class point_rep, class duration_rep>
+ inline
+ point_rep period<point_rep,duration_rep>::begin() const
+ {
+ return begin_;
+ }
+
+ //! Return one past the last element
+ template<class point_rep, class duration_rep>
+ inline
+ point_rep period<point_rep,duration_rep>::end() const
+ {
+ return last_ + duration_rep::unit();
+ }
+
+ //! Return the last item in the period
+ template<class point_rep, class duration_rep>
+ inline
+ point_rep period<point_rep,duration_rep>::last() const
+ {
+ return last_;
+ }
+
+ //! True if period is ill formed (length is zero or less)
+ template<class point_rep, class duration_rep>
+ inline
+ bool period<point_rep,duration_rep>::is_null() const
+ {
+ return end() <= begin_;
+ }
+
+ //! Return the length of the period
+ template<class point_rep, class duration_rep>
+ inline
+ duration_rep period<point_rep,duration_rep>::length() const
+ {
+ if(last_ < begin_){ // invalid period
+ return last_+duration_rep::unit() - begin_;
+ }
+ else{
+ return end() - begin_; // normal case
+ }
+ }
+
+ //! Equality operator
+ template<class point_rep, class duration_rep>
+ inline
+ bool period<point_rep,duration_rep>::operator==(const period& rhs) const
+ {
+ return ((begin_ == rhs.begin_) &&
+ (last_ == rhs.last_));
+ }
+
+ //! Strict as defined by rhs.last <= lhs.last
+ template<class point_rep, class duration_rep>
+ inline
+ bool period<point_rep,duration_rep>::operator<(const period& rhs) const
+ {
+ return (last_ < rhs.begin_);
+ }
+
+
+ //! Shift the start and end by the specified amount
+ template<class point_rep, class duration_rep>
+ inline
+ void period<point_rep,duration_rep>::shift(const duration_rep& d)
+ {
+ begin_ = begin_ + d;
+ last_ = last_ + d;
+ }
+
+ /** Expands the size of the period by the duration on both ends.
+ *
+ *So before expand
+ *@code
+ *
+ * [-------]
+ * ^ ^ ^ ^ ^ ^ ^
+ * 1 2 3 4 5 6 7
+ *
+ *@endcode
+ * After expand(2)
+ *@code
+ *
+ * [----------------------]
+ * ^ ^ ^ ^ ^ ^ ^
+ * 1 2 3 4 5 6 7
+ *
+ *@endcode
+ */
+ template<class point_rep, class duration_rep>
+ inline
+ void period<point_rep,duration_rep>::expand(const duration_rep& d)
+ {
+ begin_ = begin_ - d;
+ last_ = last_ + d;
+ }
+
+ //! True if the point is inside the period, zero length periods contain no points
+ template<class point_rep, class duration_rep>
+ inline
+ bool period<point_rep,duration_rep>::contains(const point_rep& point) const
+ {
+ return ((point >= begin_) &&
+ (point <= last_));
+ }
+
+
+ //! True if this period fully contains (or equals) the other period
+ template<class point_rep, class duration_rep>
+ inline
+ bool period<point_rep,duration_rep>::contains(const period<point_rep,duration_rep>& other) const
+ {
+ return ((begin_ <= other.begin_) && (last_ >= other.last_));
+ }
+
+
+ //! True if periods are next to each other without a gap.
+ /* In the example below, p1 and p2 are adjacent, but p3 is not adjacent
+ * with either of p1 or p2.
+ *@code
+ * [-p1-)
+ * [-p2-)
+ * [-p3-)
+ *@endcode
+ */
+ template<class point_rep, class duration_rep>
+ inline
+ bool
+ period<point_rep,duration_rep>::is_adjacent(const period<point_rep,duration_rep>& other) const
+ {
+ return (other.begin() == end() ||
+ begin_ == other.end());
+ }
+
+
+ //! True if all of the period is prior or t < start
+ /* In the example below only point 1 would evaluate to true.
+ *@code
+ * [---------])
+ * ^ ^ ^ ^ ^
+ * 1 2 3 4 5
+ *
+ *@endcode
+ */
+ template<class point_rep, class duration_rep>
+ inline
+ bool
+ period<point_rep,duration_rep>::is_after(const point_rep& t) const
+ {
+ if (is_null())
+ {
+ return false; //null period isn't after
+ }
+
+ return t < begin_;
+ }
+
+ //! True if all of the period is prior to the passed point or end <= t
+ /* In the example below points 4 and 5 return true.
+ *@code
+ * [---------])
+ * ^ ^ ^ ^ ^
+ * 1 2 3 4 5
+ *
+ *@endcode
+ */
+ template<class point_rep, class duration_rep>
+ inline
+ bool
+ period<point_rep,duration_rep>::is_before(const point_rep& t) const
+ {
+ if (is_null())
+ {
+ return false; //null period isn't before anything
+ }
+
+ return last_ < t;
+ }
+
+
+ //! True if the periods overlap in any way
+ /* In the example below p1 intersects with p2, p4, and p6.
+ *@code
+ * [---p1---)
+ * [---p2---)
+ * [---p3---)
+ * [---p4---)
+ * [-p5-)
+ * [-p6-)
+ *@endcode
+ */
+ template<class point_rep, class duration_rep>
+ inline
+ bool period<point_rep,duration_rep>::intersects(const period<point_rep,duration_rep>& other) const
+ {
+ return ( contains(other.begin_) ||
+ other.contains(begin_) ||
+ ((other.begin_ < begin_) && (other.last_ >= begin_)));
+ }
+
+ //! Returns the period of intersection or invalid range no intersection
+ template<class point_rep, class duration_rep>
+ inline
+ period<point_rep,duration_rep>
+ period<point_rep,duration_rep>::intersection(const period<point_rep,duration_rep>& other) const
+ {
+ if (begin_ > other.begin_) {
+ if (last_ <= other.last_) { //case2
+ return *this;
+ }
+ //case 1
+ return period<point_rep,duration_rep>(begin_, other.end());
+ }
+ else {
+ if (last_ <= other.last_) { //case3
+ return period<point_rep,duration_rep>(other.begin_, this->end());
+ }
+ //case4
+ return other;
+ }
+ //unreachable
+ }
+
+ //! Returns the union of intersecting periods -- or null period
+ /*!
+ */
+ template<class point_rep, class duration_rep>
+ inline
+ period<point_rep,duration_rep>
+ period<point_rep,duration_rep>::merge(const period<point_rep,duration_rep>& other) const
+ {
+ if (this->intersects(other)) {
+ if (begin_ < other.begin_) {
+ return period<point_rep,duration_rep>(begin_, last_ > other.last_ ? this->end() : other.end());
+ }
+
+ return period<point_rep,duration_rep>(other.begin_, last_ > other.last_ ? this->end() : other.end());
+
+ }
+ return period<point_rep,duration_rep>(begin_,begin_); // no intersect return null
+ }
+
+ //! Combine two periods with earliest start and latest end.
+ /*! Combines two periods and any gap between them such that
+ * start = min(p1.start, p2.start)
+ * end = max(p1.end , p2.end)
+ *@code
+ * [---p1---)
+ * [---p2---)
+ * result:
+ * [-----------p3----------)
+ *@endcode
+ */
+ template<class point_rep, class duration_rep>
+ inline
+ period<point_rep,duration_rep>
+ period<point_rep,duration_rep>::span(const period<point_rep,duration_rep>& other) const
+ {
+ point_rep start((begin_ < other.begin_) ? begin() : other.begin());
+ point_rep newend((last_ < other.last_) ? other.end() : this->end());
+ return period<point_rep,duration_rep>(start, newend);
+ }
+
+
+} } //namespace date_time
+
+
+
+#endif
diff --git a/ext/boost/date_time/period_formatter.hpp b/ext/boost/date_time/period_formatter.hpp
new file mode 100644
index 0000000000..08082e10f6
--- /dev/null
+++ b/ext/boost/date_time/period_formatter.hpp
@@ -0,0 +1,196 @@
+
+#ifndef DATETIME_PERIOD_FORMATTER_HPP___
+#define DATETIME_PERIOD_FORMATTER_HPP___
+
+/* 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) $
+ */
+
+
+
+namespace boost { namespace date_time {
+
+
+ //! Not a facet, but a class used to specify and control period formats
+ /*! Provides settings for the following:
+ * - period_separator -- default '/'
+ * - period_open_start_delimeter -- default '['
+ * - period_open_range_end_delimeter -- default ')'
+ * - period_closed_range_end_delimeter -- default ']'
+ * - display_as_open_range, display_as_closed_range -- default closed_range
+ *
+ * Thus the default formatting for a period is as follows:
+ *@code
+ * [period.start()/period.last()]
+ *@endcode
+ * So for a typical date_period this would be
+ *@code
+ * [2004-Jan-04/2004-Feb-01]
+ *@endcode
+ * where the date formatting is controlled by the date facet
+ */
+ template <class CharT, class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
+ class period_formatter {
+ public:
+ typedef std::basic_string<CharT> string_type;
+ typedef CharT char_type;
+ typedef typename std::basic_string<char_type>::const_iterator const_itr_type;
+ typedef std::vector<std::basic_string<CharT> > collection_type;
+
+ static const char_type default_period_separator[2];
+ static const char_type default_period_start_delimeter[2];
+ static const char_type default_period_open_range_end_delimeter[2];
+ static const char_type default_period_closed_range_end_delimeter[2];
+
+ enum range_display_options { AS_OPEN_RANGE, AS_CLOSED_RANGE };
+
+ //! Constructor that sets up period formatter options -- default should suffice most cases.
+ period_formatter(range_display_options range_option_in = AS_CLOSED_RANGE,
+ const char_type* const period_separator = default_period_separator,
+ const char_type* const period_start_delimeter = default_period_start_delimeter,
+ const char_type* const period_open_range_end_delimeter = default_period_open_range_end_delimeter,
+ const char_type* const period_closed_range_end_delimeter = default_period_closed_range_end_delimeter) :
+ m_range_option(range_option_in),
+ m_period_separator(period_separator),
+ m_period_start_delimeter(period_start_delimeter),
+ m_open_range_end_delimeter(period_open_range_end_delimeter),
+ m_closed_range_end_delimeter(period_closed_range_end_delimeter)
+ {}
+
+ //! Puts the characters between period elements into stream -- default is /
+ OutItrT put_period_separator(OutItrT& oitr) const
+ {
+ const_itr_type ci = m_period_separator.begin();
+ while (ci != m_period_separator.end()) {
+ *oitr = *ci;
+ ci++;
+ }
+ return oitr;
+ }
+
+ //! Puts the period start characters into stream -- default is [
+ OutItrT put_period_start_delimeter(OutItrT& oitr) const
+ {
+ const_itr_type ci = m_period_start_delimeter.begin();
+ while (ci != m_period_start_delimeter.end()) {
+ *oitr = *ci;
+ ci++;
+ }
+ return oitr;
+ }
+
+ //! Puts the period end characters into stream as controled by open/closed range setting.
+ OutItrT put_period_end_delimeter(OutItrT& oitr) const
+ {
+
+ const_itr_type ci, end;
+ if (m_range_option == AS_OPEN_RANGE) {
+ ci = m_open_range_end_delimeter.begin();
+ end = m_open_range_end_delimeter.end();
+ }
+ else {
+ ci = m_closed_range_end_delimeter.begin();
+ end = m_closed_range_end_delimeter.end();
+ }
+ while (ci != end) {
+ *oitr = *ci;
+ ci++;
+ }
+ return oitr;
+ }
+
+ range_display_options range_option() const
+ {
+ return m_range_option;
+ }
+
+ //! Reset the range_option control
+ void
+ range_option(range_display_options option) const
+ {
+ m_range_option = option;
+ }
+ void delimiter_strings(const string_type& separator,
+ const string_type& start_delim,
+ const string_type& open_end_delim,
+ const string_type& closed_end_delim)
+ {
+ m_period_separator;
+ m_period_start_delimeter;
+ m_open_range_end_delimeter;
+ m_closed_range_end_delimeter;
+ }
+
+
+ //! Generic code to output a period -- no matter the period type.
+ /*! This generic code will output any period using a facet to
+ * to output the 'elements'. For example, in the case of a date_period
+ * the elements will be instances of a date which will be formatted
+ * according the to setup in the passed facet parameter.
+ *
+ * The steps for formatting a period are always the same:
+ * - put the start delimiter
+ * - put start element
+ * - put the separator
+ * - put either last or end element depending on range settings
+ * - put end delimeter depending on range settings
+ *
+ * Thus for a typical date period the result might look like this:
+ *@code
+ *
+ * [March 01, 2004/June 07, 2004] <-- closed range
+ * [March 01, 2004/June 08, 2004) <-- open range
+ *
+ *@endcode
+ */
+ template<class period_type, class facet_type>
+ OutItrT put_period(OutItrT next,
+ std::ios_base& a_ios,
+ char_type a_fill,
+ const period_type& p,
+ const facet_type& facet) const {
+ put_period_start_delimeter(next);
+ next = facet.put(next, a_ios, a_fill, p.begin());
+ put_period_separator(next);
+ if (m_range_option == AS_CLOSED_RANGE) {
+ facet.put(next, a_ios, a_fill, p.last());
+ }
+ else {
+ facet.put(next, a_ios, a_fill, p.end());
+ }
+ put_period_end_delimeter(next);
+ return next;
+ }
+
+
+ private:
+ range_display_options m_range_option;
+ string_type m_period_separator;
+ string_type m_period_start_delimeter;
+ string_type m_open_range_end_delimeter;
+ string_type m_closed_range_end_delimeter;
+ };
+
+ template <class CharT, class OutItrT>
+ const typename period_formatter<CharT, OutItrT>::char_type
+ period_formatter<CharT, OutItrT>::default_period_separator[2] = {'/'};
+
+ template <class CharT, class OutItrT>
+ const typename period_formatter<CharT, OutItrT>::char_type
+ period_formatter<CharT, OutItrT>::default_period_start_delimeter[2] = {'['};
+
+ template <class CharT, class OutItrT>
+ const typename period_formatter<CharT, OutItrT>::char_type
+ period_formatter<CharT, OutItrT>::default_period_open_range_end_delimeter[2] = {')'};
+
+ template <class CharT, class OutItrT>
+ const typename period_formatter<CharT, OutItrT>::char_type
+ period_formatter<CharT, OutItrT>::default_period_closed_range_end_delimeter[2] = {']'};
+
+ } } //namespace boost::date_time
+
+#endif
diff --git a/ext/boost/date_time/period_parser.hpp b/ext/boost/date_time/period_parser.hpp
new file mode 100644
index 0000000000..9cd57e18c7
--- /dev/null
+++ b/ext/boost/date_time/period_parser.hpp
@@ -0,0 +1,198 @@
+
+#ifndef DATETIME_PERIOD_PARSER_HPP___
+#define DATETIME_PERIOD_PARSER_HPP___
+
+/* 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-11-13 15:10:23 -0500 (Thu, 13 Nov 2008) $
+ */
+
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/string_parse_tree.hpp>
+#include <boost/date_time/string_convert.hpp>
+
+
+namespace boost { namespace date_time {
+
+
+ //! Not a facet, but a class used to specify and control period parsing
+ /*! Provides settings for the following:
+ * - period_separator -- default '/'
+ * - period_open_start_delimeter -- default '['
+ * - period_open_range_end_delimeter -- default ')'
+ * - period_closed_range_end_delimeter -- default ']'
+ * - display_as_open_range, display_as_closed_range -- default closed_range
+ *
+ * For a typical date_period, the contents of the input stream would be
+ *@code
+ * [2004-Jan-04/2004-Feb-01]
+ *@endcode
+ * where the date format is controlled by the date facet
+ */
+ template<class date_type, typename CharT>
+ class period_parser {
+ public:
+ typedef std::basic_string<CharT> string_type;
+ typedef CharT char_type;
+ //typedef typename std::basic_string<char_type>::const_iterator const_itr_type;
+ typedef std::istreambuf_iterator<CharT> stream_itr_type;
+ typedef string_parse_tree<CharT> parse_tree_type;
+ typedef typename parse_tree_type::parse_match_result_type match_results;
+ typedef std::vector<std::basic_string<CharT> > collection_type;
+
+ static const char_type default_period_separator[2];
+ static const char_type default_period_start_delimeter[2];
+ static const char_type default_period_open_range_end_delimeter[2];
+ static const char_type default_period_closed_range_end_delimeter[2];
+
+ enum period_range_option { AS_OPEN_RANGE, AS_CLOSED_RANGE };
+
+ //! Constructor that sets up period parser options
+ period_parser(period_range_option range_opt = AS_CLOSED_RANGE,
+ const char_type* const period_separator = default_period_separator,
+ const char_type* const period_start_delimeter = default_period_start_delimeter,
+ const char_type* const period_open_range_end_delimeter = default_period_open_range_end_delimeter,
+ const char_type* const period_closed_range_end_delimeter = default_period_closed_range_end_delimeter)
+ : m_range_option(range_opt)
+ {
+ delimiters.push_back(string_type(period_separator));
+ delimiters.push_back(string_type(period_start_delimeter));
+ delimiters.push_back(string_type(period_open_range_end_delimeter));
+ delimiters.push_back(string_type(period_closed_range_end_delimeter));
+ }
+
+ period_parser(const period_parser<date_type,CharT>& p_parser)
+ {
+ this->delimiters = p_parser.delimiters;
+ this->m_range_option = p_parser.m_range_option;
+ }
+
+ period_range_option range_option() const
+ {
+ return m_range_option;
+ }
+ void range_option(period_range_option option)
+ {
+ m_range_option = option;
+ }
+ collection_type delimiter_strings() const
+ {
+ return delimiters;
+ }
+ void delimiter_strings(const string_type& separator,
+ const string_type& start_delim,
+ const string_type& open_end_delim,
+ const string_type& closed_end_delim)
+ {
+ delimiters.clear();
+ delimiters.push_back(separator);
+ delimiters.push_back(start_delim);
+ delimiters.push_back(open_end_delim);
+ delimiters.push_back(closed_end_delim);
+ }
+
+ //! Generic code to parse a period -- no matter the period type.
+ /*! This generic code will parse any period using a facet to
+ * to get the 'elements'. For example, in the case of a date_period
+ * the elements will be instances of a date which will be parsed
+ * according the to setup in the passed facet parameter.
+ *
+ * The steps for parsing a period are always the same:
+ * - consume the start delimiter
+ * - get start element
+ * - consume the separator
+ * - get either last or end element depending on range settings
+ * - consume the end delimeter depending on range settings
+ *
+ * Thus for a typical date period the contents of the input stream
+ * might look like this:
+ *@code
+ *
+ * [March 01, 2004/June 07, 2004] <-- closed range
+ * [March 01, 2004/June 08, 2004) <-- open range
+ *
+ *@endcode
+ */
+ template<class period_type, class duration_type, class facet_type>
+ period_type get_period(stream_itr_type& sitr,
+ stream_itr_type& stream_end,
+ std::ios_base& a_ios,
+ const period_type& /* p */,
+ const duration_type& dur_unit,
+ const facet_type& facet) const
+ {
+ // skip leading whitespace
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+ typedef typename period_type::point_type point_type;
+ point_type p1(not_a_date_time), p2(not_a_date_time);
+
+
+ consume_delim(sitr, stream_end, delimiters[START]); // start delim
+ facet.get(sitr, stream_end, a_ios, p1); // first point
+ consume_delim(sitr, stream_end, delimiters[SEPARATOR]); // separator
+ facet.get(sitr, stream_end, a_ios, p2); // second point
+
+ // period construction parameters are always open range [begin, end)
+ if (m_range_option == AS_CLOSED_RANGE) {
+ consume_delim(sitr, stream_end, delimiters[CLOSED_END]);// end delim
+ // add 1 duration unit to p2 to make range open
+ p2 += dur_unit;
+ }
+ else {
+ consume_delim(sitr, stream_end, delimiters[OPEN_END]); // end delim
+ }
+
+ return period_type(p1, p2);
+ }
+
+ private:
+ collection_type delimiters;
+ period_range_option m_range_option;
+
+ enum delim_ids { SEPARATOR, START, OPEN_END, CLOSED_END };
+
+ //! throws ios_base::failure if delimiter and parsed data do not match
+ void consume_delim(stream_itr_type& sitr,
+ stream_itr_type& stream_end,
+ const string_type& delim) const
+ {
+ /* string_parse_tree will not parse a string of punctuation characters
+ * without knowing exactly how many characters to process
+ * Ex [2000. Will not parse out the '[' string without knowing
+ * to process only one character. By using length of the delimiter
+ * string we can safely iterate past it. */
+ string_type s;
+ for(unsigned int i = 0; i < delim.length() && sitr != stream_end; ++i) {
+ s += *sitr;
+ ++sitr;
+ }
+ if(s != delim) {
+ boost::throw_exception(std::ios_base::failure("Parse failed. Expected '"
+ + convert_string_type<char_type,char>(delim) + "' but found '" + convert_string_type<char_type,char>(s) + "'"));
+ }
+ }
+ };
+
+ template <class date_type, class char_type>
+ const typename period_parser<date_type, char_type>::char_type
+ period_parser<date_type, char_type>::default_period_separator[2] = {'/'};
+
+ template <class date_type, class char_type>
+ const typename period_parser<date_type, char_type>::char_type
+ period_parser<date_type, char_type>::default_period_start_delimeter[2] = {'['};
+
+ template <class date_type, class char_type>
+ const typename period_parser<date_type, char_type>::char_type
+ period_parser<date_type, char_type>::default_period_open_range_end_delimeter[2] = {')'};
+
+ template <class date_type, class char_type>
+ const typename period_parser<date_type, char_type>::char_type
+ period_parser<date_type, char_type>::default_period_closed_range_end_delimeter[2] = {']'};
+
+ } } //namespace boost::date_time
+
+#endif // DATETIME_PERIOD_PARSER_HPP___
diff --git a/ext/boost/date_time/posix_time/conversion.hpp b/ext/boost/date_time/posix_time/conversion.hpp
new file mode 100644
index 0000000000..6d35f4fc56
--- /dev/null
+++ b/ext/boost/date_time/posix_time/conversion.hpp
@@ -0,0 +1,91 @@
+#ifndef POSIX_TIME_CONVERSION_HPP___
+#define POSIX_TIME_CONVERSION_HPP___
+
+/* 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: 2009-06-04 04:24:49 -0400 (Thu, 04 Jun 2009) $
+ */
+
+#include "boost/date_time/posix_time/ptime.hpp"
+#include "boost/date_time/posix_time/posix_time_duration.hpp"
+#include "boost/date_time/filetime_functions.hpp"
+#include "boost/date_time/c_time.hpp"
+#include "boost/date_time/gregorian/conversion.hpp"
+
+namespace boost {
+
+namespace posix_time {
+
+
+ //! Function that converts a time_t into a ptime.
+ inline
+ ptime from_time_t(std::time_t t)
+ {
+ ptime start(gregorian::date(1970,1,1));
+ return start + seconds(static_cast<long>(t));
+ }
+
+ //! Convert a time to a tm structure truncating any fractional seconds
+ inline
+ std::tm to_tm(const boost::posix_time::ptime& t) {
+ std::tm timetm = boost::gregorian::to_tm(t.date());
+ boost::posix_time::time_duration td = t.time_of_day();
+ timetm.tm_hour = td.hours();
+ timetm.tm_min = td.minutes();
+ timetm.tm_sec = td.seconds();
+ timetm.tm_isdst = -1; // -1 used when dst info is unknown
+ return timetm;
+ }
+ //! Convert a time_duration to a tm structure truncating any fractional seconds and zeroing fields for date components
+ inline
+ std::tm to_tm(const boost::posix_time::time_duration& td) {
+ std::tm timetm = {};
+ timetm.tm_hour = date_time::absolute_value(td.hours());
+ timetm.tm_min = date_time::absolute_value(td.minutes());
+ timetm.tm_sec = date_time::absolute_value(td.seconds());
+ timetm.tm_isdst = -1; // -1 used when dst info is unknown
+ return timetm;
+ }
+
+ //! Convert a tm struct to a ptime ignoring is_dst flag
+ inline
+ ptime ptime_from_tm(const std::tm& timetm) {
+ boost::gregorian::date d = boost::gregorian::date_from_tm(timetm);
+ return ptime(d, time_duration(timetm.tm_hour, timetm.tm_min, timetm.tm_sec));
+ }
+
+
+#if defined(BOOST_HAS_FTIME)
+
+ //! Function to create a time object from an initialized FILETIME struct.
+ /*! Function to create a time object from an initialized FILETIME struct.
+ * A FILETIME struct holds 100-nanosecond units (0.0000001). When
+ * built with microsecond resolution the FILETIME's sub second value
+ * will be truncated. Nanosecond resolution has no truncation.
+ *
+ * \note FILETIME is part of the Win32 API, so it is not portable to non-windows
+ * platforms.
+ *
+ * \note The function is templated on the FILETIME type, so that
+ * it can be used with both native FILETIME and the ad-hoc
+ * boost::date_time::winapi::file_time type.
+ */
+ template< typename TimeT, typename FileTimeT >
+ inline
+ TimeT from_ftime(const FileTimeT& ft)
+ {
+ return boost::date_time::time_from_ftime<TimeT>(ft);
+ }
+
+#endif // BOOST_HAS_FTIME
+
+} } //namespace boost::posix_time
+
+
+
+
+#endif
+
diff --git a/ext/boost/date_time/posix_time/date_duration_operators.hpp b/ext/boost/date_time/posix_time/date_duration_operators.hpp
new file mode 100644
index 0000000000..e6899ba0aa
--- /dev/null
+++ b/ext/boost/date_time/posix_time/date_duration_operators.hpp
@@ -0,0 +1,114 @@
+#ifndef DATE_DURATION_OPERATORS_HPP___
+#define DATE_DURATION_OPERATORS_HPP___
+
+/* Copyright (c) 2004 CrystalClear Software, Inc.
+ * 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) $
+ */
+
+#include "boost/date_time/gregorian/greg_duration_types.hpp"
+#include "boost/date_time/posix_time/ptime.hpp"
+
+namespace boost {
+namespace posix_time {
+
+ /*!@file date_duration_operators.hpp Operators for ptime and
+ * optional gregorian types. Operators use snap-to-end-of-month behavior.
+ * Further details on this behavior can be found in reference for
+ * date_time/date_duration_types.hpp and documentation for
+ * month and year iterators.
+ */
+
+
+ /*! Adds a months object and a ptime. Result will be same
+ * day-of-month as ptime unless original day was the last day of month.
+ * see date_time::months_duration for more details */
+ inline
+ ptime
+ operator+(const ptime& t, const boost::gregorian::months& m)
+ {
+ return t + m.get_offset(t.date());
+ }
+
+ /*! Adds a months object to a ptime. Result will be same
+ * day-of-month as ptime unless original day was the last day of month.
+ * see date_time::months_duration for more details */
+ inline
+ ptime
+ operator+=(ptime& t, const boost::gregorian::months& m)
+ {
+ // get_neg_offset returns a negative duration, so we add
+ return t += m.get_offset(t.date());
+ }
+
+ /*! Subtracts a months object and a ptime. Result will be same
+ * day-of-month as ptime unless original day was the last day of month.
+ * see date_time::months_duration for more details */
+ inline
+ ptime
+ operator-(const ptime& t, const boost::gregorian::months& m)
+ {
+ // get_neg_offset returns a negative duration, so we add
+ return t + m.get_neg_offset(t.date());
+ }
+
+ /*! Subtracts a months object from a ptime. Result will be same
+ * day-of-month as ptime unless original day was the last day of month.
+ * see date_time::months_duration for more details */
+ inline
+ ptime
+ operator-=(ptime& t, const boost::gregorian::months& m)
+ {
+ return t += m.get_neg_offset(t.date());
+ }
+
+ // ptime & years
+
+ /*! Adds a years object and a ptime. Result will be same
+ * month and day-of-month as ptime unless original day was the
+ * last day of month. see date_time::years_duration for more details */
+ inline
+ ptime
+ operator+(const ptime& t, const boost::gregorian::years& y)
+ {
+ return t + y.get_offset(t.date());
+ }
+
+ /*! Adds a years object to a ptime. Result will be same
+ * month and day-of-month as ptime unless original day was the
+ * last day of month. see date_time::years_duration for more details */
+ inline
+ ptime
+ operator+=(ptime& t, const boost::gregorian::years& y)
+ {
+ return t += y.get_offset(t.date());
+ }
+
+ /*! Subtracts a years object and a ptime. Result will be same
+ * month and day-of-month as ptime unless original day was the
+ * last day of month. see date_time::years_duration for more details */
+ inline
+ ptime
+ operator-(const ptime& t, const boost::gregorian::years& y)
+ {
+ // get_neg_offset returns a negative duration, so we add
+ return t + y.get_neg_offset(t.date());
+ }
+
+ /*! Subtracts a years object from a ptime. Result will be same
+ * month and day-of-month as ptime unless original day was the
+ * last day of month. see date_time::years_duration for more details */
+ inline
+ ptime
+ operator-=(ptime& t, const boost::gregorian::years& y)
+ {
+ // get_neg_offset returns a negative duration, so we add
+ return t += y.get_neg_offset(t.date());
+ }
+
+}} // namespaces
+
+#endif // DATE_DURATION_OPERATORS_HPP___
diff --git a/ext/boost/date_time/posix_time/posix_time.hpp b/ext/boost/date_time/posix_time/posix_time.hpp
new file mode 100644
index 0000000000..4e9294c426
--- /dev/null
+++ b/ext/boost/date_time/posix_time/posix_time.hpp
@@ -0,0 +1,39 @@
+#ifndef POSIX_TIME_HPP___
+#define POSIX_TIME_HPP___
+
+/* 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-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+/*!@file posix_time.hpp Global header file to get all of posix time types
+ */
+
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/posix_time/ptime.hpp"
+#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
+#include "boost/date_time/posix_time/date_duration_operators.hpp"
+#endif
+
+// output functions
+#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
+#include "boost/date_time/posix_time/time_formatters_limited.hpp"
+#else
+#include "boost/date_time/posix_time/time_formatters.hpp"
+#endif // BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS
+
+// streaming operators
+#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+#include "boost/date_time/posix_time/posix_time_legacy_io.hpp"
+#else
+#include "boost/date_time/posix_time/posix_time_io.hpp"
+#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
+
+#include "boost/date_time/posix_time/time_parsers.hpp"
+#include "boost/date_time/posix_time/conversion.hpp"
+
+
+#endif
+
diff --git a/ext/boost/date_time/posix_time/posix_time_config.hpp b/ext/boost/date_time/posix_time/posix_time_config.hpp
new file mode 100644
index 0000000000..60c3f7ee37
--- /dev/null
+++ b/ext/boost/date_time/posix_time/posix_time_config.hpp
@@ -0,0 +1,178 @@
+#ifndef POSIX_TIME_CONFIG_HPP___
+#define POSIX_TIME_CONFIG_HPP___
+
+/* Copyright (c) 2002,2003,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: 2009-06-04 07:52:28 -0400 (Thu, 04 Jun 2009) $
+ */
+
+#include <cstdlib> //for MCW 7.2 std::abs(long long)
+#include <boost/limits.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/date_time/time_duration.hpp>
+#include <boost/date_time/time_resolution_traits.hpp>
+#include <boost/date_time/gregorian/gregorian_types.hpp>
+#include <boost/date_time/wrapping_int.hpp>
+#include <boost/date_time/compiler_config.hpp>
+
+namespace boost {
+namespace posix_time {
+
+//Remove the following line if you want 64 bit millisecond resolution time
+//#define BOOST_GDTL_POSIX_TIME_STD_CONFIG
+
+#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
+ // set up conditional test compilations
+#define BOOST_DATE_TIME_HAS_MILLISECONDS
+#define BOOST_DATE_TIME_HAS_MICROSECONDS
+#define BOOST_DATE_TIME_HAS_NANOSECONDS
+ typedef date_time::time_resolution_traits<boost::date_time::time_resolution_traits_adapted64_impl, boost::date_time::nano,
+ 1000000000, 9 > time_res_traits;
+#else
+ // set up conditional test compilations
+#define BOOST_DATE_TIME_HAS_MILLISECONDS
+#define BOOST_DATE_TIME_HAS_MICROSECONDS
+#undef BOOST_DATE_TIME_HAS_NANOSECONDS
+ typedef date_time::time_resolution_traits<
+ boost::date_time::time_resolution_traits_adapted64_impl, boost::date_time::micro,
+ 1000000, 6 > time_res_traits;
+
+
+// #undef BOOST_DATE_TIME_HAS_MILLISECONDS
+// #undef BOOST_DATE_TIME_HAS_MICROSECONDS
+// #undef BOOST_DATE_TIME_HAS_NANOSECONDS
+// typedef date_time::time_resolution_traits<boost::int64_t, boost::date_time::tenth,
+// 10, 0 > time_res_traits;
+
+#endif
+
+
+ //! Base time duration type
+ /*! \ingroup time_basics
+ */
+ class time_duration :
+ public date_time::time_duration<time_duration, time_res_traits>
+ {
+ public:
+ typedef time_res_traits rep_type;
+ typedef time_res_traits::day_type day_type;
+ typedef time_res_traits::hour_type hour_type;
+ typedef time_res_traits::min_type min_type;
+ typedef time_res_traits::sec_type sec_type;
+ typedef time_res_traits::fractional_seconds_type fractional_seconds_type;
+ typedef time_res_traits::tick_type tick_type;
+ typedef time_res_traits::impl_type impl_type;
+ time_duration(hour_type hour,
+ min_type min,
+ sec_type sec,
+ fractional_seconds_type fs=0) :
+ date_time::time_duration<time_duration, time_res_traits>(hour,min,sec,fs)
+ {}
+ time_duration() :
+ date_time::time_duration<time_duration, time_res_traits>(0,0,0)
+ {}
+ //! Construct from special_values
+ time_duration(boost::date_time::special_values sv) :
+ date_time::time_duration<time_duration, time_res_traits>(sv)
+ {}
+ //Give duration access to ticks constructor -- hide from users
+ friend class date_time::time_duration<time_duration, time_res_traits>;
+ private:
+ explicit time_duration(impl_type tick_count) :
+ date_time::time_duration<time_duration, time_res_traits>(tick_count)
+ {}
+ };
+
+#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
+
+ //! Simple implementation for the time rep
+ struct simple_time_rep
+ {
+ typedef gregorian::date date_type;
+ typedef time_duration time_duration_type;
+ simple_time_rep(date_type d, time_duration_type tod) :
+ day(d),
+ time_of_day(tod)
+ {
+ // make sure we have sane values for date & time
+ if(!day.is_special() && !time_of_day.is_special()){
+ if(time_of_day >= time_duration_type(24,0,0)) {
+ while(time_of_day >= time_duration_type(24,0,0)) {
+ day += date_type::duration_type(1);
+ time_of_day -= time_duration_type(24,0,0);
+ }
+ }
+ else if(time_of_day.is_negative()) {
+ while(time_of_day.is_negative()) {
+ day -= date_type::duration_type(1);
+ time_of_day += time_duration_type(24,0,0);
+ }
+ }
+ }
+ }
+ date_type day;
+ time_duration_type time_of_day;
+ bool is_special()const
+ {
+ return(is_pos_infinity() || is_neg_infinity() || is_not_a_date_time());
+ }
+ bool is_pos_infinity()const
+ {
+ return(day.is_pos_infinity() || time_of_day.is_pos_infinity());
+ }
+ bool is_neg_infinity()const
+ {
+ return(day.is_neg_infinity() || time_of_day.is_neg_infinity());
+ }
+ bool is_not_a_date_time()const
+ {
+ return(day.is_not_a_date() || time_of_day.is_not_a_date_time());
+ }
+ };
+
+ class posix_time_system_config
+ {
+ public:
+ typedef simple_time_rep time_rep_type;
+ typedef gregorian::date date_type;
+ typedef gregorian::date_duration date_duration_type;
+ typedef time_duration time_duration_type;
+ typedef time_res_traits::tick_type int_type;
+ typedef time_res_traits resolution_traits;
+#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers
+#else
+ BOOST_STATIC_CONSTANT(boost::int64_t, tick_per_second = 1000000000);
+#endif
+ };
+
+#else
+
+ class millisec_posix_time_system_config
+ {
+ public:
+ typedef boost::int64_t time_rep_type;
+ //typedef time_res_traits::tick_type time_rep_type;
+ typedef gregorian::date date_type;
+ typedef gregorian::date_duration date_duration_type;
+ typedef time_duration time_duration_type;
+ typedef time_res_traits::tick_type int_type;
+ typedef time_res_traits::impl_type impl_type;
+ typedef time_res_traits resolution_traits;
+#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers
+#else
+ BOOST_STATIC_CONSTANT(boost::int64_t, tick_per_second = 1000000);
+#endif
+ };
+
+#endif
+
+} }//namespace posix_time
+
+
+#endif
+
+
diff --git a/ext/boost/date_time/posix_time/posix_time_duration.hpp b/ext/boost/date_time/posix_time/posix_time_duration.hpp
new file mode 100644
index 0000000000..db3b85fec3
--- /dev/null
+++ b/ext/boost/date_time/posix_time/posix_time_duration.hpp
@@ -0,0 +1,82 @@
+#ifndef POSIX_TIME_DURATION_HPP___
+#define POSIX_TIME_DURATION_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/posix_time/posix_time_config.hpp"
+
+namespace boost {
+namespace posix_time {
+
+ //! Allows expression of durations as an hour count
+ /*! \ingroup time_basics
+ */
+ class hours : public time_duration
+ {
+ public:
+ explicit hours(long h) :
+ time_duration(h,0,0)
+ {}
+ };
+
+ //! Allows expression of durations as a minute count
+ /*! \ingroup time_basics
+ */
+ class minutes : public time_duration
+ {
+ public:
+ explicit minutes(long m) :
+ time_duration(0,m,0)
+ {}
+ };
+
+ //! Allows expression of durations as a seconds count
+ /*! \ingroup time_basics
+ */
+ class seconds : public time_duration
+ {
+ public:
+ explicit seconds(long s) :
+ time_duration(0,0,s)
+ {}
+ };
+
+
+ //! Allows expression of durations as milli seconds
+ /*! \ingroup time_basics
+ */
+ typedef date_time::subsecond_duration<time_duration,1000> millisec;
+ typedef date_time::subsecond_duration<time_duration,1000> milliseconds;
+
+ //! Allows expression of durations as micro seconds
+ /*! \ingroup time_basics
+ */
+ typedef date_time::subsecond_duration<time_duration,1000000> microsec;
+ typedef date_time::subsecond_duration<time_duration,1000000> microseconds;
+
+ //This is probably not needed anymore...
+#if defined(BOOST_DATE_TIME_HAS_NANOSECONDS)
+
+ //! Allows expression of durations as nano seconds
+ /*! \ingroup time_basics
+ */
+ typedef date_time::subsecond_duration<time_duration,1000000000> nanosec;
+ typedef date_time::subsecond_duration<time_duration,1000000000> nanoseconds;
+
+
+#endif
+
+
+
+
+} }//namespace posix_time
+
+
+#endif
+
diff --git a/ext/boost/date_time/posix_time/posix_time_io.hpp b/ext/boost/date_time/posix_time/posix_time_io.hpp
new file mode 100644
index 0000000000..9a80737a47
--- /dev/null
+++ b/ext/boost/date_time/posix_time/posix_time_io.hpp
@@ -0,0 +1,239 @@
+#ifndef DATE_TIME_POSIX_TIME_IO_HPP__
+#define DATE_TIME_POSIX_TIME_IO_HPP__
+
+/* Copyright (c) 2004-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-13 14:05:31 -0500 (Thu, 13 Nov 2008) $
+ */
+
+#include <locale>
+#include <iostream>
+#include <iterator> // i/ostreambuf_iterator
+#include <boost/io/ios_state.hpp>
+#include <boost/date_time/time_facet.hpp>
+#include <boost/date_time/period_formatter.hpp>
+#include <boost/date_time/posix_time/ptime.hpp>
+#include <boost/date_time/posix_time/time_period.hpp>
+#include <boost/date_time/posix_time/posix_time_duration.hpp>
+#include <boost/date_time/posix_time/conversion.hpp> // to_tm will be needed in the facets
+
+namespace boost {
+namespace posix_time {
+
+
+ //! wptime_facet is depricated and will be phased out. use wtime_facet instead
+ //typedef boost::date_time::time_facet<ptime, wchar_t> wptime_facet;
+ //! ptime_facet is depricated and will be phased out. use time_facet instead
+ //typedef boost::date_time::time_facet<ptime, char> ptime_facet;
+
+ //! wptime_input_facet is depricated and will be phased out. use wtime_input_facet instead
+ //typedef boost::date_time::time_input_facet<ptime,wchar_t> wptime_input_facet;
+ //! ptime_input_facet is depricated and will be phased out. use time_input_facet instead
+ //typedef boost::date_time::time_input_facet<ptime,char> ptime_input_facet;
+
+ typedef boost::date_time::time_facet<ptime, wchar_t> wtime_facet;
+ typedef boost::date_time::time_facet<ptime, char> time_facet;
+
+ typedef boost::date_time::time_input_facet<ptime, wchar_t> wtime_input_facet;
+ typedef boost::date_time::time_input_facet<ptime, char> time_input_facet;
+
+ template <class CharT, class TraitsT>
+ inline
+ std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os,
+ const ptime& p) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
+ typedef std::time_put<CharT> std_ptime_facet;
+ std::ostreambuf_iterator<CharT> oitr(os);
+ if (std::has_facet<custom_ptime_facet>(os.getloc()))
+ std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p);
+ else {
+ //instantiate a custom facet for dealing with times since the user
+ //has not put one in the stream so far. This is for efficiency
+ //since we would always need to reconstruct for every time period
+ //if the locale did not already exist. Of course this will be overridden
+ //if the user imbues as some later point.
+ custom_ptime_facet* f = new custom_ptime_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(oitr, os, os.fill(), p);
+ }
+ return os;
+ }
+
+ //! input operator for ptime
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, ptime& pt)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet;
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<time_input_facet>(is.getloc())) {
+ std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, pt);
+ }
+ else {
+ time_input_facet* f = new time_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, pt);
+ }
+ }
+ catch(...) {
+ // mask tells us what exceptions are turned on
+ std::ios_base::iostate exception_mask = is.exceptions();
+ // if the user wants exceptions on failbit, we'll rethrow our
+ // date_time exception & set the failbit
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {} // ignore this one
+ throw; // rethrow original exception
+ }
+ else {
+ // if the user want's to fail quietly, we simply set the failbit
+ is.setstate(std::ios_base::failbit);
+ }
+ }
+ }
+ return is;
+ }
+
+
+ template <class CharT, class TraitsT>
+ inline
+ std::basic_ostream<CharT, TraitsT>&
+ operator<<(std::basic_ostream<CharT, TraitsT>& os,
+ const boost::posix_time::time_period& p) {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
+ typedef std::time_put<CharT> std_time_facet;
+ std::ostreambuf_iterator<CharT> oitr(os);
+ if (std::has_facet<custom_ptime_facet>(os.getloc())) {
+ std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p);
+ }
+ else {
+ //instantiate a custom facet for dealing with periods since the user
+ //has not put one in the stream so far. This is for efficiency
+ //since we would always need to reconstruct for every time period
+ //if the local did not already exist. Of course this will be overridden
+ //if the user imbues as some later point.
+ custom_ptime_facet* f = new custom_ptime_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(oitr, os, os.fill(), p);
+ }
+ return os;
+ }
+
+ //! input operator for time_period
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, time_period& tp)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet;
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<time_input_facet>(is.getloc())) {
+ std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, tp);
+ }
+ else {
+ time_input_facet* f = new time_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, tp);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+ }
+ }
+ return is;
+ }
+
+
+ //! ostream operator for posix_time::time_duration
+ // todo fix to use facet -- place holder for now...
+ template <class CharT, class Traits>
+ inline
+ std::basic_ostream<CharT, Traits>&
+ operator<<(std::basic_ostream<CharT, Traits>& os, const time_duration& td)
+ {
+ boost::io::ios_flags_saver iflags(os);
+ typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
+ typedef std::time_put<CharT> std_ptime_facet;
+ std::ostreambuf_iterator<CharT> oitr(os);
+ if (std::has_facet<custom_ptime_facet>(os.getloc()))
+ std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), td);
+ else {
+ //instantiate a custom facet for dealing with times since the user
+ //has not put one in the stream so far. This is for efficiency
+ //since we would always need to reconstruct for every time period
+ //if the locale did not already exist. Of course this will be overridden
+ //if the user imbues as some later point.
+ custom_ptime_facet* f = new custom_ptime_facet();
+ std::locale l = std::locale(os.getloc(), f);
+ os.imbue(l);
+ f->put(oitr, os, os.fill(), td);
+ }
+ return os;
+ }
+
+ //! input operator for time_duration
+ template <class CharT, class Traits>
+ inline
+ std::basic_istream<CharT, Traits>&
+ operator>>(std::basic_istream<CharT, Traits>& is, time_duration& td)
+ {
+ boost::io::ios_flags_saver iflags(is);
+ typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+ if (strm_sentry) {
+ try {
+ typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet;
+ std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+ if(std::has_facet<time_input_facet>(is.getloc())) {
+ std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, td);
+ }
+ else {
+ time_input_facet* f = new time_input_facet();
+ std::locale l = std::locale(is.getloc(), f);
+ is.imbue(l);
+ f->get(sit, str_end, is, td);
+ }
+ }
+ catch(...) {
+ std::ios_base::iostate exception_mask = is.exceptions();
+ if(std::ios_base::failbit & exception_mask) {
+ try { is.setstate(std::ios_base::failbit); }
+ catch(std::ios_base::failure&) {}
+ throw; // rethrow original exception
+ }
+ else {
+ is.setstate(std::ios_base::failbit);
+ }
+ }
+ }
+ return is;
+ }
+
+} } // namespaces
+#endif // DATE_TIME_POSIX_TIME_IO_HPP__
diff --git a/ext/boost/date_time/posix_time/posix_time_legacy_io.hpp b/ext/boost/date_time/posix_time/posix_time_legacy_io.hpp
new file mode 100644
index 0000000000..f5b20a8f8b
--- /dev/null
+++ b/ext/boost/date_time/posix_time/posix_time_legacy_io.hpp
@@ -0,0 +1,153 @@
+#ifndef POSIX_TIME_PRE133_OPERATORS_HPP___
+#define POSIX_TIME_PRE133_OPERATORS_HPP___
+
+/* 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) $
+ */
+
+/*! @file posix_time_pre133_operators.hpp
+ * These input and output operators are for use with the
+ * pre 1.33 version of the date_time libraries io facet code.
+ * The operators used in version 1.33 and later can be found
+ * in posix_time_io.hpp */
+
+#include <iostream>
+#include <string>
+#include <sstream>
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/gregorian/gregorian.hpp"
+#include "boost/date_time/posix_time/posix_time_duration.hpp"
+#include "boost/date_time/posix_time/ptime.hpp"
+#include "boost/date_time/posix_time/time_period.hpp"
+#include "boost/date_time/time_parsing.hpp"
+
+namespace boost {
+namespace posix_time {
+
+
+//The following code is removed for configurations with poor std::locale support (eg: MSVC6, gcc 2.9x)
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+ //! ostream operator for posix_time::time_duration
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os, const time_duration& td)
+ {
+ typedef boost::date_time::ostream_time_duration_formatter<time_duration, charT> duration_formatter;
+ duration_formatter::duration_put(td, os);
+ return os;
+ }
+
+ //! ostream operator for posix_time::ptime
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os, const ptime& t)
+ {
+ typedef boost::date_time::ostream_time_formatter<ptime, charT> time_formatter;
+ time_formatter::time_put(t, os);
+ return os;
+ }
+
+ //! ostream operator for posix_time::time_period
+ template <class charT, class traits>
+ inline
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os, const time_period& tp)
+ {
+ typedef boost::date_time::ostream_time_period_formatter<time_period, charT> period_formatter;
+ period_formatter::period_put(tp, os);
+ return os;
+ }
+#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
+/******** input streaming ********/
+ template<class charT>
+ inline
+ std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, time_duration& td)
+ {
+ // need to create a std::string and parse it
+ std::basic_string<charT> inp_s;
+ std::stringstream out_ss;
+ is >> inp_s;
+ typename std::basic_string<charT>::iterator b = inp_s.begin();
+ // need to use both iterators because there is no requirement
+ // for the data held by a std::basic_string<> be terminated with
+ // any marker (such as '\0').
+ typename std::basic_string<charT>::iterator e = inp_s.end();
+ while(b != e){
+ out_ss << out_ss.narrow(*b, 0);
+ ++b;
+ }
+
+ td = date_time::parse_delimited_time_duration<time_duration>(out_ss.str());
+ return is;
+ }
+
+ template<class charT>
+ inline
+ std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, ptime& pt)
+ {
+ gregorian::date d(not_a_date_time);
+ time_duration td(0,0,0);
+ is >> d >> td;
+ pt = ptime(d, td);
+
+ return is;
+ }
+
+ /** operator>> for time_period. time_period must be in
+ * "[date time_duration/date time_duration]" format. */
+ template<class charT>
+ inline
+ std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, time_period& tp)
+ {
+ gregorian::date d(not_a_date_time);
+ time_duration td(0,0,0);
+ ptime beg(d, td);
+ ptime end(beg);
+ std::basic_string<charT> s;
+ // get first date string and remove leading '['
+ is >> s;
+ {
+ std::basic_stringstream<charT> ss;
+ ss << s.substr(s.find('[')+1);
+ ss >> d;
+ }
+ // get first time_duration & second date string, remove the '/'
+ // and split into 2 strings
+ is >> s;
+ {
+ std::basic_stringstream<charT> ss;
+ ss << s.substr(0, s.find('/'));
+ ss >> td;
+ }
+ beg = ptime(d, td);
+ {
+ std::basic_stringstream<charT> ss;
+ ss << s.substr(s.find('/')+1);
+ ss >> d;
+ }
+ // get last time_duration and remove the trailing ']'
+ is >> s;
+ {
+ std::basic_stringstream<charT> ss;
+ ss << s.substr(0, s.find(']'));
+ ss >> td;
+ }
+ end = ptime(d, td);
+
+ tp = time_period(beg,end);
+ return is;
+ }
+
+
+#endif //BOOST_DATE_TIME_NO_LOCALE
+
+} } // namespaces
+
+#endif // POSIX_TIME_PRE133_OPERATORS_HPP___
diff --git a/ext/boost/date_time/posix_time/posix_time_system.hpp b/ext/boost/date_time/posix_time/posix_time_system.hpp
new file mode 100644
index 0000000000..3d44e0ff00
--- /dev/null
+++ b/ext/boost/date_time/posix_time/posix_time_system.hpp
@@ -0,0 +1,68 @@
+#ifndef POSIX_TIME_SYSTEM_HPP___
+#define POSIX_TIME_SYSTEM_HPP___
+
+/* 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) $
+ */
+
+
+#include "boost/date_time/posix_time/posix_time_config.hpp"
+#include "boost/date_time/time_system_split.hpp"
+#include "boost/date_time/time_system_counted.hpp"
+#include "boost/date_time/compiler_config.hpp"
+
+
+namespace boost {
+namespace posix_time {
+
+#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
+
+#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers
+ typedef date_time::split_timedate_system<posix_time_system_config, 1000000000> posix_time_system;
+#else
+ typedef date_time::split_timedate_system<posix_time_system_config> posix_time_system;
+#endif
+
+#else
+
+ typedef date_time::counted_time_rep<millisec_posix_time_system_config> int64_time_rep;
+ typedef date_time::counted_time_system<int64_time_rep> posix_time_system;
+
+#endif
+
+} }//namespace posix_time
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ext/boost/date_time/posix_time/posix_time_types.hpp b/ext/boost/date_time/posix_time/posix_time_types.hpp
new file mode 100644
index 0000000000..f2488f8bed
--- /dev/null
+++ b/ext/boost/date_time/posix_time/posix_time_types.hpp
@@ -0,0 +1,55 @@
+/* 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
+ */
+#ifndef POSIX_TIME_TYPES_HPP___
+#define POSIX_TIME_TYPES_HPP___
+
+#include "boost/date_time/time_clock.hpp"
+#include "boost/date_time/microsec_time_clock.hpp"
+#include "boost/date_time/posix_time/ptime.hpp"
+#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
+#include "boost/date_time/posix_time/date_duration_operators.hpp"
+#endif
+#include "boost/date_time/posix_time/posix_time_duration.hpp"
+#include "boost/date_time/posix_time/posix_time_system.hpp"
+#include "boost/date_time/posix_time/time_period.hpp"
+#include "boost/date_time/time_iterator.hpp"
+#include "boost/date_time/dst_rules.hpp"
+
+namespace boost {
+
+//!Defines a non-adjusted time system with nano-second resolution and stable calculation properties
+namespace posix_time {
+
+ //! Iterator over a defined time duration
+ /*! \ingroup time_basics
+ */
+ typedef date_time::time_itr<ptime> time_iterator;
+ //! A time clock that has a resolution of one second
+ /*! \ingroup time_basics
+ */
+ typedef date_time::second_clock<ptime> second_clock;
+
+#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
+ //! A time clock that has a resolution of one microsecond
+ /*! \ingroup time_basics
+ */
+ typedef date_time::microsec_clock<ptime> microsec_clock;
+#endif
+
+ //! Define a dst null dst rule for the posix_time system
+ typedef date_time::null_dst_rules<ptime::date_type, time_duration> no_dst;
+ //! Define US dst rule calculator for the posix_time system
+ typedef date_time::us_dst_rules<ptime::date_type, time_duration> us_dst;
+
+
+} } //namespace posix_time
+
+
+
+
+#endif
+
diff --git a/ext/boost/date_time/posix_time/ptime.hpp b/ext/boost/date_time/posix_time/ptime.hpp
new file mode 100644
index 0000000000..2abc02d318
--- /dev/null
+++ b/ext/boost/date_time/posix_time/ptime.hpp
@@ -0,0 +1,65 @@
+#ifndef POSIX_PTIME_HPP___
+#define POSIX_PTIME_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/posix_time/posix_time_system.hpp"
+#include "boost/date_time/time.hpp"
+
+namespace boost {
+
+namespace posix_time {
+
+ //bring special enum values into the namespace
+ using date_time::special_values;
+ using date_time::not_special;
+ using date_time::neg_infin;
+ using date_time::pos_infin;
+ using date_time::not_a_date_time;
+ using date_time::max_date_time;
+ using date_time::min_date_time;
+
+ //! Time type with no timezone or other adjustments
+ /*! \ingroup time_basics
+ */
+ class ptime : public date_time::base_time<ptime, posix_time_system>
+ {
+ public:
+ typedef posix_time_system time_system_type;
+ typedef time_system_type::time_rep_type time_rep_type;
+ typedef time_system_type::time_duration_type time_duration_type;
+ typedef ptime time_type;
+ //! Construct with date and offset in day
+ ptime(gregorian::date d,time_duration_type td) : date_time::base_time<time_type,time_system_type>(d,td)
+ {}
+ //! Construct a time at start of the given day (midnight)
+ explicit ptime(gregorian::date d) : date_time::base_time<time_type,time_system_type>(d,time_duration_type(0,0,0))
+ {}
+ //! Copy from time_rep
+ ptime(const time_rep_type& rhs):
+ date_time::base_time<time_type,time_system_type>(rhs)
+ {}
+ //! Construct from special value
+ ptime(const special_values sv) : date_time::base_time<time_type,time_system_type>(sv)
+ {}
+#if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR)
+ // Default constructor constructs to not_a_date_time
+ ptime() : date_time::base_time<time_type,time_system_type>(gregorian::date(not_a_date_time), time_duration_type(not_a_date_time))
+ {}
+#endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR
+
+ };
+
+
+
+} }//namespace posix_time
+
+
+#endif
+
diff --git a/ext/boost/date_time/posix_time/time_formatters.hpp b/ext/boost/date_time/posix_time/time_formatters.hpp
new file mode 100644
index 0000000000..dc8facf57a
--- /dev/null
+++ b/ext/boost/date_time/posix_time/time_formatters.hpp
@@ -0,0 +1,289 @@
+#ifndef POSIXTIME_FORMATTERS_HPP___
+#define POSIXTIME_FORMATTERS_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/gregorian/gregorian.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/date_format_simple.hpp"
+#include "boost/date_time/posix_time/posix_time_types.hpp"
+#include "boost/date_time/time_formatting_streams.hpp"
+
+#include "boost/date_time/time_parsing.hpp"
+
+/* NOTE: The "to_*_string" code for older compilers, ones that define
+ * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in
+ * formatters_limited.hpp
+ */
+
+namespace boost {
+
+namespace posix_time {
+
+ // template function called by wrapper functions:
+ // to_*_string(time_duration) & to_*_wstring(time_duration)
+ template<class charT>
+ inline std::basic_string<charT> to_simple_string_type(time_duration td) {
+ std::basic_ostringstream<charT> ss;
+ if(td.is_special()) {
+ /* simply using 'ss << td.get_rep()' won't work on compilers
+ * that don't support locales. This way does. */
+ // switch copied from date_names_put.hpp
+ switch(td.get_rep().as_special())
+ {
+ case not_a_date_time:
+ //ss << "not-a-number";
+ ss << "not-a-date-time";
+ break;
+ case pos_infin:
+ ss << "+infinity";
+ break;
+ case neg_infin:
+ ss << "-infinity";
+ break;
+ default:
+ ss << "";
+ }
+ }
+ else {
+ charT fill_char = '0';
+ if(td.is_negative()) {
+ ss << '-';
+ }
+ ss << std::setw(2) << std::setfill(fill_char)
+ << date_time::absolute_value(td.hours()) << ":";
+ ss << std::setw(2) << std::setfill(fill_char)
+ << date_time::absolute_value(td.minutes()) << ":";
+ ss << std::setw(2) << std::setfill(fill_char)
+ << date_time::absolute_value(td.seconds());
+ //TODO the following is totally non-generic, yelling FIXME
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+ boost::int64_t frac_sec =
+ date_time::absolute_value(td.fractional_seconds());
+ // JDG [7/6/02 VC++ compatibility]
+ charT buff[32];
+ _i64toa(frac_sec, buff, 10);
+#else
+ time_duration::fractional_seconds_type frac_sec =
+ date_time::absolute_value(td.fractional_seconds());
+#endif
+ if (frac_sec != 0) {
+ ss << "." << std::setw(time_duration::num_fractional_digits())
+ << std::setfill(fill_char)
+
+ // JDG [7/6/02 VC++ compatibility]
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+ << buff;
+#else
+ << frac_sec;
+#endif
+ }
+ }// else
+ return ss.str();
+ }
+ //! Time duration to string -hh::mm::ss.fffffff. Example: 10:09:03.0123456
+ /*!\ingroup time_format
+ */
+ inline std::string to_simple_string(time_duration td) {
+ return to_simple_string_type<char>(td);
+ }
+
+
+ // template function called by wrapper functions:
+ // to_*_string(time_duration) & to_*_wstring(time_duration)
+ template<class charT>
+ inline std::basic_string<charT> to_iso_string_type(time_duration td)
+ {
+ std::basic_ostringstream<charT> ss;
+ if(td.is_special()) {
+ /* simply using 'ss << td.get_rep()' won't work on compilers
+ * that don't support locales. This way does. */
+ // switch copied from date_names_put.hpp
+ switch(td.get_rep().as_special()) {
+ case not_a_date_time:
+ //ss << "not-a-number";
+ ss << "not-a-date-time";
+ break;
+ case pos_infin:
+ ss << "+infinity";
+ break;
+ case neg_infin:
+ ss << "-infinity";
+ break;
+ default:
+ ss << "";
+ }
+ }
+ else {
+ charT fill_char = '0';
+ if(td.is_negative()) {
+ ss << '-';
+ }
+ ss << std::setw(2) << std::setfill(fill_char)
+ << date_time::absolute_value(td.hours());
+ ss << std::setw(2) << std::setfill(fill_char)
+ << date_time::absolute_value(td.minutes());
+ ss << std::setw(2) << std::setfill(fill_char)
+ << date_time::absolute_value(td.seconds());
+ //TODO the following is totally non-generic, yelling FIXME
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+ boost::int64_t frac_sec =
+ date_time::absolute_value(td.fractional_seconds());
+ // JDG [7/6/02 VC++ compatibility]
+ charT buff[32];
+ _i64toa(frac_sec, buff, 10);
+#else
+ time_duration::fractional_seconds_type frac_sec =
+ date_time::absolute_value(td.fractional_seconds());
+#endif
+ if (frac_sec != 0) {
+ ss << "." << std::setw(time_duration::num_fractional_digits())
+ << std::setfill(fill_char)
+
+ // JDG [7/6/02 VC++ compatibility]
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+ << buff;
+#else
+ << frac_sec;
+#endif
+ }
+ }// else
+ return ss.str();
+ }
+ //! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456
+ /*!\ingroup time_format
+ */
+ inline std::string to_iso_string(time_duration td){
+ return to_iso_string_type<char>(td);
+ }
+
+ //! Time to simple format CCYY-mmm-dd hh:mm:ss.fffffff
+ /*!\ingroup time_format
+ */
+ template<class charT>
+ inline std::basic_string<charT> to_simple_string_type(ptime t)
+ {
+ // can't use this w/gcc295, no to_simple_string_type<>(td) available
+ std::basic_string<charT> ts = gregorian::to_simple_string_type<charT>(t.date());// + " ";
+ if(!t.time_of_day().is_special()) {
+ charT space = ' ';
+ return ts + space + to_simple_string_type<charT>(t.time_of_day());
+ }
+ else {
+ return ts;
+ }
+ }
+ inline std::string to_simple_string(ptime t){
+ return to_simple_string_type<char>(t);
+ }
+
+ // function called by wrapper functions to_*_string(time_period)
+ // & to_*_wstring(time_period)
+ template<class charT>
+ inline std::basic_string<charT> to_simple_string_type(time_period tp)
+ {
+ charT beg = '[', mid = '/', end = ']';
+ std::basic_string<charT> d1(to_simple_string_type<charT>(tp.begin()));
+ std::basic_string<charT> d2(to_simple_string_type<charT>(tp.last()));
+ return std::basic_string<charT>(beg + d1 + mid + d2 + end);
+ }
+ //! Convert to string of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff]
+ /*!\ingroup time_format
+ */
+ inline std::string to_simple_string(time_period tp){
+ return to_simple_string_type<char>(tp);
+ }
+
+ // function called by wrapper functions to_*_string(time_period)
+ // & to_*_wstring(time_period)
+ template<class charT>
+ inline std::basic_string<charT> to_iso_string_type(ptime t)
+ {
+ std::basic_string<charT> ts = gregorian::to_iso_string_type<charT>(t.date());// + "T";
+ if(!t.time_of_day().is_special()) {
+ charT sep = 'T';
+ return ts + sep + to_iso_string_type<charT>(t.time_of_day());
+ }
+ else {
+ return ts;
+ }
+ }
+ //! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator
+ /*!\ingroup time_format
+ */
+ inline std::string to_iso_string(ptime t){
+ return to_iso_string_type<char>(t);
+ }
+
+
+ // function called by wrapper functions to_*_string(time_period)
+ // & to_*_wstring(time_period)
+ template<class charT>
+ inline std::basic_string<charT> to_iso_extended_string_type(ptime t)
+ {
+ std::basic_string<charT> ts = gregorian::to_iso_extended_string_type<charT>(t.date());// + "T";
+ if(!t.time_of_day().is_special()) {
+ charT sep = 'T';
+ return ts + sep + to_simple_string_type<charT>(t.time_of_day());
+ }
+ else {
+ return ts;
+ }
+ }
+ //! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator
+ /*!\ingroup time_format
+ */
+ inline std::string to_iso_extended_string(ptime t){
+ return to_iso_extended_string_type<char>(t);
+ }
+
+#if !defined(BOOST_NO_STD_WSTRING)
+ //! Time duration to wstring -hh::mm::ss.fffffff. Example: 10:09:03.0123456
+ /*!\ingroup time_format
+ */
+ inline std::wstring to_simple_wstring(time_duration td) {
+ return to_simple_string_type<wchar_t>(td);
+ }
+ //! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456
+ /*!\ingroup time_format
+ */
+ inline std::wstring to_iso_wstring(time_duration td){
+ return to_iso_string_type<wchar_t>(td);
+ }
+ inline std::wstring to_simple_wstring(ptime t){
+ return to_simple_string_type<wchar_t>(t);
+ }
+ //! Convert to wstring of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff]
+ /*!\ingroup time_format
+ */
+ inline std::wstring to_simple_wstring(time_period tp){
+ return to_simple_string_type<wchar_t>(tp);
+ }
+ //! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator
+ /*!\ingroup time_format
+ */
+ inline std::wstring to_iso_wstring(ptime t){
+ return to_iso_string_type<wchar_t>(t);
+ }
+ //! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator
+ /*!\ingroup time_format
+ */
+ inline std::wstring to_iso_extended_wstring(ptime t){
+ return to_iso_extended_string_type<wchar_t>(t);
+ }
+
+#endif // BOOST_NO_STD_WSTRING
+
+
+} } //namespace posix_time
+
+
+#endif
+
diff --git a/ext/boost/date_time/posix_time/time_formatters_limited.hpp b/ext/boost/date_time/posix_time/time_formatters_limited.hpp
new file mode 100644
index 0000000000..def51694a1
--- /dev/null
+++ b/ext/boost/date_time/posix_time/time_formatters_limited.hpp
@@ -0,0 +1,211 @@
+#ifndef POSIXTIME_FORMATTERS_LIMITED_HPP___
+#define POSIXTIME_FORMATTERS_LIMITED_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/gregorian/gregorian.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/date_format_simple.hpp"
+#include "boost/date_time/posix_time/posix_time_types.hpp"
+#include "boost/date_time/time_formatting_streams.hpp"
+
+namespace boost {
+
+namespace posix_time {
+
+ //! Time duration to string -hh::mm::ss.fffffff. Example: 10:09:03.0123456
+ /*!\ingroup time_format
+ */
+ inline std::string to_simple_string(time_duration td) {
+ std::ostringstream ss;
+ if(td.is_special()) {
+ /* simply using 'ss << td.get_rep()' won't work on compilers
+ * that don't support locales. This way does. */
+ // switch copied from date_names_put.hpp
+ switch(td.get_rep().as_special())
+ {
+ case not_a_date_time:
+ //ss << "not-a-number";
+ ss << "not-a-date-time";
+ break;
+ case pos_infin:
+ ss << "+infinity";
+ break;
+ case neg_infin:
+ ss << "-infinity";
+ break;
+ default:
+ ss << "";
+ }
+ }
+ else {
+ if(td.is_negative()) {
+ ss << '-';
+ }
+ ss << std::setw(2) << std::setfill('0')
+ << date_time::absolute_value(td.hours()) << ":";
+ ss << std::setw(2) << std::setfill('0')
+ << date_time::absolute_value(td.minutes()) << ":";
+ ss << std::setw(2) << std::setfill('0')
+ << date_time::absolute_value(td.seconds());
+ //TODO the following is totally non-generic, yelling FIXME
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+ boost::int64_t frac_sec =
+ date_time::absolute_value(td.fractional_seconds());
+ // JDG [7/6/02 VC++ compatibility]
+ char buff[32];
+ _i64toa(frac_sec, buff, 10);
+#else
+ time_duration::fractional_seconds_type frac_sec =
+ date_time::absolute_value(td.fractional_seconds());
+#endif
+ if (frac_sec != 0) {
+ ss << "." << std::setw(time_duration::num_fractional_digits())
+ << std::setfill('0')
+
+ // JDG [7/6/02 VC++ compatibility]
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+ << buff;
+#else
+ << frac_sec;
+#endif
+ }
+ }// else
+ return ss.str();
+ }
+
+ //! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456
+ /*!\ingroup time_format
+ */
+ inline
+ std::string
+ to_iso_string(time_duration td)
+ {
+ std::ostringstream ss;
+ if(td.is_special()) {
+ /* simply using 'ss << td.get_rep()' won't work on compilers
+ * that don't support locales. This way does. */
+ // switch copied from date_names_put.hpp
+ switch(td.get_rep().as_special()) {
+ case not_a_date_time:
+ //ss << "not-a-number";
+ ss << "not-a-date-time";
+ break;
+ case pos_infin:
+ ss << "+infinity";
+ break;
+ case neg_infin:
+ ss << "-infinity";
+ break;
+ default:
+ ss << "";
+ }
+ }
+ else {
+ if(td.is_negative()) {
+ ss << '-';
+ }
+ ss << std::setw(2) << std::setfill('0')
+ << date_time::absolute_value(td.hours());
+ ss << std::setw(2) << std::setfill('0')
+ << date_time::absolute_value(td.minutes());
+ ss << std::setw(2) << std::setfill('0')
+ << date_time::absolute_value(td.seconds());
+ //TODO the following is totally non-generic, yelling FIXME
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+ boost::int64_t frac_sec =
+ date_time::absolute_value(td.fractional_seconds());
+ // JDG [7/6/02 VC++ compatibility]
+ char buff[32];
+ _i64toa(frac_sec, buff, 10);
+#else
+ time_duration::fractional_seconds_type frac_sec =
+ date_time::absolute_value(td.fractional_seconds());
+#endif
+ if (frac_sec != 0) {
+ ss << "." << std::setw(time_duration::num_fractional_digits())
+ << std::setfill('0')
+
+ // JDG [7/6/02 VC++ compatibility]
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+ << buff;
+#else
+ << frac_sec;
+#endif
+ }
+ }// else
+ return ss.str();
+ }
+
+ //! Time to simple format CCYY-mmm-dd hh:mm:ss.fffffff
+ /*!\ingroup time_format
+ */
+ inline
+ std::string
+ to_simple_string(ptime t)
+ {
+ std::string ts = gregorian::to_simple_string(t.date());// + " ";
+ if(!t.time_of_day().is_special()) {
+ return ts + " " + to_simple_string(t.time_of_day());
+ }
+ else {
+ return ts;
+ }
+ }
+
+ //! Convert to string of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff]
+ /*!\ingroup time_format
+ */
+ inline
+ std::string
+ to_simple_string(time_period tp)
+ {
+ std::string d1(to_simple_string(tp.begin()));
+ std::string d2(to_simple_string(tp.last()));
+ return std::string("[" + d1 + "/" + d2 +"]");
+ }
+
+ //! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator
+ /*!\ingroup time_format
+ */
+ inline
+ std::string to_iso_string(ptime t)
+ {
+ std::string ts = gregorian::to_iso_string(t.date());// + "T";
+ if(!t.time_of_day().is_special()) {
+ return ts + "T" + to_iso_string(t.time_of_day());
+ }
+ else {
+ return ts;
+ }
+ }
+
+ //! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator
+ /*!\ingroup time_format
+ */
+ inline
+ std::string
+ to_iso_extended_string(ptime t)
+ {
+ std::string ts = gregorian::to_iso_extended_string(t.date());// + "T";
+ if(!t.time_of_day().is_special()) {
+ return ts + "T" + to_simple_string(t.time_of_day());
+ }
+ else {
+ return ts;
+ }
+ }
+
+
+} } //namespace posix_time
+
+
+#endif
+
diff --git a/ext/boost/date_time/posix_time/time_parsers.hpp b/ext/boost/date_time/posix_time/time_parsers.hpp
new file mode 100644
index 0000000000..8a352f6e2b
--- /dev/null
+++ b/ext/boost/date_time/posix_time/time_parsers.hpp
@@ -0,0 +1,44 @@
+#ifndef POSIXTIME_PARSERS_HPP___
+#define POSIXTIME_PARSERS_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/gregorian/gregorian.hpp"
+#include "boost/date_time/time_parsing.hpp"
+#include "boost/date_time/posix_time/posix_time_types.hpp"
+
+
+namespace boost {
+
+namespace posix_time {
+
+ //! Creates a time_duration object from a delimited string
+ /*! Expected format for string is "[-]h[h][:mm][:ss][.fff]".
+ * A negative duration will be created if the first character in
+ * string is a '-', all other '-' will be treated as delimiters.
+ * Accepted delimiters are "-:,.". */
+ inline time_duration duration_from_string(const std::string& s) {
+ return date_time::parse_delimited_time_duration<time_duration>(s);
+ }
+
+ inline ptime time_from_string(const std::string& s) {
+ return date_time::parse_delimited_time<ptime>(s, ' ');
+ }
+
+ inline ptime from_iso_string(const std::string& s) {
+ return date_time::parse_iso_time<ptime>(s, 'T');
+ }
+
+
+
+} } //namespace posix_time
+
+
+#endif
+
diff --git a/ext/boost/date_time/posix_time/time_period.hpp b/ext/boost/date_time/posix_time/time_period.hpp
new file mode 100644
index 0000000000..cb7bf07f47
--- /dev/null
+++ b/ext/boost/date_time/posix_time/time_period.hpp
@@ -0,0 +1,29 @@
+#ifndef POSIX_TIME_PERIOD_HPP___
+#define POSIX_TIME_PERIOD_HPP___
+
+/* 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) $
+ */
+
+#include "boost/date_time/period.hpp"
+#include "boost/date_time/posix_time/posix_time_duration.hpp"
+#include "boost/date_time/posix_time/ptime.hpp"
+
+namespace boost {
+namespace posix_time {
+
+ //! Time period type
+ /*! \ingroup time_basics
+ */
+ typedef date_time::period<ptime, time_duration> time_period;
+
+
+} }//namespace posix_time
+
+
+#endif
+
diff --git a/ext/boost/date_time/posix_time/time_serialize.hpp b/ext/boost/date_time/posix_time/time_serialize.hpp
new file mode 100644
index 0000000000..acadd57bb3
--- /dev/null
+++ b/ext/boost/date_time/posix_time/time_serialize.hpp
@@ -0,0 +1,200 @@
+#ifndef POSIX_TIME_SERIALIZE_HPP___
+#define POSIX_TIME_SERIALIZE_HPP___
+
+/* Copyright (c) 2004-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-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/posix_time/posix_time.hpp"
+#include "boost/date_time/gregorian/greg_serialize.hpp"
+#include "boost/serialization/split_free.hpp"
+
+
+// macros to split serialize functions into save & load functions
+// NOTE: these macros define template functions in the boost::serialization namespace.
+// They must be expanded *outside* of any namespace
+BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::ptime)
+BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::time_duration)
+BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::time_period)
+
+namespace boost {
+namespace serialization {
+
+
+/*** time_duration ***/
+
+//! Function to save posix_time::time_duration objects using serialization lib
+/*! time_duration objects are broken down into 4 parts for serialization:
+ * types are hour_type, min_type, sec_type, and fractional_seconds_type
+ * as defined in the time_duration class
+ */
+template<class Archive>
+void save(Archive & ar,
+ const posix_time::time_duration& td,
+ unsigned int /*version*/)
+{
+ // serialize a bool so we know how to read this back in later
+ bool is_special = td.is_special();
+ ar & make_nvp("is_special", is_special);
+ if(is_special) {
+ std::string s = to_simple_string(td);
+ ar & make_nvp("sv_time_duration", s);
+ }
+ else {
+ typename posix_time::time_duration::hour_type h = td.hours();
+ typename posix_time::time_duration::min_type m = td.minutes();
+ typename posix_time::time_duration::sec_type s = td.seconds();
+ typename posix_time::time_duration::fractional_seconds_type fs = td.fractional_seconds();
+ ar & make_nvp("time_duration_hours", h);
+ ar & make_nvp("time_duration_minutes", m);
+ ar & make_nvp("time_duration_seconds", s);
+ ar & make_nvp("time_duration_fractional_seconds", fs);
+ }
+}
+
+//! Function to load posix_time::time_duration objects using serialization lib
+/*! time_duration objects are broken down into 4 parts for serialization:
+ * types are hour_type, min_type, sec_type, and fractional_seconds_type
+ * as defined in the time_duration class
+ */
+template<class Archive>
+void load(Archive & ar,
+ posix_time::time_duration & td,
+ unsigned int /*version*/)
+{
+ bool is_special = false;
+ ar & make_nvp("is_special", is_special);
+ if(is_special) {
+ std::string s;
+ ar & make_nvp("sv_time_duration", s);
+ posix_time::special_values sv = gregorian::special_value_from_string(s);
+ td = posix_time::time_duration(sv);
+ }
+ else {
+ typename posix_time::time_duration::hour_type h(0);
+ typename posix_time::time_duration::min_type m(0);
+ typename posix_time::time_duration::sec_type s(0);
+ typename posix_time::time_duration::fractional_seconds_type fs(0);
+ ar & make_nvp("time_duration_hours", h);
+ ar & make_nvp("time_duration_minutes", m);
+ ar & make_nvp("time_duration_seconds", s);
+ ar & make_nvp("time_duration_fractional_seconds", fs);
+ td = posix_time::time_duration(h,m,s,fs);
+ }
+}
+
+// no load_construct_data function provided as time_duration provides a
+// default constructor
+
+/*** ptime ***/
+
+//! Function to save posix_time::ptime objects using serialization lib
+/*! ptime objects are broken down into 2 parts for serialization:
+ * a date object and a time_duration onject
+ */
+template<class Archive>
+void save(Archive & ar,
+ const posix_time::ptime& pt,
+ unsigned int /*version*/)
+{
+ // from_iso_string does not include fractional seconds
+ // therefore date and time_duration are used
+ typename posix_time::ptime::date_type d = pt.date();
+ ar & make_nvp("ptime_date", d);
+ if(!pt.is_special()) {
+ typename posix_time::ptime::time_duration_type td = pt.time_of_day();
+ ar & make_nvp("ptime_time_duration", td);
+ }
+}
+
+//! Function to load posix_time::ptime objects using serialization lib
+/*! ptime objects are broken down into 2 parts for serialization:
+ * a date object and a time_duration onject
+ */
+template<class Archive>
+void load(Archive & ar,
+ posix_time::ptime & pt,
+ unsigned int /*version*/)
+{
+ // from_iso_string does not include fractional seconds
+ // therefore date and time_duration are used
+ typename posix_time::ptime::date_type d(posix_time::not_a_date_time);
+ typename posix_time::ptime::time_duration_type td;
+ ar & make_nvp("ptime_date", d);
+ if(!d.is_special()) {
+ ar & make_nvp("ptime_time_duration", td);
+ pt = boost::posix_time::ptime(d,td);
+ }
+ else {
+ pt = boost::posix_time::ptime(d.as_special());
+ }
+
+}
+
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar,
+ posix_time::ptime* pt,
+ const unsigned int /*file_version*/)
+{
+ // retrieve data from archive required to construct new
+ // invoke inplace constructor to initialize instance of date
+ new(pt) boost::posix_time::ptime(boost::posix_time::not_a_date_time);
+}
+
+/*** time_period ***/
+
+//! Function to save posix_time::time_period objects using serialization lib
+/*! time_period objects are broken down into 2 parts for serialization:
+ * a begining ptime object and an ending ptime object
+ */
+template<class Archive>
+void save(Archive & ar,
+ const posix_time::time_period& tp,
+ unsigned int /*version*/)
+{
+ posix_time::ptime beg(tp.begin().date(), tp.begin().time_of_day());
+ posix_time::ptime end(tp.end().date(), tp.end().time_of_day());
+ ar & make_nvp("time_period_begin", beg);
+ ar & make_nvp("time_period_end", end);
+}
+
+//! Function to load posix_time::time_period objects using serialization lib
+/*! time_period objects are broken down into 2 parts for serialization:
+ * a begining ptime object and an ending ptime object
+ */
+template<class Archive>
+void load(Archive & ar,
+ boost::posix_time::time_period & tp,
+ unsigned int /*version*/)
+{
+ posix_time::time_duration td(1,0,0);
+ gregorian::date d(gregorian::not_a_date_time);
+ posix_time::ptime beg(d,td);
+ posix_time::ptime end(d,td);
+ ar & make_nvp("time_period_begin", beg);
+ ar & make_nvp("time_period_end", end);
+ tp = boost::posix_time::time_period(beg, end);
+}
+
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar,
+ boost::posix_time::time_period* tp,
+ const unsigned int /*file_version*/)
+{
+ posix_time::time_duration td(1,0,0);
+ gregorian::date d(gregorian::not_a_date_time);
+ posix_time::ptime beg(d,td);
+ posix_time::ptime end(d,td);
+ new(tp) boost::posix_time::time_period(beg,end);
+}
+
+} // namespace serialization
+} // namespace boost
+
+#endif
diff --git a/ext/boost/date_time/special_defs.hpp b/ext/boost/date_time/special_defs.hpp
new file mode 100644
index 0000000000..56eb6fea1d
--- /dev/null
+++ b/ext/boost/date_time/special_defs.hpp
@@ -0,0 +1,25 @@
+#ifndef DATE_TIME_SPECIAL_DEFS_HPP__
+#define DATE_TIME_SPECIAL_DEFS_HPP__
+
+/* 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) $
+ */
+
+namespace boost {
+namespace date_time {
+
+ enum special_values {not_a_date_time,
+ neg_infin, pos_infin,
+ min_date_time, max_date_time,
+ not_special, NumSpecialValues};
+
+
+} } //namespace date_time
+
+
+#endif
+
diff --git a/ext/boost/date_time/special_values_formatter.hpp b/ext/boost/date_time/special_values_formatter.hpp
new file mode 100644
index 0000000000..33542b6e42
--- /dev/null
+++ b/ext/boost/date_time/special_values_formatter.hpp
@@ -0,0 +1,96 @@
+
+#ifndef DATETIME_SPECIAL_VALUE_FORMATTER_HPP___
+#define DATETIME_SPECIAL_VALUE_FORMATTER_HPP___
+
+/* Copyright (c) 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) $
+ */
+
+#include <vector>
+#include <string>
+#include "boost/date_time/special_defs.hpp"
+
+namespace boost { namespace date_time {
+
+
+ //! Class that provides generic formmatting ostream formatting for special values
+ /*! This class provides for the formmating of special values to an output stream.
+ * In particular, it produces strings for the values of negative and positive
+ * infinity as well as not_a_date_time.
+ *
+ * While not a facet, this class is used by the date and time facets for formatting
+ * special value types.
+ *
+ */
+ template <class CharT, class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
+ class special_values_formatter
+ {
+ public:
+ typedef std::basic_string<CharT> string_type;
+ typedef CharT char_type;
+ typedef std::vector<string_type> collection_type;
+ static const char_type default_special_value_names[3][17];
+
+ //! Construct special values formatter using default strings.
+ /*! Default strings are not-a-date-time -infinity +infinity
+ */
+ special_values_formatter()
+ {
+ std::copy(&default_special_value_names[0],
+ &default_special_value_names[3],
+ std::back_inserter(m_special_value_names));
+ }
+
+ //! Construct special values formatter from array of strings
+ /*! This constructor will take pair of iterators from an array of strings
+ * that represent the special values and copy them for use in formatting
+ * special values.
+ *@code
+ * const char* const special_value_names[]={"nadt","-inf","+inf" };
+ *
+ * special_value_formatter svf(&special_value_names[0], &special_value_names[3]);
+ *@endcode
+ */
+ special_values_formatter(const char_type* const* begin, const char_type* const* end)
+ {
+ std::copy(begin, end, std::back_inserter(m_special_value_names));
+ }
+ special_values_formatter(typename collection_type::iterator beg, typename collection_type::iterator end)
+ {
+ std::copy(beg, end, std::back_inserter(m_special_value_names));
+ }
+
+ OutItrT put_special(OutItrT next,
+ const boost::date_time::special_values& value) const
+ {
+
+ unsigned int index = value;
+ if (index < m_special_value_names.size()) {
+ std::copy(m_special_value_names[index].begin(),
+ m_special_value_names[index].end(),
+ next);
+ }
+ return next;
+ }
+ protected:
+ collection_type m_special_value_names;
+ };
+
+ //! Storage for the strings used to indicate special values
+ /* using c_strings to initialize these worked fine in testing, however,
+ * a project that compiled its objects separately, then linked in a separate
+ * step wound up with redefinition errors for the values in this array.
+ * Initializing individual characters eliminated this problem */
+ template <class CharT, class OutItrT>
+ const typename special_values_formatter<CharT, OutItrT>::char_type special_values_formatter<CharT, OutItrT>::default_special_value_names[3][17] = {
+ {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'},
+ {'-','i','n','f','i','n','i','t','y'},
+ {'+','i','n','f','i','n','i','t','y'} };
+
+ } } //namespace boost::date_time
+
+#endif
diff --git a/ext/boost/date_time/special_values_parser.hpp b/ext/boost/date_time/special_values_parser.hpp
new file mode 100644
index 0000000000..e48ec5fda9
--- /dev/null
+++ b/ext/boost/date_time/special_values_parser.hpp
@@ -0,0 +1,159 @@
+
+#ifndef DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
+#define DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
+
+/* Copyright (c) 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:
+ */
+
+
+#include "boost/date_time/string_parse_tree.hpp"
+#include "boost/date_time/special_defs.hpp"
+#include <string>
+#include <vector>
+
+namespace boost { namespace date_time {
+
+ //! Class for special_value parsing
+ /*!
+ * TODO: add doc-comments for which elements can be changed
+ * Parses input stream for strings representing special_values.
+ * Special values parsed are:
+ * - not_a_date_time
+ * - neg_infin
+ * - pod_infin
+ * - min_date_time
+ * - max_date_time
+ */
+ template<class date_type, typename charT>
+ class special_values_parser
+ {
+ public:
+ typedef std::basic_string<charT> string_type;
+ //typedef std::basic_stringstream<charT> stringstream_type;
+ typedef std::istreambuf_iterator<charT> stream_itr_type;
+ //typedef typename string_type::const_iterator const_itr;
+ //typedef typename date_type::year_type year_type;
+ //typedef typename date_type::month_type month_type;
+ typedef typename date_type::duration_type duration_type;
+ //typedef typename date_type::day_of_week_type day_of_week_type;
+ //typedef typename date_type::day_type day_type;
+ typedef string_parse_tree<charT> parse_tree_type;
+ typedef typename parse_tree_type::parse_match_result_type match_results;
+ typedef std::vector<std::basic_string<charT> > collection_type;
+
+ typedef charT char_type;
+ static const char_type nadt_string[16];
+ static const char_type neg_inf_string[10];
+ static const char_type pos_inf_string[10];
+ static const char_type min_date_time_string[18];
+ static const char_type max_date_time_string[18];
+
+ //! Creates a special_values_parser with the default set of "sv_strings"
+ special_values_parser()
+ {
+ sv_strings(string_type(nadt_string),
+ string_type(neg_inf_string),
+ string_type(pos_inf_string),
+ string_type(min_date_time_string),
+ string_type(max_date_time_string));
+ }
+
+ //! Creates a special_values_parser using a user defined set of element strings
+ special_values_parser(const string_type& nadt_str,
+ const string_type& neg_inf_str,
+ const string_type& pos_inf_str,
+ const string_type& min_dt_str,
+ const string_type& max_dt_str)
+ {
+ sv_strings(nadt_str, neg_inf_str, pos_inf_str, min_dt_str, max_dt_str);
+ }
+
+ special_values_parser(typename collection_type::iterator beg, typename collection_type::iterator end)
+ {
+ collection_type phrases;
+ std::copy(beg, end, std::back_inserter(phrases));
+ m_sv_strings = parse_tree_type(phrases, static_cast<int>(not_a_date_time));
+ }
+
+ special_values_parser(const special_values_parser<date_type,charT>& svp)
+ {
+ this->m_sv_strings = svp.m_sv_strings;
+ }
+
+ //! Replace special value strings
+ void sv_strings(const string_type& nadt_str,
+ const string_type& neg_inf_str,
+ const string_type& pos_inf_str,
+ const string_type& min_dt_str,
+ const string_type& max_dt_str)
+ {
+ collection_type phrases;
+ phrases.push_back(nadt_str);
+ phrases.push_back(neg_inf_str);
+ phrases.push_back(pos_inf_str);
+ phrases.push_back(min_dt_str);
+ phrases.push_back(max_dt_str);
+ m_sv_strings = parse_tree_type(phrases, static_cast<int>(not_a_date_time));
+ }
+
+ /* Does not return a special_value because if the parsing fails,
+ * the return value will always be not_a_date_time
+ * (mr.current_match retains its default value of -1 on a failed
+ * parse and that casts to not_a_date_time). */
+ //! Sets match_results.current_match to the corresponding special_value or -1
+ bool match(stream_itr_type& sitr,
+ stream_itr_type& str_end,
+ match_results& mr) const
+ {
+ unsigned int level = 0;
+ m_sv_strings.match(sitr, str_end, mr, level);
+ return (mr.current_match != match_results::PARSE_ERROR);
+ }
+ /*special_values match(stream_itr_type& sitr,
+ stream_itr_type& str_end,
+ match_results& mr) const
+ {
+ unsigned int level = 0;
+ m_sv_strings.match(sitr, str_end, mr, level);
+ if(mr.current_match == match_results::PARSE_ERROR) {
+ throw std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'");
+ }
+ return static_cast<special_values>(mr.current_match);
+ }*/
+
+
+ private:
+ parse_tree_type m_sv_strings;
+
+ };
+
+ template<class date_type, class CharT>
+ const typename special_values_parser<date_type, CharT>::char_type
+ special_values_parser<date_type, CharT>::nadt_string[16] =
+ {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'};
+ template<class date_type, class CharT>
+ const typename special_values_parser<date_type, CharT>::char_type
+ special_values_parser<date_type, CharT>::neg_inf_string[10] =
+ {'-','i','n','f','i','n','i','t','y'};
+ template<class date_type, class CharT>
+ const typename special_values_parser<date_type, CharT>::char_type
+ special_values_parser<date_type, CharT>::pos_inf_string[10] =
+ {'+','i','n','f','i','n','i','t','y'};
+ template<class date_type, class CharT>
+ const typename special_values_parser<date_type, CharT>::char_type
+ special_values_parser<date_type, CharT>::min_date_time_string[18] =
+ {'m','i','n','i','m','u','m','-','d','a','t','e','-','t','i','m','e'};
+ template<class date_type, class CharT>
+ const typename special_values_parser<date_type, CharT>::char_type
+ special_values_parser<date_type, CharT>::max_date_time_string[18] =
+ {'m','a','x','i','m','u','m','-','d','a','t','e','-','t','i','m','e'};
+
+} } //namespace
+
+#endif // DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
+
diff --git a/ext/boost/date_time/string_convert.hpp b/ext/boost/date_time/string_convert.hpp
new file mode 100644
index 0000000000..54a979c70f
--- /dev/null
+++ b/ext/boost/date_time/string_convert.hpp
@@ -0,0 +1,33 @@
+#ifndef _STRING_CONVERT_HPP___
+#define _STRING_CONVERT_HPP___
+
+/* Copyright (c) 2005 CrystalClear Software, Inc.
+ * 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) $
+ */
+
+#include "boost/date_time/compiler_config.hpp"
+#include <string>
+
+namespace boost {
+namespace date_time {
+
+ //! Converts a string from one value_type to another
+ /*! Converts a wstring to a string (or a string to wstring). If both template parameters
+ * are of same type, a copy of the input string is returned. */
+ template<class InputT, class OutputT>
+ inline
+ std::basic_string<OutputT> convert_string_type(const std::basic_string<InputT>& inp_str)
+ {
+ typedef std::basic_string<InputT> input_type;
+ typedef std::basic_string<OutputT> output_type;
+ output_type result;
+ result.insert(result.begin(), inp_str.begin(), inp_str.end());
+ return result;
+ }
+
+}} // namespace boost::date_time
+
+#endif // _STRING_CONVERT_HPP___
diff --git a/ext/boost/date_time/string_parse_tree.hpp b/ext/boost/date_time/string_parse_tree.hpp
new file mode 100644
index 0000000000..0d515ff824
--- /dev/null
+++ b/ext/boost/date_time/string_parse_tree.hpp
@@ -0,0 +1,278 @@
+#ifndef BOOST_DATE_TIME_STRING_PARSE_TREE___HPP__
+#define BOOST_DATE_TIME_STRING_PARSE_TREE___HPP__
+
+/* Copyright (c) 2004-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-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+#include "boost/lexical_cast.hpp" //error without?
+#include "boost/algorithm/string/case_conv.hpp"
+#include <map>
+#include <string>
+#include <vector>
+#include <algorithm>
+
+namespace boost { namespace date_time {
+
+
+template<typename charT>
+struct parse_match_result
+{
+ parse_match_result() :
+ match_depth(0),
+ current_match(-1)// -1 is match_not-found value
+ {}
+ typedef std::basic_string<charT> string_type;
+ string_type remaining() const
+ {
+ if (match_depth == cache.size()) {
+ return string_type();
+ }
+ if (current_match == -1) {
+ return cache;
+ }
+ //some of the cache was used return the rest
+ return string_type(cache, match_depth);
+ }
+ charT last_char() const
+ {
+ return cache[cache.size()-1];
+ }
+ //! Returns true if more characters were parsed than was necessary
+ /*! Should be used in conjunction with last_char()
+ * to get the remaining character.
+ */
+ bool has_remaining() const
+ {
+ return (cache.size() > match_depth);
+ }
+
+ // cache will hold characters that have been read from the stream
+ string_type cache;
+ unsigned short match_depth;
+ short current_match;
+ enum PARSE_STATE { PARSE_ERROR= -1 };
+};
+
+ //for debug -- really only char streams...
+template<typename charT>
+std::basic_ostream<charT>&
+operator<<(std::basic_ostream<charT>& os, parse_match_result<charT>& mr)
+{
+ os << "cm: " << mr.current_match
+ << " C: '" << mr.cache
+ << "' md: " << mr.match_depth
+ << " R: " << mr.remaining();
+ return os;
+}
+
+
+
+//! Recursive data structure to allow efficient parsing of various strings
+/*! This class provides a quick lookup by building what amounts to a
+ * tree data structure. It also features a match function which can
+ * can handle nasty input interators by caching values as it recurses
+ * the tree so that it can backtrack as needed.
+ */
+template<typename charT>
+struct string_parse_tree
+{
+#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) )
+ typedef std::multimap<charT, string_parse_tree< charT> > ptree_coll;
+#else
+ typedef std::multimap<charT, string_parse_tree > ptree_coll;
+#endif
+ typedef typename ptree_coll::value_type value_type;
+ typedef typename ptree_coll::iterator iterator;
+ typedef typename ptree_coll::const_iterator const_iterator;
+ typedef std::basic_string<charT> string_type;
+ typedef std::vector<std::basic_string<charT> > collection_type;
+ typedef parse_match_result<charT> parse_match_result_type;
+
+ /*! Parameter "starting_point" designates where the numbering begins.
+ * A starting_point of zero will start the numbering at zero
+ * (Sun=0, Mon=1, ...) were a starting_point of one starts the
+ * numbering at one (Jan=1, Feb=2, ...). The default is zero,
+ * negative vaules are not allowed */
+ string_parse_tree(collection_type names, unsigned int starting_point=0)
+ {
+ // iterate thru all the elements and build the tree
+ unsigned short index = 0;
+ while (index != names.size() ) {
+ string_type s = boost::algorithm::to_lower_copy(names[index]);
+ insert(s, static_cast<unsigned short>(index + starting_point));
+ index++;
+ }
+ //set the last tree node = index+1 indicating a value
+ index++;
+ }
+
+
+ string_parse_tree(short value = -1) :
+ m_value(value)
+ {}
+ ptree_coll m_next_chars;
+ short m_value;
+
+ void insert(const string_type& s, unsigned short value)
+ {
+ unsigned int i = 0;
+ iterator ti;
+ while(i < s.size()) {
+ if (i==0) {
+ if (i == (s.size()-1)) {
+ ti = m_next_chars.insert(value_type(s[i],
+ string_parse_tree<charT>(value)));
+ }
+ else {
+ ti = m_next_chars.insert(value_type(s[i],
+ string_parse_tree<charT>()));
+ }
+ }
+ else {
+ if (i == (s.size()-1)) {
+ ti = ti->second.m_next_chars.insert(value_type(s[i],
+ string_parse_tree<charT>(value)));
+ }
+
+ else {
+ ti = ti->second.m_next_chars.insert(value_type(s[i],
+ string_parse_tree<charT>()));
+ }
+
+ }
+ i++;
+ }
+ }
+
+
+ //! Recursive function that finds a matching string in the tree.
+ /*! Must check match_results::has_remaining() after match() is
+ * called. This is required so the user can determine if
+ * stream iterator is already pointing to the expected
+ * character or not (match() might advance sitr to next char in stream).
+ *
+ * A parse_match_result that has been returned from a failed match
+ * attempt can be sent in to the match function of a different
+ * string_parse_tree to attempt a match there. Use the iterators
+ * for the partially consumed stream, the parse_match_result object,
+ * and '0' for the level parameter. */
+ short
+ match(std::istreambuf_iterator<charT>& sitr,
+ std::istreambuf_iterator<charT>& stream_end,
+ parse_match_result_type& result,
+ unsigned int& level) const
+ {
+
+ level++;
+ charT c;
+ // if we conditionally advance sitr, we won't have
+ // to consume the next character past the input
+ bool adv_itr = true;
+ if (level > result.cache.size()) {
+ if (sitr == stream_end) return 0; //bail - input exhausted
+ c = static_cast<charT>(std::tolower(*sitr));
+ //result.cache += c;
+ //sitr++;
+ }
+ else {
+ // if we're looking for characters from the cache,
+ // we don't want to increment sitr
+ adv_itr = false;
+ c = static_cast<charT>(std::tolower(result.cache[level-1]));
+ }
+ const_iterator litr = m_next_chars.lower_bound(c);
+ const_iterator uitr = m_next_chars.upper_bound(c);
+ while (litr != uitr) { // equal if not found
+ if(adv_itr) {
+ sitr++;
+ result.cache += c;
+ }
+ if (litr->second.m_value != -1) { // -1 is default value
+ if (result.match_depth < level) {
+ result.current_match = litr->second.m_value;
+ result.match_depth = static_cast<unsigned short>(level);
+ }
+ litr->second.match(sitr, stream_end,
+ result, level);
+ level--;
+ }
+ else {
+ litr->second.match(sitr, stream_end,
+ result, level);
+ level--;
+ }
+
+ if(level <= result.cache.size()) {
+ adv_itr = false;
+ }
+
+ litr++;
+ }
+ return result.current_match;
+
+ }
+
+ /*! Must check match_results::has_remaining() after match() is
+ * called. This is required so the user can determine if
+ * stream iterator is already pointing to the expected
+ * character or not (match() might advance sitr to next char in stream).
+ */
+ parse_match_result_type
+ match(std::istreambuf_iterator<charT>& sitr,
+ std::istreambuf_iterator<charT>& stream_end) const
+ {
+ // lookup to_lower of char in tree.
+ unsigned int level = 0;
+ // string_type cache;
+ parse_match_result_type result;
+ match(sitr, stream_end, result, level);
+ return result;
+ }
+
+ void printme(std::ostream& os, int& level)
+ {
+ level++;
+ iterator itr = m_next_chars.begin();
+ iterator end = m_next_chars.end();
+ // os << "starting level: " << level << std::endl;
+ while (itr != end) {
+ os << "level: " << level
+ << " node: " << itr->first
+ << " value: " << itr->second.m_value
+ << std::endl;
+ itr->second.printme(os, level);
+ itr++;
+ }
+ level--;
+ }
+
+ void print(std::ostream& os)
+ {
+ int level = 0;
+ printme(os, level);
+ }
+
+ void printmatch(std::ostream& os, charT c)
+ {
+ iterator litr = m_next_chars.lower_bound(c);
+ iterator uitr = m_next_chars.upper_bound(c);
+ os << "matches for: " << c << std::endl;
+ while (litr != uitr) {
+ os << " node: " << litr->first
+ << " value: " << litr->second.m_value
+ << std::endl;
+ litr++;
+ }
+ }
+
+};
+
+
+} } //namespace
+#endif
diff --git a/ext/boost/date_time/strings_from_facet.hpp b/ext/boost/date_time/strings_from_facet.hpp
new file mode 100644
index 0000000000..2bc26fb33e
--- /dev/null
+++ b/ext/boost/date_time/strings_from_facet.hpp
@@ -0,0 +1,125 @@
+#ifndef DATE_TIME_STRINGS_FROM_FACET__HPP___
+#define DATE_TIME_STRINGS_FROM_FACET__HPP___
+
+/* Copyright (c) 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: 2009-02-01 06:29:43 -0500 (Sun, 01 Feb 2009) $
+ */
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include <locale>
+
+namespace boost { namespace date_time {
+
+//! This function gathers up all the month strings from a std::locale
+/*! Using the time_put facet, this function creates a collection of
+ * all the month strings from a locale. This is handy when building
+ * custom date parsers or formatters that need to be localized.
+ *
+ *@param charT The type of char to use when gathering typically char
+ * or wchar_t.
+ *@param locale The locale to use when gathering the strings
+ *@param short_strings True(default) to gather short strings,
+ * false for long strings.
+ *@return A vector of strings containing the strings in order. eg:
+ * Jan, Feb, Mar, etc.
+ */
+template<typename charT>
+std::vector<std::basic_string<charT> >
+gather_month_strings(const std::locale& locale, bool short_strings=true)
+{
+ typedef std::basic_string<charT> string_type;
+ typedef std::vector<string_type> collection_type;
+ typedef std::basic_ostringstream<charT> ostream_type;
+ typedef std::ostreambuf_iterator<charT> ostream_iter_type;
+ typedef std::basic_ostringstream<charT> stringstream_type;
+ typedef std::time_put<charT> time_put_facet_type;
+ charT short_fmt[3] = { '%', 'b' };
+ charT long_fmt[3] = { '%', 'B' };
+ collection_type months;
+ string_type outfmt(short_fmt);
+ if (!short_strings) {
+ outfmt = long_fmt;
+ }
+ {
+ //grab the needed strings by using the locale to
+ //output each month
+ const charT* p_outfmt = outfmt.c_str(), *p_outfmt_end = p_outfmt + outfmt.size();
+ for (int m=0; m < 12; m++) {
+ tm tm_value;
+ tm_value.tm_mon = m;
+ stringstream_type ss;
+ ostream_iter_type oitr(ss);
+ std::use_facet<time_put_facet_type>(locale).put(oitr, ss, ss.fill(),
+ &tm_value,
+ p_outfmt,
+ p_outfmt_end);
+ months.push_back(ss.str());
+ }
+ }
+ return months;
+}
+
+//! This function gathers up all the weekday strings from a std::locale
+/*! Using the time_put facet, this function creates a collection of
+ * all the weekday strings from a locale starting with the string for
+ * 'Sunday'. This is handy when building custom date parsers or
+ * formatters that need to be localized.
+ *
+ *@param charT The type of char to use when gathering typically char
+ * or wchar_t.
+ *@param locale The locale to use when gathering the strings
+ *@param short_strings True(default) to gather short strings,
+ * false for long strings.
+ *@return A vector of strings containing the weekdays in order. eg:
+ * Sun, Mon, Tue, Wed, Thu, Fri, Sat
+ */
+template<typename charT>
+std::vector<std::basic_string<charT> >
+gather_weekday_strings(const std::locale& locale, bool short_strings=true)
+{
+ typedef std::basic_string<charT> string_type;
+ typedef std::vector<string_type> collection_type;
+ typedef std::basic_ostringstream<charT> ostream_type;
+ typedef std::ostreambuf_iterator<charT> ostream_iter_type;
+ typedef std::basic_ostringstream<charT> stringstream_type;
+ typedef std::time_put<charT> time_put_facet_type;
+ charT short_fmt[3] = { '%', 'a' };
+ charT long_fmt[3] = { '%', 'A' };
+
+ collection_type weekdays;
+
+
+ string_type outfmt(short_fmt);
+ if (!short_strings) {
+ outfmt = long_fmt;
+ }
+ {
+ //grab the needed strings by using the locale to
+ //output each month / weekday
+ const charT* p_outfmt = outfmt.c_str(), *p_outfmt_end = p_outfmt + outfmt.size();
+ for (int i=0; i < 7; i++) {
+ tm tm_value;
+ tm_value.tm_wday = i;
+ stringstream_type ss;
+ ostream_iter_type oitr(ss);
+ std::use_facet<time_put_facet_type>(locale).put(oitr, ss, ss.fill(),
+ &tm_value,
+ p_outfmt,
+ p_outfmt_end);
+
+ weekdays.push_back(ss.str());
+ }
+ }
+ return weekdays;
+}
+
+} } //namespace
+
+
+#endif
diff --git a/ext/boost/date_time/time.hpp b/ext/boost/date_time/time.hpp
new file mode 100644
index 0000000000..6a6cbe1f89
--- /dev/null
+++ b/ext/boost/date_time/time.hpp
@@ -0,0 +1,191 @@
+#ifndef DATE_TIME_TIME_HPP___
+#define DATE_TIME_TIME_HPP___
+
+/* Copyright (c) 2002,2003,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-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+/*! @file time.hpp
+ This file contains the interface for the time associated classes.
+*/
+#include <string>
+#include <boost/operators.hpp>
+#include <boost/date_time/time_defs.hpp>
+#include <boost/date_time/special_defs.hpp>
+
+namespace boost {
+namespace date_time {
+
+ //! Representation of a precise moment in time, including the date.
+ /*!
+ This class is a skeleton for the interface of a temporal type
+ with a resolution that is higher than a day. It is intended that
+ this class be the base class and that the actual time
+ class be derived using the BN pattern. In this way, the derived
+ class can make decisions such as 'should there be a default constructor'
+ and what should it set its value to, should there be optional constructors
+ say allowing only an time_durations that generate a time from a clock,etc.
+ So, in fact multiple time types can be created for a time_system with
+ different construction policies, and all of them can perform basic
+ operations by only writing a copy constructor. Finally, compiler
+ errors are also shorter.
+
+ The real behavior of the time class is provided by the time_system
+ template parameter. This class must provide all the logic
+ for addition, subtraction, as well as define all the interface
+ types.
+
+ */
+
+ template <class T, class time_system>
+ class base_time : private
+ boost::less_than_comparable<T
+ , boost::equality_comparable<T
+ > >
+ {
+ public:
+ typedef T time_type;
+ typedef typename time_system::time_rep_type time_rep_type;
+ typedef typename time_system::date_type date_type;
+ typedef typename time_system::date_duration_type date_duration_type;
+ typedef typename time_system::time_duration_type time_duration_type;
+ //typedef typename time_system::hms_type hms_type;
+
+ base_time(const date_type& day,
+ const time_duration_type& td,
+ dst_flags dst=not_dst) :
+ time_(time_system::get_time_rep(day, td, dst))
+ {}
+ base_time(special_values sv) :
+ time_(time_system::get_time_rep(sv))
+ {}
+ base_time(const time_rep_type& rhs) :
+ time_(rhs)
+ {}
+ date_type date() const
+ {
+ return time_system::get_date(time_);
+ }
+ time_duration_type time_of_day() const
+ {
+ return time_system::get_time_of_day(time_);
+ }
+ /*! Optional bool parameter will return time zone as an offset
+ * (ie "+07:00"). Empty string is returned for classes that do
+ * not use a time_zone */
+ std::string zone_name(bool /*as_offset*/=false) const
+ {
+ return time_system::zone_name(time_);
+ }
+ /*! Optional bool parameter will return time zone as an offset
+ * (ie "+07:00"). Empty string is returned for classes that do
+ * not use a time_zone */
+ std::string zone_abbrev(bool /*as_offset*/=false) const
+ {
+ return time_system::zone_name(time_);
+ }
+ //! An empty string is returned for classes that do not use a time_zone
+ std::string zone_as_posix_string() const
+ {
+ return std::string();
+ }
+
+ //! check to see if date is not a value
+ bool is_not_a_date_time() const
+ {
+ return time_.is_not_a_date_time();
+ }
+ //! check to see if date is one of the infinity values
+ bool is_infinity() const
+ {
+ return (is_pos_infinity() || is_neg_infinity());
+ }
+ //! check to see if date is greater than all possible dates
+ bool is_pos_infinity() const
+ {
+ return time_.is_pos_infinity();
+ }
+ //! check to see if date is greater than all possible dates
+ bool is_neg_infinity() const
+ {
+ return time_.is_neg_infinity();
+ }
+ //! check to see if time is a special value
+ bool is_special() const
+ {
+ return(is_not_a_date_time() || is_infinity());
+ }
+ //!Equality operator -- others generated by boost::equality_comparable
+ bool operator==(const time_type& rhs) const
+ {
+ return time_system::is_equal(time_,rhs.time_);
+ }
+ //!Equality operator -- others generated by boost::less_than_comparable
+ bool operator<(const time_type& rhs) const
+ {
+ return time_system::is_less(time_,rhs.time_);
+ }
+ //! difference between two times
+ time_duration_type operator-(const time_type& rhs) const
+ {
+ return time_system::subtract_times(time_, rhs.time_);
+ }
+ //! add date durations
+ time_type operator+(const date_duration_type& dd) const
+ {
+ return time_system::add_days(time_, dd);
+ }
+ time_type operator+=(const date_duration_type& dd)
+ {
+ time_ = (time_system::get_time_rep(date() + dd, time_of_day()));
+ return time_type(time_);
+ }
+ //! subtract date durations
+ time_type operator-(const date_duration_type& dd) const
+ {
+ return time_system::subtract_days(time_, dd);
+ }
+ time_type operator-=(const date_duration_type& dd)
+ {
+ time_ = (time_system::get_time_rep(date() - dd, time_of_day()));
+ return time_type(time_);
+ }
+ //! add time durations
+ time_type operator+(const time_duration_type& td) const
+ {
+ return time_type(time_system::add_time_duration(time_, td));
+ }
+ time_type operator+=(const time_duration_type& td)
+ {
+ time_ = (time_system::get_time_rep(date(), time_of_day() + td));
+ return time_type(time_);
+ }
+ //! subtract time durations
+ time_type operator-(const time_duration_type& rhs) const
+ {
+ return time_system::subtract_time_duration(time_, rhs);
+ }
+ time_type operator-=(const time_duration_type& td)
+ {
+ time_ = (time_system::get_time_rep(date(), time_of_day() - td));
+ return time_type(time_);
+ }
+
+ protected:
+ time_rep_type time_;
+ };
+
+
+
+
+
+} } //namespace date_time::boost
+
+
+#endif
+
diff --git a/ext/boost/date_time/time_clock.hpp b/ext/boost/date_time/time_clock.hpp
new file mode 100644
index 0000000000..1ea5d2e8bd
--- /dev/null
+++ b/ext/boost/date_time/time_clock.hpp
@@ -0,0 +1,83 @@
+#ifndef DATE_TIME_TIME_CLOCK_HPP___
+#define DATE_TIME_TIME_CLOCK_HPP___
+
+/* Copyright (c) 2002,2003,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-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+/*! @file time_clock.hpp
+ This file contains the interface for clock devices.
+*/
+
+#include "boost/date_time/c_time.hpp"
+#include "boost/shared_ptr.hpp"
+
+namespace boost {
+namespace date_time {
+
+
+ //! A clock providing time level services based on C time_t capabilities
+ /*! This clock provides resolution to the 1 second level
+ */
+ template<class time_type>
+ class second_clock
+ {
+ public:
+ typedef typename time_type::date_type date_type;
+ typedef typename time_type::time_duration_type time_duration_type;
+
+ static time_type local_time()
+ {
+ ::std::time_t t;
+ ::std::time(&t);
+ ::std::tm curr, *curr_ptr;
+ //curr_ptr = ::std::localtime(&t);
+ curr_ptr = c_time::localtime(&t, &curr);
+ return create_time(curr_ptr);
+ }
+
+
+ //! Get the current day in universal date as a ymd_type
+ static time_type universal_time()
+ {
+
+ ::std::time_t t;
+ ::std::time(&t);
+ ::std::tm curr, *curr_ptr;
+ //curr_ptr = ::std::gmtime(&t);
+ curr_ptr = c_time::gmtime(&t, &curr);
+ return create_time(curr_ptr);
+ }
+
+ template<class time_zone_type>
+ static time_type local_time(boost::shared_ptr<time_zone_type> tz_ptr)
+ {
+ typedef typename time_type::utc_time_type utc_time_type;
+ utc_time_type utc_time = second_clock<utc_time_type>::universal_time();
+ return time_type(utc_time, tz_ptr);
+ }
+
+
+ private:
+ static time_type create_time(::std::tm* current)
+ {
+ date_type d(static_cast<unsigned short>(current->tm_year + 1900),
+ static_cast<unsigned short>(current->tm_mon + 1),
+ static_cast<unsigned short>(current->tm_mday));
+ time_duration_type td(current->tm_hour,
+ current->tm_min,
+ current->tm_sec);
+ return time_type(d,td);
+ }
+
+ };
+
+
+} } //namespace date_time
+
+
+#endif
diff --git a/ext/boost/date_time/time_defs.hpp b/ext/boost/date_time/time_defs.hpp
new file mode 100644
index 0000000000..55fe42a594
--- /dev/null
+++ b/ext/boost/date_time/time_defs.hpp
@@ -0,0 +1,43 @@
+#ifndef DATE_TIME_TIME_PRECISION_LIMITS_HPP
+#define DATE_TIME_TIME_PRECISION_LIMITS_HPP
+
+/* 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-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+
+/*! \file time_defs.hpp
+ This file contains nice definitions for handling the resoluion of various time
+ reprsentations.
+*/
+
+namespace boost {
+namespace date_time {
+
+ //!Defines some nice types for handling time level resolutions
+ enum time_resolutions {
+ sec,
+ tenth,
+ hundreth, // deprecated misspelled version of hundredth
+ hundredth = hundreth,
+ milli,
+ ten_thousandth,
+ micro,
+ nano,
+ NumResolutions
+ };
+
+ //! Flags for daylight savings or summer time
+ enum dst_flags {not_dst, is_dst, calculate};
+
+
+} } //namespace date_time
+
+
+
+#endif
diff --git a/ext/boost/date_time/time_duration.hpp b/ext/boost/date_time/time_duration.hpp
new file mode 100644
index 0000000000..2fd259012e
--- /dev/null
+++ b/ext/boost/date_time/time_duration.hpp
@@ -0,0 +1,282 @@
+#ifndef DATE_TIME_TIME_DURATION_HPP___
+#define DATE_TIME_TIME_DURATION_HPP___
+
+/* 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: 2009-06-04 04:24:49 -0400 (Thu, 04 Jun 2009) $
+ */
+
+#include <boost/cstdint.hpp>
+#include <boost/operators.hpp>
+#include <boost/date_time/time_defs.hpp>
+#include <boost/date_time/special_defs.hpp>
+#include <boost/date_time/compiler_config.hpp>
+
+namespace boost {
+namespace date_time {
+
+
+ //! Represents some amount of elapsed time measure to a given resolution
+ /*! This class represents a standard set of capabilities for all
+ counted time durations. Time duration implementations should derive
+ from this class passing their type as the first template parameter.
+ This design allows the subclass duration types to provide custom
+ construction policies or other custom features not provided here.
+
+ @param T The subclass type
+ @param rep_type The time resolution traits for this duration type.
+ */
+ template<class T, typename rep_type>
+ class time_duration : private
+ boost::less_than_comparable<T
+ , boost::equality_comparable<T
+ > >
+ /* dividable, addable, and subtractable operator templates
+ * won't work with this class (MSVC++ 6.0). return type
+ * from '+=' is different than expected return type
+ * from '+'. multipliable probably wont work
+ * either (haven't tried) */
+ {
+ public:
+ typedef T duration_type; //the subclass
+ typedef rep_type traits_type;
+ typedef typename rep_type::day_type day_type;
+ typedef typename rep_type::hour_type hour_type;
+ typedef typename rep_type::min_type min_type;
+ typedef typename rep_type::sec_type sec_type;
+ typedef typename rep_type::fractional_seconds_type fractional_seconds_type;
+ typedef typename rep_type::tick_type tick_type;
+ typedef typename rep_type::impl_type impl_type;
+
+ time_duration() : ticks_(0) {}
+ time_duration(hour_type hours_in,
+ min_type minutes_in,
+ sec_type seconds_in=0,
+ fractional_seconds_type frac_sec_in = 0) :
+ ticks_(rep_type::to_tick_count(hours_in,minutes_in,seconds_in,frac_sec_in))
+ {}
+ // copy constructor required for dividable<>
+ //! Construct from another time_duration (Copy constructor)
+ time_duration(const time_duration<T, rep_type>& other)
+ : ticks_(other.ticks_)
+ {}
+ //! Construct from special_values
+ time_duration(special_values sv) : ticks_(impl_type::from_special(sv))
+ {}
+ //! Returns smallest representable duration
+ static duration_type unit()
+ {
+ return duration_type(0,0,0,1);
+ }
+ //! Return the number of ticks in a second
+ static tick_type ticks_per_second()
+ {
+ return rep_type::res_adjust();
+ }
+ //! Provide the resolution of this duration type
+ static time_resolutions resolution()
+ {
+ return rep_type::resolution();
+ }
+ //! Returns number of hours in the duration
+ hour_type hours() const
+ {
+ return static_cast<hour_type>(ticks() / (3600*ticks_per_second()));
+ }
+ //! Returns normalized number of minutes
+ min_type minutes() const
+ {
+ return static_cast<min_type>((ticks() / (60*ticks_per_second())) % 60);
+ }
+ //! Returns normalized number of seconds (0..60)
+ sec_type seconds() const
+ {
+ return static_cast<sec_type>((ticks()/ticks_per_second()) % 60);
+ }
+ //! Returns total number of seconds truncating any fractional seconds
+ sec_type total_seconds() const
+ {
+ return static_cast<sec_type>(ticks() / ticks_per_second());
+ }
+ //! Returns total number of milliseconds truncating any fractional seconds
+ tick_type total_milliseconds() const
+ {
+ if (ticks_per_second() < 1000) {
+ return ticks() * (static_cast<tick_type>(1000) / ticks_per_second());
+ }
+ return ticks() / (ticks_per_second() / static_cast<tick_type>(1000)) ;
+ }
+ //! Returns total number of nanoseconds truncating any sub millisecond values
+ tick_type total_nanoseconds() const
+ {
+ if (ticks_per_second() < 1000000000) {
+ return ticks() * (static_cast<tick_type>(1000000000) / ticks_per_second());
+ }
+ return ticks() / (ticks_per_second() / static_cast<tick_type>(1000000000)) ;
+ }
+ //! Returns total number of microseconds truncating any sub microsecond values
+ tick_type total_microseconds() const
+ {
+ if (ticks_per_second() < 1000000) {
+ return ticks() * (static_cast<tick_type>(1000000) / ticks_per_second());
+ }
+ return ticks() / (ticks_per_second() / static_cast<tick_type>(1000000)) ;
+ }
+ //! Returns count of fractional seconds at given resolution
+ fractional_seconds_type fractional_seconds() const
+ {
+ return (ticks() % ticks_per_second());
+ }
+ //! Returns number of possible digits in fractional seconds
+ static unsigned short num_fractional_digits()
+ {
+ return rep_type::num_fractional_digits();
+ }
+ duration_type invert_sign() const
+ {
+ return duration_type(ticks_ * (-1));
+ }
+ bool is_negative() const
+ {
+ return ticks_ < 0;
+ }
+ bool operator<(const time_duration& rhs) const
+ {
+ return ticks_ < rhs.ticks_;
+ }
+ bool operator==(const time_duration& rhs) const
+ {
+ return ticks_ == rhs.ticks_;
+ }
+ //! unary- Allows for time_duration td = -td1
+ duration_type operator-()const
+ {
+ return duration_type(ticks_ * (-1));
+ }
+ duration_type operator-(const duration_type& d) const
+ {
+ return duration_type(ticks_ - d.ticks_);
+ }
+ duration_type operator+(const duration_type& d) const
+ {
+ return duration_type(ticks_ + d.ticks_);
+ }
+ duration_type operator/(int divisor) const
+ {
+ return duration_type(ticks_ / divisor);
+ }
+ duration_type operator-=(const duration_type& d)
+ {
+ ticks_ = ticks_ - d.ticks_;
+ return duration_type(ticks_);
+ }
+ duration_type operator+=(const duration_type& d)
+ {
+ ticks_ = ticks_ + d.ticks_;
+ return duration_type(ticks_);
+ }
+ //! Division operations on a duration with an integer.
+ duration_type operator/=(int divisor)
+ {
+ ticks_ = ticks_ / divisor;
+ return duration_type(ticks_);
+ }
+ //! Multiplication operations an a duration with an integer
+ duration_type operator*(int rhs) const
+ {
+ return duration_type(ticks_ * rhs);
+ }
+ duration_type operator*=(int divisor)
+ {
+ ticks_ = ticks_ * divisor;
+ return duration_type(ticks_);
+ }
+ tick_type ticks() const
+ {
+ return traits_type::as_number(ticks_);
+ }
+
+ //! Is ticks_ a special value?
+ bool is_special()const
+ {
+ if(traits_type::is_adapted())
+ {
+ return ticks_.is_special();
+ }
+ else{
+ return false;
+ }
+ }
+ //! Is duration pos-infinity
+ bool is_pos_infinity()const
+ {
+ if(traits_type::is_adapted())
+ {
+ return ticks_.is_pos_infinity();
+ }
+ else{
+ return false;
+ }
+ }
+ //! Is duration neg-infinity
+ bool is_neg_infinity()const
+ {
+ if(traits_type::is_adapted())
+ {
+ return ticks_.is_neg_infinity();
+ }
+ else{
+ return false;
+ }
+ }
+ //! Is duration not-a-date-time
+ bool is_not_a_date_time()const
+ {
+ if(traits_type::is_adapted())
+ {
+ return ticks_.is_nan();
+ }
+ else{
+ return false;
+ }
+ }
+
+ //! Used for special_values output
+ impl_type get_rep()const
+ {
+ return ticks_;
+ }
+
+ protected:
+ explicit time_duration(impl_type in) : ticks_(in) {};
+ impl_type ticks_;
+ };
+
+
+
+ //! Template for instantiating derived adjusting durations
+ /* These templates are designed to work with multiples of
+ * 10 for frac_of_second and resoultion adjustment
+ */
+ template<class base_duration, boost::int64_t frac_of_second>
+ class subsecond_duration : public base_duration
+ {
+ public:
+ typedef typename base_duration::traits_type traits_type;
+ explicit subsecond_duration(boost::int64_t ss) :
+ base_duration(0,0,0,ss*traits_type::res_adjust()/frac_of_second)
+ {}
+ };
+
+
+
+} } //namespace date_time
+
+
+
+
+#endif
+
diff --git a/ext/boost/date_time/time_facet.hpp b/ext/boost/date_time/time_facet.hpp
new file mode 100644
index 0000000000..c1a2f8e863
--- /dev/null
+++ b/ext/boost/date_time/time_facet.hpp
@@ -0,0 +1,1327 @@
+
+#ifndef _DATE_TIME_FACET__HPP__
+#define _DATE_TIME_FACET__HPP__
+
+/* Copyright (c) 2004-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: Martin Andrian, Jeff Garland, Bart Garst
+ * $Date: 2008-11-23 06:13:35 -0500 (Sun, 23 Nov 2008) $
+ */
+
+#include <cctype>
+#include <locale>
+#include <limits>
+#include <string>
+#include <sstream>
+#include <iomanip>
+#include <iterator> // i/ostreambuf_iterator
+#include <exception>
+#include <boost/assert.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/algorithm/string/erase.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/date_facet.hpp>
+#include <boost/date_time/string_convert.hpp>
+#include <boost/date_time/special_defs.hpp>
+
+namespace boost {
+namespace date_time {
+
+ template <class CharT>
+ struct time_formats {
+ public:
+ typedef CharT char_type;
+ static const char_type fractional_seconds_format[3]; // f
+ static const char_type fractional_seconds_or_none_format[3]; // F
+ static const char_type seconds_with_fractional_seconds_format[3]; // s
+ static const char_type seconds_format[3]; // S
+ static const char_type hours_format[3]; // H
+ static const char_type unrestricted_hours_format[3]; // O
+ static const char_type standard_format[9]; // x X
+ static const char_type zone_abbrev_format[3]; // z
+ static const char_type zone_name_format[3]; // Z
+ static const char_type zone_iso_format[3]; // q
+ static const char_type zone_iso_extended_format[3]; // Q
+ static const char_type posix_zone_string_format[4]; // ZP
+ static const char_type duration_sign_negative_only[3]; // -
+ static const char_type duration_sign_always[3]; // +
+ static const char_type duration_seperator[2];
+ static const char_type negative_sign[2]; //-
+ static const char_type positive_sign[2]; //+
+ static const char_type iso_time_format_specifier[18];
+ static const char_type iso_time_format_extended_specifier[22];
+ //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz]
+ static const char_type default_time_format[23];
+ // default_time_input_format uses a posix_time_zone_string instead of a time zone abbrev
+ static const char_type default_time_input_format[24];
+ //default time_duration format is HH:MM:SS[.fff...]
+ static const char_type default_time_duration_format[11];
+ };
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::fractional_seconds_format[3] = {'%','f'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::fractional_seconds_or_none_format[3] = {'%','F'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::seconds_with_fractional_seconds_format[3] =
+ {'%','s'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::seconds_format[3] = {'%','S'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::hours_format[3] = {'%','H'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::unrestricted_hours_format[3] = {'%','O'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ //time_formats<CharT>::standard_format[5] = {'%','c',' ','%','z'};
+ time_formats<CharT>::standard_format[9] = {'%','x',' ','%','X',' ','%','z'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::zone_abbrev_format[3] = {'%','z'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::zone_name_format[3] = {'%','Z'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::zone_iso_format[3] = {'%','q'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::zone_iso_extended_format[3] ={'%','Q'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::posix_zone_string_format[4] ={'%','Z','P'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::duration_seperator[2] = {':'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::negative_sign[2] = {'-'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::positive_sign[2] = {'+'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::duration_sign_negative_only[3] ={'%','-'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::duration_sign_always[3] ={'%','+'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::iso_time_format_specifier[18] =
+ {'%', 'Y', '%', 'm', '%', 'd', 'T',
+ '%', 'H', '%', 'M', '%', 'S', '%', 'F', '%','q' };
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::iso_time_format_extended_specifier[22] =
+ {'%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ',
+ '%', 'H', ':', '%', 'M', ':', '%', 'S', '%', 'F','%','Q'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::default_time_format[23] =
+ {'%','Y','-','%','b','-','%','d',' ',
+ '%','H',':','%','M',':','%','S','%','F',' ','%','z'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::default_time_input_format[24] =
+ {'%','Y','-','%','b','-','%','d',' ',
+ '%','H',':','%','M',':','%','S','%','F',' ','%','Z','P'};
+
+ template <class CharT>
+ const typename time_formats<CharT>::char_type
+ time_formats<CharT>::default_time_duration_format[11] =
+ {'%','H',':','%','M',':','%','S','%','F'};
+
+
+
+ /*! Facet used for format-based output of time types
+ * This class provides for the use of format strings to output times. In addition
+ * to the flags for formatting date elements, the following are the allowed format flags:
+ * - %x %X => default format - enables addition of more flags to default (ie. "%x %X %z")
+ * - %f => fractional seconds ".123456"
+ * - %F => fractional seconds or none: like frac sec but empty if frac sec == 0
+ * - %s => seconds w/ fractional sec "02.123" (this is the same as "%S%f)
+ * - %S => seconds "02"
+ * - %z => abbreviated time zone "EDT"
+ * - %Z => full time zone name "Eastern Daylight Time"
+ */
+ template <class time_type,
+ class CharT,
+ class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
+ class time_facet :
+ public boost::date_time::date_facet<typename time_type::date_type , CharT, OutItrT> {
+ public:
+ typedef typename time_type::date_type date_type;
+ typedef typename time_type::time_duration_type time_duration_type;
+ typedef boost::date_time::period<time_type,time_duration_type> period_type;
+ typedef boost::date_time::date_facet<typename time_type::date_type, CharT, OutItrT> base_type;
+ typedef typename base_type::string_type string_type;
+ typedef typename base_type::char_type char_type;
+ typedef typename base_type::period_formatter_type period_formatter_type;
+ typedef typename base_type::special_values_formatter_type special_values_formatter_type;
+ typedef typename base_type::date_gen_formatter_type date_gen_formatter_type;
+ static const char_type* fractional_seconds_format; // %f
+ static const char_type* fractional_seconds_or_none_format; // %F
+ static const char_type* seconds_with_fractional_seconds_format; // %s
+ static const char_type* seconds_format; // %S
+ static const char_type* hours_format; // %H
+ static const char_type* unrestricted_hours_format; // %O
+ static const char_type* standard_format; // %x X
+ static const char_type* zone_abbrev_format; // %z
+ static const char_type* zone_name_format; // %Z
+ static const char_type* zone_iso_format; // %q
+ static const char_type* zone_iso_extended_format; // %Q
+ static const char_type* posix_zone_string_format; // %ZP
+ static const char_type* duration_seperator;
+ static const char_type* duration_sign_always; // %+
+ static const char_type* duration_sign_negative_only; // %-
+ static const char_type* negative_sign; //-
+ static const char_type* positive_sign; //+
+ static const char_type* iso_time_format_specifier;
+ static const char_type* iso_time_format_extended_specifier;
+
+ //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz]
+ static const char_type* default_time_format;
+ //default time_duration format is HH:MM:SS[.fff...]
+ static const char_type* default_time_duration_format;
+ static std::locale::id id;
+
+#if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
+ std::locale::id& __get_id (void) const { return id; }
+#endif
+
+ //! sets default formats for ptime, local_date_time, and time_duration
+ explicit time_facet(::size_t a_ref = 0)
+ : base_type(default_time_format, period_formatter_type(), special_values_formatter_type(), date_gen_formatter_type(), a_ref),
+ m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format)
+ {}
+
+ //! Construct the facet with an explicitly specified format
+ explicit time_facet(const char_type* a_format,
+ period_formatter_type period_formatter = period_formatter_type(),
+ const special_values_formatter_type& special_value_formatter = special_values_formatter_type(),
+ date_gen_formatter_type dg_formatter = date_gen_formatter_type(),
+ ::size_t a_ref = 0)
+ : base_type(a_format,
+ period_formatter,
+ special_value_formatter,
+ dg_formatter,
+ a_ref),
+ m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format)
+ {}
+
+ //! Changes format for time_duration
+ void time_duration_format(const char_type* const format)
+ {
+ m_time_duration_format = format;
+ }
+
+ virtual void set_iso_format()
+ {
+ this->m_format = iso_time_format_specifier;
+ }
+ virtual void set_iso_extended_format()
+ {
+ this->m_format = iso_time_format_extended_specifier;
+ }
+
+ OutItrT put(OutItrT a_next,
+ std::ios_base& a_ios,
+ char_type a_fill,
+ const time_type& a_time) const
+ {
+ if (a_time.is_special()) {
+ return this->do_put_special(a_next, a_ios, a_fill,
+ a_time.date().as_special());
+ }
+ string_type format(this->m_format);
+
+ string_type frac_str;
+ if (format.find(seconds_with_fractional_seconds_format) != string_type::npos) {
+ // replace %s with %S.nnn
+ frac_str =
+ fractional_seconds_as_string(a_time.time_of_day(), false);
+ char_type sep = std::use_facet<std::numpunct<char_type> >(a_ios.getloc()).decimal_point();
+
+ string_type replace_string(seconds_format);
+ replace_string += sep;
+ replace_string += frac_str;
+ boost::algorithm::replace_all(format,
+ seconds_with_fractional_seconds_format,
+ replace_string);
+ }
+ /* NOTE: replacing posix_zone_string_format must be done BEFORE
+ * zone_name_format: "%ZP" & "%Z", if Z is checked first it will
+ * incorrectly replace a zone_name where a posix_string should go */
+ if (format.find(posix_zone_string_format) != string_type::npos) {
+ if(a_time.zone_abbrev().empty()) {
+ // if zone_abbrev() returns an empty string, we want to
+ // erase posix_zone_string_format from format
+ boost::algorithm::erase_all(format, posix_zone_string_format);
+ }
+ else{
+ boost::algorithm::replace_all(format,
+ posix_zone_string_format,
+ a_time.zone_as_posix_string());
+ }
+ }
+ if (format.find(zone_name_format) != string_type::npos) {
+ if(a_time.zone_name().empty()) {
+ /* TODO: this'll probably create problems if a user places
+ * the zone_*_format flag in the format with a ptime. This
+ * code removes the flag from the default formats */
+
+ // if zone_name() returns an empty string, we want to
+ // erase zone_name_format & one preceeding space
+ std::basic_ostringstream<char_type> ss;
+ ss << ' ' << zone_name_format;
+ boost::algorithm::erase_all(format, ss.str());
+ }
+ else{
+ boost::algorithm::replace_all(format,
+ zone_name_format,
+ a_time.zone_name());
+ }
+ }
+ if (format.find(zone_abbrev_format) != string_type::npos) {
+ if(a_time.zone_abbrev(false).empty()) {
+ /* TODO: this'll probably create problems if a user places
+ * the zone_*_format flag in the format with a ptime. This
+ * code removes the flag from the default formats */
+
+ // if zone_abbrev() returns an empty string, we want to
+ // erase zone_abbrev_format & one preceeding space
+ std::basic_ostringstream<char_type> ss;
+ ss << ' ' << zone_abbrev_format;
+ boost::algorithm::erase_all(format, ss.str());
+ }
+ else{
+ boost::algorithm::replace_all(format,
+ zone_abbrev_format,
+ a_time.zone_abbrev(false));
+ }
+ }
+ if (format.find(zone_iso_extended_format) != string_type::npos) {
+ if(a_time.zone_name(true).empty()) {
+ /* TODO: this'll probably create problems if a user places
+ * the zone_*_format flag in the format with a ptime. This
+ * code removes the flag from the default formats */
+
+ // if zone_name() returns an empty string, we want to
+ // erase zone_iso_extended_format from format
+ boost::algorithm::erase_all(format, zone_iso_extended_format);
+ }
+ else{
+ boost::algorithm::replace_all(format,
+ zone_iso_extended_format,
+ a_time.zone_name(true));
+ }
+ }
+
+ if (format.find(zone_iso_format) != string_type::npos) {
+ if(a_time.zone_abbrev(true).empty()) {
+ /* TODO: this'll probably create problems if a user places
+ * the zone_*_format flag in the format with a ptime. This
+ * code removes the flag from the default formats */
+
+ // if zone_abbrev() returns an empty string, we want to
+ // erase zone_iso_format from format
+ boost::algorithm::erase_all(format, zone_iso_format);
+ }
+ else{
+ boost::algorithm::replace_all(format,
+ zone_iso_format,
+ a_time.zone_abbrev(true));
+ }
+ }
+ if (format.find(fractional_seconds_format) != string_type::npos) {
+ // replace %f with nnnnnnn
+ if (!frac_str.size()) {
+ frac_str = fractional_seconds_as_string(a_time.time_of_day(), false);
+ }
+ boost::algorithm::replace_all(format,
+ fractional_seconds_format,
+ frac_str);
+ }
+
+ if (format.find(fractional_seconds_or_none_format) != string_type::npos) {
+ // replace %F with nnnnnnn or nothing if fs == 0
+ frac_str =
+ fractional_seconds_as_string(a_time.time_of_day(), true);
+ if (frac_str.size()) {
+ char_type sep = std::use_facet<std::numpunct<char_type> >(a_ios.getloc()).decimal_point();
+ string_type replace_string;
+ replace_string += sep;
+ replace_string += frac_str;
+ boost::algorithm::replace_all(format,
+ fractional_seconds_or_none_format,
+ replace_string);
+ }
+ else {
+ boost::algorithm::erase_all(format,
+ fractional_seconds_or_none_format);
+ }
+ }
+
+ return this->do_put_tm(a_next, a_ios, a_fill,
+ to_tm(a_time), format);
+ }
+
+ //! put function for time_duration
+ OutItrT put(OutItrT a_next,
+ std::ios_base& a_ios,
+ char_type a_fill,
+ const time_duration_type& a_time_dur) const
+ {
+ if (a_time_dur.is_special()) {
+ return this->do_put_special(a_next, a_ios, a_fill,
+ a_time_dur.get_rep().as_special());
+ }
+
+ string_type format(m_time_duration_format);
+ if (a_time_dur.is_negative()) {
+ // replace %- with minus sign. Should we use the numpunct facet?
+ boost::algorithm::replace_all(format,
+ duration_sign_negative_only,
+ negative_sign);
+ // remove all the %+ in the string with '-'
+ boost::algorithm::replace_all(format,
+ duration_sign_always,
+ negative_sign);
+ }
+ else { //duration is positive
+ // remove all the %- combos from the string
+ boost::algorithm::erase_all(format, duration_sign_negative_only);
+ // remove all the %+ in the string with '+'
+ boost::algorithm::replace_all(format,
+ duration_sign_always,
+ positive_sign);
+ }
+
+ /*
+ * It is possible for a time duration to span more then 24 hours.
+ * Standard time_put::put is obliged to behave the same as strftime
+ * (See ISO 14882-2003 22.2.5.3.1 par. 1) and strftime's behavior is
+ * unspecified for the case when tm_hour field is outside 0-23 range
+ * (See ISO 9899-1999 7.23.3.5 par. 3). So we must output %H and %O
+ * here ourself.
+ */
+ string_type hours_str;
+ if (format.find(unrestricted_hours_format) != string_type::npos) {
+ hours_str = hours_as_string(a_time_dur);
+ boost::algorithm::replace_all(format, unrestricted_hours_format, hours_str);
+ }
+ // We still have to process restricted hours format specifier. In order to
+ // support parseability of durations in ISO format (%H%M%S), we'll have to
+ // restrict the stringified hours length to 2 characters.
+ if (format.find(hours_format) != string_type::npos) {
+ if (hours_str.empty())
+ hours_str = hours_as_string(a_time_dur);
+ BOOST_ASSERT(hours_str.length() <= 2);
+ boost::algorithm::replace_all(format, hours_format, hours_str);
+ }
+
+ string_type frac_str;
+ if (format.find(seconds_with_fractional_seconds_format) != string_type::npos) {
+ // replace %s with %S.nnn
+ frac_str =
+ fractional_seconds_as_string(a_time_dur, false);
+ char_type sep = std::use_facet<std::numpunct<char_type> >(a_ios.getloc()).decimal_point();
+
+ string_type replace_string(seconds_format);
+ replace_string += sep;
+ replace_string += frac_str;
+ boost::algorithm::replace_all(format,
+ seconds_with_fractional_seconds_format,
+ replace_string);
+ }
+ if (format.find(fractional_seconds_format) != string_type::npos) {
+ // replace %f with nnnnnnn
+ if (!frac_str.size()) {
+ frac_str = fractional_seconds_as_string(a_time_dur, false);
+ }
+ boost::algorithm::replace_all(format,
+ fractional_seconds_format,
+ frac_str);
+ }
+
+ if (format.find(fractional_seconds_or_none_format) != string_type::npos) {
+ // replace %F with nnnnnnn or nothing if fs == 0
+ frac_str =
+ fractional_seconds_as_string(a_time_dur, true);
+ if (frac_str.size()) {
+ char_type sep = std::use_facet<std::numpunct<char_type> >(a_ios.getloc()).decimal_point();
+ string_type replace_string;
+ replace_string += sep;
+ replace_string += frac_str;
+ boost::algorithm::replace_all(format,
+ fractional_seconds_or_none_format,
+ replace_string);
+ }
+ else {
+ boost::algorithm::erase_all(format,
+ fractional_seconds_or_none_format);
+ }
+ }
+
+ return this->do_put_tm(a_next, a_ios, a_fill,
+ to_tm(a_time_dur), format);
+ }
+
+ OutItrT put(OutItrT next, std::ios_base& a_ios,
+ char_type fill, const period_type& p) const
+ {
+ return this->m_period_formatter.put_period(next, a_ios, fill,p,*this);
+ }
+
+
+ protected:
+
+ static
+ string_type
+ fractional_seconds_as_string(const time_duration_type& a_time,
+ bool null_when_zero)
+ {
+ typename time_duration_type::fractional_seconds_type frac_sec =
+ a_time.fractional_seconds();
+
+ if (null_when_zero && (frac_sec == 0)) {
+ return string_type();
+ }
+
+ //make sure there is no sign
+ return integral_as_string(
+ date_time::absolute_value(frac_sec),
+ time_duration_type::num_fractional_digits());
+ }
+
+ static
+ string_type
+ hours_as_string(const time_duration_type& a_time, int width = 2)
+ {
+ return integral_as_string(date_time::absolute_value(a_time.hours()), width);
+ }
+
+ template< typename IntT >
+ static
+ string_type
+ integral_as_string(IntT val, int width = 2)
+ {
+ std::basic_ostringstream<char_type> ss;
+ ss.imbue(std::locale::classic()); // don't want any formatting
+ ss << std::setw(width)
+ << std::setfill(static_cast<char_type>('0'));
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+ // JDG [7/6/02 VC++ compatibility]
+ char_type buff[34];
+ ss << _i64toa(static_cast<boost::int64_t>(val), buff, 10);
+#else
+ ss << val;
+#endif
+ return ss.str();
+ }
+
+ private:
+ string_type m_time_duration_format;
+
+ };
+
+ template <class time_type, class CharT, class OutItrT>
+ std::locale::id time_facet<time_type, CharT, OutItrT>::id;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::fractional_seconds_format = time_formats<CharT>::fractional_seconds_format;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::fractional_seconds_or_none_format = time_formats<CharT>::fractional_seconds_or_none_format;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::seconds_with_fractional_seconds_format =
+ time_formats<CharT>::seconds_with_fractional_seconds_format;
+
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::zone_name_format = time_formats<CharT>::zone_name_format;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::zone_abbrev_format = time_formats<CharT>::zone_abbrev_format;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::zone_iso_extended_format =time_formats<CharT>::zone_iso_extended_format;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::posix_zone_string_format =time_formats<CharT>::posix_zone_string_format;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::zone_iso_format = time_formats<CharT>::zone_iso_format;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::seconds_format = time_formats<CharT>::seconds_format;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::hours_format = time_formats<CharT>::hours_format;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::unrestricted_hours_format = time_formats<CharT>::unrestricted_hours_format;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::standard_format = time_formats<CharT>::standard_format;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::duration_seperator = time_formats<CharT>::duration_seperator;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::negative_sign = time_formats<CharT>::negative_sign;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::positive_sign = time_formats<CharT>::positive_sign;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::duration_sign_negative_only = time_formats<CharT>::duration_sign_negative_only;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::duration_sign_always = time_formats<CharT>::duration_sign_always;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type,CharT, OutItrT>::char_type*
+ time_facet<time_type,CharT, OutItrT>::iso_time_format_specifier = time_formats<CharT>::iso_time_format_specifier;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::iso_time_format_extended_specifier = time_formats<CharT>::iso_time_format_extended_specifier;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::default_time_format =
+ time_formats<CharT>::default_time_format;
+
+ template <class time_type, class CharT, class OutItrT>
+ const typename time_facet<time_type, CharT, OutItrT>::char_type*
+ time_facet<time_type, CharT, OutItrT>::default_time_duration_format =
+ time_formats<CharT>::default_time_duration_format;
+
+
+ //! Facet for format-based input.
+ /*!
+ */
+ template <class time_type,
+ class CharT,
+ class InItrT = std::istreambuf_iterator<CharT, std::char_traits<CharT> > >
+ class time_input_facet :
+ public boost::date_time::date_input_facet<typename time_type::date_type , CharT, InItrT> {
+ public:
+ typedef typename time_type::date_type date_type;
+ typedef typename time_type::time_duration_type time_duration_type;
+ typedef typename time_duration_type::fractional_seconds_type fracional_seconds_type;
+ typedef boost::date_time::period<time_type,time_duration_type> period_type;
+ typedef boost::date_time::date_input_facet<typename time_type::date_type, CharT, InItrT> base_type;
+ typedef typename base_type::duration_type date_duration_type;
+ typedef typename base_type::year_type year_type;
+ typedef typename base_type::month_type month_type;
+ typedef typename base_type::day_type day_type;
+ typedef typename base_type::string_type string_type;
+ typedef typename string_type::const_iterator const_itr;
+ typedef typename base_type::char_type char_type;
+ typedef typename base_type::format_date_parser_type format_date_parser_type;
+ typedef typename base_type::period_parser_type period_parser_type;
+ typedef typename base_type::special_values_parser_type special_values_parser_type;
+ typedef typename base_type::date_gen_parser_type date_gen_parser_type;
+ typedef typename base_type::special_values_parser_type::match_results match_results;
+
+ static const char_type* fractional_seconds_format; // f
+ static const char_type* fractional_seconds_or_none_format; // F
+ static const char_type* seconds_with_fractional_seconds_format; // s
+ static const char_type* seconds_format; // S
+ static const char_type* standard_format; // x X
+ static const char_type* zone_abbrev_format; // z
+ static const char_type* zone_name_format; // Z
+ static const char_type* zone_iso_format; // q
+ static const char_type* zone_iso_extended_format; // Q
+ static const char_type* duration_seperator;
+ static const char_type* iso_time_format_specifier;
+ static const char_type* iso_time_format_extended_specifier;
+ static const char_type* default_time_input_format;
+ static const char_type* default_time_duration_format;
+ static std::locale::id id;
+
+ //! Constructor that takes a format string for a ptime
+ explicit time_input_facet(const string_type& format, ::size_t a_ref = 0)
+ : base_type(format, a_ref),
+ m_time_duration_format(default_time_duration_format)
+ { }
+
+ explicit time_input_facet(const string_type& format,
+ const format_date_parser_type& date_parser,
+ const special_values_parser_type& sv_parser,
+ const period_parser_type& per_parser,
+ const date_gen_parser_type& date_gen_parser,
+ ::size_t a_ref = 0)
+ : base_type(format,
+ date_parser,
+ sv_parser,
+ per_parser,
+ date_gen_parser,
+ a_ref),
+ m_time_duration_format(default_time_duration_format)
+ {}
+
+ //! sets default formats for ptime, local_date_time, and time_duration
+ explicit time_input_facet(::size_t a_ref = 0)
+ : base_type(default_time_input_format, a_ref),
+ m_time_duration_format(default_time_duration_format)
+ { }
+
+ //! Set the format for time_duration
+ void time_duration_format(const char_type* const format) {
+ m_time_duration_format = format;
+ }
+ virtual void set_iso_format()
+ {
+ this->m_format = iso_time_format_specifier;
+ }
+ virtual void set_iso_extended_format()
+ {
+ this->m_format = iso_time_format_extended_specifier;
+ }
+
+ InItrT get(InItrT& sitr,
+ InItrT& stream_end,
+ std::ios_base& a_ios,
+ period_type& p) const
+ {
+ p = this->m_period_parser.get_period(sitr,
+ stream_end,
+ a_ios,
+ p,
+ time_duration_type::unit(),
+ *this);
+ return sitr;
+ }
+
+ //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz]
+ //default time_duration format is %H:%M:%S%F HH:MM:SS[.fff...]
+
+ InItrT get(InItrT& sitr,
+ InItrT& stream_end,
+ std::ios_base& a_ios,
+ time_duration_type& td) const
+ {
+ // skip leading whitespace
+ while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; }
+
+ bool use_current_char = false;
+
+ // num_get will consume the +/-, we may need a copy if special_value
+ char_type c = '\0';
+ if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) {
+ c = *sitr;
+ }
+
+ typedef typename time_duration_type::hour_type hour_type;
+ typedef typename time_duration_type::min_type min_type;
+ typedef typename time_duration_type::sec_type sec_type;
+
+ hour_type hour = 0;
+ min_type min = 0;
+ sec_type sec = 0;
+ typename time_duration_type::fractional_seconds_type frac(0);
+
+ typedef std::num_get<CharT, InItrT> num_get;
+ if(!std::has_facet<num_get>(a_ios.getloc())) {
+ num_get* ng = new num_get();
+ std::locale loc = std::locale(a_ios.getloc(), ng);
+ a_ios.imbue(loc);
+ }
+
+ const_itr itr(m_time_duration_format.begin());
+ while (itr != m_time_duration_format.end() && (sitr != stream_end)) {
+ if (*itr == '%') {
+ ++itr;
+ if (*itr != '%') {
+ switch(*itr) {
+ case 'O':
+ {
+ // A period may span more than 24 hours. In that case the format
+ // string should be composed with the unrestricted hours specifier.
+ hour = var_string_to_int<hour_type, CharT>(sitr, stream_end,
+ std::numeric_limits<hour_type>::digits10 + 1);
+ if(hour == -1){
+ return check_special_value(sitr, stream_end, td, c);
+ }
+ break;
+ }
+ case 'H':
+ {
+ match_results mr;
+ hour = fixed_string_to_int<hour_type, CharT>(sitr, stream_end, mr, 2);
+ if(hour == -1){
+ return check_special_value(sitr, stream_end, td, c);
+ }
+ break;
+ }
+ case 'M':
+ {
+ match_results mr;
+ min = fixed_string_to_int<min_type, CharT>(sitr, stream_end, mr, 2);
+ if(min == -1){
+ return check_special_value(sitr, stream_end, td, c);
+ }
+ break;
+ }
+ case 's':
+ case 'S':
+ {
+ match_results mr;
+ sec = fixed_string_to_int<sec_type, CharT>(sitr, stream_end, mr, 2);
+ if(sec == -1){
+ return check_special_value(sitr, stream_end, td, c);
+ }
+ if (*itr == 'S')
+ break;
+ // %s is the same as %S%f so we drop through into %f
+ }
+ case 'f':
+ {
+ // check for decimal, check special_values if missing
+ if(*sitr == '.') {
+ ++sitr;
+ parse_frac_type(sitr, stream_end, frac);
+ // sitr will point to next expected char after this parsing
+ // is complete so no need to advance it
+ use_current_char = true;
+ }
+ else {
+ return check_special_value(sitr, stream_end, td, c);
+ }
+ break;
+ }
+ case 'F':
+ {
+ // check for decimal, skip if missing
+ if(*sitr == '.') {
+ ++sitr;
+ parse_frac_type(sitr, stream_end, frac);
+ // sitr will point to next expected char after this parsing
+ // is complete so no need to advance it
+ use_current_char = true;
+ }
+ else {
+ // nothing was parsed so we don't want to advance sitr
+ use_current_char = true;
+ }
+ break;
+ }
+ default:
+ {} // ignore what we don't understand?
+ }// switch
+ }
+ else { // itr == '%', second consecutive
+ ++sitr;
+ }
+
+ ++itr; //advance past format specifier
+ }
+ else { //skip past chars in format and in buffer
+ ++itr;
+ // set use_current_char when sitr is already
+ // pointing at the next character to process
+ if (use_current_char) {
+ use_current_char = false;
+ }
+ else {
+ ++sitr;
+ }
+ }
+ }
+
+ td = time_duration_type(hour, min, sec, frac);
+ return sitr;
+ }
+
+
+ //! Parses a time object from the input stream
+ InItrT get(InItrT& sitr,
+ InItrT& stream_end,
+ std::ios_base& a_ios,
+ time_type& t) const
+ {
+ string_type tz_str;
+ return get(sitr, stream_end, a_ios, t, tz_str, false);
+ }
+ //! Expects a time_zone in the input stream
+ InItrT get_local_time(InItrT& sitr,
+ InItrT& stream_end,
+ std::ios_base& a_ios,
+ time_type& t,
+ string_type& tz_str) const
+ {
+ return get(sitr, stream_end, a_ios, t, tz_str, true);
+ }
+
+ protected:
+
+ InItrT get(InItrT& sitr,
+ InItrT& stream_end,
+ std::ios_base& a_ios,
+ time_type& t,
+ string_type& tz_str,
+ bool time_is_local) const
+ {
+ // skip leading whitespace
+ while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; }
+
+ bool use_current_char = false;
+ bool use_current_format_char = false; // used whith two character flags
+
+ // num_get will consume the +/-, we may need a copy if special_value
+ char_type c = '\0';
+ if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) {
+ c = *sitr;
+ }
+
+ typedef typename time_duration_type::hour_type hour_type;
+ typedef typename time_duration_type::min_type min_type;
+ typedef typename time_duration_type::sec_type sec_type;
+
+ // time elements
+ hour_type hour = 0;
+ min_type min = 0;
+ sec_type sec = 0;
+ typename time_duration_type::fractional_seconds_type frac(0);
+ // date elements
+ short day_of_year(0);
+ /* Initialized the following to their minimum values. These intermediate
+ * objects are used so we get specific exceptions when part of the input
+ * is unparsable.
+ * Ex: "205-Jan-15" will throw a bad_year, "2005-Jsn-15"- bad_month, etc.*/
+ year_type t_year(1400);
+ month_type t_month(1);
+ day_type t_day(1);
+
+ typedef std::num_get<CharT, InItrT> num_get;
+ if(!std::has_facet<num_get>(a_ios.getloc())) {
+ num_get* ng = new num_get();
+ std::locale loc = std::locale(a_ios.getloc(), ng);
+ a_ios.imbue(loc);
+ }
+
+ const_itr itr(this->m_format.begin());
+ while (itr != this->m_format.end() && (sitr != stream_end)) {
+ if (*itr == '%') {
+ ++itr;
+ if (*itr != '%') {
+ // the cases are grouped by date & time flags - not alphabetical order
+ switch(*itr) {
+ // date flags
+ case 'Y':
+ case 'y':
+ {
+ char_type cs[3] = { '%', *itr };
+ string_type s(cs);
+ match_results mr;
+ try {
+ t_year = this->m_parser.parse_year(sitr, stream_end, s, mr);
+ }
+ catch(std::out_of_range&) { // base class for bad_year exception
+ if(this->m_sv_parser.match(sitr, stream_end, mr)) {
+ t = time_type(static_cast<special_values>(mr.current_match));
+ return sitr;
+ }
+ else {
+ throw; // rethrow bad_year
+ }
+ }
+ break;
+ }
+ case 'B':
+ case 'b':
+ case 'm':
+ {
+ char_type cs[3] = { '%', *itr };
+ string_type s(cs);
+ match_results mr;
+ try {
+ t_month = this->m_parser.parse_month(sitr, stream_end, s, mr);
+ }
+ catch(std::out_of_range&) { // base class for bad_month exception
+ if(this->m_sv_parser.match(sitr, stream_end, mr)) {
+ t = time_type(static_cast<special_values>(mr.current_match));
+ return sitr;
+ }
+ else {
+ throw; // rethrow bad_month
+ }
+ }
+ // did m_parser already advance sitr to next char?
+ if(mr.has_remaining()) {
+ use_current_char = true;
+ }
+ break;
+ }
+ case 'a':
+ case 'A':
+ case 'w':
+ {
+ // weekday is not used in construction but we need to get it out of the stream
+ char_type cs[3] = { '%', *itr };
+ string_type s(cs);
+ match_results mr;
+ typename date_type::day_of_week_type wd(0);
+ try {
+ wd = this->m_parser.parse_weekday(sitr, stream_end, s, mr);
+ }
+ catch(std::out_of_range&) { // base class for bad_weekday exception
+ if(this->m_sv_parser.match(sitr, stream_end, mr)) {
+ t = time_type(static_cast<special_values>(mr.current_match));
+ return sitr;
+ }
+ else {
+ throw; // rethrow bad_weekday
+ }
+ }
+ // did m_parser already advance sitr to next char?
+ if(mr.has_remaining()) {
+ use_current_char = true;
+ }
+ break;
+ }
+ case 'j':
+ {
+ // code that gets julian day (from format_date_parser)
+ match_results mr;
+ day_of_year = fixed_string_to_int<unsigned short, CharT>(sitr, stream_end, mr, 3);
+ if(day_of_year == -1) {
+ if(this->m_sv_parser.match(sitr, stream_end, mr)) {
+ t = time_type(static_cast<special_values>(mr.current_match));
+ return sitr;
+ }
+ }
+ // these next two lines are so we get an exception with bad input
+ typedef typename time_type::date_type::day_of_year_type day_of_year_type;
+ day_of_year_type t_day_of_year(day_of_year);
+ break;
+ }
+ case 'd':
+ {
+ try {
+ t_day = this->m_parser.parse_day_of_month(sitr, stream_end);
+ }
+ catch(std::out_of_range&) { // base class for exception bad_day_of_month
+ match_results mr;
+ if(this->m_sv_parser.match(sitr, stream_end, mr)) {
+ t = time_type(static_cast<special_values>(mr.current_match));
+ return sitr;
+ }
+ else {
+ throw; // rethrow bad_day_of_month
+ }
+ }
+ break;
+ }
+ // time flags
+ case 'H':
+ {
+ match_results mr;
+ hour = fixed_string_to_int<hour_type, CharT>(sitr, stream_end, mr, 2);
+ if(hour == -1){
+ return check_special_value(sitr, stream_end, t, c);
+ }
+ break;
+ }
+ case 'M':
+ {
+ match_results mr;
+ min = fixed_string_to_int<min_type, CharT>(sitr, stream_end, mr, 2);
+ if(min == -1){
+ return check_special_value(sitr, stream_end, t, c);
+ }
+ break;
+ }
+ case 's':
+ case 'S':
+ {
+ match_results mr;
+ sec = fixed_string_to_int<sec_type, CharT>(sitr, stream_end, mr, 2);
+ if(sec == -1){
+ return check_special_value(sitr, stream_end, t, c);
+ }
+ if (*itr == 'S')
+ break;
+ // %s is the same as %S%f so we drop through into %f
+ }
+ case 'f':
+ {
+ // check for decimal, check SV if missing
+ if(*sitr == '.') {
+ ++sitr;
+ parse_frac_type(sitr, stream_end, frac);
+ // sitr will point to next expected char after this parsing
+ // is complete so no need to advance it
+ use_current_char = true;
+ }
+ else {
+ return check_special_value(sitr, stream_end, t, c);
+ }
+ break;
+ }
+ case 'F':
+ {
+ // check for decimal, skip if missing
+ if(*sitr == '.') {
+ ++sitr;
+ parse_frac_type(sitr, stream_end, frac);
+ // sitr will point to next expected char after this parsing
+ // is complete so no need to advance it
+ use_current_char = true;
+ }
+ else {
+ // nothing was parsed so we don't want to advance sitr
+ use_current_char = true;
+ }
+ break;
+ }
+ // time_zone flags
+ //case 'q':
+ //case 'Q':
+ //case 'z':
+ case 'Z':
+ {
+ if(time_is_local) { // skip if 't' is a ptime
+ ++itr;
+ if(*itr == 'P') {
+ // skip leading whitespace
+ while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; }
+ // parse zone
+ while((sitr != stream_end) && (!std::isspace(*sitr))) {
+ tz_str += *sitr;
+ ++sitr;
+ }
+ }
+ else {
+ use_current_format_char = true;
+ }
+
+ }
+ else {
+ // nothing was parsed so we don't want to advance sitr
+ use_current_char = true;
+ }
+
+ break;
+ }
+ default:
+ {} // ignore what we don't understand?
+ }// switch
+ }
+ else { // itr == '%', second consecutive
+ ++sitr;
+ }
+
+ if(use_current_format_char) {
+ use_current_format_char = false;
+ }
+ else {
+ ++itr; //advance past format specifier
+ }
+
+ }
+ else { //skip past chars in format and in buffer
+ ++itr;
+ // set use_current_char when sitr is already
+ // pointing at the next character to process
+ if (use_current_char) {
+ use_current_char = false;
+ }
+ else {
+ ++sitr;
+ }
+ }
+ }
+
+ date_type d(not_a_date_time);
+ if (day_of_year > 0) {
+ d = date_type(static_cast<unsigned short>(t_year-1),12,31) + date_duration_type(day_of_year);
+ }
+ else {
+ d = date_type(t_year, t_month, t_day);
+ }
+
+ time_duration_type td(hour, min, sec, frac);
+ t = time_type(d, td);
+ return sitr;
+ }
+
+ //! Helper function to check for special_value
+ /*! First character may have been consumed during original parse
+ * attempt. Parameter 'c' should be a copy of that character.
+ * Throws ios_base::failure if parse fails. */
+ template<class temporal_type>
+ inline
+ InItrT check_special_value(InItrT& sitr,InItrT& stream_end, temporal_type& tt, char_type c='\0') const
+ {
+ match_results mr;
+ if((c == '-' || c == '+') && (*sitr != c)) { // was the first character consumed?
+ mr.cache += c;
+ }
+ this->m_sv_parser.match(sitr, stream_end, mr);
+ if(mr.current_match == match_results::PARSE_ERROR) {
+ std::string tmp = convert_string_type<char_type, char>(mr.cache);
+ boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + tmp + "'"));
+ BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return sitr); // should never reach
+ }
+ tt = temporal_type(static_cast<special_values>(mr.current_match));
+ return sitr;
+ }
+
+ //! Helper function for parsing a fractional second type from the stream
+ void parse_frac_type(InItrT& sitr,
+ InItrT& stream_end,
+ fracional_seconds_type& frac) const
+ {
+ string_type cache;
+ while((sitr != stream_end) && std::isdigit(*sitr)) {
+ cache += *sitr;
+ ++sitr;
+ }
+ if(cache.size() > 0) {
+ unsigned short precision = time_duration_type::num_fractional_digits();
+ // input may be only the first few decimal places
+ if(cache.size() < precision) {
+ frac = lexical_cast<fracional_seconds_type>(cache);
+ frac = decimal_adjust(frac, static_cast<unsigned short>(precision - cache.size()));
+ }
+ else {
+ // if input has too many decimal places, drop excess digits
+ frac = lexical_cast<fracional_seconds_type>(cache.substr(0, precision));
+ }
+ }
+ }
+
+ private:
+ string_type m_time_duration_format;
+
+ //! Helper function to adjust trailing zeros when parsing fractional digits
+ template<class int_type>
+ inline
+ int_type decimal_adjust(int_type val, const unsigned short places) const
+ {
+ unsigned long factor = 1;
+ for(int i = 0; i < places; ++i){
+ factor *= 10; // shift decimal to the right
+ }
+ return val * factor;
+ }
+
+ };
+
+template <class time_type, class CharT, class InItrT>
+ std::locale::id time_input_facet<time_type, CharT, InItrT>::id;
+
+template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::fractional_seconds_format = time_formats<CharT>::fractional_seconds_format;
+
+ template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::fractional_seconds_or_none_format = time_formats<CharT>::fractional_seconds_or_none_format;
+
+ template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::seconds_with_fractional_seconds_format = time_formats<CharT>::seconds_with_fractional_seconds_format;
+
+ template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::seconds_format = time_formats<CharT>::seconds_format;
+
+ template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::standard_format = time_formats<CharT>::standard_format;
+
+ template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::zone_abbrev_format = time_formats<CharT>::zone_abbrev_format;
+
+ template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::zone_name_format = time_formats<CharT>::zone_name_format;
+
+ template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::zone_iso_format = time_formats<CharT>::zone_iso_format;
+
+ template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::zone_iso_extended_format = time_formats<CharT>::zone_iso_extended_format;
+
+ template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::duration_seperator = time_formats<CharT>::duration_seperator;
+
+ template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::iso_time_format_specifier = time_formats<CharT>::iso_time_format_specifier;
+
+ template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::iso_time_format_extended_specifier = time_formats<CharT>::iso_time_format_extended_specifier;
+
+ template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::default_time_input_format = time_formats<CharT>::default_time_input_format;
+
+ template <class time_type, class CharT, class InItrT>
+ const typename time_input_facet<time_type, CharT, InItrT>::char_type*
+ time_input_facet<time_type, CharT, InItrT>::default_time_duration_format = time_formats<CharT>::default_time_duration_format;
+
+
+} } // namespaces
+
+
+#endif
+
diff --git a/ext/boost/date_time/time_formatting_streams.hpp b/ext/boost/date_time/time_formatting_streams.hpp
new file mode 100644
index 0000000000..3537c103cc
--- /dev/null
+++ b/ext/boost/date_time/time_formatting_streams.hpp
@@ -0,0 +1,122 @@
+#ifndef DATE_TIME_TIME_FORMATTING_STREAMS_HPP___
+#define DATE_TIME_TIME_FORMATTING_STREAMS_HPP___
+
+/* 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-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <boost/date_time/compiler_config.hpp>
+
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+
+#include <locale>
+#include <iomanip>
+#include <iostream>
+#include <boost/date_time/date_formatting_locales.hpp>
+#include <boost/date_time/time_resolution_traits.hpp>
+
+namespace boost {
+namespace date_time {
+
+
+ //! Put a time type into a stream using appropriate facets
+ template<class time_duration_type,
+ class charT = char>
+ class ostream_time_duration_formatter
+ {
+ public:
+ typedef std::basic_ostream<charT> ostream_type;
+ typedef typename time_duration_type::fractional_seconds_type fractional_seconds_type;
+
+ //! Put time into an ostream
+ static void duration_put(const time_duration_type& td,
+ ostream_type& os)
+ {
+ if(td.is_special()) {
+ os << td.get_rep();
+ }
+ else {
+ charT fill_char = '0';
+ if(td.is_negative()) {
+ os << '-';
+ }
+ os << std::setw(2) << std::setfill(fill_char)
+ << absolute_value(td.hours()) << ":";
+ os << std::setw(2) << std::setfill(fill_char)
+ << absolute_value(td.minutes()) << ":";
+ os << std::setw(2) << std::setfill(fill_char)
+ << absolute_value(td.seconds());
+ fractional_seconds_type frac_sec =
+ absolute_value(td.fractional_seconds());
+ if (frac_sec != 0) {
+ os << "."
+ << std::setw(time_duration_type::num_fractional_digits())
+ << std::setfill(fill_char)
+ << frac_sec;
+ }
+ } // else
+ } // duration_put
+ }; //class ostream_time_duration_formatter
+
+ //! Put a time type into a stream using appropriate facets
+ template<class time_type,
+ class charT = char>
+ class ostream_time_formatter
+ {
+ public:
+ typedef std::basic_ostream<charT> ostream_type;
+ typedef typename time_type::date_type date_type;
+ typedef typename time_type::time_duration_type time_duration_type;
+ typedef ostream_time_duration_formatter<time_duration_type, charT> duration_formatter;
+
+ //! Put time into an ostream
+ static void time_put(const time_type& t,
+ ostream_type& os)
+ {
+ date_type d = t.date();
+ os << d;
+ if(!d.is_infinity() && !d.is_not_a_date())
+ {
+ os << " "; //TODO: fix the separator here.
+ duration_formatter::duration_put(t.time_of_day(), os);
+ }
+
+ } // time_to_ostream
+ }; //class ostream_time_formatter
+
+
+ //! Put a time period into a stream using appropriate facets
+ template<class time_period_type,
+ class charT = char>
+ class ostream_time_period_formatter
+ {
+ public:
+ typedef std::basic_ostream<charT> ostream_type;
+ typedef typename time_period_type::point_type time_type;
+ typedef ostream_time_formatter<time_type, charT> time_formatter;
+
+ //! Put time into an ostream
+ static void period_put(const time_period_type& tp,
+ ostream_type& os)
+ {
+ os << '['; //TODO: facet or manipulator for periods?
+ time_formatter::time_put(tp.begin(), os);
+ os << '/'; //TODO: facet or manipulator for periods?
+ time_formatter::time_put(tp.last(), os);
+ os << ']';
+
+ } // period_put
+
+ }; //class ostream_time_period_formatter
+
+
+
+} } //namespace date_time
+
+#endif //BOOST_DATE_TIME_NO_LOCALE
+
+#endif
diff --git a/ext/boost/date_time/time_iterator.hpp b/ext/boost/date_time/time_iterator.hpp
new file mode 100644
index 0000000000..2258a3308e
--- /dev/null
+++ b/ext/boost/date_time/time_iterator.hpp
@@ -0,0 +1,52 @@
+#ifndef DATE_TIME_TIME_ITERATOR_HPP___
+#define DATE_TIME_TIME_ITERATOR_HPP___
+
+/* 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) $
+ */
+
+
+namespace boost {
+namespace date_time {
+
+
+ //! Simple time iterator skeleton class
+ template<class time_type>
+ class time_itr {
+ public:
+ typedef typename time_type::time_duration_type time_duration_type;
+ time_itr(time_type t, time_duration_type d) : current_(t), offset_(d) {};
+ time_itr& operator++()
+ {
+ current_ = current_ + offset_;
+ return *this;
+ }
+ time_itr& operator--()
+ {
+ current_ = current_ - offset_;
+ return *this;
+ }
+ time_type operator*() {return current_;};
+ time_type* operator->() {return &current_;};
+ bool operator< (const time_type& t) {return current_ < t;};
+ bool operator<= (const time_type& t) {return current_ <= t;};
+ bool operator!= (const time_type& t) {return current_ != t;};
+ bool operator== (const time_type& t) {return current_ == t;};
+ bool operator> (const time_type& t) {return current_ > t;};
+ bool operator>= (const time_type& t) {return current_ >= t;};
+
+ private:
+ time_type current_;
+ time_duration_type offset_;
+ };
+
+
+
+} }//namespace date_time
+
+
+#endif
diff --git a/ext/boost/date_time/time_parsing.hpp b/ext/boost/date_time/time_parsing.hpp
new file mode 100644
index 0000000000..dfccf6a1df
--- /dev/null
+++ b/ext/boost/date_time/time_parsing.hpp
@@ -0,0 +1,321 @@
+#ifndef _DATE_TIME_TIME_PARSING_HPP___
+#define _DATE_TIME_TIME_PARSING_HPP___
+
+/* Copyright (c) 2002,2003,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-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/tokenizer.hpp"
+#include "boost/lexical_cast.hpp"
+#include "boost/date_time/date_parsing.hpp"
+#include "boost/cstdint.hpp"
+#include <iostream>
+
+namespace boost {
+namespace date_time {
+
+ //! computes exponential math like 2^8 => 256, only works with positive integers
+ //Not general purpose, but needed b/c std::pow is not available
+ //everywehere. Hasn't been tested with negatives and zeros
+ template<class int_type>
+ inline
+ int_type power(int_type base, int_type exponent)
+ {
+ int_type result = 1;
+ for(int i = 0; i < exponent; ++i){
+ result *= base;
+ }
+ return result;
+ }
+
+ //! Creates a time_duration object from a delimited string
+ /*! Expected format for string is "[-]h[h][:mm][:ss][.fff]".
+ * If the number of fractional digits provided is greater than the
+ * precision of the time duration type then the extra digits are
+ * truncated.
+ *
+ * A negative duration will be created if the first character in
+ * string is a '-', all other '-' will be treated as delimiters.
+ * Accepted delimiters are "-:,.".
+ */
+ template<class time_duration, class char_type>
+ inline
+ time_duration
+ str_from_delimited_time_duration(const std::basic_string<char_type>& s)
+ {
+ unsigned short min=0, sec =0;
+ int hour =0;
+ bool is_neg = (s.at(0) == '-');
+ boost::int64_t fs=0;
+ int pos = 0;
+
+ typedef typename std::basic_string<char_type>::traits_type traits_type;
+ typedef boost::char_separator<char_type, traits_type> char_separator_type;
+ typedef boost::tokenizer<char_separator_type,
+ typename std::basic_string<char_type>::const_iterator,
+ std::basic_string<char_type> > tokenizer;
+ typedef typename boost::tokenizer<char_separator_type,
+ typename std::basic_string<char_type>::const_iterator,
+ typename std::basic_string<char_type> >::iterator tokenizer_iterator;
+
+ char_type sep_chars[5] = {'-',':',',','.'};
+ char_separator_type sep(sep_chars);
+ tokenizer tok(s,sep);
+ for(tokenizer_iterator beg=tok.begin(); beg!=tok.end();++beg){
+ switch(pos) {
+ case 0: {
+ hour = boost::lexical_cast<int>(*beg);
+ break;
+ }
+ case 1: {
+ min = boost::lexical_cast<unsigned short>(*beg);
+ break;
+ }
+ case 2: {
+ sec = boost::lexical_cast<unsigned short>(*beg);
+ break;
+ };
+ case 3: {
+ int digits = static_cast<int>(beg->length());
+ //Works around a bug in MSVC 6 library that does not support
+ //operator>> thus meaning lexical_cast will fail to compile.
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+ // msvc wouldn't compile 'time_duration::num_fractional_digits()'
+ // (required template argument list) as a workaround a temp
+ // time_duration object was used
+ time_duration td(hour,min,sec,fs);
+ int precision = td.num_fractional_digits();
+ // _atoi64 is an MS specific function
+ if(digits >= precision) {
+ // drop excess digits
+ fs = _atoi64(beg->substr(0, precision).c_str());
+ }
+ else {
+ fs = _atoi64(beg->c_str());
+ }
+#else
+ int precision = time_duration::num_fractional_digits();
+ if(digits >= precision) {
+ // drop excess digits
+ fs = boost::lexical_cast<boost::int64_t>(beg->substr(0, precision));
+ }
+ else {
+ fs = boost::lexical_cast<boost::int64_t>(*beg);
+ }
+#endif
+ if(digits < precision){
+ // trailing zeros get dropped from the string,
+ // "1:01:01.1" would yield .000001 instead of .100000
+ // the power() compensates for the missing decimal places
+ fs *= power(10, precision - digits);
+ }
+
+ break;
+ }
+ }//switch
+ pos++;
+ }
+ if(is_neg) {
+ return -time_duration(hour, min, sec, fs);
+ }
+ else {
+ return time_duration(hour, min, sec, fs);
+ }
+ }
+
+ //! Creates a time_duration object from a delimited string
+ /*! Expected format for string is "[-]h[h][:mm][:ss][.fff]".
+ * If the number of fractional digits provided is greater than the
+ * precision of the time duration type then the extra digits are
+ * truncated.
+ *
+ * A negative duration will be created if the first character in
+ * string is a '-', all other '-' will be treated as delimiters.
+ * Accepted delimiters are "-:,.".
+ */
+ template<class time_duration>
+ inline
+ time_duration
+ parse_delimited_time_duration(const std::string& s)
+ {
+ return str_from_delimited_time_duration<time_duration,char>(s);
+ }
+
+ //! Utility function to split appart string
+ inline
+ bool
+ split(const std::string& s,
+ char sep,
+ std::string& first,
+ std::string& second)
+ {
+ int sep_pos = static_cast<int>(s.find(sep));
+ first = s.substr(0,sep_pos);
+ second = s.substr(sep_pos+1);
+ return true;
+ }
+
+
+ template<class time_type>
+ inline
+ time_type
+ parse_delimited_time(const std::string& s, char sep)
+ {
+ typedef typename time_type::time_duration_type time_duration;
+ typedef typename time_type::date_type date_type;
+
+ //split date/time on a unique delimiter char such as ' ' or 'T'
+ std::string date_string, tod_string;
+ split(s, sep, date_string, tod_string);
+ //call parse_date with first string
+ date_type d = parse_date<date_type>(date_string);
+ //call parse_time_duration with remaining string
+ time_duration td = parse_delimited_time_duration<time_duration>(tod_string);
+ //construct a time
+ return time_type(d, td);
+
+ }
+
+ //! Parse time duration part of an iso time of form: [-]hhmmss[.fff...] (eg: 120259.123 is 12 hours, 2 min, 59 seconds, 123000 microseconds)
+ template<class time_duration>
+ inline
+ time_duration
+ parse_undelimited_time_duration(const std::string& s)
+ {
+ int precision = 0;
+ {
+ // msvc wouldn't compile 'time_duration::num_fractional_digits()'
+ // (required template argument list) as a workaround, a temp
+ // time_duration object was used
+ time_duration tmp(0,0,0,1);
+ precision = tmp.num_fractional_digits();
+ }
+ // 'precision+1' is so we grab all digits, plus the decimal
+ int offsets[] = {2,2,2, precision+1};
+ int pos = 0, sign = 0;
+ int hours = 0;
+ short min=0, sec=0;
+ boost::int64_t fs=0;
+ // increment one position if the string was "signed"
+ if(s.at(sign) == '-')
+ {
+ ++sign;
+ }
+ // stlport choked when passing s.substr() to tokenizer
+ // using a new string fixed the error
+ std::string remain = s.substr(sign);
+ /* We do not want the offset_separator to wrap the offsets, we
+ * will never want to process more than:
+ * 2 char, 2 char, 2 char, frac_sec length.
+ * We *do* want the offset_separator to give us a partial for the
+ * last characters if there were not enough provided in the input string. */
+ bool wrap_off = false;
+ bool ret_part = true;
+ boost::offset_separator osf(offsets, offsets+4, wrap_off, ret_part);
+ typedef boost::tokenizer<boost::offset_separator,
+ std::basic_string<char>::const_iterator,
+ std::basic_string<char> > tokenizer;
+ typedef boost::tokenizer<boost::offset_separator,
+ std::basic_string<char>::const_iterator,
+ std::basic_string<char> >::iterator tokenizer_iterator;
+ tokenizer tok(remain, osf);
+ for(tokenizer_iterator ti=tok.begin(); ti!=tok.end();++ti){
+ switch(pos) {
+ case 0:
+ {
+ hours = boost::lexical_cast<int>(*ti);
+ break;
+ }
+ case 1:
+ {
+ min = boost::lexical_cast<short>(*ti);
+ break;
+ }
+ case 2:
+ {
+ sec = boost::lexical_cast<short>(*ti);
+ break;
+ }
+ case 3:
+ {
+ std::string char_digits(ti->substr(1)); // digits w/no decimal
+ int digits = static_cast<int>(char_digits.length());
+
+ //Works around a bug in MSVC 6 library that does not support
+ //operator>> thus meaning lexical_cast will fail to compile.
+#if (defined(BOOST_MSVC) && (_MSC_VER <= 1200)) // 1200 == VC++ 6.0
+ // _atoi64 is an MS specific function
+ if(digits >= precision) {
+ // drop excess digits
+ fs = _atoi64(char_digits.substr(0, precision).c_str());
+ }
+ else if(digits == 0) {
+ fs = 0; // just in case _atoi64 doesn't like an empty string
+ }
+ else {
+ fs = _atoi64(char_digits.c_str());
+ }
+#else
+ if(digits >= precision) {
+ // drop excess digits
+ fs = boost::lexical_cast<boost::int64_t>(char_digits.substr(0, precision));
+ }
+ else if(digits == 0) {
+ fs = 0; // lexical_cast doesn't like empty strings
+ }
+ else {
+ fs = boost::lexical_cast<boost::int64_t>(char_digits);
+ }
+#endif
+ if(digits < precision){
+ // trailing zeros get dropped from the string,
+ // "1:01:01.1" would yield .000001 instead of .100000
+ // the power() compensates for the missing decimal places
+ fs *= power(10, precision - digits);
+ }
+
+ break;
+ }
+ };
+ pos++;
+ }
+ if(sign) {
+ return -time_duration(hours, min, sec, fs);
+ }
+ else {
+ return time_duration(hours, min, sec, fs);
+ }
+ }
+
+ //! Parse time string of form YYYYMMDDThhmmss where T is delimeter between date and time
+ template<class time_type>
+ inline
+ time_type
+ parse_iso_time(const std::string& s, char sep)
+ {
+ typedef typename time_type::time_duration_type time_duration;
+ typedef typename time_type::date_type date_type;
+
+ //split date/time on a unique delimiter char such as ' ' or 'T'
+ std::string date_string, tod_string;
+ split(s, sep, date_string, tod_string);
+ //call parse_date with first string
+ date_type d = parse_undelimited_date<date_type>(date_string);
+ //call parse_time_duration with remaining string
+ time_duration td = parse_undelimited_time_duration<time_duration>(tod_string);
+ //construct a time
+ return time_type(d, td);
+ }
+
+
+
+} }//namespace date_time
+
+
+
+
+#endif
diff --git a/ext/boost/date_time/time_resolution_traits.hpp b/ext/boost/date_time/time_resolution_traits.hpp
new file mode 100644
index 0000000000..658f3d207c
--- /dev/null
+++ b/ext/boost/date_time/time_resolution_traits.hpp
@@ -0,0 +1,144 @@
+#ifndef DATE_TIME_TIME_RESOLUTION_TRAITS_HPP
+#define DATE_TIME_TIME_RESOLUTION_TRAITS_HPP
+
+/* 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: 2009-06-06 07:25:55 -0400 (Sat, 06 Jun 2009) $
+ */
+
+
+#include <boost/cstdint.hpp>
+#include <boost/date_time/time_defs.hpp>
+#include <boost/date_time/int_adapter.hpp>
+#include <boost/date_time/compiler_config.hpp>
+
+namespace boost {
+namespace date_time {
+
+ //! Simple function to calculate absolute value of a numeric type
+ template <typename T>
+ // JDG [7/6/02 made a template],
+ // moved here from time_duration.hpp 2003-Sept-4.
+ inline T absolute_value(T x)
+ {
+ return x < 0 ? -x : x;
+ }
+
+ //! traits struct for time_resolution_traits implementation type
+ struct time_resolution_traits_bi32_impl {
+ typedef boost::int32_t int_type;
+ typedef boost::int32_t impl_type;
+ static int_type as_number(impl_type i){ return i;}
+ //! Used to determine if implemented type is int_adapter or int
+ static bool is_adapted() { return false;}
+ };
+ //! traits struct for time_resolution_traits implementation type
+ struct time_resolution_traits_adapted32_impl {
+ typedef boost::int32_t int_type;
+ typedef boost::date_time::int_adapter<boost::int32_t> impl_type;
+ static int_type as_number(impl_type i){ return i.as_number();}
+ //! Used to determine if implemented type is int_adapter or int
+ static bool is_adapted() { return true;}
+ };
+ //! traits struct for time_resolution_traits implementation type
+ struct time_resolution_traits_bi64_impl {
+ typedef boost::int64_t int_type;
+ typedef boost::int64_t impl_type;
+ static int_type as_number(impl_type i){ return i;}
+ //! Used to determine if implemented type is int_adapter or int
+ static bool is_adapted() { return false;}
+ };
+ //! traits struct for time_resolution_traits implementation type
+ struct time_resolution_traits_adapted64_impl {
+ typedef boost::int64_t int_type;
+ typedef boost::date_time::int_adapter<boost::int64_t> impl_type;
+ static int_type as_number(impl_type i){ return i.as_number();}
+ //! Used to determine if implemented type is int_adapter or int
+ static bool is_adapted() { return true;}
+ };
+
+ template<typename frac_sec_type,
+ time_resolutions res,
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+ boost::int64_t resolution_adjust,
+#else
+ typename frac_sec_type::int_type resolution_adjust,
+#endif
+ unsigned short frac_digits,
+ typename v_type = boost::int32_t >
+ class time_resolution_traits {
+ public:
+ typedef typename frac_sec_type::int_type fractional_seconds_type;
+ typedef typename frac_sec_type::int_type tick_type;
+ typedef typename frac_sec_type::impl_type impl_type;
+ typedef v_type day_type;
+ typedef v_type hour_type;
+ typedef v_type min_type;
+ typedef v_type sec_type;
+
+ // bring in function from frac_sec_type traits structs
+ static fractional_seconds_type as_number(impl_type i)
+ {
+ return frac_sec_type::as_number(i);
+ }
+ static bool is_adapted()
+ {
+ return frac_sec_type::is_adapted();
+ }
+
+ //Would like this to be frac_sec_type, but some compilers complain
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+ BOOST_STATIC_CONSTANT(boost::int64_t, ticks_per_second = resolution_adjust);
+#else
+ BOOST_STATIC_CONSTANT(fractional_seconds_type, ticks_per_second = resolution_adjust);
+#endif
+
+ static time_resolutions resolution()
+ {
+ return res;
+ }
+ static unsigned short num_fractional_digits()
+ {
+ return frac_digits;
+ }
+ static fractional_seconds_type res_adjust()
+ {
+ return resolution_adjust;
+ }
+ //! Any negative argument results in a negative tick_count
+ static tick_type to_tick_count(hour_type hours,
+ min_type minutes,
+ sec_type seconds,
+ fractional_seconds_type fs)
+ {
+ if(hours < 0 || minutes < 0 || seconds < 0 || fs < 0)
+ {
+ hours = absolute_value(hours);
+ minutes = absolute_value(minutes);
+ seconds = absolute_value(seconds);
+ fs = absolute_value(fs);
+ return (((((fractional_seconds_type(hours)*3600)
+ + (fractional_seconds_type(minutes)*60)
+ + seconds)*res_adjust()) + fs) * -1);
+ }
+
+ return (((fractional_seconds_type(hours)*3600)
+ + (fractional_seconds_type(minutes)*60)
+ + seconds)*res_adjust()) + fs;
+ }
+
+ };
+
+ typedef time_resolution_traits<time_resolution_traits_adapted32_impl, milli, 1000, 3 > milli_res;
+ typedef time_resolution_traits<time_resolution_traits_adapted64_impl, micro, 1000000, 6 > micro_res;
+ typedef time_resolution_traits<time_resolution_traits_adapted64_impl, nano, 1000000000, 9 > nano_res;
+
+
+} } //namespace date_time
+
+
+
+#endif
diff --git a/ext/boost/date_time/time_system_counted.hpp b/ext/boost/date_time/time_system_counted.hpp
new file mode 100644
index 0000000000..fa883907eb
--- /dev/null
+++ b/ext/boost/date_time/time_system_counted.hpp
@@ -0,0 +1,254 @@
+#ifndef DATE_TIME_TIME_SYSTEM_COUNTED_HPP
+#define DATE_TIME_TIME_SYSTEM_COUNTED_HPP
+
+/* 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) $
+ */
+
+
+
+#include "boost/date_time/time_defs.hpp"
+#include <string>
+
+
+namespace boost {
+namespace date_time {
+
+ //! Time representation that uses a single integer count
+ template<class config>
+ struct counted_time_rep
+ {
+ typedef typename config::int_type int_type;
+ typedef typename config::date_type date_type;
+ typedef typename config::impl_type impl_type;
+ typedef typename date_type::duration_type date_duration_type;
+ typedef typename date_type::calendar_type calendar_type;
+ typedef typename date_type::ymd_type ymd_type;
+ typedef typename config::time_duration_type time_duration_type;
+ typedef typename config::resolution_traits resolution_traits;
+
+ counted_time_rep(const date_type& d, const time_duration_type& time_of_day)
+ : time_count_(1)
+ {
+ if(d.is_infinity() || d.is_not_a_date() || time_of_day.is_special()) {
+ time_count_ = time_of_day.get_rep() + d.day_count();
+ //std::cout << time_count_ << std::endl;
+ }
+ else {
+ time_count_ = (d.day_number() * frac_sec_per_day()) + time_of_day.ticks();
+ }
+ }
+ explicit counted_time_rep(int_type count) :
+ time_count_(count)
+ {}
+ explicit counted_time_rep(impl_type count) :
+ time_count_(count)
+ {}
+ date_type date() const
+ {
+ if(time_count_.is_special()) {
+ return date_type(time_count_.as_special());
+ }
+ else {
+ typename calendar_type::date_int_type dc = day_count();
+ //std::cout << "time_rep here:" << dc << std::endl;
+ ymd_type ymd = calendar_type::from_day_number(dc);
+ return date_type(ymd);
+ }
+ }
+ //int_type day_count() const
+ unsigned long day_count() const
+ {
+ /* resolution_traits::as_number returns a boost::int64_t &
+ * frac_sec_per_day is also a boost::int64_t so, naturally,
+ * the division operation returns a boost::int64_t.
+ * The static_cast to an unsigned long is ok (results in no data loss)
+ * because frac_sec_per_day is either the number of
+ * microseconds per day, or the number of nanoseconds per day.
+ * Worst case scenario: resolution_traits::as_number returns the
+ * maximum value an int64_t can hold and frac_sec_per_day
+ * is microseconds per day (lowest possible value).
+ * The division operation will then return a value of 106751991 -
+ * easily fitting in an unsigned long.
+ */
+ return static_cast<unsigned long>(resolution_traits::as_number(time_count_) / frac_sec_per_day());
+ }
+ int_type time_count() const
+ {
+ return resolution_traits::as_number(time_count_);
+ }
+ int_type tod() const
+ {
+ return resolution_traits::as_number(time_count_) % frac_sec_per_day();
+ }
+ static int_type frac_sec_per_day()
+ {
+ int_type seconds_per_day = 60*60*24;
+ int_type fractional_sec_per_sec(resolution_traits::res_adjust());
+ return seconds_per_day*fractional_sec_per_sec;
+ }
+ bool is_pos_infinity()const
+ {
+ return impl_type::is_pos_inf(time_count_.as_number());
+ }
+ bool is_neg_infinity()const
+ {
+ return impl_type::is_neg_inf(time_count_.as_number());
+ }
+ bool is_not_a_date_time()const
+ {
+ return impl_type::is_not_a_number(time_count_.as_number());
+ }
+ bool is_special()const
+ {
+ return time_count_.is_special();
+ }
+ impl_type get_rep()const
+ {
+ return time_count_;
+ }
+ private:
+ impl_type time_count_;
+ };
+
+ //! An unadjusted time system implementation.
+ template<class time_rep>
+ class counted_time_system
+ {
+ public:
+ typedef time_rep time_rep_type;
+ typedef typename time_rep_type::impl_type impl_type;
+ typedef typename time_rep_type::time_duration_type time_duration_type;
+ typedef typename time_duration_type::fractional_seconds_type fractional_seconds_type;
+ typedef typename time_rep_type::date_type date_type;
+ typedef typename time_rep_type::date_duration_type date_duration_type;
+
+
+ template<class T> static void unused_var(const T&) {}
+
+ static time_rep_type get_time_rep(const date_type& day,
+ const time_duration_type& tod,
+ date_time::dst_flags dst=not_dst)
+ {
+ unused_var(dst);
+ return time_rep_type(day, tod);
+ }
+
+ static time_rep_type get_time_rep(special_values sv)
+ {
+ switch (sv) {
+ case not_a_date_time:
+ return time_rep_type(date_type(not_a_date_time),
+ time_duration_type(not_a_date_time));
+ case pos_infin:
+ return time_rep_type(date_type(pos_infin),
+ time_duration_type(pos_infin));
+ case neg_infin:
+ return time_rep_type(date_type(neg_infin),
+ time_duration_type(neg_infin));
+ case max_date_time: {
+ time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1);
+ return time_rep_type(date_type(max_date_time), td);
+ }
+ case min_date_time:
+ return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0));
+
+ default:
+ return time_rep_type(date_type(not_a_date_time),
+ time_duration_type(not_a_date_time));
+
+ }
+
+ }
+
+ static date_type get_date(const time_rep_type& val)
+ {
+ return val.date();
+ }
+ static time_duration_type get_time_of_day(const time_rep_type& val)
+ {
+ if(val.is_special()) {
+ return time_duration_type(val.get_rep().as_special());
+ }
+ else{
+ return time_duration_type(0,0,0,val.tod());
+ }
+ }
+ static std::string zone_name(const time_rep_type&)
+ {
+ return "";
+ }
+ static bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs)
+ {
+ return (lhs.time_count() == rhs.time_count());
+ }
+ static bool is_less(const time_rep_type& lhs, const time_rep_type& rhs)
+ {
+ return (lhs.time_count() < rhs.time_count());
+ }
+ static time_rep_type add_days(const time_rep_type& base,
+ const date_duration_type& dd)
+ {
+ if(base.is_special() || dd.is_special()) {
+ return(time_rep_type(base.get_rep() + dd.get_rep()));
+ }
+ else {
+ return time_rep_type(base.time_count() + (dd.days() * time_rep_type::frac_sec_per_day()));
+ }
+ }
+ static time_rep_type subtract_days(const time_rep_type& base,
+ const date_duration_type& dd)
+ {
+ if(base.is_special() || dd.is_special()) {
+ return(time_rep_type(base.get_rep() - dd.get_rep()));
+ }
+ else{
+ return time_rep_type(base.time_count() - (dd.days() * time_rep_type::frac_sec_per_day()));
+ }
+ }
+ static time_rep_type subtract_time_duration(const time_rep_type& base,
+ const time_duration_type& td)
+ {
+ if(base.is_special() || td.is_special()) {
+ return(time_rep_type(base.get_rep() - td.get_rep()));
+ }
+ else {
+ return time_rep_type(base.time_count() - td.ticks());
+ }
+ }
+ static time_rep_type add_time_duration(const time_rep_type& base,
+ time_duration_type td)
+ {
+ if(base.is_special() || td.is_special()) {
+ return(time_rep_type(base.get_rep() + td.get_rep()));
+ }
+ else {
+ return time_rep_type(base.time_count() + td.ticks());
+ }
+ }
+ static time_duration_type subtract_times(const time_rep_type& lhs,
+ const time_rep_type& rhs)
+ {
+ if(lhs.is_special() || rhs.is_special()) {
+ return(time_duration_type(
+ impl_type::to_special((lhs.get_rep() - rhs.get_rep()).as_number())));
+ }
+ else {
+ fractional_seconds_type fs = lhs.time_count() - rhs.time_count();
+ return time_duration_type(0,0,0,fs);
+ }
+ }
+
+ };
+
+
+} } //namespace date_time
+
+
+
+#endif
+
diff --git a/ext/boost/date_time/time_system_split.hpp b/ext/boost/date_time/time_system_split.hpp
new file mode 100644
index 0000000000..08ea1ec2d1
--- /dev/null
+++ b/ext/boost/date_time/time_system_split.hpp
@@ -0,0 +1,207 @@
+#ifndef DATE_TIME_TIME_SYSTEM_SPLIT_HPP
+#define DATE_TIME_TIME_SYSTEM_SPLIT_HPP
+
+/* Copyright (c) 2002,2003,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-13 15:10:23 -0500 (Thu, 13 Nov 2008) $
+ */
+
+
+#include <string>
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/special_defs.hpp"
+
+namespace boost {
+namespace date_time {
+
+ //! An unadjusted time system implementation.
+#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT))
+ template<typename config, boost::int32_t ticks_per_second>
+#else
+ template<typename config>
+#endif
+ class split_timedate_system
+ {
+ public:
+ typedef typename config::time_rep_type time_rep_type;
+ typedef typename config::date_type date_type;
+ typedef typename config::time_duration_type time_duration_type;
+ typedef typename config::date_duration_type date_duration_type;
+ typedef typename config::int_type int_type;
+ typedef typename config::resolution_traits resolution_traits;
+
+ //86400 is number of seconds in a day...
+#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT))
+ typedef date_time::wrapping_int<int_type, INT64_C(86400) * ticks_per_second > wrap_int_type;
+#else
+ private:
+ BOOST_STATIC_CONSTANT(int_type, ticks_per_day = INT64_C(86400) * config::tick_per_second);
+ public:
+# if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0X581) )
+ typedef date_time::wrapping_int< split_timedate_system::int_type, split_timedate_system::ticks_per_day> wrap_int_type;
+# else
+ typedef date_time::wrapping_int<int_type, ticks_per_day> wrap_int_type;
+#endif
+#endif
+
+ static time_rep_type get_time_rep(special_values sv)
+ {
+ switch (sv) {
+ case not_a_date_time:
+ return time_rep_type(date_type(not_a_date_time),
+ time_duration_type(not_a_date_time));
+ case pos_infin:
+ return time_rep_type(date_type(pos_infin),
+ time_duration_type(pos_infin));
+ case neg_infin:
+ return time_rep_type(date_type(neg_infin),
+ time_duration_type(neg_infin));
+ case max_date_time: {
+ time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1);
+ return time_rep_type(date_type(max_date_time), td);
+ }
+ case min_date_time:
+ return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0));
+
+ default:
+ return time_rep_type(date_type(not_a_date_time),
+ time_duration_type(not_a_date_time));
+
+ }
+
+ }
+
+ static time_rep_type get_time_rep(const date_type& day,
+ const time_duration_type& tod,
+ date_time::dst_flags /* dst */ = not_dst)
+ {
+ if(day.is_special() || tod.is_special()) {
+ if(day.is_not_a_date() || tod.is_not_a_date_time()) {
+ return time_rep_type(date_type(not_a_date_time),
+ time_duration_type(not_a_date_time));
+ }
+ else if(day.is_pos_infinity()) {
+ if(tod.is_neg_infinity()) {
+ return time_rep_type(date_type(not_a_date_time),
+ time_duration_type(not_a_date_time));
+ }
+ else {
+ return time_rep_type(day, time_duration_type(pos_infin));
+ }
+ }
+ else if(day.is_neg_infinity()) {
+ if(tod.is_pos_infinity()) {
+ return time_rep_type(date_type(not_a_date_time),
+ time_duration_type(not_a_date_time));
+ }
+ else {
+ return time_rep_type(day, time_duration_type(neg_infin));
+ }
+ }
+ else if(tod.is_pos_infinity()) {
+ if(day.is_neg_infinity()) {
+ return time_rep_type(date_type(not_a_date_time),
+ time_duration_type(not_a_date_time));
+ }
+ else {
+ return time_rep_type(date_type(pos_infin), tod);
+ }
+ }
+ else if(tod.is_neg_infinity()) {
+ if(day.is_pos_infinity()) {
+ return time_rep_type(date_type(not_a_date_time),
+ time_duration_type(not_a_date_time));
+ }
+ else {
+ return time_rep_type(date_type(neg_infin), tod);
+ }
+ }
+ }
+ return time_rep_type(day, tod);
+ }
+ static date_type get_date(const time_rep_type& val)
+ {
+ return date_type(val.day);
+ }
+ static time_duration_type get_time_of_day(const time_rep_type& val)
+ {
+ return time_duration_type(val.time_of_day);
+ }
+ static std::string zone_name(const time_rep_type&)
+ {
+ return std::string();
+ }
+ static bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs)
+ {
+ return ((lhs.day == rhs.day) && (lhs.time_of_day == rhs.time_of_day));
+ }
+ static bool is_less(const time_rep_type& lhs, const time_rep_type& rhs)
+ {
+ if (lhs.day < rhs.day) return true;
+ if (lhs.day > rhs.day) return false;
+ return (lhs.time_of_day < rhs.time_of_day);
+ }
+ static time_rep_type add_days(const time_rep_type& base,
+ const date_duration_type& dd)
+ {
+ return time_rep_type(base.day+dd, base.time_of_day);
+ }
+ static time_rep_type subtract_days(const time_rep_type& base,
+ const date_duration_type& dd)
+ {
+ return split_timedate_system::get_time_rep(base.day-dd, base.time_of_day);
+ }
+ static time_rep_type subtract_time_duration(const time_rep_type& base,
+ const time_duration_type& td)
+ {
+ if(base.day.is_special() || td.is_special())
+ {
+ return split_timedate_system::get_time_rep(base.day, -td);
+ }
+ if (td.is_negative()) {
+ time_duration_type td1 = td.invert_sign();
+ return add_time_duration(base,td1);
+ }
+
+ wrap_int_type day_offset(base.time_of_day.ticks());
+ date_duration_type day_overflow(static_cast<typename date_duration_type::duration_rep_type>(day_offset.subtract(td.ticks())));
+
+ return time_rep_type(base.day-day_overflow,
+ time_duration_type(0,0,0,day_offset.as_int()));
+ }
+ static time_rep_type add_time_duration(const time_rep_type& base,
+ time_duration_type td)
+ {
+ if(base.day.is_special() || td.is_special()) {
+ return split_timedate_system::get_time_rep(base.day, td);
+ }
+ if (td.is_negative()) {
+ time_duration_type td1 = td.invert_sign();
+ return subtract_time_duration(base,td1);
+ }
+
+ wrap_int_type day_offset(base.time_of_day.ticks());
+ date_duration_type day_overflow(static_cast< typename date_duration_type::duration_rep_type >(day_offset.add(td.ticks())));
+
+ return time_rep_type(base.day+day_overflow,
+ time_duration_type(0,0,0,day_offset.as_int()));
+ }
+ static time_duration_type subtract_times(const time_rep_type& lhs,
+ const time_rep_type& rhs)
+ {
+ date_duration_type dd = lhs.day - rhs.day;
+ time_duration_type td(dd.days()*24,0,0); //days * 24 hours
+ time_duration_type td2 = lhs.time_of_day - rhs.time_of_day;
+ return td+td2;
+ // return time_rep_type(base.day-dd, base.time_of_day);
+ }
+
+ };
+
+} } //namespace date_time
+
+
+#endif
diff --git a/ext/boost/date_time/time_zone_base.hpp b/ext/boost/date_time/time_zone_base.hpp
new file mode 100644
index 0000000000..0d3cb903e6
--- /dev/null
+++ b/ext/boost/date_time/time_zone_base.hpp
@@ -0,0 +1,99 @@
+#ifndef _DATE_TIME_TIME_ZONE_BASE__
+#define _DATE_TIME_TIME_ZONE_BASE__
+
+/* Copyright (c) 2003-2005 CrystalClear Software, Inc.
+ * 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) $
+ */
+
+
+#include <string>
+#include <sstream>
+
+namespace boost {
+namespace date_time {
+
+
+
+ //! Interface class for dynamic time zones.
+ /*! This class represents the base interface for all timezone
+ * representations. Subclasses may provide different systems
+ * for identifying a particular zone. For example some may
+ * provide a geographical based zone construction while others
+ * may specify the offset from GMT. Another possible implementation
+ * would be to convert from POSIX timezone strings. Regardless of
+ * the construction technique, this is the interface that these
+ * time zone types must provide.
+ *
+ * Note that this class is intended to be used as a shared
+ * resource (hence the derivation from boost::counted_base.
+ */
+ template<typename time_type, typename CharT>
+ class time_zone_base {
+ public:
+ typedef CharT char_type;
+ typedef std::basic_string<CharT> string_type;
+ typedef std::basic_ostringstream<CharT> stringstream_type;
+ typedef typename time_type::date_type::year_type year_type;
+ typedef typename time_type::time_duration_type time_duration_type;
+
+ time_zone_base() {};
+ virtual ~time_zone_base() {};
+ //!String for the timezone when in daylight savings (eg: EDT)
+ virtual string_type dst_zone_abbrev() const=0;
+ //!String for the zone when not in daylight savings (eg: EST)
+ virtual string_type std_zone_abbrev() const=0;
+ //!String for the timezone when in daylight savings (eg: Eastern Daylight Time)
+ virtual string_type dst_zone_name() const=0;
+ //!String for the zone when not in daylight savings (eg: Eastern Standard Time)
+ virtual string_type std_zone_name() const=0;
+ //! True if zone uses daylight savings adjustments otherwise false
+ virtual bool has_dst() const=0;
+ //! Local time that DST starts -- undefined if has_dst is false
+ virtual time_type dst_local_start_time(year_type y) const=0;
+ //! Local time that DST ends -- undefined if has_dst is false
+ virtual time_type dst_local_end_time(year_type y) const=0;
+ //! Base offset from UTC for zone (eg: -07:30:00)
+ virtual time_duration_type base_utc_offset() const=0;
+ //! Adjustment forward or back made while DST is in effect
+ virtual time_duration_type dst_offset() const=0;
+ //! Returns a POSIX time_zone string for this object
+ virtual string_type to_posix_string() const =0;
+
+ private:
+
+ };
+
+
+ //! Structure which holds the time offsets associated with daylight savings time
+ /*!
+ *@param time_duration_type A type used to represent the offset
+ */
+ template<class time_duration_type>
+ class dst_adjustment_offsets
+ {
+ public:
+ dst_adjustment_offsets(const time_duration_type& dst_adjust,
+ const time_duration_type& dst_start_offset,
+ const time_duration_type& dst_end_offset) :
+ dst_adjust_(dst_adjust),
+ dst_start_offset_(dst_start_offset),
+ dst_end_offset_(dst_end_offset)
+ {}
+
+ //! Amount DST adjusts the clock eg: plus one hour
+ time_duration_type dst_adjust_;
+ //! Time past midnight on start transition day that dst starts
+ time_duration_type dst_start_offset_;
+ //! Time past midnight on end transition day that dst ends
+ time_duration_type dst_end_offset_;
+ };
+
+
+} } //namespace date_time
+
+
+
+#endif
diff --git a/ext/boost/date_time/time_zone_names.hpp b/ext/boost/date_time/time_zone_names.hpp
new file mode 100644
index 0000000000..05260c7162
--- /dev/null
+++ b/ext/boost/date_time/time_zone_names.hpp
@@ -0,0 +1,98 @@
+#ifndef DATE_TIME_TIME_ZONE_NAMES_HPP__
+#define DATE_TIME_TIME_ZONE_NAMES_HPP__
+
+/* Copyright (c) 2002-2003,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
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include <string>
+
+namespace boost {
+namespace date_time {
+
+ template<class CharT>
+ struct default_zone_names {
+ public:
+ typedef CharT char_type;
+ static const char_type standard_name[9];
+ static const char_type standard_abbrev[11];
+ static const char_type non_dst_identifier[7];
+ };
+ template <class CharT>
+ const typename default_zone_names<CharT>::char_type
+ default_zone_names<CharT>::standard_name[9] =
+ {'s','t','d','_','n','a','m','e'};
+
+ template <class CharT>
+ const typename default_zone_names<CharT>::char_type
+ default_zone_names<CharT>::standard_abbrev[11] =
+ {'s','t','d','_','a','b','b','r','e','v'};
+
+ template <class CharT>
+ const typename default_zone_names<CharT>::char_type
+ default_zone_names<CharT>::non_dst_identifier[7] =
+ {'n','o','-','d','s','t'};
+
+ //! Base type that holds various string names for timezone output.
+ /*! Class that holds various types of strings used for timezones.
+ * For example, for the western United States there is the full
+ * name: Pacific Standard Time and the abbreviated name: PST.
+ * During daylight savings there are additional names:
+ * Pacific Daylight Time and PDT.
+ *@parm CharT Allows class to support different character types
+ */
+ template<class CharT>
+ class time_zone_names_base
+ {
+ public:
+ typedef std::basic_string<CharT> string_type;
+ time_zone_names_base() :
+ std_zone_name_(default_zone_names<CharT>::standard_name),
+ std_zone_abbrev_(default_zone_names<CharT>::standard_abbrev),
+ dst_zone_name_(default_zone_names<CharT>::non_dst_identifier),
+ dst_zone_abbrev_(default_zone_names<CharT>::non_dst_identifier)
+ {}
+ time_zone_names_base(const string_type& std_zone_name_str,
+ const string_type& std_zone_abbrev_str,
+ const string_type& dst_zone_name_str,
+ const string_type& dst_zone_abbrev_str) :
+ std_zone_name_(std_zone_name_str),
+ std_zone_abbrev_(std_zone_abbrev_str),
+ dst_zone_name_(dst_zone_name_str),
+ dst_zone_abbrev_(dst_zone_abbrev_str)
+ {}
+ string_type dst_zone_abbrev() const
+ {
+ return dst_zone_abbrev_;
+ }
+ string_type std_zone_abbrev() const
+ {
+ return std_zone_abbrev_;
+ }
+ string_type dst_zone_name() const
+ {
+ return dst_zone_name_;
+ }
+ string_type std_zone_name() const
+ {
+ return std_zone_name_;
+ }
+ private:
+ string_type std_zone_name_;
+ string_type std_zone_abbrev_;
+ string_type dst_zone_name_;
+ string_type dst_zone_abbrev_;
+
+ };
+
+ //! Specialization of timezone names for standard char.
+ //typedef time_zone_names_base<char> time_zone_names;
+
+} } //namespace
+
+
+#endif
diff --git a/ext/boost/date_time/tz_db_base.hpp b/ext/boost/date_time/tz_db_base.hpp
new file mode 100644
index 0000000000..2440115460
--- /dev/null
+++ b/ext/boost/date_time/tz_db_base.hpp
@@ -0,0 +1,378 @@
+#ifndef DATE_TIME_TZ_DB_BASE_HPP__
+#define DATE_TIME_TZ_DB_BASE_HPP__
+
+/* Copyright (c) 2003-2005 CrystalClear Software, Inc.
+ * 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-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <map>
+#include <vector>
+#include <string>
+#include <sstream>
+#include <fstream>
+#include <stdexcept>
+#include <boost/tokenizer.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/time_zone_names.hpp>
+#include <boost/date_time/time_zone_base.hpp>
+#include <boost/date_time/time_parsing.hpp>
+
+namespace boost {
+ namespace date_time {
+
+ //! Exception thrown when tz database cannot locate requested data file
+ class data_not_accessible : public std::logic_error
+ {
+ public:
+ data_not_accessible() :
+ std::logic_error(std::string("Unable to locate or access the required datafile."))
+ {}
+ data_not_accessible(const std::string& filespec) :
+ std::logic_error(std::string("Unable to locate or access the required datafile. Filespec: " + filespec))
+ {}
+ };
+
+ //! Exception thrown when tz database locates incorrect field structure in data file
+ class bad_field_count : public std::out_of_range
+ {
+ public:
+ bad_field_count(const std::string& s) :
+ std::out_of_range(s)
+ {}
+ };
+
+ //! Creates a database of time_zones from csv datafile
+ /*! The csv file containing the zone_specs used by the
+ * tz_db_base is intended to be customized by the
+ * library user. When customizing this file (or creating your own) the
+ * file must follow a specific format.
+ *
+ * This first line is expected to contain column headings and is therefore
+ * not processed by the tz_db_base.
+ *
+ * Each record (line) must have eleven fields. Some of those fields can
+ * be empty. Every field (even empty ones) must be enclosed in
+ * double-quotes.
+ * Ex:
+ * @code
+ * "America/Phoenix" <- string enclosed in quotes
+ * "" <- empty field
+ * @endcode
+ *
+ * Some fields represent a length of time. The format of these fields
+ * must be:
+ * @code
+ * "{+|-}hh:mm[:ss]" <- length-of-time format
+ * @endcode
+ * Where the plus or minus is mandatory and the seconds are optional.
+ *
+ * Since some time zones do not use daylight savings it is not always
+ * necessary for every field in a zone_spec to contain a value. All
+ * zone_specs must have at least ID and GMT offset. Zones that use
+ * daylight savings must have all fields filled except:
+ * STD ABBR, STD NAME, DST NAME. You should take note
+ * that DST ABBR is mandatory for zones that use daylight savings
+ * (see field descriptions for further details).
+ *
+ * ******* Fields and their description/details *********
+ *
+ * ID:
+ * Contains the identifying string for the zone_spec. Any string will
+ * do as long as it's unique. No two ID's can be the same.
+ *
+ * STD ABBR:
+ * STD NAME:
+ * DST ABBR:
+ * DST NAME:
+ * These four are all the names and abbreviations used by the time
+ * zone being described. While any string will do in these fields,
+ * care should be taken. These fields hold the strings that will be
+ * used in the output of many of the local_time classes.
+ * Ex:
+ * @code
+ * time_zone nyc = tz_db.time_zone_from_region("America/New_York");
+ * local_time ny_time(date(2004, Aug, 30), IS_DST, nyc);
+ * cout << ny_time.to_long_string() << endl;
+ * // 2004-Aug-30 00:00:00 Eastern Daylight Time
+ * cout << ny_time.to_short_string() << endl;
+ * // 2004-Aug-30 00:00:00 EDT
+ * @endcode
+ *
+ * NOTE: The exact format/function names may vary - see local_time
+ * documentation for further details.
+ *
+ * GMT offset:
+ * This is the number of hours added to utc to get the local time
+ * before any daylight savings adjustments are made. Some examples
+ * are: America/New_York offset -5 hours, & Africa/Cairo offset +2 hours.
+ * The format must follow the length-of-time format described above.
+ *
+ * DST adjustment:
+ * The amount of time added to gmt_offset when daylight savings is in
+ * effect. The format must follow the length-of-time format described
+ * above.
+ *
+ * DST Start Date rule:
+ * This is a specially formatted string that describes the day of year
+ * in which the transition take place. It holds three fields of it's own,
+ * separated by semicolons.
+ * The first field indicates the "nth" weekday of the month. The possible
+ * values are: 1 (first), 2 (second), 3 (third), 4 (fourth), 5 (fifth),
+ * and -1 (last).
+ * The second field indicates the day-of-week from 0-6 (Sun=0).
+ * The third field indicates the month from 1-12 (Jan=1).
+ *
+ * Examples are: "-1;5;9"="Last Friday of September",
+ * "2;1;3"="Second Monday of March"
+ *
+ * Start time:
+ * Start time is the number of hours past midnight, on the day of the
+ * start transition, the transition takes place. More simply put, the
+ * time of day the transition is made (in 24 hours format). The format
+ * must follow the length-of-time format described above with the
+ * exception that it must always be positive.
+ *
+ * DST End date rule:
+ * See DST Start date rule. The difference here is this is the day
+ * daylight savings ends (transition to STD).
+ *
+ * End time:
+ * Same as Start time.
+ */
+ template<class time_zone_type, class rule_type>
+ class tz_db_base {
+ public:
+ /* Having CharT as a template parameter created problems
+ * with posix_time::duration_from_string. Templatizing
+ * duration_from_string was not possible at this time, however,
+ * it should be possible in the future (when poor compilers get
+ * fixed or stop being used).
+ * Since this class was designed to use CharT as a parameter it
+ * is simply typedef'd here to ease converting in back to a
+ * parameter the future */
+ typedef char char_type;
+
+ typedef typename time_zone_type::base_type time_zone_base_type;
+ typedef typename time_zone_type::time_duration_type time_duration_type;
+ typedef time_zone_names_base<char_type> time_zone_names;
+ typedef boost::date_time::dst_adjustment_offsets<time_duration_type> dst_adjustment_offsets;
+ typedef std::basic_string<char_type> string_type;
+
+ //! Constructs an empty database
+ tz_db_base() {}
+
+ //! Process csv data file, may throw exceptions
+ /*! May throw data_not_accessible, or bad_field_count exceptions */
+ void load_from_file(const std::string& pathspec)
+ {
+ string_type in_str;
+ std::string buff;
+
+ std::ifstream ifs(pathspec.c_str());
+ if(!ifs){
+ boost::throw_exception(data_not_accessible(pathspec));
+ }
+ std::getline(ifs, buff); // first line is column headings
+
+ while( std::getline(ifs, buff)) {
+ parse_string(buff);
+ }
+ }
+
+ //! returns true if record successfully added to map
+ /*! Takes a region name in the form of "America/Phoenix", and a
+ * time_zone object for that region. The id string must be a unique
+ * name that does not already exist in the database. */
+ bool add_record(const string_type& region,
+ boost::shared_ptr<time_zone_base_type> tz)
+ {
+ typename map_type::value_type p(region, tz);
+ return (m_zone_map.insert(p)).second;
+ }
+
+ //! Returns a time_zone object built from the specs for the given region
+ /*! Returns a time_zone object built from the specs for the given
+ * region. If region does not exist a local_time::record_not_found
+ * exception will be thrown */
+ boost::shared_ptr<time_zone_base_type>
+ time_zone_from_region(const string_type& region) const
+ {
+ // get the record
+ typename map_type::const_iterator record = m_zone_map.find(region);
+ if(record == m_zone_map.end()){
+ return boost::shared_ptr<time_zone_base_type>(); //null pointer
+ }
+ return record->second;
+ }
+
+ //! Returns a vector of strings holding the time zone regions in the database
+ std::vector<std::string> region_list() const
+ {
+ typedef std::vector<std::string> vector_type;
+ vector_type regions;
+ typename map_type::const_iterator itr = m_zone_map.begin();
+ while(itr != m_zone_map.end()) {
+ regions.push_back(itr->first);
+ ++itr;
+ }
+ return regions;
+ }
+
+ private:
+ typedef std::map<string_type, boost::shared_ptr<time_zone_base_type> > map_type;
+ map_type m_zone_map;
+
+ // start and end rule are of the same type
+ typedef typename rule_type::start_rule::week_num week_num;
+
+ /* TODO: mechanisms need to be put in place to handle different
+ * types of rule specs. parse_rules() only handles nth_kday
+ * rule types. */
+
+ //! parses rule specs for transition day rules
+ rule_type* parse_rules(const string_type& sr, const string_type& er) const
+ {
+ using namespace gregorian;
+ // start and end rule are of the same type,
+ // both are included here for readability
+ typedef typename rule_type::start_rule start_rule;
+ typedef typename rule_type::end_rule end_rule;
+
+ // these are: [start|end] nth, day, month
+ int s_nth = 0, s_d = 0, s_m = 0;
+ int e_nth = 0, e_d = 0, e_m = 0;
+ split_rule_spec(s_nth, s_d, s_m, sr);
+ split_rule_spec(e_nth, e_d, e_m, er);
+
+ typename start_rule::week_num s_wn, e_wn;
+ s_wn = get_week_num(s_nth);
+ e_wn = get_week_num(e_nth);
+
+
+ return new rule_type(start_rule(s_wn, s_d, s_m),
+ end_rule(e_wn, e_d, e_m));
+ }
+ //! helper function for parse_rules()
+ week_num get_week_num(int nth) const
+ {
+ typedef typename rule_type::start_rule start_rule;
+ switch(nth){
+ case 1:
+ return start_rule::first;
+ case 2:
+ return start_rule::second;
+ case 3:
+ return start_rule::third;
+ case 4:
+ return start_rule::fourth;
+ case 5:
+ case -1:
+ return start_rule::fifth;
+ default:
+ // shouldn't get here - add error handling later
+ break;
+ }
+ return start_rule::fifth; // silence warnings
+ }
+
+ //! splits the [start|end]_date_rule string into 3 ints
+ void split_rule_spec(int& nth, int& d, int& m, string_type rule) const
+ {
+ typedef boost::char_separator<char_type, std::char_traits<char_type> > char_separator_type;
+ typedef boost::tokenizer<char_separator_type,
+ std::basic_string<char_type>::const_iterator,
+ std::basic_string<char_type> > tokenizer;
+ typedef boost::tokenizer<char_separator_type,
+ std::basic_string<char_type>::const_iterator,
+ std::basic_string<char_type> >::iterator tokenizer_iterator;
+
+ const char_type sep_char[] = { ';', '\0'};
+ char_separator_type sep(sep_char);
+ tokenizer tokens(rule, sep); // 3 fields
+
+ tokenizer_iterator tok_iter = tokens.begin();
+ nth = std::atoi(tok_iter->c_str()); ++tok_iter;
+ d = std::atoi(tok_iter->c_str()); ++tok_iter;
+ m = std::atoi(tok_iter->c_str());
+ }
+
+
+ //! Take a line from the csv, turn it into a time_zone_type.
+ /*! Take a line from the csv, turn it into a time_zone_type,
+ * and add it to the map. Zone_specs in csv file are expected to
+ * have eleven fields that describe the time zone. Returns true if
+ * zone_spec successfully added to database */
+ bool parse_string(string_type& s)
+ {
+ std::vector<string_type> result;
+ typedef boost::token_iterator_generator<boost::escaped_list_separator<char_type>, string_type::const_iterator, string_type >::type token_iter_type;
+
+ token_iter_type i = boost::make_token_iterator<string_type>(s.begin(), s.end(),boost::escaped_list_separator<char_type>());
+
+ token_iter_type end;
+ while (i != end) {
+ result.push_back(*i);
+ i++;
+ }
+
+ enum db_fields { ID, STDABBR, STDNAME, DSTABBR, DSTNAME, GMTOFFSET,
+ DSTADJUST, START_DATE_RULE, START_TIME, END_DATE_RULE,
+ END_TIME, FIELD_COUNT };
+
+ //take a shot at fixing gcc 4.x error
+ const unsigned int expected_fields = static_cast<unsigned int>(FIELD_COUNT);
+ if (result.size() != expected_fields) {
+ std::ostringstream msg;
+ msg << "Expecting " << FIELD_COUNT << " fields, got "
+ << result.size() << " fields in line: " << s;
+ boost::throw_exception(bad_field_count(msg.str()));
+ BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return false); // should never reach
+ }
+
+ // initializations
+ bool has_dst = true;
+ if(result[DSTABBR] == std::string()){
+ has_dst = false;
+ }
+
+
+ // start building components of a time_zone
+ time_zone_names names(result[STDNAME], result[STDABBR],
+ result[DSTNAME], result[DSTABBR]);
+
+ time_duration_type utc_offset =
+ str_from_delimited_time_duration<time_duration_type,char_type>(result[GMTOFFSET]);
+
+ dst_adjustment_offsets adjust(time_duration_type(0,0,0),
+ time_duration_type(0,0,0),
+ time_duration_type(0,0,0));
+
+ boost::shared_ptr<rule_type> rules;
+
+ if(has_dst){
+ adjust = dst_adjustment_offsets(
+ str_from_delimited_time_duration<time_duration_type,char_type>(result[DSTADJUST]),
+ str_from_delimited_time_duration<time_duration_type,char_type>(result[START_TIME]),
+ str_from_delimited_time_duration<time_duration_type,char_type>(result[END_TIME])
+ );
+
+ rules =
+ boost::shared_ptr<rule_type>(parse_rules(result[START_DATE_RULE],
+ result[END_DATE_RULE]));
+ }
+ string_type id(result[ID]);
+ boost::shared_ptr<time_zone_base_type> zone(new time_zone_type(names, utc_offset, adjust, rules));
+ return (add_record(id, zone));
+
+ }
+
+ };
+
+} } // namespace
+
+#endif // DATE_TIME_TZ_DB_BASE_HPP__
diff --git a/ext/boost/date_time/wrapping_int.hpp b/ext/boost/date_time/wrapping_int.hpp
new file mode 100644
index 0000000000..969b078ac1
--- /dev/null
+++ b/ext/boost/date_time/wrapping_int.hpp
@@ -0,0 +1,169 @@
+#ifndef _DATE_TIME_WRAPPING_INT_HPP__
+#define _DATE_TIME_WRAPPING_INT_HPP__
+
+/* Copyright (c) 2002,2003,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-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+namespace boost {
+namespace date_time {
+
+//! A wrapping integer used to support time durations (WARNING: only instantiate with a signed type)
+/*! In composite date and time types this type is used to
+ * wrap at the day boundary.
+ * Ex:
+ * A wrapping_int<short, 10> will roll over after nine, and
+ * roll under below zero. This gives a range of [0,9]
+ *
+ * NOTE: it is strongly recommended that wrapping_int2 be used
+ * instead of wrapping_int as wrapping_int is to be depricated
+ * at some point soon.
+ *
+ * Also Note that warnings will occur if instantiated with an
+ * unsigned type. Only a signed type should be used!
+ */
+template<typename int_type_, int_type_ wrap_val>
+class wrapping_int {
+public:
+ typedef int_type_ int_type;
+ //typedef overflow_type_ overflow_type;
+ static int_type wrap_value() {return wrap_val;}
+ //!Add, return true if wrapped
+ wrapping_int(int_type v) : value_(v) {};
+ //! Explicit converion method
+ int_type as_int() const {return value_;}
+ operator int_type() const {return value_;}
+ //!Add, return number of wraps performed
+ /*! The sign of the returned value will indicate which direction the
+ * wraps went. Ex: add a negative number and wrapping under could occur,
+ * this would be indicated by a negative return value. If wrapping over
+ * took place, a positive value would be returned */
+ template< typename IntT >
+ IntT add(IntT v)
+ {
+ int_type remainder = static_cast<int_type>(v % (wrap_val));
+ IntT overflow = static_cast<IntT>(v / (wrap_val));
+ value_ = static_cast<int_type>(value_ + remainder);
+ return calculate_wrap(overflow);
+ }
+ //! Subtract will return '+d' if wrapping under took place ('d' is the number of wraps)
+ /*! The sign of the returned value will indicate which direction the
+ * wraps went (positive indicates wrap under, negative indicates wrap over).
+ * Ex: subtract a negative number and wrapping over could
+ * occur, this would be indicated by a negative return value. If
+ * wrapping under took place, a positive value would be returned. */
+ template< typename IntT >
+ IntT subtract(IntT v)
+ {
+ int_type remainder = static_cast<int_type>(v % (wrap_val));
+ IntT underflow = static_cast<IntT>(-(v / (wrap_val)));
+ value_ = static_cast<int_type>(value_ - remainder);
+ return calculate_wrap(underflow) * -1;
+ }
+private:
+ int_type value_;
+
+ template< typename IntT >
+ IntT calculate_wrap(IntT wrap)
+ {
+ if ((value_) >= wrap_val)
+ {
+ ++wrap;
+ value_ -= (wrap_val);
+ }
+ else if(value_ < 0)
+ {
+ --wrap;
+ value_ += (wrap_val);
+ }
+ return wrap;
+ }
+
+};
+
+
+//! A wrapping integer used to wrap around at the top (WARNING: only instantiate with a signed type)
+/*! Bad name, quick impl to fix a bug -- fix later!!
+ * This allows the wrap to restart at a value other than 0.
+ */
+template<typename int_type_, int_type_ wrap_min, int_type_ wrap_max>
+class wrapping_int2 {
+public:
+ typedef int_type_ int_type;
+ static int_type wrap_value() {return wrap_max;}
+ static int_type min_value() {return wrap_min;}
+ /*! If initializing value is out of range of [wrap_min, wrap_max],
+ * value will be initialized to closest of min or max */
+ wrapping_int2(int_type v) : value_(v) {
+ if(value_ < wrap_min)
+ {
+ value_ = wrap_min;
+ }
+ if(value_ > wrap_max)
+ {
+ value_ = wrap_max;
+ }
+ }
+ //! Explicit converion method
+ int_type as_int() const {return value_;}
+ operator int_type() const {return value_;}
+ //!Add, return number of wraps performed
+ /*! The sign of the returned value will indicate which direction the
+ * wraps went. Ex: add a negative number and wrapping under could occur,
+ * this would be indicated by a negative return value. If wrapping over
+ * took place, a positive value would be returned */
+ template< typename IntT >
+ IntT add(IntT v)
+ {
+ int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
+ IntT overflow = static_cast<IntT>(v / (wrap_max - wrap_min + 1));
+ value_ = static_cast<int_type>(value_ + remainder);
+ return calculate_wrap(overflow);
+ }
+ //! Subtract will return '-d' if wrapping under took place ('d' is the number of wraps)
+ /*! The sign of the returned value will indicate which direction the
+ * wraps went. Ex: subtract a negative number and wrapping over could
+ * occur, this would be indicated by a positive return value. If
+ * wrapping under took place, a negative value would be returned */
+ template< typename IntT >
+ IntT subtract(IntT v)
+ {
+ int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
+ IntT underflow = static_cast<IntT>(-(v / (wrap_max - wrap_min + 1)));
+ value_ = static_cast<int_type>(value_ - remainder);
+ return calculate_wrap(underflow);
+ }
+
+private:
+ int_type value_;
+
+ template< typename IntT >
+ IntT calculate_wrap(IntT wrap)
+ {
+ if ((value_) > wrap_max)
+ {
+ ++wrap;
+ value_ -= (wrap_max - wrap_min + 1);
+ }
+ else if((value_) < wrap_min)
+ {
+ --wrap;
+ value_ += (wrap_max - wrap_min + 1);
+ }
+ return wrap;
+ }
+};
+
+
+
+} } //namespace date_time
+
+
+
+#endif
+
diff --git a/ext/boost/date_time/year_month_day.hpp b/ext/boost/date_time/year_month_day.hpp
new file mode 100644
index 0000000000..802ce42eb9
--- /dev/null
+++ b/ext/boost/date_time/year_month_day.hpp
@@ -0,0 +1,45 @@
+#ifndef YearMonthDayBase_HPP__
+#define YearMonthDayBase_HPP__
+
+/* 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) $
+ */
+
+namespace boost {
+namespace date_time {
+
+ //! Allow rapid creation of ymd triples of different types
+ template<typename YearType, typename MonthType, typename DayType>
+ struct year_month_day_base {
+ year_month_day_base(YearType year,
+ MonthType month,
+ DayType day);
+ YearType year;
+ MonthType month;
+ DayType day;
+ typedef YearType year_type;
+ typedef MonthType month_type;
+ typedef DayType day_type;
+ };
+
+
+ //! A basic constructor
+ template<typename YearType, typename MonthType, typename DayType>
+ inline
+ year_month_day_base<YearType,MonthType,DayType>::year_month_day_base(YearType y,
+ MonthType m,
+ DayType d) :
+ year(y),
+ month(m),
+ day(d)
+ {}
+
+} }//namespace date_time
+
+
+#endif
+
diff --git a/ext/boost/functional/detail/container_fwd.hpp b/ext/boost/functional/detail/container_fwd.hpp
new file mode 100644
index 0000000000..9a69d155b2
--- /dev/null
+++ b/ext/boost/functional/detail/container_fwd.hpp
@@ -0,0 +1,19 @@
+
+// Copyright 2005-2008 Daniel James.
+// 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)
+
+// Forwarding header for container_fwd.hpp's new location.
+// This header is deprecated, I'll be adding a warning in a future release,
+// then converting it to an error and finally removing this header completely.
+
+#if !defined(BOOST_FUNCTIONAL_DETAIL_CONTAINER_FWD_HPP)
+#define BOOST_FUNCTIONAL_DETAIL_CONTAINER_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/detail/container_fwd.hpp>
+
+#endif
diff --git a/ext/boost/functional/hash.hpp b/ext/boost/functional/hash.hpp
new file mode 100644
index 0000000000..44983f19b2
--- /dev/null
+++ b/ext/boost/functional/hash.hpp
@@ -0,0 +1,7 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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/functional/hash/hash.hpp>
+
diff --git a/ext/boost/functional/hash/detail/float_functions.hpp b/ext/boost/functional/hash/detail/float_functions.hpp
new file mode 100644
index 0000000000..01cac09722
--- /dev/null
+++ b/ext/boost/functional/hash/detail/float_functions.hpp
@@ -0,0 +1,246 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP)
+#define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP
+
+#include <boost/config.hpp>
+#include <boost/config/no_tr1/cmath.hpp>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// The C++ standard requires that the C float functions are overloarded
+// for float, double and long double in the std namespace, but some of the older
+// library implementations don't support this. On some that don't, the C99
+// float functions (frexpf, frexpl, etc.) are available.
+//
+// The following tries to automatically detect which are available.
+
+namespace boost {
+ namespace hash_detail {
+
+ // Returned by dummy versions of the float functions.
+
+ struct not_found {
+ // Implicitly convertible to float and long double in order to avoid
+ // a compile error when the dummy float functions are used.
+
+ inline operator float() const { return 0; }
+ inline operator long double() const { return 0; }
+ };
+
+ // A type for detecting the return type of functions.
+
+ template <typename T> struct is;
+ template <> struct is<float> { char x[10]; };
+ template <> struct is<double> { char x[20]; };
+ template <> struct is<long double> { char x[30]; };
+ template <> struct is<boost::hash_detail::not_found> { char x[40]; };
+
+ // Used to convert the return type of a function to a type for sizeof.
+
+ template <typename T> is<T> float_type(T);
+
+ // call_ldexp
+ //
+ // This will get specialized for float and long double
+
+ template <typename Float> struct call_ldexp
+ {
+ typedef double float_type;
+
+ inline double operator()(double a, int b) const
+ {
+ using namespace std;
+ return ldexp(a, b);
+ }
+ };
+
+ // call_frexp
+ //
+ // This will get specialized for float and long double
+
+ template <typename Float> struct call_frexp
+ {
+ typedef double float_type;
+
+ inline double operator()(double a, int* b) const
+ {
+ using namespace std;
+ return frexp(a, b);
+ }
+ };
+ }
+}
+
+// A namespace for dummy functions to detect when the actual function we want
+// isn't available. ldexpl, ldexpf etc. might be added tby the macros below.
+//
+// AFAICT these have to be outside of the boost namespace, as if they're in
+// the boost namespace they'll always be preferable to any other function
+// (since the arguments are built in types, ADL can't be used).
+
+namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS {
+ template <class Float> boost::hash_detail::not_found ldexp(Float, int);
+ template <class Float> boost::hash_detail::not_found frexp(Float, int*);
+}
+
+// Macros for generating specializations of call_ldexp and call_frexp.
+//
+// check_cpp and check_c99 check if the C++ or C99 functions are available.
+//
+// Then the call_* functions select an appropriate implementation.
+//
+// I used c99_func in a few places just to get a unique name.
+//
+// Important: when using 'using namespace' at namespace level, include as
+// little as possible in that namespace, as Visual C++ has an odd bug which
+// can cause the namespace to be imported at the global level. This seems to
+// happen mainly when there's a template in the same namesapce.
+
+#define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \
+namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { \
+ template <class Float> \
+ boost::hash_detail::not_found c99_func(Float, type2); \
+} \
+ \
+namespace boost { \
+ namespace hash_detail { \
+ namespace c99_func##_detect { \
+ using namespace std; \
+ using namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS; \
+ \
+ struct check { \
+ static type1 x; \
+ static type2 y; \
+ BOOST_STATIC_CONSTANT(bool, cpp = \
+ sizeof(float_type(cpp_func(x,y))) \
+ == sizeof(is<type1>)); \
+ BOOST_STATIC_CONSTANT(bool, c99 = \
+ sizeof(float_type(c99_func(x,y))) \
+ == sizeof(is<type1>)); \
+ }; \
+ } \
+ \
+ template <bool x> \
+ struct call_c99_##c99_func : \
+ boost::hash_detail::call_##cpp_func<double> {}; \
+ \
+ template <> \
+ struct call_c99_##c99_func<true> { \
+ typedef type1 float_type; \
+ \
+ template <typename T> \
+ inline type1 operator()(type1 a, T b) const \
+ { \
+ using namespace std; \
+ return c99_func(a, b); \
+ } \
+ }; \
+ \
+ template <bool x> \
+ struct call_cpp_##c99_func : \
+ call_c99_##c99_func< \
+ ::boost::hash_detail::c99_func##_detect::check::c99 \
+ > {}; \
+ \
+ template <> \
+ struct call_cpp_##c99_func<true> { \
+ typedef type1 float_type; \
+ \
+ template <typename T> \
+ inline type1 operator()(type1 a, T b) const \
+ { \
+ using namespace std; \
+ return cpp_func(a, b); \
+ } \
+ }; \
+ \
+ template <> \
+ struct call_##cpp_func<type1> : \
+ call_cpp_##c99_func< \
+ ::boost::hash_detail::c99_func##_detect::check::cpp \
+ > {}; \
+ } \
+}
+
+#define BOOST_HASH_CALL_FLOAT_MACRO(cpp_func, c99_func, type1, type2) \
+namespace boost { \
+ namespace hash_detail { \
+ \
+ template <> \
+ struct call_##cpp_func<type1> { \
+ typedef type1 float_type; \
+ inline type1 operator()(type1 x, type2 y) const { \
+ return c99_func(x, y); \
+ } \
+ }; \
+ } \
+}
+
+#if defined(ldexpf)
+BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpf, float, int)
+#else
+BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpf, float, int)
+#endif
+
+#if defined(ldexpl)
+BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpl, long double, int)
+#else
+BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpl, long double, int)
+#endif
+
+#if defined(frexpf)
+BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpf, float, int*)
+#else
+BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpf, float, int*)
+#endif
+
+#if defined(frexpl)
+BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpl, long double, int*)
+#else
+BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpl, long double, int*)
+#endif
+
+#undef BOOST_HASH_CALL_FLOAT_MACRO
+#undef BOOST_HASH_CALL_FLOAT_FUNC
+
+
+namespace boost
+{
+ namespace hash_detail
+ {
+ template <typename Float1, typename Float2>
+ struct select_hash_type_impl {
+ typedef double type;
+ };
+
+ template <>
+ struct select_hash_type_impl<float, float> {
+ typedef float type;
+ };
+
+ template <>
+ struct select_hash_type_impl<long double, long double> {
+ typedef long double type;
+ };
+
+
+ // select_hash_type
+ //
+ // If there is support for a particular floating point type, use that
+ // otherwise use double (there's always support for double).
+
+ template <typename Float>
+ struct select_hash_type : select_hash_type_impl<
+ BOOST_DEDUCED_TYPENAME call_ldexp<Float>::float_type,
+ BOOST_DEDUCED_TYPENAME call_frexp<Float>::float_type
+ > {};
+ }
+}
+
+#endif
diff --git a/ext/boost/functional/hash/detail/hash_float.hpp b/ext/boost/functional/hash/detail/hash_float.hpp
new file mode 100644
index 0000000000..ea1bc25f48
--- /dev/null
+++ b/ext/boost/functional/hash/detail/hash_float.hpp
@@ -0,0 +1,101 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER)
+#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/config.hpp>
+#include <boost/functional/hash/detail/float_functions.hpp>
+#include <boost/functional/hash/detail/limits.hpp>
+#include <boost/integer/static_log2.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/assert.hpp>
+
+// Include hash implementation for the current platform.
+
+// Cygwn
+#if defined(__CYGWIN__)
+# if defined(__i386__) || defined(_M_IX86)
+# include <boost/functional/hash/detail/hash_float_x86.hpp>
+# else
+# include <boost/functional/hash/detail/hash_float_generic.hpp>
+# endif
+#else
+# include <boost/functional/hash/detail/hash_float_generic.hpp>
+#endif
+
+// Can we use fpclassify?
+
+// STLport
+#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
+#define BOOST_HASH_USE_FPCLASSIFY 0
+
+// GNU libstdc++ 3
+#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
+# if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
+ !(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
+# define BOOST_HASH_USE_FPCLASSIFY 1
+# else
+# define BOOST_HASH_USE_FPCLASSIFY 0
+# endif
+
+// Everything else
+#else
+# define BOOST_HASH_USE_FPCLASSIFY 0
+#endif
+
+#if BOOST_HASH_USE_FPCLASSIFY
+
+#include <boost/config/no_tr1/cmath.hpp>
+
+namespace boost
+{
+ namespace hash_detail
+ {
+ template <class T>
+ inline std::size_t float_hash_value(T v)
+ {
+ using namespace std;
+ switch (fpclassify(v)) {
+ case FP_ZERO:
+ return 0;
+ case FP_INFINITE:
+ return (std::size_t)(v > 0 ? -1 : -2);
+ case FP_NAN:
+ return (std::size_t)(-3);
+ case FP_NORMAL:
+ case FP_SUBNORMAL:
+ return float_hash_impl(v);
+ default:
+ BOOST_ASSERT(0);
+ return 0;
+ }
+ }
+ }
+}
+
+#else // !BOOST_HASH_USE_FPCLASSIFY
+
+namespace boost
+{
+ namespace hash_detail
+ {
+ template <class T>
+ inline std::size_t float_hash_value(T v)
+ {
+ return v == 0 ? 0 : float_hash_impl(v);
+ }
+ }
+}
+
+#endif // BOOST_HASH_USE_FPCLASSIFY
+
+#undef BOOST_HASH_USE_FPCLASSIFY
+
+#endif
diff --git a/ext/boost/functional/hash/detail/hash_float_generic.hpp b/ext/boost/functional/hash/detail/hash_float_generic.hpp
new file mode 100644
index 0000000000..f9acee9cd1
--- /dev/null
+++ b/ext/boost/functional/hash/detail/hash_float_generic.hpp
@@ -0,0 +1,93 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+// A general purpose hash function for non-zero floating point values.
+
+#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER)
+#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER
+
+#include <boost/functional/hash/detail/float_functions.hpp>
+#include <boost/integer/static_log2.hpp>
+#include <boost/functional/hash/detail/limits.hpp>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+#if BOOST_MSVC >= 1400
+#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
+ // not satisfy test. Loop body not executed
+#endif
+#endif
+
+namespace boost
+{
+ namespace hash_detail
+ {
+ inline void hash_float_combine(std::size_t& seed, std::size_t value)
+ {
+ seed ^= value + (seed<<6) + (seed>>2);
+ }
+
+ template <class T>
+ inline std::size_t float_hash_impl2(T v)
+ {
+ boost::hash_detail::call_frexp<T> frexp;
+ boost::hash_detail::call_ldexp<T> ldexp;
+
+ int exp = 0;
+
+ v = frexp(v, &exp);
+
+ // A postive value is easier to hash, so combine the
+ // sign with the exponent and use the absolute value.
+ if(v < 0) {
+ v = -v;
+ exp += limits<T>::max_exponent -
+ limits<T>::min_exponent;
+ }
+
+ // The result of frexp is always between 0.5 and 1, so its
+ // top bit will always be 1. Subtract by 0.5 to remove that.
+ v -= T(0.5);
+ v = ldexp(v, limits<std::size_t>::digits + 1);
+ std::size_t seed = static_cast<std::size_t>(v);
+ v -= seed;
+
+ // ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
+ std::size_t const length
+ = (limits<T>::digits *
+ boost::static_log2<limits<T>::radix>::value - 1)
+ / limits<std::size_t>::digits;
+
+ for(std::size_t i = 0; i != length; ++i)
+ {
+ v = ldexp(v, limits<std::size_t>::digits);
+ std::size_t part = static_cast<std::size_t>(v);
+ v -= part;
+ hash_float_combine(seed, part);
+ }
+
+ hash_float_combine(seed, exp);
+
+ return seed;
+ }
+
+ template <class T>
+ inline std::size_t float_hash_impl(T v)
+ {
+ typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
+ return float_hash_impl2(static_cast<type>(v));
+ }
+ }
+}
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/ext/boost/functional/hash/detail/hash_float_x86.hpp b/ext/boost/functional/hash/detail/hash_float_x86.hpp
new file mode 100644
index 0000000000..b39bb0d081
--- /dev/null
+++ b/ext/boost/functional/hash/detail/hash_float_x86.hpp
@@ -0,0 +1,56 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+// A non-portable hash function form non-zero floats on x86.
+//
+// Even if you're on an x86 platform, this might not work if their floating
+// point isn't set up as this expects. So this should only be used if it's
+// absolutely certain that it will work.
+
+#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_X86_HEADER)
+#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_X86_HEADER
+
+#include <boost/cstdint.hpp>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+namespace boost
+{
+ namespace hash_detail
+ {
+ inline void hash_float_combine(std::size_t& seed, std::size_t value)
+ {
+ seed ^= value + (seed<<6) + (seed>>2);
+ }
+
+ inline std::size_t float_hash_impl(float v)
+ {
+ boost::uint32_t* ptr = (boost::uint32_t*)&v;
+ std::size_t seed = *ptr;
+ return seed;
+ }
+
+ inline std::size_t float_hash_impl(double v)
+ {
+ boost::uint32_t* ptr = (boost::uint32_t*)&v;
+ std::size_t seed = *ptr++;
+ hash_float_combine(seed, *ptr);
+ return seed;
+ }
+
+ inline std::size_t float_hash_impl(long double v)
+ {
+ boost::uint32_t* ptr = (boost::uint32_t*)&v;
+ std::size_t seed = *ptr++;
+ hash_float_combine(seed, *ptr++);
+ hash_float_combine(seed, *(boost::uint16_t*)ptr);
+ return seed;
+ }
+ }
+}
+
+#endif
diff --git a/ext/boost/functional/hash/detail/limits.hpp b/ext/boost/functional/hash/detail/limits.hpp
new file mode 100644
index 0000000000..f5b520ea9d
--- /dev/null
+++ b/ext/boost/functional/hash/detail/limits.hpp
@@ -0,0 +1,61 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+//
+// On some platforms std::limits gives incorrect values for long double.
+// This tries to work around them.
+
+#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER)
+#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/limits.hpp>
+
+// On OpenBSD, numeric_limits is not reliable for long doubles, but
+// the macros defined in <float.h> are and support long double when STLport
+// doesn't.
+
+#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
+#include <float.h>
+#endif
+
+namespace boost
+{
+ namespace hash_detail
+ {
+ template <class T>
+ struct limits : std::numeric_limits<T> {};
+
+#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
+ template <>
+ struct limits<long double>
+ : std::numeric_limits<long double>
+ {
+ static long double epsilon() {
+ return LDBL_EPSILON;
+ }
+
+ static long double (max)() {
+ return LDBL_MAX;
+ }
+
+ static long double (min)() {
+ return LDBL_MIN;
+ }
+
+ BOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG);
+ BOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP);
+ BOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP);
+#if defined(_STLP_NO_LONG_DOUBLE)
+ BOOST_STATIC_CONSTANT(int, radix = FLT_RADIX);
+#endif
+ };
+#endif // __OpenBSD__
+ }
+}
+
+#endif
diff --git a/ext/boost/functional/hash/extensions.hpp b/ext/boost/functional/hash/extensions.hpp
new file mode 100644
index 0000000000..3c587a3bf5
--- /dev/null
+++ b/ext/boost/functional/hash/extensions.hpp
@@ -0,0 +1,286 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+// Based on Peter Dimov's proposal
+// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
+// issue 6.18.
+
+// This implements the extensions to the standard.
+// It's undocumented, so you shouldn't use it....
+
+#if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
+#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
+
+#include <boost/functional/hash/hash.hpp>
+#include <boost/detail/container_fwd.hpp>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+#include <boost/type_traits/is_array.hpp>
+#endif
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+#include <boost/type_traits/is_const.hpp>
+#endif
+
+namespace boost
+{
+ template <class A, class B>
+ std::size_t hash_value(std::pair<A, B> const&);
+ template <class T, class A>
+ std::size_t hash_value(std::vector<T, A> const&);
+ template <class T, class A>
+ std::size_t hash_value(std::list<T, A> const& v);
+ template <class T, class A>
+ std::size_t hash_value(std::deque<T, A> const& v);
+ template <class K, class C, class A>
+ std::size_t hash_value(std::set<K, C, A> const& v);
+ template <class K, class C, class A>
+ std::size_t hash_value(std::multiset<K, C, A> const& v);
+ template <class K, class T, class C, class A>
+ std::size_t hash_value(std::map<K, T, C, A> const& v);
+ template <class K, class T, class C, class A>
+ std::size_t hash_value(std::multimap<K, T, C, A> const& v);
+
+ template <class T>
+ std::size_t hash_value(std::complex<T> const&);
+
+ template <class A, class B>
+ std::size_t hash_value(std::pair<A, B> const& v)
+ {
+ std::size_t seed = 0;
+ hash_combine(seed, v.first);
+ hash_combine(seed, v.second);
+ return seed;
+ }
+
+ template <class T, class A>
+ std::size_t hash_value(std::vector<T, A> const& v)
+ {
+ return hash_range(v.begin(), v.end());
+ }
+
+ template <class T, class A>
+ std::size_t hash_value(std::list<T, A> const& v)
+ {
+ return hash_range(v.begin(), v.end());
+ }
+
+ template <class T, class A>
+ std::size_t hash_value(std::deque<T, A> const& v)
+ {
+ return hash_range(v.begin(), v.end());
+ }
+
+ template <class K, class C, class A>
+ std::size_t hash_value(std::set<K, C, A> const& v)
+ {
+ return hash_range(v.begin(), v.end());
+ }
+
+ template <class K, class C, class A>
+ std::size_t hash_value(std::multiset<K, C, A> const& v)
+ {
+ return hash_range(v.begin(), v.end());
+ }
+
+ template <class K, class T, class C, class A>
+ std::size_t hash_value(std::map<K, T, C, A> const& v)
+ {
+ return hash_range(v.begin(), v.end());
+ }
+
+ template <class K, class T, class C, class A>
+ std::size_t hash_value(std::multimap<K, T, C, A> const& v)
+ {
+ return hash_range(v.begin(), v.end());
+ }
+
+ template <class T>
+ std::size_t hash_value(std::complex<T> const& v)
+ {
+ boost::hash<T> hasher;
+ std::size_t seed = hasher(v.imag());
+ seed ^= hasher(v.real()) + (seed<<6) + (seed>>2);
+ return seed;
+ }
+
+ //
+ // call_hash_impl
+ //
+
+ // On compilers without function template ordering, this deals with arrays.
+
+#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+ namespace hash_detail
+ {
+ template <bool IsArray>
+ struct call_hash_impl
+ {
+ template <class T>
+ struct inner
+ {
+ static std::size_t call(T const& v)
+ {
+ using namespace boost;
+ return hash_value(v);
+ }
+ };
+ };
+
+ template <>
+ struct call_hash_impl<true>
+ {
+ template <class Array>
+ struct inner
+ {
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+ static std::size_t call(Array const& v)
+#else
+ static std::size_t call(Array& v)
+#endif
+ {
+ const int size = sizeof(v) / sizeof(*v);
+ return boost::hash_range(v, v + size);
+ }
+ };
+ };
+
+ template <class T>
+ struct call_hash
+ : public call_hash_impl<boost::is_array<T>::value>
+ ::BOOST_NESTED_TEMPLATE inner<T>
+ {
+ };
+ }
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ //
+ // boost::hash
+ //
+
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+ template <class T> struct hash
+ : std::unary_function<T, std::size_t>
+ {
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+ std::size_t operator()(T const& val) const
+ {
+ return hash_value(val);
+ }
+#else
+ std::size_t operator()(T const& val) const
+ {
+ return hash_detail::call_hash<T>::call(val);
+ }
+#endif
+ };
+
+#if BOOST_WORKAROUND(__DMC__, <= 0x848)
+ template <class T, unsigned int n> struct hash<T[n]>
+ : std::unary_function<T[n], std::size_t>
+ {
+ std::size_t operator()(const T* val) const
+ {
+ return boost::hash_range(val, val+n);
+ }
+ };
+#endif
+
+#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+ // On compilers without partial specialization, boost::hash<T>
+ // has already been declared to deal with pointers, so just
+ // need to supply the non-pointer version of hash_impl.
+
+ namespace hash_detail
+ {
+ template <bool IsPointer>
+ struct hash_impl;
+
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+
+ template <>
+ struct hash_impl<false>
+ {
+ template <class T>
+ struct inner
+ : std::unary_function<T, std::size_t>
+ {
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+ std::size_t operator()(T const& val) const
+ {
+ return hash_value(val);
+ }
+#else
+ std::size_t operator()(T const& val) const
+ {
+ return hash_detail::call_hash<T>::call(val);
+ }
+#endif
+ };
+ };
+
+#else // Visual C++ 6.5
+
+ // Visual C++ 6.5 has problems with nested member functions and
+ // applying const to const types in templates. So we get this:
+
+ template <bool IsConst>
+ struct hash_impl_msvc
+ {
+ template <class T>
+ struct inner
+ : public std::unary_function<T, std::size_t>
+ {
+ std::size_t operator()(T const& val) const
+ {
+ return hash_detail::call_hash<T const>::call(val);
+ }
+
+ std::size_t operator()(T& val) const
+ {
+ return hash_detail::call_hash<T>::call(val);
+ }
+ };
+ };
+
+ template <>
+ struct hash_impl_msvc<true>
+ {
+ template <class T>
+ struct inner
+ : public std::unary_function<T, std::size_t>
+ {
+ std::size_t operator()(T& val) const
+ {
+ return hash_detail::call_hash<T>::call(val);
+ }
+ };
+ };
+
+ template <class T>
+ struct hash_impl_msvc2
+ : public hash_impl_msvc<boost::is_const<T>::value>
+ ::BOOST_NESTED_TEMPLATE inner<T> {};
+
+ template <>
+ struct hash_impl<false>
+ {
+ template <class T>
+ struct inner : public hash_impl_msvc2<T> {};
+ };
+
+#endif // Visual C++ 6.5
+ }
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+}
+
+#endif
diff --git a/ext/boost/functional/hash/hash.hpp b/ext/boost/functional/hash/hash.hpp
new file mode 100644
index 0000000000..6784f3ef6b
--- /dev/null
+++ b/ext/boost/functional/hash/hash.hpp
@@ -0,0 +1,478 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+// Based on Peter Dimov's proposal
+// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
+// issue 6.18.
+
+#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
+#define BOOST_FUNCTIONAL_HASH_HASH_HPP
+
+#include <boost/functional/hash/hash_fwd.hpp>
+#include <functional>
+#include <boost/functional/hash/detail/hash_float.hpp>
+#include <string>
+#include <boost/limits.hpp>
+
+#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+#include <boost/type_traits/is_pointer.hpp>
+#endif
+
+#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
+#define BOOST_HASH_CHAR_TRAITS string_char_traits
+#else
+#define BOOST_HASH_CHAR_TRAITS char_traits
+#endif
+
+namespace boost
+{
+ std::size_t hash_value(bool);
+ std::size_t hash_value(char);
+ std::size_t hash_value(unsigned char);
+ std::size_t hash_value(signed char);
+ std::size_t hash_value(short);
+ std::size_t hash_value(unsigned short);
+ std::size_t hash_value(int);
+ std::size_t hash_value(unsigned int);
+ std::size_t hash_value(long);
+ std::size_t hash_value(unsigned long);
+
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+ std::size_t hash_value(wchar_t);
+#endif
+
+#if defined(BOOST_HAS_LONG_LONG)
+ std::size_t hash_value(boost::long_long_type);
+ std::size_t hash_value(boost::ulong_long_type);
+#endif
+
+#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
+ template <class T> std::size_t hash_value(T* const&);
+#else
+ template <class T> std::size_t hash_value(T*);
+#endif
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+ template< class T, unsigned N >
+ std::size_t hash_value(const T (&x)[N]);
+
+ template< class T, unsigned N >
+ std::size_t hash_value(T (&x)[N]);
+#endif
+
+ std::size_t hash_value(float v);
+ std::size_t hash_value(double v);
+ std::size_t hash_value(long double v);
+
+ template <class Ch, class A>
+ std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
+
+ // Implementation
+
+ namespace hash_detail
+ {
+ template <class T>
+ inline std::size_t hash_value_signed(T val)
+ {
+ const int size_t_bits = std::numeric_limits<std::size_t>::digits;
+ // ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
+ const int length = (std::numeric_limits<T>::digits - 1)
+ / size_t_bits;
+
+ std::size_t seed = 0;
+ T positive = val < 0 ? -1 - val : val;
+
+ // Hopefully, this loop can be unrolled.
+ for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
+ {
+ seed ^= (std::size_t) (positive >> i) + (seed<<6) + (seed>>2);
+ }
+ seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
+
+ return seed;
+ }
+
+ template <class T>
+ inline std::size_t hash_value_unsigned(T val)
+ {
+ const int size_t_bits = std::numeric_limits<std::size_t>::digits;
+ // ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
+ const int length = (std::numeric_limits<T>::digits - 1)
+ / size_t_bits;
+
+ std::size_t seed = 0;
+
+ // Hopefully, this loop can be unrolled.
+ for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
+ {
+ seed ^= (std::size_t) (val >> i) + (seed<<6) + (seed>>2);
+ }
+ seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
+
+ return seed;
+ }
+ }
+
+ inline std::size_t hash_value(bool v)
+ {
+ return static_cast<std::size_t>(v);
+ }
+
+ inline std::size_t hash_value(char v)
+ {
+ return static_cast<std::size_t>(v);
+ }
+
+ inline std::size_t hash_value(unsigned char v)
+ {
+ return static_cast<std::size_t>(v);
+ }
+
+ inline std::size_t hash_value(signed char v)
+ {
+ return static_cast<std::size_t>(v);
+ }
+
+ inline std::size_t hash_value(short v)
+ {
+ return static_cast<std::size_t>(v);
+ }
+
+ inline std::size_t hash_value(unsigned short v)
+ {
+ return static_cast<std::size_t>(v);
+ }
+
+ inline std::size_t hash_value(int v)
+ {
+ return static_cast<std::size_t>(v);
+ }
+
+ inline std::size_t hash_value(unsigned int v)
+ {
+ return static_cast<std::size_t>(v);
+ }
+
+ inline std::size_t hash_value(long v)
+ {
+ return static_cast<std::size_t>(v);
+ }
+
+ inline std::size_t hash_value(unsigned long v)
+ {
+ return static_cast<std::size_t>(v);
+ }
+
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+ inline std::size_t hash_value(wchar_t v)
+ {
+ return static_cast<std::size_t>(v);
+ }
+#endif
+
+#if defined(BOOST_HAS_LONG_LONG)
+ inline std::size_t hash_value(boost::long_long_type v)
+ {
+ return hash_detail::hash_value_signed(v);
+ }
+
+ inline std::size_t hash_value(boost::ulong_long_type v)
+ {
+ return hash_detail::hash_value_unsigned(v);
+ }
+#endif
+
+ // Implementation by Alberto Barbati and Dave Harris.
+#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
+ template <class T> std::size_t hash_value(T* const& v)
+#else
+ template <class T> std::size_t hash_value(T* v)
+#endif
+ {
+ std::size_t x = static_cast<std::size_t>(
+ reinterpret_cast<std::ptrdiff_t>(v));
+
+ return x + (x >> 3);
+ }
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+ template <class T>
+ inline void hash_combine(std::size_t& seed, T& v)
+#else
+ template <class T>
+ inline void hash_combine(std::size_t& seed, T const& v)
+#endif
+ {
+ boost::hash<T> hasher;
+ seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
+ }
+
+ template <class It>
+ inline std::size_t hash_range(It first, It last)
+ {
+ std::size_t seed = 0;
+
+ for(; first != last; ++first)
+ {
+ hash_combine(seed, *first);
+ }
+
+ return seed;
+ }
+
+ template <class It>
+ inline void hash_range(std::size_t& seed, It first, It last)
+ {
+ for(; first != last; ++first)
+ {
+ hash_combine(seed, *first);
+ }
+ }
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
+ template <class T>
+ inline std::size_t hash_range(T* first, T* last)
+ {
+ std::size_t seed = 0;
+
+ for(; first != last; ++first)
+ {
+ boost::hash<T> hasher;
+ seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
+ }
+
+ return seed;
+ }
+
+ template <class T>
+ inline void hash_range(std::size_t& seed, T* first, T* last)
+ {
+ for(; first != last; ++first)
+ {
+ boost::hash<T> hasher;
+ seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
+ }
+ }
+#endif
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+ template< class T, unsigned N >
+ inline std::size_t hash_value(const T (&x)[N])
+ {
+ return hash_range(x, x + N);
+ }
+
+ template< class T, unsigned N >
+ inline std::size_t hash_value(T (&x)[N])
+ {
+ return hash_range(x, x + N);
+ }
+#endif
+
+ template <class Ch, class A>
+ inline std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
+ {
+ return hash_range(v.begin(), v.end());
+ }
+
+ inline std::size_t hash_value(float v)
+ {
+ return boost::hash_detail::float_hash_value(v);
+ }
+
+ inline std::size_t hash_value(double v)
+ {
+ return boost::hash_detail::float_hash_value(v);
+ }
+
+ inline std::size_t hash_value(long double v)
+ {
+ return boost::hash_detail::float_hash_value(v);
+ }
+
+ //
+ // boost::hash
+ //
+
+ // Define the specializations required by the standard. The general purpose
+ // boost::hash is defined later in extensions.hpp if BOOST_HASH_NO_EXTENSIONS
+ // is not defined.
+
+ // BOOST_HASH_SPECIALIZE - define a specialization for a type which is
+ // passed by copy.
+ //
+ // BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is
+ // passed by copy.
+ //
+ // These are undefined later.
+
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+#define BOOST_HASH_SPECIALIZE(type) \
+ template <> struct hash<type> \
+ : public std::unary_function<type, std::size_t> \
+ { \
+ std::size_t operator()(type v) const \
+ { \
+ return boost::hash_value(v); \
+ } \
+ };
+
+#define BOOST_HASH_SPECIALIZE_REF(type) \
+ template <> struct hash<type> \
+ : public std::unary_function<type, std::size_t> \
+ { \
+ std::size_t operator()(type const& v) const \
+ { \
+ return boost::hash_value(v); \
+ } \
+ };
+#else
+#define BOOST_HASH_SPECIALIZE(type) \
+ template <> struct hash<type> \
+ : public std::unary_function<type, std::size_t> \
+ { \
+ std::size_t operator()(type v) const \
+ { \
+ return boost::hash_value(v); \
+ } \
+ }; \
+ \
+ template <> struct hash<const type> \
+ : public std::unary_function<const type, std::size_t> \
+ { \
+ std::size_t operator()(const type v) const \
+ { \
+ return boost::hash_value(v); \
+ } \
+ };
+
+#define BOOST_HASH_SPECIALIZE_REF(type) \
+ template <> struct hash<type> \
+ : public std::unary_function<type, std::size_t> \
+ { \
+ std::size_t operator()(type const& v) const \
+ { \
+ return boost::hash_value(v); \
+ } \
+ }; \
+ \
+ template <> struct hash<const type> \
+ : public std::unary_function<const type, std::size_t> \
+ { \
+ std::size_t operator()(type const& v) const \
+ { \
+ return boost::hash_value(v); \
+ } \
+ };
+#endif
+
+ BOOST_HASH_SPECIALIZE(bool)
+ BOOST_HASH_SPECIALIZE(char)
+ BOOST_HASH_SPECIALIZE(signed char)
+ BOOST_HASH_SPECIALIZE(unsigned char)
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+ BOOST_HASH_SPECIALIZE(wchar_t)
+#endif
+ BOOST_HASH_SPECIALIZE(short)
+ BOOST_HASH_SPECIALIZE(unsigned short)
+ BOOST_HASH_SPECIALIZE(int)
+ BOOST_HASH_SPECIALIZE(unsigned int)
+ BOOST_HASH_SPECIALIZE(long)
+ BOOST_HASH_SPECIALIZE(unsigned long)
+
+ BOOST_HASH_SPECIALIZE(float)
+ BOOST_HASH_SPECIALIZE(double)
+ BOOST_HASH_SPECIALIZE(long double)
+
+ BOOST_HASH_SPECIALIZE_REF(std::string)
+#if !defined(BOOST_NO_STD_WSTRING)
+ BOOST_HASH_SPECIALIZE_REF(std::wstring)
+#endif
+
+#if defined(BOOST_HAS_LONG_LONG)
+ BOOST_HASH_SPECIALIZE(boost::long_long_type)
+ BOOST_HASH_SPECIALIZE(boost::ulong_long_type)
+#endif
+
+#undef BOOST_HASH_SPECIALIZE
+#undef BOOST_HASH_SPECIALIZE_REF
+
+// Specializing boost::hash for pointers.
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+ template <class T>
+ struct hash<T*>
+ : public std::unary_function<T*, std::size_t>
+ {
+ std::size_t operator()(T* v) const
+ {
+#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590)
+ return boost::hash_value(v);
+#else
+ std::size_t x = static_cast<std::size_t>(
+ reinterpret_cast<std::ptrdiff_t>(v));
+
+ return x + (x >> 3);
+#endif
+ }
+ };
+
+#else
+
+ // For compilers without partial specialization, we define a
+ // boost::hash for all remaining types. But hash_impl is only defined
+ // for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS
+ // is defined there will still be a compile error for types not supported
+ // in the standard.
+
+ namespace hash_detail
+ {
+ template <bool IsPointer>
+ struct hash_impl;
+
+ template <>
+ struct hash_impl<true>
+ {
+ template <class T>
+ struct inner
+ : public std::unary_function<T, std::size_t>
+ {
+ std::size_t operator()(T val) const
+ {
+#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590)
+ return boost::hash_value(val);
+#else
+ std::size_t x = static_cast<std::size_t>(
+ reinterpret_cast<std::ptrdiff_t>(val));
+
+ return x + (x >> 3);
+#endif
+ }
+ };
+ };
+ }
+
+ template <class T> struct hash
+ : public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
+ ::BOOST_NESTED_TEMPLATE inner<T>
+ {
+ };
+
+#endif
+}
+
+#undef BOOST_HASH_CHAR_TRAITS
+
+#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
+
+// Include this outside of the include guards in case the file is included
+// twice - once with BOOST_HASH_NO_EXTENSIONS defined, and then with it
+// undefined.
+
+#if !defined(BOOST_HASH_NO_EXTENSIONS) \
+ && !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
+#include <boost/functional/hash/extensions.hpp>
+#endif
diff --git a/ext/boost/functional/hash/hash_fwd.hpp b/ext/boost/functional/hash/hash_fwd.hpp
new file mode 100644
index 0000000000..1d51b07f2d
--- /dev/null
+++ b/ext/boost/functional/hash/hash_fwd.hpp
@@ -0,0 +1,40 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+// Based on Peter Dimov's proposal
+// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
+// issue 6.18.
+
+#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP)
+#define BOOST_FUNCTIONAL_HASH_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/config.hpp>
+#include <cstddef>
+#include <boost/detail/workaround.hpp>
+
+namespace boost
+{
+ template <class T> struct hash;
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+ template <class T> void hash_combine(std::size_t& seed, T& v);
+#else
+ template <class T> void hash_combine(std::size_t& seed, T const& v);
+#endif
+
+ template <class It> std::size_t hash_range(It, It);
+ template <class It> void hash_range(std::size_t&, It, It);
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
+ template <class T> inline std::size_t hash_range(T*, T*);
+ template <class T> inline void hash_range(std::size_t&, T*, T*);
+#endif
+}
+
+#endif
diff --git a/ext/boost/functional/hash_fwd.hpp b/ext/boost/functional/hash_fwd.hpp
new file mode 100644
index 0000000000..b640988618
--- /dev/null
+++ b/ext/boost/functional/hash_fwd.hpp
@@ -0,0 +1,7 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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/functional/hash/hash_fwd.hpp>
+
diff --git a/ext/boost/integer/integer_mask.hpp b/ext/boost/integer/integer_mask.hpp
new file mode 100644
index 0000000000..0a092d3850
--- /dev/null
+++ b/ext/boost/integer/integer_mask.hpp
@@ -0,0 +1,93 @@
+// Boost integer/integer_mask.hpp header file ------------------------------//
+
+// (C) Copyright Daryle Walker 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_INTEGER_INTEGER_MASK_HPP
+#define BOOST_INTEGER_INTEGER_MASK_HPP
+
+#include <boost/integer_fwd.hpp> // self include
+
+#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT
+#include <boost/integer.hpp> // for boost::uint_t
+
+#include <climits> // for UCHAR_MAX, etc.
+#include <cstddef> // for std::size_t
+
+#include <boost/limits.hpp> // for std::numeric_limits
+
+
+namespace boost
+{
+
+
+// Specified single-bit mask class declaration -----------------------------//
+// (Lowest bit starts counting at 0.)
+
+template < std::size_t Bit >
+struct high_bit_mask_t
+{
+ typedef typename uint_t<(Bit + 1)>::least least;
+ typedef typename uint_t<(Bit + 1)>::fast fast;
+
+ BOOST_STATIC_CONSTANT( least, high_bit = (least( 1u ) << Bit) );
+ BOOST_STATIC_CONSTANT( fast, high_bit_fast = (fast( 1u ) << Bit) );
+
+ BOOST_STATIC_CONSTANT( std::size_t, bit_position = Bit );
+
+}; // boost::high_bit_mask_t
+
+
+// Specified bit-block mask class declaration ------------------------------//
+// Makes masks for the lowest N bits
+// (Specializations are needed when N fills up a type.)
+
+template < std::size_t Bits >
+struct low_bits_mask_t
+{
+ typedef typename uint_t<Bits>::least least;
+ typedef typename uint_t<Bits>::fast fast;
+
+ BOOST_STATIC_CONSTANT( least, sig_bits = (~( ~(least( 0u )) << Bits )) );
+ BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
+
+ BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
+
+}; // boost::low_bits_mask_t
+
+
+#define BOOST_LOW_BITS_MASK_SPECIALIZE( Type ) \
+ template < > struct low_bits_mask_t< std::numeric_limits<Type>::digits > { \
+ typedef std::numeric_limits<Type> limits_type; \
+ typedef uint_t<limits_type::digits>::least least; \
+ typedef uint_t<limits_type::digits>::fast fast; \
+ BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) ); \
+ BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); \
+ BOOST_STATIC_CONSTANT( std::size_t, bit_count = limits_type::digits ); \
+ }
+
+BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned char );
+
+#if USHRT_MAX > UCHAR_MAX
+BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned short );
+#endif
+
+#if UINT_MAX > USHRT_MAX
+BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned int );
+#endif
+
+#if ULONG_MAX > UINT_MAX
+BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned long );
+#endif
+
+#undef BOOST_LOW_BITS_MASK_SPECIALIZE
+
+
+} // namespace boost
+
+
+#endif // BOOST_INTEGER_INTEGER_MASK_HPP
diff --git a/ext/boost/integer/static_log2.hpp b/ext/boost/integer/static_log2.hpp
new file mode 100644
index 0000000000..219a48e341
--- /dev/null
+++ b/ext/boost/integer/static_log2.hpp
@@ -0,0 +1,132 @@
+// -------------- Boost static_log2.hpp header file ----------------------- //
+//
+// Copyright (C) 2001 Daryle Walker.
+// Copyright (C) 2003 Vesa Karvonen.
+// Copyright (C) 2003 Gennaro Prota.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// ---------------------------------------------------
+// See http://www.boost.org/libs/integer for documentation.
+// ------------------------------------------------------------------------- //
+
+
+#ifndef BOOST_INTEGER_STATIC_LOG2_HPP
+#define BOOST_INTEGER_STATIC_LOG2_HPP
+
+#include "boost/config.hpp" // for BOOST_STATIC_CONSTANT
+
+namespace boost {
+
+ namespace detail {
+
+ namespace static_log2_impl {
+
+ // choose_initial_n<>
+ //
+ // Recursively doubles its integer argument, until it
+ // becomes >= of the "width" (C99, 6.2.6.2p4) of
+ // static_log2_argument_type.
+ //
+ // Used to get the maximum power of two less then the width.
+ //
+ // Example: if on your platform argument_type has 48 value
+ // bits it yields n=32.
+ //
+ // It's easy to prove that, starting from such a value
+ // of n, the core algorithm works correctly for any width
+ // of static_log2_argument_type and that recursion always
+ // terminates with x = 1 and n = 0 (see the algorithm's
+ // invariant).
+
+ typedef unsigned long argument_type;
+ typedef int result_type;
+
+
+ template <result_type n>
+ struct choose_initial_n {
+
+ BOOST_STATIC_CONSTANT(bool, c = (argument_type(1) << n << n) != 0);
+ BOOST_STATIC_CONSTANT(
+ result_type,
+ value = !c*n + choose_initial_n<2*c*n>::value
+ );
+
+ };
+
+ template <>
+ struct choose_initial_n<0> {
+ BOOST_STATIC_CONSTANT(result_type, value = 0);
+ };
+
+
+
+ // start computing from n_zero - must be a power of two
+ const result_type n_zero = 16;
+ const result_type initial_n = choose_initial_n<n_zero>::value;
+
+ // static_log2_impl<>
+ //
+ // * Invariant:
+ // 2n
+ // 1 <= x && x < 2 at the start of each recursion
+ // (see also choose_initial_n<>)
+ //
+ // * Type requirements:
+ //
+ // argument_type maybe any unsigned type with at least n_zero + 1
+ // value bits. (Note: If larger types will be standardized -e.g.
+ // unsigned long long- then the argument_type typedef can be
+ // changed without affecting the rest of the code.)
+ //
+
+ template <argument_type x, result_type n = initial_n>
+ struct static_log2_impl {
+
+ BOOST_STATIC_CONSTANT(bool, c = (x >> n) > 0); // x >= 2**n ?
+ BOOST_STATIC_CONSTANT(
+ result_type,
+ value = c*n + (static_log2_impl< (x>>c*n), n/2 >::value)
+ );
+
+ };
+
+ template <>
+ struct static_log2_impl<1, 0> {
+ BOOST_STATIC_CONSTANT(result_type, value = 0);
+ };
+
+ }
+ } // detail
+
+
+
+ // --------------------------------------
+ // static_log2<x>
+ // ----------------------------------------
+
+ typedef detail::static_log2_impl::argument_type static_log2_argument_type;
+ typedef detail::static_log2_impl::result_type static_log2_result_type;
+
+
+ template <static_log2_argument_type x>
+ struct static_log2 {
+
+ BOOST_STATIC_CONSTANT(
+ static_log2_result_type,
+ value = detail::static_log2_impl::static_log2_impl<x>::value
+ );
+
+ };
+
+
+ template <>
+ struct static_log2<0> { };
+
+}
+
+
+
+#endif // include guard
diff --git a/ext/boost/integer/static_min_max.hpp b/ext/boost/integer/static_min_max.hpp
new file mode 100644
index 0000000000..264603727f
--- /dev/null
+++ b/ext/boost/integer/static_min_max.hpp
@@ -0,0 +1,55 @@
+// Boost integer/static_min_max.hpp header file ----------------------------//
+
+// (C) Copyright Daryle Walker 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_INTEGER_STATIC_MIN_MAX_HPP
+#define BOOST_INTEGER_STATIC_MIN_MAX_HPP
+
+#include <boost/integer_fwd.hpp> // self include
+
+#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT
+
+
+namespace boost
+{
+
+
+// Compile-time extrema class declarations ---------------------------------//
+// Get the minimum or maximum of two values, signed or unsigned.
+
+template < long Value1, long Value2 >
+struct static_signed_min
+{
+ BOOST_STATIC_CONSTANT( long, value = (Value1 > Value2) ? Value2 : Value1 );
+};
+
+template < long Value1, long Value2 >
+struct static_signed_max
+{
+ BOOST_STATIC_CONSTANT( long, value = (Value1 < Value2) ? Value2 : Value1 );
+};
+
+template < unsigned long Value1, unsigned long Value2 >
+struct static_unsigned_min
+{
+ BOOST_STATIC_CONSTANT( unsigned long, value
+ = (Value1 > Value2) ? Value2 : Value1 );
+};
+
+template < unsigned long Value1, unsigned long Value2 >
+struct static_unsigned_max
+{
+ BOOST_STATIC_CONSTANT( unsigned long, value
+ = (Value1 < Value2) ? Value2 : Value1 );
+};
+
+
+} // namespace boost
+
+
+#endif // BOOST_INTEGER_STATIC_MIN_MAX_HPP
diff --git a/ext/boost/optional/optional.hpp b/ext/boost/optional/optional.hpp
new file mode 100644
index 0000000000..42277ba61e
--- /dev/null
+++ b/ext/boost/optional/optional.hpp
@@ -0,0 +1,922 @@
+// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/lib/optional for documentation.
+//
+// You are welcome to contact the author at:
+// fernando_cacciola@hotmail.com
+//
+#ifndef BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
+#define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
+
+#include<new>
+#include<algorithm>
+
+#include "boost/config.hpp"
+#include "boost/assert.hpp"
+#include "boost/type.hpp"
+#include "boost/type_traits/alignment_of.hpp"
+#include "boost/type_traits/type_with_alignment.hpp"
+#include "boost/type_traits/remove_reference.hpp"
+#include "boost/type_traits/is_reference.hpp"
+#include "boost/mpl/if.hpp"
+#include "boost/mpl/bool.hpp"
+#include "boost/mpl/not.hpp"
+#include "boost/detail/reference_content.hpp"
+#include "boost/none.hpp"
+#include "boost/utility/compare_pointees.hpp"
+
+#include "boost/optional/optional_fwd.hpp"
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
+// VC6.0 has the following bug:
+// When a templated assignment operator exist, an implicit conversion
+// constructing an optional<T> is used when assigment of the form:
+// optional<T> opt ; opt = T(...);
+// is compiled.
+// However, optional's ctor is _explicit_ and the assignemt shouldn't compile.
+// Therefore, for VC6.0 templated assignment is disabled.
+//
+#define BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
+#endif
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
+// VC7.0 has the following bug:
+// When both a non-template and a template copy-ctor exist
+// and the templated version is made 'explicit', the explicit is also
+// given to the non-templated version, making the class non-implicitely-copyable.
+//
+#define BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
+#endif
+
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION,<=700)
+// AFAICT only VC7.1 correctly resolves the overload set
+// that includes the in-place factory taking functions,
+// so for the other VC versions, in-place factory support
+// is disabled
+#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+#endif
+
+#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551)
+// BCB (5.5.1) cannot parse the nested template struct in an inplace factory.
+#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+#endif
+
+#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) \
+ && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581) )
+// BCB (up to 5.64) has the following bug:
+// If there is a member function/operator template of the form
+// template<class Expr> mfunc( Expr expr ) ;
+// some calls are resolved to this even if there are other better matches.
+// The effect of this bug is that calls to converting ctors and assignments
+// are incrorrectly sink to this general catch-all member function template as shown above.
+#define BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
+#endif
+
+// Daniel Wallin discovered that bind/apply.hpp badly interacts with the apply<>
+// member template of a factory as used in the optional<> implementation.
+// He proposed this simple fix which is to move the call to apply<> outside
+// namespace boost.
+namespace boost_optional_detail
+{
+ template <class T, class Factory>
+ void construct(Factory const& factory, void* address)
+ {
+ factory.BOOST_NESTED_TEMPLATE apply<T>(address);
+ }
+}
+
+
+namespace boost {
+
+class in_place_factory_base ;
+class typed_in_place_factory_base ;
+
+namespace optional_detail {
+
+// This local class is used instead of that in "aligned_storage.hpp"
+// because I've found the 'official' class to ICE BCB5.5
+// when some types are used with optional<>
+// (due to sizeof() passed down as a non-type template parameter)
+template <class T>
+class aligned_storage
+{
+ // Borland ICEs if unnamed unions are used for this!
+ union dummy_u
+ {
+ char data[ sizeof(T) ];
+ BOOST_DEDUCED_TYPENAME type_with_alignment<
+ ::boost::alignment_of<T>::value >::type aligner_;
+ } dummy_ ;
+
+ public:
+
+ void const* address() const { return &dummy_.data[0]; }
+ void * address() { return &dummy_.data[0]; }
+} ;
+
+template<class T>
+struct types_when_isnt_ref
+{
+ typedef T const& reference_const_type ;
+ typedef T & reference_type ;
+ typedef T const* pointer_const_type ;
+ typedef T * pointer_type ;
+ typedef T const& argument_type ;
+} ;
+template<class T>
+struct types_when_is_ref
+{
+ typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type raw_type ;
+
+ typedef raw_type& reference_const_type ;
+ typedef raw_type& reference_type ;
+ typedef raw_type* pointer_const_type ;
+ typedef raw_type* pointer_type ;
+ typedef raw_type& argument_type ;
+} ;
+
+struct optional_tag {} ;
+
+template<class T>
+class optional_base : public optional_tag
+{
+ private :
+
+ typedef
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+ BOOST_DEDUCED_TYPENAME
+#endif
+ ::boost::detail::make_reference_content<T>::type internal_type ;
+
+ typedef aligned_storage<internal_type> storage_type ;
+
+ typedef types_when_isnt_ref<T> types_when_not_ref ;
+ typedef types_when_is_ref<T> types_when_ref ;
+
+ typedef optional_base<T> this_type ;
+
+ protected :
+
+ typedef T value_type ;
+
+ typedef mpl::true_ is_reference_tag ;
+ typedef mpl::false_ is_not_reference_tag ;
+
+ typedef BOOST_DEDUCED_TYPENAME is_reference<T>::type is_reference_predicate ;
+
+ typedef BOOST_DEDUCED_TYPENAME mpl::if_<is_reference_predicate,types_when_ref,types_when_not_ref>::type types ;
+
+ typedef bool (this_type::*unspecified_bool_type)() const;
+
+ typedef BOOST_DEDUCED_TYPENAME types::reference_type reference_type ;
+ typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ;
+ typedef BOOST_DEDUCED_TYPENAME types::pointer_type pointer_type ;
+ typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type pointer_const_type ;
+ typedef BOOST_DEDUCED_TYPENAME types::argument_type argument_type ;
+
+ // Creates an optional<T> uninitialized.
+ // No-throw
+ optional_base()
+ :
+ m_initialized(false) {}
+
+ // Creates an optional<T> uninitialized.
+ // No-throw
+ optional_base ( none_t )
+ :
+ m_initialized(false) {}
+
+ // Creates an optional<T> initialized with 'val'.
+ // Can throw if T::T(T const&) does
+ optional_base ( argument_type val )
+ :
+ m_initialized(false)
+ {
+ construct(val);
+ }
+
+ // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialzed optional<T>.
+ // Can throw if T::T(T const&) does
+ optional_base ( bool cond, argument_type val )
+ :
+ m_initialized(false)
+ {
+ if ( cond )
+ construct(val);
+ }
+
+ // Creates a deep copy of another optional<T>
+ // Can throw if T::T(T const&) does
+ optional_base ( optional_base const& rhs )
+ :
+ m_initialized(false)
+ {
+ if ( rhs.is_initialized() )
+ construct(rhs.get_impl());
+ }
+
+
+ // This is used for both converting and in-place constructions.
+ // Derived classes use the 'tag' to select the appropriate
+ // implementation (the correct 'construct()' overload)
+ template<class Expr>
+ explicit optional_base ( Expr const& expr, Expr const* tag )
+ :
+ m_initialized(false)
+ {
+ construct(expr,tag);
+ }
+
+
+
+ // No-throw (assuming T::~T() doesn't)
+ ~optional_base() { destroy() ; }
+
+ // Assigns from another optional<T> (deep-copies the rhs value)
+ void assign ( optional_base const& rhs )
+ {
+ if (is_initialized())
+ {
+ if ( rhs.is_initialized() )
+ assign_value(rhs.get_impl(), is_reference_predicate() );
+ else destroy();
+ }
+ else
+ {
+ if ( rhs.is_initialized() )
+ construct(rhs.get_impl());
+ }
+ }
+
+ // Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
+ template<class U>
+ void assign ( optional<U> const& rhs )
+ {
+ if (is_initialized())
+ {
+ if ( rhs.is_initialized() )
+ assign_value(static_cast<value_type>(rhs.get()), is_reference_predicate() );
+ else destroy();
+ }
+ else
+ {
+ if ( rhs.is_initialized() )
+ construct(static_cast<value_type>(rhs.get()));
+ }
+ }
+
+ // Assigns from a T (deep-copies the rhs value)
+ void assign ( argument_type val )
+ {
+ if (is_initialized())
+ assign_value(val, is_reference_predicate() );
+ else construct(val);
+ }
+
+ // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
+ // No-throw (assuming T::~T() doesn't)
+ void assign ( none_t ) { destroy(); }
+
+#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+ template<class Expr>
+ void assign_expr ( Expr const& expr, Expr const* tag )
+ {
+ if (is_initialized())
+ assign_expr_to_initialized(expr,tag);
+ else construct(expr,tag);
+ }
+#endif
+
+ public :
+
+ // Destroys the current value, if any, leaving this UNINITIALIZED
+ // No-throw (assuming T::~T() doesn't)
+ void reset() { destroy(); }
+
+ // Replaces the current value -if any- with 'val'
+ void reset ( argument_type val ) { assign(val); }
+
+ // Returns a pointer to the value if this is initialized, otherwise,
+ // returns NULL.
+ // No-throw
+ pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
+ pointer_type get_ptr() { return m_initialized ? get_ptr_impl() : 0 ; }
+
+ bool is_initialized() const { return m_initialized ; }
+
+ protected :
+
+ void construct ( argument_type val )
+ {
+ new (m_storage.address()) internal_type(val) ;
+ m_initialized = true ;
+ }
+
+#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+ // Constructs in-place using the given factory
+ template<class Expr>
+ void construct ( Expr const& factory, in_place_factory_base const* )
+ {
+ BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
+ boost_optional_detail::construct<value_type>(factory, m_storage.address());
+ m_initialized = true ;
+ }
+
+ // Constructs in-place using the given typed factory
+ template<class Expr>
+ void construct ( Expr const& factory, typed_in_place_factory_base const* )
+ {
+ BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
+ factory.apply(m_storage.address()) ;
+ m_initialized = true ;
+ }
+
+ template<class Expr>
+ void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag )
+ {
+ destroy();
+ construct(factory,tag);
+ }
+
+ // Constructs in-place using the given typed factory
+ template<class Expr>
+ void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag )
+ {
+ destroy();
+ construct(factory,tag);
+ }
+#endif
+
+ // Constructs using any expression implicitely convertible to the single argument
+ // of a one-argument T constructor.
+ // Converting constructions of optional<T> from optional<U> uses this function with
+ // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
+ template<class Expr>
+ void construct ( Expr const& expr, void const* )
+ {
+ new (m_storage.address()) internal_type(expr) ;
+ m_initialized = true ;
+ }
+
+ // Assigns using a form any expression implicitely convertible to the single argument
+ // of a T's assignment operator.
+ // Converting assignments of optional<T> from optional<U> uses this function with
+ // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
+ template<class Expr>
+ void assign_expr_to_initialized ( Expr const& expr, void const* )
+ {
+ assign_value(expr, is_reference_predicate());
+ }
+
+#ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
+ // BCB5.64 (and probably lower versions) workaround.
+ // The in-place factories are supported by means of catch-all constructors
+ // and assignment operators (the functions are parameterized in terms of
+ // an arbitrary 'Expr' type)
+ // This compiler incorrectly resolves the overload set and sinks optional<T> and optional<U>
+ // to the 'Expr'-taking functions even though explicit overloads are present for them.
+ // Thus, the following overload is needed to properly handle the case when the 'lhs'
+ // is another optional.
+ //
+ // For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error
+ // instead of choosing the wrong overload
+ //
+ // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
+ template<class Expr>
+ void construct ( Expr const& expr, optional_tag const* )
+ {
+ if ( expr.is_initialized() )
+ {
+ // An exception can be thrown here.
+ // It it happens, THIS will be left uninitialized.
+ new (m_storage.address()) internal_type(expr.get()) ;
+ m_initialized = true ;
+ }
+ }
+#endif
+
+ void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; }
+ void assign_value ( argument_type val, is_reference_tag ) { construct(val); }
+
+ void destroy()
+ {
+ if ( m_initialized )
+ destroy_impl(is_reference_predicate()) ;
+ }
+
+ unspecified_bool_type safe_bool() const { return m_initialized ? &this_type::is_initialized : 0 ; }
+
+ reference_const_type get_impl() const { return dereference(get_object(), is_reference_predicate() ) ; }
+ reference_type get_impl() { return dereference(get_object(), is_reference_predicate() ) ; }
+
+ pointer_const_type get_ptr_impl() const { return cast_ptr(get_object(), is_reference_predicate() ) ; }
+ pointer_type get_ptr_impl() { return cast_ptr(get_object(), is_reference_predicate() ) ; }
+
+ private :
+
+ // internal_type can be either T or reference_content<T>
+ internal_type const* get_object() const { return static_cast<internal_type const*>(m_storage.address()); }
+ internal_type * get_object() { return static_cast<internal_type *> (m_storage.address()); }
+
+ // reference_content<T> lacks an implicit conversion to T&, so the following is needed to obtain a proper reference.
+ reference_const_type dereference( internal_type const* p, is_not_reference_tag ) const { return *p ; }
+ reference_type dereference( internal_type* p, is_not_reference_tag ) { return *p ; }
+ reference_const_type dereference( internal_type const* p, is_reference_tag ) const { return p->get() ; }
+ reference_type dereference( internal_type* p, is_reference_tag ) { return p->get() ; }
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
+ void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->internal_type::~internal_type() ; m_initialized = false ; }
+#else
+ void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->T::~T() ; m_initialized = false ; }
+#endif
+
+ void destroy_impl ( is_reference_tag ) { m_initialized = false ; }
+
+ // If T is of reference type, trying to get a pointer to the held value must result in a compile-time error.
+ // Decent compilers should disallow conversions from reference_content<T>* to T*, but just in case,
+ // the following olverloads are used to filter out the case and guarantee an error in case of T being a reference.
+ pointer_const_type cast_ptr( internal_type const* p, is_not_reference_tag ) const { return p ; }
+ pointer_type cast_ptr( internal_type * p, is_not_reference_tag ) { return p ; }
+ pointer_const_type cast_ptr( internal_type const* p, is_reference_tag ) const { return &p->get() ; }
+ pointer_type cast_ptr( internal_type * p, is_reference_tag ) { return &p->get() ; }
+
+ bool m_initialized ;
+ storage_type m_storage ;
+} ;
+
+} // namespace optional_detail
+
+template<class T>
+class optional : public optional_detail::optional_base<T>
+{
+ typedef optional_detail::optional_base<T> base ;
+
+ typedef BOOST_DEDUCED_TYPENAME base::unspecified_bool_type unspecified_bool_type ;
+
+ public :
+
+ typedef optional<T> this_type ;
+
+ typedef BOOST_DEDUCED_TYPENAME base::value_type value_type ;
+ typedef BOOST_DEDUCED_TYPENAME base::reference_type reference_type ;
+ typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
+ typedef BOOST_DEDUCED_TYPENAME base::pointer_type pointer_type ;
+ typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type pointer_const_type ;
+ typedef BOOST_DEDUCED_TYPENAME base::argument_type argument_type ;
+
+ // Creates an optional<T> uninitialized.
+ // No-throw
+ optional() : base() {}
+
+ // Creates an optional<T> uninitialized.
+ // No-throw
+ optional( none_t none_ ) : base(none_) {}
+
+ // Creates an optional<T> initialized with 'val'.
+ // Can throw if T::T(T const&) does
+ optional ( argument_type val ) : base(val) {}
+
+ // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
+ // Can throw if T::T(T const&) does
+ optional ( bool cond, argument_type val ) : base(cond,val) {}
+
+#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
+ // NOTE: MSVC needs templated versions first
+
+ // Creates a deep copy of another convertible optional<U>
+ // Requires a valid conversion from U to T.
+ // Can throw if T::T(U const&) does
+ template<class U>
+ explicit optional ( optional<U> const& rhs )
+ :
+ base()
+ {
+ if ( rhs.is_initialized() )
+ this->construct(rhs.get());
+ }
+#endif
+
+#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+ // Creates an optional<T> with an expression which can be either
+ // (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n);
+ // (b) An instance of TypedInPlaceFactory ( i.e. in_place<T>(a,b,...,n);
+ // (c) Any expression implicitely convertible to the single type
+ // of a one-argument T's constructor.
+ // (d*) Weak compilers (BCB) might also resolved Expr as optional<T> and optional<U>
+ // even though explicit overloads are present for these.
+ // Depending on the above some T ctor is called.
+ // Can throw is the resolved T ctor throws.
+ template<class Expr>
+ explicit optional ( Expr const& expr ) : base(expr,&expr) {}
+#endif
+
+ // Creates a deep copy of another optional<T>
+ // Can throw if T::T(T const&) does
+ optional ( optional const& rhs ) : base(rhs) {}
+
+ // No-throw (assuming T::~T() doesn't)
+ ~optional() {}
+
+#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
+ // Assigns from an expression. See corresponding constructor.
+ // Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED
+ template<class Expr>
+ optional& operator= ( Expr expr )
+ {
+ this->assign_expr(expr,&expr);
+ return *this ;
+ }
+#endif
+
+
+#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
+ // Assigns from another convertible optional<U> (converts && deep-copies the rhs value)
+ // Requires a valid conversion from U to T.
+ // Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED
+ template<class U>
+ optional& operator= ( optional<U> const& rhs )
+ {
+ this->assign(rhs);
+ return *this ;
+ }
+#endif
+
+ // Assigns from another optional<T> (deep-copies the rhs value)
+ // Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
+ // (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw)
+ optional& operator= ( optional const& rhs )
+ {
+ this->assign( rhs ) ;
+ return *this ;
+ }
+
+ // Assigns from a T (deep-copies the rhs value)
+ // Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
+ optional& operator= ( argument_type val )
+ {
+ this->assign( val ) ;
+ return *this ;
+ }
+
+ // Assigns from a "none"
+ // Which destroys the current value, if any, leaving this UNINITIALIZED
+ // No-throw (assuming T::~T() doesn't)
+ optional& operator= ( none_t none_ )
+ {
+ this->assign( none_ ) ;
+ return *this ;
+ }
+
+ // Returns a reference to the value if this is initialized, otherwise,
+ // the behaviour is UNDEFINED
+ // No-throw
+ reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
+ reference_type get() { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
+
+ // Returns a copy of the value if this is initialized, 'v' otherwise
+ reference_const_type get_value_or ( reference_const_type v ) const { return this->is_initialized() ? get() : v ; }
+ reference_type get_value_or ( reference_type v ) { return this->is_initialized() ? get() : v ; }
+
+ // Returns a pointer to the value if this is initialized, otherwise,
+ // the behaviour is UNDEFINED
+ // No-throw
+ pointer_const_type operator->() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
+ pointer_type operator->() { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
+
+ // Returns a reference to the value if this is initialized, otherwise,
+ // the behaviour is UNDEFINED
+ // No-throw
+ reference_const_type operator *() const { return this->get() ; }
+ reference_type operator *() { return this->get() ; }
+
+ // implicit conversion to "bool"
+ // No-throw
+ operator unspecified_bool_type() const { return this->safe_bool() ; }
+
+ // This is provided for those compilers which don't like the conversion to bool
+ // on some contexts.
+ bool operator!() const { return !this->is_initialized() ; }
+} ;
+
+// Returns optional<T>(v)
+template<class T>
+inline
+optional<T> make_optional ( T const& v )
+{
+ return optional<T>(v);
+}
+
+// Returns optional<T>(cond,v)
+template<class T>
+inline
+optional<T> make_optional ( bool cond, T const& v )
+{
+ return optional<T>(cond,v);
+}
+
+// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
+// No-throw
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
+get ( optional<T> const& opt )
+{
+ return opt.get() ;
+}
+
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::reference_type
+get ( optional<T>& opt )
+{
+ return opt.get() ;
+}
+
+// Returns a pointer to the value if this is initialized, otherwise, returns NULL.
+// No-throw
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
+get ( optional<T> const* opt )
+{
+ return opt->get_ptr() ;
+}
+
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
+get ( optional<T>* opt )
+{
+ return opt->get_ptr() ;
+}
+
+// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
+// No-throw
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
+get_optional_value_or ( optional<T> const& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type v )
+{
+ return opt.get_value_or(v) ;
+}
+
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::reference_type
+get_optional_value_or ( optional<T>& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_type v )
+{
+ return opt.get_value_or(v) ;
+}
+
+// Returns a pointer to the value if this is initialized, otherwise, returns NULL.
+// No-throw
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
+get_pointer ( optional<T> const& opt )
+{
+ return opt.get_ptr() ;
+}
+
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
+get_pointer ( optional<T>& opt )
+{
+ return opt.get_ptr() ;
+}
+
+// optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values).
+// WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in generic code instead.
+
+
+//
+// optional<T> vs optional<T> cases
+//
+
+template<class T>
+inline
+bool operator == ( optional<T> const& x, optional<T> const& y )
+{ return equal_pointees(x,y); }
+
+template<class T>
+inline
+bool operator < ( optional<T> const& x, optional<T> const& y )
+{ return less_pointees(x,y); }
+
+template<class T>
+inline
+bool operator != ( optional<T> const& x, optional<T> const& y )
+{ return !( x == y ) ; }
+
+template<class T>
+inline
+bool operator > ( optional<T> const& x, optional<T> const& y )
+{ return y < x ; }
+
+template<class T>
+inline
+bool operator <= ( optional<T> const& x, optional<T> const& y )
+{ return !( y < x ) ; }
+
+template<class T>
+inline
+bool operator >= ( optional<T> const& x, optional<T> const& y )
+{ return !( x < y ) ; }
+
+
+//
+// optional<T> vs T cases
+//
+template<class T>
+inline
+bool operator == ( optional<T> const& x, T const& y )
+{ return equal_pointees(x, optional<T>(y)); }
+
+template<class T>
+inline
+bool operator < ( optional<T> const& x, T const& y )
+{ return less_pointees(x, optional<T>(y)); }
+
+template<class T>
+inline
+bool operator != ( optional<T> const& x, T const& y )
+{ return !( x == y ) ; }
+
+template<class T>
+inline
+bool operator > ( optional<T> const& x, T const& y )
+{ return y < x ; }
+
+template<class T>
+inline
+bool operator <= ( optional<T> const& x, T const& y )
+{ return !( y < x ) ; }
+
+template<class T>
+inline
+bool operator >= ( optional<T> const& x, T const& y )
+{ return !( x < y ) ; }
+
+//
+// T vs optional<T> cases
+//
+
+template<class T>
+inline
+bool operator == ( T const& x, optional<T> const& y )
+{ return equal_pointees( optional<T>(x), y ); }
+
+template<class T>
+inline
+bool operator < ( T const& x, optional<T> const& y )
+{ return less_pointees( optional<T>(x), y ); }
+
+template<class T>
+inline
+bool operator != ( T const& x, optional<T> const& y )
+{ return !( x == y ) ; }
+
+template<class T>
+inline
+bool operator > ( T const& x, optional<T> const& y )
+{ return y < x ; }
+
+template<class T>
+inline
+bool operator <= ( T const& x, optional<T> const& y )
+{ return !( y < x ) ; }
+
+template<class T>
+inline
+bool operator >= ( T const& x, optional<T> const& y )
+{ return !( x < y ) ; }
+
+
+//
+// optional<T> vs none cases
+//
+
+template<class T>
+inline
+bool operator == ( optional<T> const& x, none_t )
+{ return equal_pointees(x, optional<T>() ); }
+
+template<class T>
+inline
+bool operator < ( optional<T> const& x, none_t )
+{ return less_pointees(x,optional<T>() ); }
+
+template<class T>
+inline
+bool operator != ( optional<T> const& x, none_t y )
+{ return !( x == y ) ; }
+
+template<class T>
+inline
+bool operator > ( optional<T> const& x, none_t y )
+{ return y < x ; }
+
+template<class T>
+inline
+bool operator <= ( optional<T> const& x, none_t y )
+{ return !( y < x ) ; }
+
+template<class T>
+inline
+bool operator >= ( optional<T> const& x, none_t y )
+{ return !( x < y ) ; }
+
+//
+// none vs optional<T> cases
+//
+
+template<class T>
+inline
+bool operator == ( none_t x, optional<T> const& y )
+{ return equal_pointees(optional<T>() ,y); }
+
+template<class T>
+inline
+bool operator < ( none_t x, optional<T> const& y )
+{ return less_pointees(optional<T>() ,y); }
+
+template<class T>
+inline
+bool operator != ( none_t x, optional<T> const& y )
+{ return !( x == y ) ; }
+
+template<class T>
+inline
+bool operator > ( none_t x, optional<T> const& y )
+{ return y < x ; }
+
+template<class T>
+inline
+bool operator <= ( none_t x, optional<T> const& y )
+{ return !( y < x ) ; }
+
+template<class T>
+inline
+bool operator >= ( none_t x, optional<T> const& y )
+{ return !( x < y ) ; }
+
+//
+// The following swap implementation follows the GCC workaround as found in
+// "boost/detail/compressed_pair.hpp"
+//
+namespace optional_detail {
+
+// GCC < 3.2 gets the using declaration at namespace scope (FLC, DWA)
+#if BOOST_WORKAROUND(__GNUC__, < 3) \
+ || BOOST_WORKAROUND(__GNUC__, == 3) && __GNUC_MINOR__ <= 2
+ using std::swap;
+#define BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
+#endif
+
+// optional's swap:
+// If both are initialized, calls swap(T&, T&). If this swap throws, both will remain initialized but their values are now unspecified.
+// If only one is initialized, calls U.reset(*I), THEN I.reset().
+// If U.reset(*I) throws, both are left UNCHANGED (U is kept uinitialized and I is never reset)
+// If both are uninitialized, do nothing (no-throw)
+template<class T>
+inline
+void optional_swap ( optional<T>& x, optional<T>& y )
+{
+ if ( !x && !!y )
+ {
+ x.reset(*y);
+ y.reset();
+ }
+ else if ( !!x && !y )
+ {
+ y.reset(*x);
+ x.reset();
+ }
+ else if ( !!x && !!y )
+ {
+// GCC > 3.2 and all other compilers have the using declaration at function scope (FLC)
+#ifndef BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
+ // allow for Koenig lookup
+ using std::swap ;
+#endif
+ swap(*x,*y);
+ }
+}
+
+} // namespace optional_detail
+
+template<class T> inline void swap ( optional<T>& x, optional<T>& y )
+{
+ optional_detail::optional_swap(x,y);
+}
+
+
+} // namespace boost
+
+#endif
+
diff --git a/ext/boost/optional/optional_fwd.hpp b/ext/boost/optional/optional_fwd.hpp
new file mode 100644
index 0000000000..2cf4fa654c
--- /dev/null
+++ b/ext/boost/optional/optional_fwd.hpp
@@ -0,0 +1,22 @@
+// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/lib/optional for documentation.
+//
+// You are welcome to contact the author at:
+// fernando_cacciola@hotmail.com
+//
+#ifndef BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
+#define BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
+
+namespace boost {
+
+template<class T> class optional ;
+
+} // namespace boost
+
+#endif
+
diff --git a/ext/boost/optional/optional_io.hpp b/ext/boost/optional/optional_io.hpp
new file mode 100644
index 0000000000..ef1ecaf3a0
--- /dev/null
+++ b/ext/boost/optional/optional_io.hpp
@@ -0,0 +1,84 @@
+// Copyright (C) 2005, Fernando Luis Cacciola Carballal.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/lib/optional for documentation.
+//
+// You are welcome to contact the author at:
+// fernando_cacciola@hotmail.com
+//
+#ifndef BOOST_OPTIONAL_OPTIONAL_IO_FLC_19NOV2002_HPP
+#define BOOST_OPTIONAL_OPTIONAL_IO_FLC_19NOV2002_HPP
+
+#if defined __GNUC__
+# if (__GNUC__ == 2 && __GNUC_MINOR__ <= 97)
+# define BOOST_OPTIONAL_NO_TEMPLATED_STREAMS
+# endif
+#endif // __GNUC__
+
+#if defined BOOST_OPTIONAL_NO_TEMPLATED_STREAMS
+# include <iostream>
+#else
+# include <istream>
+# include <ostream>
+#endif
+
+
+#include "boost/optional/optional.hpp"
+#include "boost/utility/value_init.hpp"
+
+namespace boost
+{
+
+#if defined (BOOST_NO_TEMPLATED_STREAMS)
+template<class T>
+inline std::ostream& operator<<(std::ostream& out, optional<T> const& v)
+#else
+template<class CharType, class CharTrait, class T>
+inline
+std::basic_ostream<CharType, CharTrait>&
+operator<<(std::basic_ostream<CharType, CharTrait>& out, optional<T> const& v)
+#endif
+{
+ if ( out.good() )
+ {
+ if ( !v )
+ out << "--" ;
+ else out << ' ' << *v ;
+ }
+
+ return out;
+}
+
+#if defined (BOOST_NO_TEMPLATED_STREAMS)
+template<class T>
+inline std::istream& operator>>(std::istream& in, optional<T>& v)
+#else
+template<class CharType, class CharTrait, class T>
+inline
+std::basic_istream<CharType, CharTrait>&
+operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v)
+#endif
+{
+ if ( in.good() )
+ {
+ int d = in.get();
+ if ( d == ' ' )
+ {
+ T x ;
+ in >> x;
+ v = x ;
+ }
+ else
+ v = optional<T>() ;
+ }
+
+ return in;
+}
+
+} // namespace boost
+
+#endif
+
diff --git a/ext/boost/regex/concepts.hpp b/ext/boost/regex/concepts.hpp
new file mode 100644
index 0000000000..98fd59413f
--- /dev/null
+++ b/ext/boost/regex/concepts.hpp
@@ -0,0 +1,906 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE concepts.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares regular expression concepts.
+ */
+
+#ifndef BOOST_REGEX_CONCEPTS_HPP_INCLUDED
+#define BOOST_REGEX_CONCEPTS_HPP_INCLUDED
+
+#include <boost/concept_archetype.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/type_traits/is_enum.hpp>
+#include <boost/type_traits/is_base_and_derived.hpp>
+#include <boost/static_assert.hpp>
+#ifndef BOOST_TEST_TR1_REGEX
+#include <boost/regex.hpp>
+#endif
+#include <bitset>
+#include <vector>
+#include <iostream>
+
+namespace boost{
+
+//
+// bitmask_archetype:
+// this can be either an integer type, an enum, or a std::bitset,
+// we use the latter as the architype as it offers the "strictest"
+// of the possible interfaces:
+//
+typedef std::bitset<512> bitmask_archetype;
+//
+// char_architype:
+// A strict model for the character type interface.
+//
+struct char_architype
+{
+ // default constructable:
+ char_architype();
+ // copy constructable / assignable:
+ char_architype(const char_architype&);
+ char_architype& operator=(const char_architype&);
+ // constructable from an integral value:
+ char_architype(unsigned long val);
+ // comparable:
+ bool operator==(const char_architype&)const;
+ bool operator!=(const char_architype&)const;
+ bool operator<(const char_architype&)const;
+ bool operator<=(const char_architype&)const;
+ bool operator>=(const char_architype&)const;
+ bool operator>(const char_architype&)const;
+ // conversion to integral type:
+ operator long()const;
+};
+//
+// char_architype can not be used with basic_string:
+//
+} // namespace boost
+namespace std{
+ template<> struct char_traits<boost::char_architype>
+ {
+ // The intent is that this template is not instantiated,
+ // but this typedef gives us a chance of compilation in
+ // case it is:
+ typedef boost::char_architype char_type;
+ };
+}
+namespace boost{
+//
+// regex_traits_architype:
+// A strict interpretation of the regular expression traits class requirements.
+//
+template <class charT>
+struct regex_traits_architype
+{
+public:
+ regex_traits_architype();
+ typedef charT char_type;
+ // typedef std::size_t size_type;
+ typedef std::vector<char_type> string_type;
+ typedef copy_constructible_archetype<assignable_archetype<> > locale_type;
+ typedef bitmask_archetype char_class_type;
+
+ static std::size_t length(const char_type* ) { return 0; }
+
+ charT translate(charT ) const { return charT(); }
+ charT translate_nocase(charT ) const { return static_object<charT>::get(); }
+
+ template <class ForwardIterator>
+ string_type transform(ForwardIterator , ForwardIterator ) const
+ { return static_object<string_type>::get(); }
+ template <class ForwardIterator>
+ string_type transform_primary(ForwardIterator , ForwardIterator ) const
+ { return static_object<string_type>::get(); }
+
+ template <class ForwardIterator>
+ char_class_type lookup_classname(ForwardIterator , ForwardIterator ) const
+ { return static_object<char_class_type>::get(); }
+ template <class ForwardIterator>
+ string_type lookup_collatename(ForwardIterator , ForwardIterator ) const
+ { return static_object<string_type>::get(); }
+
+ bool isctype(charT, char_class_type) const
+ { return false; }
+ int value(charT, int) const
+ { return 0; }
+
+ locale_type imbue(locale_type l)
+ { return l; }
+ locale_type getloc()const
+ { return static_object<locale_type>::get(); }
+
+private:
+ // this type is not copyable:
+ regex_traits_architype(const regex_traits_architype&);
+ regex_traits_architype& operator=(const regex_traits_architype&);
+};
+
+//
+// alter this to std::tr1, to test a std implementation:
+//
+#ifndef BOOST_TEST_TR1_REGEX
+namespace global_regex_namespace = ::boost;
+#else
+namespace global_regex_namespace = ::std::tr1;
+#endif
+
+template <class Bitmask>
+struct BitmaskConcept
+{
+ void constraints()
+ {
+ function_requires<CopyConstructibleConcept<Bitmask> >();
+ function_requires<AssignableConcept<Bitmask> >();
+
+ m_mask1 = m_mask2 | m_mask3;
+ m_mask1 = m_mask2 & m_mask3;
+ m_mask1 = m_mask2 ^ m_mask3;
+
+ m_mask1 = ~m_mask2;
+
+ m_mask1 |= m_mask2;
+ m_mask1 &= m_mask2;
+ m_mask1 ^= m_mask2;
+ }
+ Bitmask m_mask1, m_mask2, m_mask3;
+};
+
+template <class traits>
+struct RegexTraitsConcept
+{
+ RegexTraitsConcept();
+ // required typedefs:
+ typedef typename traits::char_type char_type;
+ // typedef typename traits::size_type size_type;
+ typedef typename traits::string_type string_type;
+ typedef typename traits::locale_type locale_type;
+ typedef typename traits::char_class_type char_class_type;
+
+ void constraints()
+ {
+ //function_requires<UnsignedIntegerConcept<size_type> >();
+ function_requires<RandomAccessContainerConcept<string_type> >();
+ function_requires<DefaultConstructibleConcept<locale_type> >();
+ function_requires<CopyConstructibleConcept<locale_type> >();
+ function_requires<AssignableConcept<locale_type> >();
+ function_requires<BitmaskConcept<char_class_type> >();
+
+ std::size_t n = traits::length(m_pointer);
+ ignore_unused_variable_warning(n);
+
+ char_type c = m_ctraits.translate(m_char);
+ ignore_unused_variable_warning(c);
+ c = m_ctraits.translate_nocase(m_char);
+
+ //string_type::foobar bar;
+ string_type s1 = m_ctraits.transform(m_pointer, m_pointer);
+ ignore_unused_variable_warning(s1);
+
+ string_type s2 = m_ctraits.transform_primary(m_pointer, m_pointer);
+ ignore_unused_variable_warning(s2);
+
+ char_class_type cc = m_ctraits.lookup_classname(m_pointer, m_pointer);
+ ignore_unused_variable_warning(cc);
+
+ string_type s3 = m_ctraits.lookup_collatename(m_pointer, m_pointer);
+ ignore_unused_variable_warning(s3);
+
+ bool b = m_ctraits.isctype(m_char, cc);
+ ignore_unused_variable_warning(b);
+
+ int v = m_ctraits.value(m_char, 16);
+ ignore_unused_variable_warning(v);
+
+ locale_type l(m_ctraits.getloc());
+ m_traits.imbue(l);
+ ignore_unused_variable_warning(l);
+ }
+ traits m_traits;
+ const traits m_ctraits;
+ const char_type* m_pointer;
+ char_type m_char;
+private:
+ RegexTraitsConcept& operator=(RegexTraitsConcept&);
+};
+
+//
+// helper class to compute what traits class a regular expression type is using:
+//
+template <class Regex>
+struct regex_traits_computer;
+
+template <class charT, class traits>
+struct regex_traits_computer< global_regex_namespace::basic_regex<charT, traits> >
+{
+ typedef traits type;
+};
+
+//
+// BaseRegexConcept does not test anything dependent on basic_string,
+// in case our charT does not have an associated char_traits:
+//
+template <class Regex>
+struct BaseRegexConcept
+{
+ typedef typename Regex::value_type value_type;
+ //typedef typename Regex::size_type size_type;
+ typedef typename Regex::flag_type flag_type;
+ typedef typename Regex::locale_type locale_type;
+ typedef input_iterator_archetype<value_type> input_iterator_type;
+
+ // derived test types:
+ typedef const value_type* pointer_type;
+ typedef bidirectional_iterator_archetype<value_type> BidiIterator;
+ typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;
+ typedef global_regex_namespace::match_results<BidiIterator> match_results_type;
+ typedef output_iterator_archetype<value_type> OutIterator;
+ typedef typename regex_traits_computer<Regex>::type traits_type;
+ typedef global_regex_namespace::regex_iterator<BidiIterator, value_type, traits_type> regex_iterator_type;
+ typedef global_regex_namespace::regex_token_iterator<BidiIterator, value_type, traits_type> regex_token_iterator_type;
+
+ void global_constraints()
+ {
+ //
+ // test non-template components:
+ //
+ function_requires<BitmaskConcept<global_regex_namespace::regex_constants::syntax_option_type> >();
+ global_regex_namespace::regex_constants::syntax_option_type opts
+ = global_regex_namespace::regex_constants::icase
+ | global_regex_namespace::regex_constants::nosubs
+ | global_regex_namespace::regex_constants::optimize
+ | global_regex_namespace::regex_constants::collate
+ | global_regex_namespace::regex_constants::ECMAScript
+ | global_regex_namespace::regex_constants::basic
+ | global_regex_namespace::regex_constants::extended
+ | global_regex_namespace::regex_constants::awk
+ | global_regex_namespace::regex_constants::grep
+ | global_regex_namespace::regex_constants::egrep;
+ ignore_unused_variable_warning(opts);
+
+ function_requires<BitmaskConcept<global_regex_namespace::regex_constants::match_flag_type> >();
+ global_regex_namespace::regex_constants::match_flag_type mopts
+ = global_regex_namespace::regex_constants::match_default
+ | global_regex_namespace::regex_constants::match_not_bol
+ | global_regex_namespace::regex_constants::match_not_eol
+ | global_regex_namespace::regex_constants::match_not_bow
+ | global_regex_namespace::regex_constants::match_not_eow
+ | global_regex_namespace::regex_constants::match_any
+ | global_regex_namespace::regex_constants::match_not_null
+ | global_regex_namespace::regex_constants::match_continuous
+ | global_regex_namespace::regex_constants::match_prev_avail
+ | global_regex_namespace::regex_constants::format_default
+ | global_regex_namespace::regex_constants::format_sed
+ | global_regex_namespace::regex_constants::format_no_copy
+ | global_regex_namespace::regex_constants::format_first_only;
+ ignore_unused_variable_warning(mopts);
+
+ BOOST_STATIC_ASSERT((::boost::is_enum<global_regex_namespace::regex_constants::error_type>::value));
+ global_regex_namespace::regex_constants::error_type e1 = global_regex_namespace::regex_constants::error_collate;
+ ignore_unused_variable_warning(e1);
+ e1 = global_regex_namespace::regex_constants::error_ctype;
+ ignore_unused_variable_warning(e1);
+ e1 = global_regex_namespace::regex_constants::error_escape;
+ ignore_unused_variable_warning(e1);
+ e1 = global_regex_namespace::regex_constants::error_backref;
+ ignore_unused_variable_warning(e1);
+ e1 = global_regex_namespace::regex_constants::error_brack;
+ ignore_unused_variable_warning(e1);
+ e1 = global_regex_namespace::regex_constants::error_paren;
+ ignore_unused_variable_warning(e1);
+ e1 = global_regex_namespace::regex_constants::error_brace;
+ ignore_unused_variable_warning(e1);
+ e1 = global_regex_namespace::regex_constants::error_badbrace;
+ ignore_unused_variable_warning(e1);
+ e1 = global_regex_namespace::regex_constants::error_range;
+ ignore_unused_variable_warning(e1);
+ e1 = global_regex_namespace::regex_constants::error_space;
+ ignore_unused_variable_warning(e1);
+ e1 = global_regex_namespace::regex_constants::error_badrepeat;
+ ignore_unused_variable_warning(e1);
+ e1 = global_regex_namespace::regex_constants::error_complexity;
+ ignore_unused_variable_warning(e1);
+ e1 = global_regex_namespace::regex_constants::error_stack;
+ ignore_unused_variable_warning(e1);
+
+ BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::runtime_error, global_regex_namespace::regex_error>::value ));
+ const global_regex_namespace::regex_error except(e1);
+ e1 = except.code();
+
+ typedef typename Regex::value_type value_type;
+ function_requires< RegexTraitsConcept<global_regex_namespace::regex_traits<char> > >();
+ function_requires< BaseRegexConcept<global_regex_namespace::basic_regex<char> > >();
+ }
+ void constraints()
+ {
+ global_constraints();
+
+ BOOST_STATIC_ASSERT((::boost::is_same< flag_type, global_regex_namespace::regex_constants::syntax_option_type>::value));
+ flag_type opts
+ = Regex::icase
+ | Regex::nosubs
+ | Regex::optimize
+ | Regex::collate
+ | Regex::ECMAScript
+ | Regex::basic
+ | Regex::extended
+ | Regex::awk
+ | Regex::grep
+ | Regex::egrep;
+ ignore_unused_variable_warning(opts);
+
+ function_requires<DefaultConstructibleConcept<Regex> >();
+ function_requires<CopyConstructibleConcept<Regex> >();
+
+ // Regex constructors:
+ Regex e1(m_pointer);
+ ignore_unused_variable_warning(e1);
+ Regex e2(m_pointer, m_flags);
+ ignore_unused_variable_warning(e2);
+ Regex e3(m_pointer, m_size, m_flags);
+ ignore_unused_variable_warning(e3);
+ Regex e4(in1, in2);
+ ignore_unused_variable_warning(e4);
+ Regex e5(in1, in2, m_flags);
+ ignore_unused_variable_warning(e5);
+
+ // assign etc:
+ Regex e;
+ e = m_pointer;
+ e = e1;
+ e.assign(e1);
+ e.assign(m_pointer);
+ e.assign(m_pointer, m_flags);
+ e.assign(m_pointer, m_size, m_flags);
+ e.assign(in1, in2);
+ e.assign(in1, in2, m_flags);
+
+ // access:
+ const Regex ce;
+ unsigned i = ce.mark_count();
+ ignore_unused_variable_warning(i);
+ m_flags = ce.flags();
+ e.imbue(ce.getloc());
+ e.swap(e1);
+
+ global_regex_namespace::swap(e, e1);
+
+ // sub_match:
+ BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::pair<BidiIterator, BidiIterator>, sub_match_type>::value));
+ typedef typename sub_match_type::value_type sub_value_type;
+ typedef typename sub_match_type::difference_type sub_diff_type;
+ typedef typename sub_match_type::iterator sub_iter_type;
+ BOOST_STATIC_ASSERT((::boost::is_same<sub_value_type, value_type>::value));
+ BOOST_STATIC_ASSERT((::boost::is_same<sub_iter_type, BidiIterator>::value));
+ bool b = m_sub.matched;
+ ignore_unused_variable_warning(b);
+ BidiIterator bi = m_sub.first;
+ ignore_unused_variable_warning(bi);
+ bi = m_sub.second;
+ ignore_unused_variable_warning(bi);
+ sub_diff_type diff = m_sub.length();
+ ignore_unused_variable_warning(diff);
+ // match_results tests:
+ typedef typename match_results_type::value_type mr_value_type;
+ typedef typename match_results_type::const_reference mr_const_reference;
+ typedef typename match_results_type::reference mr_reference;
+ typedef typename match_results_type::const_iterator mr_const_iterator;
+ typedef typename match_results_type::iterator mr_iterator;
+ typedef typename match_results_type::difference_type mr_difference_type;
+ typedef typename match_results_type::size_type mr_size_type;
+ typedef typename match_results_type::allocator_type mr_allocator_type;
+ typedef typename match_results_type::char_type mr_char_type;
+ typedef typename match_results_type::string_type mr_string_type;
+
+ match_results_type m1;
+ mr_allocator_type at;
+ match_results_type m2(at);
+ match_results_type m3(m1);
+ m1 = m2;
+
+ int ival = 0;
+
+ mr_size_type mrs = m_cresults.size();
+ ignore_unused_variable_warning(mrs);
+ mrs = m_cresults.max_size();
+ ignore_unused_variable_warning(mrs);
+ b = m_cresults.empty();
+ ignore_unused_variable_warning(b);
+ mr_difference_type mrd = m_cresults.length();
+ ignore_unused_variable_warning(mrd);
+ mrd = m_cresults.length(ival);
+ ignore_unused_variable_warning(mrd);
+ mrd = m_cresults.position();
+ ignore_unused_variable_warning(mrd);
+ mrd = m_cresults.position(mrs);
+ ignore_unused_variable_warning(mrd);
+
+ mr_const_reference mrcr = m_cresults[ival];
+ ignore_unused_variable_warning(mrcr);
+ mr_const_reference mrcr2 = m_cresults.prefix();
+ ignore_unused_variable_warning(mrcr2);
+ mr_const_reference mrcr3 = m_cresults.suffix();
+ ignore_unused_variable_warning(mrcr3);
+ mr_const_iterator mrci = m_cresults.begin();
+ ignore_unused_variable_warning(mrci);
+ mrci = m_cresults.end();
+ ignore_unused_variable_warning(mrci);
+
+ mr_allocator_type at2 = m_cresults.get_allocator();
+ m_results.swap(m_results);
+ global_regex_namespace::swap(m_results, m_results);
+
+ // regex_match:
+ b = global_regex_namespace::regex_match(m_in, m_in, m_results, e);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_match(m_in, m_in, m_results, e, m_mft);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_match(m_in, m_in, e);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_match(m_in, m_in, e, m_mft);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_match(m_pointer, m_pmatch, e);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_match(m_pointer, m_pmatch, e, m_mft);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_match(m_pointer, e);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_match(m_pointer, e, m_mft);
+ ignore_unused_variable_warning(b);
+ // regex_search:
+ b = global_regex_namespace::regex_search(m_in, m_in, m_results, e);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_search(m_in, m_in, m_results, e, m_mft);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_search(m_in, m_in, e);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_search(m_in, m_in, e, m_mft);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_search(m_pointer, m_pmatch, e);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_search(m_pointer, m_pmatch, e, m_mft);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_search(m_pointer, e);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_search(m_pointer, e, m_mft);
+ ignore_unused_variable_warning(b);
+
+ // regex_iterator:
+ typedef typename regex_iterator_type::regex_type rit_regex_type;
+ typedef typename regex_iterator_type::value_type rit_value_type;
+ typedef typename regex_iterator_type::difference_type rit_difference_type;
+ typedef typename regex_iterator_type::pointer rit_pointer;
+ typedef typename regex_iterator_type::reference rit_reference;
+ typedef typename regex_iterator_type::iterator_category rit_iterator_category;
+ BOOST_STATIC_ASSERT((::boost::is_same<rit_regex_type, Regex>::value));
+ BOOST_STATIC_ASSERT((::boost::is_same<rit_value_type, match_results_type>::value));
+ BOOST_STATIC_ASSERT((::boost::is_same<rit_difference_type, std::ptrdiff_t>::value));
+ BOOST_STATIC_ASSERT((::boost::is_same<rit_pointer, const match_results_type*>::value));
+ BOOST_STATIC_ASSERT((::boost::is_same<rit_reference, const match_results_type&>::value));
+ BOOST_STATIC_ASSERT((::boost::is_convertible<rit_iterator_category*, std::forward_iterator_tag*>::value));
+ // this takes care of most of the checks needed:
+ function_requires<ForwardIteratorConcept<regex_iterator_type> >();
+ regex_iterator_type iter1(m_in, m_in, e);
+ ignore_unused_variable_warning(iter1);
+ regex_iterator_type iter2(m_in, m_in, e, m_mft);
+ ignore_unused_variable_warning(iter2);
+
+ // regex_token_iterator:
+ typedef typename regex_token_iterator_type::regex_type rtit_regex_type;
+ typedef typename regex_token_iterator_type::value_type rtit_value_type;
+ typedef typename regex_token_iterator_type::difference_type rtit_difference_type;
+ typedef typename regex_token_iterator_type::pointer rtit_pointer;
+ typedef typename regex_token_iterator_type::reference rtit_reference;
+ typedef typename regex_token_iterator_type::iterator_category rtit_iterator_category;
+ BOOST_STATIC_ASSERT((::boost::is_same<rtit_regex_type, Regex>::value));
+ BOOST_STATIC_ASSERT((::boost::is_same<rtit_value_type, sub_match_type>::value));
+ BOOST_STATIC_ASSERT((::boost::is_same<rtit_difference_type, std::ptrdiff_t>::value));
+ BOOST_STATIC_ASSERT((::boost::is_same<rtit_pointer, const sub_match_type*>::value));
+ BOOST_STATIC_ASSERT((::boost::is_same<rtit_reference, const sub_match_type&>::value));
+ BOOST_STATIC_ASSERT((::boost::is_convertible<rtit_iterator_category*, std::forward_iterator_tag*>::value));
+ // this takes care of most of the checks needed:
+ function_requires<ForwardIteratorConcept<regex_token_iterator_type> >();
+ regex_token_iterator_type ti1(m_in, m_in, e);
+ ignore_unused_variable_warning(ti1);
+ regex_token_iterator_type ti2(m_in, m_in, e, 0);
+ ignore_unused_variable_warning(ti2);
+ regex_token_iterator_type ti3(m_in, m_in, e, 0, m_mft);
+ ignore_unused_variable_warning(ti3);
+ std::vector<int> subs;
+ regex_token_iterator_type ti4(m_in, m_in, e, subs);
+ ignore_unused_variable_warning(ti4);
+ regex_token_iterator_type ti5(m_in, m_in, e, subs, m_mft);
+ ignore_unused_variable_warning(ti5);
+ static const int i_array[3] = { 1, 2, 3, };
+ regex_token_iterator_type ti6(m_in, m_in, e, i_array);
+ ignore_unused_variable_warning(ti6);
+ regex_token_iterator_type ti7(m_in, m_in, e, i_array, m_mft);
+ ignore_unused_variable_warning(ti7);
+ }
+
+ pointer_type m_pointer;
+ flag_type m_flags;
+ std::size_t m_size;
+ input_iterator_type in1, in2;
+ const sub_match_type m_sub;
+ const value_type m_char;
+ match_results_type m_results;
+ const match_results_type m_cresults;
+ OutIterator m_out;
+ BidiIterator m_in;
+ global_regex_namespace::regex_constants::match_flag_type m_mft;
+ global_regex_namespace::match_results<pointer_type> m_pmatch;
+
+ BaseRegexConcept();
+ BaseRegexConcept(const BaseRegexConcept&);
+ BaseRegexConcept& operator=(const BaseRegexConcept&);
+};
+
+//
+// RegexConcept:
+// Test every interface in the std:
+//
+template <class Regex>
+struct RegexConcept
+{
+ typedef typename Regex::value_type value_type;
+ //typedef typename Regex::size_type size_type;
+ typedef typename Regex::flag_type flag_type;
+ typedef typename Regex::locale_type locale_type;
+
+ // derived test types:
+ typedef const value_type* pointer_type;
+ typedef std::basic_string<value_type> string_type;
+ typedef boost::bidirectional_iterator_archetype<value_type> BidiIterator;
+ typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;
+ typedef global_regex_namespace::match_results<BidiIterator> match_results_type;
+ typedef output_iterator_archetype<value_type> OutIterator;
+
+
+ void constraints()
+ {
+ function_requires<BaseRegexConcept<Regex> >();
+ // string based construct:
+ Regex e1(m_string);
+ ignore_unused_variable_warning(e1);
+ Regex e2(m_string, m_flags);
+ ignore_unused_variable_warning(e2);
+
+ // assign etc:
+ Regex e;
+ e = m_string;
+ e.assign(m_string);
+ e.assign(m_string, m_flags);
+
+ // sub_match:
+ string_type s(m_sub);
+ ignore_unused_variable_warning(s);
+ s = m_sub.str();
+ ignore_unused_variable_warning(s);
+ int i = m_sub.compare(m_string);
+ ignore_unused_variable_warning(i);
+
+ int i2 = m_sub.compare(m_sub);
+ ignore_unused_variable_warning(i2);
+ i2 = m_sub.compare(m_pointer);
+ ignore_unused_variable_warning(i2);
+
+ bool b = m_sub == m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_sub != m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_sub <= m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_sub <= m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_sub > m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_sub >= m_sub;
+ ignore_unused_variable_warning(b);
+
+ b = m_sub == m_pointer;
+ ignore_unused_variable_warning(b);
+ b = m_sub != m_pointer;
+ ignore_unused_variable_warning(b);
+ b = m_sub <= m_pointer;
+ ignore_unused_variable_warning(b);
+ b = m_sub <= m_pointer;
+ ignore_unused_variable_warning(b);
+ b = m_sub > m_pointer;
+ ignore_unused_variable_warning(b);
+ b = m_sub >= m_pointer;
+ ignore_unused_variable_warning(b);
+
+ b = m_pointer == m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_pointer != m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_pointer <= m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_pointer <= m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_pointer > m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_pointer >= m_sub;
+ ignore_unused_variable_warning(b);
+
+ b = m_sub == m_char;
+ ignore_unused_variable_warning(b);
+ b = m_sub != m_char;
+ ignore_unused_variable_warning(b);
+ b = m_sub <= m_char;
+ ignore_unused_variable_warning(b);
+ b = m_sub <= m_char;
+ ignore_unused_variable_warning(b);
+ b = m_sub > m_char;
+ ignore_unused_variable_warning(b);
+ b = m_sub >= m_char;
+ ignore_unused_variable_warning(b);
+
+ b = m_char == m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_char != m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_char <= m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_char <= m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_char > m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_char >= m_sub;
+ ignore_unused_variable_warning(b);
+
+ b = m_sub == m_string;
+ ignore_unused_variable_warning(b);
+ b = m_sub != m_string;
+ ignore_unused_variable_warning(b);
+ b = m_sub <= m_string;
+ ignore_unused_variable_warning(b);
+ b = m_sub <= m_string;
+ ignore_unused_variable_warning(b);
+ b = m_sub > m_string;
+ ignore_unused_variable_warning(b);
+ b = m_sub >= m_string;
+ ignore_unused_variable_warning(b);
+
+ b = m_string == m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_string != m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_string <= m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_string <= m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_string > m_sub;
+ ignore_unused_variable_warning(b);
+ b = m_string >= m_sub;
+ ignore_unused_variable_warning(b);
+
+ // match results:
+ m_string = m_results.str();
+ ignore_unused_variable_warning(m_string);
+ m_string = m_results.str(0);
+ ignore_unused_variable_warning(m_string);
+ m_out = m_cresults.format(m_out, m_string);
+ m_out = m_cresults.format(m_out, m_string, m_mft);
+ m_string = m_cresults.format(m_string);
+ ignore_unused_variable_warning(m_string);
+ m_string = m_cresults.format(m_string, m_mft);
+ ignore_unused_variable_warning(m_string);
+
+ // regex_match:
+ b = global_regex_namespace::regex_match(m_string, m_smatch, e);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_match(m_string, m_smatch, e, m_mft);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_match(m_string, e);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_match(m_string, e, m_mft);
+ ignore_unused_variable_warning(b);
+
+ // regex_search:
+ b = global_regex_namespace::regex_search(m_string, m_smatch, e);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_search(m_string, m_smatch, e, m_mft);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_search(m_string, e);
+ ignore_unused_variable_warning(b);
+ b = global_regex_namespace::regex_search(m_string, e, m_mft);
+ ignore_unused_variable_warning(b);
+
+ // regex_replace:
+ m_out = global_regex_namespace::regex_replace(m_out, m_in, m_in, e, m_string, m_mft);
+ m_out = global_regex_namespace::regex_replace(m_out, m_in, m_in, e, m_string);
+ m_string = global_regex_namespace::regex_replace(m_string, e, m_string, m_mft);
+ ignore_unused_variable_warning(m_string);
+ m_string = global_regex_namespace::regex_replace(m_string, e, m_string);
+ ignore_unused_variable_warning(m_string);
+
+ }
+
+ flag_type m_flags;
+ string_type m_string;
+ const sub_match_type m_sub;
+ match_results_type m_results;
+ pointer_type m_pointer;
+ value_type m_char;
+ const match_results_type m_cresults;
+ OutIterator m_out;
+ BidiIterator m_in;
+ global_regex_namespace::regex_constants::match_flag_type m_mft;
+ global_regex_namespace::match_results<typename string_type::const_iterator> m_smatch;
+
+ RegexConcept();
+ RegexConcept(const RegexConcept&);
+ RegexConcept& operator=(const RegexConcept&);
+};
+
+#ifndef BOOST_REGEX_TEST_STD
+//
+// BoostRegexConcept:
+// Test every interface in the Boost implementation:
+//
+template <class Regex>
+struct BoostRegexConcept
+{
+ typedef typename Regex::value_type value_type;
+ typedef typename Regex::size_type size_type;
+ typedef typename Regex::flag_type flag_type;
+ typedef typename Regex::locale_type locale_type;
+
+ // derived test types:
+ typedef const value_type* pointer_type;
+ typedef std::basic_string<value_type> string_type;
+ typedef typename Regex::const_iterator const_iterator;
+ typedef bidirectional_iterator_archetype<value_type> BidiIterator;
+ typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;
+ typedef global_regex_namespace::match_results<BidiIterator> match_results_type;
+
+ void constraints()
+ {
+ global_regex_namespace::regex_constants::match_flag_type mopts
+ = global_regex_namespace::regex_constants::match_default
+ | global_regex_namespace::regex_constants::match_not_bol
+ | global_regex_namespace::regex_constants::match_not_eol
+ | global_regex_namespace::regex_constants::match_not_bow
+ | global_regex_namespace::regex_constants::match_not_eow
+ | global_regex_namespace::regex_constants::match_any
+ | global_regex_namespace::regex_constants::match_not_null
+ | global_regex_namespace::regex_constants::match_continuous
+ | global_regex_namespace::regex_constants::match_partial
+ | global_regex_namespace::regex_constants::match_prev_avail
+ | global_regex_namespace::regex_constants::format_default
+ | global_regex_namespace::regex_constants::format_sed
+ | global_regex_namespace::regex_constants::format_perl
+ | global_regex_namespace::regex_constants::format_no_copy
+ | global_regex_namespace::regex_constants::format_first_only;
+
+ (void)mopts;
+
+ function_requires<RegexConcept<Regex> >();
+ const global_regex_namespace::regex_error except(global_regex_namespace::regex_constants::error_collate);
+ std::ptrdiff_t pt = except.position();
+ ignore_unused_variable_warning(pt);
+ const Regex ce, ce2;
+#ifndef BOOST_NO_STD_LOCALE
+ m_stream << ce;
+#endif
+ unsigned i = ce.error_code();
+ ignore_unused_variable_warning(i);
+ pointer_type p = ce.expression();
+ ignore_unused_variable_warning(p);
+ int i2 = ce.compare(ce2);
+ ignore_unused_variable_warning(i2);
+ bool b = ce == ce2;
+ ignore_unused_variable_warning(b);
+ b = ce.empty();
+ ignore_unused_variable_warning(b);
+ b = ce != ce2;
+ ignore_unused_variable_warning(b);
+ b = ce < ce2;
+ ignore_unused_variable_warning(b);
+ b = ce > ce2;
+ ignore_unused_variable_warning(b);
+ b = ce <= ce2;
+ ignore_unused_variable_warning(b);
+ b = ce >= ce2;
+ ignore_unused_variable_warning(b);
+ i = ce.status();
+ ignore_unused_variable_warning(i);
+ size_type s = ce.max_size();
+ ignore_unused_variable_warning(s);
+ s = ce.size();
+ ignore_unused_variable_warning(s);
+ const_iterator pi = ce.begin();
+ ignore_unused_variable_warning(pi);
+ pi = ce.end();
+ ignore_unused_variable_warning(pi);
+ string_type s2 = ce.str();
+ ignore_unused_variable_warning(s2);
+
+ m_string = m_sub + m_sub;
+ ignore_unused_variable_warning(m_string);
+ m_string = m_sub + m_pointer;
+ ignore_unused_variable_warning(m_string);
+ m_string = m_pointer + m_sub;
+ ignore_unused_variable_warning(m_string);
+ m_string = m_sub + m_string;
+ ignore_unused_variable_warning(m_string);
+ m_string = m_string + m_sub;
+ ignore_unused_variable_warning(m_string);
+ m_string = m_sub + m_char;
+ ignore_unused_variable_warning(m_string);
+ m_string = m_char + m_sub;
+ ignore_unused_variable_warning(m_string);
+
+ // Named sub-expressions:
+ m_sub = m_cresults[&m_char];
+ ignore_unused_variable_warning(m_sub);
+ m_sub = m_cresults[m_string];
+ ignore_unused_variable_warning(m_sub);
+ m_sub = m_cresults[""];
+ ignore_unused_variable_warning(m_sub);
+ m_sub = m_cresults[std::string("")];
+ ignore_unused_variable_warning(m_sub);
+ m_string = m_cresults.str(&m_char);
+ ignore_unused_variable_warning(m_string);
+ m_string = m_cresults.str(m_string);
+ ignore_unused_variable_warning(m_string);
+ m_string = m_cresults.str("");
+ ignore_unused_variable_warning(m_string);
+ m_string = m_cresults.str(std::string(""));
+ ignore_unused_variable_warning(m_string);
+
+ typename match_results_type::difference_type diff;
+ diff = m_cresults.length(&m_char);
+ ignore_unused_variable_warning(diff);
+ diff = m_cresults.length(m_string);
+ ignore_unused_variable_warning(diff);
+ diff = m_cresults.length("");
+ ignore_unused_variable_warning(diff);
+ diff = m_cresults.length(std::string(""));
+ ignore_unused_variable_warning(diff);
+ diff = m_cresults.position(&m_char);
+ ignore_unused_variable_warning(diff);
+ diff = m_cresults.position(m_string);
+ ignore_unused_variable_warning(diff);
+ diff = m_cresults.position("");
+ ignore_unused_variable_warning(diff);
+ diff = m_cresults.position(std::string(""));
+ ignore_unused_variable_warning(diff);
+
+#ifndef BOOST_NO_STD_LOCALE
+ m_stream << m_sub;
+ m_stream << m_cresults;
+#endif
+ }
+
+ std::basic_ostream<value_type> m_stream;
+ sub_match_type m_sub;
+ pointer_type m_pointer;
+ string_type m_string;
+ const value_type m_char;
+ match_results_type m_results;
+ const match_results_type m_cresults;
+
+ BoostRegexConcept();
+ BoostRegexConcept(const BoostRegexConcept&);
+ BoostRegexConcept& operator=(const BoostRegexConcept&);
+};
+
+#endif // BOOST_REGEX_TEST_STD
+
+}
+
+#endif
diff --git a/ext/boost/regex/config.hpp b/ext/boost/regex/config.hpp
new file mode 100644
index 0000000000..8306f3ff9a
--- /dev/null
+++ b/ext/boost/regex/config.hpp
@@ -0,0 +1,417 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE config.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: regex extended config setup.
+ */
+
+#ifndef BOOST_REGEX_CONFIG_HPP
+#define BOOST_REGEX_CONFIG_HPP
+/*
+ * Borland C++ Fix/error check
+ * this has to go *before* we include any std lib headers:
+ */
+#if defined(__BORLANDC__)
+# include <boost/regex/config/borland.hpp>
+#endif
+
+/*****************************************************************************
+ *
+ * Include all the headers we need here:
+ *
+ ****************************************************************************/
+
+#ifdef __cplusplus
+
+# ifndef BOOST_REGEX_USER_CONFIG
+# define BOOST_REGEX_USER_CONFIG <boost/regex/user.hpp>
+# endif
+
+# include BOOST_REGEX_USER_CONFIG
+
+# include <boost/config.hpp>
+
+#else
+ /*
+ * C build,
+ * don't include <boost/config.hpp> because that may
+ * do C++ specific things in future...
+ */
+# include <stdlib.h>
+# include <stddef.h>
+# ifdef _MSC_VER
+# define BOOST_MSVC _MSC_VER
+# endif
+#endif
+
+/*****************************************************************************
+ *
+ * Boilerplate regex config options:
+ *
+ ****************************************************************************/
+
+/* Obsolete macro, use BOOST_VERSION instead: */
+#define BOOST_RE_VERSION 320
+
+/* fix: */
+#if defined(_UNICODE) && !defined(UNICODE)
+#define UNICODE
+#endif
+
+/*
+ * Fix for gcc prior to 3.4: std::ctype<wchar_t> doesn't allow
+ * masks to be combined, for example:
+ * std::use_facet<std::ctype<wchar_t> >.is(std::ctype_base::lower|std::ctype_base::upper, L'a');
+ * returns *false*.
+ */
+#ifdef __GLIBCPP__
+# define BOOST_REGEX_BUGGY_CTYPE_FACET
+#endif
+
+/*
+ * Intel C++ before 8.0 ends up with unresolved externals unless we turn off
+ * extern template support:
+ */
+#if defined(BOOST_INTEL) && defined(__cplusplus) && (BOOST_INTEL <= 800)
+# define BOOST_REGEX_NO_EXTERNAL_TEMPLATES
+#endif
+/*
+ * Visual C++ doesn't support external templates with C++ extensions turned off:
+ */
+#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
+# define BOOST_REGEX_NO_EXTERNAL_TEMPLATES
+#endif
+
+/*
+ * If there isn't good enough wide character support then there will
+ * be no wide character regular expressions:
+ */
+#if (defined(BOOST_NO_CWCHAR) || defined(BOOST_NO_CWCTYPE) || defined(BOOST_NO_STD_WSTRING))
+# if !defined(BOOST_NO_WREGEX)
+# define BOOST_NO_WREGEX
+# endif
+#else
+# if defined(__sgi) && (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))
+ /* STLPort on IRIX is misconfigured: <cwctype> does not compile
+ * as a temporary fix include <wctype.h> instead and prevent inclusion
+ * of STLPort version of <cwctype> */
+# include <wctype.h>
+# define __STLPORT_CWCTYPE
+# define _STLP_CWCTYPE
+# endif
+
+#ifdef __cplusplus
+# include <boost/regex/config/cwchar.hpp>
+#endif
+
+#endif
+
+/*
+ * If Win32 support has been disabled for boost in general, then
+ * it is for regex in particular:
+ */
+#if defined(BOOST_DISABLE_WIN32) && !defined(BOOST_REGEX_NO_W32)
+# define BOOST_REGEX_NO_W32
+#endif
+
+/* disable our own file-iterators and mapfiles if we can't
+ * support them: */
+#if !defined(BOOST_HAS_DIRENT_H) && !(defined(_WIN32) && !defined(BOOST_REGEX_NO_W32))
+# define BOOST_REGEX_NO_FILEITER
+#endif
+
+/* backwards compatibitity: */
+#if defined(BOOST_RE_NO_LIB)
+# define BOOST_REGEX_NO_LIB
+#endif
+
+#if defined(__GNUC__) && (defined(_WIN32) || defined(__CYGWIN__))
+/* gcc on win32 has problems if you include <windows.h>
+ (sporadically generates bad code). */
+# define BOOST_REGEX_NO_W32
+#endif
+#if defined(__COMO__) && !defined(BOOST_REGEX_NO_W32) && !defined(_MSC_EXTENSIONS)
+# define BOOST_REGEX_NO_W32
+#endif
+
+/*****************************************************************************
+ *
+ * Wide character workarounds:
+ *
+ ****************************************************************************/
+
+/*
+ * define BOOST_REGEX_HAS_OTHER_WCHAR_T when wchar_t is a native type, but the users
+ * code may be built with wchar_t as unsigned short: basically when we're building
+ * with MSVC and the /Zc:wchar_t option we place some extra unsigned short versions
+ * of the non-inline functions in the library, so that users can still link to the lib,
+ * irrespective of whether their own code is built with /Zc:wchar_t.
+ */
+#if defined(__cplusplus) && (defined(BOOST_MSVC) || defined(__ICL)) && !defined(BOOST_NO_INTRINSIC_WCHAR_T) && defined(BOOST_WINDOWS) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) && !defined(BOOST_RWSTD_VER)
+# define BOOST_REGEX_HAS_OTHER_WCHAR_T
+# ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable : 4251 4231 4660)
+# endif
+# if defined(_DLL) && defined(BOOST_MSVC) && (BOOST_MSVC < 1600)
+# include <string>
+ extern template class __declspec(dllimport) std::basic_string<unsigned short>;
+# endif
+# ifdef BOOST_MSVC
+# pragma warning(pop)
+# endif
+#endif
+
+
+/*****************************************************************************
+ *
+ * Set up dll import/export options:
+ *
+ ****************************************************************************/
+
+#if defined(BOOST_HAS_DECLSPEC) && (defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_REGEX_STATIC_LINK)
+# if defined(BOOST_REGEX_SOURCE)
+# define BOOST_REGEX_DECL __declspec(dllexport)
+# define BOOST_REGEX_BUILD_DLL
+# else
+# define BOOST_REGEX_DECL __declspec(dllimport)
+# endif
+#endif
+
+#ifndef BOOST_REGEX_DECL
+# define BOOST_REGEX_DECL
+#endif
+
+#if !defined(BOOST_REGEX_NO_LIB) && !defined(BOOST_REGEX_SOURCE) && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus)
+# define BOOST_LIB_NAME boost_regex
+# if defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
+# define BOOST_DYN_LINK
+# endif
+# ifdef BOOST_REGEX_DIAG
+# define BOOST_LIB_DIAGNOSTIC
+# endif
+# include <boost/config/auto_link.hpp>
+#endif
+
+/*****************************************************************************
+ *
+ * Set up function call type:
+ *
+ ****************************************************************************/
+
+#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1200) && defined(_MSC_EXTENSIONS)
+#if defined(_DEBUG) || defined(__MSVC_RUNTIME_CHECKS) || defined(_MANAGED)
+# define BOOST_REGEX_CALL __cdecl
+#else
+# define BOOST_REGEX_CALL __fastcall
+#endif
+# define BOOST_REGEX_CCALL __cdecl
+#endif
+
+#if defined(__BORLANDC__) && !defined(BOOST_DISABLE_WIN32)
+# define BOOST_REGEX_CALL __fastcall
+# define BOOST_REGEX_CCALL __stdcall
+#endif
+
+#ifndef BOOST_REGEX_CALL
+# define BOOST_REGEX_CALL
+#endif
+#ifndef BOOST_REGEX_CCALL
+#define BOOST_REGEX_CCALL
+#endif
+
+/*****************************************************************************
+ *
+ * Set up localisation model:
+ *
+ ****************************************************************************/
+
+/* backwards compatibility: */
+#ifdef BOOST_RE_LOCALE_C
+# define BOOST_REGEX_USE_C_LOCALE
+#endif
+
+#ifdef BOOST_RE_LOCALE_CPP
+# define BOOST_REGEX_USE_CPP_LOCALE
+#endif
+
+/* Win32 defaults to native Win32 locale: */
+#if defined(_WIN32) && !defined(BOOST_REGEX_USE_WIN32_LOCALE) && !defined(BOOST_REGEX_USE_C_LOCALE) && !defined(BOOST_REGEX_USE_CPP_LOCALE) && !defined(BOOST_REGEX_NO_W32)
+# define BOOST_REGEX_USE_WIN32_LOCALE
+#endif
+/* otherwise use C++ locale if supported: */
+#if !defined(BOOST_REGEX_USE_WIN32_LOCALE) && !defined(BOOST_REGEX_USE_C_LOCALE) && !defined(BOOST_REGEX_USE_CPP_LOCALE) && !defined(BOOST_NO_STD_LOCALE)
+# define BOOST_REGEX_USE_CPP_LOCALE
+#endif
+/* otherwise use C+ locale: */
+#if !defined(BOOST_REGEX_USE_WIN32_LOCALE) && !defined(BOOST_REGEX_USE_C_LOCALE) && !defined(BOOST_REGEX_USE_CPP_LOCALE)
+# define BOOST_REGEX_USE_C_LOCALE
+#endif
+
+#ifndef BOOST_REGEX_MAX_STATE_COUNT
+# define BOOST_REGEX_MAX_STATE_COUNT 100000000
+#endif
+
+
+/*****************************************************************************
+ *
+ * Error Handling for exception free compilers:
+ *
+ ****************************************************************************/
+
+#ifdef BOOST_NO_EXCEPTIONS
+/*
+ * If there are no exceptions then we must report critical-errors
+ * the only way we know how; by terminating.
+ */
+#include <stdexcept>
+#include <string>
+#include <boost/throw_exception.hpp>
+
+# define BOOST_REGEX_NOEH_ASSERT(x)\
+if(0 == (x))\
+{\
+ std::string s("Error: critical regex++ failure in: ");\
+ s.append(#x);\
+ std::runtime_error e(s);\
+ boost::throw_exception(e);\
+}
+#else
+/*
+ * With exceptions then error handling is taken care of and
+ * there is no need for these checks:
+ */
+# define BOOST_REGEX_NOEH_ASSERT(x)
+#endif
+
+
+/*****************************************************************************
+ *
+ * Stack protection under MS Windows:
+ *
+ ****************************************************************************/
+
+#if !defined(BOOST_REGEX_NO_W32) && !defined(BOOST_REGEX_V3)
+# if(defined(_WIN32) || defined(_WIN64) || defined(_WINCE)) \
+ && !defined(__GNUC__) \
+ && !(defined(__BORLANDC__) && (__BORLANDC__ >= 0x600)) \
+ && !(defined(__MWERKS__) && (__MWERKS__ <= 0x3003))
+# define BOOST_REGEX_HAS_MS_STACK_GUARD
+# endif
+#elif defined(BOOST_REGEX_HAS_MS_STACK_GUARD)
+# undef BOOST_REGEX_HAS_MS_STACK_GUARD
+#endif
+
+#if defined(__cplusplus) && defined(BOOST_REGEX_HAS_MS_STACK_GUARD)
+
+namespace boost{
+namespace re_detail{
+
+BOOST_REGEX_DECL void BOOST_REGEX_CALL reset_stack_guard_page();
+
+}
+}
+
+#endif
+
+
+/*****************************************************************************
+ *
+ * Algorithm selection and configuration:
+ *
+ ****************************************************************************/
+
+#if !defined(BOOST_REGEX_RECURSIVE) && !defined(BOOST_REGEX_NON_RECURSIVE)
+# if defined(BOOST_REGEX_HAS_MS_STACK_GUARD) && !defined(_STLP_DEBUG) && !defined(__STL_DEBUG) && !(defined(BOOST_MSVC) && (BOOST_MSVC >= 1400))
+# define BOOST_REGEX_RECURSIVE
+# else
+# define BOOST_REGEX_NON_RECURSIVE
+# endif
+#endif
+
+#ifdef BOOST_REGEX_NON_RECURSIVE
+# ifdef BOOST_REGEX_RECURSIVE
+# error "Can't set both BOOST_REGEX_RECURSIVE and BOOST_REGEX_NON_RECURSIVE"
+# endif
+# ifndef BOOST_REGEX_BLOCKSIZE
+# define BOOST_REGEX_BLOCKSIZE 4096
+# endif
+# if BOOST_REGEX_BLOCKSIZE < 512
+# error "BOOST_REGEX_BLOCKSIZE must be at least 512"
+# endif
+# ifndef BOOST_REGEX_MAX_BLOCKS
+# define BOOST_REGEX_MAX_BLOCKS 1024
+# endif
+# ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
+# undef BOOST_REGEX_HAS_MS_STACK_GUARD
+# endif
+# ifndef BOOST_REGEX_MAX_CACHE_BLOCKS
+# define BOOST_REGEX_MAX_CACHE_BLOCKS 16
+# endif
+#endif
+
+
+/*****************************************************************************
+ *
+ * helper memory allocation functions:
+ *
+ ****************************************************************************/
+
+#if defined(__cplusplus) && defined(BOOST_REGEX_NON_RECURSIVE)
+namespace boost{ namespace re_detail{
+
+BOOST_REGEX_DECL void* BOOST_REGEX_CALL get_mem_block();
+BOOST_REGEX_DECL void BOOST_REGEX_CALL put_mem_block(void*);
+
+}} /* namespaces */
+#endif
+
+/*****************************************************************************
+ *
+ * Diagnostics:
+ *
+ ****************************************************************************/
+
+#ifdef BOOST_REGEX_CONFIG_INFO
+BOOST_REGEX_DECL void BOOST_REGEX_CALL print_regex_library_info();
+#endif
+
+#if defined(BOOST_REGEX_DIAG)
+# pragma message ("BOOST_REGEX_DECL" BOOST_STRINGIZE(=BOOST_REGEX_DECL))
+# pragma message ("BOOST_REGEX_CALL" BOOST_STRINGIZE(=BOOST_REGEX_CALL))
+# pragma message ("BOOST_REGEX_CCALL" BOOST_STRINGIZE(=BOOST_REGEX_CCALL))
+#ifdef BOOST_REGEX_USE_C_LOCALE
+# pragma message ("Using C locale in regex traits class")
+#elif BOOST_REGEX_USE_CPP_LOCALE
+# pragma message ("Using C++ locale in regex traits class")
+#else
+# pragma message ("Using Win32 locale in regex traits class")
+#endif
+#if defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
+# pragma message ("Dynamic linking enabled")
+#endif
+#if defined(BOOST_REGEX_NO_LIB) || defined(BOOST_ALL_NO_LIB)
+# pragma message ("Auto-linking disabled")
+#endif
+#ifdef BOOST_REGEX_NO_EXTERNAL_TEMPLATES
+# pragma message ("Extern templates disabled")
+#endif
+
+#endif
+
+#endif
+
+
+
+
diff --git a/ext/boost/regex/config/borland.hpp b/ext/boost/regex/config/borland.hpp
new file mode 100644
index 0000000000..51c2126b8e
--- /dev/null
+++ b/ext/boost/regex/config/borland.hpp
@@ -0,0 +1,72 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE boost/regex/config/borland.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: regex borland-specific config setup.
+ */
+
+
+#if defined(__BORLANDC__)
+# if (__BORLANDC__ == 0x550) || (__BORLANDC__ == 0x551)
+ // problems with std::basic_string and dll RTL:
+# if defined(_RTLDLL) && defined(_RWSTD_COMPILE_INSTANTIATE)
+# ifdef BOOST_REGEX_BUILD_DLL
+# error _RWSTD_COMPILE_INSTANTIATE must not be defined when building regex++ as a DLL
+# else
+# pragma message("Defining _RWSTD_COMPILE_INSTANTIATE when linking to the DLL version of the RTL may produce memory corruption problems in std::basic_string, as a result of separate versions of basic_string's static data in the RTL and you're exe/dll: be warned!!")
+# endif
+# endif
+# ifndef _RTLDLL
+ // this is harmless for a staic link:
+# define _RWSTD_COMPILE_INSTANTIATE
+# endif
+ // external templates cause problems for some reason:
+# define BOOST_REGEX_NO_EXTERNAL_TEMPLATES
+# endif
+# if (__BORLANDC__ <= 0x540) && !defined(BOOST_REGEX_NO_LIB) && !defined(_NO_VCL)
+ // C++ Builder 4 and earlier, we can't tell whether we should be using
+ // the VCL runtime or not, do a static link instead:
+# define BOOST_REGEX_STATIC_LINK
+# endif
+ //
+ // VCL support:
+ // if we're building a console app then there can't be any VCL (can there?)
+# if !defined(__CONSOLE__) && !defined(_NO_VCL)
+# define BOOST_REGEX_USE_VCL
+# endif
+ //
+ // if this isn't Win32 then don't automatically select link
+ // libraries:
+ //
+# ifndef _Windows
+# ifndef BOOST_REGEX_NO_LIB
+# define BOOST_REGEX_NO_LIB
+# endif
+# ifndef BOOST_REGEX_STATIC_LINK
+# define BOOST_REGEX_STATIC_LINK
+# endif
+# endif
+
+#if __BORLANDC__ < 0x600
+//
+// string workarounds:
+//
+#include <cstring>
+#undef strcmp
+#undef strcpy
+#endif
+
+#endif
+
+
diff --git a/ext/boost/regex/config/cwchar.hpp b/ext/boost/regex/config/cwchar.hpp
new file mode 100644
index 0000000000..a55089d0ab
--- /dev/null
+++ b/ext/boost/regex/config/cwchar.hpp
@@ -0,0 +1,207 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE boost/regex/config/cwchar.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: regex wide character string fixes.
+ */
+
+#ifndef BOOST_REGEX_CONFIG_CWCHAR_HPP
+#define BOOST_REGEX_CONFIG_CWCHAR_HPP
+
+#include <cwchar>
+#include <cwctype>
+#include <boost/config.hpp>
+
+#if defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
+// apparently this is required for the RW STL on Linux:
+#undef iswalnum
+#undef iswalpha
+#undef iswblank
+#undef iswcntrl
+#undef iswdigit
+#undef iswgraph
+#undef iswlower
+#undef iswprint
+#undef iswprint
+#undef iswpunct
+#undef iswspace
+#undef iswupper
+#undef iswxdigit
+#undef iswctype
+#undef towlower
+#undef towupper
+#undef towctrans
+#undef wctrans
+#undef wctype
+#endif
+
+namespace std{
+
+#ifndef BOOST_NO_STDC_NAMESPACE
+extern "C"{
+#endif
+
+#ifdef iswalnum
+inline int (iswalnum)(wint_t i)
+{ return iswalnum(i); }
+#undef iswalnum
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::iswalnum;
+#endif
+
+#ifdef iswalpha
+inline int (iswalpha)(wint_t i)
+{ return iswalpha(i); }
+#undef iswalpha
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::iswalpha;
+#endif
+
+#ifdef iswcntrl
+inline int (iswcntrl)(wint_t i)
+{ return iswcntrl(i); }
+#undef iswcntrl
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::iswcntrl;
+#endif
+
+#ifdef iswdigit
+inline int (iswdigit)(wint_t i)
+{ return iswdigit(i); }
+#undef iswdigit
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::iswdigit;
+#endif
+
+#ifdef iswgraph
+inline int (iswgraph)(wint_t i)
+{ return iswgraph(i); }
+#undef iswgraph
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::iswgraph;
+#endif
+
+#ifdef iswlower
+inline int (iswlower)(wint_t i)
+{ return iswlower(i); }
+#undef iswlower
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::iswlower;
+#endif
+
+#ifdef iswprint
+inline int (iswprint)(wint_t i)
+{ return iswprint(i); }
+#undef iswprint
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::iswprint;
+#endif
+
+#ifdef iswpunct
+inline int (iswpunct)(wint_t i)
+{ return iswpunct(i); }
+#undef iswpunct
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::iswpunct;
+#endif
+
+#ifdef iswspace
+inline int (iswspace)(wint_t i)
+{ return iswspace(i); }
+#undef iswspace
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::iswspace;
+#endif
+
+#ifdef iswupper
+inline int (iswupper)(wint_t i)
+{ return iswupper(i); }
+#undef iswupper
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::iswupper;
+#endif
+
+#ifdef iswxdigit
+inline int (iswxdigit)(wint_t i)
+{ return iswxdigit(i); }
+#undef iswxdigit
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::iswxdigit;
+#endif
+
+#ifdef towlower
+inline wint_t (towlower)(wint_t i)
+{ return towlower(i); }
+#undef towlower
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::towlower;
+#endif
+
+#ifdef towupper
+inline wint_t (towupper)(wint_t i)
+{ return towupper(i); }
+#undef towupper
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using :: towupper;
+#endif
+
+#ifdef wcscmp
+inline int (wcscmp)(const wchar_t *p1, const wchar_t *p2)
+{ return wcscmp(p1,p2); }
+#undef wcscmp
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::wcscmp;
+#endif
+
+#ifdef wcscoll
+inline int (wcscoll)(const wchar_t *p1, const wchar_t *p2)
+{ return wcscoll(p1,p2); }
+#undef wcscoll
+#elif defined(BOOST_NO_STDC_NAMESPACE) && !defined(UNDER_CE)
+using ::wcscoll;
+#endif
+
+#ifdef wcscpy
+inline wchar_t *(wcscpy)(wchar_t *p1, const wchar_t *p2)
+{ return wcscpy(p1,p2); }
+#undef wcscpy
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::wcscpy;
+#endif
+
+#ifdef wcslen
+inline size_t (wcslen)(const wchar_t *p)
+{ return wcslen(p); }
+#undef wcslen
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::wcslen;
+#endif
+
+#ifdef wcsxfrm
+size_t wcsxfrm(wchar_t *p1, const wchar_t *p2, size_t s)
+{ return wcsxfrm(p1,p2,s); }
+#undef wcsxfrm
+#elif defined(BOOST_NO_STDC_NAMESPACE)
+using ::wcsxfrm;
+#endif
+
+
+#ifndef BOOST_NO_STDC_NAMESPACE
+} // extern "C"
+#endif
+
+} // namespace std
+
+#endif
+
diff --git a/ext/boost/regex/icu.hpp b/ext/boost/regex/icu.hpp
new file mode 100644
index 0000000000..247155724e
--- /dev/null
+++ b/ext/boost/regex/icu.hpp
@@ -0,0 +1,1021 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE icu.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Unicode regular expressions on top of the ICU Library.
+ */
+
+#ifndef BOOST_REGEX_ICU_HPP
+#define BOOST_REGEX_ICU_HPP
+
+#include <unicode/utypes.h>
+#include <unicode/uchar.h>
+#include <unicode/coll.h>
+#include <boost/regex.hpp>
+#include <boost/regex/pending/unicode_iterator.hpp>
+#include <boost/mpl/int_fwd.hpp>
+#include <bitset>
+
+
+namespace boost{
+
+namespace re_detail{
+
+//
+// Implementation details:
+//
+class BOOST_REGEX_DECL icu_regex_traits_implementation
+{
+ typedef UChar32 char_type;
+ typedef std::size_t size_type;
+ typedef std::vector<char_type> string_type;
+ typedef U_NAMESPACE_QUALIFIER Locale locale_type;
+ typedef boost::uint_least32_t char_class_type;
+public:
+ icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale& l)
+ : m_locale(l)
+ {
+ UErrorCode success = U_ZERO_ERROR;
+ m_collator.reset(U_NAMESPACE_QUALIFIER Collator::createInstance(l, success));
+ if(U_SUCCESS(success) == 0)
+ init_error();
+ m_collator->setStrength(U_NAMESPACE_QUALIFIER Collator::IDENTICAL);
+ success = U_ZERO_ERROR;
+ m_primary_collator.reset(U_NAMESPACE_QUALIFIER Collator::createInstance(l, success));
+ if(U_SUCCESS(success) == 0)
+ init_error();
+ m_primary_collator->setStrength(U_NAMESPACE_QUALIFIER Collator::PRIMARY);
+ }
+ U_NAMESPACE_QUALIFIER Locale getloc()const
+ {
+ return m_locale;
+ }
+ string_type do_transform(const char_type* p1, const char_type* p2, const U_NAMESPACE_QUALIFIER Collator* pcoll) const;
+ string_type transform(const char_type* p1, const char_type* p2) const
+ {
+ return do_transform(p1, p2, m_collator.get());
+ }
+ string_type transform_primary(const char_type* p1, const char_type* p2) const
+ {
+ return do_transform(p1, p2, m_primary_collator.get());
+ }
+private:
+ void init_error()
+ {
+ std::runtime_error e("Could not initialize ICU resources");
+ boost::throw_exception(e);
+ }
+ U_NAMESPACE_QUALIFIER Locale m_locale; // The ICU locale that we're using
+ boost::scoped_ptr< U_NAMESPACE_QUALIFIER Collator> m_collator; // The full collation object
+ boost::scoped_ptr< U_NAMESPACE_QUALIFIER Collator> m_primary_collator; // The primary collation object
+};
+
+inline boost::shared_ptr<icu_regex_traits_implementation> get_icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale& loc)
+{
+ return boost::shared_ptr<icu_regex_traits_implementation>(new icu_regex_traits_implementation(loc));
+}
+
+}
+
+class BOOST_REGEX_DECL icu_regex_traits
+{
+public:
+ typedef UChar32 char_type;
+ typedef std::size_t size_type;
+ typedef std::vector<char_type> string_type;
+ typedef U_NAMESPACE_QUALIFIER Locale locale_type;
+#ifdef BOOST_NO_INT64_T
+ typedef std::bitset<64> char_class_type;
+#else
+ typedef boost::uint64_t char_class_type;
+#endif
+
+ struct boost_extensions_tag{};
+
+ icu_regex_traits()
+ : m_pimpl(re_detail::get_icu_regex_traits_implementation(U_NAMESPACE_QUALIFIER Locale()))
+ {
+ }
+ static size_type length(const char_type* p);
+
+ ::boost::regex_constants::syntax_type syntax_type(char_type c)const
+ {
+ return ((c < 0x7f) && (c > 0)) ? re_detail::get_default_syntax_type(static_cast<char>(c)) : regex_constants::syntax_char;
+ }
+ ::boost::regex_constants::escape_syntax_type escape_syntax_type(char_type c) const
+ {
+ return ((c < 0x7f) && (c > 0)) ? re_detail::get_default_escape_syntax_type(static_cast<char>(c)) : regex_constants::syntax_char;
+ }
+ char_type translate(char_type c) const
+ {
+ return c;
+ }
+ char_type translate_nocase(char_type c) const
+ {
+ return ::u_tolower(c);
+ }
+ char_type translate(char_type c, bool icase) const
+ {
+ return icase ? translate_nocase(c) : translate(c);
+ }
+ char_type tolower(char_type c) const
+ {
+ return ::u_tolower(c);
+ }
+ char_type toupper(char_type c) const
+ {
+ return ::u_toupper(c);
+ }
+ string_type transform(const char_type* p1, const char_type* p2) const
+ {
+ return m_pimpl->transform(p1, p2);
+ }
+ string_type transform_primary(const char_type* p1, const char_type* p2) const
+ {
+ return m_pimpl->transform_primary(p1, p2);
+ }
+ char_class_type lookup_classname(const char_type* p1, const char_type* p2) const;
+ string_type lookup_collatename(const char_type* p1, const char_type* p2) const;
+ bool isctype(char_type c, char_class_type f) const;
+ int toi(const char_type*& p1, const char_type* p2, int radix)const
+ {
+ return re_detail::global_toi(p1, p2, radix, *this);
+ }
+ int value(char_type c, int radix)const
+ {
+ return u_digit(c, static_cast< ::int8_t>(radix));
+ }
+ locale_type imbue(locale_type l)
+ {
+ locale_type result(m_pimpl->getloc());
+ m_pimpl = re_detail::get_icu_regex_traits_implementation(l);
+ return result;
+ }
+ locale_type getloc()const
+ {
+ return locale_type();
+ }
+ std::string error_string(::boost::regex_constants::error_type n) const
+ {
+ return re_detail::get_default_error_string(n);
+ }
+private:
+ icu_regex_traits(const icu_regex_traits&);
+ icu_regex_traits& operator=(const icu_regex_traits&);
+
+ //
+ // define the bitmasks offsets we need for additional character properties:
+ //
+ enum{
+ offset_blank = U_CHAR_CATEGORY_COUNT,
+ offset_space = U_CHAR_CATEGORY_COUNT+1,
+ offset_xdigit = U_CHAR_CATEGORY_COUNT+2,
+ offset_underscore = U_CHAR_CATEGORY_COUNT+3,
+ offset_unicode = U_CHAR_CATEGORY_COUNT+4,
+ offset_any = U_CHAR_CATEGORY_COUNT+5,
+ offset_ascii = U_CHAR_CATEGORY_COUNT+6,
+ offset_horizontal = U_CHAR_CATEGORY_COUNT+7,
+ offset_vertical = U_CHAR_CATEGORY_COUNT+8
+ };
+
+ //
+ // and now the masks:
+ //
+ static const char_class_type mask_blank;
+ static const char_class_type mask_space;
+ static const char_class_type mask_xdigit;
+ static const char_class_type mask_underscore;
+ static const char_class_type mask_unicode;
+ static const char_class_type mask_any;
+ static const char_class_type mask_ascii;
+ static const char_class_type mask_horizontal;
+ static const char_class_type mask_vertical;
+
+ static char_class_type lookup_icu_mask(const ::UChar32* p1, const ::UChar32* p2);
+
+ boost::shared_ptr< ::boost::re_detail::icu_regex_traits_implementation> m_pimpl;
+};
+
+} // namespace boost
+
+//
+// template instances:
+//
+#define BOOST_REGEX_CHAR_T UChar32
+#undef BOOST_REGEX_TRAITS_T
+#define BOOST_REGEX_TRAITS_T , icu_regex_traits
+#define BOOST_REGEX_ICU_INSTANCES
+#ifdef BOOST_REGEX_ICU_INSTANTIATE
+# define BOOST_REGEX_INSTANTIATE
+#endif
+#include <boost/regex/v4/instances.hpp>
+#undef BOOST_REGEX_CHAR_T
+#undef BOOST_REGEX_TRAITS_T
+#undef BOOST_REGEX_ICU_INSTANCES
+#ifdef BOOST_REGEX_INSTANTIATE
+# undef BOOST_REGEX_INSTANTIATE
+#endif
+
+namespace boost{
+
+// types:
+typedef basic_regex< ::UChar32, icu_regex_traits> u32regex;
+typedef match_results<const ::UChar32*> u32match;
+typedef match_results<const ::UChar*> u16match;
+
+//
+// Construction of 32-bit regex types from UTF-8 and UTF-16 primitives:
+//
+namespace re_detail{
+
+#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
+template <class InputIterator>
+inline u32regex do_make_u32regex(InputIterator i,
+ InputIterator j,
+ boost::regex_constants::syntax_option_type opt,
+ const boost::mpl::int_<1>*)
+{
+ typedef boost::u8_to_u32_iterator<InputIterator, UChar32> conv_type;
+ return u32regex(conv_type(i), conv_type(j), opt);
+}
+
+template <class InputIterator>
+inline u32regex do_make_u32regex(InputIterator i,
+ InputIterator j,
+ boost::regex_constants::syntax_option_type opt,
+ const boost::mpl::int_<2>*)
+{
+ typedef boost::u16_to_u32_iterator<InputIterator, UChar32> conv_type;
+ return u32regex(conv_type(i), conv_type(j), opt);
+}
+
+template <class InputIterator>
+inline u32regex do_make_u32regex(InputIterator i,
+ InputIterator j,
+ boost::regex_constants::syntax_option_type opt,
+ const boost::mpl::int_<4>*)
+{
+ return u32regex(i, j, opt);
+}
+#else
+template <class InputIterator>
+inline u32regex do_make_u32regex(InputIterator i,
+ InputIterator j,
+ boost::regex_constants::syntax_option_type opt,
+ const boost::mpl::int_<1>*)
+{
+ typedef boost::u8_to_u32_iterator<InputIterator, UChar32> conv_type;
+ typedef std::vector<UChar32> vector_type;
+ vector_type v;
+ conv_type a(i), b(j);
+ while(a != b)
+ {
+ v.push_back(*a);
+ ++a;
+ }
+ if(v.size())
+ return u32regex(&*v.begin(), v.size(), opt);
+ return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
+}
+
+template <class InputIterator>
+inline u32regex do_make_u32regex(InputIterator i,
+ InputIterator j,
+ boost::regex_constants::syntax_option_type opt,
+ const boost::mpl::int_<2>*)
+{
+ typedef boost::u16_to_u32_iterator<InputIterator, UChar32> conv_type;
+ typedef std::vector<UChar32> vector_type;
+ vector_type v;
+ conv_type a(i), b(j);
+ while(a != b)
+ {
+ v.push_back(*a);
+ ++a;
+ }
+ if(v.size())
+ return u32regex(&*v.begin(), v.size(), opt);
+ return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
+}
+
+template <class InputIterator>
+inline u32regex do_make_u32regex(InputIterator i,
+ InputIterator j,
+ boost::regex_constants::syntax_option_type opt,
+ const boost::mpl::int_<4>*)
+{
+ typedef std::vector<UChar32> vector_type;
+ vector_type v;
+ while(i != j)
+ {
+ v.push_back((UChar32)(*i));
+ ++i;
+ }
+ if(v.size())
+ return u32regex(&*v.begin(), v.size(), opt);
+ return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
+}
+#endif
+}
+
+//
+// Construction from an iterator pair:
+//
+template <class InputIterator>
+inline u32regex make_u32regex(InputIterator i,
+ InputIterator j,
+ boost::regex_constants::syntax_option_type opt)
+{
+ return re_detail::do_make_u32regex(i, j, opt, static_cast<boost::mpl::int_<sizeof(*i)> const*>(0));
+}
+//
+// construction from UTF-8 nul-terminated strings:
+//
+inline u32regex make_u32regex(const char* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)
+{
+ return re_detail::do_make_u32regex(p, p + std::strlen(p), opt, static_cast<boost::mpl::int_<1> const*>(0));
+}
+inline u32regex make_u32regex(const unsigned char* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)
+{
+ return re_detail::do_make_u32regex(p, p + std::strlen(reinterpret_cast<const char*>(p)), opt, static_cast<boost::mpl::int_<1> const*>(0));
+}
+//
+// construction from UTF-16 nul-terminated strings:
+//
+#ifndef BOOST_NO_WREGEX
+inline u32regex make_u32regex(const wchar_t* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)
+{
+ return re_detail::do_make_u32regex(p, p + std::wcslen(p), opt, static_cast<boost::mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
+inline u32regex make_u32regex(const UChar* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)
+{
+ return re_detail::do_make_u32regex(p, p + u_strlen(p), opt, static_cast<boost::mpl::int_<2> const*>(0));
+}
+#endif
+//
+// construction from basic_string class-template:
+//
+template<class C, class T, class A>
+inline u32regex make_u32regex(const std::basic_string<C, T, A>& s, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)
+{
+ return re_detail::do_make_u32regex(s.begin(), s.end(), opt, static_cast<boost::mpl::int_<sizeof(C)> const*>(0));
+}
+//
+// Construction from ICU string type:
+//
+inline u32regex make_u32regex(const UnicodeString& s, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)
+{
+ return re_detail::do_make_u32regex(s.getBuffer(), s.getBuffer() + s.length(), opt, static_cast<boost::mpl::int_<2> const*>(0));
+}
+
+//
+// regex_match overloads that widen the character type as appropriate:
+//
+namespace re_detail{
+template<class MR1, class MR2>
+void copy_results(MR1& out, MR2 const& in)
+{
+ // copy results from an adapted MR2 match_results:
+ out.set_size(in.size(), in.prefix().first.base(), in.suffix().second.base());
+ out.set_base(in.base().base());
+ for(int i = 0; i < (int)in.size(); ++i)
+ {
+ if(in[i].matched)
+ {
+ out.set_first(in[i].first.base(), i);
+ out.set_second(in[i].second.base(), i);
+ }
+ }
+}
+
+template <class BidiIterator, class Allocator>
+inline bool do_regex_match(BidiIterator first, BidiIterator last,
+ match_results<BidiIterator, Allocator>& m,
+ const u32regex& e,
+ match_flag_type flags,
+ boost::mpl::int_<4> const*)
+{
+ return ::boost::regex_match(first, last, m, e, flags);
+}
+template <class BidiIterator, class Allocator>
+bool do_regex_match(BidiIterator first, BidiIterator last,
+ match_results<BidiIterator, Allocator>& m,
+ const u32regex& e,
+ match_flag_type flags,
+ boost::mpl::int_<2> const*)
+{
+ typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;
+ typedef match_results<conv_type> match_type;
+ typedef typename match_type::allocator_type alloc_type;
+ match_type what;
+ bool result = ::boost::regex_match(conv_type(first), conv_type(last), what, e, flags);
+ // copy results across to m:
+ if(result) copy_results(m, what);
+ return result;
+}
+template <class BidiIterator, class Allocator>
+bool do_regex_match(BidiIterator first, BidiIterator last,
+ match_results<BidiIterator, Allocator>& m,
+ const u32regex& e,
+ match_flag_type flags,
+ boost::mpl::int_<1> const*)
+{
+ typedef u8_to_u32_iterator<BidiIterator, UChar32> conv_type;
+ typedef match_results<conv_type> match_type;
+ typedef typename match_type::allocator_type alloc_type;
+ match_type what;
+ bool result = ::boost::regex_match(conv_type(first), conv_type(last), what, e, flags);
+ // copy results across to m:
+ if(result) copy_results(m, what);
+ return result;
+}
+} // namespace re_detail
+
+template <class BidiIterator, class Allocator>
+inline bool u32regex_match(BidiIterator first, BidiIterator last,
+ match_results<BidiIterator, Allocator>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_match(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0));
+}
+inline bool u32regex_match(const UChar* p,
+ match_results<const UChar*>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0));
+}
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(BOOST_NO_WREGEX)
+inline bool u32regex_match(const wchar_t* p,
+ match_results<const wchar_t*>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_match(const char* p,
+ match_results<const char*>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_match(const unsigned char* p,
+ match_results<const unsigned char*>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_match(const std::string& s,
+ match_results<std::string::const_iterator>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0));
+}
+#ifndef BOOST_NO_STD_WSTRING
+inline bool u32regex_match(const std::wstring& s,
+ match_results<std::wstring::const_iterator>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_match(const UnicodeString& s,
+ match_results<const UChar*>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+//
+// regex_match overloads that do not return what matched:
+//
+template <class BidiIterator>
+inline bool u32regex_match(BidiIterator first, BidiIterator last,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<BidiIterator> m;
+ return re_detail::do_regex_match(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0));
+}
+inline bool u32regex_match(const UChar* p,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const UChar*> m;
+ return re_detail::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0));
+}
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(BOOST_NO_WREGEX)
+inline bool u32regex_match(const wchar_t* p,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const wchar_t*> m;
+ return re_detail::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_match(const char* p,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const char*> m;
+ return re_detail::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_match(const unsigned char* p,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const unsigned char*> m;
+ return re_detail::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_match(const std::string& s,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<std::string::const_iterator> m;
+ return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0));
+}
+#ifndef BOOST_NO_STD_WSTRING
+inline bool u32regex_match(const std::wstring& s,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<std::wstring::const_iterator> m;
+ return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_match(const UnicodeString& s,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const UChar*> m;
+ return re_detail::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+
+//
+// regex_search overloads that widen the character type as appropriate:
+//
+namespace re_detail{
+template <class BidiIterator, class Allocator>
+inline bool do_regex_search(BidiIterator first, BidiIterator last,
+ match_results<BidiIterator, Allocator>& m,
+ const u32regex& e,
+ match_flag_type flags,
+ BidiIterator base,
+ boost::mpl::int_<4> const*)
+{
+ return ::boost::regex_search(first, last, m, e, flags, base);
+}
+template <class BidiIterator, class Allocator>
+bool do_regex_search(BidiIterator first, BidiIterator last,
+ match_results<BidiIterator, Allocator>& m,
+ const u32regex& e,
+ match_flag_type flags,
+ BidiIterator base,
+ boost::mpl::int_<2> const*)
+{
+ typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;
+ typedef match_results<conv_type> match_type;
+ typedef typename match_type::allocator_type alloc_type;
+ match_type what;
+ bool result = ::boost::regex_search(conv_type(first), conv_type(last), what, e, flags, conv_type(base));
+ // copy results across to m:
+ if(result) copy_results(m, what);
+ return result;
+}
+template <class BidiIterator, class Allocator>
+bool do_regex_search(BidiIterator first, BidiIterator last,
+ match_results<BidiIterator, Allocator>& m,
+ const u32regex& e,
+ match_flag_type flags,
+ BidiIterator base,
+ boost::mpl::int_<1> const*)
+{
+ typedef u8_to_u32_iterator<BidiIterator, UChar32> conv_type;
+ typedef match_results<conv_type> match_type;
+ typedef typename match_type::allocator_type alloc_type;
+ match_type what;
+ bool result = ::boost::regex_search(conv_type(first), conv_type(last), what, e, flags, conv_type(base));
+ // copy results across to m:
+ if(result) copy_results(m, what);
+ return result;
+}
+}
+
+template <class BidiIterator, class Allocator>
+inline bool u32regex_search(BidiIterator first, BidiIterator last,
+ match_results<BidiIterator, Allocator>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));
+}
+template <class BidiIterator, class Allocator>
+inline bool u32regex_search(BidiIterator first, BidiIterator last,
+ match_results<BidiIterator, Allocator>& m,
+ const u32regex& e,
+ match_flag_type flags,
+ BidiIterator base)
+{
+ return re_detail::do_regex_search(first, last, m, e, flags, base, static_cast<mpl::int_<sizeof(*first)> const*>(0));
+}
+inline bool u32regex_search(const UChar* p,
+ match_results<const UChar*>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));
+}
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(BOOST_NO_WREGEX)
+inline bool u32regex_search(const wchar_t* p,
+ match_results<const wchar_t*>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_search(const char* p,
+ match_results<const char*>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_search(const unsigned char* p,
+ match_results<const unsigned char*>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_search(const std::string& s,
+ match_results<std::string::const_iterator>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));
+}
+#ifndef BOOST_NO_STD_WSTRING
+inline bool u32regex_search(const std::wstring& s,
+ match_results<std::wstring::const_iterator>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_search(const UnicodeString& s,
+ match_results<const UChar*>& m,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ return re_detail::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+template <class BidiIterator>
+inline bool u32regex_search(BidiIterator first, BidiIterator last,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<BidiIterator> m;
+ return re_detail::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));
+}
+inline bool u32regex_search(const UChar* p,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const UChar*> m;
+ return re_detail::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));
+}
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(BOOST_NO_WREGEX)
+inline bool u32regex_search(const wchar_t* p,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const wchar_t*> m;
+ return re_detail::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_search(const char* p,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const char*> m;
+ return re_detail::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_search(const unsigned char* p,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const unsigned char*> m;
+ return re_detail::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
+}
+inline bool u32regex_search(const std::string& s,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<std::string::const_iterator> m;
+ return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));
+}
+#ifndef BOOST_NO_STD_WSTRING
+inline bool u32regex_search(const std::wstring& s,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<std::wstring::const_iterator> m;
+ return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+#endif
+inline bool u32regex_search(const UnicodeString& s,
+ const u32regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const UChar*> m;
+ return re_detail::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
+}
+
+//
+// overloads for regex_replace with utf-8 and utf-16 data types:
+//
+namespace re_detail{
+template <class I>
+inline std::pair< boost::u8_to_u32_iterator<I>, boost::u8_to_u32_iterator<I> >
+ make_utf32_seq(I i, I j, mpl::int_<1> const*)
+{
+ return std::pair< boost::u8_to_u32_iterator<I>, boost::u8_to_u32_iterator<I> >(boost::u8_to_u32_iterator<I>(i), boost::u8_to_u32_iterator<I>(j));
+}
+template <class I>
+inline std::pair< boost::u16_to_u32_iterator<I>, boost::u16_to_u32_iterator<I> >
+ make_utf32_seq(I i, I j, mpl::int_<2> const*)
+{
+ return std::pair< boost::u16_to_u32_iterator<I>, boost::u16_to_u32_iterator<I> >(boost::u16_to_u32_iterator<I>(i), boost::u16_to_u32_iterator<I>(j));
+}
+template <class I>
+inline std::pair< I, I >
+ make_utf32_seq(I i, I j, mpl::int_<4> const*)
+{
+ return std::pair< I, I >(i, j);
+}
+template <class charT>
+inline std::pair< boost::u8_to_u32_iterator<const charT*>, boost::u8_to_u32_iterator<const charT*> >
+ make_utf32_seq(const charT* p, mpl::int_<1> const*)
+{
+ return std::pair< boost::u8_to_u32_iterator<const charT*>, boost::u8_to_u32_iterator<const charT*> >(boost::u8_to_u32_iterator<const charT*>(p), boost::u8_to_u32_iterator<const charT*>(p+std::strlen((const char*)p)));
+}
+template <class charT>
+inline std::pair< boost::u16_to_u32_iterator<const charT*>, boost::u16_to_u32_iterator<const charT*> >
+ make_utf32_seq(const charT* p, mpl::int_<2> const*)
+{
+ return std::pair< boost::u16_to_u32_iterator<const charT*>, boost::u16_to_u32_iterator<const charT*> >(boost::u16_to_u32_iterator<const charT*>(p), boost::u16_to_u32_iterator<const charT*>(p+u_strlen((const UChar*)p)));
+}
+template <class charT>
+inline std::pair< const charT*, const charT* >
+ make_utf32_seq(const charT* p, mpl::int_<4> const*)
+{
+ return std::pair< const charT*, const charT* >(p, p+icu_regex_traits::length((UChar32 const*)p));
+}
+template <class OutputIterator>
+inline OutputIterator make_utf32_out(OutputIterator o, mpl::int_<4> const*)
+{
+ return o;
+}
+template <class OutputIterator>
+inline utf16_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, mpl::int_<2> const*)
+{
+ return o;
+}
+template <class OutputIterator>
+inline utf8_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, mpl::int_<1> const*)
+{
+ return o;
+}
+
+template <class OutputIterator, class I1, class I2>
+OutputIterator do_regex_replace(OutputIterator out,
+ std::pair<I1, I1> const& in,
+ const u32regex& e,
+ const std::pair<I2, I2>& fmt,
+ match_flag_type flags
+ )
+{
+ // unfortunately we have to copy the format string in order to pass in onward:
+ std::vector<UChar32> f;
+#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
+ f.assign(fmt.first, fmt.second);
+#else
+ f.clear();
+ I2 pos = fmt.first;
+ while(pos != fmt.second)
+ f.push_back(*pos++);
+#endif
+
+ regex_iterator<I1, UChar32, icu_regex_traits> i(in.first, in.second, e, flags);
+ regex_iterator<I1, UChar32, icu_regex_traits> j;
+ if(i == j)
+ {
+ if(!(flags & regex_constants::format_no_copy))
+ out = re_detail::copy(in.first, in.second, out);
+ }
+ else
+ {
+ I1 last_m = in.first;
+ while(i != j)
+ {
+ if(!(flags & regex_constants::format_no_copy))
+ out = re_detail::copy(i->prefix().first, i->prefix().second, out);
+ if(f.size())
+ out = ::boost::re_detail::regex_format_imp(out, *i, &*f.begin(), &*f.begin() + f.size(), flags, e.get_traits());
+ else
+ out = ::boost::re_detail::regex_format_imp(out, *i, static_cast<UChar32 const*>(0), static_cast<UChar32 const*>(0), flags, e.get_traits());
+ last_m = (*i)[0].second;
+ if(flags & regex_constants::format_first_only)
+ break;
+ ++i;
+ }
+ if(!(flags & regex_constants::format_no_copy))
+ out = re_detail::copy(last_m, in.second, out);
+ }
+ return out;
+}
+template <class BaseIterator>
+inline const BaseIterator& extract_output_base(const BaseIterator& b)
+{
+ return b;
+}
+template <class BaseIterator>
+inline BaseIterator extract_output_base(const utf8_output_iterator<BaseIterator>& b)
+{
+ return b.base();
+}
+template <class BaseIterator>
+inline BaseIterator extract_output_base(const utf16_output_iterator<BaseIterator>& b)
+{
+ return b.base();
+}
+} // re_detail
+
+template <class OutputIterator, class BidirectionalIterator, class charT>
+inline OutputIterator u32regex_replace(OutputIterator out,
+ BidirectionalIterator first,
+ BidirectionalIterator last,
+ const u32regex& e,
+ const charT* fmt,
+ match_flag_type flags = match_default)
+{
+ return re_detail::extract_output_base
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+ <OutputIterator>
+#endif
+ (
+ re_detail::do_regex_replace(
+ re_detail::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
+ re_detail::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
+ e,
+ re_detail::make_utf32_seq(fmt, static_cast<mpl::int_<sizeof(*fmt)> const*>(0)),
+ flags)
+ );
+}
+
+template <class OutputIterator, class Iterator, class charT>
+inline OutputIterator u32regex_replace(OutputIterator out,
+ Iterator first,
+ Iterator last,
+ const u32regex& e,
+ const std::basic_string<charT>& fmt,
+ match_flag_type flags = match_default)
+{
+ return re_detail::extract_output_base
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+ <OutputIterator>
+#endif
+ (
+ re_detail::do_regex_replace(
+ re_detail::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
+ re_detail::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
+ e,
+ re_detail::make_utf32_seq(fmt.begin(), fmt.end(), static_cast<mpl::int_<sizeof(charT)> const*>(0)),
+ flags)
+ );
+}
+
+template <class OutputIterator, class Iterator>
+inline OutputIterator u32regex_replace(OutputIterator out,
+ Iterator first,
+ Iterator last,
+ const u32regex& e,
+ const UnicodeString& fmt,
+ match_flag_type flags = match_default)
+{
+ return re_detail::extract_output_base
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+ <OutputIterator>
+#endif
+ (
+ re_detail::do_regex_replace(
+ re_detail::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
+ re_detail::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
+ e,
+ re_detail::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<mpl::int_<2> const*>(0)),
+ flags)
+ );
+}
+
+template <class charT>
+std::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,
+ const u32regex& e,
+ const charT* fmt,
+ match_flag_type flags = match_default)
+{
+ std::basic_string<charT> result;
+ re_detail::string_out_iterator<std::basic_string<charT> > i(result);
+ u32regex_replace(i, s.begin(), s.end(), e, fmt, flags);
+ return result;
+}
+
+template <class charT>
+std::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,
+ const u32regex& e,
+ const std::basic_string<charT>& fmt,
+ match_flag_type flags = match_default)
+{
+ std::basic_string<charT> result;
+ re_detail::string_out_iterator<std::basic_string<charT> > i(result);
+ u32regex_replace(i, s.begin(), s.end(), e, fmt.c_str(), flags);
+ return result;
+}
+
+namespace re_detail{
+
+class unicode_string_out_iterator
+{
+ UnicodeString* out;
+public:
+ unicode_string_out_iterator(UnicodeString& s) : out(&s) {}
+ unicode_string_out_iterator& operator++() { return *this; }
+ unicode_string_out_iterator& operator++(int) { return *this; }
+ unicode_string_out_iterator& operator*() { return *this; }
+ unicode_string_out_iterator& operator=(UChar v)
+ {
+ *out += v;
+ return *this;
+ }
+ typedef std::ptrdiff_t difference_type;
+ typedef UChar value_type;
+ typedef value_type* pointer;
+ typedef value_type& reference;
+ typedef std::output_iterator_tag iterator_category;
+};
+
+}
+
+inline UnicodeString u32regex_replace(const UnicodeString& s,
+ const u32regex& e,
+ const UChar* fmt,
+ match_flag_type flags = match_default)
+{
+ UnicodeString result;
+ re_detail::unicode_string_out_iterator i(result);
+ u32regex_replace(i, s.getBuffer(), s.getBuffer()+s.length(), e, fmt, flags);
+ return result;
+}
+
+inline UnicodeString u32regex_replace(const UnicodeString& s,
+ const u32regex& e,
+ const UnicodeString& fmt,
+ match_flag_type flags = match_default)
+{
+ UnicodeString result;
+ re_detail::unicode_string_out_iterator i(result);
+ re_detail::do_regex_replace(
+ re_detail::make_utf32_out(i, static_cast<mpl::int_<2> const*>(0)),
+ re_detail::make_utf32_seq(s.getBuffer(), s.getBuffer()+s.length(), static_cast<mpl::int_<2> const*>(0)),
+ e,
+ re_detail::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<mpl::int_<2> const*>(0)),
+ flags);
+ return result;
+}
+
+} // namespace boost.
+
+#include <boost/regex/v4/u32regex_iterator.hpp>
+#include <boost/regex/v4/u32regex_token_iterator.hpp>
+
+#endif
diff --git a/ext/boost/regex/mfc.hpp b/ext/boost/regex/mfc.hpp
new file mode 100644
index 0000000000..02502f9504
--- /dev/null
+++ b/ext/boost/regex/mfc.hpp
@@ -0,0 +1,190 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE mfc.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Overloads and helpers for using MFC/ATL string types with Boost.Regex.
+ */
+
+#ifndef BOOST_REGEX_MFC_HPP
+#define BOOST_REGEX_MFC_HPP
+
+#include <atlsimpstr.h>
+#include <boost/regex.hpp>
+
+namespace boost{
+
+//
+// define the types used for TCHAR's:
+typedef basic_regex<TCHAR> tregex;
+typedef match_results<TCHAR const*> tmatch;
+typedef regex_iterator<TCHAR const*> tregex_iterator;
+typedef regex_token_iterator<TCHAR const*> tregex_token_iterator;
+
+#if _MSC_VER >= 1310
+#define SIMPLE_STRING_PARAM class B, bool b
+#define SIMPLE_STRING_ARG_LIST B, b
+#else
+#define SIMPLE_STRING_PARAM class B
+#define SIMPLE_STRING_ARG_LIST B
+#endif
+
+//
+// define regex creation functions:
+//
+template <SIMPLE_STRING_PARAM>
+inline basic_regex<B>
+make_regex(const ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>& s, ::boost::regex_constants::syntax_option_type f = boost::regex_constants::normal)
+{
+ basic_regex<B> result(s.GetString(), s.GetString() + s.GetLength(), f);
+ return result;
+}
+//
+// regex_match overloads:
+//
+template <SIMPLE_STRING_PARAM, class A, class T>
+inline bool regex_match(const ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>& s,
+ match_results<const B*, A>& what,
+ const basic_regex<B, T>& e,
+ boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
+{
+ return ::boost::regex_match(s.GetString(),
+ s.GetString() + s.GetLength(),
+ what,
+ e,
+ f);
+}
+
+template <SIMPLE_STRING_PARAM, class T>
+inline bool regex_match(const ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>& s,
+ const basic_regex<B, T>& e,
+ boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
+{
+ return ::boost::regex_match(s.GetString(),
+ s.GetString() + s.GetLength(),
+ e,
+ f);
+}
+//
+// regex_search overloads:
+//
+template <SIMPLE_STRING_PARAM, class A, class T>
+inline bool regex_search(const ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>& s,
+ match_results<const B*, A>& what,
+ const basic_regex<B, T>& e,
+ boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
+{
+ return ::boost::regex_search(s.GetString(),
+ s.GetString() + s.GetLength(),
+ what,
+ e,
+ f);
+}
+
+template <SIMPLE_STRING_PARAM, class T>
+inline bool regex_search(const ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>& s,
+ const basic_regex<B, T>& e,
+ boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
+{
+ return ::boost::regex_search(s.GetString(),
+ s.GetString() + s.GetLength(),
+ e,
+ f);
+}
+//
+// regex_iterator creation:
+//
+template <SIMPLE_STRING_PARAM>
+inline regex_iterator<B const*>
+make_regex_iterator(const ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>& s, const basic_regex<B>& e, ::boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
+{
+ regex_iterator<B const*> result(s.GetString(), s.GetString() + s.GetLength(), e, f);
+ return result;
+}
+
+template <SIMPLE_STRING_PARAM>
+inline regex_token_iterator<B const*>
+ make_regex_token_iterator(const ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>& s, const basic_regex<B>& e, int sub = 0, ::boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
+{
+ regex_token_iterator<B const*> result(s.GetString(), s.GetString() + s.GetLength(), e, sub, f);
+ return result;
+}
+
+template <SIMPLE_STRING_PARAM>
+inline regex_token_iterator<B const*>
+make_regex_token_iterator(const ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>& s, const basic_regex<B>& e, const std::vector<int>& subs, ::boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
+{
+ regex_token_iterator<B const*> result(s.GetString(), s.GetString() + s.GetLength(), e, subs, f);
+ return result;
+}
+
+template <SIMPLE_STRING_PARAM, std::size_t N>
+inline regex_token_iterator<B const*>
+make_regex_token_iterator(const ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>& s, const basic_regex<B>& e, const int (& subs)[N], ::boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)
+{
+ regex_token_iterator<B const*> result(s.GetString(), s.GetString() + s.GetLength(), e, subs, f);
+ return result;
+}
+
+template <class OutputIterator, class BidirectionalIterator, class traits,
+ SIMPLE_STRING_PARAM>
+OutputIterator regex_replace(OutputIterator out,
+ BidirectionalIterator first,
+ BidirectionalIterator last,
+ const basic_regex<B, traits>& e,
+ const ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>& fmt,
+ match_flag_type flags = match_default)
+{
+ return ::boost::regex_replace(out, first, last, e, fmt.GetString(), flags);
+}
+
+namespace re_detail{
+
+template <SIMPLE_STRING_PARAM>
+class mfc_string_out_iterator
+{
+ ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>* out;
+public:
+ mfc_string_out_iterator(ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>& s) : out(&s) {}
+ mfc_string_out_iterator& operator++() { return *this; }
+ mfc_string_out_iterator& operator++(int) { return *this; }
+ mfc_string_out_iterator& operator*() { return *this; }
+ mfc_string_out_iterator& operator=(B v)
+ {
+ out->AppendChar(v);
+ return *this;
+ }
+ typedef std::ptrdiff_t difference_type;
+ typedef B value_type;
+ typedef value_type* pointer;
+ typedef value_type& reference;
+ typedef std::output_iterator_tag iterator_category;
+};
+
+}
+
+template <class traits, SIMPLE_STRING_PARAM>
+ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST> regex_replace(const ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>& s,
+ const basic_regex<B, traits>& e,
+ const ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST>& fmt,
+ match_flag_type flags = match_default)
+{
+ ATL::CSimpleStringT<SIMPLE_STRING_ARG_LIST> result(s.GetManager());
+ re_detail::mfc_string_out_iterator<SIMPLE_STRING_ARG_LIST> i(result);
+ regex_replace(i, s.GetString(), s.GetString() + s.GetLength(), e, fmt.GetString(), flags);
+ return result;
+}
+
+} // namespace boost.
+
+#endif
diff --git a/ext/boost/regex/pattern_except.hpp b/ext/boost/regex/pattern_except.hpp
new file mode 100644
index 0000000000..57ea14c256
--- /dev/null
+++ b/ext/boost/regex/pattern_except.hpp
@@ -0,0 +1,100 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE pattern_except.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares pattern-matching exception classes.
+ */
+
+#ifndef BOOST_RE_PAT_EXCEPT_HPP
+#define BOOST_RE_PAT_EXCEPT_HPP
+
+#ifndef BOOST_REGEX_CONFIG_HPP
+#include <boost/regex/config.hpp>
+#endif
+
+#include <stdexcept>
+#include <cstddef>
+#include <boost/regex/v4/error_type.hpp>
+
+namespace boost{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4275)
+#endif
+class BOOST_REGEX_DECL regex_error : public std::runtime_error
+{
+public:
+ explicit regex_error(const std::string& s, regex_constants::error_type err = regex_constants::error_unknown, std::ptrdiff_t pos = 0);
+ explicit regex_error(regex_constants::error_type err);
+ ~regex_error() throw();
+ regex_constants::error_type code()const
+ { return m_error_code; }
+ std::ptrdiff_t position()const
+ { return m_position; }
+ void raise()const;
+private:
+ regex_constants::error_type m_error_code;
+ std::ptrdiff_t m_position;
+};
+
+typedef regex_error bad_pattern;
+typedef regex_error bad_expression;
+
+namespace re_detail{
+
+BOOST_REGEX_DECL void BOOST_REGEX_CALL raise_runtime_error(const std::runtime_error& ex);
+
+template <class traits>
+void raise_error(const traits& t, regex_constants::error_type code)
+{
+ (void)t; // warning suppression
+ std::runtime_error e(t.error_string(code));
+ ::boost::re_detail::raise_runtime_error(e);
+}
+
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace boost
+
+#endif
+
+
+
diff --git a/ext/boost/regex/pending/object_cache.hpp b/ext/boost/regex/pending/object_cache.hpp
new file mode 100644
index 0000000000..2a7e00bc0a
--- /dev/null
+++ b/ext/boost/regex/pending/object_cache.hpp
@@ -0,0 +1,163 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE object_cache.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Implements a generic object cache.
+ */
+
+#ifndef BOOST_REGEX_OBJECT_CACHE_HPP
+#define BOOST_REGEX_OBJECT_CACHE_HPP
+
+#include <map>
+#include <list>
+#include <stdexcept>
+#include <string>
+#include <boost/config.hpp>
+#include <boost/shared_ptr.hpp>
+#ifdef BOOST_HAS_THREADS
+#include <boost/regex/pending/static_mutex.hpp>
+#endif
+
+namespace boost{
+
+template <class Key, class Object>
+class object_cache
+{
+public:
+ typedef std::pair< ::boost::shared_ptr<Object const>, Key const*> value_type;
+ typedef std::list<value_type> list_type;
+ typedef typename list_type::iterator list_iterator;
+ typedef std::map<Key, list_iterator> map_type;
+ typedef typename map_type::iterator map_iterator;
+ typedef typename list_type::size_type size_type;
+ static boost::shared_ptr<Object const> get(const Key& k, size_type max_cache_size);
+
+private:
+ static boost::shared_ptr<Object const> do_get(const Key& k, size_type max_cache_size);
+
+ struct data
+ {
+ list_type cont;
+ map_type index;
+ };
+
+ // Needed by compilers not implementing the resolution to DR45. For reference,
+ // see http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.
+ friend struct data;
+};
+
+template <class Key, class Object>
+boost::shared_ptr<Object const> object_cache<Key, Object>::get(const Key& k, size_type max_cache_size)
+{
+#ifdef BOOST_HAS_THREADS
+ static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT;
+
+ boost::static_mutex::scoped_lock l(mut);
+ if(l)
+ {
+ return do_get(k, max_cache_size);
+ }
+ //
+ // what do we do if the lock fails?
+ // for now just throw, but we should never really get here...
+ //
+ ::boost::throw_exception(std::runtime_error("Error in thread safety code: could not acquire a lock"));
+ return boost::shared_ptr<Object>();
+#else
+ return do_get(k, max_cache_size);
+#endif
+}
+
+template <class Key, class Object>
+boost::shared_ptr<Object const> object_cache<Key, Object>::do_get(const Key& k, size_type max_cache_size)
+{
+ typedef typename object_cache<Key, Object>::data object_data;
+ typedef typename map_type::size_type map_size_type;
+ static object_data s_data;
+
+ //
+ // see if the object is already in the cache:
+ //
+ map_iterator mpos = s_data.index.find(k);
+ if(mpos != s_data.index.end())
+ {
+ //
+ // Eureka!
+ // We have a cached item, bump it up the list and return it:
+ //
+ if(--(s_data.cont.end()) != mpos->second)
+ {
+ // splice out the item we want to move:
+ list_type temp;
+ temp.splice(temp.end(), s_data.cont, mpos->second);
+ // and now place it at the end of the list:
+ s_data.cont.splice(s_data.cont.end(), temp, temp.begin());
+ BOOST_ASSERT(*(s_data.cont.back().second) == k);
+ // update index with new position:
+ mpos->second = --(s_data.cont.end());
+ BOOST_ASSERT(&(mpos->first) == mpos->second->second);
+ BOOST_ASSERT(&(mpos->first) == s_data.cont.back().second);
+ }
+ return s_data.cont.back().first;
+ }
+ //
+ // if we get here then the item is not in the cache,
+ // so create it:
+ //
+ boost::shared_ptr<Object const> result(new Object(k));
+ //
+ // Add it to the list, and index it:
+ //
+ s_data.cont.push_back(value_type(result, static_cast<Key const*>(0)));
+ s_data.index.insert(std::make_pair(k, --(s_data.cont.end())));
+ s_data.cont.back().second = &(s_data.index.find(k)->first);
+ map_size_type s = s_data.index.size();
+ BOOST_ASSERT(s_data.index[k]->first.get() == result.get());
+ BOOST_ASSERT(&(s_data.index.find(k)->first) == s_data.cont.back().second);
+ BOOST_ASSERT(s_data.index.find(k)->first == k);
+ if(s > max_cache_size)
+ {
+ //
+ // We have too many items in the list, so we need to start
+ // popping them off the back of the list, but only if they're
+ // being held uniquely by us:
+ //
+ list_iterator pos = s_data.cont.begin();
+ list_iterator last = s_data.cont.end();
+ while((pos != last) && (s > max_cache_size))
+ {
+ if(pos->first.unique())
+ {
+ list_iterator condemmed(pos);
+ ++pos;
+ // now remove the items from our containers,
+ // then order has to be as follows:
+ BOOST_ASSERT(s_data.index.find(*(condemmed->second)) != s_data.index.end());
+ s_data.index.erase(*(condemmed->second));
+ s_data.cont.erase(condemmed);
+ --s;
+ }
+ else
+ --pos;
+ }
+ BOOST_ASSERT(s_data.index[k]->first.get() == result.get());
+ BOOST_ASSERT(&(s_data.index.find(k)->first) == s_data.cont.back().second);
+ BOOST_ASSERT(s_data.index.find(k)->first == k);
+ }
+ return result;
+}
+
+}
+
+#endif
diff --git a/ext/boost/regex/pending/static_mutex.hpp b/ext/boost/regex/pending/static_mutex.hpp
new file mode 100644
index 0000000000..218169c3c8
--- /dev/null
+++ b/ext/boost/regex/pending/static_mutex.hpp
@@ -0,0 +1,184 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE static_mutex.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares static_mutex lock type, there are three different
+ * implementations: POSIX pthreads, WIN32 threads, and portable,
+ * these are described in more detail below.
+ */
+
+#ifndef BOOST_REGEX_STATIC_MUTEX_HPP
+#define BOOST_REGEX_STATIC_MUTEX_HPP
+
+#include <boost/config.hpp>
+#include <boost/regex/config.hpp> // dll import/export options.
+
+#ifdef BOOST_HAS_PTHREADS
+#include <pthread.h>
+#endif
+
+#if defined(BOOST_HAS_PTHREADS) && defined(PTHREAD_MUTEX_INITIALIZER)
+//
+// pthreads version:
+// simple wrap around a pthread_mutex_t initialized with
+// PTHREAD_MUTEX_INITIALIZER.
+//
+namespace boost{
+
+class BOOST_REGEX_DECL scoped_static_mutex_lock;
+
+class static_mutex
+{
+public:
+ typedef scoped_static_mutex_lock scoped_lock;
+ pthread_mutex_t m_mutex;
+};
+
+#define BOOST_STATIC_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, }
+
+class BOOST_REGEX_DECL scoped_static_mutex_lock
+{
+public:
+ scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
+ ~scoped_static_mutex_lock();
+ inline bool locked()const
+ {
+ return m_have_lock;
+ }
+ inline operator void const*()const
+ {
+ return locked() ? this : 0;
+ }
+ void lock();
+ void unlock();
+private:
+ static_mutex& m_mutex;
+ bool m_have_lock;
+};
+
+
+} // namespace boost
+#elif defined(BOOST_HAS_WINTHREADS)
+//
+// Win32 version:
+// Use a 32-bit int as a lock, along with a test-and-set
+// implementation using InterlockedCompareExchange.
+//
+
+#include <boost/cstdint.hpp>
+
+namespace boost{
+
+class BOOST_REGEX_DECL scoped_static_mutex_lock;
+
+class static_mutex
+{
+public:
+ typedef scoped_static_mutex_lock scoped_lock;
+ boost::int32_t m_mutex;
+};
+
+#define BOOST_STATIC_MUTEX_INIT { 0, }
+
+class BOOST_REGEX_DECL scoped_static_mutex_lock
+{
+public:
+ scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
+ ~scoped_static_mutex_lock();
+ operator void const*()const;
+ bool locked()const;
+ void lock();
+ void unlock();
+private:
+ static_mutex& m_mutex;
+ bool m_have_lock;
+ scoped_static_mutex_lock(const scoped_static_mutex_lock&);
+ scoped_static_mutex_lock& operator=(const scoped_static_mutex_lock&);
+};
+
+inline scoped_static_mutex_lock::operator void const*()const
+{
+ return locked() ? this : 0;
+}
+
+inline bool scoped_static_mutex_lock::locked()const
+{
+ return m_have_lock;
+}
+
+} // namespace
+
+#else
+//
+// Portable version of a static mutex based on Boost.Thread library:
+// This has to use a single mutex shared by all instances of static_mutex
+// because boost::call_once doesn't alow us to pass instance information
+// down to the initialisation proceedure. In fact the initialisation routine
+// may need to be called more than once - but only once per instance.
+//
+// Since this preprocessor path is almost never taken, we hide these header
+// dependencies so that build tools don't find them.
+//
+#define B1 <boost/thread/once.hpp>
+#define B2 <boost/thread/recursive_mutex.hpp>
+#include B1
+#include B2
+#undef B1
+#undef B2
+
+namespace boost{
+
+class BOOST_REGEX_DECL scoped_static_mutex_lock;
+extern "C" BOOST_REGEX_DECL void free_static_mutex();
+
+class BOOST_REGEX_DECL static_mutex
+{
+public:
+ typedef scoped_static_mutex_lock scoped_lock;
+ static void init();
+ static boost::recursive_mutex* m_pmutex;
+ static boost::once_flag m_once;
+};
+
+#define BOOST_STATIC_MUTEX_INIT { }
+
+class BOOST_REGEX_DECL scoped_static_mutex_lock
+{
+public:
+ scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
+ ~scoped_static_mutex_lock();
+ operator void const*()const;
+ bool locked()const;
+ void lock();
+ void unlock();
+private:
+ boost::recursive_mutex::scoped_lock* m_plock;
+ bool m_have_lock;
+};
+
+inline scoped_static_mutex_lock::operator void const*()const
+{
+ return locked() ? this : 0;
+}
+
+inline bool scoped_static_mutex_lock::locked()const
+{
+ return m_have_lock;
+}
+
+} // namespace
+
+#endif
+
+#endif
diff --git a/ext/boost/regex/pending/unicode_iterator.hpp b/ext/boost/regex/pending/unicode_iterator.hpp
new file mode 100644
index 0000000000..657ca0a4cf
--- /dev/null
+++ b/ext/boost/regex/pending/unicode_iterator.hpp
@@ -0,0 +1,692 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE unicode_iterator.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Iterator adapters for converting between different Unicode encodings.
+ */
+
+/****************************************************************************
+
+Contents:
+~~~~~~~~~
+
+1) Read Only, Input Adapters:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+template <class BaseIterator, class U8Type = ::boost::uint8_t>
+class u32_to_u8_iterator;
+
+Adapts sequence of UTF-32 code points to "look like" a sequence of UTF-8.
+
+template <class BaseIterator, class U32Type = ::boost::uint32_t>
+class u8_to_u32_iterator;
+
+Adapts sequence of UTF-8 code points to "look like" a sequence of UTF-32.
+
+template <class BaseIterator, class U16Type = ::boost::uint16_t>
+class u32_to_u16_iterator;
+
+Adapts sequence of UTF-32 code points to "look like" a sequence of UTF-16.
+
+template <class BaseIterator, class U32Type = ::boost::uint32_t>
+class u16_to_u32_iterator;
+
+Adapts sequence of UTF-16 code points to "look like" a sequence of UTF-32.
+
+2) Single pass output iterator adapters:
+
+template <class BaseIterator>
+class utf8_output_iterator;
+
+Accepts UTF-32 code points and forwards them on as UTF-8 code points.
+
+template <class BaseIterator>
+class utf16_output_iterator;
+
+Accepts UTF-32 code points and forwards them on as UTF-16 code points.
+
+****************************************************************************/
+
+#ifndef BOOST_REGEX_UNICODE_ITERATOR_HPP
+#define BOOST_REGEX_UNICODE_ITERATOR_HPP
+#include <boost/cstdint.hpp>
+#include <boost/assert.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/throw_exception.hpp>
+#include <stdexcept>
+#ifndef BOOST_NO_STD_LOCALE
+#include <sstream>
+#include <ios>
+#endif
+#include <limits.h> // CHAR_BIT
+
+namespace boost{
+
+namespace detail{
+
+static const ::boost::uint16_t high_surrogate_base = 0xD7C0u;
+static const ::boost::uint16_t low_surrogate_base = 0xDC00u;
+static const ::boost::uint32_t ten_bit_mask = 0x3FFu;
+
+inline bool is_high_surrogate(::boost::uint16_t v)
+{
+ return (v & 0xFC00u) == 0xd800u;
+}
+inline bool is_low_surrogate(::boost::uint16_t v)
+{
+ return (v & 0xFC00u) == 0xdc00u;
+}
+template <class T>
+inline bool is_surrogate(T v)
+{
+ return (v & 0xF800u) == 0xd800;
+}
+
+inline unsigned utf8_byte_count(boost::uint8_t c)
+{
+ // if the most significant bit with a zero in it is in position
+ // 8-N then there are N bytes in this UTF-8 sequence:
+ boost::uint8_t mask = 0x80u;
+ unsigned result = 0;
+ while(c & mask)
+ {
+ ++result;
+ mask >>= 1;
+ }
+ return (result == 0) ? 1 : ((result > 4) ? 4 : result);
+}
+
+inline unsigned utf8_trailing_byte_count(boost::uint8_t c)
+{
+ return utf8_byte_count(c) - 1;
+}
+
+inline void invalid_utf32_code_point(::boost::uint32_t val)
+{
+#ifndef BOOST_NO_STD_LOCALE
+ std::stringstream ss;
+ ss << "Invalid UTF-32 code point U+" << std::showbase << std::hex << val << " encountered while trying to encode UTF-16 sequence";
+ std::out_of_range e(ss.str());
+#else
+ std::out_of_range e("Invalid UTF-32 code point encountered while trying to encode UTF-16 sequence");
+#endif
+ boost::throw_exception(e);
+}
+
+
+} // namespace detail
+
+template <class BaseIterator, class U16Type = ::boost::uint16_t>
+class u32_to_u16_iterator
+ : public boost::iterator_facade<u32_to_u16_iterator<BaseIterator, U16Type>, U16Type, std::bidirectional_iterator_tag, const U16Type>
+{
+ typedef boost::iterator_facade<u32_to_u16_iterator<BaseIterator, U16Type>, U16Type, std::bidirectional_iterator_tag, const U16Type> base_type;
+
+#if !defined(BOOST_NO_STD_ITERATOR_TRAITS) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+ typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;
+
+ BOOST_STATIC_ASSERT(sizeof(base_value_type)*CHAR_BIT == 32);
+ BOOST_STATIC_ASSERT(sizeof(U16Type)*CHAR_BIT == 16);
+#endif
+
+public:
+ typename base_type::reference
+ dereference()const
+ {
+ if(m_current == 2)
+ extract_current();
+ return m_values[m_current];
+ }
+ bool equal(const u32_to_u16_iterator& that)const
+ {
+ if(m_position == that.m_position)
+ {
+ // Both m_currents must be equal, or both even
+ // this is the same as saying their sum must be even:
+ return (m_current + that.m_current) & 1u ? false : true;
+ }
+ return false;
+ }
+ void increment()
+ {
+ // if we have a pending read then read now, so that we know whether
+ // to skip a position, or move to a low-surrogate:
+ if(m_current == 2)
+ {
+ // pending read:
+ extract_current();
+ }
+ // move to the next surrogate position:
+ ++m_current;
+ // if we've reached the end skip a position:
+ if(m_values[m_current] == 0)
+ {
+ m_current = 2;
+ ++m_position;
+ }
+ }
+ void decrement()
+ {
+ if(m_current != 1)
+ {
+ // decrementing an iterator always leads to a valid position:
+ --m_position;
+ extract_current();
+ m_current = m_values[1] ? 1 : 0;
+ }
+ else
+ {
+ m_current = 0;
+ }
+ }
+ BaseIterator base()const
+ {
+ return m_position;
+ }
+ // construct:
+ u32_to_u16_iterator() : m_position(), m_current(0)
+ {
+ m_values[0] = 0;
+ m_values[1] = 0;
+ m_values[2] = 0;
+ }
+ u32_to_u16_iterator(BaseIterator b) : m_position(b), m_current(2)
+ {
+ m_values[0] = 0;
+ m_values[1] = 0;
+ m_values[2] = 0;
+ }
+private:
+
+ void extract_current()const
+ {
+ // begin by checking for a code point out of range:
+ ::boost::uint32_t v = *m_position;
+ if(v >= 0x10000u)
+ {
+ if(v > 0x10FFFFu)
+ detail::invalid_utf32_code_point(*m_position);
+ // split into two surrogates:
+ m_values[0] = static_cast<U16Type>(v >> 10) + detail::high_surrogate_base;
+ m_values[1] = static_cast<U16Type>(v & detail::ten_bit_mask) + detail::low_surrogate_base;
+ m_current = 0;
+ BOOST_ASSERT(detail::is_high_surrogate(m_values[0]));
+ BOOST_ASSERT(detail::is_low_surrogate(m_values[1]));
+ }
+ else
+ {
+ // 16-bit code point:
+ m_values[0] = static_cast<U16Type>(*m_position);
+ m_values[1] = 0;
+ m_current = 0;
+ // value must not be a surrogate:
+ if(detail::is_surrogate(m_values[0]))
+ detail::invalid_utf32_code_point(*m_position);
+ }
+ }
+ BaseIterator m_position;
+ mutable U16Type m_values[3];
+ mutable unsigned m_current;
+};
+
+template <class BaseIterator, class U32Type = ::boost::uint32_t>
+class u16_to_u32_iterator
+ : public boost::iterator_facade<u16_to_u32_iterator<BaseIterator, U32Type>, U32Type, std::bidirectional_iterator_tag, const U32Type>
+{
+ typedef boost::iterator_facade<u16_to_u32_iterator<BaseIterator, U32Type>, U32Type, std::bidirectional_iterator_tag, const U32Type> base_type;
+ // special values for pending iterator reads:
+ BOOST_STATIC_CONSTANT(U32Type, pending_read = 0xffffffffu);
+
+#if !defined(BOOST_NO_STD_ITERATOR_TRAITS) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+ typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;
+
+ BOOST_STATIC_ASSERT(sizeof(base_value_type)*CHAR_BIT == 16);
+ BOOST_STATIC_ASSERT(sizeof(U32Type)*CHAR_BIT == 32);
+#endif
+
+public:
+ typename base_type::reference
+ dereference()const
+ {
+ if(m_value == pending_read)
+ extract_current();
+ return m_value;
+ }
+ bool equal(const u16_to_u32_iterator& that)const
+ {
+ return m_position == that.m_position;
+ }
+ void increment()
+ {
+ // skip high surrogate first if there is one:
+ if(detail::is_high_surrogate(*m_position)) ++m_position;
+ ++m_position;
+ m_value = pending_read;
+ }
+ void decrement()
+ {
+ --m_position;
+ // if we have a low surrogate then go back one more:
+ if(detail::is_low_surrogate(*m_position))
+ --m_position;
+ m_value = pending_read;
+ }
+ BaseIterator base()const
+ {
+ return m_position;
+ }
+ // construct:
+ u16_to_u32_iterator() : m_position()
+ {
+ m_value = pending_read;
+ }
+ u16_to_u32_iterator(BaseIterator b) : m_position(b)
+ {
+ m_value = pending_read;
+ }
+private:
+ static void invalid_code_point(::boost::uint16_t val)
+ {
+#ifndef BOOST_NO_STD_LOCALE
+ std::stringstream ss;
+ ss << "Misplaced UTF-16 surrogate U+" << std::showbase << std::hex << val << " encountered while trying to encode UTF-32 sequence";
+ std::out_of_range e(ss.str());
+#else
+ std::out_of_range e("Misplaced UTF-16 surrogate encountered while trying to encode UTF-32 sequence");
+#endif
+ boost::throw_exception(e);
+ }
+ void extract_current()const
+ {
+ m_value = static_cast<U32Type>(static_cast< ::boost::uint16_t>(*m_position));
+ // if the last value is a high surrogate then adjust m_position and m_value as needed:
+ if(detail::is_high_surrogate(*m_position))
+ {
+ // precondition; next value must have be a low-surrogate:
+ BaseIterator next(m_position);
+ ::boost::uint16_t t = *++next;
+ if((t & 0xFC00u) != 0xDC00u)
+ invalid_code_point(t);
+ m_value = (m_value - detail::high_surrogate_base) << 10;
+ m_value |= (static_cast<U32Type>(static_cast< ::boost::uint16_t>(t)) & detail::ten_bit_mask);
+ }
+ // postcondition; result must not be a surrogate:
+ if(detail::is_surrogate(m_value))
+ invalid_code_point(static_cast< ::boost::uint16_t>(m_value));
+ }
+ BaseIterator m_position;
+ mutable U32Type m_value;
+};
+
+template <class BaseIterator, class U8Type = ::boost::uint8_t>
+class u32_to_u8_iterator
+ : public boost::iterator_facade<u32_to_u8_iterator<BaseIterator, U8Type>, U8Type, std::bidirectional_iterator_tag, const U8Type>
+{
+ typedef boost::iterator_facade<u32_to_u8_iterator<BaseIterator, U8Type>, U8Type, std::bidirectional_iterator_tag, const U8Type> base_type;
+
+#if !defined(BOOST_NO_STD_ITERATOR_TRAITS) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+ typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;
+
+ BOOST_STATIC_ASSERT(sizeof(base_value_type)*CHAR_BIT == 32);
+ BOOST_STATIC_ASSERT(sizeof(U8Type)*CHAR_BIT == 8);
+#endif
+
+public:
+ typename base_type::reference
+ dereference()const
+ {
+ if(m_current == 4)
+ extract_current();
+ return m_values[m_current];
+ }
+ bool equal(const u32_to_u8_iterator& that)const
+ {
+ if(m_position == that.m_position)
+ {
+ // either the m_current's must be equal, or one must be 0 and
+ // the other 4: which means neither must have bits 1 or 2 set:
+ return (m_current == that.m_current)
+ || (((m_current | that.m_current) & 3) == 0);
+ }
+ return false;
+ }
+ void increment()
+ {
+ // if we have a pending read then read now, so that we know whether
+ // to skip a position, or move to a low-surrogate:
+ if(m_current == 4)
+ {
+ // pending read:
+ extract_current();
+ }
+ // move to the next surrogate position:
+ ++m_current;
+ // if we've reached the end skip a position:
+ if(m_values[m_current] == 0)
+ {
+ m_current = 4;
+ ++m_position;
+ }
+ }
+ void decrement()
+ {
+ if((m_current & 3) == 0)
+ {
+ --m_position;
+ extract_current();
+ m_current = 3;
+ while(m_current && (m_values[m_current] == 0))
+ --m_current;
+ }
+ else
+ --m_current;
+ }
+ BaseIterator base()const
+ {
+ return m_position;
+ }
+ // construct:
+ u32_to_u8_iterator() : m_position(), m_current(0)
+ {
+ m_values[0] = 0;
+ m_values[1] = 0;
+ m_values[2] = 0;
+ m_values[3] = 0;
+ m_values[4] = 0;
+ }
+ u32_to_u8_iterator(BaseIterator b) : m_position(b), m_current(4)
+ {
+ m_values[0] = 0;
+ m_values[1] = 0;
+ m_values[2] = 0;
+ m_values[3] = 0;
+ m_values[4] = 0;
+ }
+private:
+
+ void extract_current()const
+ {
+ boost::uint32_t c = *m_position;
+ if(c > 0x10FFFFu)
+ detail::invalid_utf32_code_point(c);
+ if(c < 0x80u)
+ {
+ m_values[0] = static_cast<unsigned char>(c);
+ m_values[1] = static_cast<unsigned char>(0u);
+ m_values[2] = static_cast<unsigned char>(0u);
+ m_values[3] = static_cast<unsigned char>(0u);
+ }
+ else if(c < 0x800u)
+ {
+ m_values[0] = static_cast<unsigned char>(0xC0u + (c >> 6));
+ m_values[1] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
+ m_values[2] = static_cast<unsigned char>(0u);
+ m_values[3] = static_cast<unsigned char>(0u);
+ }
+ else if(c < 0x10000u)
+ {
+ m_values[0] = static_cast<unsigned char>(0xE0u + (c >> 12));
+ m_values[1] = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));
+ m_values[2] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
+ m_values[3] = static_cast<unsigned char>(0u);
+ }
+ else
+ {
+ m_values[0] = static_cast<unsigned char>(0xF0u + (c >> 18));
+ m_values[1] = static_cast<unsigned char>(0x80u + ((c >> 12) & 0x3Fu));
+ m_values[2] = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));
+ m_values[3] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
+ }
+ m_current= 0;
+ }
+ BaseIterator m_position;
+ mutable U8Type m_values[5];
+ mutable unsigned m_current;
+};
+
+template <class BaseIterator, class U32Type = ::boost::uint32_t>
+class u8_to_u32_iterator
+ : public boost::iterator_facade<u8_to_u32_iterator<BaseIterator, U32Type>, U32Type, std::bidirectional_iterator_tag, const U32Type>
+{
+ typedef boost::iterator_facade<u8_to_u32_iterator<BaseIterator, U32Type>, U32Type, std::bidirectional_iterator_tag, const U32Type> base_type;
+ // special values for pending iterator reads:
+ BOOST_STATIC_CONSTANT(U32Type, pending_read = 0xffffffffu);
+
+#if !defined(BOOST_NO_STD_ITERATOR_TRAITS) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+ typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;
+
+ BOOST_STATIC_ASSERT(sizeof(base_value_type)*CHAR_BIT == 8);
+ BOOST_STATIC_ASSERT(sizeof(U32Type)*CHAR_BIT == 32);
+#endif
+
+public:
+ typename base_type::reference
+ dereference()const
+ {
+ if(m_value == pending_read)
+ extract_current();
+ return m_value;
+ }
+ bool equal(const u8_to_u32_iterator& that)const
+ {
+ return m_position == that.m_position;
+ }
+ void increment()
+ {
+ // skip high surrogate first if there is one:
+ unsigned c = detail::utf8_byte_count(*m_position);
+ std::advance(m_position, c);
+ m_value = pending_read;
+ }
+ void decrement()
+ {
+ // Keep backtracking until we don't have a trailing character:
+ unsigned count = 0;
+ while((*--m_position & 0xC0u) == 0x80u) ++count;
+ // now check that the sequence was valid:
+ if(count != detail::utf8_trailing_byte_count(*m_position))
+ invalid_sequnce();
+ m_value = pending_read;
+ }
+ BaseIterator base()const
+ {
+ return m_position;
+ }
+ // construct:
+ u8_to_u32_iterator() : m_position()
+ {
+ m_value = pending_read;
+ }
+ u8_to_u32_iterator(BaseIterator b) : m_position(b)
+ {
+ m_value = pending_read;
+ }
+private:
+ static void invalid_sequnce()
+ {
+ std::out_of_range e("Invalid UTF-8 sequence encountered while trying to encode UTF-32 character");
+ boost::throw_exception(e);
+ }
+ void extract_current()const
+ {
+ m_value = static_cast<U32Type>(static_cast< ::boost::uint8_t>(*m_position));
+ // we must not have a continuation character:
+ if((m_value & 0xC0u) == 0x80u)
+ invalid_sequnce();
+ // see how many extra byts we have:
+ unsigned extra = detail::utf8_trailing_byte_count(*m_position);
+ // extract the extra bits, 6 from each extra byte:
+ BaseIterator next(m_position);
+ for(unsigned c = 0; c < extra; ++c)
+ {
+ ++next;
+ m_value <<= 6;
+ m_value += static_cast<boost::uint8_t>(*next) & 0x3Fu;
+ }
+ // we now need to remove a few of the leftmost bits, but how many depends
+ // upon how many extra bytes we've extracted:
+ static const boost::uint32_t masks[4] =
+ {
+ 0x7Fu,
+ 0x7FFu,
+ 0xFFFFu,
+ 0x1FFFFFu,
+ };
+ m_value &= masks[extra];
+ // check the result:
+ if(m_value > static_cast<U32Type>(0x10FFFFu))
+ invalid_sequnce();
+ }
+ BaseIterator m_position;
+ mutable U32Type m_value;
+};
+
+template <class BaseIterator>
+class utf16_output_iterator
+{
+public:
+ typedef void difference_type;
+ typedef void value_type;
+ typedef boost::uint32_t* pointer;
+ typedef boost::uint32_t& reference;
+ typedef std::output_iterator_tag iterator_category;
+
+ utf16_output_iterator(const BaseIterator& b)
+ : m_position(b){}
+ utf16_output_iterator(const utf16_output_iterator& that)
+ : m_position(that.m_position){}
+ utf16_output_iterator& operator=(const utf16_output_iterator& that)
+ {
+ m_position = that.m_position;
+ return *this;
+ }
+ const utf16_output_iterator& operator*()const
+ {
+ return *this;
+ }
+ void operator=(boost::uint32_t val)const
+ {
+ push(val);
+ }
+ utf16_output_iterator& operator++()
+ {
+ return *this;
+ }
+ utf16_output_iterator& operator++(int)
+ {
+ return *this;
+ }
+ BaseIterator base()const
+ {
+ return m_position;
+ }
+private:
+ void push(boost::uint32_t v)const
+ {
+ if(v >= 0x10000u)
+ {
+ // begin by checking for a code point out of range:
+ if(v > 0x10FFFFu)
+ detail::invalid_utf32_code_point(v);
+ // split into two surrogates:
+ *m_position++ = static_cast<boost::uint16_t>(v >> 10) + detail::high_surrogate_base;
+ *m_position++ = static_cast<boost::uint16_t>(v & detail::ten_bit_mask) + detail::low_surrogate_base;
+ }
+ else
+ {
+ // 16-bit code point:
+ // value must not be a surrogate:
+ if(detail::is_surrogate(v))
+ detail::invalid_utf32_code_point(v);
+ *m_position++ = static_cast<boost::uint16_t>(v);
+ }
+ }
+ mutable BaseIterator m_position;
+};
+
+template <class BaseIterator>
+class utf8_output_iterator
+{
+public:
+ typedef void difference_type;
+ typedef void value_type;
+ typedef boost::uint32_t* pointer;
+ typedef boost::uint32_t& reference;
+ typedef std::output_iterator_tag iterator_category;
+
+ utf8_output_iterator(const BaseIterator& b)
+ : m_position(b){}
+ utf8_output_iterator(const utf8_output_iterator& that)
+ : m_position(that.m_position){}
+ utf8_output_iterator& operator=(const utf8_output_iterator& that)
+ {
+ m_position = that.m_position;
+ return *this;
+ }
+ const utf8_output_iterator& operator*()const
+ {
+ return *this;
+ }
+ void operator=(boost::uint32_t val)const
+ {
+ push(val);
+ }
+ utf8_output_iterator& operator++()
+ {
+ return *this;
+ }
+ utf8_output_iterator& operator++(int)
+ {
+ return *this;
+ }
+ BaseIterator base()const
+ {
+ return m_position;
+ }
+private:
+ void push(boost::uint32_t c)const
+ {
+ if(c > 0x10FFFFu)
+ detail::invalid_utf32_code_point(c);
+ if(c < 0x80u)
+ {
+ *m_position++ = static_cast<unsigned char>(c);
+ }
+ else if(c < 0x800u)
+ {
+ *m_position++ = static_cast<unsigned char>(0xC0u + (c >> 6));
+ *m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
+ }
+ else if(c < 0x10000u)
+ {
+ *m_position++ = static_cast<unsigned char>(0xE0u + (c >> 12));
+ *m_position++ = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));
+ *m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
+ }
+ else
+ {
+ *m_position++ = static_cast<unsigned char>(0xF0u + (c >> 18));
+ *m_position++ = static_cast<unsigned char>(0x80u + ((c >> 12) & 0x3Fu));
+ *m_position++ = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));
+ *m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));
+ }
+ }
+ mutable BaseIterator m_position;
+};
+
+} // namespace boost
+
+#endif // BOOST_REGEX_UNICODE_ITERATOR_HPP
+
diff --git a/ext/boost/regex/regex_traits.hpp b/ext/boost/regex/regex_traits.hpp
new file mode 100644
index 0000000000..730ba6e0d8
--- /dev/null
+++ b/ext/boost/regex/regex_traits.hpp
@@ -0,0 +1,35 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_traits.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares regular expression traits classes.
+ */
+
+#ifndef BOOST_REGEX_TRAITS_HPP
+#define BOOST_REGEX_TRAITS_HPP
+
+#ifndef BOOST_REGEX_CONFIG_HPP
+# include <boost/regex/config.hpp>
+#endif
+
+# ifndef BOOST_REGEX_TRAITS_HPP_INCLUDED
+# include <boost/regex/v4/regex_traits.hpp>
+# endif
+
+#endif // include
+
+
+
+
+
diff --git a/ext/boost/regex/user.hpp b/ext/boost/regex/user.hpp
new file mode 100644
index 0000000000..95908173d7
--- /dev/null
+++ b/ext/boost/regex/user.hpp
@@ -0,0 +1,90 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE user.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: User settable options.
+ */
+
+// define if you want the regex library to use the C locale
+// even on Win32:
+// #define BOOST_REGEX_USE_C_LOCALE
+
+// define this is you want the regex library to use the C++
+// locale:
+// #define BOOST_REGEX_USE_CPP_LOCALE
+
+// define this if the runtime library is a dll, and you
+// want BOOST_REGEX_DYN_LINK to set up dll exports/imports
+// with __declspec(dllexport)/__declspec(dllimport.)
+// #define BOOST_REGEX_HAS_DLL_RUNTIME
+
+// define this if you want to dynamically link to regex,
+// if the runtime library is also a dll (Probably Win32 specific,
+// and has no effect unless BOOST_REGEX_HAS_DLL_RUNTIME is set):
+// #define BOOST_REGEX_DYN_LINK
+
+// define this if you don't want the lib to automatically
+// select its link libraries:
+// #define BOOST_REGEX_NO_LIB
+
+// define this if templates with switch statements cause problems:
+// #define BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE
+
+// define this to disable Win32 support when available:
+// #define BOOST_REGEX_NO_W32
+
+// define this if bool is not a real type:
+// #define BOOST_REGEX_NO_BOOL
+
+// define this if no template instances are to be placed in
+// the library rather than users object files:
+// #define BOOST_REGEX_NO_EXTERNAL_TEMPLATES
+
+// define this if the forward declarations in regex_fwd.hpp
+// cause more problems than they are worth:
+// #define BOOST_REGEX_NO_FWD
+
+// define this if your compiler supports MS Windows structured
+// exception handling.
+// #define BOOST_REGEX_HAS_MS_STACK_GUARD
+
+// define this if you want to use the recursive algorithm
+// even if BOOST_REGEX_HAS_MS_STACK_GUARD is not defined.
+// #define BOOST_REGEX_RECURSIVE
+
+// define this if you want to use the non-recursive
+// algorithm, even if the recursive version would be the default.
+// #define BOOST_REGEX_NON_RECURSIVE
+
+// define this if you want to set the size of the memory blocks
+// used by the non-recursive algorithm.
+// #define BOOST_REGEX_BLOCKSIZE 4096
+
+// define this if you want to set the maximum number of memory blocks
+// used by the non-recursive algorithm.
+// #define BOOST_REGEX_MAX_BLOCKS 1024
+
+// define this if you want to set the maximum number of memory blocks
+// cached by the non-recursive algorithm: Normally this is 16, but can be
+// higher if you have multiple threads all using boost.regex, or lower
+// if you don't want boost.regex to cache memory.
+// #define BOOST_REGEX_MAX_CACHE_BLOCKS 16
+
+// define this if you want to be able to access extended capture
+// information in your sub_match's (caution this will slow things
+// down quite a bit).
+// #define BOOST_REGEX_MATCH_EXTRA
+
+// define this if you want to enable support for Unicode via ICU.
+// #define BOOST_HAS_ICU
diff --git a/ext/boost/regex/v4/basic_regex.hpp b/ext/boost/regex/v4/basic_regex.hpp
new file mode 100644
index 0000000000..09b0467b40
--- /dev/null
+++ b/ext/boost/regex/v4/basic_regex.hpp
@@ -0,0 +1,825 @@
+/*
+ *
+ * Copyright (c) 1998-2004
+ * John Maddock
+ *
+ * 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)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org/ for most recent version.
+ * FILE basic_regex.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares template class basic_regex.
+ */
+
+#ifndef BOOST_REGEX_V4_BASIC_REGEX_HPP
+#define BOOST_REGEX_V4_BASIC_REGEX_HPP
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/functional/hash.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace boost{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4251 4231 4660 4800)
+#endif
+
+namespace re_detail{
+
+//
+// forward declaration, we will need this one later:
+//
+template <class charT, class traits>
+class basic_regex_parser;
+
+template <class I>
+void bubble_down_one(I first, I last)
+{
+ if(first != last)
+ {
+ I next = last - 1;
+ while((next != first) && !(*(next-1) < *next))
+ {
+ (next-1)->swap(*next);
+ --next;
+ }
+ }
+}
+
+//
+// Class named_subexpressions
+// Contains information about named subexpressions within the regex.
+//
+template <class charT>
+class named_subexpressions_base
+{
+public:
+ virtual int get_id(const charT* i, const charT* j)const = 0;
+ virtual int get_id(std::size_t hash)const = 0;
+#ifdef __GNUC__
+ // warning supression:
+ virtual ~named_subexpressions_base(){}
+#endif
+};
+
+template <class Iterator>
+inline std::size_t hash_value_from_capture_name(Iterator i, Iterator j)
+{
+ std::size_t r = boost::hash_range(i, j);
+ r %= ((std::numeric_limits<int>::max)() - 10001);
+ r += 10000;
+ return r;
+}
+
+template <class charT>
+class named_subexpressions : public named_subexpressions_base<charT>
+{
+ struct name
+ {
+ name(const charT* i, const charT* j, int idx)
+ : /*n(i, j), */ index(idx)
+ {
+ hash = hash_value_from_capture_name(i, j);
+ }
+ name(std::size_t h, int idx)
+ : index(idx), hash(h)
+ {
+ }
+ //std::vector<charT> n;
+ int index;
+ std::size_t hash;
+ bool operator < (const name& other)const
+ {
+ return hash < other.hash; //std::lexicographical_compare(n.begin(), n.end(), other.n.begin(), other.n.end());
+ }
+ bool operator == (const name& other)const
+ {
+ return hash == other.hash; //n == other.n;
+ }
+ void swap(name& other)
+ {
+ //n.swap(other.n);
+ std::swap(index, other.index);
+ std::swap(hash, other.hash);
+ }
+ };
+public:
+ named_subexpressions(){}
+ void set_name(const charT* i, const charT* j, int index)
+ {
+ m_sub_names.push_back(name(i, j, index));
+ bubble_down_one(m_sub_names.begin(), m_sub_names.end());
+ }
+ int get_id(const charT* i, const charT* j)const
+ {
+ name t(i, j, 0);
+ typename std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
+ if((pos != m_sub_names.end()) && (*pos == t))
+ {
+ return pos->index;
+ }
+ return -1;
+ }
+ int get_id(std::size_t h)const
+ {
+ name t(h, 0);
+ typename std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
+ if((pos != m_sub_names.end()) && (*pos == t))
+ {
+ return pos->index;
+ }
+ return -1;
+ }
+private:
+ std::vector<name> m_sub_names;
+};
+
+template <class charT, class Other>
+class named_subexpressions_converter : public named_subexpressions_base<charT>
+{
+ boost::shared_ptr<named_subexpressions<Other> > m_converter;
+public:
+ named_subexpressions_converter(boost::shared_ptr<named_subexpressions<Other> > s)
+ : m_converter(s) {}
+ int get_id(const charT* i, const charT* j)const
+ {
+ if(i == j)
+ return -1;
+ std::vector<Other> v;
+ while(i != j)
+ {
+ v.push_back(*i);
+ ++i;
+ }
+ return m_converter->get_id(&v[0], &v[0] + v.size());
+ }
+ int get_id(std::size_t h)const
+ {
+ return m_converter->get_id(h);
+ }
+};
+
+template <class To>
+inline boost::shared_ptr<named_subexpressions_base<To> > convert_to_named_subs_imp(
+ boost::shared_ptr<named_subexpressions<To> > s,
+ boost::integral_constant<bool,true> const&)
+{
+ return s;
+}
+template <class To, class From>
+inline boost::shared_ptr<named_subexpressions_base<To> > convert_to_named_subs_imp(
+ boost::shared_ptr<named_subexpressions<From> > s,
+ boost::integral_constant<bool,false> const&)
+{
+ return boost::shared_ptr<named_subexpressions_converter<To, From> >(new named_subexpressions_converter<To, From>(s));
+}
+template <class To, class From>
+inline boost::shared_ptr<named_subexpressions_base<To> > convert_to_named_subs(
+ boost::shared_ptr<named_subexpressions<From> > s)
+{
+ typedef typename boost::is_same<To, From>::type tag_type;
+ return convert_to_named_subs_imp<To>(s, tag_type());
+}
+//
+// class regex_data:
+// represents the data we wish to expose to the matching algorithms.
+//
+template <class charT, class traits>
+struct regex_data : public named_subexpressions<charT>
+{
+ typedef regex_constants::syntax_option_type flag_type;
+ typedef std::size_t size_type;
+
+ regex_data(const ::boost::shared_ptr<
+ ::boost::regex_traits_wrapper<traits> >& t)
+ : m_ptraits(t), m_expression(0), m_expression_len(0) {}
+ regex_data()
+ : m_ptraits(new ::boost::regex_traits_wrapper<traits>()), m_expression(0), m_expression_len(0) {}
+
+ ::boost::shared_ptr<
+ ::boost::regex_traits_wrapper<traits>
+ > m_ptraits; // traits class instance
+ flag_type m_flags; // flags with which we were compiled
+ int m_status; // error code (0 implies OK).
+ const charT* m_expression; // the original expression
+ std::ptrdiff_t m_expression_len; // the length of the original expression
+ size_type m_mark_count; // the number of marked sub-expressions
+ re_detail::re_syntax_base* m_first_state; // the first state of the machine
+ unsigned m_restart_type; // search optimisation type
+ unsigned char m_startmap[1 << CHAR_BIT]; // which characters can start a match
+ unsigned int m_can_be_null; // whether we can match a null string
+ re_detail::raw_storage m_data; // the buffer in which our states are constructed
+ typename traits::char_class_type m_word_mask; // mask used to determine if a character is a word character
+ std::vector<
+ std::pair<
+ std::size_t, std::size_t> > m_subs; // Position of sub-expressions within the *string*.
+ bool m_has_recursions; // whether we have recursive expressions;
+};
+//
+// class basic_regex_implementation
+// pimpl implementation class for basic_regex.
+//
+template <class charT, class traits>
+class basic_regex_implementation
+ : public regex_data<charT, traits>
+{
+public:
+ typedef regex_constants::syntax_option_type flag_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::size_t size_type;
+ typedef typename traits::locale_type locale_type;
+ typedef const charT* const_iterator;
+
+ basic_regex_implementation(){}
+ basic_regex_implementation(const ::boost::shared_ptr<
+ ::boost::regex_traits_wrapper<traits> >& t)
+ : regex_data<charT, traits>(t) {}
+ void assign(const charT* arg_first,
+ const charT* arg_last,
+ flag_type f)
+ {
+ regex_data<charT, traits>* pdat = this;
+ basic_regex_parser<charT, traits> parser(pdat);
+ parser.parse(arg_first, arg_last, f);
+ }
+
+ locale_type BOOST_REGEX_CALL imbue(locale_type l)
+ {
+ return this->m_ptraits->imbue(l);
+ }
+ locale_type BOOST_REGEX_CALL getloc()const
+ {
+ return this->m_ptraits->getloc();
+ }
+ std::basic_string<charT> BOOST_REGEX_CALL str()const
+ {
+ std::basic_string<charT> result;
+ if(this->m_status == 0)
+ result = std::basic_string<charT>(this->m_expression, this->m_expression_len);
+ return result;
+ }
+ const_iterator BOOST_REGEX_CALL expression()const
+ {
+ return this->m_expression;
+ }
+ std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const
+ {
+ if(n == 0)
+ throw std::out_of_range("0 is not a valid subexpression index.");
+ const std::pair<std::size_t, std::size_t>& pi = this->m_subs.at(n - 1);
+ std::pair<const_iterator, const_iterator> p(expression() + pi.first, expression() + pi.second);
+ return p;
+ }
+ //
+ // begin, end:
+ const_iterator BOOST_REGEX_CALL begin()const
+ {
+ return (!this->m_status ? 0 : this->m_expression);
+ }
+ const_iterator BOOST_REGEX_CALL end()const
+ {
+ return (!this->m_status ? 0 : this->m_expression + this->m_expression_len);
+ }
+ flag_type BOOST_REGEX_CALL flags()const
+ {
+ return this->m_flags;
+ }
+ size_type BOOST_REGEX_CALL size()const
+ {
+ return this->m_expression_len;
+ }
+ int BOOST_REGEX_CALL status()const
+ {
+ return this->m_status;
+ }
+ size_type BOOST_REGEX_CALL mark_count()const
+ {
+ return this->m_mark_count;
+ }
+ const re_detail::re_syntax_base* get_first_state()const
+ {
+ return this->m_first_state;
+ }
+ unsigned get_restart_type()const
+ {
+ return this->m_restart_type;
+ }
+ const unsigned char* get_map()const
+ {
+ return this->m_startmap;
+ }
+ const ::boost::regex_traits_wrapper<traits>& get_traits()const
+ {
+ return *(this->m_ptraits);
+ }
+ bool can_be_null()const
+ {
+ return this->m_can_be_null;
+ }
+ const regex_data<charT, traits>& get_data()const
+ {
+ basic_regex_implementation<charT, traits> const* p = this;
+ return *static_cast<const regex_data<charT, traits>*>(p);
+ }
+};
+
+} // namespace re_detail
+//
+// class basic_regex:
+// represents the compiled
+// regular expression:
+//
+
+#ifdef BOOST_REGEX_NO_FWD
+template <class charT, class traits = regex_traits<charT> >
+#else
+template <class charT, class traits >
+#endif
+class basic_regex : public regbase
+{
+public:
+ // typedefs:
+ typedef std::size_t traits_size_type;
+ typedef typename traits::string_type traits_string_type;
+ typedef charT char_type;
+ typedef traits traits_type;
+
+ typedef charT value_type;
+ typedef charT& reference;
+ typedef const charT& const_reference;
+ typedef const charT* const_iterator;
+ typedef const_iterator iterator;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::size_t size_type;
+ typedef regex_constants::syntax_option_type flag_type;
+ // locale_type
+ // placeholder for actual locale type used by the
+ // traits class to localise *this.
+ typedef typename traits::locale_type locale_type;
+
+public:
+ explicit basic_regex(){}
+ explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)
+ {
+ assign(p, f);
+ }
+ basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
+ {
+ assign(p1, p2, f);
+ }
+ basic_regex(const charT* p, size_type len, flag_type f)
+ {
+ assign(p, len, f);
+ }
+ basic_regex(const basic_regex& that)
+ : m_pimpl(that.m_pimpl) {}
+ ~basic_regex(){}
+ basic_regex& BOOST_REGEX_CALL operator=(const basic_regex& that)
+ {
+ return assign(that);
+ }
+ basic_regex& BOOST_REGEX_CALL operator=(const charT* ptr)
+ {
+ return assign(ptr);
+ }
+
+ //
+ // assign:
+ basic_regex& assign(const basic_regex& that)
+ {
+ m_pimpl = that.m_pimpl;
+ return *this;
+ }
+ basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)
+ {
+ return assign(p, p + traits::length(p), f);
+ }
+ basic_regex& assign(const charT* p, size_type len, flag_type f)
+ {
+ return assign(p, p + len, f);
+ }
+private:
+ basic_regex& do_assign(const charT* p1,
+ const charT* p2,
+ flag_type f);
+public:
+ basic_regex& assign(const charT* p1,
+ const charT* p2,
+ flag_type f = regex_constants::normal)
+ {
+ return do_assign(p1, p2, f);
+ }
+#if !defined(BOOST_NO_MEMBER_TEMPLATES)
+
+ template <class ST, class SA>
+ unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
+ {
+ return set_expression(p.data(), p.data() + p.size(), f);
+ }
+
+ template <class ST, class SA>
+ explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
+ {
+ assign(p, f);
+ }
+
+ template <class InputIterator>
+ basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
+ {
+ typedef typename traits::string_type seq_type;
+ seq_type a(arg_first, arg_last);
+ if(a.size())
+ assign(&*a.begin(), &*a.begin() + a.size(), f);
+ else
+ assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
+ }
+
+ template <class ST, class SA>
+ basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
+ {
+ return assign(p.data(), p.data() + p.size(), regex_constants::normal);
+ }
+
+ template <class string_traits, class A>
+ basic_regex& BOOST_REGEX_CALL assign(
+ const std::basic_string<charT, string_traits, A>& s,
+ flag_type f = regex_constants::normal)
+ {
+ return assign(s.data(), s.data() + s.size(), f);
+ }
+
+ template <class InputIterator>
+ basic_regex& BOOST_REGEX_CALL assign(InputIterator arg_first,
+ InputIterator arg_last,
+ flag_type f = regex_constants::normal)
+ {
+ typedef typename traits::string_type seq_type;
+ seq_type a(arg_first, arg_last);
+ if(a.size())
+ {
+ const charT* p1 = &*a.begin();
+ const charT* p2 = &*a.begin() + a.size();
+ return assign(p1, p2, f);
+ }
+ return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
+ }
+#else
+ unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
+ {
+ return set_expression(p.data(), p.data() + p.size(), f);
+ }
+
+ basic_regex(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
+ {
+ assign(p, f);
+ }
+
+ basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
+ {
+ return assign(p.data(), p.data() + p.size(), regex_constants::normal);
+ }
+
+ basic_regex& BOOST_REGEX_CALL assign(
+ const std::basic_string<charT>& s,
+ flag_type f = regex_constants::normal)
+ {
+ return assign(s.data(), s.data() + s.size(), f);
+ }
+
+#endif
+
+ //
+ // locale:
+ locale_type BOOST_REGEX_CALL imbue(locale_type l);
+ locale_type BOOST_REGEX_CALL getloc()const
+ {
+ return m_pimpl.get() ? m_pimpl->getloc() : locale_type();
+ }
+ //
+ // getflags:
+ // retained for backwards compatibility only, "flags"
+ // is now the preferred name:
+ flag_type BOOST_REGEX_CALL getflags()const
+ {
+ return flags();
+ }
+ flag_type BOOST_REGEX_CALL flags()const
+ {
+ return m_pimpl.get() ? m_pimpl->flags() : 0;
+ }
+ //
+ // str:
+ std::basic_string<charT> BOOST_REGEX_CALL str()const
+ {
+ return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();
+ }
+ //
+ // begin, end, subexpression:
+ std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const
+ {
+ if(!m_pimpl.get())
+ throw std::logic_error("Can't access subexpressions in an invalid regex.");
+ return m_pimpl->subexpression(n);
+ }
+ const_iterator BOOST_REGEX_CALL begin()const
+ {
+ return (m_pimpl.get() ? m_pimpl->begin() : 0);
+ }
+ const_iterator BOOST_REGEX_CALL end()const
+ {
+ return (m_pimpl.get() ? m_pimpl->end() : 0);
+ }
+ //
+ // swap:
+ void BOOST_REGEX_CALL swap(basic_regex& that)throw()
+ {
+ m_pimpl.swap(that.m_pimpl);
+ }
+ //
+ // size:
+ size_type BOOST_REGEX_CALL size()const
+ {
+ return (m_pimpl.get() ? m_pimpl->size() : 0);
+ }
+ //
+ // max_size:
+ size_type BOOST_REGEX_CALL max_size()const
+ {
+ return UINT_MAX;
+ }
+ //
+ // empty:
+ bool BOOST_REGEX_CALL empty()const
+ {
+ return (m_pimpl.get() ? 0 != m_pimpl->status() : true);
+ }
+
+ size_type BOOST_REGEX_CALL mark_count()const
+ {
+ return (m_pimpl.get() ? m_pimpl->mark_count() : 0);
+ }
+
+ int status()const
+ {
+ return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);
+ }
+
+ int BOOST_REGEX_CALL compare(const basic_regex& that) const
+ {
+ if(m_pimpl.get() == that.m_pimpl.get())
+ return 0;
+ if(!m_pimpl.get())
+ return -1;
+ if(!that.m_pimpl.get())
+ return 1;
+ if(status() != that.status())
+ return status() - that.status();
+ if(flags() != that.flags())
+ return flags() - that.flags();
+ return str().compare(that.str());
+ }
+ bool BOOST_REGEX_CALL operator==(const basic_regex& e)const
+ {
+ return compare(e) == 0;
+ }
+ bool BOOST_REGEX_CALL operator != (const basic_regex& e)const
+ {
+ return compare(e) != 0;
+ }
+ bool BOOST_REGEX_CALL operator<(const basic_regex& e)const
+ {
+ return compare(e) < 0;
+ }
+ bool BOOST_REGEX_CALL operator>(const basic_regex& e)const
+ {
+ return compare(e) > 0;
+ }
+ bool BOOST_REGEX_CALL operator<=(const basic_regex& e)const
+ {
+ return compare(e) <= 0;
+ }
+ bool BOOST_REGEX_CALL operator>=(const basic_regex& e)const
+ {
+ return compare(e) >= 0;
+ }
+
+ //
+ // The following are deprecated as public interfaces
+ // but are available for compatibility with earlier versions.
+ const charT* BOOST_REGEX_CALL expression()const
+ {
+ return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0);
+ }
+ unsigned int BOOST_REGEX_CALL set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
+ {
+ assign(p1, p2, f | regex_constants::no_except);
+ return status();
+ }
+ unsigned int BOOST_REGEX_CALL set_expression(const charT* p, flag_type f = regex_constants::normal)
+ {
+ assign(p, f | regex_constants::no_except);
+ return status();
+ }
+ unsigned int BOOST_REGEX_CALL error_code()const
+ {
+ return status();
+ }
+ //
+ // private access methods:
+ //
+ const re_detail::re_syntax_base* get_first_state()const
+ {
+ BOOST_ASSERT(0 != m_pimpl.get());
+ return m_pimpl->get_first_state();
+ }
+ unsigned get_restart_type()const
+ {
+ BOOST_ASSERT(0 != m_pimpl.get());
+ return m_pimpl->get_restart_type();
+ }
+ const unsigned char* get_map()const
+ {
+ BOOST_ASSERT(0 != m_pimpl.get());
+ return m_pimpl->get_map();
+ }
+ const ::boost::regex_traits_wrapper<traits>& get_traits()const
+ {
+ BOOST_ASSERT(0 != m_pimpl.get());
+ return m_pimpl->get_traits();
+ }
+ bool can_be_null()const
+ {
+ BOOST_ASSERT(0 != m_pimpl.get());
+ return m_pimpl->can_be_null();
+ }
+ const re_detail::regex_data<charT, traits>& get_data()const
+ {
+ BOOST_ASSERT(0 != m_pimpl.get());
+ return m_pimpl->get_data();
+ }
+ boost::shared_ptr<re_detail::named_subexpressions<charT> > get_named_subs()const
+ {
+ return m_pimpl;
+ }
+
+private:
+ shared_ptr<re_detail::basic_regex_implementation<charT, traits> > m_pimpl;
+};
+
+//
+// out of line members;
+// these are the only members that mutate the basic_regex object,
+// and are designed to provide the strong exception guarentee
+// (in the event of a throw, the state of the object remains unchanged).
+//
+template <class charT, class traits>
+basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,
+ const charT* p2,
+ flag_type f)
+{
+ shared_ptr<re_detail::basic_regex_implementation<charT, traits> > temp;
+ if(!m_pimpl.get())
+ {
+ temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>());
+ }
+ else
+ {
+ temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>(m_pimpl->m_ptraits));
+ }
+ temp->assign(p1, p2, f);
+ temp.swap(m_pimpl);
+ return *this;
+}
+
+template <class charT, class traits>
+typename basic_regex<charT, traits>::locale_type BOOST_REGEX_CALL basic_regex<charT, traits>::imbue(locale_type l)
+{
+ shared_ptr<re_detail::basic_regex_implementation<charT, traits> > temp(new re_detail::basic_regex_implementation<charT, traits>());
+ locale_type result = temp->imbue(l);
+ temp.swap(m_pimpl);
+ return result;
+}
+
+//
+// non-members:
+//
+template <class charT, class traits>
+void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2)
+{
+ e1.swap(e2);
+}
+
+#ifndef BOOST_NO_STD_LOCALE
+template <class charT, class traits, class traits2>
+std::basic_ostream<charT, traits>&
+ operator << (std::basic_ostream<charT, traits>& os,
+ const basic_regex<charT, traits2>& e)
+{
+ return (os << e.str());
+}
+#else
+template <class traits>
+std::ostream& operator << (std::ostream& os, const basic_regex<char, traits>& e)
+{
+ return (os << e.str());
+}
+#endif
+
+//
+// class reg_expression:
+// this is provided for backwards compatibility only,
+// it is deprecated, no not use!
+//
+#ifdef BOOST_REGEX_NO_FWD
+template <class charT, class traits = regex_traits<charT> >
+#else
+template <class charT, class traits >
+#endif
+class reg_expression : public basic_regex<charT, traits>
+{
+public:
+ typedef typename basic_regex<charT, traits>::flag_type flag_type;
+ typedef typename basic_regex<charT, traits>::size_type size_type;
+ explicit reg_expression(){}
+ explicit reg_expression(const charT* p, flag_type f = regex_constants::normal)
+ : basic_regex<charT, traits>(p, f){}
+ reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
+ : basic_regex<charT, traits>(p1, p2, f){}
+ reg_expression(const charT* p, size_type len, flag_type f)
+ : basic_regex<charT, traits>(p, len, f){}
+ reg_expression(const reg_expression& that)
+ : basic_regex<charT, traits>(that) {}
+ ~reg_expression(){}
+ reg_expression& BOOST_REGEX_CALL operator=(const reg_expression& that)
+ {
+ return this->assign(that);
+ }
+
+#if !defined(BOOST_NO_MEMBER_TEMPLATES)
+ template <class ST, class SA>
+ explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
+ : basic_regex<charT, traits>(p, f)
+ {
+ }
+
+ template <class InputIterator>
+ reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
+ : basic_regex<charT, traits>(arg_first, arg_last, f)
+ {
+ }
+
+ template <class ST, class SA>
+ reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
+ {
+ this->assign(p);
+ return *this;
+ }
+#else
+ explicit reg_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
+ : basic_regex<charT, traits>(p, f)
+ {
+ }
+
+ reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
+ {
+ this->assign(p);
+ return *this;
+ }
+#endif
+
+};
+
+#ifdef BOOST_MSVC
+#pragma warning (pop)
+#endif
+
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/ext/boost/regex/v4/basic_regex_creator.hpp b/ext/boost/regex/v4/basic_regex_creator.hpp
new file mode 100644
index 0000000000..6f0050542d
--- /dev/null
+++ b/ext/boost/regex/v4/basic_regex_creator.hpp
@@ -0,0 +1,1436 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE basic_regex_creator.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares template class basic_regex_creator which fills in
+ * the data members of a regex_data object.
+ */
+
+#ifndef BOOST_REGEX_V4_BASIC_REGEX_CREATOR_HPP
+#define BOOST_REGEX_V4_BASIC_REGEX_CREATOR_HPP
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable: 4800)
+#endif
+
+namespace boost{
+
+namespace re_detail{
+
+template <class charT>
+struct digraph : public std::pair<charT, charT>
+{
+ digraph() : std::pair<charT, charT>(0, 0){}
+ digraph(charT c1) : std::pair<charT, charT>(c1, 0){}
+ digraph(charT c1, charT c2) : std::pair<charT, charT>(c1, c2)
+ {}
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+ digraph(const digraph<charT>& d) : std::pair<charT, charT>(d.first, d.second){}
+#endif
+ template <class Seq>
+ digraph(const Seq& s) : std::pair<charT, charT>()
+ {
+ BOOST_ASSERT(s.size() <= 2);
+ BOOST_ASSERT(s.size());
+ this->first = s[0];
+ this->second = (s.size() > 1) ? s[1] : 0;
+ }
+};
+
+template <class charT, class traits>
+class basic_char_set
+{
+public:
+ typedef digraph<charT> digraph_type;
+ typedef typename traits::string_type string_type;
+ typedef typename traits::char_class_type mask_type;
+
+ basic_char_set()
+ {
+ m_negate = false;
+ m_has_digraphs = false;
+ m_classes = 0;
+ m_negated_classes = 0;
+ m_empty = true;
+ }
+
+ void add_single(const digraph_type& s)
+ {
+ m_singles.insert(m_singles.end(), s);
+ if(s.second)
+ m_has_digraphs = true;
+ m_empty = false;
+ }
+ void add_range(const digraph_type& first, const digraph_type& end)
+ {
+ m_ranges.insert(m_ranges.end(), first);
+ m_ranges.insert(m_ranges.end(), end);
+ if(first.second)
+ {
+ m_has_digraphs = true;
+ add_single(first);
+ }
+ if(end.second)
+ {
+ m_has_digraphs = true;
+ add_single(end);
+ }
+ m_empty = false;
+ }
+ void add_class(mask_type m)
+ {
+ m_classes |= m;
+ m_empty = false;
+ }
+ void add_negated_class(mask_type m)
+ {
+ m_negated_classes |= m;
+ m_empty = false;
+ }
+ void add_equivalent(const digraph_type& s)
+ {
+ m_equivalents.insert(m_equivalents.end(), s);
+ if(s.second)
+ {
+ m_has_digraphs = true;
+ add_single(s);
+ }
+ m_empty = false;
+ }
+ void negate()
+ {
+ m_negate = true;
+ //m_empty = false;
+ }
+
+ //
+ // accessor functions:
+ //
+ bool has_digraphs()const
+ {
+ return m_has_digraphs;
+ }
+ bool is_negated()const
+ {
+ return m_negate;
+ }
+ typedef typename std::vector<digraph_type>::const_iterator list_iterator;
+ list_iterator singles_begin()const
+ {
+ return m_singles.begin();
+ }
+ list_iterator singles_end()const
+ {
+ return m_singles.end();
+ }
+ list_iterator ranges_begin()const
+ {
+ return m_ranges.begin();
+ }
+ list_iterator ranges_end()const
+ {
+ return m_ranges.end();
+ }
+ list_iterator equivalents_begin()const
+ {
+ return m_equivalents.begin();
+ }
+ list_iterator equivalents_end()const
+ {
+ return m_equivalents.end();
+ }
+ mask_type classes()const
+ {
+ return m_classes;
+ }
+ mask_type negated_classes()const
+ {
+ return m_negated_classes;
+ }
+ bool empty()const
+ {
+ return m_empty;
+ }
+private:
+ std::vector<digraph_type> m_singles; // a list of single characters to match
+ std::vector<digraph_type> m_ranges; // a list of end points of our ranges
+ bool m_negate; // true if the set is to be negated
+ bool m_has_digraphs; // true if we have digraphs present
+ mask_type m_classes; // character classes to match
+ mask_type m_negated_classes; // negated character classes to match
+ bool m_empty; // whether we've added anything yet
+ std::vector<digraph_type> m_equivalents; // a list of equivalence classes
+};
+
+template <class charT, class traits>
+class basic_regex_creator
+{
+public:
+ basic_regex_creator(regex_data<charT, traits>* data);
+ std::ptrdiff_t getoffset(void* addr)
+ {
+ return getoffset(addr, m_pdata->m_data.data());
+ }
+ std::ptrdiff_t getoffset(const void* addr, const void* base)
+ {
+ return static_cast<const char*>(addr) - static_cast<const char*>(base);
+ }
+ re_syntax_base* getaddress(std::ptrdiff_t off)
+ {
+ return getaddress(off, m_pdata->m_data.data());
+ }
+ re_syntax_base* getaddress(std::ptrdiff_t off, void* base)
+ {
+ return static_cast<re_syntax_base*>(static_cast<void*>(static_cast<char*>(base) + off));
+ }
+ void init(unsigned l_flags)
+ {
+ m_pdata->m_flags = l_flags;
+ m_icase = l_flags & regex_constants::icase;
+ }
+ regbase::flag_type flags()
+ {
+ return m_pdata->m_flags;
+ }
+ void flags(regbase::flag_type f)
+ {
+ m_pdata->m_flags = f;
+ if(m_icase != static_cast<bool>(f & regbase::icase))
+ {
+ m_icase = static_cast<bool>(f & regbase::icase);
+ }
+ }
+ re_syntax_base* append_state(syntax_element_type t, std::size_t s = sizeof(re_syntax_base));
+ re_syntax_base* insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s = sizeof(re_syntax_base));
+ re_literal* append_literal(charT c);
+ re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set);
+ re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set, mpl::false_*);
+ re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set, mpl::true_*);
+ void finalize(const charT* p1, const charT* p2);
+protected:
+ regex_data<charT, traits>* m_pdata; // pointer to the basic_regex_data struct we are filling in
+ const ::boost::regex_traits_wrapper<traits>&
+ m_traits; // convenience reference to traits class
+ re_syntax_base* m_last_state; // the last state we added
+ bool m_icase; // true for case insensitive matches
+ unsigned m_repeater_id; // the state_id of the next repeater
+ bool m_has_backrefs; // true if there are actually any backrefs
+ unsigned m_backrefs; // bitmask of permitted backrefs
+ boost::uintmax_t m_bad_repeats; // bitmask of repeats we can't deduce a startmap for;
+ bool m_has_recursions; // set when we have recursive expresisons to fixup
+ typename traits::char_class_type m_word_mask; // mask used to determine if a character is a word character
+ typename traits::char_class_type m_mask_space; // mask used to determine if a character is a word character
+ typename traits::char_class_type m_lower_mask; // mask used to determine if a character is a lowercase character
+ typename traits::char_class_type m_upper_mask; // mask used to determine if a character is an uppercase character
+ typename traits::char_class_type m_alpha_mask; // mask used to determine if a character is an alphabetic character
+private:
+ basic_regex_creator& operator=(const basic_regex_creator&);
+ basic_regex_creator(const basic_regex_creator&);
+
+ void fixup_pointers(re_syntax_base* state);
+ void fixup_recursions(re_syntax_base* state);
+ void create_startmaps(re_syntax_base* state);
+ int calculate_backstep(re_syntax_base* state);
+ void create_startmap(re_syntax_base* state, unsigned char* l_map, unsigned int* pnull, unsigned char mask);
+ unsigned get_restart_type(re_syntax_base* state);
+ void set_all_masks(unsigned char* bits, unsigned char);
+ bool is_bad_repeat(re_syntax_base* pt);
+ void set_bad_repeat(re_syntax_base* pt);
+ syntax_element_type get_repeat_type(re_syntax_base* state);
+ void probe_leading_repeat(re_syntax_base* state);
+};
+
+template <class charT, class traits>
+basic_regex_creator<charT, traits>::basic_regex_creator(regex_data<charT, traits>* data)
+ : m_pdata(data), m_traits(*(data->m_ptraits)), m_last_state(0), m_repeater_id(0), m_has_backrefs(false), m_backrefs(0), m_has_recursions(false)
+{
+ m_pdata->m_data.clear();
+ m_pdata->m_status = ::boost::regex_constants::error_ok;
+ static const charT w = 'w';
+ static const charT s = 's';
+ static const charT l[5] = { 'l', 'o', 'w', 'e', 'r', };
+ static const charT u[5] = { 'u', 'p', 'p', 'e', 'r', };
+ static const charT a[5] = { 'a', 'l', 'p', 'h', 'a', };
+ m_word_mask = m_traits.lookup_classname(&w, &w +1);
+ m_mask_space = m_traits.lookup_classname(&s, &s +1);
+ m_lower_mask = m_traits.lookup_classname(l, l + 5);
+ m_upper_mask = m_traits.lookup_classname(u, u + 5);
+ m_alpha_mask = m_traits.lookup_classname(a, a + 5);
+ m_pdata->m_word_mask = m_word_mask;
+ BOOST_ASSERT(m_word_mask != 0);
+ BOOST_ASSERT(m_mask_space != 0);
+ BOOST_ASSERT(m_lower_mask != 0);
+ BOOST_ASSERT(m_upper_mask != 0);
+ BOOST_ASSERT(m_alpha_mask != 0);
+}
+
+template <class charT, class traits>
+re_syntax_base* basic_regex_creator<charT, traits>::append_state(syntax_element_type t, std::size_t s)
+{
+ // if the state is a backref then make a note of it:
+ if(t == syntax_element_backref)
+ this->m_has_backrefs = true;
+ // append a new state, start by aligning our last one:
+ m_pdata->m_data.align();
+ // set the offset to the next state in our last one:
+ if(m_last_state)
+ m_last_state->next.i = m_pdata->m_data.size() - getoffset(m_last_state);
+ // now actually extent our data:
+ m_last_state = static_cast<re_syntax_base*>(m_pdata->m_data.extend(s));
+ // fill in boilerplate options in the new state:
+ m_last_state->next.i = 0;
+ m_last_state->type = t;
+ return m_last_state;
+}
+
+template <class charT, class traits>
+re_syntax_base* basic_regex_creator<charT, traits>::insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s)
+{
+ // append a new state, start by aligning our last one:
+ m_pdata->m_data.align();
+ // set the offset to the next state in our last one:
+ if(m_last_state)
+ m_last_state->next.i = m_pdata->m_data.size() - getoffset(m_last_state);
+ // remember the last state position:
+ std::ptrdiff_t off = getoffset(m_last_state) + s;
+ // now actually insert our data:
+ re_syntax_base* new_state = static_cast<re_syntax_base*>(m_pdata->m_data.insert(pos, s));
+ // fill in boilerplate options in the new state:
+ new_state->next.i = s;
+ new_state->type = t;
+ m_last_state = getaddress(off);
+ return new_state;
+}
+
+template <class charT, class traits>
+re_literal* basic_regex_creator<charT, traits>::append_literal(charT c)
+{
+ re_literal* result;
+ // start by seeing if we have an existing re_literal we can extend:
+ if((0 == m_last_state) || (m_last_state->type != syntax_element_literal))
+ {
+ // no existing re_literal, create a new one:
+ result = static_cast<re_literal*>(append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));
+ result->length = 1;
+ *static_cast<charT*>(static_cast<void*>(result+1)) = m_traits.translate(c, m_icase);
+ }
+ else
+ {
+ // we have an existing re_literal, extend it:
+ std::ptrdiff_t off = getoffset(m_last_state);
+ m_pdata->m_data.extend(sizeof(charT));
+ m_last_state = result = static_cast<re_literal*>(getaddress(off));
+ charT* characters = static_cast<charT*>(static_cast<void*>(result+1));
+ characters[result->length] = m_traits.translate(c, m_icase);
+ ++(result->length);
+ }
+ return result;
+}
+
+template <class charT, class traits>
+inline re_syntax_base* basic_regex_creator<charT, traits>::append_set(
+ const basic_char_set<charT, traits>& char_set)
+{
+ typedef mpl::bool_< (sizeof(charT) == 1) > truth_type;
+ return char_set.has_digraphs()
+ ? append_set(char_set, static_cast<mpl::false_*>(0))
+ : append_set(char_set, static_cast<truth_type*>(0));
+}
+
+template <class charT, class traits>
+re_syntax_base* basic_regex_creator<charT, traits>::append_set(
+ const basic_char_set<charT, traits>& char_set, mpl::false_*)
+{
+ typedef typename traits::string_type string_type;
+ typedef typename basic_char_set<charT, traits>::list_iterator item_iterator;
+ typedef typename traits::char_class_type mask_type;
+
+ re_set_long<mask_type>* result = static_cast<re_set_long<mask_type>*>(append_state(syntax_element_long_set, sizeof(re_set_long<mask_type>)));
+ //
+ // fill in the basics:
+ //
+ result->csingles = static_cast<unsigned int>(::boost::re_detail::distance(char_set.singles_begin(), char_set.singles_end()));
+ result->cranges = static_cast<unsigned int>(::boost::re_detail::distance(char_set.ranges_begin(), char_set.ranges_end())) / 2;
+ result->cequivalents = static_cast<unsigned int>(::boost::re_detail::distance(char_set.equivalents_begin(), char_set.equivalents_end()));
+ result->cclasses = char_set.classes();
+ result->cnclasses = char_set.negated_classes();
+ if(flags() & regbase::icase)
+ {
+ // adjust classes as needed:
+ if(((result->cclasses & m_lower_mask) == m_lower_mask) || ((result->cclasses & m_upper_mask) == m_upper_mask))
+ result->cclasses |= m_alpha_mask;
+ if(((result->cnclasses & m_lower_mask) == m_lower_mask) || ((result->cnclasses & m_upper_mask) == m_upper_mask))
+ result->cnclasses |= m_alpha_mask;
+ }
+
+ result->isnot = char_set.is_negated();
+ result->singleton = !char_set.has_digraphs();
+ //
+ // remember where the state is for later:
+ //
+ std::ptrdiff_t offset = getoffset(result);
+ //
+ // now extend with all the singles:
+ //
+ item_iterator first, last;
+ first = char_set.singles_begin();
+ last = char_set.singles_end();
+ while(first != last)
+ {
+ charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (first->second ? 3 : 2)));
+ p[0] = m_traits.translate(first->first, m_icase);
+ if(first->second)
+ {
+ p[1] = m_traits.translate(first->second, m_icase);
+ p[2] = 0;
+ }
+ else
+ p[1] = 0;
+ ++first;
+ }
+ //
+ // now extend with all the ranges:
+ //
+ first = char_set.ranges_begin();
+ last = char_set.ranges_end();
+ while(first != last)
+ {
+ // first grab the endpoints of the range:
+ digraph<charT> c1 = *first;
+ c1.first = this->m_traits.translate(c1.first, this->m_icase);
+ c1.second = this->m_traits.translate(c1.second, this->m_icase);
+ ++first;
+ digraph<charT> c2 = *first;
+ c2.first = this->m_traits.translate(c2.first, this->m_icase);
+ c2.second = this->m_traits.translate(c2.second, this->m_icase);
+ ++first;
+ string_type s1, s2;
+ // different actions now depending upon whether collation is turned on:
+ if(flags() & regex_constants::collate)
+ {
+ // we need to transform our range into sort keys:
+#if BOOST_WORKAROUND(__GNUC__, < 3)
+ string_type in(3, charT(0));
+ in[0] = c1.first;
+ in[1] = c1.second;
+ s1 = this->m_traits.transform(in.c_str(), (in[1] ? in.c_str()+2 : in.c_str()+1));
+ in[0] = c2.first;
+ in[1] = c2.second;
+ s2 = this->m_traits.transform(in.c_str(), (in[1] ? in.c_str()+2 : in.c_str()+1));
+#else
+ charT a1[3] = { c1.first, c1.second, charT(0), };
+ charT a2[3] = { c2.first, c2.second, charT(0), };
+ s1 = this->m_traits.transform(a1, (a1[1] ? a1+2 : a1+1));
+ s2 = this->m_traits.transform(a2, (a2[1] ? a2+2 : a2+1));
+#endif
+ if(s1.size() == 0)
+ s1 = string_type(1, charT(0));
+ if(s2.size() == 0)
+ s2 = string_type(1, charT(0));
+ }
+ else
+ {
+ if(c1.second)
+ {
+ s1.insert(s1.end(), c1.first);
+ s1.insert(s1.end(), c1.second);
+ }
+ else
+ s1 = string_type(1, c1.first);
+ if(c2.second)
+ {
+ s2.insert(s2.end(), c2.first);
+ s2.insert(s2.end(), c2.second);
+ }
+ else
+ s2.insert(s2.end(), c2.first);
+ }
+ if(s1 > s2)
+ {
+ // Oops error:
+ return 0;
+ }
+ charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (s1.size() + s2.size() + 2) ) );
+ re_detail::copy(s1.begin(), s1.end(), p);
+ p[s1.size()] = charT(0);
+ p += s1.size() + 1;
+ re_detail::copy(s2.begin(), s2.end(), p);
+ p[s2.size()] = charT(0);
+ }
+ //
+ // now process the equivalence classes:
+ //
+ first = char_set.equivalents_begin();
+ last = char_set.equivalents_end();
+ while(first != last)
+ {
+ string_type s;
+ if(first->second)
+ {
+#if BOOST_WORKAROUND(__GNUC__, < 3)
+ string_type in(3, charT(0));
+ in[0] = first->first;
+ in[1] = first->second;
+ s = m_traits.transform_primary(in.c_str(), in.c_str()+2);
+#else
+ charT cs[3] = { first->first, first->second, charT(0), };
+ s = m_traits.transform_primary(cs, cs+2);
+#endif
+ }
+ else
+ s = m_traits.transform_primary(&first->first, &first->first+1);
+ if(s.empty())
+ return 0; // invalid or unsupported equivalence class
+ charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (s.size()+1) ) );
+ re_detail::copy(s.begin(), s.end(), p);
+ p[s.size()] = charT(0);
+ ++first;
+ }
+ //
+ // finally reset the address of our last state:
+ //
+ m_last_state = result = static_cast<re_set_long<mask_type>*>(getaddress(offset));
+ return result;
+}
+
+namespace{
+
+template<class T>
+inline bool char_less(T t1, T t2)
+{
+ return t1 < t2;
+}
+template<>
+inline bool char_less<char>(char t1, char t2)
+{
+ return static_cast<unsigned char>(t1) < static_cast<unsigned char>(t2);
+}
+template<>
+inline bool char_less<signed char>(signed char t1, signed char t2)
+{
+ return static_cast<unsigned char>(t1) < static_cast<unsigned char>(t2);
+}
+}
+
+template <class charT, class traits>
+re_syntax_base* basic_regex_creator<charT, traits>::append_set(
+ const basic_char_set<charT, traits>& char_set, mpl::true_*)
+{
+ typedef typename traits::string_type string_type;
+ typedef typename basic_char_set<charT, traits>::list_iterator item_iterator;
+
+ re_set* result = static_cast<re_set*>(append_state(syntax_element_set, sizeof(re_set)));
+ bool negate = char_set.is_negated();
+ std::memset(result->_map, 0, sizeof(result->_map));
+ //
+ // handle singles first:
+ //
+ item_iterator first, last;
+ first = char_set.singles_begin();
+ last = char_set.singles_end();
+ while(first != last)
+ {
+ for(unsigned int i = 0; i < (1 << CHAR_BIT); ++i)
+ {
+ if(this->m_traits.translate(static_cast<charT>(i), this->m_icase)
+ == this->m_traits.translate(first->first, this->m_icase))
+ result->_map[i] = true;
+ }
+ ++first;
+ }
+ //
+ // OK now handle ranges:
+ //
+ first = char_set.ranges_begin();
+ last = char_set.ranges_end();
+ while(first != last)
+ {
+ // first grab the endpoints of the range:
+ charT c1 = this->m_traits.translate(first->first, this->m_icase);
+ ++first;
+ charT c2 = this->m_traits.translate(first->first, this->m_icase);
+ ++first;
+ // different actions now depending upon whether collation is turned on:
+ if(flags() & regex_constants::collate)
+ {
+ // we need to transform our range into sort keys:
+ charT c3[2] = { c1, charT(0), };
+ string_type s1 = this->m_traits.transform(c3, c3+1);
+ c3[0] = c2;
+ string_type s2 = this->m_traits.transform(c3, c3+1);
+ if(s1 > s2)
+ {
+ // Oops error:
+ return 0;
+ }
+ BOOST_ASSERT(c3[1] == charT(0));
+ for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
+ {
+ c3[0] = static_cast<charT>(i);
+ string_type s3 = this->m_traits.transform(c3, c3 +1);
+ if((s1 <= s3) && (s3 <= s2))
+ result->_map[i] = true;
+ }
+ }
+ else
+ {
+ if(char_less<charT>(c2, c1))
+ {
+ // Oops error:
+ return 0;
+ }
+ // everything in range matches:
+ std::memset(result->_map + static_cast<unsigned char>(c1), true, 1 + static_cast<unsigned char>(c2) - static_cast<unsigned char>(c1));
+ }
+ }
+ //
+ // and now the classes:
+ //
+ typedef typename traits::char_class_type mask_type;
+ mask_type m = char_set.classes();
+ if(flags() & regbase::icase)
+ {
+ // adjust m as needed:
+ if(((m & m_lower_mask) == m_lower_mask) || ((m & m_upper_mask) == m_upper_mask))
+ m |= m_alpha_mask;
+ }
+ if(m != 0)
+ {
+ for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
+ {
+ if(this->m_traits.isctype(static_cast<charT>(i), m))
+ result->_map[i] = true;
+ }
+ }
+ //
+ // and now the negated classes:
+ //
+ m = char_set.negated_classes();
+ if(flags() & regbase::icase)
+ {
+ // adjust m as needed:
+ if(((m & m_lower_mask) == m_lower_mask) || ((m & m_upper_mask) == m_upper_mask))
+ m |= m_alpha_mask;
+ }
+ if(m != 0)
+ {
+ for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
+ {
+ if(0 == this->m_traits.isctype(static_cast<charT>(i), m))
+ result->_map[i] = true;
+ }
+ }
+ //
+ // now process the equivalence classes:
+ //
+ first = char_set.equivalents_begin();
+ last = char_set.equivalents_end();
+ while(first != last)
+ {
+ string_type s;
+ BOOST_ASSERT(static_cast<charT>(0) == first->second);
+ s = m_traits.transform_primary(&first->first, &first->first+1);
+ if(s.empty())
+ return 0; // invalid or unsupported equivalence class
+ for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
+ {
+ charT c[2] = { (static_cast<charT>(i)), charT(0), };
+ string_type s2 = this->m_traits.transform_primary(c, c+1);
+ if(s == s2)
+ result->_map[i] = true;
+ }
+ ++first;
+ }
+ if(negate)
+ {
+ for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
+ {
+ result->_map[i] = !(result->_map[i]);
+ }
+ }
+ return result;
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::finalize(const charT* p1, const charT* p2)
+{
+ // we've added all the states we need, now finish things off.
+ // start by adding a terminating state:
+ append_state(syntax_element_match);
+ // extend storage to store original expression:
+ std::ptrdiff_t len = p2 - p1;
+ m_pdata->m_expression_len = len;
+ charT* ps = static_cast<charT*>(m_pdata->m_data.extend(sizeof(charT) * (1 + (p2 - p1))));
+ m_pdata->m_expression = ps;
+ re_detail::copy(p1, p2, ps);
+ ps[p2 - p1] = 0;
+ // fill in our other data...
+ // successful parsing implies a zero status:
+ m_pdata->m_status = 0;
+ // get the first state of the machine:
+ m_pdata->m_first_state = static_cast<re_syntax_base*>(m_pdata->m_data.data());
+ // fixup pointers in the machine:
+ fixup_pointers(m_pdata->m_first_state);
+ if(m_has_recursions)
+ {
+ m_pdata->m_has_recursions = true;
+ fixup_recursions(m_pdata->m_first_state);
+ }
+ else
+ m_pdata->m_has_recursions = false;
+ // create nested startmaps:
+ create_startmaps(m_pdata->m_first_state);
+ // create main startmap:
+ std::memset(m_pdata->m_startmap, 0, sizeof(m_pdata->m_startmap));
+ m_pdata->m_can_be_null = 0;
+
+ m_bad_repeats = 0;
+ create_startmap(m_pdata->m_first_state, m_pdata->m_startmap, &(m_pdata->m_can_be_null), mask_all);
+ // get the restart type:
+ m_pdata->m_restart_type = get_restart_type(m_pdata->m_first_state);
+ // optimise a leading repeat if there is one:
+ probe_leading_repeat(m_pdata->m_first_state);
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::fixup_pointers(re_syntax_base* state)
+{
+ while(state)
+ {
+ switch(state->type)
+ {
+ case syntax_element_recurse:
+ m_has_recursions = true;
+ if(state->next.i)
+ state->next.p = getaddress(state->next.i, state);
+ else
+ state->next.p = 0;
+ break;
+ case syntax_element_rep:
+ case syntax_element_dot_rep:
+ case syntax_element_char_rep:
+ case syntax_element_short_set_rep:
+ case syntax_element_long_set_rep:
+ // set the state_id of this repeat:
+ static_cast<re_repeat*>(state)->state_id = m_repeater_id++;
+ // fall through:
+ case syntax_element_alt:
+ std::memset(static_cast<re_alt*>(state)->_map, 0, sizeof(static_cast<re_alt*>(state)->_map));
+ static_cast<re_alt*>(state)->can_be_null = 0;
+ // fall through:
+ case syntax_element_jump:
+ static_cast<re_jump*>(state)->alt.p = getaddress(static_cast<re_jump*>(state)->alt.i, state);
+ // fall through again:
+ default:
+ if(state->next.i)
+ state->next.p = getaddress(state->next.i, state);
+ else
+ state->next.p = 0;
+ }
+ state = state->next.p;
+ }
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::fixup_recursions(re_syntax_base* state)
+{
+ re_syntax_base* base = state;
+ while(state)
+ {
+ switch(state->type)
+ {
+ case syntax_element_assert_backref:
+ {
+ // just check that the index is valid:
+ int id = static_cast<const re_brace*>(state)->index;
+ if(id < 0)
+ {
+ id = -id-1;
+ if(id >= 10000)
+ {
+ id = m_pdata->get_id(id);
+ if(id <= 0)
+ {
+ // check of sub-expression that doesn't exist:
+ if(0 == this->m_pdata->m_status) // update the error code if not already set
+ this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;
+ //
+ // clear the expression, we should be empty:
+ //
+ this->m_pdata->m_expression = 0;
+ this->m_pdata->m_expression_len = 0;
+ //
+ // and throw if required:
+ //
+ if(0 == (this->flags() & regex_constants::no_except))
+ {
+ std::string message = this->m_pdata->m_ptraits->error_string(boost::regex_constants::error_bad_pattern);
+ boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);
+ e.raise();
+ }
+ }
+ }
+ }
+ }
+ break;
+ case syntax_element_recurse:
+ {
+ bool ok = false;
+ re_syntax_base* p = base;
+ int id = static_cast<re_jump*>(state)->alt.i;
+ if(id > 10000)
+ id = m_pdata->get_id(id);
+ while(p)
+ {
+ if((p->type == syntax_element_startmark) && (static_cast<re_brace*>(p)->index == id))
+ {
+ static_cast<re_jump*>(state)->alt.p = p;
+ ok = true;
+ break;
+ }
+ p = p->next.p;
+ }
+ if(!ok)
+ {
+ // recursion to sub-expression that doesn't exist:
+ if(0 == this->m_pdata->m_status) // update the error code if not already set
+ this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;
+ //
+ // clear the expression, we should be empty:
+ //
+ this->m_pdata->m_expression = 0;
+ this->m_pdata->m_expression_len = 0;
+ //
+ // and throw if required:
+ //
+ if(0 == (this->flags() & regex_constants::no_except))
+ {
+ std::string message = this->m_pdata->m_ptraits->error_string(boost::regex_constants::error_bad_pattern);
+ boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);
+ e.raise();
+ }
+ }
+ }
+ default:
+ break;
+ }
+ state = state->next.p;
+ }
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::create_startmaps(re_syntax_base* state)
+{
+ // non-recursive implementation:
+ // create the last map in the machine first, so that earlier maps
+ // can make use of the result...
+ //
+ // This was originally a recursive implementation, but that caused stack
+ // overflows with complex expressions on small stacks (think COM+).
+
+ // start by saving the case setting:
+ bool l_icase = m_icase;
+ std::vector<std::pair<bool, re_syntax_base*> > v;
+
+ while(state)
+ {
+ switch(state->type)
+ {
+ case syntax_element_toggle_case:
+ // we need to track case changes here:
+ m_icase = static_cast<re_case*>(state)->icase;
+ state = state->next.p;
+ continue;
+ case syntax_element_alt:
+ case syntax_element_rep:
+ case syntax_element_dot_rep:
+ case syntax_element_char_rep:
+ case syntax_element_short_set_rep:
+ case syntax_element_long_set_rep:
+ // just push the state onto our stack for now:
+ v.push_back(std::pair<bool, re_syntax_base*>(m_icase, state));
+ state = state->next.p;
+ break;
+ case syntax_element_backstep:
+ // we need to calculate how big the backstep is:
+ static_cast<re_brace*>(state)->index
+ = this->calculate_backstep(state->next.p);
+ if(static_cast<re_brace*>(state)->index < 0)
+ {
+ // Oops error:
+ if(0 == this->m_pdata->m_status) // update the error code if not already set
+ this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;
+ //
+ // clear the expression, we should be empty:
+ //
+ this->m_pdata->m_expression = 0;
+ this->m_pdata->m_expression_len = 0;
+ //
+ // and throw if required:
+ //
+ if(0 == (this->flags() & regex_constants::no_except))
+ {
+ std::string message = this->m_pdata->m_ptraits->error_string(boost::regex_constants::error_bad_pattern);
+ boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);
+ e.raise();
+ }
+ }
+ // fall through:
+ default:
+ state = state->next.p;
+ }
+ }
+ // now work through our list, building all the maps as we go:
+ while(v.size())
+ {
+ const std::pair<bool, re_syntax_base*>& p = v.back();
+ m_icase = p.first;
+ state = p.second;
+ v.pop_back();
+
+ // Build maps:
+ m_bad_repeats = 0;
+ create_startmap(state->next.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_take);
+ m_bad_repeats = 0;
+ create_startmap(static_cast<re_alt*>(state)->alt.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_skip);
+ // adjust the type of the state to allow for faster matching:
+ state->type = this->get_repeat_type(state);
+ }
+ // restore case sensitivity:
+ m_icase = l_icase;
+}
+
+template <class charT, class traits>
+int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state)
+{
+ typedef typename traits::char_class_type mask_type;
+ int result = 0;
+ while(state)
+ {
+ switch(state->type)
+ {
+ case syntax_element_startmark:
+ if((static_cast<re_brace*>(state)->index == -1)
+ || (static_cast<re_brace*>(state)->index == -2))
+ {
+ state = static_cast<re_jump*>(state->next.p)->alt.p->next.p;
+ continue;
+ }
+ else if(static_cast<re_brace*>(state)->index == -3)
+ {
+ state = state->next.p->next.p;
+ continue;
+ }
+ break;
+ case syntax_element_endmark:
+ if((static_cast<re_brace*>(state)->index == -1)
+ || (static_cast<re_brace*>(state)->index == -2))
+ return result;
+ break;
+ case syntax_element_literal:
+ result += static_cast<re_literal*>(state)->length;
+ break;
+ case syntax_element_wild:
+ case syntax_element_set:
+ result += 1;
+ break;
+ case syntax_element_dot_rep:
+ case syntax_element_char_rep:
+ case syntax_element_short_set_rep:
+ case syntax_element_backref:
+ case syntax_element_rep:
+ case syntax_element_combining:
+ case syntax_element_long_set_rep:
+ case syntax_element_backstep:
+ {
+ re_repeat* rep = static_cast<re_repeat *>(state);
+ // adjust the type of the state to allow for faster matching:
+ state->type = this->get_repeat_type(state);
+ if((state->type == syntax_element_dot_rep)
+ || (state->type == syntax_element_char_rep)
+ || (state->type == syntax_element_short_set_rep))
+ {
+ if(rep->max != rep->min)
+ return -1;
+ result += static_cast<int>(rep->min);
+ state = rep->alt.p;
+ continue;
+ }
+ else if((state->type == syntax_element_long_set_rep))
+ {
+ BOOST_ASSERT(rep->next.p->type == syntax_element_long_set);
+ if(static_cast<re_set_long<mask_type>*>(rep->next.p)->singleton == 0)
+ return -1;
+ if(rep->max != rep->min)
+ return -1;
+ result += static_cast<int>(rep->min);
+ state = rep->alt.p;
+ continue;
+ }
+ }
+ return -1;
+ case syntax_element_long_set:
+ if(static_cast<re_set_long<mask_type>*>(state)->singleton == 0)
+ return -1;
+ result += 1;
+ break;
+ case syntax_element_jump:
+ state = static_cast<re_jump*>(state)->alt.p;
+ continue;
+ default:
+ break;
+ }
+ state = state->next.p;
+ }
+ return -1;
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::create_startmap(re_syntax_base* state, unsigned char* l_map, unsigned int* pnull, unsigned char mask)
+{
+ int not_last_jump = 1;
+
+ // track case sensitivity:
+ bool l_icase = m_icase;
+
+ while(state)
+ {
+ switch(state->type)
+ {
+ case syntax_element_toggle_case:
+ l_icase = static_cast<re_case*>(state)->icase;
+ state = state->next.p;
+ break;
+ case syntax_element_literal:
+ {
+ // don't set anything in *pnull, set each element in l_map
+ // that could match the first character in the literal:
+ if(l_map)
+ {
+ l_map[0] |= mask_init;
+ charT first_char = *static_cast<charT*>(static_cast<void*>(static_cast<re_literal*>(state) + 1));
+ for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
+ {
+ if(m_traits.translate(static_cast<charT>(i), l_icase) == first_char)
+ l_map[i] |= mask;
+ }
+ }
+ return;
+ }
+ case syntax_element_end_line:
+ {
+ // next character must be a line separator (if there is one):
+ if(l_map)
+ {
+ l_map[0] |= mask_init;
+ l_map['\n'] |= mask;
+ l_map['\r'] |= mask;
+ l_map['\f'] |= mask;
+ l_map[0x85] |= mask;
+ }
+ // now figure out if we can match a NULL string at this point:
+ if(pnull)
+ create_startmap(state->next.p, 0, pnull, mask);
+ return;
+ }
+ case syntax_element_recurse:
+ case syntax_element_backref:
+ // can be null, and any character can match:
+ if(pnull)
+ *pnull |= mask;
+ // fall through:
+ case syntax_element_wild:
+ {
+ // can't be null, any character can match:
+ set_all_masks(l_map, mask);
+ return;
+ }
+ case syntax_element_match:
+ {
+ // must be null, any character can match:
+ set_all_masks(l_map, mask);
+ if(pnull)
+ *pnull |= mask;
+ return;
+ }
+ case syntax_element_word_start:
+ {
+ // recurse, then AND with all the word characters:
+ create_startmap(state->next.p, l_map, pnull, mask);
+ if(l_map)
+ {
+ l_map[0] |= mask_init;
+ for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
+ {
+ if(!m_traits.isctype(static_cast<charT>(i), m_word_mask))
+ l_map[i] &= static_cast<unsigned char>(~mask);
+ }
+ }
+ return;
+ }
+ case syntax_element_word_end:
+ {
+ // recurse, then AND with all the word characters:
+ create_startmap(state->next.p, l_map, pnull, mask);
+ if(l_map)
+ {
+ l_map[0] |= mask_init;
+ for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
+ {
+ if(m_traits.isctype(static_cast<charT>(i), m_word_mask))
+ l_map[i] &= static_cast<unsigned char>(~mask);
+ }
+ }
+ return;
+ }
+ case syntax_element_buffer_end:
+ {
+ // we *must be null* :
+ if(pnull)
+ *pnull |= mask;
+ return;
+ }
+ case syntax_element_long_set:
+ if(l_map)
+ {
+ typedef typename traits::char_class_type mask_type;
+ if(static_cast<re_set_long<mask_type>*>(state)->singleton)
+ {
+ l_map[0] |= mask_init;
+ for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
+ {
+ charT c = static_cast<charT>(i);
+ if(&c != re_is_set_member(&c, &c + 1, static_cast<re_set_long<mask_type>*>(state), *m_pdata, m_icase))
+ l_map[i] |= mask;
+ }
+ }
+ else
+ set_all_masks(l_map, mask);
+ }
+ return;
+ case syntax_element_set:
+ if(l_map)
+ {
+ l_map[0] |= mask_init;
+ for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
+ {
+ if(static_cast<re_set*>(state)->_map[
+ static_cast<unsigned char>(m_traits.translate(static_cast<charT>(i), l_icase))])
+ l_map[i] |= mask;
+ }
+ }
+ return;
+ case syntax_element_jump:
+ // take the jump:
+ state = static_cast<re_alt*>(state)->alt.p;
+ not_last_jump = -1;
+ break;
+ case syntax_element_alt:
+ case syntax_element_rep:
+ case syntax_element_dot_rep:
+ case syntax_element_char_rep:
+ case syntax_element_short_set_rep:
+ case syntax_element_long_set_rep:
+ {
+ re_alt* rep = static_cast<re_alt*>(state);
+ if(rep->_map[0] & mask_init)
+ {
+ if(l_map)
+ {
+ // copy previous results:
+ l_map[0] |= mask_init;
+ for(unsigned int i = 0; i <= UCHAR_MAX; ++i)
+ {
+ if(rep->_map[i] & mask_any)
+ l_map[i] |= mask;
+ }
+ }
+ if(pnull)
+ {
+ if(rep->can_be_null & mask_any)
+ *pnull |= mask;
+ }
+ }
+ else
+ {
+ // we haven't created a startmap for this alternative yet
+ // so take the union of the two options:
+ if(is_bad_repeat(state))
+ {
+ set_all_masks(l_map, mask);
+ if(pnull)
+ *pnull |= mask;
+ return;
+ }
+ set_bad_repeat(state);
+ create_startmap(state->next.p, l_map, pnull, mask);
+ if((state->type == syntax_element_alt)
+ || (static_cast<re_repeat*>(state)->min == 0)
+ || (not_last_jump == 0))
+ create_startmap(rep->alt.p, l_map, pnull, mask);
+ }
+ }
+ return;
+ case syntax_element_soft_buffer_end:
+ // match newline or null:
+ if(l_map)
+ {
+ l_map[0] |= mask_init;
+ l_map['\n'] |= mask;
+ l_map['\r'] |= mask;
+ }
+ if(pnull)
+ *pnull |= mask;
+ return;
+ case syntax_element_endmark:
+ // need to handle independent subs as a special case:
+ if(static_cast<re_brace*>(state)->index < 0)
+ {
+ // can be null, any character can match:
+ set_all_masks(l_map, mask);
+ if(pnull)
+ *pnull |= mask;
+ return;
+ }
+ else
+ {
+ state = state->next.p;
+ break;
+ }
+
+ case syntax_element_startmark:
+ // need to handle independent subs as a special case:
+ if(static_cast<re_brace*>(state)->index == -3)
+ {
+ state = state->next.p->next.p;
+ break;
+ }
+ // otherwise fall through:
+ default:
+ state = state->next.p;
+ }
+ ++not_last_jump;
+ }
+}
+
+template <class charT, class traits>
+unsigned basic_regex_creator<charT, traits>::get_restart_type(re_syntax_base* state)
+{
+ //
+ // find out how the machine starts, so we can optimise the search:
+ //
+ while(state)
+ {
+ switch(state->type)
+ {
+ case syntax_element_startmark:
+ case syntax_element_endmark:
+ state = state->next.p;
+ continue;
+ case syntax_element_start_line:
+ return regbase::restart_line;
+ case syntax_element_word_start:
+ return regbase::restart_word;
+ case syntax_element_buffer_start:
+ return regbase::restart_buf;
+ case syntax_element_restart_continue:
+ return regbase::restart_continue;
+ default:
+ state = 0;
+ continue;
+ }
+ }
+ return regbase::restart_any;
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::set_all_masks(unsigned char* bits, unsigned char mask)
+{
+ //
+ // set mask in all of bits elements,
+ // if bits[0] has mask_init not set then we can
+ // optimise this to a call to memset:
+ //
+ if(bits)
+ {
+ if(bits[0] == 0)
+ (std::memset)(bits, mask, 1u << CHAR_BIT);
+ else
+ {
+ for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
+ bits[i] |= mask;
+ }
+ bits[0] |= mask_init;
+ }
+}
+
+template <class charT, class traits>
+bool basic_regex_creator<charT, traits>::is_bad_repeat(re_syntax_base* pt)
+{
+ switch(pt->type)
+ {
+ case syntax_element_rep:
+ case syntax_element_dot_rep:
+ case syntax_element_char_rep:
+ case syntax_element_short_set_rep:
+ case syntax_element_long_set_rep:
+ {
+ unsigned state_id = static_cast<re_repeat*>(pt)->state_id;
+ if(state_id > sizeof(m_bad_repeats) * CHAR_BIT)
+ return true; // run out of bits, assume we can't traverse this one.
+ static const boost::uintmax_t one = 1uL;
+ return m_bad_repeats & (one << state_id);
+ }
+ default:
+ return false;
+ }
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::set_bad_repeat(re_syntax_base* pt)
+{
+ switch(pt->type)
+ {
+ case syntax_element_rep:
+ case syntax_element_dot_rep:
+ case syntax_element_char_rep:
+ case syntax_element_short_set_rep:
+ case syntax_element_long_set_rep:
+ {
+ unsigned state_id = static_cast<re_repeat*>(pt)->state_id;
+ static const boost::uintmax_t one = 1uL;
+ if(state_id <= sizeof(m_bad_repeats) * CHAR_BIT)
+ m_bad_repeats |= (one << state_id);
+ }
+ default:
+ break;
+ }
+}
+
+template <class charT, class traits>
+syntax_element_type basic_regex_creator<charT, traits>::get_repeat_type(re_syntax_base* state)
+{
+ typedef typename traits::char_class_type mask_type;
+ if(state->type == syntax_element_rep)
+ {
+ // check to see if we are repeating a single state:
+ if(state->next.p->next.p->next.p == static_cast<re_alt*>(state)->alt.p)
+ {
+ switch(state->next.p->type)
+ {
+ case re_detail::syntax_element_wild:
+ return re_detail::syntax_element_dot_rep;
+ case re_detail::syntax_element_literal:
+ return re_detail::syntax_element_char_rep;
+ case re_detail::syntax_element_set:
+ return re_detail::syntax_element_short_set_rep;
+ case re_detail::syntax_element_long_set:
+ if(static_cast<re_detail::re_set_long<mask_type>*>(state->next.p)->singleton)
+ return re_detail::syntax_element_long_set_rep;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return state->type;
+}
+
+template <class charT, class traits>
+void basic_regex_creator<charT, traits>::probe_leading_repeat(re_syntax_base* state)
+{
+ // enumerate our states, and see if we have a leading repeat
+ // for which failed search restarts can be optimised;
+ do
+ {
+ switch(state->type)
+ {
+ case syntax_element_startmark:
+ if(static_cast<re_brace*>(state)->index >= 0)
+ {
+ state = state->next.p;
+ continue;
+ }
+ if((static_cast<re_brace*>(state)->index == -1)
+ || (static_cast<re_brace*>(state)->index == -2))
+ {
+ // skip past the zero width assertion:
+ state = static_cast<const re_jump*>(state->next.p)->alt.p->next.p;
+ continue;
+ }
+ if(static_cast<re_brace*>(state)->index == -3)
+ {
+ // Have to skip the leading jump state:
+ state = state->next.p->next.p;
+ continue;
+ }
+ return;
+ case syntax_element_endmark:
+ case syntax_element_start_line:
+ case syntax_element_end_line:
+ case syntax_element_word_boundary:
+ case syntax_element_within_word:
+ case syntax_element_word_start:
+ case syntax_element_word_end:
+ case syntax_element_buffer_start:
+ case syntax_element_buffer_end:
+ case syntax_element_restart_continue:
+ state = state->next.p;
+ break;
+ case syntax_element_dot_rep:
+ case syntax_element_char_rep:
+ case syntax_element_short_set_rep:
+ case syntax_element_long_set_rep:
+ if(this->m_has_backrefs == 0)
+ static_cast<re_repeat*>(state)->leading = true;
+ // fall through:
+ default:
+ return;
+ }
+ }while(state);
+}
+
+
+} // namespace re_detail
+
+} // namespace boost
+
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/ext/boost/regex/v4/basic_regex_parser.hpp b/ext/boost/regex/v4/basic_regex_parser.hpp
new file mode 100644
index 0000000000..7d2f5543e2
--- /dev/null
+++ b/ext/boost/regex/v4/basic_regex_parser.hpp
@@ -0,0 +1,2571 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE basic_regex_parser.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares template class basic_regex_parser.
+ */
+
+#ifndef BOOST_REGEX_V4_BASIC_REGEX_PARSER_HPP
+#define BOOST_REGEX_V4_BASIC_REGEX_PARSER_HPP
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace boost{
+namespace re_detail{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4244 4800)
+#endif
+
+template <class charT, class traits>
+class basic_regex_parser : public basic_regex_creator<charT, traits>
+{
+public:
+ basic_regex_parser(regex_data<charT, traits>* data);
+ void parse(const charT* p1, const charT* p2, unsigned flags);
+ void fail(regex_constants::error_type error_code, std::ptrdiff_t position);
+
+ bool parse_all();
+ bool parse_basic();
+ bool parse_extended();
+ bool parse_literal();
+ bool parse_open_paren();
+ bool parse_basic_escape();
+ bool parse_extended_escape();
+ bool parse_match_any();
+ bool parse_repeat(std::size_t low = 0, std::size_t high = (std::numeric_limits<std::size_t>::max)());
+ bool parse_repeat_range(bool isbasic);
+ bool parse_alt();
+ bool parse_set();
+ bool parse_backref();
+ void parse_set_literal(basic_char_set<charT, traits>& char_set);
+ bool parse_inner_set(basic_char_set<charT, traits>& char_set);
+ bool parse_QE();
+ bool parse_perl_extension();
+ bool add_emacs_code(bool negate);
+ bool unwind_alts(std::ptrdiff_t last_paren_start);
+ digraph<charT> get_next_set_literal(basic_char_set<charT, traits>& char_set);
+ charT unescape_character();
+ regex_constants::syntax_option_type parse_options();
+
+private:
+ typedef bool (basic_regex_parser::*parser_proc_type)();
+ typedef typename traits::string_type string_type;
+ typedef typename traits::char_class_type char_class_type;
+ parser_proc_type m_parser_proc; // the main parser to use
+ const charT* m_base; // the start of the string being parsed
+ const charT* m_end; // the end of the string being parsed
+ const charT* m_position; // our current parser position
+ unsigned m_mark_count; // how many sub-expressions we have
+ int m_mark_reset; // used to indicate that we're inside a (?|...) block.
+ unsigned m_max_mark; // largest mark count seen inside a (?|...) block.
+ std::ptrdiff_t m_paren_start; // where the last seen ')' began (where repeats are inserted).
+ std::ptrdiff_t m_alt_insert_point; // where to insert the next alternative
+ bool m_has_case_change; // true if somewhere in the current block the case has changed
+#if defined(BOOST_MSVC) && defined(_M_IX86)
+ // This is an ugly warning suppression workaround (for warnings *inside* std::vector
+ // that can not otherwise be suppressed)...
+ BOOST_STATIC_ASSERT(sizeof(long) >= sizeof(void*));
+ std::vector<long> m_alt_jumps; // list of alternative in the current scope.
+#else
+ std::vector<std::ptrdiff_t> m_alt_jumps; // list of alternative in the current scope.
+#endif
+
+ basic_regex_parser& operator=(const basic_regex_parser&);
+ basic_regex_parser(const basic_regex_parser&);
+};
+
+template <class charT, class traits>
+basic_regex_parser<charT, traits>::basic_regex_parser(regex_data<charT, traits>* data)
+ : basic_regex_creator<charT, traits>(data), m_mark_count(0), m_mark_reset(-1), m_max_mark(0), m_paren_start(0), m_alt_insert_point(0), m_has_case_change(false)
+{
+}
+
+template <class charT, class traits>
+void basic_regex_parser<charT, traits>::parse(const charT* p1, const charT* p2, unsigned l_flags)
+{
+ // pass l_flags on to base class:
+ this->init(l_flags);
+ // set up pointers:
+ m_position = m_base = p1;
+ m_end = p2;
+ // empty strings are errors:
+ if((p1 == p2) &&
+ (
+ ((l_flags & regbase::main_option_type) != regbase::perl_syntax_group)
+ || (l_flags & regbase::no_empty_expressions)
+ )
+ )
+ {
+ fail(regex_constants::error_empty, 0);
+ return;
+ }
+ // select which parser to use:
+ switch(l_flags & regbase::main_option_type)
+ {
+ case regbase::perl_syntax_group:
+ {
+ m_parser_proc = &basic_regex_parser<charT, traits>::parse_extended;
+ //
+ // Add a leading paren with index zero to give recursions a target:
+ //
+ re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
+ br->index = 0;
+ br->icase = this->flags() & regbase::icase;
+ break;
+ }
+ case regbase::basic_syntax_group:
+ m_parser_proc = &basic_regex_parser<charT, traits>::parse_basic;
+ break;
+ case regbase::literal:
+ m_parser_proc = &basic_regex_parser<charT, traits>::parse_literal;
+ break;
+ }
+
+ // parse all our characters:
+ bool result = parse_all();
+ //
+ // Unwind our alternatives:
+ //
+ unwind_alts(-1);
+ // reset l_flags as a global scope (?imsx) may have altered them:
+ this->flags(l_flags);
+ // if we haven't gobbled up all the characters then we must
+ // have had an unexpected ')' :
+ if(!result)
+ {
+ fail(regex_constants::error_paren, ::boost::re_detail::distance(m_base, m_position));
+ return;
+ }
+ // if an error has been set then give up now:
+ if(this->m_pdata->m_status)
+ return;
+ // fill in our sub-expression count:
+ this->m_pdata->m_mark_count = 1 + m_mark_count;
+ this->finalize(p1, p2);
+}
+
+template <class charT, class traits>
+void basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_code, std::ptrdiff_t position)
+{
+ if(0 == this->m_pdata->m_status) // update the error code if not already set
+ this->m_pdata->m_status = error_code;
+ m_position = m_end; // don't bother parsing anything else
+ // get the error message:
+ std::string message = this->m_pdata->m_ptraits->error_string(error_code);
+ // and raise the exception, this will do nothing if exceptions are disabled:
+#ifndef BOOST_NO_EXCEPTIONS
+ if(0 == (this->flags() & regex_constants::no_except))
+ {
+ boost::regex_error e(message, error_code, position);
+ e.raise();
+ }
+#else
+ (void)position; // suppress warnings.
+#endif
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_all()
+{
+ bool result = true;
+ while(result && (m_position != m_end))
+ {
+ result = (this->*m_parser_proc)();
+ }
+ return result;
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4702)
+#endif
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_basic()
+{
+ switch(this->m_traits.syntax_type(*m_position))
+ {
+ case regex_constants::syntax_escape:
+ return parse_basic_escape();
+ case regex_constants::syntax_dot:
+ return parse_match_any();
+ case regex_constants::syntax_caret:
+ ++m_position;
+ this->append_state(syntax_element_start_line);
+ break;
+ case regex_constants::syntax_dollar:
+ ++m_position;
+ this->append_state(syntax_element_end_line);
+ break;
+ case regex_constants::syntax_star:
+ if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line))
+ return parse_literal();
+ else
+ {
+ ++m_position;
+ return parse_repeat();
+ }
+ case regex_constants::syntax_plus:
+ if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))
+ return parse_literal();
+ else
+ {
+ ++m_position;
+ return parse_repeat(1);
+ }
+ case regex_constants::syntax_question:
+ if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))
+ return parse_literal();
+ else
+ {
+ ++m_position;
+ return parse_repeat(0, 1);
+ }
+ case regex_constants::syntax_open_set:
+ return parse_set();
+ case regex_constants::syntax_newline:
+ if(this->flags() & regbase::newline_alt)
+ return parse_alt();
+ else
+ return parse_literal();
+ default:
+ return parse_literal();
+ }
+ return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_extended()
+{
+ bool result = true;
+ switch(this->m_traits.syntax_type(*m_position))
+ {
+ case regex_constants::syntax_open_mark:
+ return parse_open_paren();
+ case regex_constants::syntax_close_mark:
+ return false;
+ case regex_constants::syntax_escape:
+ return parse_extended_escape();
+ case regex_constants::syntax_dot:
+ return parse_match_any();
+ case regex_constants::syntax_caret:
+ ++m_position;
+ this->append_state(
+ (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_start : syntax_element_start_line));
+ break;
+ case regex_constants::syntax_dollar:
+ ++m_position;
+ this->append_state(
+ (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_end : syntax_element_end_line));
+ break;
+ case regex_constants::syntax_star:
+ if(m_position == this->m_base)
+ {
+ fail(regex_constants::error_badrepeat, 0);
+ return false;
+ }
+ ++m_position;
+ return parse_repeat();
+ case regex_constants::syntax_question:
+ if(m_position == this->m_base)
+ {
+ fail(regex_constants::error_badrepeat, 0);
+ return false;
+ }
+ ++m_position;
+ return parse_repeat(0,1);
+ case regex_constants::syntax_plus:
+ if(m_position == this->m_base)
+ {
+ fail(regex_constants::error_badrepeat, 0);
+ return false;
+ }
+ ++m_position;
+ return parse_repeat(1);
+ case regex_constants::syntax_open_brace:
+ ++m_position;
+ return parse_repeat_range(false);
+ case regex_constants::syntax_close_brace:
+ fail(regex_constants::error_brace, this->m_position - this->m_end);
+ return false;
+ case regex_constants::syntax_or:
+ return parse_alt();
+ case regex_constants::syntax_open_set:
+ return parse_set();
+ case regex_constants::syntax_newline:
+ if(this->flags() & regbase::newline_alt)
+ return parse_alt();
+ else
+ return parse_literal();
+ case regex_constants::syntax_hash:
+ //
+ // If we have a mod_x flag set, then skip until
+ // we get to a newline character:
+ //
+ if((this->flags()
+ & (regbase::no_perl_ex|regbase::mod_x))
+ == regbase::mod_x)
+ {
+ while((m_position != m_end) && !is_separator(*m_position++)){}
+ return true;
+ }
+ // Otherwise fall through:
+ default:
+ result = parse_literal();
+ break;
+ }
+ return result;
+}
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_literal()
+{
+ // append this as a literal provided it's not a space character
+ // or the perl option regbase::mod_x is not set:
+ if(
+ ((this->flags()
+ & (regbase::main_option_type|regbase::mod_x|regbase::no_perl_ex))
+ != regbase::mod_x)
+ || !this->m_traits.isctype(*m_position, this->m_mask_space))
+ this->append_literal(*m_position);
+ ++m_position;
+ return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_open_paren()
+{
+ //
+ // skip the '(' and error check:
+ //
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_paren, m_position - m_base);
+ return false;
+ }
+ //
+ // begin by checking for a perl-style (?...) extension:
+ //
+ if(
+ ((this->flags() & (regbase::main_option_type | regbase::no_perl_ex)) == 0)
+ || ((this->flags() & (regbase::main_option_type | regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))
+ )
+ {
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question)
+ return parse_perl_extension();
+ }
+ //
+ // update our mark count, and append the required state:
+ //
+ unsigned markid = 0;
+ if(0 == (this->flags() & regbase::nosubs))
+ {
+ markid = ++m_mark_count;
+#ifndef BOOST_NO_STD_DISTANCE
+ if(this->flags() & regbase::save_subexpression_location)
+ this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 1, 0));
+#else
+ if(this->flags() & regbase::save_subexpression_location)
+ this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>((m_position - m_base) - 1, 0));
+#endif
+ }
+ re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
+ pb->index = markid;
+ pb->icase = this->flags() & regbase::icase;
+ std::ptrdiff_t last_paren_start = this->getoffset(pb);
+ // back up insertion point for alternations, and set new point:
+ std::ptrdiff_t last_alt_point = m_alt_insert_point;
+ this->m_pdata->m_data.align();
+ m_alt_insert_point = this->m_pdata->m_data.size();
+ //
+ // back up the current flags in case we have a nested (?imsx) group:
+ //
+ regex_constants::syntax_option_type opts = this->flags();
+ bool old_case_change = m_has_case_change;
+ m_has_case_change = false; // no changes to this scope as yet...
+ //
+ // Back up branch reset data in case we have a nested (?|...)
+ //
+ int mark_reset = m_mark_reset;
+ m_mark_reset = -1;
+ //
+ // now recursively add more states, this will terminate when we get to a
+ // matching ')' :
+ //
+ parse_all();
+ //
+ // Unwind pushed alternatives:
+ //
+ if(0 == unwind_alts(last_paren_start))
+ return false;
+ //
+ // restore flags:
+ //
+ if(m_has_case_change)
+ {
+ // the case has changed in one or more of the alternatives
+ // within the scoped (...) block: we have to add a state
+ // to reset the case sensitivity:
+ static_cast<re_case*>(
+ this->append_state(syntax_element_toggle_case, sizeof(re_case))
+ )->icase = opts & regbase::icase;
+ }
+ this->flags(opts);
+ m_has_case_change = old_case_change;
+ //
+ // restore branch reset:
+ //
+ m_mark_reset = mark_reset;
+ //
+ // we either have a ')' or we have run out of characters prematurely:
+ //
+ if(m_position == m_end)
+ {
+ this->fail(regex_constants::error_paren, ::boost::re_detail::distance(m_base, m_end));
+ return false;
+ }
+ BOOST_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark);
+#ifndef BOOST_NO_STD_DISTANCE
+ if(markid && (this->flags() & regbase::save_subexpression_location))
+ this->m_pdata->m_subs.at(markid - 1).second = std::distance(m_base, m_position);
+#else
+ if(markid && (this->flags() & regbase::save_subexpression_location))
+ this->m_pdata->m_subs.at(markid - 1).second = (m_position - m_base);
+#endif
+ ++m_position;
+ //
+ // append closing parenthesis state:
+ //
+ pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
+ pb->index = markid;
+ pb->icase = this->flags() & regbase::icase;
+ this->m_paren_start = last_paren_start;
+ //
+ // restore the alternate insertion point:
+ //
+ this->m_alt_insert_point = last_alt_point;
+ //
+ // allow backrefs to this mark:
+ //
+ if((markid > 0) && (markid < sizeof(unsigned) * CHAR_BIT))
+ this->m_backrefs |= 1u << (markid - 1);
+
+ return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_basic_escape()
+{
+ ++m_position;
+ bool result = true;
+ switch(this->m_traits.escape_syntax_type(*m_position))
+ {
+ case regex_constants::syntax_open_mark:
+ return parse_open_paren();
+ case regex_constants::syntax_close_mark:
+ return false;
+ case regex_constants::syntax_plus:
+ if(this->flags() & regex_constants::bk_plus_qm)
+ {
+ ++m_position;
+ return parse_repeat(1);
+ }
+ else
+ return parse_literal();
+ case regex_constants::syntax_question:
+ if(this->flags() & regex_constants::bk_plus_qm)
+ {
+ ++m_position;
+ return parse_repeat(0, 1);
+ }
+ else
+ return parse_literal();
+ case regex_constants::syntax_open_brace:
+ if(this->flags() & regbase::no_intervals)
+ return parse_literal();
+ ++m_position;
+ return parse_repeat_range(true);
+ case regex_constants::syntax_close_brace:
+ if(this->flags() & regbase::no_intervals)
+ return parse_literal();
+ fail(regex_constants::error_brace, this->m_position - this->m_base);
+ return false;
+ case regex_constants::syntax_or:
+ if(this->flags() & regbase::bk_vbar)
+ return parse_alt();
+ else
+ result = parse_literal();
+ break;
+ case regex_constants::syntax_digit:
+ return parse_backref();
+ case regex_constants::escape_type_start_buffer:
+ if(this->flags() & regbase::emacs_ex)
+ {
+ ++m_position;
+ this->append_state(syntax_element_buffer_start);
+ }
+ else
+ result = parse_literal();
+ break;
+ case regex_constants::escape_type_end_buffer:
+ if(this->flags() & regbase::emacs_ex)
+ {
+ ++m_position;
+ this->append_state(syntax_element_buffer_end);
+ }
+ else
+ result = parse_literal();
+ break;
+ case regex_constants::escape_type_word_assert:
+ if(this->flags() & regbase::emacs_ex)
+ {
+ ++m_position;
+ this->append_state(syntax_element_word_boundary);
+ }
+ else
+ result = parse_literal();
+ break;
+ case regex_constants::escape_type_not_word_assert:
+ if(this->flags() & regbase::emacs_ex)
+ {
+ ++m_position;
+ this->append_state(syntax_element_within_word);
+ }
+ else
+ result = parse_literal();
+ break;
+ case regex_constants::escape_type_left_word:
+ if(this->flags() & regbase::emacs_ex)
+ {
+ ++m_position;
+ this->append_state(syntax_element_word_start);
+ }
+ else
+ result = parse_literal();
+ break;
+ case regex_constants::escape_type_right_word:
+ if(this->flags() & regbase::emacs_ex)
+ {
+ ++m_position;
+ this->append_state(syntax_element_word_end);
+ }
+ else
+ result = parse_literal();
+ break;
+ default:
+ if(this->flags() & regbase::emacs_ex)
+ {
+ bool negate = true;
+ switch(*m_position)
+ {
+ case 'w':
+ negate = false;
+ // fall through:
+ case 'W':
+ {
+ basic_char_set<charT, traits> char_set;
+ if(negate)
+ char_set.negate();
+ char_set.add_class(this->m_word_mask);
+ if(0 == this->append_set(char_set))
+ {
+ fail(regex_constants::error_ctype, m_position - m_base);
+ return false;
+ }
+ ++m_position;
+ return true;
+ }
+ case 's':
+ negate = false;
+ // fall through:
+ case 'S':
+ return add_emacs_code(negate);
+ case 'c':
+ case 'C':
+ // not supported yet:
+ fail(regex_constants::error_escape, m_position - m_base);
+ return false;
+ default:
+ break;
+ }
+ }
+ result = parse_literal();
+ break;
+ }
+ return result;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_extended_escape()
+{
+ ++m_position;
+ bool negate = false; // in case this is a character class escape: \w \d etc
+ switch(this->m_traits.escape_syntax_type(*m_position))
+ {
+ case regex_constants::escape_type_not_class:
+ negate = true;
+ // fall through:
+ case regex_constants::escape_type_class:
+ {
+escape_type_class_jump:
+ typedef typename traits::char_class_type mask_type;
+ mask_type m = this->m_traits.lookup_classname(m_position, m_position+1);
+ if(m != 0)
+ {
+ basic_char_set<charT, traits> char_set;
+ if(negate)
+ char_set.negate();
+ char_set.add_class(m);
+ if(0 == this->append_set(char_set))
+ {
+ fail(regex_constants::error_ctype, m_position - m_base);
+ return false;
+ }
+ ++m_position;
+ return true;
+ }
+ //
+ // not a class, just a regular unknown escape:
+ //
+ this->append_literal(unescape_character());
+ break;
+ }
+ case regex_constants::syntax_digit:
+ return parse_backref();
+ case regex_constants::escape_type_left_word:
+ ++m_position;
+ this->append_state(syntax_element_word_start);
+ break;
+ case regex_constants::escape_type_right_word:
+ ++m_position;
+ this->append_state(syntax_element_word_end);
+ break;
+ case regex_constants::escape_type_start_buffer:
+ ++m_position;
+ this->append_state(syntax_element_buffer_start);
+ break;
+ case regex_constants::escape_type_end_buffer:
+ ++m_position;
+ this->append_state(syntax_element_buffer_end);
+ break;
+ case regex_constants::escape_type_word_assert:
+ ++m_position;
+ this->append_state(syntax_element_word_boundary);
+ break;
+ case regex_constants::escape_type_not_word_assert:
+ ++m_position;
+ this->append_state(syntax_element_within_word);
+ break;
+ case regex_constants::escape_type_Z:
+ ++m_position;
+ this->append_state(syntax_element_soft_buffer_end);
+ break;
+ case regex_constants::escape_type_Q:
+ return parse_QE();
+ case regex_constants::escape_type_C:
+ return parse_match_any();
+ case regex_constants::escape_type_X:
+ ++m_position;
+ this->append_state(syntax_element_combining);
+ break;
+ case regex_constants::escape_type_G:
+ ++m_position;
+ this->append_state(syntax_element_restart_continue);
+ break;
+ case regex_constants::escape_type_not_property:
+ negate = true;
+ // fall through:
+ case regex_constants::escape_type_property:
+ {
+ ++m_position;
+ char_class_type m;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return false;
+ }
+ // maybe have \p{ddd}
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
+ {
+ const charT* base = m_position;
+ // skip forward until we find enclosing brace:
+ while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
+ ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return false;
+ }
+ m = this->m_traits.lookup_classname(++base, m_position++);
+ }
+ else
+ {
+ m = this->m_traits.lookup_classname(m_position, m_position+1);
+ ++m_position;
+ }
+ if(m != 0)
+ {
+ basic_char_set<charT, traits> char_set;
+ if(negate)
+ char_set.negate();
+ char_set.add_class(m);
+ if(0 == this->append_set(char_set))
+ {
+ fail(regex_constants::error_ctype, m_position - m_base);
+ return false;
+ }
+ return true;
+ }
+ fail(regex_constants::error_ctype, m_position - m_base);
+ return false;
+ }
+ case regex_constants::escape_type_reset_start_mark:
+ if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
+ {
+ re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
+ pb->index = -5;
+ pb->icase = this->flags() & regbase::icase;
+ this->m_pdata->m_data.align();
+ ++m_position;
+ return true;
+ }
+ goto escape_type_class_jump;
+ case regex_constants::escape_type_line_ending:
+ if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
+ {
+ const charT* e = get_escape_R_string<charT>();
+ const charT* old_position = m_position;
+ const charT* old_end = m_end;
+ const charT* old_base = m_base;
+ m_position = e;
+ m_base = e;
+ m_end = e + traits::length(e);
+ bool r = parse_all();
+ m_position = ++old_position;
+ m_end = old_end;
+ m_base = old_base;
+ return r;
+ }
+ goto escape_type_class_jump;
+ case regex_constants::escape_type_extended_backref:
+ if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
+ {
+ bool have_brace = false;
+ bool negative = false;
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return false;
+ }
+ // maybe have \g{ddd}
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
+ {
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return false;
+ }
+ have_brace = true;
+ }
+ negative = (*m_position == static_cast<charT>('-'));
+ if((negative) && (++m_position == m_end))
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return false;
+ }
+ const charT* pc = m_position;
+ int i = this->m_traits.toi(pc, m_end, 10);
+ if(i < 0)
+ {
+ // Check for a named capture:
+ const charT* base = m_position;
+ while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
+ ++m_position;
+ i = this->m_pdata->get_id(base, m_position);
+ pc = m_position;
+ }
+ if(negative)
+ i = 1 + m_mark_count - i;
+ if((i > 0) && (this->m_backrefs & (1u << (i-1))))
+ {
+ m_position = pc;
+ re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));
+ pb->index = i;
+ pb->icase = this->flags() & regbase::icase;
+ }
+ else
+ {
+ fail(regex_constants::error_backref, m_position - m_end);
+ return false;
+ }
+ m_position = pc;
+ if(have_brace)
+ {
+ if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return false;
+ }
+ ++m_position;
+ }
+ return true;
+ }
+ goto escape_type_class_jump;
+ case regex_constants::escape_type_control_v:
+ if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
+ goto escape_type_class_jump;
+ // fallthrough:
+ default:
+ this->append_literal(unescape_character());
+ break;
+ }
+ return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_match_any()
+{
+ //
+ // we have a '.' that can match any character:
+ //
+ ++m_position;
+ static_cast<re_dot*>(
+ this->append_state(syntax_element_wild, sizeof(re_dot))
+ )->mask = static_cast<unsigned char>(this->flags() & regbase::no_mod_s
+ ? re_detail::force_not_newline
+ : this->flags() & regbase::mod_s ?
+ re_detail::force_newline : re_detail::dont_care);
+ return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_repeat(std::size_t low, std::size_t high)
+{
+ bool greedy = true;
+ bool pocessive = false;
+ std::size_t insert_point;
+ //
+ // when we get to here we may have a non-greedy ? mark still to come:
+ //
+ if((m_position != m_end)
+ && (
+ (0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
+ || ((regbase::basic_syntax_group|regbase::emacs_ex) == (this->flags() & (regbase::main_option_type | regbase::emacs_ex)))
+ )
+ )
+ {
+ // OK we have a perl or emacs regex, check for a '?':
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question)
+ {
+ greedy = false;
+ ++m_position;
+ }
+ // for perl regexes only check for pocessive ++ repeats.
+ if((0 == (this->flags() & regbase::main_option_type))
+ && (this->m_traits.syntax_type(*m_position) == regex_constants::syntax_plus))
+ {
+ pocessive = true;
+ ++m_position;
+ }
+ }
+ if(0 == this->m_last_state)
+ {
+ fail(regex_constants::error_badrepeat, ::boost::re_detail::distance(m_base, m_position));
+ return false;
+ }
+ if(this->m_last_state->type == syntax_element_endmark)
+ {
+ // insert a repeat before the '(' matching the last ')':
+ insert_point = this->m_paren_start;
+ }
+ else if((this->m_last_state->type == syntax_element_literal) && (static_cast<re_literal*>(this->m_last_state)->length > 1))
+ {
+ // the last state was a literal with more than one character, split it in two:
+ re_literal* lit = static_cast<re_literal*>(this->m_last_state);
+ charT c = (static_cast<charT*>(static_cast<void*>(lit+1)))[lit->length - 1];
+ --(lit->length);
+ // now append new state:
+ lit = static_cast<re_literal*>(this->append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));
+ lit->length = 1;
+ (static_cast<charT*>(static_cast<void*>(lit+1)))[0] = c;
+ insert_point = this->getoffset(this->m_last_state);
+ }
+ else
+ {
+ // repeat the last state whatever it was, need to add some error checking here:
+ switch(this->m_last_state->type)
+ {
+ case syntax_element_start_line:
+ case syntax_element_end_line:
+ case syntax_element_word_boundary:
+ case syntax_element_within_word:
+ case syntax_element_word_start:
+ case syntax_element_word_end:
+ case syntax_element_buffer_start:
+ case syntax_element_buffer_end:
+ case syntax_element_alt:
+ case syntax_element_soft_buffer_end:
+ case syntax_element_restart_continue:
+ case syntax_element_jump:
+ case syntax_element_startmark:
+ case syntax_element_backstep:
+ // can't legally repeat any of the above:
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ default:
+ // do nothing...
+ break;
+ }
+ insert_point = this->getoffset(this->m_last_state);
+ }
+ //
+ // OK we now know what to repeat, so insert the repeat around it:
+ //
+ re_repeat* rep = static_cast<re_repeat*>(this->insert_state(insert_point, syntax_element_rep, re_repeater_size));
+ rep->min = low;
+ rep->max = high;
+ rep->greedy = greedy;
+ rep->leading = false;
+ // store our repeater position for later:
+ std::ptrdiff_t rep_off = this->getoffset(rep);
+ // and append a back jump to the repeat:
+ re_jump* jmp = static_cast<re_jump*>(this->append_state(syntax_element_jump, sizeof(re_jump)));
+ jmp->alt.i = rep_off - this->getoffset(jmp);
+ this->m_pdata->m_data.align();
+ // now fill in the alt jump for the repeat:
+ rep = static_cast<re_repeat*>(this->getaddress(rep_off));
+ rep->alt.i = this->m_pdata->m_data.size() - rep_off;
+ //
+ // If the repeat is pocessive then bracket the repeat with a (?>...)
+ // independent sub-expression construct:
+ //
+ if(pocessive)
+ {
+ re_brace* pb = static_cast<re_brace*>(this->insert_state(insert_point, syntax_element_startmark, sizeof(re_brace)));
+ pb->index = -3;
+ pb->icase = this->flags() & regbase::icase;
+ re_jump* jmp = static_cast<re_jump*>(this->insert_state(insert_point + sizeof(re_brace), syntax_element_jump, sizeof(re_jump)));
+ this->m_pdata->m_data.align();
+ jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);
+ pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
+ pb->index = -3;
+ pb->icase = this->flags() & regbase::icase;
+ }
+ return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)
+{
+ //
+ // parse a repeat-range:
+ //
+ std::size_t min, max;
+ int v;
+ // skip whitespace:
+ while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
+ ++m_position;
+ // fail if at end:
+ if(this->m_position == this->m_end)
+ {
+ fail(regex_constants::error_brace, this->m_position - this->m_base);
+ return false;
+ }
+ // get min:
+ v = this->m_traits.toi(m_position, m_end, 10);
+ // skip whitespace:
+ while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
+ ++m_position;
+ if(v < 0)
+ {
+ fail(regex_constants::error_badbrace, this->m_position - this->m_base);
+ return false;
+ }
+ else if(this->m_position == this->m_end)
+ {
+ fail(regex_constants::error_brace, this->m_position - this->m_base);
+ return false;
+ }
+ min = v;
+ // see if we have a comma:
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_comma)
+ {
+ // move on and error check:
+ ++m_position;
+ // skip whitespace:
+ while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
+ ++m_position;
+ if(this->m_position == this->m_end)
+ {
+ fail(regex_constants::error_brace, this->m_position - this->m_base);
+ return false;
+ }
+ // get the value if any:
+ v = this->m_traits.toi(m_position, m_end, 10);
+ max = (v >= 0) ? v : (std::numeric_limits<std::size_t>::max)();
+ }
+ else
+ {
+ // no comma, max = min:
+ max = min;
+ }
+ // skip whitespace:
+ while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
+ ++m_position;
+ // OK now check trailing }:
+ if(this->m_position == this->m_end)
+ {
+ fail(regex_constants::error_brace, this->m_position - this->m_base);
+ return false;
+ }
+ if(isbasic)
+ {
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_escape)
+ {
+ ++m_position;
+ if(this->m_position == this->m_end)
+ {
+ fail(regex_constants::error_brace, this->m_position - this->m_base);
+ return false;
+ }
+ }
+ else
+ {
+ fail(regex_constants::error_badbrace, this->m_position - this->m_base);
+ return false;
+ }
+ }
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_brace)
+ ++m_position;
+ else
+ {
+ fail(regex_constants::error_badbrace, this->m_position - this->m_base);
+ return false;
+ }
+ //
+ // finally go and add the repeat, unless error:
+ //
+ if(min > max)
+ {
+ fail(regex_constants::error_badbrace, this->m_position - this->m_base);
+ return false;
+ }
+ return parse_repeat(min, max);
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_alt()
+{
+ //
+ // error check: if there have been no previous states,
+ // or if the last state was a '(' then error:
+ //
+ if(
+ ((this->m_last_state == 0) || (this->m_last_state->type == syntax_element_startmark))
+ &&
+ !(
+ ((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group)
+ &&
+ ((this->flags() & regbase::no_empty_expressions) == 0)
+ )
+ )
+ {
+ fail(regex_constants::error_empty, this->m_position - this->m_base);
+ return false;
+ }
+ //
+ // Reset mark count if required:
+ //
+ if(m_max_mark < m_mark_count)
+ m_max_mark = m_mark_count;
+ if(m_mark_reset >= 0)
+ m_mark_count = m_mark_reset;
+
+ ++m_position;
+ //
+ // we need to append a trailing jump:
+ //
+ re_syntax_base* pj = this->append_state(re_detail::syntax_element_jump, sizeof(re_jump));
+ std::ptrdiff_t jump_offset = this->getoffset(pj);
+ //
+ // now insert the alternative:
+ //
+ re_alt* palt = static_cast<re_alt*>(this->insert_state(this->m_alt_insert_point, syntax_element_alt, re_alt_size));
+ jump_offset += re_alt_size;
+ this->m_pdata->m_data.align();
+ palt->alt.i = this->m_pdata->m_data.size() - this->getoffset(palt);
+ //
+ // update m_alt_insert_point so that the next alternate gets
+ // inserted at the start of the second of the two we've just created:
+ //
+ this->m_alt_insert_point = this->m_pdata->m_data.size();
+ //
+ // the start of this alternative must have a case changes state
+ // if the current block has messed around with case changes:
+ //
+ if(m_has_case_change)
+ {
+ static_cast<re_case*>(
+ this->append_state(syntax_element_toggle_case, sizeof(re_case))
+ )->icase = this->m_icase;
+ }
+ //
+ // push the alternative onto our stack, a recursive
+ // implementation here is easier to understand (and faster
+ // as it happens), but causes all kinds of stack overflow problems
+ // on programs with small stacks (COM+).
+ //
+ m_alt_jumps.push_back(jump_offset);
+ return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_set()
+{
+ ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_brack, m_position - m_base);
+ return false;
+ }
+ basic_char_set<charT, traits> char_set;
+
+ const charT* base = m_position; // where the '[' was
+ const charT* item_base = m_position; // where the '[' or '^' was
+
+ while(m_position != m_end)
+ {
+ switch(this->m_traits.syntax_type(*m_position))
+ {
+ case regex_constants::syntax_caret:
+ if(m_position == base)
+ {
+ char_set.negate();
+ ++m_position;
+ item_base = m_position;
+ }
+ else
+ parse_set_literal(char_set);
+ break;
+ case regex_constants::syntax_close_set:
+ if(m_position == item_base)
+ {
+ parse_set_literal(char_set);
+ break;
+ }
+ else
+ {
+ ++m_position;
+ if(0 == this->append_set(char_set))
+ {
+ fail(regex_constants::error_range, m_position - m_base);
+ return false;
+ }
+ }
+ return true;
+ case regex_constants::syntax_open_set:
+ if(parse_inner_set(char_set))
+ break;
+ return true;
+ case regex_constants::syntax_escape:
+ {
+ //
+ // look ahead and see if this is a character class shortcut
+ // \d \w \s etc...
+ //
+ ++m_position;
+ if(this->m_traits.escape_syntax_type(*m_position)
+ == regex_constants::escape_type_class)
+ {
+ char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);
+ if(m != 0)
+ {
+ char_set.add_class(m);
+ ++m_position;
+ break;
+ }
+ }
+ else if(this->m_traits.escape_syntax_type(*m_position)
+ == regex_constants::escape_type_not_class)
+ {
+ // negated character class:
+ char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);
+ if(m != 0)
+ {
+ char_set.add_negated_class(m);
+ ++m_position;
+ break;
+ }
+ }
+ // not a character class, just a regular escape:
+ --m_position;
+ parse_set_literal(char_set);
+ break;
+ }
+ default:
+ parse_set_literal(char_set);
+ break;
+ }
+ }
+ return m_position != m_end;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_inner_set(basic_char_set<charT, traits>& char_set)
+{
+ //
+ // we have either a character class [:name:]
+ // a collating element [.name.]
+ // or an equivalence class [=name=]
+ //
+ if(m_end == ++m_position)
+ {
+ fail(regex_constants::error_brack, m_position - m_base);
+ return false;
+ }
+ switch(this->m_traits.syntax_type(*m_position))
+ {
+ case regex_constants::syntax_dot:
+ //
+ // a collating element is treated as a literal:
+ //
+ --m_position;
+ parse_set_literal(char_set);
+ return true;
+ case regex_constants::syntax_colon:
+ {
+ // check that character classes are actually enabled:
+ if((this->flags() & (regbase::main_option_type | regbase::no_char_classes))
+ == (regbase::basic_syntax_group | regbase::no_char_classes))
+ {
+ --m_position;
+ parse_set_literal(char_set);
+ return true;
+ }
+ // skip the ':'
+ if(m_end == ++m_position)
+ {
+ fail(regex_constants::error_brack, m_position - m_base);
+ return false;
+ }
+ const charT* name_first = m_position;
+ // skip at least one character, then find the matching ':]'
+ if(m_end == ++m_position)
+ {
+ fail(regex_constants::error_brack, m_position - m_base);
+ return false;
+ }
+ while((m_position != m_end)
+ && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_colon))
+ ++m_position;
+ const charT* name_last = m_position;
+ if(m_end == m_position)
+ {
+ fail(regex_constants::error_brack, m_position - m_base);
+ return false;
+ }
+ if((m_end == ++m_position)
+ || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
+ {
+ fail(regex_constants::error_brack, m_position - m_base);
+ return false;
+ }
+ //
+ // check for negated class:
+ //
+ bool negated = false;
+ if(this->m_traits.syntax_type(*name_first) == regex_constants::syntax_caret)
+ {
+ ++name_first;
+ negated = true;
+ }
+ typedef typename traits::char_class_type mask_type;
+ mask_type m = this->m_traits.lookup_classname(name_first, name_last);
+ if(m == 0)
+ {
+ if(char_set.empty() && (name_last - name_first == 1))
+ {
+ // maybe a special case:
+ ++m_position;
+ if( (m_position != m_end)
+ && (this->m_traits.syntax_type(*m_position)
+ == regex_constants::syntax_close_set))
+ {
+ if(this->m_traits.escape_syntax_type(*name_first)
+ == regex_constants::escape_type_left_word)
+ {
+ ++m_position;
+ this->append_state(syntax_element_word_start);
+ return false;
+ }
+ if(this->m_traits.escape_syntax_type(*name_first)
+ == regex_constants::escape_type_right_word)
+ {
+ ++m_position;
+ this->append_state(syntax_element_word_end);
+ return false;
+ }
+ }
+ }
+ fail(regex_constants::error_ctype, name_first - m_base);
+ return false;
+ }
+ if(negated == false)
+ char_set.add_class(m);
+ else
+ char_set.add_negated_class(m);
+ ++m_position;
+ break;
+ }
+ case regex_constants::syntax_equal:
+ {
+ // skip the '='
+ if(m_end == ++m_position)
+ {
+ fail(regex_constants::error_brack, m_position - m_base);
+ return false;
+ }
+ const charT* name_first = m_position;
+ // skip at least one character, then find the matching '=]'
+ if(m_end == ++m_position)
+ {
+ fail(regex_constants::error_brack, m_position - m_base);
+ return false;
+ }
+ while((m_position != m_end)
+ && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal))
+ ++m_position;
+ const charT* name_last = m_position;
+ if(m_end == m_position)
+ {
+ fail(regex_constants::error_brack, m_position - m_base);
+ return false;
+ }
+ if((m_end == ++m_position)
+ || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
+ {
+ fail(regex_constants::error_brack, m_position - m_base);
+ return false;
+ }
+ string_type m = this->m_traits.lookup_collatename(name_first, name_last);
+ if((0 == m.size()) || (m.size() > 2))
+ {
+ fail(regex_constants::error_collate, name_first - m_base);
+ return false;
+ }
+ digraph<charT> d;
+ d.first = m[0];
+ if(m.size() > 1)
+ d.second = m[1];
+ else
+ d.second = 0;
+ char_set.add_equivalent(d);
+ ++m_position;
+ break;
+ }
+ default:
+ --m_position;
+ parse_set_literal(char_set);
+ break;
+ }
+ return true;
+}
+
+template <class charT, class traits>
+void basic_regex_parser<charT, traits>::parse_set_literal(basic_char_set<charT, traits>& char_set)
+{
+ digraph<charT> start_range(get_next_set_literal(char_set));
+ if(m_end == m_position)
+ {
+ fail(regex_constants::error_brack, m_position - m_base);
+ return;
+ }
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)
+ {
+ // we have a range:
+ if(m_end == ++m_position)
+ {
+ fail(regex_constants::error_brack, m_position - m_base);
+ return;
+ }
+ if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set)
+ {
+ digraph<charT> end_range = get_next_set_literal(char_set);
+ char_set.add_range(start_range, end_range);
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)
+ {
+ if(m_end == ++m_position)
+ {
+ fail(regex_constants::error_brack, m_position - m_base);
+ return;
+ }
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_set)
+ {
+ // trailing - :
+ --m_position;
+ return;
+ }
+ fail(regex_constants::error_range, m_position - m_base);
+ return;
+ }
+ return;
+ }
+ --m_position;
+ }
+ char_set.add_single(start_range);
+}
+
+template <class charT, class traits>
+digraph<charT> basic_regex_parser<charT, traits>::get_next_set_literal(basic_char_set<charT, traits>& char_set)
+{
+ digraph<charT> result;
+ switch(this->m_traits.syntax_type(*m_position))
+ {
+ case regex_constants::syntax_dash:
+ if(!char_set.empty())
+ {
+ // see if we are at the end of the set:
+ if((++m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
+ {
+ fail(regex_constants::error_range, m_position - m_base);
+ return result;
+ }
+ --m_position;
+ }
+ result.first = *m_position++;
+ return result;
+ case regex_constants::syntax_escape:
+ // check to see if escapes are supported first:
+ if(this->flags() & regex_constants::no_escape_in_lists)
+ {
+ result = *m_position++;
+ break;
+ }
+ ++m_position;
+ result = unescape_character();
+ break;
+ case regex_constants::syntax_open_set:
+ {
+ if(m_end == ++m_position)
+ {
+ fail(regex_constants::error_collate, m_position - m_base);
+ return result;
+ }
+ if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot)
+ {
+ --m_position;
+ result.first = *m_position;
+ ++m_position;
+ return result;
+ }
+ if(m_end == ++m_position)
+ {
+ fail(regex_constants::error_collate, m_position - m_base);
+ return result;
+ }
+ const charT* name_first = m_position;
+ // skip at least one character, then find the matching ':]'
+ if(m_end == ++m_position)
+ {
+ fail(regex_constants::error_collate, name_first - m_base);
+ return result;
+ }
+ while((m_position != m_end)
+ && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot))
+ ++m_position;
+ const charT* name_last = m_position;
+ if(m_end == m_position)
+ {
+ fail(regex_constants::error_collate, name_first - m_base);
+ return result;
+ }
+ if((m_end == ++m_position)
+ || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
+ {
+ fail(regex_constants::error_collate, name_first - m_base);
+ return result;
+ }
+ ++m_position;
+ string_type s = this->m_traits.lookup_collatename(name_first, name_last);
+ if(s.empty() || (s.size() > 2))
+ {
+ fail(regex_constants::error_collate, name_first - m_base);
+ return result;
+ }
+ result.first = s[0];
+ if(s.size() > 1)
+ result.second = s[1];
+ else
+ result.second = 0;
+ return result;
+ }
+ default:
+ result = *m_position++;
+ }
+ return result;
+}
+
+//
+// does a value fit in the specified charT type?
+//
+template <class charT>
+bool valid_value(charT, int v, const mpl::true_&)
+{
+ return (v >> (sizeof(charT) * CHAR_BIT)) == 0;
+}
+template <class charT>
+bool valid_value(charT, int, const mpl::false_&)
+{
+ return true; // v will alsways fit in a charT
+}
+template <class charT>
+bool valid_value(charT c, int v)
+{
+ return valid_value(c, v, mpl::bool_<(sizeof(charT) < sizeof(int))>());
+}
+
+template <class charT, class traits>
+charT basic_regex_parser<charT, traits>::unescape_character()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+ charT result(0);
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return false;
+ }
+ switch(this->m_traits.escape_syntax_type(*m_position))
+ {
+ case regex_constants::escape_type_control_a:
+ result = charT('\a');
+ break;
+ case regex_constants::escape_type_e:
+ result = charT(27);
+ break;
+ case regex_constants::escape_type_control_f:
+ result = charT('\f');
+ break;
+ case regex_constants::escape_type_control_n:
+ result = charT('\n');
+ break;
+ case regex_constants::escape_type_control_r:
+ result = charT('\r');
+ break;
+ case regex_constants::escape_type_control_t:
+ result = charT('\t');
+ break;
+ case regex_constants::escape_type_control_v:
+ result = charT('\v');
+ break;
+ case regex_constants::escape_type_word_assert:
+ result = charT('\b');
+ break;
+ case regex_constants::escape_type_ascii_control:
+ ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return result;
+ }
+ /*
+ if((*m_position < charT('@'))
+ || (*m_position > charT(125)) )
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return result;
+ }
+ */
+ result = static_cast<charT>(*m_position % 32);
+ break;
+ case regex_constants::escape_type_hex:
+ ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return result;
+ }
+ // maybe have \x{ddd}
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
+ {
+ ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return result;
+ }
+ int i = this->m_traits.toi(m_position, m_end, 16);
+ if((m_position == m_end)
+ || (i < 0)
+ || ((std::numeric_limits<charT>::is_specialized) && (i > (int)(std::numeric_limits<charT>::max)()))
+ || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
+ {
+ fail(regex_constants::error_badbrace, m_position - m_base);
+ return result;
+ }
+ ++m_position;
+ result = charT(i);
+ }
+ else
+ {
+ std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), m_end - m_position);
+ int i = this->m_traits.toi(m_position, m_position + len, 16);
+ if((i < 0)
+ || !valid_value(charT(0), i))
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return result;
+ }
+ result = charT(i);
+ }
+ return result;
+ case regex_constants::syntax_digit:
+ {
+ // an octal escape sequence, the first character must be a zero
+ // followed by up to 3 octal digits:
+ std::ptrdiff_t len = (std::min)(::boost::re_detail::distance(m_position, m_end), static_cast<std::ptrdiff_t>(4));
+ const charT* bp = m_position;
+ int val = this->m_traits.toi(bp, bp + 1, 8);
+ if(val != 0)
+ {
+ // Oops not an octal escape after all:
+ fail(regex_constants::error_escape, m_position - m_base);
+ return result;
+ }
+ val = this->m_traits.toi(m_position, m_position + len, 8);
+ if(val < 0)
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return result;
+ }
+ return static_cast<charT>(val);
+ }
+ case regex_constants::escape_type_named_char:
+ {
+ ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return false;
+ }
+ // maybe have \N{name}
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
+ {
+ const charT* base = m_position;
+ // skip forward until we find enclosing brace:
+ while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
+ ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return false;
+ }
+ string_type s = this->m_traits.lookup_collatename(++base, m_position++);
+ if(s.empty())
+ {
+ fail(regex_constants::error_collate, m_position - m_base);
+ return false;
+ }
+ if(s.size() == 1)
+ {
+ return s[0];
+ }
+ }
+ // fall through is a failure:
+ fail(regex_constants::error_escape, m_position - m_base);
+ return false;
+ }
+ default:
+ result = *m_position;
+ break;
+ }
+ ++m_position;
+ return result;
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_backref()
+{
+ BOOST_ASSERT(m_position != m_end);
+ const charT* pc = m_position;
+ int i = this->m_traits.toi(pc, pc + 1, 10);
+ if((i == 0) || (((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group) && (this->flags() & regbase::no_bk_refs)))
+ {
+ // not a backref at all but an octal escape sequence:
+ charT c = unescape_character();
+ this->append_literal(c);
+ }
+ else if((i > 0) && (this->m_backrefs & (1u << (i-1))))
+ {
+ m_position = pc;
+ re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));
+ pb->index = i;
+ pb->icase = this->flags() & regbase::icase;
+ }
+ else
+ {
+ fail(regex_constants::error_backref, m_position - m_end);
+ return false;
+ }
+ return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_QE()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+ //
+ // parse a \Q...\E sequence:
+ //
+ ++m_position; // skip the Q
+ const charT* start = m_position;
+ const charT* end;
+ do
+ {
+ while((m_position != m_end)
+ && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape))
+ ++m_position;
+ if(m_position == m_end)
+ {
+ // a \Q...\E sequence may terminate with the end of the expression:
+ end = m_position;
+ break;
+ }
+ if(++m_position == m_end) // skip the escape
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return false;
+ }
+ // check to see if it's a \E:
+ if(this->m_traits.escape_syntax_type(*m_position) == regex_constants::escape_type_E)
+ {
+ ++m_position;
+ end = m_position - 2;
+ break;
+ }
+ // otherwise go round again:
+ }while(true);
+ //
+ // now add all the character between the two escapes as literals:
+ //
+ while(start != end)
+ {
+ this->append_literal(*start);
+ ++start;
+ }
+ return true;
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::parse_perl_extension()
+{
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ //
+ // treat comments as a special case, as these
+ // are the only ones that don't start with a leading
+ // startmark state:
+ //
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_hash)
+ {
+ while((m_position != m_end)
+ && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark))
+ {}
+ return true;
+ }
+ //
+ // backup some state, and prepare the way:
+ //
+ int markid = 0;
+ std::ptrdiff_t jump_offset = 0;
+ re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
+ pb->icase = this->flags() & regbase::icase;
+ std::ptrdiff_t last_paren_start = this->getoffset(pb);
+ // back up insertion point for alternations, and set new point:
+ std::ptrdiff_t last_alt_point = m_alt_insert_point;
+ this->m_pdata->m_data.align();
+ m_alt_insert_point = this->m_pdata->m_data.size();
+ std::ptrdiff_t expected_alt_point = m_alt_insert_point;
+ bool restore_flags = true;
+ regex_constants::syntax_option_type old_flags = this->flags();
+ bool old_case_change = m_has_case_change;
+ m_has_case_change = false;
+ charT name_delim;
+ int mark_reset = m_mark_reset;
+ m_mark_reset = -1;
+ int v;
+ //
+ // select the actual extension used:
+ //
+ switch(this->m_traits.syntax_type(*m_position))
+ {
+ case regex_constants::syntax_or:
+ m_mark_reset = m_mark_count;
+ // fall through:
+ case regex_constants::syntax_colon:
+ //
+ // a non-capturing mark:
+ //
+ pb->index = markid = 0;
+ ++m_position;
+ break;
+ case regex_constants::syntax_digit:
+ {
+ //
+ // a recursive subexpression:
+ //
+ v = this->m_traits.toi(m_position, m_end, 10);
+ if((v < 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
+ {
+ fail(regex_constants::error_backref, m_position - m_base);
+ return false;
+ }
+insert_recursion:
+ pb->index = markid = 0;
+ static_cast<re_jump*>(this->append_state(syntax_element_recurse, sizeof(re_jump)))->alt.i = v;
+ static_cast<re_case*>(
+ this->append_state(syntax_element_toggle_case, sizeof(re_case))
+ )->icase = this->flags() & regbase::icase;
+ break;
+ }
+ case regex_constants::syntax_plus:
+ //
+ // A forward-relative recursive subexpression:
+ //
+ ++m_position;
+ v = this->m_traits.toi(m_position, m_end, 10);
+ if((v <= 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
+ {
+ fail(regex_constants::error_backref, m_position - m_base);
+ return false;
+ }
+ v += m_mark_count;
+ goto insert_recursion;
+ case regex_constants::syntax_dash:
+ //
+ // Possibly a backward-relative recursive subexpression:
+ //
+ ++m_position;
+ v = this->m_traits.toi(m_position, m_end, 10);
+ if(v <= 0)
+ {
+ --m_position;
+ // Oops not a relative recursion at all, but a (?-imsx) group:
+ goto option_group_jump;
+ }
+ v = m_mark_count + 1 - v;
+ if(v <= 0)
+ {
+ fail(regex_constants::error_backref, m_position - m_base);
+ return false;
+ }
+ goto insert_recursion;
+ case regex_constants::syntax_equal:
+ pb->index = markid = -1;
+ ++m_position;
+ jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
+ this->m_pdata->m_data.align();
+ m_alt_insert_point = this->m_pdata->m_data.size();
+ break;
+ case regex_constants::syntax_not:
+ pb->index = markid = -2;
+ ++m_position;
+ jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
+ this->m_pdata->m_data.align();
+ m_alt_insert_point = this->m_pdata->m_data.size();
+ break;
+ case regex_constants::escape_type_left_word:
+ {
+ // a lookbehind assertion:
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ regex_constants::syntax_type t = this->m_traits.syntax_type(*m_position);
+ if(t == regex_constants::syntax_not)
+ pb->index = markid = -2;
+ else if(t == regex_constants::syntax_equal)
+ pb->index = markid = -1;
+ else
+ {
+ // Probably a named capture which also starts (?< :
+ name_delim = '>';
+ --m_position;
+ goto named_capture_jump;
+ }
+ ++m_position;
+ jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
+ this->append_state(syntax_element_backstep, sizeof(re_brace));
+ this->m_pdata->m_data.align();
+ m_alt_insert_point = this->m_pdata->m_data.size();
+ break;
+ }
+ case regex_constants::escape_type_right_word:
+ //
+ // an independent sub-expression:
+ //
+ pb->index = markid = -3;
+ ++m_position;
+ jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
+ this->m_pdata->m_data.align();
+ m_alt_insert_point = this->m_pdata->m_data.size();
+ break;
+ case regex_constants::syntax_open_mark:
+ {
+ // a conditional expression:
+ pb->index = markid = -4;
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ int v = this->m_traits.toi(m_position, m_end, 10);
+ if(*m_position == charT('R'))
+ {
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ if(*m_position == charT('&'))
+ {
+ const charT* base = ++m_position;
+ while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
+ ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ v = -static_cast<int>(hash_value_from_capture_name(base, m_position));
+ }
+ else
+ {
+ v = -this->m_traits.toi(m_position, m_end, 10);
+ }
+ re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
+ br->index = v < 0 ? (v - 1) : 0;
+ if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ }
+ else if((*m_position == charT('\'')) || (*m_position == charT('<')))
+ {
+ const charT* base = ++m_position;
+ while((m_position != m_end) && (*m_position != charT('>')) && (*m_position != charT('\'')))
+ ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ v = static_cast<int>(hash_value_from_capture_name(base, m_position));
+ re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
+ br->index = v;
+ if((*m_position != charT('>')) && (*m_position != charT('\'')) || (++m_position == m_end))
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ }
+ else if(*m_position == charT('D'))
+ {
+ const char* def = "DEFINE";
+ while(*def && (m_position != m_end) && (*m_position == charT(*def)))
+ ++m_position, ++def;
+ if((m_position == m_end) || *def)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
+ br->index = 9999; // special magic value!
+ if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ }
+ else if(v > 0)
+ {
+ re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
+ br->index = v;
+ if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ }
+ else
+ {
+ // verify that we have a lookahead or lookbehind assert:
+ if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_question)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::escape_type_left_word)
+ {
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)
+ && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ m_position -= 3;
+ }
+ else
+ {
+ if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)
+ && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))
+ {
+ fail(regex_constants::error_paren, m_position - m_base);
+ return false;
+ }
+ m_position -= 2;
+ }
+ }
+ break;
+ }
+ case regex_constants::syntax_close_mark:
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ case regex_constants::escape_type_end_buffer:
+ {
+ name_delim = *m_position;
+named_capture_jump:
+ markid = 0;
+ if(0 == (this->flags() & regbase::nosubs))
+ {
+ markid = ++m_mark_count;
+ #ifndef BOOST_NO_STD_DISTANCE
+ if(this->flags() & regbase::save_subexpression_location)
+ this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 2, 0));
+ #else
+ if(this->flags() & regbase::save_subexpression_location)
+ this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>((m_position - m_base) - 2, 0));
+ #endif
+ }
+ pb->index = markid;
+ const charT* base = ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_paren, m_position - m_base);
+ return false;
+ }
+ while((m_position != m_end) && (*m_position != name_delim))
+ ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_paren, m_position - m_base);
+ return false;
+ }
+ this->m_pdata->set_name(base, m_position, markid);
+ ++m_position;
+ break;
+ }
+ default:
+ if(*m_position == charT('R'))
+ {
+ ++m_position;
+ v = 0;
+ if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
+ {
+ fail(regex_constants::error_backref, m_position - m_base);
+ return false;
+ }
+ goto insert_recursion;
+ }
+ if(*m_position == charT('&'))
+ {
+ ++m_position;
+ const charT* base = m_position;
+ while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
+ ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_backref, m_position - m_base);
+ return false;
+ }
+ v = static_cast<int>(hash_value_from_capture_name(base, m_position));
+ goto insert_recursion;
+ }
+ if(*m_position == charT('P'))
+ {
+ ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_backref, m_position - m_base);
+ return false;
+ }
+ if(*m_position == charT('>'))
+ {
+ ++m_position;
+ const charT* base = m_position;
+ while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
+ ++m_position;
+ if(m_position == m_end)
+ {
+ fail(regex_constants::error_backref, m_position - m_base);
+ return false;
+ }
+ v = static_cast<int>(hash_value_from_capture_name(base, m_position));
+ goto insert_recursion;
+ }
+ }
+ //
+ // lets assume that we have a (?imsx) group and try and parse it:
+ //
+option_group_jump:
+ regex_constants::syntax_option_type opts = parse_options();
+ if(m_position == m_end)
+ return false;
+ // make a note of whether we have a case change:
+ m_has_case_change = ((opts & regbase::icase) != (this->flags() & regbase::icase));
+ pb->index = markid = 0;
+ if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark)
+ {
+ // update flags and carry on as normal:
+ this->flags(opts);
+ restore_flags = false;
+ old_case_change |= m_has_case_change; // defer end of scope by one ')'
+ }
+ else if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_colon)
+ {
+ // update flags and carry on until the matching ')' is found:
+ this->flags(opts);
+ ++m_position;
+ }
+ else
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+
+ // finally append a case change state if we need it:
+ if(m_has_case_change)
+ {
+ static_cast<re_case*>(
+ this->append_state(syntax_element_toggle_case, sizeof(re_case))
+ )->icase = opts & regbase::icase;
+ }
+
+ }
+ //
+ // now recursively add more states, this will terminate when we get to a
+ // matching ')' :
+ //
+ parse_all();
+ //
+ // Unwind alternatives:
+ //
+ if(0 == unwind_alts(last_paren_start))
+ return false;
+ //
+ // we either have a ')' or we have run out of characters prematurely:
+ //
+ if(m_position == m_end)
+ {
+ this->fail(regex_constants::error_paren, ::boost::re_detail::distance(m_base, m_end));
+ return false;
+ }
+ BOOST_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark);
+ ++m_position;
+ //
+ // restore the flags:
+ //
+ if(restore_flags)
+ {
+ // append a case change state if we need it:
+ if(m_has_case_change)
+ {
+ static_cast<re_case*>(
+ this->append_state(syntax_element_toggle_case, sizeof(re_case))
+ )->icase = old_flags & regbase::icase;
+ }
+ this->flags(old_flags);
+ }
+ //
+ // set up the jump pointer if we have one:
+ //
+ if(jump_offset)
+ {
+ this->m_pdata->m_data.align();
+ re_jump* jmp = static_cast<re_jump*>(this->getaddress(jump_offset));
+ jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);
+ if(this->m_last_state == jmp)
+ {
+ // Oops... we didn't have anything inside the assertion:
+ fail(regex_constants::error_empty, m_position - m_base);
+ return false;
+ }
+ }
+ //
+ // verify that if this is conditional expression, that we do have
+ // an alternative, if not add one:
+ //
+ if(markid == -4)
+ {
+ re_syntax_base* b = this->getaddress(expected_alt_point);
+ // Make sure we have exactly one alternative following this state:
+ if(b->type != syntax_element_alt)
+ {
+ re_alt* alt = static_cast<re_alt*>(this->insert_state(expected_alt_point, syntax_element_alt, sizeof(re_alt)));
+ alt->alt.i = this->m_pdata->m_data.size() - this->getoffset(alt);
+ }
+ else if(this->getaddress(static_cast<re_alt*>(b)->alt.i, b)->type == syntax_element_alt)
+ {
+ // Can't have seen more than one alternative:
+ fail(regex_constants::error_bad_pattern, m_position - m_base);
+ return false;
+ }
+ else
+ {
+ // We must *not* have seen an alternative inside a (DEFINE) block:
+ b = this->getaddress(b->next.i, b);
+ if((b->type == syntax_element_assert_backref) && (static_cast<re_brace*>(b)->index == 9999))
+ {
+ fail(regex_constants::error_bad_pattern, m_position - m_base);
+ return false;
+ }
+ }
+ // check for invalid repetition of next state:
+ b = this->getaddress(expected_alt_point);
+ b = this->getaddress(static_cast<re_alt*>(b)->next.i, b);
+ if((b->type != syntax_element_assert_backref)
+ && (b->type != syntax_element_startmark))
+ {
+ fail(regex_constants::error_badrepeat, m_position - m_base);
+ return false;
+ }
+ }
+ //
+ // append closing parenthesis state:
+ //
+ pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
+ pb->index = markid;
+ pb->icase = this->flags() & regbase::icase;
+ this->m_paren_start = last_paren_start;
+ //
+ // restore the alternate insertion point:
+ //
+ this->m_alt_insert_point = last_alt_point;
+ //
+ // and the case change data:
+ //
+ m_has_case_change = old_case_change;
+ //
+ // And the mark_reset data:
+ //
+ if(m_max_mark > m_mark_count)
+ {
+ m_mark_count = m_max_mark;
+ }
+ m_mark_reset = mark_reset;
+
+
+ if(markid > 0)
+ {
+#ifndef BOOST_NO_STD_DISTANCE
+ if(this->flags() & regbase::save_subexpression_location)
+ this->m_pdata->m_subs.at(markid - 1).second = std::distance(m_base, m_position) - 1;
+#else
+ if(this->flags() & regbase::save_subexpression_location)
+ this->m_pdata->m_subs.at(markid - 1).second = (m_position - m_base) - 1;
+#endif
+ //
+ // allow backrefs to this mark:
+ //
+ if((markid > 0) && (markid < (int)(sizeof(unsigned) * CHAR_BIT)))
+ this->m_backrefs |= 1u << (markid - 1);
+ }
+ return true;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::add_emacs_code(bool negate)
+{
+ //
+ // parses an emacs style \sx or \Sx construct.
+ //
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_escape, m_position - m_base);
+ return false;
+ }
+ basic_char_set<charT, traits> char_set;
+ if(negate)
+ char_set.negate();
+
+ static const charT s_punct[5] = { 'p', 'u', 'n', 'c', 't', };
+
+ switch(*m_position)
+ {
+ case 's':
+ case ' ':
+ char_set.add_class(this->m_mask_space);
+ break;
+ case 'w':
+ char_set.add_class(this->m_word_mask);
+ break;
+ case '_':
+ char_set.add_single(digraph<charT>(charT('$')));
+ char_set.add_single(digraph<charT>(charT('&')));
+ char_set.add_single(digraph<charT>(charT('*')));
+ char_set.add_single(digraph<charT>(charT('+')));
+ char_set.add_single(digraph<charT>(charT('-')));
+ char_set.add_single(digraph<charT>(charT('_')));
+ char_set.add_single(digraph<charT>(charT('<')));
+ char_set.add_single(digraph<charT>(charT('>')));
+ break;
+ case '.':
+ char_set.add_class(this->m_traits.lookup_classname(s_punct, s_punct+5));
+ break;
+ case '(':
+ char_set.add_single(digraph<charT>(charT('(')));
+ char_set.add_single(digraph<charT>(charT('[')));
+ char_set.add_single(digraph<charT>(charT('{')));
+ break;
+ case ')':
+ char_set.add_single(digraph<charT>(charT(')')));
+ char_set.add_single(digraph<charT>(charT(']')));
+ char_set.add_single(digraph<charT>(charT('}')));
+ break;
+ case '"':
+ char_set.add_single(digraph<charT>(charT('"')));
+ char_set.add_single(digraph<charT>(charT('\'')));
+ char_set.add_single(digraph<charT>(charT('`')));
+ break;
+ case '\'':
+ char_set.add_single(digraph<charT>(charT('\'')));
+ char_set.add_single(digraph<charT>(charT(',')));
+ char_set.add_single(digraph<charT>(charT('#')));
+ break;
+ case '<':
+ char_set.add_single(digraph<charT>(charT(';')));
+ break;
+ case '>':
+ char_set.add_single(digraph<charT>(charT('\n')));
+ char_set.add_single(digraph<charT>(charT('\f')));
+ break;
+ default:
+ fail(regex_constants::error_ctype, m_position - m_base);
+ return false;
+ }
+ if(0 == this->append_set(char_set))
+ {
+ fail(regex_constants::error_ctype, m_position - m_base);
+ return false;
+ }
+ ++m_position;
+ return true;
+}
+
+template <class charT, class traits>
+regex_constants::syntax_option_type basic_regex_parser<charT, traits>::parse_options()
+{
+ // we have a (?imsx-imsx) group, convert it into a set of flags:
+ regex_constants::syntax_option_type f = this->flags();
+ bool breakout = false;
+ do
+ {
+ switch(*m_position)
+ {
+ case 's':
+ f |= regex_constants::mod_s;
+ f &= ~regex_constants::no_mod_s;
+ break;
+ case 'm':
+ f &= ~regex_constants::no_mod_m;
+ break;
+ case 'i':
+ f |= regex_constants::icase;
+ break;
+ case 'x':
+ f |= regex_constants::mod_x;
+ break;
+ default:
+ breakout = true;
+ continue;
+ }
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_paren, m_position - m_base);
+ return false;
+ }
+ }
+ while(!breakout);
+
+ if(*m_position == static_cast<charT>('-'))
+ {
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_paren, m_position - m_base);
+ return false;
+ }
+ do
+ {
+ switch(*m_position)
+ {
+ case 's':
+ f &= ~regex_constants::mod_s;
+ f |= regex_constants::no_mod_s;
+ break;
+ case 'm':
+ f |= regex_constants::no_mod_m;
+ break;
+ case 'i':
+ f &= ~regex_constants::icase;
+ break;
+ case 'x':
+ f &= ~regex_constants::mod_x;
+ break;
+ default:
+ breakout = true;
+ continue;
+ }
+ if(++m_position == m_end)
+ {
+ fail(regex_constants::error_paren, m_position - m_base);
+ return false;
+ }
+ }
+ while(!breakout);
+ }
+ return f;
+}
+
+template <class charT, class traits>
+bool basic_regex_parser<charT, traits>::unwind_alts(std::ptrdiff_t last_paren_start)
+{
+ //
+ // If we didn't actually add any states after the last
+ // alternative then that's an error:
+ //
+ if((this->m_alt_insert_point == static_cast<std::ptrdiff_t>(this->m_pdata->m_data.size()))
+ && m_alt_jumps.size() && (m_alt_jumps.back() > last_paren_start)
+ &&
+ !(
+ ((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group)
+ &&
+ ((this->flags() & regbase::no_empty_expressions) == 0)
+ )
+ )
+ {
+ fail(regex_constants::error_empty, this->m_position - this->m_base);
+ return false;
+ }
+ //
+ // Fix up our alternatives:
+ //
+ while(m_alt_jumps.size() && (m_alt_jumps.back() > last_paren_start))
+ {
+ //
+ // fix up the jump to point to the end of the states
+ // that we've just added:
+ //
+ std::ptrdiff_t jump_offset = m_alt_jumps.back();
+ m_alt_jumps.pop_back();
+ this->m_pdata->m_data.align();
+ re_jump* jmp = static_cast<re_jump*>(this->getaddress(jump_offset));
+ BOOST_ASSERT(jmp->type == syntax_element_jump);
+ jmp->alt.i = this->m_pdata->m_data.size() - jump_offset;
+ }
+ return true;
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace re_detail
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/ext/boost/regex/v4/c_regex_traits.hpp b/ext/boost/regex/v4/c_regex_traits.hpp
new file mode 100644
index 0000000000..d99b0f341b
--- /dev/null
+++ b/ext/boost/regex/v4/c_regex_traits.hpp
@@ -0,0 +1,211 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE c_regex_traits.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares regular expression traits class that wraps the global C locale.
+ */
+
+#ifndef BOOST_C_REGEX_TRAITS_HPP_INCLUDED
+#define BOOST_C_REGEX_TRAITS_HPP_INCLUDED
+
+#ifndef BOOST_REGEX_CONFIG_HPP
+#include <boost/regex/config.hpp>
+#endif
+#ifndef BOOST_REGEX_WORKAROUND_HPP
+#include <boost/regex/v4/regex_workaround.hpp>
+#endif
+
+#include <cctype>
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std{
+ using ::strlen; using ::tolower;
+}
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace boost{
+
+template <class charT>
+struct c_regex_traits;
+
+template<>
+struct BOOST_REGEX_DECL c_regex_traits<char>
+{
+ c_regex_traits(){}
+ typedef char char_type;
+ typedef std::size_t size_type;
+ typedef std::string string_type;
+ struct locale_type{};
+ typedef boost::uint32_t char_class_type;
+
+ static size_type length(const char_type* p)
+ {
+ return (std::strlen)(p);
+ }
+
+ char translate(char c) const
+ {
+ return c;
+ }
+ char translate_nocase(char c) const
+ {
+ return static_cast<char>((std::tolower)(static_cast<unsigned char>(c)));
+ }
+
+ static string_type BOOST_REGEX_CALL transform(const char* p1, const char* p2);
+ static string_type BOOST_REGEX_CALL transform_primary(const char* p1, const char* p2);
+
+ static char_class_type BOOST_REGEX_CALL lookup_classname(const char* p1, const char* p2);
+ static string_type BOOST_REGEX_CALL lookup_collatename(const char* p1, const char* p2);
+
+ static bool BOOST_REGEX_CALL isctype(char, char_class_type);
+ static int BOOST_REGEX_CALL value(char, int);
+
+ locale_type imbue(locale_type l)
+ { return l; }
+ locale_type getloc()const
+ { return locale_type(); }
+
+private:
+ // this type is not copyable:
+ c_regex_traits(const c_regex_traits&);
+ c_regex_traits& operator=(const c_regex_traits&);
+};
+
+#ifndef BOOST_NO_WREGEX
+template<>
+struct BOOST_REGEX_DECL c_regex_traits<wchar_t>
+{
+ c_regex_traits(){}
+ typedef wchar_t char_type;
+ typedef std::size_t size_type;
+ typedef std::wstring string_type;
+ struct locale_type{};
+ typedef boost::uint32_t char_class_type;
+
+ static size_type length(const char_type* p)
+ {
+ return (std::wcslen)(p);
+ }
+
+ wchar_t translate(wchar_t c) const
+ {
+ return c;
+ }
+ wchar_t translate_nocase(wchar_t c) const
+ {
+ return (std::towlower)(c);
+ }
+
+ static string_type BOOST_REGEX_CALL transform(const wchar_t* p1, const wchar_t* p2);
+ static string_type BOOST_REGEX_CALL transform_primary(const wchar_t* p1, const wchar_t* p2);
+
+ static char_class_type BOOST_REGEX_CALL lookup_classname(const wchar_t* p1, const wchar_t* p2);
+ static string_type BOOST_REGEX_CALL lookup_collatename(const wchar_t* p1, const wchar_t* p2);
+
+ static bool BOOST_REGEX_CALL isctype(wchar_t, char_class_type);
+ static int BOOST_REGEX_CALL value(wchar_t, int);
+
+ locale_type imbue(locale_type l)
+ { return l; }
+ locale_type getloc()const
+ { return locale_type(); }
+
+private:
+ // this type is not copyable:
+ c_regex_traits(const c_regex_traits&);
+ c_regex_traits& operator=(const c_regex_traits&);
+};
+
+#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
+//
+// Provide an unsigned short version as well, so the user can link to this
+// no matter whether they build with /Zc:wchar_t or not (MSVC specific).
+//
+template<>
+struct BOOST_REGEX_DECL c_regex_traits<unsigned short>
+{
+ c_regex_traits(){}
+ typedef unsigned short char_type;
+ typedef std::size_t size_type;
+ typedef std::basic_string<unsigned short> string_type;
+ struct locale_type{};
+ typedef boost::uint32_t char_class_type;
+
+ static size_type length(const char_type* p)
+ {
+ return (std::wcslen)((const wchar_t*)p);
+ }
+
+ unsigned short translate(unsigned short c) const
+ {
+ return c;
+ }
+ unsigned short translate_nocase(unsigned short c) const
+ {
+ return (std::towlower)((wchar_t)c);
+ }
+
+ static string_type BOOST_REGEX_CALL transform(const unsigned short* p1, const unsigned short* p2);
+ static string_type BOOST_REGEX_CALL transform_primary(const unsigned short* p1, const unsigned short* p2);
+
+ static char_class_type BOOST_REGEX_CALL lookup_classname(const unsigned short* p1, const unsigned short* p2);
+ static string_type BOOST_REGEX_CALL lookup_collatename(const unsigned short* p1, const unsigned short* p2);
+
+ static bool BOOST_REGEX_CALL isctype(unsigned short, char_class_type);
+ static int BOOST_REGEX_CALL value(unsigned short, int);
+
+ locale_type imbue(locale_type l)
+ { return l; }
+ locale_type getloc()const
+ { return locale_type(); }
+
+private:
+ // this type is not copyable:
+ c_regex_traits(const c_regex_traits&);
+ c_regex_traits& operator=(const c_regex_traits&);
+};
+
+#endif
+
+#endif // BOOST_NO_WREGEX
+
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
+
+
diff --git a/ext/boost/regex/v4/char_regex_traits.hpp b/ext/boost/regex/v4/char_regex_traits.hpp
new file mode 100644
index 0000000000..e8a501ca00
--- /dev/null
+++ b/ext/boost/regex/v4/char_regex_traits.hpp
@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE char_regex_traits.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares deprecated traits classes char_regex_traits<>.
+ */
+
+
+#ifndef BOOST_REGEX_V4_CHAR_REGEX_TRAITS_HPP
+#define BOOST_REGEX_V4_CHAR_REGEX_TRAITS_HPP
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace boost{
+
+namespace deprecated{
+//
+// class char_regex_traits_i
+// provides case insensitive traits classes (deprecated):
+template <class charT>
+class char_regex_traits_i : public regex_traits<charT> {};
+
+template<>
+class char_regex_traits_i<char> : public regex_traits<char>
+{
+public:
+ typedef char char_type;
+ typedef unsigned char uchar_type;
+ typedef unsigned int size_type;
+ typedef regex_traits<char> base_type;
+
+};
+
+#ifndef BOOST_NO_WREGEX
+template<>
+class char_regex_traits_i<wchar_t> : public regex_traits<wchar_t>
+{
+public:
+ typedef wchar_t char_type;
+ typedef unsigned short uchar_type;
+ typedef unsigned int size_type;
+ typedef regex_traits<wchar_t> base_type;
+
+};
+#endif
+} // namespace deprecated
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif // include
+
diff --git a/ext/boost/regex/v4/cpp_regex_traits.hpp b/ext/boost/regex/v4/cpp_regex_traits.hpp
new file mode 100644
index 0000000000..7ce3ed300e
--- /dev/null
+++ b/ext/boost/regex/v4/cpp_regex_traits.hpp
@@ -0,0 +1,1086 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE cpp_regex_traits.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares regular expression traits class cpp_regex_traits.
+ */
+
+#ifndef BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
+#define BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
+
+#include <boost/config.hpp>
+
+#ifndef BOOST_NO_STD_LOCALE
+
+#ifndef BOOST_RE_PAT_EXCEPT_HPP
+#include <boost/regex/pattern_except.hpp>
+#endif
+#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
+#include <boost/regex/v4/regex_traits_defaults.hpp>
+#endif
+#ifdef BOOST_HAS_THREADS
+#include <boost/regex/pending/static_mutex.hpp>
+#endif
+#ifndef BOOST_REGEX_PRIMARY_TRANSFORM
+#include <boost/regex/v4/primary_transform.hpp>
+#endif
+#ifndef BOOST_REGEX_OBJECT_CACHE_HPP
+#include <boost/regex/pending/object_cache.hpp>
+#endif
+
+#include <istream>
+#include <ios>
+#include <climits>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4786)
+#endif
+
+namespace boost{
+
+//
+// forward declaration is needed by some compilers:
+//
+template <class charT>
+class cpp_regex_traits;
+
+namespace re_detail{
+
+//
+// class parser_buf:
+// acts as a stream buffer which wraps around a pair of pointers:
+//
+template <class charT,
+ class traits = ::std::char_traits<charT> >
+class parser_buf : public ::std::basic_streambuf<charT, traits>
+{
+ typedef ::std::basic_streambuf<charT, traits> base_type;
+ typedef typename base_type::int_type int_type;
+ typedef typename base_type::char_type char_type;
+ typedef typename base_type::pos_type pos_type;
+ typedef ::std::streamsize streamsize;
+ typedef typename base_type::off_type off_type;
+public:
+ parser_buf() : base_type() { setbuf(0, 0); }
+ const charT* getnext() { return this->gptr(); }
+protected:
+ std::basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n);
+ typename parser_buf<charT, traits>::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which);
+ typename parser_buf<charT, traits>::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which);
+private:
+ parser_buf& operator=(const parser_buf&);
+ parser_buf(const parser_buf&);
+};
+
+template<class charT, class traits>
+std::basic_streambuf<charT, traits>*
+parser_buf<charT, traits>::setbuf(char_type* s, streamsize n)
+{
+ this->setg(s, s, s + n);
+ return this;
+}
+
+template<class charT, class traits>
+typename parser_buf<charT, traits>::pos_type
+parser_buf<charT, traits>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)
+{
+ if(which & ::std::ios_base::out)
+ return pos_type(off_type(-1));
+ std::ptrdiff_t size = this->egptr() - this->eback();
+ std::ptrdiff_t pos = this->gptr() - this->eback();
+ charT* g = this->eback();
+ switch(way)
+ {
+ case ::std::ios_base::beg:
+ if((off < 0) || (off > size))
+ return pos_type(off_type(-1));
+ else
+ this->setg(g, g + off, g + size);
+ break;
+ case ::std::ios_base::end:
+ if((off < 0) || (off > size))
+ return pos_type(off_type(-1));
+ else
+ this->setg(g, g + size - off, g + size);
+ break;
+ case ::std::ios_base::cur:
+ {
+ std::ptrdiff_t newpos = static_cast<std::ptrdiff_t>(pos + off);
+ if((newpos < 0) || (newpos > size))
+ return pos_type(off_type(-1));
+ else
+ this->setg(g, g + newpos, g + size);
+ break;
+ }
+ default: ;
+ }
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4244)
+#endif
+ return static_cast<pos_type>(this->gptr() - this->eback());
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template<class charT, class traits>
+typename parser_buf<charT, traits>::pos_type
+parser_buf<charT, traits>::seekpos(pos_type sp, ::std::ios_base::openmode which)
+{
+ if(which & ::std::ios_base::out)
+ return pos_type(off_type(-1));
+ off_type size = static_cast<off_type>(this->egptr() - this->eback());
+ charT* g = this->eback();
+ if(off_type(sp) <= size)
+ {
+ this->setg(g, g + off_type(sp), g + size);
+ }
+ return pos_type(off_type(-1));
+}
+
+//
+// class cpp_regex_traits_base:
+// acts as a container for locale and the facets we are using.
+//
+template <class charT>
+struct cpp_regex_traits_base
+{
+ cpp_regex_traits_base(const std::locale& l)
+ { imbue(l); }
+ std::locale imbue(const std::locale& l);
+
+ std::locale m_locale;
+ std::ctype<charT> const* m_pctype;
+#ifndef BOOST_NO_STD_MESSAGES
+ std::messages<charT> const* m_pmessages;
+#endif
+ std::collate<charT> const* m_pcollate;
+
+ bool operator<(const cpp_regex_traits_base& b)const
+ {
+ if(m_pctype == b.m_pctype)
+ {
+#ifndef BOOST_NO_STD_MESSAGES
+ if(m_pmessages == b.m_pmessages)
+ {
+ }
+ return m_pmessages < b.m_pmessages;
+#else
+ return m_pcollate < b.m_pcollate;
+#endif
+ }
+ return m_pctype < b.m_pctype;
+ }
+ bool operator==(const cpp_regex_traits_base& b)const
+ {
+ return (m_pctype == b.m_pctype)
+#ifndef BOOST_NO_STD_MESSAGES
+ && (m_pmessages == b.m_pmessages)
+#endif
+ && (m_pcollate == b.m_pcollate);
+ }
+};
+
+template <class charT>
+std::locale cpp_regex_traits_base<charT>::imbue(const std::locale& l)
+{
+ std::locale result(m_locale);
+ m_locale = l;
+ m_pctype = &BOOST_USE_FACET(std::ctype<charT>, l);
+#ifndef BOOST_NO_STD_MESSAGES
+ m_pmessages = &BOOST_USE_FACET(std::messages<charT>, l);
+#endif
+ m_pcollate = &BOOST_USE_FACET(std::collate<charT>, l);
+ return result;
+}
+
+//
+// class cpp_regex_traits_char_layer:
+// implements methods that require specialisation for narrow characters:
+//
+template <class charT>
+class cpp_regex_traits_char_layer : public cpp_regex_traits_base<charT>
+{
+ typedef std::basic_string<charT> string_type;
+ typedef std::map<charT, regex_constants::syntax_type> map_type;
+ typedef typename map_type::const_iterator map_iterator_type;
+public:
+ cpp_regex_traits_char_layer(const std::locale& l)
+ : cpp_regex_traits_base<charT>(l)
+ {
+ init();
+ }
+ cpp_regex_traits_char_layer(const cpp_regex_traits_base<charT>& b)
+ : cpp_regex_traits_base<charT>(b)
+ {
+ init();
+ }
+ void init();
+
+ regex_constants::syntax_type syntax_type(charT c)const
+ {
+ map_iterator_type i = m_char_map.find(c);
+ return ((i == m_char_map.end()) ? 0 : i->second);
+ }
+ regex_constants::escape_syntax_type escape_syntax_type(charT c) const
+ {
+ map_iterator_type i = m_char_map.find(c);
+ if(i == m_char_map.end())
+ {
+ if(this->m_pctype->is(std::ctype_base::lower, c)) return regex_constants::escape_type_class;
+ if(this->m_pctype->is(std::ctype_base::upper, c)) return regex_constants::escape_type_not_class;
+ return 0;
+ }
+ return i->second;
+ }
+
+private:
+ string_type get_default_message(regex_constants::syntax_type);
+ // TODO: use a hash table when available!
+ map_type m_char_map;
+};
+
+template <class charT>
+void cpp_regex_traits_char_layer<charT>::init()
+{
+ // we need to start by initialising our syntax map so we know which
+ // character is used for which purpose:
+#ifndef BOOST_NO_STD_MESSAGES
+#ifndef __IBMCPP__
+ typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
+#else
+ typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
+#endif
+ std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
+ if(cat_name.size())
+ {
+ cat = this->m_pmessages->open(
+ cat_name,
+ this->m_locale);
+ if((int)cat < 0)
+ {
+ std::string m("Unable to open message catalog: ");
+ std::runtime_error err(m + cat_name);
+ boost::re_detail::raise_runtime_error(err);
+ }
+ }
+ //
+ // if we have a valid catalog then load our messages:
+ //
+ if((int)cat >= 0)
+ {
+#ifndef BOOST_NO_EXCEPTIONS
+ try{
+#endif
+ for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
+ {
+ string_type mss = this->m_pmessages->get(cat, 0, i, get_default_message(i));
+ for(typename string_type::size_type j = 0; j < mss.size(); ++j)
+ {
+ m_char_map[mss[j]] = i;
+ }
+ }
+ this->m_pmessages->close(cat);
+#ifndef BOOST_NO_EXCEPTIONS
+ }
+ catch(...)
+ {
+ this->m_pmessages->close(cat);
+ throw;
+ }
+#endif
+ }
+ else
+ {
+#endif
+ for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
+ {
+ const char* ptr = get_default_syntax(i);
+ while(ptr && *ptr)
+ {
+ m_char_map[this->m_pctype->widen(*ptr)] = i;
+ ++ptr;
+ }
+ }
+#ifndef BOOST_NO_STD_MESSAGES
+ }
+#endif
+}
+
+template <class charT>
+typename cpp_regex_traits_char_layer<charT>::string_type
+ cpp_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
+{
+ const char* ptr = get_default_syntax(i);
+ string_type result;
+ while(ptr && *ptr)
+ {
+ result.append(1, this->m_pctype->widen(*ptr));
+ ++ptr;
+ }
+ return result;
+}
+
+//
+// specialised version for narrow characters:
+//
+template <>
+class BOOST_REGEX_DECL cpp_regex_traits_char_layer<char> : public cpp_regex_traits_base<char>
+{
+ typedef std::string string_type;
+public:
+ cpp_regex_traits_char_layer(const std::locale& l)
+ : cpp_regex_traits_base<char>(l)
+ {
+ init();
+ }
+ cpp_regex_traits_char_layer(const cpp_regex_traits_base<char>& l)
+ : cpp_regex_traits_base<char>(l)
+ {
+ init();
+ }
+
+ regex_constants::syntax_type syntax_type(char c)const
+ {
+ return m_char_map[static_cast<unsigned char>(c)];
+ }
+ regex_constants::escape_syntax_type escape_syntax_type(char c) const
+ {
+ return m_char_map[static_cast<unsigned char>(c)];
+ }
+
+private:
+ regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
+ void init();
+};
+
+#ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
+enum
+{
+ char_class_space=1<<0,
+ char_class_print=1<<1,
+ char_class_cntrl=1<<2,
+ char_class_upper=1<<3,
+ char_class_lower=1<<4,
+ char_class_alpha=1<<5,
+ char_class_digit=1<<6,
+ char_class_punct=1<<7,
+ char_class_xdigit=1<<8,
+ char_class_alnum=char_class_alpha|char_class_digit,
+ char_class_graph=char_class_alnum|char_class_punct,
+ char_class_blank=1<<9,
+ char_class_word=1<<10,
+ char_class_unicode=1<<11,
+ char_class_horizontal_space=1<<12,
+ char_class_vertical_space=1<<13
+};
+
+#endif
+
+//
+// class cpp_regex_traits_implementation:
+// provides pimpl implementation for cpp_regex_traits.
+//
+template <class charT>
+class cpp_regex_traits_implementation : public cpp_regex_traits_char_layer<charT>
+{
+public:
+ typedef typename cpp_regex_traits<charT>::char_class_type char_class_type;
+ typedef typename std::ctype<charT>::mask native_mask_type;
+#ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
+ BOOST_STATIC_CONSTANT(char_class_type, mask_blank = 1u << 24);
+ BOOST_STATIC_CONSTANT(char_class_type, mask_word = 1u << 25);
+ BOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 1u << 26);
+ BOOST_STATIC_CONSTANT(char_class_type, mask_horizontal = 1u << 27);
+ BOOST_STATIC_CONSTANT(char_class_type, mask_vertical = 1u << 28);
+#endif
+
+ typedef std::basic_string<charT> string_type;
+ typedef charT char_type;
+ //cpp_regex_traits_implementation();
+ cpp_regex_traits_implementation(const std::locale& l)
+ : cpp_regex_traits_char_layer<charT>(l)
+ {
+ init();
+ }
+ cpp_regex_traits_implementation(const cpp_regex_traits_base<charT>& l)
+ : cpp_regex_traits_char_layer<charT>(l)
+ {
+ init();
+ }
+ std::string error_string(regex_constants::error_type n) const
+ {
+ if(!m_error_strings.empty())
+ {
+ std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
+ return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
+ }
+ return get_default_error_string(n);
+ }
+ char_class_type lookup_classname(const charT* p1, const charT* p2) const
+ {
+ char_class_type result = lookup_classname_imp(p1, p2);
+ if(result == 0)
+ {
+ string_type temp(p1, p2);
+ this->m_pctype->tolower(&*temp.begin(), &*temp.begin() + temp.size());
+ result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
+ }
+ return result;
+ }
+ string_type lookup_collatename(const charT* p1, const charT* p2) const;
+ string_type transform_primary(const charT* p1, const charT* p2) const;
+ string_type transform(const charT* p1, const charT* p2) const;
+private:
+ std::map<int, std::string> m_error_strings; // error messages indexed by numberic ID
+ std::map<string_type, char_class_type> m_custom_class_names; // character class names
+ std::map<string_type, string_type> m_custom_collate_names; // collating element names
+ unsigned m_collate_type; // the form of the collation string
+ charT m_collate_delim; // the collation group delimiter
+ //
+ // helpers:
+ //
+ char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
+ void init();
+#ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
+public:
+ bool isctype(charT c, char_class_type m)const;
+#endif
+};
+
+#ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
+#if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
+
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_blank;
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_word;
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_unicode;
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_vertical;
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_horizontal;
+
+#endif
+#endif
+
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::string_type
+ cpp_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
+{
+ //
+ // PRECONDITIONS:
+ //
+ // A bug in gcc 3.2 (and maybe other versions as well) treats
+ // p1 as a null terminated string, for efficiency reasons
+ // we work around this elsewhere, but just assert here that
+ // we adhere to gcc's (buggy) preconditions...
+ //
+ BOOST_ASSERT(*p2 == 0);
+
+ string_type result;
+ //
+ // swallowing all exceptions here is a bad idea
+ // however at least one std lib will always throw
+ // std::bad_alloc for certain arguments...
+ //
+ try{
+ //
+ // What we do here depends upon the format of the sort key returned by
+ // sort key returned by this->transform:
+ //
+ switch(m_collate_type)
+ {
+ case sort_C:
+ case sort_unknown:
+ // the best we can do is translate to lower case, then get a regular sort key:
+ {
+ result.assign(p1, p2);
+ this->m_pctype->tolower(&*result.begin(), &*result.begin() + result.size());
+ result = this->m_pcollate->transform(&*result.begin(), &*result.begin() + result.size());
+ break;
+ }
+ case sort_fixed:
+ {
+ // get a regular sort key, and then truncate it:
+ result.assign(this->m_pcollate->transform(p1, p2));
+ result.erase(this->m_collate_delim);
+ break;
+ }
+ case sort_delim:
+ // get a regular sort key, and then truncate everything after the delim:
+ result.assign(this->m_pcollate->transform(p1, p2));
+ std::size_t i;
+ for(i = 0; i < result.size(); ++i)
+ {
+ if(result[i] == m_collate_delim)
+ break;
+ }
+ result.erase(i);
+ break;
+ }
+ }catch(...){}
+ while(result.size() && (charT(0) == *result.rbegin()))
+ result.erase(result.size() - 1);
+ if(result.empty())
+ {
+ // character is ignorable at the primary level:
+ result = string_type(1, charT(0));
+ }
+ return result;
+}
+
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::string_type
+ cpp_regex_traits_implementation<charT>::transform(const charT* p1, const charT* p2) const
+{
+ //
+ // PRECONDITIONS:
+ //
+ // A bug in gcc 3.2 (and maybe other versions as well) treats
+ // p1 as a null terminated string, for efficiency reasons
+ // we work around this elsewhere, but just assert here that
+ // we adhere to gcc's (buggy) preconditions...
+ //
+ BOOST_ASSERT(*p2 == 0);
+ //
+ // swallowing all exceptions here is a bad idea
+ // however at least one std lib will always throw
+ // std::bad_alloc for certain arguments...
+ //
+ string_type result;
+ try{
+ result = this->m_pcollate->transform(p1, p2);
+ //
+ // Borland's STLPort version returns a NULL-terminated
+ // string that has garbage at the end - each call to
+ // std::collate<wchar_t>::transform returns a different string!
+ // So as a workaround, we'll truncate the string at the first NULL
+ // which _seems_ to work....
+#if BOOST_WORKAROUND(__BORLANDC__, < 0x580)
+ result.erase(result.find(charT(0)));
+#else
+ //
+ // some implementations (Dinkumware) append unnecessary trailing \0's:
+ while(result.size() && (charT(0) == *result.rbegin()))
+ result.erase(result.size() - 1);
+#endif
+ BOOST_ASSERT(std::find(result.begin(), result.end(), charT(0)) == result.end());
+ }
+ catch(...)
+ {
+ }
+ return result;
+}
+
+
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::string_type
+ cpp_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
+{
+ typedef typename std::map<string_type, string_type>::const_iterator iter_type;
+ if(m_custom_collate_names.size())
+ {
+ iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
+ if(pos != m_custom_collate_names.end())
+ return pos->second;
+ }
+#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
+ && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)\
+ && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
+ std::string name(p1, p2);
+#else
+ std::string name;
+ const charT* p0 = p1;
+ while(p0 != p2)
+ name.append(1, char(*p0++));
+#endif
+ name = lookup_default_collate_name(name);
+#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
+ && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)\
+ && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
+ if(name.size())
+ return string_type(name.begin(), name.end());
+#else
+ if(name.size())
+ {
+ string_type result;
+ typedef std::string::const_iterator iter;
+ iter b = name.begin();
+ iter e = name.end();
+ while(b != e)
+ result.append(1, charT(*b++));
+ return result;
+ }
+#endif
+ if(p2 - p1 == 1)
+ return string_type(1, *p1);
+ return string_type();
+}
+
+template <class charT>
+void cpp_regex_traits_implementation<charT>::init()
+{
+#ifndef BOOST_NO_STD_MESSAGES
+#ifndef __IBMCPP__
+ typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
+#else
+ typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
+#endif
+ std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
+ if(cat_name.size())
+ {
+ cat = this->m_pmessages->open(
+ cat_name,
+ this->m_locale);
+ if((int)cat < 0)
+ {
+ std::string m("Unable to open message catalog: ");
+ std::runtime_error err(m + cat_name);
+ boost::re_detail::raise_runtime_error(err);
+ }
+ }
+ //
+ // if we have a valid catalog then load our messages:
+ //
+ if((int)cat >= 0)
+ {
+ //
+ // Error messages:
+ //
+ for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0);
+ i <= boost::regex_constants::error_unknown;
+ i = static_cast<boost::regex_constants::error_type>(i + 1))
+ {
+ const char* p = get_default_error_string(i);
+ string_type default_message;
+ while(*p)
+ {
+ default_message.append(1, this->m_pctype->widen(*p));
+ ++p;
+ }
+ string_type s = this->m_pmessages->get(cat, 0, i+200, default_message);
+ std::string result;
+ for(std::string::size_type j = 0; j < s.size(); ++j)
+ {
+ result.append(1, this->m_pctype->narrow(s[j], 0));
+ }
+ m_error_strings[i] = result;
+ }
+ //
+ // Custom class names:
+ //
+#ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
+ static const char_class_type masks[16] =
+ {
+ std::ctype<charT>::alnum,
+ std::ctype<charT>::alpha,
+ std::ctype<charT>::cntrl,
+ std::ctype<charT>::digit,
+ std::ctype<charT>::graph,
+ cpp_regex_traits_implementation<charT>::mask_horizontal,
+ std::ctype<charT>::lower,
+ std::ctype<charT>::print,
+ std::ctype<charT>::punct,
+ std::ctype<charT>::space,
+ std::ctype<charT>::upper,
+ cpp_regex_traits_implementation<charT>::mask_vertical,
+ std::ctype<charT>::xdigit,
+ cpp_regex_traits_implementation<charT>::mask_blank,
+ cpp_regex_traits_implementation<charT>::mask_word,
+ cpp_regex_traits_implementation<charT>::mask_unicode,
+ };
+#else
+ static const char_class_type masks[14] =
+ {
+ ::boost::re_detail::char_class_alnum,
+ ::boost::re_detail::char_class_alpha,
+ ::boost::re_detail::char_class_cntrl,
+ ::boost::re_detail::char_class_digit,
+ ::boost::re_detail::char_class_graph,
+ ::boost::re_detail::char_class_horizontal_space,
+ ::boost::re_detail::char_class_lower,
+ ::boost::re_detail::char_class_print,
+ ::boost::re_detail::char_class_punct,
+ ::boost::re_detail::char_class_space,
+ ::boost::re_detail::char_class_upper,
+ ::boost::re_detail::char_class_vertical_space,
+ ::boost::re_detail::char_class_xdigit,
+ ::boost::re_detail::char_class_blank,
+ ::boost::re_detail::char_class_word,
+ ::boost::re_detail::char_class_unicode,
+ };
+#endif
+ static const string_type null_string;
+ for(unsigned int j = 0; j <= 13; ++j)
+ {
+ string_type s(this->m_pmessages->get(cat, 0, j+300, null_string));
+ if(s.size())
+ this->m_custom_class_names[s] = masks[j];
+ }
+ }
+#endif
+ //
+ // get the collation format used by m_pcollate:
+ //
+ m_collate_type = re_detail::find_sort_syntax(this, &m_collate_delim);
+}
+
+template <class charT>
+typename cpp_regex_traits_implementation<charT>::char_class_type
+ cpp_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
+{
+#ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
+ static const char_class_type masks[22] =
+ {
+ 0,
+ std::ctype<char>::alnum,
+ std::ctype<char>::alpha,
+ cpp_regex_traits_implementation<charT>::mask_blank,
+ std::ctype<char>::cntrl,
+ std::ctype<char>::digit,
+ std::ctype<char>::digit,
+ std::ctype<char>::graph,
+ cpp_regex_traits_implementation<charT>::mask_horizontal,
+ std::ctype<char>::lower,
+ std::ctype<char>::lower,
+ std::ctype<char>::print,
+ std::ctype<char>::punct,
+ std::ctype<char>::space,
+ std::ctype<char>::space,
+ std::ctype<char>::upper,
+ cpp_regex_traits_implementation<charT>::mask_unicode,
+ std::ctype<char>::upper,
+ cpp_regex_traits_implementation<charT>::mask_vertical,
+ std::ctype<char>::alnum | cpp_regex_traits_implementation<charT>::mask_word,
+ std::ctype<char>::alnum | cpp_regex_traits_implementation<charT>::mask_word,
+ std::ctype<char>::xdigit,
+ };
+#else
+ static const char_class_type masks[22] =
+ {
+ 0,
+ ::boost::re_detail::char_class_alnum,
+ ::boost::re_detail::char_class_alpha,
+ ::boost::re_detail::char_class_blank,
+ ::boost::re_detail::char_class_cntrl,
+ ::boost::re_detail::char_class_digit,
+ ::boost::re_detail::char_class_digit,
+ ::boost::re_detail::char_class_graph,
+ ::boost::re_detail::char_class_horizontal_space,
+ ::boost::re_detail::char_class_lower,
+ ::boost::re_detail::char_class_lower,
+ ::boost::re_detail::char_class_print,
+ ::boost::re_detail::char_class_punct,
+ ::boost::re_detail::char_class_space,
+ ::boost::re_detail::char_class_space,
+ ::boost::re_detail::char_class_upper,
+ ::boost::re_detail::char_class_unicode,
+ ::boost::re_detail::char_class_upper,
+ ::boost::re_detail::char_class_vertical_space,
+ ::boost::re_detail::char_class_alnum | ::boost::re_detail::char_class_word,
+ ::boost::re_detail::char_class_alnum | ::boost::re_detail::char_class_word,
+ ::boost::re_detail::char_class_xdigit,
+ };
+#endif
+ if(m_custom_class_names.size())
+ {
+ typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
+ map_iter pos = m_custom_class_names.find(string_type(p1, p2));
+ if(pos != m_custom_class_names.end())
+ return pos->second;
+ }
+ std::size_t state_id = 1 + re_detail::get_default_class_id(p1, p2);
+ BOOST_ASSERT(state_id < sizeof(masks) / sizeof(masks[0]));
+ return masks[state_id];
+}
+
+#ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
+template <class charT>
+bool cpp_regex_traits_implementation<charT>::isctype(const charT c, char_class_type mask) const
+{
+ return
+ ((mask & ::boost::re_detail::char_class_space) && (m_pctype->is(std::ctype<charT>::space, c)))
+ || ((mask & ::boost::re_detail::char_class_print) && (m_pctype->is(std::ctype<charT>::print, c)))
+ || ((mask & ::boost::re_detail::char_class_cntrl) && (m_pctype->is(std::ctype<charT>::cntrl, c)))
+ || ((mask & ::boost::re_detail::char_class_upper) && (m_pctype->is(std::ctype<charT>::upper, c)))
+ || ((mask & ::boost::re_detail::char_class_lower) && (m_pctype->is(std::ctype<charT>::lower, c)))
+ || ((mask & ::boost::re_detail::char_class_alpha) && (m_pctype->is(std::ctype<charT>::alpha, c)))
+ || ((mask & ::boost::re_detail::char_class_digit) && (m_pctype->is(std::ctype<charT>::digit, c)))
+ || ((mask & ::boost::re_detail::char_class_punct) && (m_pctype->is(std::ctype<charT>::punct, c)))
+ || ((mask & ::boost::re_detail::char_class_xdigit) && (m_pctype->is(std::ctype<charT>::xdigit, c)))
+ || ((mask & ::boost::re_detail::char_class_blank) && (m_pctype->is(std::ctype<charT>::space, c)) && !::boost::re_detail::is_separator(c))
+ || ((mask & ::boost::re_detail::char_class_word) && (c == '_'))
+ || ((mask & ::boost::re_detail::char_class_unicode) && ::boost::re_detail::is_extended(c))
+ || ((mask & ::boost::re_detail::char_class_vertical) && (is_separator(c) || (c == '\v')))
+ || ((mask & ::boost::re_detail::char_class_horizontal) && m_pctype->is(std::ctype<charT>::space, c) && !(is_separator(c) || (c == '\v')));
+}
+#endif
+
+
+template <class charT>
+inline boost::shared_ptr<const cpp_regex_traits_implementation<charT> > create_cpp_regex_traits(const std::locale& l BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(charT))
+{
+ cpp_regex_traits_base<charT> key(l);
+ return ::boost::object_cache<cpp_regex_traits_base<charT>, cpp_regex_traits_implementation<charT> >::get(key, 5);
+}
+
+} // re_detail
+
+template <class charT>
+class cpp_regex_traits
+{
+private:
+ typedef std::ctype<charT> ctype_type;
+public:
+ typedef charT char_type;
+ typedef std::size_t size_type;
+ typedef std::basic_string<char_type> string_type;
+ typedef std::locale locale_type;
+ typedef boost::uint_least32_t char_class_type;
+
+ struct boost_extensions_tag{};
+
+ cpp_regex_traits()
+ : m_pimpl(re_detail::create_cpp_regex_traits<charT>(std::locale()))
+ { }
+ static size_type length(const char_type* p)
+ {
+ return std::char_traits<charT>::length(p);
+ }
+ regex_constants::syntax_type syntax_type(charT c)const
+ {
+ return m_pimpl->syntax_type(c);
+ }
+ regex_constants::escape_syntax_type escape_syntax_type(charT c) const
+ {
+ return m_pimpl->escape_syntax_type(c);
+ }
+ charT translate(charT c) const
+ {
+ return c;
+ }
+ charT translate_nocase(charT c) const
+ {
+ return m_pimpl->m_pctype->tolower(c);
+ }
+ charT translate(charT c, bool icase) const
+ {
+ return icase ? m_pimpl->m_pctype->tolower(c) : c;
+ }
+ charT tolower(charT c) const
+ {
+ return m_pimpl->m_pctype->tolower(c);
+ }
+ charT toupper(charT c) const
+ {
+ return m_pimpl->m_pctype->toupper(c);
+ }
+ string_type transform(const charT* p1, const charT* p2) const
+ {
+ return m_pimpl->transform(p1, p2);
+ }
+ string_type transform_primary(const charT* p1, const charT* p2) const
+ {
+ return m_pimpl->transform_primary(p1, p2);
+ }
+ char_class_type lookup_classname(const charT* p1, const charT* p2) const
+ {
+ return m_pimpl->lookup_classname(p1, p2);
+ }
+ string_type lookup_collatename(const charT* p1, const charT* p2) const
+ {
+ return m_pimpl->lookup_collatename(p1, p2);
+ }
+ bool isctype(charT c, char_class_type f) const
+ {
+#ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
+ typedef typename std::ctype<charT>::mask ctype_mask;
+
+ static const ctype_mask mask_base =
+ static_cast<ctype_mask>(
+ std::ctype<charT>::alnum
+ | std::ctype<charT>::alpha
+ | std::ctype<charT>::cntrl
+ | std::ctype<charT>::digit
+ | std::ctype<charT>::graph
+ | std::ctype<charT>::lower
+ | std::ctype<charT>::print
+ | std::ctype<charT>::punct
+ | std::ctype<charT>::space
+ | std::ctype<charT>::upper
+ | std::ctype<charT>::xdigit);
+
+ if((f & mask_base)
+ && (m_pimpl->m_pctype->is(
+ static_cast<ctype_mask>(f & mask_base), c)))
+ return true;
+ else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_unicode) && re_detail::is_extended(c))
+ return true;
+ else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_word) && (c == '_'))
+ return true;
+ else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_blank)
+ && m_pimpl->m_pctype->is(std::ctype<charT>::space, c)
+ && !re_detail::is_separator(c))
+ return true;
+ else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_vertical)
+ && (::boost::re_detail::is_separator(c) || (c == '\v')))
+ return true;
+ else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_horizontal)
+ && this->isctype(c, std::ctype<charT>::space) && !this->isctype(c, re_detail::cpp_regex_traits_implementation<charT>::mask_vertical))
+ return true;
+ return false;
+#else
+ return m_pimpl->isctype(c, f);
+#endif
+ }
+ int toi(const charT*& p1, const charT* p2, int radix)const;
+ int value(charT c, int radix)const
+ {
+ const charT* pc = &c;
+ return toi(pc, pc + 1, radix);
+ }
+ locale_type imbue(locale_type l)
+ {
+ std::locale result(getloc());
+ m_pimpl = re_detail::create_cpp_regex_traits<charT>(l);
+ return result;
+ }
+ locale_type getloc()const
+ {
+ return m_pimpl->m_locale;
+ }
+ std::string error_string(regex_constants::error_type n) const
+ {
+ return m_pimpl->error_string(n);
+ }
+
+ //
+ // extension:
+ // set the name of the message catalog in use (defaults to "boost_regex").
+ //
+ static std::string catalog_name(const std::string& name);
+ static std::string get_catalog_name();
+
+private:
+ boost::shared_ptr<const re_detail::cpp_regex_traits_implementation<charT> > m_pimpl;
+ //
+ // catalog name handler:
+ //
+ static std::string& get_catalog_name_inst();
+
+#ifdef BOOST_HAS_THREADS
+ static static_mutex& get_mutex_inst();
+#endif
+};
+
+
+template <class charT>
+int cpp_regex_traits<charT>::toi(const charT*& first, const charT* last, int radix)const
+{
+ re_detail::parser_buf<charT> sbuf; // buffer for parsing numbers.
+ std::basic_istream<charT> is(&sbuf); // stream for parsing numbers.
+
+ // we do NOT want to parse any thousands separators inside the stream:
+ last = std::find(first, last, BOOST_USE_FACET(std::numpunct<charT>, is.getloc()).thousands_sep());
+
+ sbuf.pubsetbuf(const_cast<charT*>(static_cast<const charT*>(first)), static_cast<std::streamsize>(last-first));
+ is.clear();
+ if(std::abs(radix) == 16) is >> std::hex;
+ else if(std::abs(radix) == 8) is >> std::oct;
+ else is >> std::dec;
+ int val;
+ if(is >> val)
+ {
+ first = first + ((last - first) - sbuf.in_avail());
+ return val;
+ }
+ else
+ return -1;
+}
+
+template <class charT>
+std::string cpp_regex_traits<charT>::catalog_name(const std::string& name)
+{
+#ifdef BOOST_HAS_THREADS
+ static_mutex::scoped_lock lk(get_mutex_inst());
+#endif
+ std::string result(get_catalog_name_inst());
+ get_catalog_name_inst() = name;
+ return result;
+}
+
+template <class charT>
+std::string& cpp_regex_traits<charT>::get_catalog_name_inst()
+{
+ static std::string s_name;
+ return s_name;
+}
+
+template <class charT>
+std::string cpp_regex_traits<charT>::get_catalog_name()
+{
+#ifdef BOOST_HAS_THREADS
+ static_mutex::scoped_lock lk(get_mutex_inst());
+#endif
+ std::string result(get_catalog_name_inst());
+ return result;
+}
+
+#ifdef BOOST_HAS_THREADS
+template <class charT>
+static_mutex& cpp_regex_traits<charT>::get_mutex_inst()
+{
+ static static_mutex s_mutex = BOOST_STATIC_MUTEX_INIT;
+ return s_mutex;
+}
+#endif
+
+
+} // boost
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
+#endif
+
+
diff --git a/ext/boost/regex/v4/cregex.hpp b/ext/boost/regex/v4/cregex.hpp
new file mode 100644
index 0000000000..cafe396cd9
--- /dev/null
+++ b/ext/boost/regex/v4/cregex.hpp
@@ -0,0 +1,329 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE cregex.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares POSIX API functions
+ * + boost::RegEx high level wrapper.
+ */
+
+#ifndef BOOST_RE_CREGEX_HPP_INCLUDED
+#define BOOST_RE_CREGEX_HPP_INCLUDED
+
+#ifndef BOOST_REGEX_CONFIG_HPP
+#include <boost/regex/config.hpp>
+#endif
+#include <boost/regex/v4/match_flags.hpp>
+#include <boost/regex/v4/error_type.hpp>
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+/* include these defs only for POSIX compatablity */
+#ifdef __cplusplus
+namespace boost{
+extern "C" {
+#endif
+
+#if defined(__cplusplus) && !defined(BOOST_NO_STDC_NAMESPACE)
+typedef std::ptrdiff_t regoff_t;
+typedef std::size_t regsize_t;
+#else
+typedef ptrdiff_t regoff_t;
+typedef size_t regsize_t;
+#endif
+
+typedef struct
+{
+ unsigned int re_magic;
+#ifdef __cplusplus
+ std::size_t re_nsub; /* number of parenthesized subexpressions */
+#else
+ size_t re_nsub;
+#endif
+ const char* re_endp; /* end pointer for REG_PEND */
+ void* guts; /* none of your business :-) */
+ match_flag_type eflags; /* none of your business :-) */
+} regex_tA;
+
+#ifndef BOOST_NO_WREGEX
+typedef struct
+{
+ unsigned int re_magic;
+#ifdef __cplusplus
+ std::size_t re_nsub; /* number of parenthesized subexpressions */
+#else
+ size_t re_nsub;
+#endif
+ const wchar_t* re_endp; /* end pointer for REG_PEND */
+ void* guts; /* none of your business :-) */
+ match_flag_type eflags; /* none of your business :-) */
+} regex_tW;
+#endif
+
+typedef struct
+{
+ regoff_t rm_so; /* start of match */
+ regoff_t rm_eo; /* end of match */
+} regmatch_t;
+
+/* regcomp() flags */
+typedef enum{
+ REG_BASIC = 0000,
+ REG_EXTENDED = 0001,
+ REG_ICASE = 0002,
+ REG_NOSUB = 0004,
+ REG_NEWLINE = 0010,
+ REG_NOSPEC = 0020,
+ REG_PEND = 0040,
+ REG_DUMP = 0200,
+ REG_NOCOLLATE = 0400,
+ REG_ESCAPE_IN_LISTS = 01000,
+ REG_NEWLINE_ALT = 02000,
+ REG_PERLEX = 04000,
+
+ REG_PERL = REG_EXTENDED | REG_NOCOLLATE | REG_ESCAPE_IN_LISTS | REG_PERLEX,
+ REG_AWK = REG_EXTENDED | REG_ESCAPE_IN_LISTS,
+ REG_GREP = REG_BASIC | REG_NEWLINE_ALT,
+ REG_EGREP = REG_EXTENDED | REG_NEWLINE_ALT,
+
+ REG_ASSERT = 15,
+ REG_INVARG = 16,
+ REG_ATOI = 255, /* convert name to number (!) */
+ REG_ITOA = 0400 /* convert number to name (!) */
+} reg_comp_flags;
+
+/* regexec() flags */
+typedef enum{
+ REG_NOTBOL = 00001,
+ REG_NOTEOL = 00002,
+ REG_STARTEND = 00004
+} reg_exec_flags;
+
+//
+// POSIX error codes:
+//
+typedef unsigned reg_error_t;
+typedef reg_error_t reg_errcode_t; // backwards compatibility
+
+static const reg_error_t REG_NOERROR = 0; /* Success. */
+static const reg_error_t REG_NOMATCH = 1; /* Didn't find a match (for regexec). */
+
+ /* POSIX regcomp return error codes. (In the order listed in the
+ standard.) */
+static const reg_error_t REG_BADPAT = 2; /* Invalid pattern. */
+static const reg_error_t REG_ECOLLATE = 3; /* Undefined collating element. */
+static const reg_error_t REG_ECTYPE = 4; /* Invalid character class name. */
+static const reg_error_t REG_EESCAPE = 5; /* Trailing backslash. */
+static const reg_error_t REG_ESUBREG = 6; /* Invalid back reference. */
+static const reg_error_t REG_EBRACK = 7; /* Unmatched left bracket. */
+static const reg_error_t REG_EPAREN = 8; /* Parenthesis imbalance. */
+static const reg_error_t REG_EBRACE = 9; /* Unmatched \{. */
+static const reg_error_t REG_BADBR = 10; /* Invalid contents of \{\}. */
+static const reg_error_t REG_ERANGE = 11; /* Invalid range end. */
+static const reg_error_t REG_ESPACE = 12; /* Ran out of memory. */
+static const reg_error_t REG_BADRPT = 13; /* No preceding re for repetition op. */
+static const reg_error_t REG_EEND = 14; /* unexpected end of expression */
+static const reg_error_t REG_ESIZE = 15; /* expression too big */
+static const reg_error_t REG_ERPAREN = 8; /* = REG_EPAREN : unmatched right parenthesis */
+static const reg_error_t REG_EMPTY = 17; /* empty expression */
+static const reg_error_t REG_E_MEMORY = 15; /* = REG_ESIZE : out of memory */
+static const reg_error_t REG_ECOMPLEXITY = 18; /* complexity too high */
+static const reg_error_t REG_ESTACK = 19; /* out of stack space */
+static const reg_error_t REG_E_UNKNOWN = 20; /* unknown error */
+static const reg_error_t REG_ENOSYS = 20; /* = REG_E_UNKNOWN : Reserved. */
+
+BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompA(regex_tA*, const char*, int);
+BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int, const regex_tA*, char*, regsize_t);
+BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecA(const regex_tA*, const char*, regsize_t, regmatch_t*, int);
+BOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeA(regex_tA*);
+
+#ifndef BOOST_NO_WREGEX
+BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW*, const wchar_t*, int);
+BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorW(int, const regex_tW*, wchar_t*, regsize_t);
+BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecW(const regex_tW*, const wchar_t*, regsize_t, regmatch_t*, int);
+BOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeW(regex_tW*);
+#endif
+
+#ifdef UNICODE
+#define regcomp regcompW
+#define regerror regerrorW
+#define regexec regexecW
+#define regfree regfreeW
+#define regex_t regex_tW
+#else
+#define regcomp regcompA
+#define regerror regerrorA
+#define regexec regexecA
+#define regfree regfreeA
+#define regex_t regex_tA
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+} // namespace
+#endif
+
+//
+// C++ high level wrapper goes here:
+//
+#if defined(__cplusplus)
+#include <string>
+#include <vector>
+namespace boost{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+class RegEx;
+
+namespace re_detail{
+
+class RegExData;
+struct pred1;
+struct pred2;
+struct pred3;
+struct pred4;
+
+} // namespace re_detail
+
+#if (defined(BOOST_MSVC) || defined(__BORLANDC__)) && !defined(BOOST_DISABLE_WIN32)
+typedef bool (__cdecl *GrepCallback)(const RegEx& expression);
+typedef bool (__cdecl *GrepFileCallback)(const char* file, const RegEx& expression);
+typedef bool (__cdecl *FindFilesCallback)(const char* file);
+#else
+typedef bool (*GrepCallback)(const RegEx& expression);
+typedef bool (*GrepFileCallback)(const char* file, const RegEx& expression);
+typedef bool (*FindFilesCallback)(const char* file);
+#endif
+
+class BOOST_REGEX_DECL RegEx
+{
+private:
+ re_detail::RegExData* pdata;
+public:
+ RegEx();
+ RegEx(const RegEx& o);
+ ~RegEx();
+ explicit RegEx(const char* c, bool icase = false);
+ explicit RegEx(const std::string& s, bool icase = false);
+ RegEx& operator=(const RegEx& o);
+ RegEx& operator=(const char* p);
+ RegEx& operator=(const std::string& s){ return this->operator=(s.c_str()); }
+ unsigned int SetExpression(const char* p, bool icase = false);
+ unsigned int SetExpression(const std::string& s, bool icase = false){ return SetExpression(s.c_str(), icase); }
+ std::string Expression()const;
+ unsigned int error_code()const;
+ //
+ // now matching operators:
+ //
+ bool Match(const char* p, match_flag_type flags = match_default);
+ bool Match(const std::string& s, match_flag_type flags = match_default) { return Match(s.c_str(), flags); }
+ bool Search(const char* p, match_flag_type flags = match_default);
+ bool Search(const std::string& s, match_flag_type flags = match_default) { return Search(s.c_str(), flags); }
+ unsigned int Grep(GrepCallback cb, const char* p, match_flag_type flags = match_default);
+ unsigned int Grep(GrepCallback cb, const std::string& s, match_flag_type flags = match_default) { return Grep(cb, s.c_str(), flags); }
+ unsigned int Grep(std::vector<std::string>& v, const char* p, match_flag_type flags = match_default);
+ unsigned int Grep(std::vector<std::string>& v, const std::string& s, match_flag_type flags = match_default) { return Grep(v, s.c_str(), flags); }
+ unsigned int Grep(std::vector<std::size_t>& v, const char* p, match_flag_type flags = match_default);
+ unsigned int Grep(std::vector<std::size_t>& v, const std::string& s, match_flag_type flags = match_default) { return Grep(v, s.c_str(), flags); }
+#ifndef BOOST_REGEX_NO_FILEITER
+ unsigned int GrepFiles(GrepFileCallback cb, const char* files, bool recurse = false, match_flag_type flags = match_default);
+ unsigned int GrepFiles(GrepFileCallback cb, const std::string& files, bool recurse = false, match_flag_type flags = match_default) { return GrepFiles(cb, files.c_str(), recurse, flags); }
+ unsigned int FindFiles(FindFilesCallback cb, const char* files, bool recurse = false, match_flag_type flags = match_default);
+ unsigned int FindFiles(FindFilesCallback cb, const std::string& files, bool recurse = false, match_flag_type flags = match_default) { return FindFiles(cb, files.c_str(), recurse, flags); }
+#endif
+
+ std::string Merge(const std::string& in, const std::string& fmt,
+ bool copy = true, match_flag_type flags = match_default);
+ std::string Merge(const char* in, const char* fmt,
+ bool copy = true, match_flag_type flags = match_default);
+
+ std::size_t Split(std::vector<std::string>& v, std::string& s, match_flag_type flags = match_default, unsigned max_count = ~0);
+ //
+ // now operators for returning what matched in more detail:
+ //
+ std::size_t Position(int i = 0)const;
+ std::size_t Length(int i = 0)const;
+ bool Matched(int i = 0)const;
+ std::size_t Marks()const;
+ std::string What(int i = 0)const;
+ std::string operator[](int i)const { return What(i); }
+
+ static const std::size_t npos;
+
+ friend struct re_detail::pred1;
+ friend struct re_detail::pred2;
+ friend struct re_detail::pred3;
+ friend struct re_detail::pred4;
+};
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace boost
+
+#endif
+
+#endif // include guard
+
+
+
+
+
+
+
+
+
+
diff --git a/ext/boost/regex/v4/error_type.hpp b/ext/boost/regex/v4/error_type.hpp
new file mode 100644
index 0000000000..b6633a0092
--- /dev/null
+++ b/ext/boost/regex/v4/error_type.hpp
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright (c) 2003-2005
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE error_type.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares regular expression error type enumerator.
+ */
+
+#ifndef BOOST_REGEX_ERROR_TYPE_HPP
+#define BOOST_REGEX_ERROR_TYPE_HPP
+
+#ifdef __cplusplus
+namespace boost{
+#endif
+
+#ifdef __cplusplus
+namespace regex_constants{
+
+enum error_type{
+
+ error_ok = 0, // not used
+ error_no_match = 1, // not used
+ error_bad_pattern = 2,
+ error_collate = 3,
+ error_ctype = 4,
+ error_escape = 5,
+ error_backref = 6,
+ error_brack = 7,
+ error_paren = 8,
+ error_brace = 9,
+ error_badbrace = 10,
+ error_range = 11,
+ error_space = 12,
+ error_badrepeat = 13,
+ error_end = 14, // not used
+ error_size = 15,
+ error_right_paren = 16, // not used
+ error_empty = 17,
+ error_complexity = 18,
+ error_stack = 19,
+ error_unknown = 20
+};
+
+}
+}
+#endif // __cplusplus
+
+#endif
diff --git a/ext/boost/regex/v4/fileiter.hpp b/ext/boost/regex/v4/fileiter.hpp
new file mode 100644
index 0000000000..f13c4b2fb7
--- /dev/null
+++ b/ext/boost/regex/v4/fileiter.hpp
@@ -0,0 +1,455 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE fileiter.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares various platform independent file and
+ * directory iterators, plus binary file input in
+ * the form of class map_file.
+ */
+
+#ifndef BOOST_RE_FILEITER_HPP_INCLUDED
+#define BOOST_RE_FILEITER_HPP_INCLUDED
+
+#ifndef BOOST_REGEX_CONFIG_HPP
+#include <boost/regex/config.hpp>
+#endif
+#include <boost/assert.hpp>
+
+#ifndef BOOST_REGEX_NO_FILEITER
+
+#if (defined(__CYGWIN__) || defined(__CYGWIN32__)) && !defined(BOOST_REGEX_NO_W32)
+#error "Sorry, can't mix <windows.h> with STL code and gcc compiler: if you ran configure, try again with configure --disable-ms-windows"
+#define BOOST_REGEX_FI_WIN32_MAP
+#define BOOST_REGEX_FI_POSIX_DIR
+#elif (defined(__WIN32__) || defined(_WIN32) || defined(WIN32)) && !defined(BOOST_REGEX_NO_W32)
+#define BOOST_REGEX_FI_WIN32_MAP
+#define BOOST_REGEX_FI_WIN32_DIR
+#else
+#define BOOST_REGEX_FI_POSIX_MAP
+#define BOOST_REGEX_FI_POSIX_DIR
+#endif
+
+#if defined(BOOST_REGEX_FI_WIN32_MAP)||defined(BOOST_REGEX_FI_WIN32_DIR)
+#include <windows.h>
+#endif
+
+#if defined(BOOST_REGEX_FI_WIN32_DIR)
+
+#include <cstddef>
+
+namespace boost{
+ namespace re_detail{
+
+#ifndef BOOST_NO_ANSI_APIS
+typedef WIN32_FIND_DATAA _fi_find_data;
+#else
+typedef WIN32_FIND_DATAW _fi_find_data;
+#endif
+typedef HANDLE _fi_find_handle;
+
+ } // namespace re_detail
+
+} // namespace boost
+
+#define _fi_invalid_handle INVALID_HANDLE_VALUE
+#define _fi_dir FILE_ATTRIBUTE_DIRECTORY
+
+#elif defined(BOOST_REGEX_FI_POSIX_DIR)
+
+#include <cstddef>
+#include <cstdio>
+#include <cctype>
+#include <iterator>
+#include <list>
+#include <cassert>
+#include <dirent.h>
+
+#if defined(__SUNPRO_CC)
+using std::list;
+#endif
+
+#ifndef MAX_PATH
+#define MAX_PATH 256
+#endif
+
+namespace boost{
+ namespace re_detail{
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+struct _fi_find_data
+{
+ unsigned dwFileAttributes;
+ char cFileName[MAX_PATH];
+};
+
+struct _fi_priv_data;
+
+typedef _fi_priv_data* _fi_find_handle;
+#define _fi_invalid_handle 0
+#define _fi_dir 1
+
+_fi_find_handle _fi_FindFirstFile(const char* lpFileName, _fi_find_data* lpFindFileData);
+bool _fi_FindNextFile(_fi_find_handle hFindFile, _fi_find_data* lpFindFileData);
+bool _fi_FindClose(_fi_find_handle hFindFile);
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+ } // namespace re_detail
+} // namespace boost
+
+#ifdef FindFirstFile
+ #undef FindFirstFile
+#endif
+#ifdef FindNextFile
+ #undef FindNextFile
+#endif
+#ifdef FindClose
+ #undef FindClose
+#endif
+
+#define FindFirstFileA _fi_FindFirstFile
+#define FindNextFileA _fi_FindNextFile
+#define FindClose _fi_FindClose
+
+#endif
+
+namespace boost{
+ namespace re_detail{
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+#ifdef BOOST_REGEX_FI_WIN32_MAP // win32 mapfile
+
+class BOOST_REGEX_DECL mapfile
+{
+ HANDLE hfile;
+ HANDLE hmap;
+ const char* _first;
+ const char* _last;
+public:
+
+ typedef const char* iterator;
+
+ mapfile(){ hfile = hmap = 0; _first = _last = 0; }
+ mapfile(const char* file){ hfile = hmap = 0; _first = _last = 0; open(file); }
+ ~mapfile(){ close(); }
+ void open(const char* file);
+ void close();
+ const char* begin(){ return _first; }
+ const char* end(){ return _last; }
+ size_t size(){ return _last - _first; }
+ bool valid(){ return (hfile != 0) && (hfile != INVALID_HANDLE_VALUE); }
+};
+
+
+#else
+
+class BOOST_REGEX_DECL mapfile_iterator;
+
+class BOOST_REGEX_DECL mapfile
+{
+ typedef char* pointer;
+ std::FILE* hfile;
+ long int _size;
+ pointer* _first;
+ pointer* _last;
+ mutable std::list<pointer*> condemed;
+ enum sizes
+ {
+ buf_size = 4096
+ };
+ void lock(pointer* node)const;
+ void unlock(pointer* node)const;
+public:
+
+ typedef mapfile_iterator iterator;
+
+ mapfile(){ hfile = 0; _size = 0; _first = _last = 0; }
+ mapfile(const char* file){ hfile = 0; _size = 0; _first = _last = 0; open(file); }
+ ~mapfile(){ close(); }
+ void open(const char* file);
+ void close();
+ iterator begin()const;
+ iterator end()const;
+ unsigned long size()const{ return _size; }
+ bool valid()const{ return hfile != 0; }
+ friend class mapfile_iterator;
+};
+
+class BOOST_REGEX_DECL mapfile_iterator
+#if !defined(BOOST_NO_STD_ITERATOR) || defined(BOOST_MSVC_STD_ITERATOR)
+: public std::iterator<std::random_access_iterator_tag, char>
+#endif
+{
+ typedef mapfile::pointer internal_pointer;
+ internal_pointer* node;
+ const mapfile* file;
+ unsigned long offset;
+ long position()const
+ {
+ return file ? ((node - file->_first) * mapfile::buf_size + offset) : 0;
+ }
+ void position(long pos)
+ {
+ if(file)
+ {
+ node = file->_first + (pos / mapfile::buf_size);
+ offset = pos % mapfile::buf_size;
+ }
+ }
+public:
+ typedef std::ptrdiff_t difference_type;
+ typedef char value_type;
+ typedef const char* pointer;
+ typedef const char& reference;
+ typedef std::random_access_iterator_tag iterator_category;
+
+ mapfile_iterator() { node = 0; file = 0; offset = 0; }
+ mapfile_iterator(const mapfile* f, long arg_position)
+ {
+ file = f;
+ node = f->_first + arg_position / mapfile::buf_size;
+ offset = arg_position % mapfile::buf_size;
+ if(file)
+ file->lock(node);
+ }
+ mapfile_iterator(const mapfile_iterator& i)
+ {
+ file = i.file;
+ node = i.node;
+ offset = i.offset;
+ if(file)
+ file->lock(node);
+ }
+ ~mapfile_iterator()
+ {
+ if(file && node)
+ file->unlock(node);
+ }
+ mapfile_iterator& operator = (const mapfile_iterator& i);
+ char operator* ()const
+ {
+ BOOST_ASSERT(node >= file->_first);
+ BOOST_ASSERT(node < file->_last);
+ return file ? *(*node + sizeof(int) + offset) : char(0);
+ }
+ char operator[] (long off)const
+ {
+ mapfile_iterator tmp(*this);
+ tmp += off;
+ return *tmp;
+ }
+ mapfile_iterator& operator++ ();
+ mapfile_iterator operator++ (int);
+ mapfile_iterator& operator-- ();
+ mapfile_iterator operator-- (int);
+
+ mapfile_iterator& operator += (long off)
+ {
+ position(position() + off);
+ return *this;
+ }
+ mapfile_iterator& operator -= (long off)
+ {
+ position(position() - off);
+ return *this;
+ }
+
+ friend inline bool operator==(const mapfile_iterator& i, const mapfile_iterator& j)
+ {
+ return (i.file == j.file) && (i.node == j.node) && (i.offset == j.offset);
+ }
+
+ friend inline bool operator!=(const mapfile_iterator& i, const mapfile_iterator& j)
+ {
+ return !(i == j);
+ }
+
+ friend inline bool operator<(const mapfile_iterator& i, const mapfile_iterator& j)
+ {
+ return i.position() < j.position();
+ }
+ friend inline bool operator>(const mapfile_iterator& i, const mapfile_iterator& j)
+ {
+ return i.position() > j.position();
+ }
+ friend inline bool operator<=(const mapfile_iterator& i, const mapfile_iterator& j)
+ {
+ return i.position() <= j.position();
+ }
+ friend inline bool operator>=(const mapfile_iterator& i, const mapfile_iterator& j)
+ {
+ return i.position() >= j.position();
+ }
+
+ friend mapfile_iterator operator + (const mapfile_iterator& i, long off);
+ friend mapfile_iterator operator + (long off, const mapfile_iterator& i)
+ {
+ mapfile_iterator tmp(i);
+ return tmp += off;
+ }
+ friend mapfile_iterator operator - (const mapfile_iterator& i, long off);
+ friend inline long operator - (const mapfile_iterator& i, const mapfile_iterator& j)
+ {
+ return i.position() - j.position();
+ }
+};
+
+#endif
+
+// _fi_sep determines the directory separator, either '\\' or '/'
+BOOST_REGEX_DECL extern const char* _fi_sep;
+
+struct file_iterator_ref
+{
+ _fi_find_handle hf;
+ _fi_find_data _data;
+ long count;
+};
+
+
+class BOOST_REGEX_DECL file_iterator
+{
+ char* _root;
+ char* _path;
+ char* ptr;
+ file_iterator_ref* ref;
+
+public:
+ typedef std::ptrdiff_t difference_type;
+ typedef const char* value_type;
+ typedef const char** pointer;
+ typedef const char*& reference;
+ typedef std::input_iterator_tag iterator_category;
+
+ file_iterator();
+ file_iterator(const char* wild);
+ ~file_iterator();
+ file_iterator(const file_iterator&);
+ file_iterator& operator=(const file_iterator&);
+ const char* root()const { return _root; }
+ const char* path()const { return _path; }
+ const char* name()const { return ptr; }
+ _fi_find_data* data() { return &(ref->_data); }
+ void next();
+ file_iterator& operator++() { next(); return *this; }
+ file_iterator operator++(int);
+ const char* operator*() { return path(); }
+
+ friend inline bool operator == (const file_iterator& f1, const file_iterator& f2)
+ {
+ return ((f1.ref->hf == _fi_invalid_handle) && (f2.ref->hf == _fi_invalid_handle));
+ }
+
+ friend inline bool operator != (const file_iterator& f1, const file_iterator& f2)
+ {
+ return !(f1 == f2);
+ }
+
+};
+
+// dwa 9/13/00 - suppress unused parameter warning
+inline bool operator < (const file_iterator&, const file_iterator&)
+{
+ return false;
+}
+
+
+class BOOST_REGEX_DECL directory_iterator
+{
+ char* _root;
+ char* _path;
+ char* ptr;
+ file_iterator_ref* ref;
+
+public:
+ typedef std::ptrdiff_t difference_type;
+ typedef const char* value_type;
+ typedef const char** pointer;
+ typedef const char*& reference;
+ typedef std::input_iterator_tag iterator_category;
+
+ directory_iterator();
+ directory_iterator(const char* wild);
+ ~directory_iterator();
+ directory_iterator(const directory_iterator& other);
+ directory_iterator& operator=(const directory_iterator& other);
+
+ const char* root()const { return _root; }
+ const char* path()const { return _path; }
+ const char* name()const { return ptr; }
+ _fi_find_data* data() { return &(ref->_data); }
+ void next();
+ directory_iterator& operator++() { next(); return *this; }
+ directory_iterator operator++(int);
+ const char* operator*() { return path(); }
+
+ static const char* separator() { return _fi_sep; }
+
+ friend inline bool operator == (const directory_iterator& f1, const directory_iterator& f2)
+ {
+ return ((f1.ref->hf == _fi_invalid_handle) && (f2.ref->hf == _fi_invalid_handle));
+ }
+
+
+ friend inline bool operator != (const directory_iterator& f1, const directory_iterator& f2)
+ {
+ return !(f1 == f2);
+ }
+
+ };
+
+inline bool operator < (const directory_iterator&, const directory_iterator&)
+{
+ return false;
+}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+
+} // namespace re_detail
+using boost::re_detail::directory_iterator;
+using boost::re_detail::file_iterator;
+using boost::re_detail::mapfile;
+} // namespace boost
+
+#endif // BOOST_REGEX_NO_FILEITER
+#endif // BOOST_RE_FILEITER_HPP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ext/boost/regex/v4/instances.hpp b/ext/boost/regex/v4/instances.hpp
new file mode 100644
index 0000000000..d12dc6b270
--- /dev/null
+++ b/ext/boost/regex/v4/instances.hpp
@@ -0,0 +1,215 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE instances.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Defines those template instances that are placed in the
+ * library rather than in the users object files.
+ */
+
+//
+// note no include guard, we may include this multiple times:
+//
+#ifndef BOOST_REGEX_NO_EXTERNAL_TEMPLATES
+
+namespace boost{
+
+//
+// this header can be included multiple times, each time with
+// a different character type, BOOST_REGEX_CHAR_T must be defined
+// first:
+//
+#ifndef BOOST_REGEX_CHAR_T
+# error "BOOST_REGEX_CHAR_T not defined"
+#endif
+
+#ifndef BOOST_REGEX_TRAITS_T
+# define BOOST_REGEX_TRAITS_T , boost::regex_traits<BOOST_REGEX_CHAR_T >
+#endif
+
+//
+// what follows is compiler specific:
+//
+
+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x600)
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+# ifndef BOOST_REGEX_INSTANTIATE
+# pragma option push -Jgx
+# endif
+
+template class BOOST_REGEX_DECL basic_regex< BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >;
+template class BOOST_REGEX_DECL match_results< const BOOST_REGEX_CHAR_T* >;
+#ifndef BOOST_NO_STD_ALLOCATOR
+template class BOOST_REGEX_DECL ::boost::re_detail::perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type BOOST_REGEX_TRAITS_T >;
+#endif
+
+# ifndef BOOST_REGEX_INSTANTIATE
+# pragma option pop
+# endif
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#elif defined(BOOST_MSVC) || defined(__ICL)
+
+# ifndef BOOST_REGEX_INSTANTIATE
+# ifdef __GNUC__
+# define template __extension__ extern template
+# else
+# if BOOST_MSVC > 1310
+# define BOOST_REGEX_TEMPLATE_DECL
+# endif
+# define template extern template
+# endif
+# endif
+
+#ifndef BOOST_REGEX_TEMPLATE_DECL
+# define BOOST_REGEX_TEMPLATE_DECL BOOST_REGEX_DECL
+#endif
+
+# ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable : 4251 4231 4660)
+# endif
+
+template class BOOST_REGEX_TEMPLATE_DECL basic_regex< BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >;
+
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+template class BOOST_REGEX_TEMPLATE_DECL match_results< const BOOST_REGEX_CHAR_T* >;
+#endif
+#ifndef BOOST_NO_STD_ALLOCATOR
+template class BOOST_REGEX_TEMPLATE_DECL ::boost::re_detail::perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type BOOST_REGEX_TRAITS_T >;
+#endif
+#if !(defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB <= 1))\
+ && !(defined(BOOST_INTEL_CXX_VERSION) && (BOOST_INTEL_CXX_VERSION <= 800))\
+ && !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))\
+ && !defined(BOOST_REGEX_ICU_INSTANCES)
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+template class BOOST_REGEX_TEMPLATE_DECL match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >;
+#endif
+#ifndef BOOST_NO_STD_ALLOCATOR
+template class BOOST_REGEX_TEMPLATE_DECL ::boost::re_detail::perl_matcher< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >;
+#endif
+#endif
+
+
+# ifdef BOOST_MSVC
+# pragma warning(pop)
+# endif
+
+# ifdef template
+# undef template
+# endif
+
+#undef BOOST_REGEX_TEMPLATE_DECL
+
+#elif (defined(__GNUC__) && (__GNUC__ >= 3))
+
+# ifndef BOOST_REGEX_INSTANTIATE
+# define template __extension__ extern template
+# endif
+
+#if !defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_REGEX_ICU_INSTANCES)
+namespace re_detail{
+template BOOST_REGEX_DECL
+std::locale cpp_regex_traits_base<BOOST_REGEX_CHAR_T>::imbue(const std::locale& l);
+
+template BOOST_REGEX_DECL
+cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::string_type
+ cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::transform_primary(const BOOST_REGEX_CHAR_T* p1, const BOOST_REGEX_CHAR_T* p2) const;
+template BOOST_REGEX_DECL
+cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::string_type
+ cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::transform(const BOOST_REGEX_CHAR_T* p1, const BOOST_REGEX_CHAR_T* p2) const;
+template BOOST_REGEX_DECL
+cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::string_type
+ cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::lookup_collatename(const BOOST_REGEX_CHAR_T* p1, const BOOST_REGEX_CHAR_T* p2) const;
+template BOOST_REGEX_DECL
+void cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::init();
+template BOOST_REGEX_DECL
+cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::char_class_type
+ cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::lookup_classname_imp(const BOOST_REGEX_CHAR_T* p1, const BOOST_REGEX_CHAR_T* p2) const;
+#ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
+template BOOST_REGEX_DECL
+bool cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::isctype(const BOOST_REGEX_CHAR_T c, char_class_type mask) const;
+#endif
+} // namespace
+template BOOST_REGEX_DECL
+int cpp_regex_traits<BOOST_REGEX_CHAR_T>::toi(const BOOST_REGEX_CHAR_T*& first, const BOOST_REGEX_CHAR_T* last, int radix)const;
+template BOOST_REGEX_DECL
+std::string cpp_regex_traits<BOOST_REGEX_CHAR_T>::catalog_name(const std::string& name);
+template BOOST_REGEX_DECL
+std::string& cpp_regex_traits<BOOST_REGEX_CHAR_T>::get_catalog_name_inst();
+template BOOST_REGEX_DECL
+std::string cpp_regex_traits<BOOST_REGEX_CHAR_T>::get_catalog_name();
+#ifdef BOOST_HAS_THREADS
+template BOOST_REGEX_DECL
+static_mutex& cpp_regex_traits<BOOST_REGEX_CHAR_T>::get_mutex_inst();
+#endif
+#endif
+
+template BOOST_REGEX_DECL basic_regex<BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >&
+ basic_regex<BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >::do_assign(
+ const BOOST_REGEX_CHAR_T* p1,
+ const BOOST_REGEX_CHAR_T* p2,
+ flag_type f);
+template BOOST_REGEX_DECL basic_regex<BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >::locale_type BOOST_REGEX_CALL
+ basic_regex<BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >::imbue(locale_type l);
+
+template BOOST_REGEX_DECL void BOOST_REGEX_CALL
+ match_results<const BOOST_REGEX_CHAR_T*>::maybe_assign(
+ const match_results<const BOOST_REGEX_CHAR_T*>& m);
+
+namespace re_detail{
+template BOOST_REGEX_DECL void perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type BOOST_REGEX_TRAITS_T >::construct_init(
+ const basic_regex<BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >& e, match_flag_type f);
+template BOOST_REGEX_DECL bool perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type BOOST_REGEX_TRAITS_T >::match();
+template BOOST_REGEX_DECL bool perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type BOOST_REGEX_TRAITS_T >::find();
+} // namespace
+
+#if (defined(__GLIBCPP__) || defined(__GLIBCXX__)) \
+ && !defined(BOOST_REGEX_ICU_INSTANCES)\
+ && !defined(__SGI_STL_PORT)\
+ && !defined(_STLPORT_VERSION)
+// std:basic_string<>::const_iterator instances as well:
+template BOOST_REGEX_DECL void BOOST_REGEX_CALL
+ match_results<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator>::maybe_assign(
+ const match_results<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator>& m);
+
+namespace re_detail{
+template BOOST_REGEX_DECL void perl_matcher<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >::construct_init(
+ const basic_regex<BOOST_REGEX_CHAR_T>& e, match_flag_type f);
+template BOOST_REGEX_DECL bool perl_matcher<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >::match();
+template BOOST_REGEX_DECL bool perl_matcher<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >::find();
+} // namespace
+#endif
+
+# ifdef template
+# undef template
+# endif
+
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_REGEX_NO_EXTERNAL_TEMPLATES
+
+
+
+
+
diff --git a/ext/boost/regex/v4/iterator_category.hpp b/ext/boost/regex/v4/iterator_category.hpp
new file mode 100644
index 0000000000..9e40142378
--- /dev/null
+++ b/ext/boost/regex/v4/iterator_category.hpp
@@ -0,0 +1,91 @@
+/*
+ *
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_match.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Iterator traits for selecting an iterator type as
+ * an integral constant expression.
+ */
+
+
+#ifndef BOOST_REGEX_ITERATOR_CATEGORY_HPP
+#define BOOST_REGEX_ITERATOR_CATEGORY_HPP
+
+#include <iterator>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+
+namespace boost{
+namespace detail{
+
+template <class I>
+struct is_random_imp
+{
+#ifndef BOOST_NO_STD_ITERATOR_TRAITS
+private:
+ typedef typename std::iterator_traits<I>::iterator_category cat;
+public:
+ BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible<cat*, std::random_access_iterator_tag*>::value));
+#else
+ BOOST_STATIC_CONSTANT(bool, value = false);
+#endif
+};
+
+template <class I>
+struct is_random_pointer_imp
+{
+ BOOST_STATIC_CONSTANT(bool, value = true);
+};
+
+template <bool is_pointer_type>
+struct is_random_imp_selector
+{
+ template <class I>
+ struct rebind
+ {
+ typedef is_random_imp<I> type;
+ };
+};
+
+template <>
+struct is_random_imp_selector<true>
+{
+ template <class I>
+ struct rebind
+ {
+ typedef is_random_pointer_imp<I> type;
+ };
+};
+
+}
+
+template <class I>
+struct is_random_access_iterator
+{
+private:
+ typedef detail::is_random_imp_selector< ::boost::is_pointer<I>::value> selector;
+ typedef typename selector::template rebind<I> bound_type;
+ typedef typename bound_type::type answer;
+public:
+ BOOST_STATIC_CONSTANT(bool, value = answer::value);
+};
+
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+template <class I>
+const bool is_random_access_iterator<I>::value;
+#endif
+
+}
+
+#endif
+
diff --git a/ext/boost/regex/v4/iterator_traits.hpp b/ext/boost/regex/v4/iterator_traits.hpp
new file mode 100644
index 0000000000..f7afacb17b
--- /dev/null
+++ b/ext/boost/regex/v4/iterator_traits.hpp
@@ -0,0 +1,135 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE iterator_traits.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares iterator traits workarounds.
+ */
+
+#ifndef BOOST_REGEX_V4_ITERATOR_TRAITS_HPP
+#define BOOST_REGEX_V4_ITERATOR_TRAITS_HPP
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace boost{
+namespace re_detail{
+
+#if defined(BOOST_NO_STD_ITERATOR_TRAITS) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+template <class T>
+struct regex_iterator_traits
+{
+ typedef typename T::iterator_category iterator_category;
+ typedef typename T::value_type value_type;
+#if !defined(BOOST_NO_STD_ITERATOR)
+ typedef typename T::difference_type difference_type;
+ typedef typename T::pointer pointer;
+ typedef typename T::reference reference;
+#else
+ typedef std::ptrdiff_t difference_type;
+ typedef value_type* pointer;
+ typedef value_type& reference;
+#endif
+};
+
+template <class T>
+struct pointer_iterator_traits
+{
+ typedef std::ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef T* pointer;
+ typedef T& reference;
+ typedef std::random_access_iterator_tag iterator_category;
+};
+template <class T>
+struct const_pointer_iterator_traits
+{
+ typedef std::ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef const T* pointer;
+ typedef const T& reference;
+ typedef std::random_access_iterator_tag iterator_category;
+};
+
+template<>
+struct regex_iterator_traits<char*> : pointer_iterator_traits<char>{};
+template<>
+struct regex_iterator_traits<const char*> : const_pointer_iterator_traits<char>{};
+template<>
+struct regex_iterator_traits<wchar_t*> : pointer_iterator_traits<wchar_t>{};
+template<>
+struct regex_iterator_traits<const wchar_t*> : const_pointer_iterator_traits<wchar_t>{};
+//
+// the follwoing are needed for ICU support:
+//
+template<>
+struct regex_iterator_traits<unsigned char*> : pointer_iterator_traits<char>{};
+template<>
+struct regex_iterator_traits<const unsigned char*> : const_pointer_iterator_traits<char>{};
+template<>
+struct regex_iterator_traits<int*> : pointer_iterator_traits<int>{};
+template<>
+struct regex_iterator_traits<const int*> : const_pointer_iterator_traits<int>{};
+
+#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
+template<>
+struct regex_iterator_traits<unsigned short*> : pointer_iterator_traits<unsigned short>{};
+template<>
+struct regex_iterator_traits<const unsigned short*> : const_pointer_iterator_traits<unsigned short>{};
+#endif
+
+#if defined(__SGI_STL_PORT) && defined(__STL_DEBUG)
+template<>
+struct regex_iterator_traits<std::string::iterator> : pointer_iterator_traits<char>{};
+template<>
+struct regex_iterator_traits<std::string::const_iterator> : const_pointer_iterator_traits<char>{};
+#ifndef BOOST_NO_STD_WSTRING
+template<>
+struct regex_iterator_traits<std::wstring::iterator> : pointer_iterator_traits<wchar_t>{};
+template<>
+struct regex_iterator_traits<std::wstring::const_iterator> : const_pointer_iterator_traits<wchar_t>{};
+#endif // BOOST_NO_WSTRING
+#endif // stport
+
+#else
+
+template <class T>
+struct regex_iterator_traits : public std::iterator_traits<T> {};
+
+#endif
+
+} // namespace re_detail
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/ext/boost/regex/v4/match_flags.hpp b/ext/boost/regex/v4/match_flags.hpp
new file mode 100644
index 0000000000..9585aca8b2
--- /dev/null
+++ b/ext/boost/regex/v4/match_flags.hpp
@@ -0,0 +1,138 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE match_flags.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares match_flags type.
+ */
+
+#ifndef BOOST_REGEX_V4_MATCH_FLAGS
+#define BOOST_REGEX_V4_MATCH_FLAGS
+
+#ifdef __cplusplus
+# include <boost/cstdint.hpp>
+#endif
+
+#ifdef __cplusplus
+namespace boost{
+ namespace regex_constants{
+#endif
+
+typedef enum _match_flags
+{
+ match_default = 0,
+ match_not_bol = 1, // first is not start of line
+ match_not_eol = match_not_bol << 1, // last is not end of line
+ match_not_bob = match_not_eol << 1, // first is not start of buffer
+ match_not_eob = match_not_bob << 1, // last is not end of buffer
+ match_not_bow = match_not_eob << 1, // first is not start of word
+ match_not_eow = match_not_bow << 1, // last is not end of word
+ match_not_dot_newline = match_not_eow << 1, // \n is not matched by '.'
+ match_not_dot_null = match_not_dot_newline << 1, // '\0' is not matched by '.'
+ match_prev_avail = match_not_dot_null << 1, // *--first is a valid expression
+ match_init = match_prev_avail << 1, // internal use
+ match_any = match_init << 1, // don't care what we match
+ match_not_null = match_any << 1, // string can't be null
+ match_continuous = match_not_null << 1, // each grep match must continue from
+ // uninterupted from the previous one
+ match_partial = match_continuous << 1, // find partial matches
+
+ match_stop = match_partial << 1, // stop after first match (grep) V3 only
+ match_not_initial_null = match_stop, // don't match initial null, V4 only
+ match_all = match_stop << 1, // must find the whole of input even if match_any is set
+ match_perl = match_all << 1, // Use perl matching rules
+ match_posix = match_perl << 1, // Use POSIX matching rules
+ match_nosubs = match_posix << 1, // don't trap marked subs
+ match_extra = match_nosubs << 1, // include full capture information for repeated captures
+ match_single_line = match_extra << 1, // treat text as single line and ignor any \n's when matching ^ and $.
+ match_unused1 = match_single_line << 1, // unused
+ match_unused2 = match_unused1 << 1, // unused
+ match_unused3 = match_unused2 << 1, // unused
+ match_max = match_unused3,
+
+ format_perl = 0, // perl style replacement
+ format_default = 0, // ditto.
+ format_sed = match_max << 1, // sed style replacement.
+ format_all = format_sed << 1, // enable all extentions to sytax.
+ format_no_copy = format_all << 1, // don't copy non-matching segments.
+ format_first_only = format_no_copy << 1, // Only replace first occurance.
+ format_is_if = format_first_only << 1, // internal use only.
+ format_literal = format_is_if << 1 // treat string as a literal
+
+} match_flags;
+
+#if (defined(_MSC_VER) && (_MSC_VER < 1300)) || defined(__BORLANDC__)
+typedef unsigned long match_flag_type;
+#else
+typedef match_flags match_flag_type;
+
+
+#ifdef __cplusplus
+inline match_flags operator&(match_flags m1, match_flags m2)
+{ return static_cast<match_flags>(static_cast<boost::int32_t>(m1) & static_cast<boost::int32_t>(m2)); }
+inline match_flags operator|(match_flags m1, match_flags m2)
+{ return static_cast<match_flags>(static_cast<boost::int32_t>(m1) | static_cast<boost::int32_t>(m2)); }
+inline match_flags operator^(match_flags m1, match_flags m2)
+{ return static_cast<match_flags>(static_cast<boost::int32_t>(m1) ^ static_cast<boost::int32_t>(m2)); }
+inline match_flags operator~(match_flags m1)
+{ return static_cast<match_flags>(~static_cast<boost::int32_t>(m1)); }
+inline match_flags& operator&=(match_flags& m1, match_flags m2)
+{ m1 = m1&m2; return m1; }
+inline match_flags& operator|=(match_flags& m1, match_flags m2)
+{ m1 = m1|m2; return m1; }
+inline match_flags& operator^=(match_flags& m1, match_flags m2)
+{ m1 = m1^m2; return m1; }
+#endif
+#endif
+
+#ifdef __cplusplus
+} // namespace regex_constants
+//
+// import names into boost for backwards compatiblity:
+//
+using regex_constants::match_flag_type;
+using regex_constants::match_default;
+using regex_constants::match_not_bol;
+using regex_constants::match_not_eol;
+using regex_constants::match_not_bob;
+using regex_constants::match_not_eob;
+using regex_constants::match_not_bow;
+using regex_constants::match_not_eow;
+using regex_constants::match_not_dot_newline;
+using regex_constants::match_not_dot_null;
+using regex_constants::match_prev_avail;
+//using regex_constants::match_init;
+using regex_constants::match_any;
+using regex_constants::match_not_null;
+using regex_constants::match_continuous;
+using regex_constants::match_partial;
+//using regex_constants::match_stop;
+using regex_constants::match_all;
+using regex_constants::match_perl;
+using regex_constants::match_posix;
+using regex_constants::match_nosubs;
+using regex_constants::match_extra;
+using regex_constants::match_single_line;
+//using regex_constants::match_max;
+using regex_constants::format_all;
+using regex_constants::format_sed;
+using regex_constants::format_perl;
+using regex_constants::format_default;
+using regex_constants::format_no_copy;
+using regex_constants::format_first_only;
+//using regex_constants::format_is_if;
+
+} // namespace boost
+#endif // __cplusplus
+#endif // include guard
+
diff --git a/ext/boost/regex/v4/match_results.hpp b/ext/boost/regex/v4/match_results.hpp
new file mode 100644
index 0000000000..09dd31f009
--- /dev/null
+++ b/ext/boost/regex/v4/match_results.hpp
@@ -0,0 +1,579 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE match_results.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares template class match_results.
+ */
+
+#ifndef BOOST_REGEX_V4_MATCH_RESULTS_HPP
+#define BOOST_REGEX_V4_MATCH_RESULTS_HPP
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace boost{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4251 4231 4660)
+#endif
+
+namespace re_detail{
+
+template <class charT>
+class named_subexpressions;
+
+}
+
+template <class BidiIterator, class Allocator>
+class match_results
+{
+private:
+#ifndef BOOST_NO_STD_ALLOCATOR
+ typedef std::vector<sub_match<BidiIterator>, Allocator> vector_type;
+#else
+ typedef std::vector<sub_match<BidiIterator> > vector_type;
+#endif
+public:
+ typedef sub_match<BidiIterator> value_type;
+#if !defined(BOOST_NO_STD_ALLOCATOR) && !(defined(BOOST_MSVC) && defined(_STLPORT_VERSION))
+ typedef typename Allocator::const_reference const_reference;
+#else
+ typedef const value_type& const_reference;
+#endif
+ typedef const_reference reference;
+ typedef typename vector_type::const_iterator const_iterator;
+ typedef const_iterator iterator;
+ typedef typename re_detail::regex_iterator_traits<
+ BidiIterator>::difference_type difference_type;
+ typedef typename Allocator::size_type size_type;
+ typedef Allocator allocator_type;
+ typedef typename re_detail::regex_iterator_traits<
+ BidiIterator>::value_type char_type;
+ typedef std::basic_string<char_type> string_type;
+ typedef re_detail::named_subexpressions_base<char_type> named_sub_type;
+
+ // construct/copy/destroy:
+ explicit match_results(const Allocator& a = Allocator())
+#ifndef BOOST_NO_STD_ALLOCATOR
+ : m_subs(a), m_base(), m_last_closed_paren(0) {}
+#else
+ : m_subs(), m_base(), m_last_closed_paren(0) { (void)a; }
+#endif
+ match_results(const match_results& m)
+ : m_subs(m.m_subs), m_base(m.m_base) {}
+ match_results& operator=(const match_results& m)
+ {
+ m_subs = m.m_subs;
+ m_base = m.m_base;
+ return *this;
+ }
+ ~match_results(){}
+
+ // size:
+ size_type size() const
+ { return empty() ? 0 : m_subs.size() - 2; }
+ size_type max_size() const
+ { return m_subs.max_size(); }
+ bool empty() const
+ { return m_subs.size() < 2; }
+ // element access:
+ difference_type length(int sub = 0) const
+ {
+ sub += 2;
+ if((sub < (int)m_subs.size()) && (sub > 0))
+ return m_subs[sub].length();
+ return 0;
+ }
+ difference_type length(const char_type* sub) const
+ {
+ const char_type* end = sub;
+ while(*end) ++end;
+ return length(named_subexpression_index(sub, end));
+ }
+ template <class charT>
+ difference_type length(const charT* sub) const
+ {
+ const charT* end = sub;
+ while(*end) ++end;
+ return length(named_subexpression_index(sub, end));
+ }
+ template <class charT, class Traits, class A>
+ difference_type length(const std::basic_string<charT, Traits, A>& sub) const
+ {
+ return length(sub.c_str());
+ }
+ difference_type position(size_type sub = 0) const
+ {
+ sub += 2;
+ if(sub < m_subs.size())
+ {
+ const sub_match<BidiIterator>& s = m_subs[sub];
+ if(s.matched || (sub == 2))
+ {
+ return ::boost::re_detail::distance((BidiIterator)(m_base), (BidiIterator)(s.first));
+ }
+ }
+ return ~static_cast<difference_type>(0);
+ }
+ difference_type position(const char_type* sub) const
+ {
+ const char_type* end = sub;
+ while(*end) ++end;
+ return position(named_subexpression_index(sub, end));
+ }
+ template <class charT>
+ difference_type position(const charT* sub) const
+ {
+ const charT* end = sub;
+ while(*end) ++end;
+ return position(named_subexpression_index(sub, end));
+ }
+ template <class charT, class Traits, class A>
+ difference_type position(const std::basic_string<charT, Traits, A>& sub) const
+ {
+ return position(sub.c_str());
+ }
+ string_type str(int sub = 0) const
+ {
+ sub += 2;
+ string_type result;
+ if(sub < (int)m_subs.size() && (sub > 0))
+ {
+ const sub_match<BidiIterator>& s = m_subs[sub];
+ if(s.matched)
+ {
+ result = s.str();
+ }
+ }
+ return result;
+ }
+ string_type str(const char_type* sub) const
+ {
+ return (*this)[sub].str();
+ }
+ template <class Traits, class A>
+ string_type str(const std::basic_string<char_type, Traits, A>& sub) const
+ {
+ return (*this)[sub].str();
+ }
+ template <class charT>
+ string_type str(const charT* sub) const
+ {
+ return (*this)[sub].str();
+ }
+ template <class charT, class Traits, class A>
+ string_type str(const std::basic_string<charT, Traits, A>& sub) const
+ {
+ return (*this)[sub].str();
+ }
+ const_reference operator[](int sub) const
+ {
+ sub += 2;
+ if(sub < (int)m_subs.size() && (sub >= 0))
+ {
+ return m_subs[sub];
+ }
+ return m_null;
+ }
+ //
+ // Named sub-expressions:
+ //
+ const_reference named_subexpression(const char_type* i, const char_type* j) const
+ {
+ int index = m_named_subs->get_id(i, j);
+ return index > 0 ? (*this)[index] : m_null;
+ }
+ template <class charT>
+ const_reference named_subexpression(const charT* i, const charT* j) const
+ {
+ BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
+ if(i == j)
+ return m_null;
+ std::vector<char_type> s;
+ while(i != j)
+ s.insert(s.end(), *i++);
+ return named_subexpression(&*s.begin(), &*s.begin() + s.size());
+ }
+ int named_subexpression_index(const char_type* i, const char_type* j) const
+ {
+ int index = m_named_subs->get_id(i, j);
+ return index > 0 ? index : -20;
+ }
+ template <class charT>
+ int named_subexpression_index(const charT* i, const charT* j) const
+ {
+ BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
+ if(i == j)
+ return -20;
+ std::vector<char_type> s;
+ while(i != j)
+ s.insert(s.end(), *i++);
+ return named_subexpression_index(&*s.begin(), &*s.begin() + s.size());
+ }
+ template <class Traits, class A>
+ const_reference operator[](const std::basic_string<char_type, Traits, A>& s) const
+ {
+ return named_subexpression(s.c_str(), s.c_str() + s.size());
+ }
+ const_reference operator[](const char_type* p) const
+ {
+ const char_type* e = p;
+ while(*e) ++e;
+ return named_subexpression(p, e);
+ }
+
+ template <class charT>
+ const_reference operator[](const charT* p) const
+ {
+ BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
+ if(*p == 0)
+ return m_null;
+ std::vector<char_type> s;
+ while(*p)
+ s.insert(s.end(), *p++);
+ return named_subexpression(&*s.begin(), &*s.begin() + s.size());
+ }
+ template <class charT, class Traits, class A>
+ const_reference operator[](const std::basic_string<charT, Traits, A>& ns) const
+ {
+ BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
+ if(ns.empty())
+ return m_null;
+ std::vector<char_type> s;
+ for(unsigned i = 0; i < ns.size(); ++i)
+ s.insert(s.end(), ns[i]);
+ return named_subexpression(&*s.begin(), &*s.begin() + s.size());
+ }
+
+ const_reference prefix() const
+ {
+ return (*this)[-1];
+ }
+
+ const_reference suffix() const
+ {
+ return (*this)[-2];
+ }
+ const_iterator begin() const
+ {
+ return (m_subs.size() > 2) ? (m_subs.begin() + 2) : m_subs.end();
+ }
+ const_iterator end() const
+ {
+ return m_subs.end();
+ }
+ // format:
+ template <class OutputIterator>
+ OutputIterator format(OutputIterator out,
+ const string_type& fmt,
+ match_flag_type flags = format_default) const
+ {
+ re_detail::trivial_format_traits<char_type> traits;
+ return re_detail::regex_format_imp(out, *this, fmt.data(), fmt.data() + fmt.size(), flags, traits);
+ }
+ string_type format(const string_type& fmt,
+ match_flag_type flags = format_default) const
+ {
+ string_type result;
+ re_detail::string_out_iterator<string_type> i(result);
+ re_detail::trivial_format_traits<char_type> traits;
+ re_detail::regex_format_imp(i, *this, fmt.data(), fmt.data() + fmt.size(), flags, traits);
+ return result;
+ }
+ // format with locale:
+ template <class OutputIterator, class RegexT>
+ OutputIterator format(OutputIterator out,
+ const string_type& fmt,
+ match_flag_type flags,
+ const RegexT& re) const
+ {
+ return ::boost::re_detail::regex_format_imp(out, *this, fmt.data(), fmt.data() + fmt.size(), flags, re.get_traits());
+ }
+ template <class RegexT>
+ string_type format(const string_type& fmt,
+ match_flag_type flags,
+ const RegexT& re) const
+ {
+ string_type result;
+ re_detail::string_out_iterator<string_type> i(result);
+ ::boost::re_detail::regex_format_imp(i, *this, fmt.data(), fmt.data() + fmt.size(), flags, re.get_traits());
+ return result;
+ }
+ const_reference get_last_closed_paren()const
+ {
+ return m_last_closed_paren == 0 ? m_null : (*this)[m_last_closed_paren];
+ }
+
+ allocator_type get_allocator() const
+ {
+#ifndef BOOST_NO_STD_ALLOCATOR
+ return m_subs.get_allocator();
+#else
+ return allocator_type();
+#endif
+ }
+ void swap(match_results& that)
+ {
+ std::swap(m_subs, that.m_subs);
+ std::swap(m_base, that.m_base);
+ }
+ bool operator==(const match_results& that)const
+ {
+ return (m_subs == that.m_subs) && (m_base == that.m_base);
+ }
+ bool operator!=(const match_results& that)const
+ { return !(*this == that); }
+
+#ifdef BOOST_REGEX_MATCH_EXTRA
+ typedef typename sub_match<BidiIterator>::capture_sequence_type capture_sequence_type;
+
+ const capture_sequence_type& captures(int i)const
+ {
+ return (*this)[i].captures();
+ }
+#endif
+
+ //
+ // private access functions:
+ void BOOST_REGEX_CALL set_second(BidiIterator i)
+ {
+ BOOST_ASSERT(m_subs.size() > 2);
+ m_subs[2].second = i;
+ m_subs[2].matched = true;
+ m_subs[0].first = i;
+ m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
+ m_null.first = i;
+ m_null.second = i;
+ m_null.matched = false;
+ }
+
+ void BOOST_REGEX_CALL set_second(BidiIterator i, size_type pos, bool m = true, bool escape_k = false)
+ {
+ if(pos)
+ m_last_closed_paren = pos;
+ pos += 2;
+ BOOST_ASSERT(m_subs.size() > pos);
+ m_subs[pos].second = i;
+ m_subs[pos].matched = m;
+ if((pos == 2) && !escape_k)
+ {
+ m_subs[0].first = i;
+ m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
+ m_null.first = i;
+ m_null.second = i;
+ m_null.matched = false;
+ }
+ }
+ void BOOST_REGEX_CALL set_size(size_type n, BidiIterator i, BidiIterator j)
+ {
+ value_type v(j);
+ size_type len = m_subs.size();
+ if(len > n + 2)
+ {
+ m_subs.erase(m_subs.begin()+n+2, m_subs.end());
+ std::fill(m_subs.begin(), m_subs.end(), v);
+ }
+ else
+ {
+ std::fill(m_subs.begin(), m_subs.end(), v);
+ if(n+2 != len)
+ m_subs.insert(m_subs.end(), n+2-len, v);
+ }
+ m_subs[1].first = i;
+ m_last_closed_paren = 0;
+ }
+ void BOOST_REGEX_CALL set_base(BidiIterator pos)
+ {
+ m_base = pos;
+ }
+ BidiIterator base()const
+ {
+ return m_base;
+ }
+ void BOOST_REGEX_CALL set_first(BidiIterator i)
+ {
+ // set up prefix:
+ m_subs[1].second = i;
+ m_subs[1].matched = (m_subs[1].first != i);
+ // set up $0:
+ m_subs[2].first = i;
+ // zero out everything else:
+ for(size_type n = 3; n < m_subs.size(); ++n)
+ {
+ m_subs[n].first = m_subs[n].second = m_subs[0].second;
+ m_subs[n].matched = false;
+ }
+ }
+ void BOOST_REGEX_CALL set_first(BidiIterator i, size_type pos, bool escape_k = false)
+ {
+ BOOST_ASSERT(pos+2 < m_subs.size());
+ if(pos || escape_k)
+ {
+ m_subs[pos+2].first = i;
+ if(escape_k)
+ {
+ m_subs[1].second = i;
+ m_subs[1].matched = (m_subs[1].first != m_subs[1].second);
+ }
+ }
+ else
+ set_first(i);
+ }
+ void BOOST_REGEX_CALL maybe_assign(const match_results<BidiIterator, Allocator>& m);
+
+ void BOOST_REGEX_CALL set_named_subs(boost::shared_ptr<named_sub_type> subs)
+ {
+ m_named_subs = subs;
+ }
+
+private:
+ vector_type m_subs; // subexpressions
+ BidiIterator m_base; // where the search started from
+ sub_match<BidiIterator> m_null; // a null match
+ boost::shared_ptr<named_sub_type> m_named_subs;
+ int m_last_closed_paren;
+};
+
+template <class BidiIterator, class Allocator>
+void BOOST_REGEX_CALL match_results<BidiIterator, Allocator>::maybe_assign(const match_results<BidiIterator, Allocator>& m)
+{
+ const_iterator p1, p2;
+ p1 = begin();
+ p2 = m.begin();
+ //
+ // Distances are measured from the start of *this* match, unless this isn't
+ // a valid match in which case we use the start of the whole sequence. Note that
+ // no subsequent match-candidate can ever be to the left of the first match found.
+ // This ensures that when we are using bidirectional iterators, that distances
+ // measured are as short as possible, and therefore as efficient as possible
+ // to compute. Finally note that we don't use the "matched" data member to test
+ // whether a sub-expression is a valid match, because partial matches set this
+ // to false for sub-expression 0.
+ //
+ BidiIterator l_end = this->suffix().second;
+ BidiIterator l_base = (p1->first == l_end) ? this->prefix().first : (*this)[0].first;
+ difference_type len1 = 0;
+ difference_type len2 = 0;
+ difference_type base1 = 0;
+ difference_type base2 = 0;
+ std::size_t i;
+ for(i = 0; i < size(); ++i, ++p1, ++p2)
+ {
+ //
+ // Leftmost takes priority over longest; handle special cases
+ // where distances need not be computed first (an optimisation
+ // for bidirectional iterators: ensure that we don't accidently
+ // compute the length of the whole sequence, as this can be really
+ // expensive).
+ //
+ if(p1->first == l_end)
+ {
+ if(p2->first != l_end)
+ {
+ // p2 must be better than p1, and no need to calculate
+ // actual distances:
+ base1 = 1;
+ base2 = 0;
+ break;
+ }
+ else
+ {
+ // *p1 and *p2 are either unmatched or match end-of sequence,
+ // either way no need to calculate distances:
+ if((p1->matched == false) && (p2->matched == true))
+ break;
+ if((p1->matched == true) && (p2->matched == false))
+ return;
+ continue;
+ }
+ }
+ else if(p2->first == l_end)
+ {
+ // p1 better than p2, and no need to calculate distances:
+ return;
+ }
+ base1 = ::boost::re_detail::distance(l_base, p1->first);
+ base2 = ::boost::re_detail::distance(l_base, p2->first);
+ BOOST_ASSERT(base1 >= 0);
+ BOOST_ASSERT(base2 >= 0);
+ if(base1 < base2) return;
+ if(base2 < base1) break;
+
+ len1 = ::boost::re_detail::distance((BidiIterator)p1->first, (BidiIterator)p1->second);
+ len2 = ::boost::re_detail::distance((BidiIterator)p2->first, (BidiIterator)p2->second);
+ BOOST_ASSERT(len1 >= 0);
+ BOOST_ASSERT(len2 >= 0);
+ if((len1 != len2) || ((p1->matched == false) && (p2->matched == true)))
+ break;
+ if((p1->matched == true) && (p2->matched == false))
+ return;
+ }
+ if(i == size())
+ return;
+ if(base2 < base1)
+ *this = m;
+ else if((len2 > len1) || ((p1->matched == false) && (p2->matched == true)) )
+ *this = m;
+}
+
+template <class BidiIterator, class Allocator>
+void swap(match_results<BidiIterator, Allocator>& a, match_results<BidiIterator, Allocator>& b)
+{
+ a.swap(b);
+}
+
+#ifndef BOOST_NO_STD_LOCALE
+template <class charT, class traits, class BidiIterator, class Allocator>
+std::basic_ostream<charT, traits>&
+ operator << (std::basic_ostream<charT, traits>& os,
+ const match_results<BidiIterator, Allocator>& s)
+{
+ return (os << s.str());
+}
+#else
+template <class BidiIterator, class Allocator>
+std::ostream& operator << (std::ostream& os,
+ const match_results<BidiIterator, Allocator>& s)
+{
+ return (os << s.str());
+}
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
+
diff --git a/ext/boost/regex/v4/mem_block_cache.hpp b/ext/boost/regex/v4/mem_block_cache.hpp
new file mode 100644
index 0000000000..222142dd69
--- /dev/null
+++ b/ext/boost/regex/v4/mem_block_cache.hpp
@@ -0,0 +1,99 @@
+ /*
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE mem_block_cache.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: memory block cache used by the non-recursive matcher.
+ */
+
+#ifndef BOOST_REGEX_V4_MEM_BLOCK_CACHE_HPP
+#define BOOST_REGEX_V4_MEM_BLOCK_CACHE_HPP
+
+#include <new>
+#ifdef BOOST_HAS_THREADS
+#include <boost/regex/pending/static_mutex.hpp>
+#endif
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost{
+namespace re_detail{
+
+struct mem_block_node
+{
+ mem_block_node* next;
+};
+
+struct mem_block_cache
+{
+ // this member has to be statically initialsed:
+ mem_block_node* next;
+ unsigned cached_blocks;
+#ifdef BOOST_HAS_THREADS
+ boost::static_mutex mut;
+#endif
+
+ ~mem_block_cache()
+ {
+ while(next)
+ {
+ mem_block_node* old = next;
+ next = next->next;
+ ::operator delete(old);
+ }
+ }
+ void* get()
+ {
+#ifdef BOOST_HAS_THREADS
+ boost::static_mutex::scoped_lock g(mut);
+#endif
+ if(next)
+ {
+ mem_block_node* result = next;
+ next = next->next;
+ --cached_blocks;
+ return result;
+ }
+ return ::operator new(BOOST_REGEX_BLOCKSIZE);
+ }
+ void put(void* p)
+ {
+#ifdef BOOST_HAS_THREADS
+ boost::static_mutex::scoped_lock g(mut);
+#endif
+ if(cached_blocks >= BOOST_REGEX_MAX_CACHE_BLOCKS)
+ {
+ ::operator delete(p);
+ }
+ else
+ {
+ mem_block_node* old = static_cast<mem_block_node*>(p);
+ old->next = next;
+ next = old;
+ ++cached_blocks;
+ }
+ }
+};
+
+extern mem_block_cache block_cache;
+
+}
+} // namespace boost
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif
+
diff --git a/ext/boost/regex/v4/perl_matcher.hpp b/ext/boost/regex/v4/perl_matcher.hpp
new file mode 100644
index 0000000000..726c2881e5
--- /dev/null
+++ b/ext/boost/regex/v4/perl_matcher.hpp
@@ -0,0 +1,580 @@
+/*
+ *
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+#ifndef BOOST_REGEX_MATCHER_HPP
+#define BOOST_REGEX_MATCHER_HPP
+
+#include <boost/regex/v4/iterator_category.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable: 4800)
+#endif
+
+namespace boost{
+namespace re_detail{
+
+//
+// error checking API:
+//
+BOOST_REGEX_DECL void BOOST_REGEX_CALL verify_options(boost::regex_constants::syntax_option_type ef, match_flag_type mf);
+//
+// function can_start:
+//
+template <class charT>
+inline bool can_start(charT c, const unsigned char* map, unsigned char mask)
+{
+ return ((c < static_cast<charT>(0)) ? true : ((c >= static_cast<charT>(1 << CHAR_BIT)) ? true : map[c] & mask));
+}
+inline bool can_start(char c, const unsigned char* map, unsigned char mask)
+{
+ return map[(unsigned char)c] & mask;
+}
+inline bool can_start(signed char c, const unsigned char* map, unsigned char mask)
+{
+ return map[(unsigned char)c] & mask;
+}
+inline bool can_start(unsigned char c, const unsigned char* map, unsigned char mask)
+{
+ return map[c] & mask;
+}
+inline bool can_start(unsigned short c, const unsigned char* map, unsigned char mask)
+{
+ return ((c >= (1 << CHAR_BIT)) ? true : map[c] & mask);
+}
+#if !defined(__hpux) // WCHAR_MIN not usable in pp-directives.
+#if defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+inline bool can_start(wchar_t c, const unsigned char* map, unsigned char mask)
+{
+ return ((c >= static_cast<wchar_t>(1u << CHAR_BIT)) ? true : map[c] & mask);
+}
+#endif
+#endif
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+inline bool can_start(unsigned int c, const unsigned char* map, unsigned char mask)
+{
+ return (((c >= static_cast<unsigned int>(1u << CHAR_BIT)) ? true : map[c] & mask));
+}
+#endif
+
+
+//
+// Unfortunately Rogue Waves standard library appears to have a bug
+// in std::basic_string::compare that results in eroneous answers
+// in some cases (tested with Borland C++ 5.1, Rogue Wave lib version
+// 0x020101) the test case was:
+// {39135,0} < {0xff,0}
+// which succeeds when it should not.
+//
+#ifndef _RWSTD_VER
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310)
+template <class C, class T, class A>
+inline int string_compare(const std::basic_string<C,T,A>& s, const C* p)
+{
+ if(0 == *p)
+ {
+ if(s.empty() || ((s.size() == 1) && (s[0] == 0)))
+ return 0;
+ }
+ return s.compare(p);
+}
+#endif
+#else
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310)
+template <class C, class T, class A>
+inline int string_compare(const std::basic_string<C,T,A>& s, const C* p)
+{
+ if(0 == *p)
+ {
+ if(s.empty() || ((s.size() == 1) && (s[0] == 0)))
+ return 0;
+ }
+ return s.compare(p);
+}
+#endif
+inline int string_compare(const std::string& s, const char* p)
+{ return std::strcmp(s.c_str(), p); }
+# ifndef BOOST_NO_WREGEX
+inline int string_compare(const std::wstring& s, const wchar_t* p)
+{ return std::wcscmp(s.c_str(), p); }
+#endif
+#endif
+template <class Seq, class C>
+inline int string_compare(const Seq& s, const C* p)
+{
+ std::size_t i = 0;
+ while((i < s.size()) && (p[i] == s[i]))
+ {
+ ++i;
+ }
+ return (i == s.size()) ? -p[i] : s[i] - p[i];
+}
+# define STR_COMP(s,p) string_compare(s,p)
+
+template<class charT>
+inline const charT* re_skip_past_null(const charT* p)
+{
+ while (*p != static_cast<charT>(0)) ++p;
+ return ++p;
+}
+
+template <class iterator, class charT, class traits_type, class char_classT>
+iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
+ iterator last,
+ const re_set_long<char_classT>* set_,
+ const regex_data<charT, traits_type>& e, bool icase)
+{
+ const charT* p = reinterpret_cast<const charT*>(set_+1);
+ iterator ptr;
+ unsigned int i;
+ //bool icase = e.m_flags & regex_constants::icase;
+
+ if(next == last) return next;
+
+ typedef typename traits_type::string_type traits_string_type;
+ const ::boost::regex_traits_wrapper<traits_type>& traits_inst = *(e.m_ptraits);
+
+ // dwa 9/13/00 suppress incorrect MSVC warning - it claims this is never
+ // referenced
+ (void)traits_inst;
+
+ // try and match a single character, could be a multi-character
+ // collating element...
+ for(i = 0; i < set_->csingles; ++i)
+ {
+ ptr = next;
+ if(*p == static_cast<charT>(0))
+ {
+ // treat null string as special case:
+ if(traits_inst.translate(*ptr, icase) != *p)
+ {
+ while(*p == static_cast<charT>(0))++p;
+ continue;
+ }
+ return set_->isnot ? next : (ptr == next) ? ++next : ptr;
+ }
+ else
+ {
+ while(*p && (ptr != last))
+ {
+ if(traits_inst.translate(*ptr, icase) != *p)
+ break;
+ ++p;
+ ++ptr;
+ }
+
+ if(*p == static_cast<charT>(0)) // if null we've matched
+ return set_->isnot ? next : (ptr == next) ? ++next : ptr;
+
+ p = re_skip_past_null(p); // skip null
+ }
+ }
+
+ charT col = traits_inst.translate(*next, icase);
+
+
+ if(set_->cranges || set_->cequivalents)
+ {
+ traits_string_type s1;
+ //
+ // try and match a range, NB only a single character can match
+ if(set_->cranges)
+ {
+ if((e.m_flags & regex_constants::collate) == 0)
+ s1.assign(1, col);
+ else
+ {
+ charT a[2] = { col, charT(0), };
+ s1 = traits_inst.transform(a, a + 1);
+ }
+ for(i = 0; i < set_->cranges; ++i)
+ {
+ if(STR_COMP(s1, p) >= 0)
+ {
+ do{ ++p; }while(*p);
+ ++p;
+ if(STR_COMP(s1, p) <= 0)
+ return set_->isnot ? next : ++next;
+ }
+ else
+ {
+ // skip first string
+ do{ ++p; }while(*p);
+ ++p;
+ }
+ // skip second string
+ do{ ++p; }while(*p);
+ ++p;
+ }
+ }
+ //
+ // try and match an equivalence class, NB only a single character can match
+ if(set_->cequivalents)
+ {
+ charT a[2] = { col, charT(0), };
+ s1 = traits_inst.transform_primary(a, a +1);
+ for(i = 0; i < set_->cequivalents; ++i)
+ {
+ if(STR_COMP(s1, p) == 0)
+ return set_->isnot ? next : ++next;
+ // skip string
+ do{ ++p; }while(*p);
+ ++p;
+ }
+ }
+ }
+ if(traits_inst.isctype(col, set_->cclasses) == true)
+ return set_->isnot ? next : ++next;
+ if((set_->cnclasses != 0) && (traits_inst.isctype(col, set_->cnclasses) == false))
+ return set_->isnot ? next : ++next;
+ return set_->isnot ? ++next : next;
+}
+
+template <class BidiIterator>
+class repeater_count
+{
+ repeater_count** stack;
+ repeater_count* next;
+ int state_id;
+ std::size_t count; // the number of iterations so far
+ BidiIterator start_pos; // where the last repeat started
+public:
+ repeater_count(repeater_count** s)
+ {
+ stack = s;
+ next = 0;
+ state_id = -1;
+ count = 0;
+ }
+ repeater_count(int i, repeater_count** s, BidiIterator start)
+ : start_pos(start)
+ {
+ state_id = i;
+ stack = s;
+ next = *stack;
+ *stack = this;
+ if(state_id > next->state_id)
+ count = 0;
+ else
+ {
+ repeater_count* p = next;
+ while(p->state_id != state_id)
+ p = p->next;
+ count = p->count;
+ start_pos = p->start_pos;
+ }
+ }
+ ~repeater_count()
+ {
+ if(next)
+ *stack = next;
+ }
+ std::size_t get_count() { return count; }
+ int get_id() { return state_id; }
+ std::size_t operator++() { return ++count; }
+ bool check_null_repeat(const BidiIterator& pos, std::size_t max)
+ {
+ // this is called when we are about to start a new repeat,
+ // if the last one was NULL move our count to max,
+ // otherwise save the current position.
+ bool result = (count == 0) ? false : (pos == start_pos);
+ if(result)
+ count = max;
+ else
+ start_pos = pos;
+ return result;
+ }
+};
+
+struct saved_state;
+
+enum saved_state_type
+{
+ saved_type_end = 0,
+ saved_type_paren = 1,
+ saved_type_recurse = 2,
+ saved_type_assertion = 3,
+ saved_state_alt = 4,
+ saved_state_repeater_count = 5,
+ saved_state_extra_block = 6,
+ saved_state_greedy_single_repeat = 7,
+ saved_state_rep_slow_dot = 8,
+ saved_state_rep_fast_dot = 9,
+ saved_state_rep_char = 10,
+ saved_state_rep_short_set = 11,
+ saved_state_rep_long_set = 12,
+ saved_state_non_greedy_long_repeat = 13,
+ saved_state_count = 14
+};
+
+template <class Results>
+struct recursion_info
+{
+ typedef typename Results::value_type value_type;
+ typedef typename value_type::iterator iterator;
+ int id;
+ const re_syntax_base* preturn_address;
+ Results results;
+ repeater_count<iterator>* repeater_stack;
+};
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4251 4231 4660)
+#endif
+
+template <class BidiIterator, class Allocator, class traits>
+class perl_matcher
+{
+public:
+ typedef typename traits::char_type char_type;
+ typedef perl_matcher<BidiIterator, Allocator, traits> self_type;
+ typedef bool (self_type::*matcher_proc_type)(void);
+ typedef std::size_t traits_size_type;
+ typedef typename is_byte<char_type>::width_type width_type;
+ typedef typename regex_iterator_traits<BidiIterator>::difference_type difference_type;
+ typedef match_results<BidiIterator, Allocator> results_type;
+
+ perl_matcher(BidiIterator first, BidiIterator end,
+ match_results<BidiIterator, Allocator>& what,
+ const basic_regex<char_type, traits>& e,
+ match_flag_type f,
+ BidiIterator l_base)
+ : m_result(what), base(first), last(end),
+ position(first), backstop(l_base), re(e), traits_inst(e.get_traits()),
+ m_independent(false), next_count(&rep_obj), rep_obj(&next_count), recursion_stack_position(0)
+ {
+ construct_init(e, f);
+ }
+
+ bool match();
+ bool find();
+
+ void setf(match_flag_type f)
+ { m_match_flags |= f; }
+ void unsetf(match_flag_type f)
+ { m_match_flags &= ~f; }
+
+private:
+ void construct_init(const basic_regex<char_type, traits>& e, match_flag_type f);
+
+ bool find_imp();
+ bool match_imp();
+#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
+ typedef bool (perl_matcher::*protected_proc_type)();
+ bool protected_call(protected_proc_type);
+#endif
+ void estimate_max_state_count(std::random_access_iterator_tag*);
+ void estimate_max_state_count(void*);
+ bool match_prefix();
+ bool match_all_states();
+
+ // match procs, stored in s_match_vtable:
+ bool match_startmark();
+ bool match_endmark();
+ bool match_literal();
+ bool match_start_line();
+ bool match_end_line();
+ bool match_wild();
+ bool match_match();
+ bool match_word_boundary();
+ bool match_within_word();
+ bool match_word_start();
+ bool match_word_end();
+ bool match_buffer_start();
+ bool match_buffer_end();
+ bool match_backref();
+ bool match_long_set();
+ bool match_set();
+ bool match_jump();
+ bool match_alt();
+ bool match_rep();
+ bool match_combining();
+ bool match_soft_buffer_end();
+ bool match_restart_continue();
+ bool match_long_set_repeat();
+ bool match_set_repeat();
+ bool match_char_repeat();
+ bool match_dot_repeat_fast();
+ bool match_dot_repeat_slow();
+ bool match_dot_repeat_dispatch()
+ {
+ return ::boost::is_random_access_iterator<BidiIterator>::value ? match_dot_repeat_fast() : match_dot_repeat_slow();
+ }
+ bool match_backstep();
+ bool match_assert_backref();
+ bool match_toggle_case();
+#ifdef BOOST_REGEX_RECURSIVE
+ bool backtrack_till_match(std::size_t count);
+#endif
+ bool match_recursion();
+
+ // find procs stored in s_find_vtable:
+ bool find_restart_any();
+ bool find_restart_word();
+ bool find_restart_line();
+ bool find_restart_buf();
+ bool find_restart_lit();
+
+private:
+ // final result structure to be filled in:
+ match_results<BidiIterator, Allocator>& m_result;
+ // temporary result for POSIX matches:
+ scoped_ptr<match_results<BidiIterator, Allocator> > m_temp_match;
+ // pointer to actual result structure to fill in:
+ match_results<BidiIterator, Allocator>* m_presult;
+ // start of sequence being searched:
+ BidiIterator base;
+ // end of sequence being searched:
+ BidiIterator last;
+ // current character being examined:
+ BidiIterator position;
+ // where to restart next search after failed match attempt:
+ BidiIterator restart;
+ // where the current search started from, acts as base for $` during grep:
+ BidiIterator search_base;
+ // how far we can go back when matching lookbehind:
+ BidiIterator backstop;
+ // the expression being examined:
+ const basic_regex<char_type, traits>& re;
+ // the expression's traits class:
+ const ::boost::regex_traits_wrapper<traits>& traits_inst;
+ // the next state in the machine being matched:
+ const re_syntax_base* pstate;
+ // matching flags in use:
+ match_flag_type m_match_flags;
+ // how many states we have examined so far:
+ boost::uintmax_t state_count;
+ // max number of states to examine before giving up:
+ boost::uintmax_t max_state_count;
+ // whether we should ignore case or not:
+ bool icase;
+ // set to true when (position == last), indicates that we may have a partial match:
+ bool m_has_partial_match;
+ // set to true whenever we get a match:
+ bool m_has_found_match;
+ // set to true whenever we're inside an independent sub-expression:
+ bool m_independent;
+ // the current repeat being examined:
+ repeater_count<BidiIterator>* next_count;
+ // the first repeat being examined (top of linked list):
+ repeater_count<BidiIterator> rep_obj;
+ // the mask to pass when matching word boundaries:
+ typename traits::char_class_type m_word_mask;
+ // the bitmask to use when determining whether a match_any matches a newline or not:
+ unsigned char match_any_mask;
+ // recursion information:
+ recursion_info<results_type> recursion_stack[50];
+ unsigned recursion_stack_position;
+
+#ifdef BOOST_REGEX_NON_RECURSIVE
+ //
+ // additional members for non-recursive version:
+ //
+ typedef bool (self_type::*unwind_proc_type)(bool);
+
+ void extend_stack();
+ bool unwind(bool);
+ bool unwind_end(bool);
+ bool unwind_paren(bool);
+ bool unwind_recursion_stopper(bool);
+ bool unwind_assertion(bool);
+ bool unwind_alt(bool);
+ bool unwind_repeater_counter(bool);
+ bool unwind_extra_block(bool);
+ bool unwind_greedy_single_repeat(bool);
+ bool unwind_slow_dot_repeat(bool);
+ bool unwind_fast_dot_repeat(bool);
+ bool unwind_char_repeat(bool);
+ bool unwind_short_set_repeat(bool);
+ bool unwind_long_set_repeat(bool);
+ bool unwind_non_greedy_repeat(bool);
+ bool unwind_recursion(bool);
+ bool unwind_recursion_pop(bool);
+ void destroy_single_repeat();
+ void push_matched_paren(int index, const sub_match<BidiIterator>& sub);
+ void push_recursion_stopper();
+ void push_assertion(const re_syntax_base* ps, bool positive);
+ void push_alt(const re_syntax_base* ps);
+ void push_repeater_count(int i, repeater_count<BidiIterator>** s);
+ void push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id);
+ void push_non_greedy_repeat(const re_syntax_base* ps);
+ void push_recursion(int id, const re_syntax_base* p, results_type* presults);
+ void push_recursion_pop();
+
+ // pointer to base of stack:
+ saved_state* m_stack_base;
+ // pointer to current stack position:
+ saved_state* m_backup_state;
+ // determines what value to return when unwinding from recursion,
+ // allows for mixed recursive/non-recursive algorithm:
+ bool m_recursive_result;
+ // how many memory blocks have we used up?:
+ unsigned used_block_count;
+#endif
+
+ // these operations aren't allowed, so are declared private,
+ // bodies are provided to keep explicit-instantiation requests happy:
+ perl_matcher& operator=(const perl_matcher&)
+ {
+ return *this;
+ }
+ perl_matcher(const perl_matcher& that)
+ : m_result(that.m_result), re(that.re), traits_inst(that.traits_inst), rep_obj(0) {}
+};
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace re_detail
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace boost
+
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
+//
+// include the implementation of perl_matcher:
+//
+#ifdef BOOST_REGEX_RECURSIVE
+#include <boost/regex/v4/perl_matcher_recursive.hpp>
+#else
+#include <boost/regex/v4/perl_matcher_non_recursive.hpp>
+#endif
+// this one has to be last:
+#include <boost/regex/v4/perl_matcher_common.hpp>
+
+#endif
+
diff --git a/ext/boost/regex/v4/perl_matcher_common.hpp b/ext/boost/regex/v4/perl_matcher_common.hpp
new file mode 100644
index 0000000000..fd439f84b6
--- /dev/null
+++ b/ext/boost/regex/v4/perl_matcher_common.hpp
@@ -0,0 +1,949 @@
+/*
+ *
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE perl_matcher_common.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Definitions of perl_matcher member functions that are
+ * common to both the recursive and non-recursive versions.
+ */
+
+#ifndef BOOST_REGEX_V4_PERL_MATCHER_COMMON_HPP
+#define BOOST_REGEX_V4_PERL_MATCHER_COMMON_HPP
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef __BORLANDC__
+# pragma option push -w-8008 -w-8066
+#endif
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable: 4800)
+#endif
+
+namespace boost{
+namespace re_detail{
+
+template <class BidiIterator, class Allocator, class traits>
+void perl_matcher<BidiIterator, Allocator, traits>::construct_init(const basic_regex<char_type, traits>& e, match_flag_type f)
+{
+ typedef typename regex_iterator_traits<BidiIterator>::iterator_category category;
+ typedef typename basic_regex<char_type, traits>::flag_type expression_flag_type;
+
+ if(e.empty())
+ {
+ // precondition failure: e is not a valid regex.
+ std::invalid_argument ex("Invalid regular expression object");
+ boost::throw_exception(ex);
+ }
+ pstate = 0;
+ m_match_flags = f;
+ estimate_max_state_count(static_cast<category*>(0));
+ expression_flag_type re_f = re.flags();
+ icase = re_f & regex_constants::icase;
+ if(!(m_match_flags & (match_perl|match_posix)))
+ {
+ if((re_f & (regbase::main_option_type|regbase::no_perl_ex)) == 0)
+ m_match_flags |= match_perl;
+ else if((re_f & (regbase::main_option_type|regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))
+ m_match_flags |= match_perl;
+ else
+ m_match_flags |= match_posix;
+ }
+ if(m_match_flags & match_posix)
+ {
+ m_temp_match.reset(new match_results<BidiIterator, Allocator>());
+ m_presult = m_temp_match.get();
+ }
+ else
+ m_presult = &m_result;
+#ifdef BOOST_REGEX_NON_RECURSIVE
+ m_stack_base = 0;
+ m_backup_state = 0;
+#endif
+ // find the value to use for matching word boundaries:
+ m_word_mask = re.get_data().m_word_mask;
+ // find bitmask to use for matching '.':
+ match_any_mask = static_cast<unsigned char>((f & match_not_dot_newline) ? re_detail::test_not_newline : re_detail::test_newline);
+}
+
+template <class BidiIterator, class Allocator, class traits>
+void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std::random_access_iterator_tag*)
+{
+ //
+ // How many states should we allow our machine to visit before giving up?
+ // This is a heuristic: it takes the greater of O(N^2) and O(NS^2)
+ // where N is the length of the string, and S is the number of states
+ // in the machine. It's tempting to up this to O(N^2S) or even O(N^2S^2)
+ // but these take unreasonably amounts of time to bale out in pathological
+ // cases.
+ //
+ // Calculate NS^2 first:
+ //
+ static const boost::uintmax_t k = 100000;
+ boost::uintmax_t dist = boost::re_detail::distance(base, last);
+ if(dist == 0)
+ dist = 1;
+ boost::uintmax_t states = re.size();
+ if(states == 0)
+ states = 1;
+ states *= states;
+ if((std::numeric_limits<boost::uintmax_t>::max)() / dist < states)
+ {
+ max_state_count = (std::numeric_limits<boost::uintmax_t>::max)() - 2;
+ return;
+ }
+ states *= dist;
+ if((std::numeric_limits<boost::uintmax_t>::max)() - k < states)
+ {
+ max_state_count = (std::numeric_limits<boost::uintmax_t>::max)() - 2;
+ return;
+ }
+ states += k;
+
+ max_state_count = states;
+
+ //
+ // Now calculate N^2:
+ //
+ states = dist;
+ if((std::numeric_limits<boost::uintmax_t>::max)() / dist < states)
+ {
+ max_state_count = (std::numeric_limits<boost::uintmax_t>::max)() - 2;
+ return;
+ }
+ states *= dist;
+ if((std::numeric_limits<boost::uintmax_t>::max)() - k < states)
+ {
+ max_state_count = (std::numeric_limits<boost::uintmax_t>::max)() - 2;
+ return;
+ }
+ states += k;
+ //
+ // N^2 can be a very large number indeed, to prevent things getting out
+ // of control, cap the max states:
+ //
+ if(states > BOOST_REGEX_MAX_STATE_COUNT)
+ states = BOOST_REGEX_MAX_STATE_COUNT;
+ //
+ // If (the possibly capped) N^2 is larger than our first estimate,
+ // use this instead:
+ //
+ if(states > max_state_count)
+ max_state_count = states;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(void*)
+{
+ // we don't know how long the sequence is:
+ max_state_count = BOOST_REGEX_MAX_STATE_COUNT;
+}
+
+#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
+template <class BidiIterator, class Allocator, class traits>
+inline bool perl_matcher<BidiIterator, Allocator, traits>::protected_call(
+ protected_proc_type proc)
+{
+ ::boost::re_detail::concrete_protected_call
+ <perl_matcher<BidiIterator, Allocator, traits> >
+ obj(this, proc);
+ return obj.execute();
+
+}
+#endif
+
+template <class BidiIterator, class Allocator, class traits>
+inline bool perl_matcher<BidiIterator, Allocator, traits>::match()
+{
+#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
+ return protected_call(&perl_matcher<BidiIterator, Allocator, traits>::match_imp);
+#else
+ return match_imp();
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_imp()
+{
+ // initialise our stack if we are non-recursive:
+#ifdef BOOST_REGEX_NON_RECURSIVE
+ save_state_init init(&m_stack_base, &m_backup_state);
+ used_block_count = BOOST_REGEX_MAX_BLOCKS;
+#if !defined(BOOST_NO_EXCEPTIONS)
+ try{
+#endif
+#endif
+
+ // reset our state machine:
+ position = base;
+ search_base = base;
+ state_count = 0;
+ m_match_flags |= regex_constants::match_all;
+ m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), search_base, last);
+ m_presult->set_base(base);
+ m_presult->set_named_subs(re_detail::convert_to_named_subs<typename match_results<BidiIterator>::char_type>(this->re.get_named_subs()));
+ if(m_match_flags & match_posix)
+ m_result = *m_presult;
+ verify_options(re.flags(), m_match_flags);
+ if(0 == match_prefix())
+ return false;
+ return (m_result[0].second == last) && (m_result[0].first == base);
+
+#if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_NO_EXCEPTIONS)
+ }
+ catch(...)
+ {
+ // unwind all pushed states, apart from anything else this
+ // ensures that all the states are correctly destructed
+ // not just the memory freed.
+ while(unwind(true)){}
+ throw;
+ }
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline bool perl_matcher<BidiIterator, Allocator, traits>::find()
+{
+#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
+ return protected_call(&perl_matcher<BidiIterator, Allocator, traits>::find_imp);
+#else
+ return find_imp();
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::find_imp()
+{
+ static matcher_proc_type const s_find_vtable[7] =
+ {
+ &perl_matcher<BidiIterator, Allocator, traits>::find_restart_any,
+ &perl_matcher<BidiIterator, Allocator, traits>::find_restart_word,
+ &perl_matcher<BidiIterator, Allocator, traits>::find_restart_line,
+ &perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_prefix,
+ &perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
+ &perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
+ };
+
+ // initialise our stack if we are non-recursive:
+#ifdef BOOST_REGEX_NON_RECURSIVE
+ save_state_init init(&m_stack_base, &m_backup_state);
+ used_block_count = BOOST_REGEX_MAX_BLOCKS;
+#if !defined(BOOST_NO_EXCEPTIONS)
+ try{
+#endif
+#endif
+
+ state_count = 0;
+ if((m_match_flags & regex_constants::match_init) == 0)
+ {
+ // reset our state machine:
+ search_base = position = base;
+ pstate = re.get_first_state();
+ m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), base, last);
+ m_presult->set_base(base);
+ m_presult->set_named_subs(re_detail::convert_to_named_subs<typename match_results<BidiIterator>::char_type>(this->re.get_named_subs()));
+ m_match_flags |= regex_constants::match_init;
+ }
+ else
+ {
+ // start again:
+ search_base = position = m_result[0].second;
+ // If last match was null and match_not_null was not set then increment
+ // our start position, otherwise we go into an infinite loop:
+ if(((m_match_flags & match_not_null) == 0) && (m_result.length() == 0))
+ {
+ if(position == last)
+ return false;
+ else
+ ++position;
+ }
+ // reset $` start:
+ m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), search_base, last);
+ //if((base != search_base) && (base == backstop))
+ // m_match_flags |= match_prev_avail;
+ }
+ if(m_match_flags & match_posix)
+ {
+ m_result.set_size(re.mark_count(), base, last);
+ m_result.set_base(base);
+ }
+
+ verify_options(re.flags(), m_match_flags);
+ // find out what kind of expression we have:
+ unsigned type = (m_match_flags & match_continuous) ?
+ static_cast<unsigned int>(regbase::restart_continue)
+ : static_cast<unsigned int>(re.get_restart_type());
+
+ // call the appropriate search routine:
+ matcher_proc_type proc = s_find_vtable[type];
+ return (this->*proc)();
+
+#if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_NO_EXCEPTIONS)
+ }
+ catch(...)
+ {
+ // unwind all pushed states, apart from anything else this
+ // ensures that all the states are correctly destructed
+ // not just the memory freed.
+ while(unwind(true)){}
+ throw;
+ }
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_prefix()
+{
+ m_has_partial_match = false;
+ m_has_found_match = false;
+ pstate = re.get_first_state();
+ m_presult->set_first(position);
+ restart = position;
+ match_all_states();
+ if(!m_has_found_match && m_has_partial_match && (m_match_flags & match_partial))
+ {
+ m_has_found_match = true;
+ m_presult->set_second(last, 0, false);
+ position = last;
+ }
+#ifdef BOOST_REGEX_MATCH_EXTRA
+ if(m_has_found_match && (match_extra & m_match_flags))
+ {
+ //
+ // we have a match, reverse the capture information:
+ //
+ for(unsigned i = 0; i < m_presult->size(); ++i)
+ {
+ typename sub_match<BidiIterator>::capture_sequence_type & seq = ((*m_presult)[i]).get_captures();
+ std::reverse(seq.begin(), seq.end());
+ }
+ }
+#endif
+ if(!m_has_found_match)
+ position = restart; // reset search postion
+ return m_has_found_match;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_literal()
+{
+ unsigned int len = static_cast<const re_literal*>(pstate)->length;
+ const char_type* what = reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);
+ //
+ // compare string with what we stored in
+ // our records:
+ for(unsigned int i = 0; i < len; ++i, ++position)
+ {
+ if((position == last) || (traits_inst.translate(*position, icase) != what[i]))
+ return false;
+ }
+ pstate = pstate->next.p;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_start_line()
+{
+ if(position == backstop)
+ {
+ if((m_match_flags & match_prev_avail) == 0)
+ {
+ if((m_match_flags & match_not_bol) == 0)
+ {
+ pstate = pstate->next.p;
+ return true;
+ }
+ return false;
+ }
+ }
+ else if(m_match_flags & match_single_line)
+ return false;
+
+ // check the previous value character:
+ BidiIterator t(position);
+ --t;
+ if(position != last)
+ {
+ if(is_separator(*t) && !((*t == static_cast<char_type>('\r')) && (*position == static_cast<char_type>('\n'))) )
+ {
+ pstate = pstate->next.p;
+ return true;
+ }
+ }
+ else if(is_separator(*t))
+ {
+ pstate = pstate->next.p;
+ return true;
+ }
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_end_line()
+{
+ if(position != last)
+ {
+ if(m_match_flags & match_single_line)
+ return false;
+ // we're not yet at the end so *first is always valid:
+ if(is_separator(*position))
+ {
+ if((position != backstop) || (m_match_flags & match_prev_avail))
+ {
+ // check that we're not in the middle of \r\n sequence
+ BidiIterator t(position);
+ --t;
+ if((*t == static_cast<char_type>('\r')) && (*position == static_cast<char_type>('\n')))
+ {
+ return false;
+ }
+ }
+ pstate = pstate->next.p;
+ return true;
+ }
+ }
+ else if((m_match_flags & match_not_eol) == 0)
+ {
+ pstate = pstate->next.p;
+ return true;
+ }
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_wild()
+{
+ if(position == last)
+ return false;
+ if(is_separator(*position) && ((match_any_mask & static_cast<const re_dot*>(pstate)->mask) == 0))
+ return false;
+ if((*position == char_type(0)) && (m_match_flags & match_not_dot_null))
+ return false;
+ pstate = pstate->next.p;
+ ++position;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary()
+{
+ bool b; // indcates whether next character is a word character
+ if(position != last)
+ {
+ // prev and this character must be opposites:
+ #if defined(BOOST_REGEX_USE_C_LOCALE) && defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)
+ b = traits::isctype(*position, m_word_mask);
+ #else
+ b = traits_inst.isctype(*position, m_word_mask);
+ #endif
+ }
+ else
+ {
+ b = (m_match_flags & match_not_eow) ? true : false;
+ }
+ if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
+ {
+ if(m_match_flags & match_not_bow)
+ b ^= true;
+ else
+ b ^= false;
+ }
+ else
+ {
+ --position;
+ b ^= traits_inst.isctype(*position, m_word_mask);
+ ++position;
+ }
+ if(b)
+ {
+ pstate = pstate->next.p;
+ return true;
+ }
+ return false; // no match if we get to here...
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_within_word()
+{
+ if(position == last)
+ return false;
+ // both prev and this character must be m_word_mask:
+ bool prev = traits_inst.isctype(*position, m_word_mask);
+ {
+ bool b;
+ if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
+ return false;
+ else
+ {
+ --position;
+ b = traits_inst.isctype(*position, m_word_mask);
+ ++position;
+ }
+ if(b == prev)
+ {
+ pstate = pstate->next.p;
+ return true;
+ }
+ }
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_word_start()
+{
+ if(position == last)
+ return false; // can't be starting a word if we're already at the end of input
+ if(!traits_inst.isctype(*position, m_word_mask))
+ return false; // next character isn't a word character
+ if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
+ {
+ if(m_match_flags & match_not_bow)
+ return false; // no previous input
+ }
+ else
+ {
+ // otherwise inside buffer:
+ BidiIterator t(position);
+ --t;
+ if(traits_inst.isctype(*t, m_word_mask))
+ return false; // previous character not non-word
+ }
+ // OK we have a match:
+ pstate = pstate->next.p;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_word_end()
+{
+ if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
+ return false; // start of buffer can't be end of word
+ BidiIterator t(position);
+ --t;
+ if(traits_inst.isctype(*t, m_word_mask) == false)
+ return false; // previous character wasn't a word character
+
+ if(position == last)
+ {
+ if(m_match_flags & match_not_eow)
+ return false; // end of buffer but not end of word
+ }
+ else
+ {
+ // otherwise inside buffer:
+ if(traits_inst.isctype(*position, m_word_mask))
+ return false; // next character is a word character
+ }
+ pstate = pstate->next.p;
+ return true; // if we fall through to here then we've succeeded
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start()
+{
+ if((position != backstop) || (m_match_flags & match_not_bob))
+ return false;
+ // OK match:
+ pstate = pstate->next.p;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end()
+{
+ if((position != last) || (m_match_flags & match_not_eob))
+ return false;
+ // OK match:
+ pstate = pstate->next.p;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_backref()
+{
+ //
+ // Compare with what we previously matched.
+ // Note that this succeeds if the backref did not partisipate
+ // in the match, this is in line with ECMAScript, but not Perl
+ // or PCRE.
+ //
+ BidiIterator i = (*m_presult)[static_cast<const re_brace*>(pstate)->index].first;
+ BidiIterator j = (*m_presult)[static_cast<const re_brace*>(pstate)->index].second;
+ while(i != j)
+ {
+ if((position == last) || (traits_inst.translate(*position, icase) != traits_inst.translate(*i, icase)))
+ return false;
+ ++i;
+ ++position;
+ }
+ pstate = pstate->next.p;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set()
+{
+ typedef typename traits::char_class_type char_class_type;
+ // let the traits class do the work:
+ if(position == last)
+ return false;
+ BidiIterator t = re_is_set_member(position, last, static_cast<const re_set_long<char_class_type>*>(pstate), re.get_data(), icase);
+ if(t != position)
+ {
+ pstate = pstate->next.p;
+ position = t;
+ return true;
+ }
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_set()
+{
+ if(position == last)
+ return false;
+ if(static_cast<const re_set*>(pstate)->_map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+ {
+ pstate = pstate->next.p;
+ ++position;
+ return true;
+ }
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_jump()
+{
+ pstate = static_cast<const re_jump*>(pstate)->alt.p;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_combining()
+{
+ if(position == last)
+ return false;
+ if(is_combining(traits_inst.translate(*position, icase)))
+ return false;
+ ++position;
+ while((position != last) && is_combining(traits_inst.translate(*position, icase)))
+ ++position;
+ pstate = pstate->next.p;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end()
+{
+ if(m_match_flags & match_not_eob)
+ return false;
+ BidiIterator p(position);
+ while((p != last) && is_separator(traits_inst.translate(*p, icase)))++p;
+ if(p != last)
+ return false;
+ pstate = pstate->next.p;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue()
+{
+ if(position == search_base)
+ {
+ pstate = pstate->next.p;
+ return true;
+ }
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_backstep()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+ if( ::boost::is_random_access_iterator<BidiIterator>::value)
+ {
+ std::ptrdiff_t maxlen = ::boost::re_detail::distance(backstop, position);
+ if(maxlen < static_cast<const re_brace*>(pstate)->index)
+ return false;
+ std::advance(position, -static_cast<const re_brace*>(pstate)->index);
+ }
+ else
+ {
+ int c = static_cast<const re_brace*>(pstate)->index;
+ while(c--)
+ {
+ if(position == backstop)
+ return false;
+ --position;
+ }
+ }
+ pstate = pstate->next.p;
+ return true;
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline bool perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref()
+{
+ // return true if marked sub-expression N has been matched:
+ int index = static_cast<const re_brace*>(pstate)->index;
+ bool result;
+ if(index == 9999)
+ {
+ // Magic value for a (DEFINE) block:
+ return false;
+ }
+ else if(index > 0)
+ {
+ // Check if index is a hash value:
+ if(index >= 10000)
+ index = re.get_data().get_id(index);
+ // Have we matched subexpression "index"?
+ result = (*m_presult)[index].matched;
+ pstate = pstate->next.p;
+ }
+ else
+ {
+ // Have we recursed into subexpression "index"?
+ // If index == 0 then check for any recursion at all, otherwise for recursion to -index-1.
+ int id = -index-1;
+ if(id >= 10000)
+ id = re.get_data().get_id(id);
+ result = recursion_stack_position && ((recursion_stack[recursion_stack_position-1].id == id) || (index == 0));
+ pstate = pstate->next.p;
+ }
+ return result;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case()
+{
+ // change our case sensitivity:
+ this->icase = static_cast<const re_case*>(pstate)->icase;
+ pstate = pstate->next.p;
+ return true;
+}
+
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_any()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+ const unsigned char* _map = re.get_map();
+ while(true)
+ {
+ // skip everything we can't match:
+ while((position != last) && !can_start(*position, _map, (unsigned char)mask_any) )
+ ++position;
+ if(position == last)
+ {
+ // run out of characters, try a null match if possible:
+ if(re.can_be_null())
+ return match_prefix();
+ break;
+ }
+ // now try and obtain a match:
+ if(match_prefix())
+ return true;
+ if(position == last)
+ return false;
+ ++position;
+ }
+ return false;
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_word()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+ // do search optimised for word starts:
+ const unsigned char* _map = re.get_map();
+ if((m_match_flags & match_prev_avail) || (position != base))
+ --position;
+ else if(match_prefix())
+ return true;
+ do
+ {
+ while((position != last) && traits_inst.isctype(*position, m_word_mask))
+ ++position;
+ while((position != last) && !traits_inst.isctype(*position, m_word_mask))
+ ++position;
+ if(position == last)
+ break;
+
+ if(can_start(*position, _map, (unsigned char)mask_any) )
+ {
+ if(match_prefix())
+ return true;
+ }
+ if(position == last)
+ break;
+ } while(true);
+ return false;
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_line()
+{
+ // do search optimised for line starts:
+ const unsigned char* _map = re.get_map();
+ if(match_prefix())
+ return true;
+ while(position != last)
+ {
+ while((position != last) && !is_separator(*position))
+ ++position;
+ if(position == last)
+ return false;
+ ++position;
+ if(position == last)
+ {
+ if(re.can_be_null() && match_prefix())
+ return true;
+ return false;
+ }
+
+ if( can_start(*position, _map, (unsigned char)mask_any) )
+ {
+ if(match_prefix())
+ return true;
+ }
+ if(position == last)
+ return false;
+ //++position;
+ }
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf()
+{
+ if((position == base) && ((m_match_flags & match_not_bob) == 0))
+ return match_prefix();
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit()
+{
+#if 0
+ if(position == last)
+ return false; // can't possibly match if we're at the end already
+
+ unsigned type = (m_match_flags & match_continuous) ?
+ static_cast<unsigned int>(regbase::restart_continue)
+ : static_cast<unsigned int>(re.get_restart_type());
+
+ const kmp_info<char_type>* info = access::get_kmp(re);
+ int len = info->len;
+ const char_type* x = info->pstr;
+ int j = 0;
+ while (position != last)
+ {
+ while((j > -1) && (x[j] != traits_inst.translate(*position, icase)))
+ j = info->kmp_next[j];
+ ++position;
+ ++j;
+ if(j >= len)
+ {
+ if(type == regbase::restart_fixed_lit)
+ {
+ std::advance(position, -j);
+ restart = position;
+ std::advance(restart, len);
+ m_result.set_first(position);
+ m_result.set_second(restart);
+ position = restart;
+ return true;
+ }
+ else
+ {
+ restart = position;
+ std::advance(position, -j);
+ if(match_prefix())
+ return true;
+ else
+ {
+ for(int k = 0; (restart != position) && (k < j); ++k, --restart)
+ {} // dwa 10/20/2000 - warning suppression for MWCW
+ if(restart != last)
+ ++restart;
+ position = restart;
+ j = 0; //we could do better than this...
+ }
+ }
+ }
+ }
+ if((m_match_flags & match_partial) && (position == last) && j)
+ {
+ // we need to check for a partial match:
+ restart = position;
+ std::advance(position, -j);
+ return match_prefix();
+ }
+#endif
+ return false;
+}
+
+} // namespace re_detail
+
+} // namespace boost
+
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
+#ifdef __BORLANDC__
+# pragma option pop
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/ext/boost/regex/v4/perl_matcher_non_recursive.hpp b/ext/boost/regex/v4/perl_matcher_non_recursive.hpp
new file mode 100644
index 0000000000..2ce7ebe034
--- /dev/null
+++ b/ext/boost/regex/v4/perl_matcher_non_recursive.hpp
@@ -0,0 +1,1635 @@
+/*
+ *
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE perl_matcher_common.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Definitions of perl_matcher member functions that are
+ * specific to the non-recursive implementation.
+ */
+
+#ifndef BOOST_REGEX_V4_PERL_MATCHER_NON_RECURSIVE_HPP
+#define BOOST_REGEX_V4_PERL_MATCHER_NON_RECURSIVE_HPP
+
+#include <new>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable: 4800)
+#endif
+
+namespace boost{
+namespace re_detail{
+
+template <class T>
+inline void inplace_destroy(T* p)
+{
+ (void)p; // warning suppression
+ p->~T();
+}
+
+struct saved_state
+{
+ union{
+ unsigned int state_id;
+ // this padding ensures correct alignment on 64-bit platforms:
+ std::size_t padding1;
+ std::ptrdiff_t padding2;
+ void* padding3;
+ };
+ saved_state(unsigned i) : state_id(i) {}
+};
+
+template <class BidiIterator>
+struct saved_matched_paren : public saved_state
+{
+ int index;
+ sub_match<BidiIterator> sub;
+ saved_matched_paren(int i, const sub_match<BidiIterator>& s) : saved_state(1), index(i), sub(s){};
+};
+
+template <class BidiIterator>
+struct saved_position : public saved_state
+{
+ const re_syntax_base* pstate;
+ BidiIterator position;
+ saved_position(const re_syntax_base* ps, BidiIterator pos, int i) : saved_state(i), pstate(ps), position(pos){};
+};
+
+template <class BidiIterator>
+struct saved_assertion : public saved_position<BidiIterator>
+{
+ bool positive;
+ saved_assertion(bool p, const re_syntax_base* ps, BidiIterator pos)
+ : saved_position<BidiIterator>(ps, pos, saved_type_assertion), positive(p){};
+};
+
+template <class BidiIterator>
+struct saved_repeater : public saved_state
+{
+ repeater_count<BidiIterator> count;
+ saved_repeater(int i, repeater_count<BidiIterator>** s, BidiIterator start)
+ : saved_state(saved_state_repeater_count), count(i,s,start){}
+};
+
+struct saved_extra_block : public saved_state
+{
+ saved_state *base, *end;
+ saved_extra_block(saved_state* b, saved_state* e)
+ : saved_state(saved_state_extra_block), base(b), end(e) {}
+};
+
+struct save_state_init
+{
+ saved_state** stack;
+ save_state_init(saved_state** base, saved_state** end)
+ : stack(base)
+ {
+ *base = static_cast<saved_state*>(get_mem_block());
+ *end = reinterpret_cast<saved_state*>(reinterpret_cast<char*>(*base)+BOOST_REGEX_BLOCKSIZE);
+ --(*end);
+ (void) new (*end)saved_state(0);
+ BOOST_ASSERT(*end > *base);
+ }
+ ~save_state_init()
+ {
+ put_mem_block(*stack);
+ *stack = 0;
+ }
+};
+
+template <class BidiIterator>
+struct saved_single_repeat : public saved_state
+{
+ std::size_t count;
+ const re_repeat* rep;
+ BidiIterator last_position;
+ saved_single_repeat(std::size_t c, const re_repeat* r, BidiIterator lp, int arg_id)
+ : saved_state(arg_id), count(c), rep(r), last_position(lp){}
+};
+
+template <class Results>
+struct saved_recursion : public saved_state
+{
+ saved_recursion(int id, const re_syntax_base* p, Results* pr)
+ : saved_state(14), recursion_id(id), preturn_address(p), results(*pr)
+ {}
+ int recursion_id;
+ const re_syntax_base* preturn_address;
+ Results results;
+};
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
+{
+ static matcher_proc_type const s_match_vtable[30] =
+ {
+ (&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),
+ &perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_literal,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_start_line,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_end_line,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_wild,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_match,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_within_word,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_word_start,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_word_end,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_backref,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_long_set,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_set,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_jump,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_alt,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_rep,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_combining,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue,
+ // Although this next line *should* be evaluated at compile time, in practice
+ // some compilers (VC++) emit run-time initialisation which breaks thread
+ // safety, so use a dispatch function instead:
+ //(::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),
+ &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_dispatch,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_backstep,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_recursion,
+ };
+
+ push_recursion_stopper();
+ do{
+ while(pstate)
+ {
+ matcher_proc_type proc = s_match_vtable[pstate->type];
+ ++state_count;
+ if(!(this->*proc)())
+ {
+ if(state_count > max_state_count)
+ raise_error(traits_inst, regex_constants::error_space);
+ if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+ m_has_partial_match = true;
+ bool successful_unwind = unwind(false);
+ if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+ m_has_partial_match = true;
+ if(false == successful_unwind)
+ return m_recursive_result;
+ }
+ }
+ }while(unwind(true));
+ return m_recursive_result;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+void perl_matcher<BidiIterator, Allocator, traits>::extend_stack()
+{
+ if(used_block_count)
+ {
+ --used_block_count;
+ saved_state* stack_base;
+ saved_state* backup_state;
+ stack_base = static_cast<saved_state*>(get_mem_block());
+ backup_state = reinterpret_cast<saved_state*>(reinterpret_cast<char*>(stack_base)+BOOST_REGEX_BLOCKSIZE);
+ saved_extra_block* block = static_cast<saved_extra_block*>(backup_state);
+ --block;
+ (void) new (block) saved_extra_block(m_stack_base, m_backup_state);
+ m_stack_base = stack_base;
+ m_backup_state = block;
+ }
+ else
+ raise_error(traits_inst, regex_constants::error_size);
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_matched_paren(int index, const sub_match<BidiIterator>& sub)
+{
+ //BOOST_ASSERT(index);
+ saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_matched_paren<BidiIterator>(index, sub);
+ m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion_stopper()
+{
+ saved_state* pmp = m_backup_state;
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = m_backup_state;
+ --pmp;
+ }
+ (void) new (pmp)saved_state(saved_type_recurse);
+ m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_assertion(const re_syntax_base* ps, bool positive)
+{
+ saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_assertion<BidiIterator>(positive, ps, position);
+ m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_alt(const re_syntax_base* ps)
+{
+ saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_position<BidiIterator>(ps, position, saved_state_alt);
+ m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_non_greedy_repeat(const re_syntax_base* ps)
+{
+ saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_position<BidiIterator>(ps, position, saved_state_non_greedy_long_repeat);
+ m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_repeater_count(int i, repeater_count<BidiIterator>** s)
+{
+ saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_repeater<BidiIterator>(i, s, position);
+ m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id)
+{
+ saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_single_repeat<BidiIterator>(c, r, last_position, state_id);
+ m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int id, const re_syntax_base* p, results_type* presults)
+{
+ saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_recursion<results_type>(id, p, presults);
+ m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
+{
+ int index = static_cast<const re_brace*>(pstate)->index;
+ icase = static_cast<const re_brace*>(pstate)->icase;
+ switch(index)
+ {
+ case 0:
+ pstate = pstate->next.p;
+ break;
+ case -1:
+ case -2:
+ {
+ // forward lookahead assert:
+ const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
+ pstate = pstate->next.p->next.p;
+ push_assertion(next_pstate, index == -1);
+ break;
+ }
+ case -3:
+ {
+ // independent sub-expression, currently this is always recursive:
+ bool old_independent = m_independent;
+ m_independent = true;
+ const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
+ pstate = pstate->next.p->next.p;
+ bool r = match_all_states();
+ pstate = next_pstate;
+ m_independent = old_independent;
+#ifdef BOOST_REGEX_MATCH_EXTRA
+ if(r && (m_match_flags & match_extra))
+ {
+ //
+ // our captures have been stored in *m_presult
+ // we need to unpack them, and insert them
+ // back in the right order when we unwind the stack:
+ //
+ match_results<BidiIterator, Allocator> temp_match(*m_presult);
+ unsigned i;
+ for(i = 0; i < temp_match.size(); ++i)
+ (*m_presult)[i].get_captures().clear();
+ // match everything else:
+ r = match_all_states();
+ // now place the stored captures back:
+ for(i = 0; i < temp_match.size(); ++i)
+ {
+ typedef typename sub_match<BidiIterator>::capture_sequence_type seq;
+ seq& s1 = (*m_presult)[i].get_captures();
+ const seq& s2 = temp_match[i].captures();
+ s1.insert(
+ s1.end(),
+ s2.begin(),
+ s2.end());
+ }
+ }
+#endif
+ return r;
+ }
+ case -4:
+ {
+ // conditional expression:
+ const re_alt* alt = static_cast<const re_alt*>(pstate->next.p);
+ BOOST_ASSERT(alt->type == syntax_element_alt);
+ pstate = alt->next.p;
+ if(pstate->type == syntax_element_assert_backref)
+ {
+ if(!match_assert_backref())
+ pstate = alt->alt.p;
+ break;
+ }
+ else
+ {
+ // zero width assertion, have to match this recursively:
+ BOOST_ASSERT(pstate->type == syntax_element_startmark);
+ bool negated = static_cast<const re_brace*>(pstate)->index == -2;
+ BidiIterator saved_position = position;
+ const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
+ pstate = pstate->next.p->next.p;
+ bool r = match_all_states();
+ position = saved_position;
+ if(negated)
+ r = !r;
+ if(r)
+ pstate = next_pstate;
+ else
+ pstate = alt->alt.p;
+ break;
+ }
+ }
+ case -5:
+ {
+ push_matched_paren(0, (*m_presult)[0]);
+ m_presult->set_first(position, 0, true);
+ pstate = pstate->next.p;
+ break;
+ }
+ default:
+ {
+ BOOST_ASSERT(index > 0);
+ if((m_match_flags & match_nosubs) == 0)
+ {
+ push_matched_paren(index, (*m_presult)[index]);
+ m_presult->set_first(position, index);
+ }
+ pstate = pstate->next.p;
+ break;
+ }
+ }
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_alt()
+{
+ bool take_first, take_second;
+ const re_alt* jmp = static_cast<const re_alt*>(pstate);
+
+ // find out which of these two alternatives we need to take:
+ if(position == last)
+ {
+ take_first = jmp->can_be_null & mask_take;
+ take_second = jmp->can_be_null & mask_skip;
+ }
+ else
+ {
+ take_first = can_start(*position, jmp->_map, (unsigned char)mask_take);
+ take_second = can_start(*position, jmp->_map, (unsigned char)mask_skip);
+ }
+
+ if(take_first)
+ {
+ // we can take the first alternative,
+ // see if we need to push next alternative:
+ if(take_second)
+ {
+ push_alt(jmp->alt.p);
+ }
+ pstate = pstate->next.p;
+ return true;
+ }
+ if(take_second)
+ {
+ pstate = jmp->alt.p;
+ return true;
+ }
+ return false; // neither option is possible
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_rep()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127 4244)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+ const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+
+ // find out which of these two alternatives we need to take:
+ bool take_first, take_second;
+ if(position == last)
+ {
+ take_first = rep->can_be_null & mask_take;
+ take_second = rep->can_be_null & mask_skip;
+ }
+ else
+ {
+ take_first = can_start(*position, rep->_map, (unsigned char)mask_take);
+ take_second = can_start(*position, rep->_map, (unsigned char)mask_skip);
+ }
+
+ if((m_backup_state->state_id != saved_state_repeater_count)
+ || (static_cast<saved_repeater<BidiIterator>*>(m_backup_state)->count.get_id() != rep->state_id)
+ || (next_count->get_id() != rep->state_id))
+ {
+ // we're moving to a different repeat from the last
+ // one, so set up a counter object:
+ push_repeater_count(rep->state_id, &next_count);
+ }
+ //
+ // If we've had at least one repeat already, and the last one
+ // matched the NULL string then set the repeat count to
+ // maximum:
+ //
+ next_count->check_null_repeat(position, rep->max);
+
+ if(next_count->get_count() < rep->min)
+ {
+ // we must take the repeat:
+ if(take_first)
+ {
+ // increase the counter:
+ ++(*next_count);
+ pstate = rep->next.p;
+ return true;
+ }
+ return false;
+ }
+
+ bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
+ if(greedy)
+ {
+ // try and take the repeat if we can:
+ if((next_count->get_count() < rep->max) && take_first)
+ {
+ if(take_second)
+ {
+ // store position in case we fail:
+ push_alt(rep->alt.p);
+ }
+ // increase the counter:
+ ++(*next_count);
+ pstate = rep->next.p;
+ return true;
+ }
+ else if(take_second)
+ {
+ pstate = rep->alt.p;
+ return true;
+ }
+ return false; // can't take anything, fail...
+ }
+ else // non-greedy
+ {
+ // try and skip the repeat if we can:
+ if(take_second)
+ {
+ if((next_count->get_count() < rep->max) && take_first)
+ {
+ // store position in case we fail:
+ push_non_greedy_repeat(rep->next.p);
+ }
+ pstate = rep->alt.p;
+ return true;
+ }
+ if((next_count->get_count() < rep->max) && take_first)
+ {
+ // increase the counter:
+ ++(*next_count);
+ pstate = rep->next.p;
+ return true;
+ }
+ }
+ return false;
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow()
+{
+ unsigned count = 0;
+ const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+ re_syntax_base* psingle = rep->next.p;
+ // match compulsary repeats first:
+ while(count < rep->min)
+ {
+ pstate = psingle;
+ if(!match_wild())
+ return false;
+ ++count;
+ }
+ bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
+ if(greedy)
+ {
+ // repeat for as long as we can:
+ while(count < rep->max)
+ {
+ pstate = psingle;
+ if(!match_wild())
+ break;
+ ++count;
+ }
+ // remember where we got to if this is a leading repeat:
+ if((rep->leading) && (count < rep->max))
+ restart = position;
+ // push backtrack info if available:
+ if(count - rep->min)
+ push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
+ // jump to next state:
+ pstate = rep->alt.p;
+ return true;
+ }
+ else
+ {
+ // non-greedy, push state and return true if we can skip:
+ if(count < rep->max)
+ push_single_repeat(count, rep, position, saved_state_rep_slow_dot);
+ pstate = rep->alt.p;
+ return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
+ }
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()
+{
+ if(m_match_flags & match_not_dot_null)
+ return match_dot_repeat_slow();
+ if((static_cast<const re_dot*>(pstate->next.p)->mask & match_any_mask) == 0)
+ return match_dot_repeat_slow();
+
+ const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+ bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
+ unsigned count = static_cast<unsigned>((std::min)(static_cast<unsigned>(::boost::re_detail::distance(position, last)), static_cast<unsigned>(greedy ? rep->max : rep->min)));
+ if(rep->min > count)
+ {
+ position = last;
+ return false; // not enough text left to match
+ }
+ std::advance(position, count);
+
+ if(greedy)
+ {
+ if((rep->leading) && (count < rep->max))
+ restart = position;
+ // push backtrack info if available:
+ if(count - rep->min)
+ push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
+ // jump to next state:
+ pstate = rep->alt.p;
+ return true;
+ }
+ else
+ {
+ // non-greedy, push state and return true if we can skip:
+ if(count < rep->max)
+ push_single_repeat(count, rep, position, saved_state_rep_fast_dot);
+ pstate = rep->alt.p;
+ return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
+ }
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+ const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+ BOOST_ASSERT(1 == static_cast<const re_literal*>(rep->next.p)->length);
+ const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(rep->next.p) + 1);
+ std::size_t count = 0;
+ //
+ // start by working out how much we can skip:
+ //
+ bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
+ std::size_t desired = greedy ? rep->max : rep->min;
+ if(::boost::is_random_access_iterator<BidiIterator>::value)
+ {
+ BidiIterator end = position;
+ std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired));
+ BidiIterator origin(position);
+ while((position != end) && (traits_inst.translate(*position, icase) == what))
+ {
+ ++position;
+ }
+ count = (unsigned)::boost::re_detail::distance(origin, position);
+ }
+ else
+ {
+ while((count < desired) && (position != last) && (traits_inst.translate(*position, icase) == what))
+ {
+ ++position;
+ ++count;
+ }
+ }
+
+ if(count < rep->min)
+ return false;
+
+ if(greedy)
+ {
+ if((rep->leading) && (count < rep->max))
+ restart = position;
+ // push backtrack info if available:
+ if(count - rep->min)
+ push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
+ // jump to next state:
+ pstate = rep->alt.p;
+ return true;
+ }
+ else
+ {
+ // non-greedy, push state and return true if we can skip:
+ if(count < rep->max)
+ push_single_repeat(count, rep, position, saved_state_rep_char);
+ pstate = rep->alt.p;
+ return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
+ }
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+ const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+ const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;
+ std::size_t count = 0;
+ //
+ // start by working out how much we can skip:
+ //
+ bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
+ std::size_t desired = greedy ? rep->max : rep->min;
+ if(::boost::is_random_access_iterator<BidiIterator>::value)
+ {
+ BidiIterator end = position;
+ std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired));
+ BidiIterator origin(position);
+ while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+ {
+ ++position;
+ }
+ count = (unsigned)::boost::re_detail::distance(origin, position);
+ }
+ else
+ {
+ while((count < desired) && (position != last) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+ {
+ ++position;
+ ++count;
+ }
+ }
+
+ if(count < rep->min)
+ return false;
+
+ if(greedy)
+ {
+ if((rep->leading) && (count < rep->max))
+ restart = position;
+ // push backtrack info if available:
+ if(count - rep->min)
+ push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
+ // jump to next state:
+ pstate = rep->alt.p;
+ return true;
+ }
+ else
+ {
+ // non-greedy, push state and return true if we can skip:
+ if(count < rep->max)
+ push_single_repeat(count, rep, position, saved_state_rep_short_set);
+ pstate = rep->alt.p;
+ return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
+ }
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+ typedef typename traits::char_class_type mask_type;
+ const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+ const re_set_long<mask_type>* set = static_cast<const re_set_long<mask_type>*>(pstate->next.p);
+ std::size_t count = 0;
+ //
+ // start by working out how much we can skip:
+ //
+ bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
+ std::size_t desired = greedy ? rep->max : rep->min;
+ if(::boost::is_random_access_iterator<BidiIterator>::value)
+ {
+ BidiIterator end = position;
+ std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired));
+ BidiIterator origin(position);
+ while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
+ {
+ ++position;
+ }
+ count = (unsigned)::boost::re_detail::distance(origin, position);
+ }
+ else
+ {
+ while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
+ {
+ ++position;
+ ++count;
+ }
+ }
+
+ if(count < rep->min)
+ return false;
+
+ if(greedy)
+ {
+ if((rep->leading) && (count < rep->max))
+ restart = position;
+ // push backtrack info if available:
+ if(count - rep->min)
+ push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
+ // jump to next state:
+ pstate = rep->alt.p;
+ return true;
+ }
+ else
+ {
+ // non-greedy, push state and return true if we can skip:
+ if(count < rep->max)
+ push_single_repeat(count, rep, position, saved_state_rep_long_set);
+ pstate = rep->alt.p;
+ return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
+ }
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()
+{
+ BOOST_ASSERT(pstate->type == syntax_element_recurse);
+ //
+ // Backup call stack:
+ //
+ push_recursion_pop();
+ //
+ // Set new call stack:
+ //
+ if(recursion_stack_position >= static_cast<int>(sizeof(recursion_stack)/sizeof(recursion_stack[0])))
+ {
+ return false;
+ }
+ recursion_stack[recursion_stack_position].preturn_address = pstate->next.p;
+ recursion_stack[recursion_stack_position].results = *m_presult;
+ pstate = static_cast<const re_jump*>(pstate)->alt.p;
+ recursion_stack[recursion_stack_position].id = static_cast<const re_brace*>(pstate)->index;
+ ++recursion_stack_position;
+ //BOOST_ASSERT(recursion_stack[recursion_stack_position-1].id);
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()
+{
+ int index = static_cast<const re_brace*>(pstate)->index;
+ icase = static_cast<const re_brace*>(pstate)->icase;
+ if(index > 0)
+ {
+ if((m_match_flags & match_nosubs) == 0)
+ {
+ m_presult->set_second(position, index);
+ }
+ if(recursion_stack_position)
+ {
+ if(index == recursion_stack[recursion_stack_position-1].id)
+ {
+ --recursion_stack_position;
+ pstate = recursion_stack[recursion_stack_position].preturn_address;
+ *m_presult = recursion_stack[recursion_stack_position].results;
+ push_recursion(recursion_stack[recursion_stack_position].id, recursion_stack[recursion_stack_position].preturn_address, &recursion_stack[recursion_stack_position].results);
+ }
+ }
+ }
+ else if((index < 0) && (index != -4))
+ {
+ // matched forward lookahead:
+ pstate = 0;
+ return true;
+ }
+ pstate = pstate->next.p;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_match()
+{
+ if(recursion_stack_position)
+ {
+ BOOST_ASSERT(0 == recursion_stack[recursion_stack_position-1].id);
+ --recursion_stack_position;
+ pstate = recursion_stack[recursion_stack_position].preturn_address;
+ *m_presult = recursion_stack[recursion_stack_position].results;
+ push_recursion(recursion_stack[recursion_stack_position].id, recursion_stack[recursion_stack_position].preturn_address, &recursion_stack[recursion_stack_position].results);
+ return true;
+ }
+ if((m_match_flags & match_not_null) && (position == (*m_presult)[0].first))
+ return false;
+ if((m_match_flags & match_all) && (position != last))
+ return false;
+ if((m_match_flags & regex_constants::match_not_initial_null) && (position == search_base))
+ return false;
+ m_presult->set_second(position);
+ pstate = 0;
+ m_has_found_match = true;
+ if((m_match_flags & match_posix) == match_posix)
+ {
+ m_result.maybe_assign(*m_presult);
+ if((m_match_flags & match_any) == 0)
+ return false;
+ }
+#ifdef BOOST_REGEX_MATCH_EXTRA
+ if(match_extra & m_match_flags)
+ {
+ for(unsigned i = 0; i < m_presult->size(); ++i)
+ if((*m_presult)[i].matched)
+ ((*m_presult)[i]).get_captures().push_back((*m_presult)[i]);
+ }
+#endif
+ return true;
+}
+
+/****************************************************************************
+
+Unwind and associated proceedures follow, these perform what normal stack
+unwinding does in the recursive implementation.
+
+****************************************************************************/
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind(bool have_match)
+{
+ static unwind_proc_type const s_unwind_table[18] =
+ {
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_end,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_paren,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_alt,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop,
+ };
+
+ m_recursive_result = have_match;
+ unwind_proc_type unwinder;
+ bool cont;
+ //
+ // keep unwinding our stack until we have something to do:
+ //
+ do
+ {
+ unwinder = s_unwind_table[m_backup_state->state_id];
+ cont = (this->*unwinder)(m_recursive_result);
+ }while(cont);
+ //
+ // return true if we have more states to try:
+ //
+ return pstate ? true : false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_end(bool)
+{
+ pstate = 0; // nothing left to search
+ return false; // end of stack nothing more to search
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_paren(bool have_match)
+{
+ saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
+ // restore previous values if no match was found:
+ if(have_match == false)
+ {
+ m_presult->set_first(pmp->sub.first, pmp->index, pmp->index == 0);
+ m_presult->set_second(pmp->sub.second, pmp->index, pmp->sub.matched, pmp->index == 0);
+ }
+#ifdef BOOST_REGEX_MATCH_EXTRA
+ //
+ // we have a match, push the capture information onto the stack:
+ //
+ else if(pmp->sub.matched && (match_extra & m_match_flags))
+ ((*m_presult)[pmp->index]).get_captures().push_back(pmp->sub);
+#endif
+ // unwind stack:
+ m_backup_state = pmp+1;
+ boost::re_detail::inplace_destroy(pmp);
+ return true; // keep looking
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper(bool)
+{
+ boost::re_detail::inplace_destroy(m_backup_state++);
+ pstate = 0; // nothing left to search
+ return false; // end of stack nothing more to search
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion(bool r)
+{
+ saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
+ pstate = pmp->pstate;
+ position = pmp->position;
+ bool result = (r == pmp->positive);
+ m_recursive_result = pmp->positive ? r : !r;
+ boost::re_detail::inplace_destroy(pmp++);
+ m_backup_state = pmp;
+ return !result; // return false if the assertion was matched to stop search.
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_alt(bool r)
+{
+ saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+ if(!r)
+ {
+ pstate = pmp->pstate;
+ position = pmp->position;
+ }
+ boost::re_detail::inplace_destroy(pmp++);
+ m_backup_state = pmp;
+ return r;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter(bool)
+{
+ saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
+ boost::re_detail::inplace_destroy(pmp++);
+ m_backup_state = pmp;
+ return true; // keep looking
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block(bool)
+{
+ saved_extra_block* pmp = static_cast<saved_extra_block*>(m_backup_state);
+ void* condemmed = m_stack_base;
+ m_stack_base = pmp->base;
+ m_backup_state = pmp->end;
+ boost::re_detail::inplace_destroy(pmp);
+ put_mem_block(condemmed);
+ return true; // keep looking
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::destroy_single_repeat()
+{
+ saved_single_repeat<BidiIterator>* p = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+ boost::re_detail::inplace_destroy(p++);
+ m_backup_state = p;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat(bool r)
+{
+ saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+
+ // if we have a match, just discard this state:
+ if(r)
+ {
+ destroy_single_repeat();
+ return true;
+ }
+
+ const re_repeat* rep = pmp->rep;
+ std::size_t count = pmp->count;
+ BOOST_ASSERT(rep->next.p != 0);
+ BOOST_ASSERT(rep->alt.p != 0);
+
+ count -= rep->min;
+
+ if((m_match_flags & match_partial) && (position == last))
+ m_has_partial_match = true;
+
+ BOOST_ASSERT(count);
+ position = pmp->last_position;
+
+ // backtrack till we can skip out:
+ do
+ {
+ --position;
+ --count;
+ ++state_count;
+ }while(count && !can_start(*position, rep->_map, mask_skip));
+
+ // if we've hit base, destroy this state:
+ if(count == 0)
+ {
+ destroy_single_repeat();
+ if(!can_start(*position, rep->_map, mask_skip))
+ return true;
+ }
+ else
+ {
+ pmp->count = count + rep->min;
+ pmp->last_position = position;
+ }
+ pstate = rep->alt.p;
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat(bool r)
+{
+ saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+
+ // if we have a match, just discard this state:
+ if(r)
+ {
+ destroy_single_repeat();
+ return true;
+ }
+
+ const re_repeat* rep = pmp->rep;
+ std::size_t count = pmp->count;
+ BOOST_ASSERT(rep->type == syntax_element_dot_rep);
+ BOOST_ASSERT(rep->next.p != 0);
+ BOOST_ASSERT(rep->alt.p != 0);
+ BOOST_ASSERT(rep->next.p->type == syntax_element_wild);
+
+ BOOST_ASSERT(count < rep->max);
+ pstate = rep->next.p;
+ position = pmp->last_position;
+
+ if(position != last)
+ {
+ // wind forward until we can skip out of the repeat:
+ do
+ {
+ if(!match_wild())
+ {
+ // failed repeat match, discard this state and look for another:
+ destroy_single_repeat();
+ return true;
+ }
+ ++count;
+ ++state_count;
+ pstate = rep->next.p;
+ }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
+ }
+ if(position == last)
+ {
+ // can't repeat any more, remove the pushed state:
+ destroy_single_repeat();
+ if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+ m_has_partial_match = true;
+ if(0 == (rep->can_be_null & mask_skip))
+ return true;
+ }
+ else if(count == rep->max)
+ {
+ // can't repeat any more, remove the pushed state:
+ destroy_single_repeat();
+ if(!can_start(*position, rep->_map, mask_skip))
+ return true;
+ }
+ else
+ {
+ pmp->count = count;
+ pmp->last_position = position;
+ }
+ pstate = rep->alt.p;
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat(bool r)
+{
+ saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+
+ // if we have a match, just discard this state:
+ if(r)
+ {
+ destroy_single_repeat();
+ return true;
+ }
+
+ const re_repeat* rep = pmp->rep;
+ std::size_t count = pmp->count;
+
+ BOOST_ASSERT(count < rep->max);
+ position = pmp->last_position;
+ if(position != last)
+ {
+
+ // wind forward until we can skip out of the repeat:
+ do
+ {
+ ++position;
+ ++count;
+ ++state_count;
+ }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
+ }
+
+ if(position == last)
+ {
+ // can't repeat any more, remove the pushed state:
+ destroy_single_repeat();
+ if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+ m_has_partial_match = true;
+ if(0 == (rep->can_be_null & mask_skip))
+ return true;
+ }
+ else if(count == rep->max)
+ {
+ // can't repeat any more, remove the pushed state:
+ destroy_single_repeat();
+ if(!can_start(*position, rep->_map, mask_skip))
+ return true;
+ }
+ else
+ {
+ pmp->count = count;
+ pmp->last_position = position;
+ }
+ pstate = rep->alt.p;
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat(bool r)
+{
+ saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+
+ // if we have a match, just discard this state:
+ if(r)
+ {
+ destroy_single_repeat();
+ return true;
+ }
+
+ const re_repeat* rep = pmp->rep;
+ std::size_t count = pmp->count;
+ pstate = rep->next.p;
+ const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);
+ position = pmp->last_position;
+
+ BOOST_ASSERT(rep->type == syntax_element_char_rep);
+ BOOST_ASSERT(rep->next.p != 0);
+ BOOST_ASSERT(rep->alt.p != 0);
+ BOOST_ASSERT(rep->next.p->type == syntax_element_literal);
+ BOOST_ASSERT(count < rep->max);
+
+ if(position != last)
+ {
+ // wind forward until we can skip out of the repeat:
+ do
+ {
+ if(traits_inst.translate(*position, icase) != what)
+ {
+ // failed repeat match, discard this state and look for another:
+ destroy_single_repeat();
+ return true;
+ }
+ ++count;
+ ++ position;
+ ++state_count;
+ pstate = rep->next.p;
+ }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
+ }
+ // remember where we got to if this is a leading repeat:
+ if((rep->leading) && (count < rep->max))
+ restart = position;
+ if(position == last)
+ {
+ // can't repeat any more, remove the pushed state:
+ destroy_single_repeat();
+ if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+ m_has_partial_match = true;
+ if(0 == (rep->can_be_null & mask_skip))
+ return true;
+ }
+ else if(count == rep->max)
+ {
+ // can't repeat any more, remove the pushed state:
+ destroy_single_repeat();
+ if(!can_start(*position, rep->_map, mask_skip))
+ return true;
+ }
+ else
+ {
+ pmp->count = count;
+ pmp->last_position = position;
+ }
+ pstate = rep->alt.p;
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat(bool r)
+{
+ saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+
+ // if we have a match, just discard this state:
+ if(r)
+ {
+ destroy_single_repeat();
+ return true;
+ }
+
+ const re_repeat* rep = pmp->rep;
+ std::size_t count = pmp->count;
+ pstate = rep->next.p;
+ const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;
+ position = pmp->last_position;
+
+ BOOST_ASSERT(rep->type == syntax_element_short_set_rep);
+ BOOST_ASSERT(rep->next.p != 0);
+ BOOST_ASSERT(rep->alt.p != 0);
+ BOOST_ASSERT(rep->next.p->type == syntax_element_set);
+ BOOST_ASSERT(count < rep->max);
+
+ if(position != last)
+ {
+ // wind forward until we can skip out of the repeat:
+ do
+ {
+ if(!map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+ {
+ // failed repeat match, discard this state and look for another:
+ destroy_single_repeat();
+ return true;
+ }
+ ++count;
+ ++ position;
+ ++state_count;
+ pstate = rep->next.p;
+ }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
+ }
+ // remember where we got to if this is a leading repeat:
+ if((rep->leading) && (count < rep->max))
+ restart = position;
+ if(position == last)
+ {
+ // can't repeat any more, remove the pushed state:
+ destroy_single_repeat();
+ if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+ m_has_partial_match = true;
+ if(0 == (rep->can_be_null & mask_skip))
+ return true;
+ }
+ else if(count == rep->max)
+ {
+ // can't repeat any more, remove the pushed state:
+ destroy_single_repeat();
+ if(!can_start(*position, rep->_map, mask_skip))
+ return true;
+ }
+ else
+ {
+ pmp->count = count;
+ pmp->last_position = position;
+ }
+ pstate = rep->alt.p;
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat(bool r)
+{
+ typedef typename traits::char_class_type mask_type;
+ saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
+
+ // if we have a match, just discard this state:
+ if(r)
+ {
+ destroy_single_repeat();
+ return true;
+ }
+
+ const re_repeat* rep = pmp->rep;
+ std::size_t count = pmp->count;
+ pstate = rep->next.p;
+ const re_set_long<mask_type>* set = static_cast<const re_set_long<mask_type>*>(pstate);
+ position = pmp->last_position;
+
+ BOOST_ASSERT(rep->type == syntax_element_long_set_rep);
+ BOOST_ASSERT(rep->next.p != 0);
+ BOOST_ASSERT(rep->alt.p != 0);
+ BOOST_ASSERT(rep->next.p->type == syntax_element_long_set);
+ BOOST_ASSERT(count < rep->max);
+
+ if(position != last)
+ {
+ // wind forward until we can skip out of the repeat:
+ do
+ {
+ if(position == re_is_set_member(position, last, set, re.get_data(), icase))
+ {
+ // failed repeat match, discard this state and look for another:
+ destroy_single_repeat();
+ return true;
+ }
+ ++position;
+ ++count;
+ ++state_count;
+ pstate = rep->next.p;
+ }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
+ }
+ // remember where we got to if this is a leading repeat:
+ if((rep->leading) && (count < rep->max))
+ restart = position;
+ if(position == last)
+ {
+ // can't repeat any more, remove the pushed state:
+ destroy_single_repeat();
+ if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+ m_has_partial_match = true;
+ if(0 == (rep->can_be_null & mask_skip))
+ return true;
+ }
+ else if(count == rep->max)
+ {
+ // can't repeat any more, remove the pushed state:
+ destroy_single_repeat();
+ if(!can_start(*position, rep->_map, mask_skip))
+ return true;
+ }
+ else
+ {
+ pmp->count = count;
+ pmp->last_position = position;
+ }
+ pstate = rep->alt.p;
+ return false;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat(bool r)
+{
+ saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+ if(!r)
+ {
+ position = pmp->position;
+ pstate = pmp->pstate;
+ ++(*next_count);
+ }
+ boost::re_detail::inplace_destroy(pmp++);
+ m_backup_state = pmp;
+ return r;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion(bool r)
+{
+ saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
+ if(!r)
+ {
+ recursion_stack[recursion_stack_position].id = pmp->recursion_id;
+ recursion_stack[recursion_stack_position].preturn_address = pmp->preturn_address;
+ recursion_stack[recursion_stack_position].results = pmp->results;
+ ++recursion_stack_position;
+ }
+ boost::re_detail::inplace_destroy(pmp++);
+ m_backup_state = pmp;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop(bool r)
+{
+ saved_state* pmp = static_cast<saved_state*>(m_backup_state);
+ if(!r)
+ {
+ --recursion_stack_position;
+ }
+ boost::re_detail::inplace_destroy(pmp++);
+ m_backup_state = pmp;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+void perl_matcher<BidiIterator, Allocator, traits>::push_recursion_pop()
+{
+ saved_state* pmp = static_cast<saved_state*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_state*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_state(15);
+ m_backup_state = pmp;
+}
+/*
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_parenthesis_pop(bool r)
+{
+ saved_state* pmp = static_cast<saved_state*>(m_backup_state);
+ if(!r)
+ {
+ --parenthesis_stack_position;
+ }
+ boost::re_detail::inplace_destroy(pmp++);
+ m_backup_state = pmp;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+void perl_matcher<BidiIterator, Allocator, traits>::push_parenthesis_pop()
+{
+ saved_state* pmp = static_cast<saved_state*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_state*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_state(16);
+ m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_parenthesis_push(bool r)
+{
+ saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+ if(!r)
+ {
+ parenthesis_stack[parenthesis_stack_position++] = pmp->position;
+ }
+ boost::re_detail::inplace_destroy(pmp++);
+ m_backup_state = pmp;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_parenthesis_push(BidiIterator p)
+{
+ saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_position<BidiIterator>(0, p, 17);
+ m_backup_state = pmp;
+}
+*/
+} // namespace re_detail
+} // namespace boost
+
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
+
diff --git a/ext/boost/regex/v4/perl_matcher_recursive.hpp b/ext/boost/regex/v4/perl_matcher_recursive.hpp
new file mode 100644
index 0000000000..48f08b7b8d
--- /dev/null
+++ b/ext/boost/regex/v4/perl_matcher_recursive.hpp
@@ -0,0 +1,992 @@
+/*
+ *
+ * Copyright (c) 2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE perl_matcher_common.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Definitions of perl_matcher member functions that are
+ * specific to the recursive implementation.
+ */
+
+#ifndef BOOST_REGEX_V4_PERL_MATCHER_RECURSIVE_HPP
+#define BOOST_REGEX_V4_PERL_MATCHER_RECURSIVE_HPP
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4800)
+#endif
+
+namespace boost{
+namespace re_detail{
+
+template <class BidiIterator>
+class backup_subex
+{
+ int index;
+ sub_match<BidiIterator> sub;
+public:
+ template <class A>
+ backup_subex(const match_results<BidiIterator, A>& w, int i)
+ : index(i), sub(w[i], false) {}
+ template <class A>
+ void restore(match_results<BidiIterator, A>& w)
+ {
+ w.set_first(sub.first, index, index == 0);
+ w.set_second(sub.second, index, sub.matched, index == 0);
+ }
+ const sub_match<BidiIterator>& get() { return sub; }
+};
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
+{
+ static matcher_proc_type const s_match_vtable[30] =
+ {
+ (&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),
+ &perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_literal,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_start_line,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_end_line,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_wild,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_match,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_within_word,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_word_start,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_word_end,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_backref,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_long_set,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_set,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_jump,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_alt,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_rep,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_combining,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue,
+ // Although this next line *should* be evaluated at compile time, in practice
+ // some compilers (VC++) emit run-time initialisation which breaks thread
+ // safety, so use a dispatch function instead:
+ //(::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),
+ &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_dispatch,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_backstep,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_recursion,
+ };
+
+ if(state_count > max_state_count)
+ raise_error(traits_inst, regex_constants::error_space);
+ while(pstate)
+ {
+ matcher_proc_type proc = s_match_vtable[pstate->type];
+ ++state_count;
+ if(!(this->*proc)())
+ {
+ if((m_match_flags & match_partial) && (position == last) && (position != search_base))
+ m_has_partial_match = true;
+ return 0;
+ }
+ }
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
+{
+ int index = static_cast<const re_brace*>(pstate)->index;
+ icase = static_cast<const re_brace*>(pstate)->icase;
+ bool r = true;
+ switch(index)
+ {
+ case 0:
+ pstate = pstate->next.p;
+ break;
+ case -1:
+ case -2:
+ {
+ // forward lookahead assert:
+ BidiIterator old_position(position);
+ const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
+ pstate = pstate->next.p->next.p;
+ r = match_all_states();
+ pstate = next_pstate;
+ position = old_position;
+ if((r && (index != -1)) || (!r && (index != -2)))
+ r = false;
+ else
+ r = true;
+ break;
+ }
+ case -3:
+ {
+ // independent sub-expression:
+ bool old_independent = m_independent;
+ m_independent = true;
+ const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
+ pstate = pstate->next.p->next.p;
+ r = match_all_states();
+ pstate = next_pstate;
+ m_independent = old_independent;
+#ifdef BOOST_REGEX_MATCH_EXTRA
+ if(r && (m_match_flags & match_extra))
+ {
+ //
+ // our captures have been stored in *m_presult
+ // we need to unpack them, and insert them
+ // back in the right order when we unwind the stack:
+ //
+ unsigned i;
+ match_results<BidiIterator, Allocator> tm(*m_presult);
+ for(i = 0; i < tm.size(); ++i)
+ (*m_presult)[i].get_captures().clear();
+ // match everything else:
+ r = match_all_states();
+ // now place the stored captures back:
+ for(i = 0; i < tm.size(); ++i)
+ {
+ typedef typename sub_match<BidiIterator>::capture_sequence_type seq;
+ seq& s1 = (*m_presult)[i].get_captures();
+ const seq& s2 = tm[i].captures();
+ s1.insert(
+ s1.end(),
+ s2.begin(),
+ s2.end());
+ }
+ }
+#endif
+ break;
+ }
+ case -4:
+ {
+ // conditional expression:
+ const re_alt* alt = static_cast<const re_alt*>(pstate->next.p);
+ BOOST_ASSERT(alt->type == syntax_element_alt);
+ pstate = alt->next.p;
+ if(pstate->type == syntax_element_assert_backref)
+ {
+ if(!match_assert_backref())
+ pstate = alt->alt.p;
+ break;
+ }
+ else
+ {
+ // zero width assertion, have to match this recursively:
+ BOOST_ASSERT(pstate->type == syntax_element_startmark);
+ bool negated = static_cast<const re_brace*>(pstate)->index == -2;
+ BidiIterator saved_position = position;
+ const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
+ pstate = pstate->next.p->next.p;
+ bool r = match_all_states();
+ position = saved_position;
+ if(negated)
+ r = !r;
+ if(r)
+ pstate = next_pstate;
+ else
+ pstate = alt->alt.p;
+ break;
+ }
+ }
+ case -5:
+ {
+ // Reset start of $0, since we have a \K escape
+ backup_subex<BidiIterator> sub(*m_presult, 0);
+ m_presult->set_first(position, 0, true);
+ pstate = pstate->next.p;
+ r = match_all_states();
+ if(r == false)
+ sub.restore(*m_presult);
+ break;
+ }
+ default:
+ {
+ BOOST_ASSERT(index > 0);
+ if((m_match_flags & match_nosubs) == 0)
+ {
+ backup_subex<BidiIterator> sub(*m_presult, index);
+ m_presult->set_first(position, index);
+ pstate = pstate->next.p;
+ r = match_all_states();
+ if(r == false)
+ sub.restore(*m_presult);
+#ifdef BOOST_REGEX_MATCH_EXTRA
+ //
+ // we have a match, push the capture information onto the stack:
+ //
+ else if(sub.get().matched && (match_extra & m_match_flags))
+ ((*m_presult)[index]).get_captures().push_back(sub.get());
+#endif
+ }
+ else
+ {
+ pstate = pstate->next.p;
+ }
+ break;
+ }
+ }
+ return r;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_alt()
+{
+ bool take_first, take_second;
+ const re_alt* jmp = static_cast<const re_alt*>(pstate);
+
+ // find out which of these two alternatives we need to take:
+ if(position == last)
+ {
+ take_first = jmp->can_be_null & mask_take;
+ take_second = jmp->can_be_null & mask_skip;
+ }
+ else
+ {
+ take_first = can_start(*position, jmp->_map, (unsigned char)mask_take);
+ take_second = can_start(*position, jmp->_map, (unsigned char)mask_skip);
+ }
+
+ if(take_first)
+ {
+ // we can take the first alternative,
+ // see if we need to push next alternative:
+ if(take_second)
+ {
+ BidiIterator oldposition(position);
+ const re_syntax_base* old_pstate = jmp->alt.p;
+ pstate = pstate->next.p;
+ if(!match_all_states())
+ {
+ pstate = old_pstate;
+ position = oldposition;
+ }
+ return true;
+ }
+ pstate = pstate->next.p;
+ return true;
+ }
+ if(take_second)
+ {
+ pstate = jmp->alt.p;
+ return true;
+ }
+ return false; // neither option is possible
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_rep()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127 4244)
+#endif
+ const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+ //
+ // Always copy the repeat count, so that the state is restored
+ // when we exit this scope:
+ //
+ repeater_count<BidiIterator> r(rep->state_id, &next_count, position);
+ //
+ // If we've had at least one repeat already, and the last one
+ // matched the NULL string then set the repeat count to
+ // maximum:
+ //
+ next_count->check_null_repeat(position, rep->max);
+
+ // find out which of these two alternatives we need to take:
+ bool take_first, take_second;
+ if(position == last)
+ {
+ take_first = rep->can_be_null & mask_take;
+ take_second = rep->can_be_null & mask_skip;
+ }
+ else
+ {
+ take_first = can_start(*position, rep->_map, (unsigned char)mask_take);
+ take_second = can_start(*position, rep->_map, (unsigned char)mask_skip);
+ }
+
+ if(next_count->get_count() < rep->min)
+ {
+ // we must take the repeat:
+ if(take_first)
+ {
+ // increase the counter:
+ ++(*next_count);
+ pstate = rep->next.p;
+ return match_all_states();
+ }
+ return false;
+ }
+ bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
+ if(greedy)
+ {
+ // try and take the repeat if we can:
+ if((next_count->get_count() < rep->max) && take_first)
+ {
+ // store position in case we fail:
+ BidiIterator pos = position;
+ // increase the counter:
+ ++(*next_count);
+ pstate = rep->next.p;
+ if(match_all_states())
+ return true;
+ // failed repeat, reset posistion and fall through for alternative:
+ position = pos;
+ }
+ if(take_second)
+ {
+ pstate = rep->alt.p;
+ return true;
+ }
+ return false; // can't take anything, fail...
+ }
+ else // non-greedy
+ {
+ // try and skip the repeat if we can:
+ if(take_second)
+ {
+ // store position in case we fail:
+ BidiIterator pos = position;
+ pstate = rep->alt.p;
+ if(match_all_states())
+ return true;
+ // failed alternative, reset posistion and fall through for repeat:
+ position = pos;
+ }
+ if((next_count->get_count() < rep->max) && take_first)
+ {
+ // increase the counter:
+ ++(*next_count);
+ pstate = rep->next.p;
+ return match_all_states();
+ }
+ }
+ return false;
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+ unsigned count = 0;
+ const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+ re_syntax_base* psingle = rep->next.p;
+ // match compulsary repeats first:
+ while(count < rep->min)
+ {
+ pstate = psingle;
+ if(!match_wild())
+ return false;
+ ++count;
+ }
+ bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
+ if(greedy)
+ {
+ // normal repeat:
+ while(count < rep->max)
+ {
+ pstate = psingle;
+ if(!match_wild())
+ break;
+ ++count;
+ }
+ if((rep->leading) && (count < rep->max))
+ restart = position;
+ pstate = rep;
+ return backtrack_till_match(count - rep->min);
+ }
+ else
+ {
+ // non-greedy, keep trying till we get a match:
+ BidiIterator save_pos;
+ do
+ {
+ if((rep->leading) && (rep->max == UINT_MAX))
+ restart = position;
+ pstate = rep->alt.p;
+ save_pos = position;
+ ++state_count;
+ if(match_all_states())
+ return true;
+ if(count >= rep->max)
+ return false;
+ ++count;
+ pstate = psingle;
+ position = save_pos;
+ if(!match_wild())
+ return false;
+ }while(true);
+ }
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+ if(m_match_flags & match_not_dot_null)
+ return match_dot_repeat_slow();
+ if((static_cast<const re_dot*>(pstate->next.p)->mask & match_any_mask) == 0)
+ return match_dot_repeat_slow();
+ //
+ // start by working out how much we can skip:
+ //
+ const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4267)
+#endif
+ bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
+ std::size_t count = (std::min)(static_cast<std::size_t>(::boost::re_detail::distance(position, last)), static_cast<std::size_t>(greedy ? rep->max : rep->min));
+ if(rep->min > count)
+ {
+ position = last;
+ return false; // not enough text left to match
+ }
+ std::advance(position, count);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+ if((rep->leading) && (count < rep->max) && greedy)
+ restart = position;
+ if(greedy)
+ return backtrack_till_match(count - rep->min);
+
+ // non-greedy, keep trying till we get a match:
+ BidiIterator save_pos;
+ do
+ {
+ while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
+ {
+ ++position;
+ ++count;
+ }
+ if((rep->leading) && (rep->max == UINT_MAX))
+ restart = position;
+ pstate = rep->alt.p;
+ save_pos = position;
+ ++state_count;
+ if(match_all_states())
+ return true;
+ if(count >= rep->max)
+ return false;
+ if(save_pos == last)
+ return false;
+ position = ++save_pos;
+ ++count;
+ }while(true);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#pragma warning(disable:4267)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+ const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+ BOOST_ASSERT(1 == static_cast<const re_literal*>(rep->next.p)->length);
+ const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(rep->next.p) + 1);
+ //
+ // start by working out how much we can skip:
+ //
+ bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
+ std::size_t count, desired;
+ if(::boost::is_random_access_iterator<BidiIterator>::value)
+ {
+ desired =
+ (std::min)(
+ (std::size_t)(greedy ? rep->max : rep->min),
+ (std::size_t)::boost::re_detail::distance(position, last));
+ count = desired;
+ ++desired;
+ if(icase)
+ {
+ while(--desired && (traits_inst.translate_nocase(*position) == what))
+ {
+ ++position;
+ }
+ }
+ else
+ {
+ while(--desired && (traits_inst.translate(*position) == what))
+ {
+ ++position;
+ }
+ }
+ count = count - desired;
+ }
+ else
+ {
+ count = 0;
+ desired = greedy ? rep->max : rep->min;
+ while((count < desired) && (position != last) && (traits_inst.translate(*position, icase) == what))
+ {
+ ++position;
+ ++count;
+ }
+ }
+ if((rep->leading) && (count < rep->max) && greedy)
+ restart = position;
+ if(count < rep->min)
+ return false;
+
+ if(greedy)
+ return backtrack_till_match(count - rep->min);
+
+ // non-greedy, keep trying till we get a match:
+ BidiIterator save_pos;
+ do
+ {
+ while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
+ {
+ if((traits_inst.translate(*position, icase) == what))
+ {
+ ++position;
+ ++count;
+ }
+ else
+ return false; // counldn't repeat even though it was the only option
+ }
+ if((rep->leading) && (rep->max == UINT_MAX))
+ restart = position;
+ pstate = rep->alt.p;
+ save_pos = position;
+ ++state_count;
+ if(match_all_states())
+ return true;
+ if(count >= rep->max)
+ return false;
+ position = save_pos;
+ if(position == last)
+ return false;
+ if(traits_inst.translate(*position, icase) == what)
+ {
+ ++position;
+ ++count;
+ }
+ else
+ {
+ return false;
+ }
+ }while(true);
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+ const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+ const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;
+ unsigned count = 0;
+ //
+ // start by working out how much we can skip:
+ //
+ bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
+ std::size_t desired = greedy ? rep->max : rep->min;
+ if(::boost::is_random_access_iterator<BidiIterator>::value)
+ {
+ BidiIterator end = position;
+ std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired));
+ BidiIterator origin(position);
+ while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+ {
+ ++position;
+ }
+ count = (unsigned)::boost::re_detail::distance(origin, position);
+ }
+ else
+ {
+ while((count < desired) && (position != last) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+ {
+ ++position;
+ ++count;
+ }
+ }
+ if((rep->leading) && (count < rep->max) && greedy)
+ restart = position;
+ if(count < rep->min)
+ return false;
+
+ if(greedy)
+ return backtrack_till_match(count - rep->min);
+
+ // non-greedy, keep trying till we get a match:
+ BidiIterator save_pos;
+ do
+ {
+ while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
+ {
+ if(map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+ {
+ ++position;
+ ++count;
+ }
+ else
+ return false; // counldn't repeat even though it was the only option
+ }
+ if((rep->leading) && (rep->max == UINT_MAX))
+ restart = position;
+ pstate = rep->alt.p;
+ save_pos = position;
+ ++state_count;
+ if(match_all_states())
+ return true;
+ if(count >= rep->max)
+ return false;
+ position = save_pos;
+ if(position == last)
+ return false;
+ if(map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
+ {
+ ++position;
+ ++count;
+ }
+ else
+ {
+ return false;
+ }
+ }while(true);
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+#ifdef __BORLANDC__
+#pragma option push -w-8008 -w-8066 -w-8004
+#endif
+ typedef typename traits::char_class_type char_class_type;
+ const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+ const re_set_long<char_class_type>* set = static_cast<const re_set_long<char_class_type>*>(pstate->next.p);
+ unsigned count = 0;
+ //
+ // start by working out how much we can skip:
+ //
+ bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
+ std::size_t desired = greedy ? rep->max : rep->min;
+ if(::boost::is_random_access_iterator<BidiIterator>::value)
+ {
+ BidiIterator end = position;
+ std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired));
+ BidiIterator origin(position);
+ while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
+ {
+ ++position;
+ }
+ count = (unsigned)::boost::re_detail::distance(origin, position);
+ }
+ else
+ {
+ while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
+ {
+ ++position;
+ ++count;
+ }
+ }
+ if((rep->leading) && (count < rep->max) && greedy)
+ restart = position;
+ if(count < rep->min)
+ return false;
+
+ if(greedy)
+ return backtrack_till_match(count - rep->min);
+
+ // non-greedy, keep trying till we get a match:
+ BidiIterator save_pos;
+ do
+ {
+ while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
+ {
+ if(position != re_is_set_member(position, last, set, re.get_data(), icase))
+ {
+ ++position;
+ ++count;
+ }
+ else
+ return false; // counldn't repeat even though it was the only option
+ }
+ if((rep->leading) && (rep->max == UINT_MAX))
+ restart = position;
+ pstate = rep->alt.p;
+ save_pos = position;
+ ++state_count;
+ if(match_all_states())
+ return true;
+ if(count >= rep->max)
+ return false;
+ position = save_pos;
+ if(position == last)
+ return false;
+ if(position != re_is_set_member(position, last, set, re.get_data(), icase))
+ {
+ ++position;
+ ++count;
+ }
+ else
+ {
+ return false;
+ }
+ }while(true);
+#ifdef __BORLANDC__
+#pragma option pop
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::backtrack_till_match(std::size_t count)
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+ if((m_match_flags & match_partial) && (position == last))
+ m_has_partial_match = true;
+
+ const re_repeat* rep = static_cast<const re_repeat*>(pstate);
+ BidiIterator backtrack = position;
+ if(position == last)
+ {
+ if(rep->can_be_null & mask_skip)
+ {
+ pstate = rep->alt.p;
+ if(match_all_states())
+ return true;
+ }
+ if(count)
+ {
+ position = --backtrack;
+ --count;
+ }
+ else
+ return false;
+ }
+ do
+ {
+ while(count && !can_start(*position, rep->_map, mask_skip))
+ {
+ --position;
+ --count;
+ ++state_count;
+ }
+ pstate = rep->alt.p;
+ backtrack = position;
+ if(match_all_states())
+ return true;
+ if(count == 0)
+ return false;
+ position = --backtrack;
+ ++state_count;
+ --count;
+ }while(true);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()
+{
+ BOOST_ASSERT(pstate->type == syntax_element_recurse);
+ //
+ // Set new call stack:
+ //
+ if(recursion_stack_position >= static_cast<int>(sizeof(recursion_stack)/sizeof(recursion_stack[0])))
+ {
+ return false;
+ }
+ recursion_stack[recursion_stack_position].preturn_address = pstate->next.p;
+ recursion_stack[recursion_stack_position].results = *m_presult;
+ recursion_stack[recursion_stack_position].repeater_stack = next_count;
+ pstate = static_cast<const re_jump*>(pstate)->alt.p;
+ recursion_stack[recursion_stack_position].id = static_cast<const re_brace*>(pstate)->index;
+ ++recursion_stack_position;
+
+ repeater_count<BidiIterator>* saved = next_count;
+ repeater_count<BidiIterator> r(&next_count); // resets all repeat counts since we're recursing and starting fresh on those
+ next_count = &r;
+ bool result = match_all_states();
+ next_count = saved;
+
+ if(!result)
+ {
+ --recursion_stack_position;
+ next_count = recursion_stack[recursion_stack_position].repeater_stack;
+ *m_presult = recursion_stack[recursion_stack_position].results;
+ return false;
+ }
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()
+{
+ int index = static_cast<const re_brace*>(pstate)->index;
+ icase = static_cast<const re_brace*>(pstate)->icase;
+ if(index > 0)
+ {
+ if((m_match_flags & match_nosubs) == 0)
+ {
+ m_presult->set_second(position, index);
+ }
+ if(recursion_stack_position)
+ {
+ if(index == recursion_stack[recursion_stack_position-1].id)
+ {
+ --recursion_stack_position;
+ recursion_info<results_type> saved = recursion_stack[recursion_stack_position];
+ const re_syntax_base* saved_state = pstate = saved.preturn_address;
+ repeater_count<BidiIterator>* saved_count = next_count;
+ next_count = saved.repeater_stack;
+ *m_presult = saved.results;
+ if(!match_all_states())
+ {
+ recursion_stack[recursion_stack_position] = saved;
+ ++recursion_stack_position;
+ next_count = saved_count;
+ return false;
+ }
+ }
+ }
+ }
+ else if((index < 0) && (index != -4))
+ {
+ // matched forward lookahead:
+ pstate = 0;
+ return true;
+ }
+ pstate = pstate ? pstate->next.p : 0;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_match()
+{
+ if(recursion_stack_position)
+ {
+ BOOST_ASSERT(0 == recursion_stack[recursion_stack_position-1].id);
+ --recursion_stack_position;
+ const re_syntax_base* saved_state = pstate = recursion_stack[recursion_stack_position].preturn_address;
+ *m_presult = recursion_stack[recursion_stack_position].results;
+ if(!match_all_states())
+ {
+ recursion_stack[recursion_stack_position].preturn_address = saved_state;
+ recursion_stack[recursion_stack_position].results = *m_presult;
+ ++recursion_stack_position;
+ return false;
+ }
+ return true;
+ }
+ if((m_match_flags & match_not_null) && (position == (*m_presult)[0].first))
+ return false;
+ if((m_match_flags & match_all) && (position != last))
+ return false;
+ if((m_match_flags & regex_constants::match_not_initial_null) && (position == search_base))
+ return false;
+ m_presult->set_second(position);
+ pstate = 0;
+ m_has_found_match = true;
+ if((m_match_flags & match_posix) == match_posix)
+ {
+ m_result.maybe_assign(*m_presult);
+ if((m_match_flags & match_any) == 0)
+ return false;
+ }
+#ifdef BOOST_REGEX_MATCH_EXTRA
+ if(match_extra & m_match_flags)
+ {
+ for(unsigned i = 0; i < m_presult->size(); ++i)
+ if((*m_presult)[i].matched)
+ ((*m_presult)[i]).get_captures().push_back((*m_presult)[i]);
+ }
+#endif
+ return true;
+}
+
+
+
+} // namespace re_detail
+} // namespace boost
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/ext/boost/regex/v4/primary_transform.hpp b/ext/boost/regex/v4/primary_transform.hpp
new file mode 100644
index 0000000000..989f500c1d
--- /dev/null
+++ b/ext/boost/regex/v4/primary_transform.hpp
@@ -0,0 +1,146 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE: primary_transform.hpp
+ * VERSION: see <boost/version.hpp>
+ * DESCRIPTION: Heuristically determines the sort string format in use
+ * by the current locale.
+ */
+
+#ifndef BOOST_REGEX_PRIMARY_TRANSFORM
+#define BOOST_REGEX_PRIMARY_TRANSFORM
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace boost{
+ namespace re_detail{
+
+
+enum{
+ sort_C,
+ sort_fixed,
+ sort_delim,
+ sort_unknown
+};
+
+template <class S, class charT>
+unsigned count_chars(const S& s, charT c)
+{
+ //
+ // Count how many occurances of character c occur
+ // in string s: if c is a delimeter between collation
+ // fields, then this should be the same value for all
+ // sort keys:
+ //
+ unsigned int count = 0;
+ for(unsigned pos = 0; pos < s.size(); ++pos)
+ {
+ if(s[pos] == c) ++count;
+ }
+ return count;
+}
+
+
+template <class traits, class charT>
+unsigned find_sort_syntax(const traits* pt, charT* delim)
+{
+ //
+ // compare 'a' with 'A' to see how similar they are,
+ // should really use a-accute but we can't portably do that,
+ //
+ typedef typename traits::string_type string_type;
+ typedef typename traits::char_type char_type;
+
+ // Suppress incorrect warning for MSVC
+ (void)pt;
+
+ char_type a[2] = {'a', '\0', };
+ string_type sa(pt->transform(a, a+1));
+ if(sa == a)
+ {
+ *delim = 0;
+ return sort_C;
+ }
+ char_type A[2] = { 'A', '\0', };
+ string_type sA(pt->transform(A, A+1));
+ char_type c[2] = { ';', '\0', };
+ string_type sc(pt->transform(c, c+1));
+
+ int pos = 0;
+ while((pos <= static_cast<int>(sa.size())) && (pos <= static_cast<int>(sA.size())) && (sa[pos] == sA[pos])) ++pos;
+ --pos;
+ if(pos < 0)
+ {
+ *delim = 0;
+ return sort_unknown;
+ }
+ //
+ // at this point sa[pos] is either the end of a fixed width field
+ // or the character that acts as a delimiter:
+ //
+ charT maybe_delim = sa[pos];
+ if((pos != 0) && (count_chars(sa, maybe_delim) == count_chars(sA, maybe_delim)) && (count_chars(sa, maybe_delim) == count_chars(sc, maybe_delim)))
+ {
+ *delim = maybe_delim;
+ return sort_delim;
+ }
+ //
+ // OK doen't look like a delimiter, try for fixed width field:
+ //
+ if((sa.size() == sA.size()) && (sa.size() == sc.size()))
+ {
+ // note assumes that the fixed width field is less than
+ // (numeric_limits<charT>::max)(), should be true for all types
+ // I can't imagine 127 character fields...
+ *delim = static_cast<charT>(++pos);
+ return sort_fixed;
+ }
+ //
+ // don't know what it is:
+ //
+ *delim = 0;
+ return sort_unknown;
+}
+
+
+ } // namespace re_detail
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
+
+
+
+
+
+
diff --git a/ext/boost/regex/v4/protected_call.hpp b/ext/boost/regex/v4/protected_call.hpp
new file mode 100644
index 0000000000..ebf15ba370
--- /dev/null
+++ b/ext/boost/regex/v4/protected_call.hpp
@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE basic_regex_creator.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares template class basic_regex_creator which fills in
+ * the data members of a regex_data object.
+ */
+
+#ifndef BOOST_REGEX_V4_PROTECTED_CALL_HPP
+#define BOOST_REGEX_V4_PROTECTED_CALL_HPP
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace boost{
+namespace re_detail{
+
+class BOOST_REGEX_DECL abstract_protected_call
+{
+public:
+ bool BOOST_REGEX_CALL execute()const;
+ // this stops gcc-4 from complaining:
+ virtual ~abstract_protected_call(){}
+private:
+ virtual bool call()const = 0;
+};
+
+template <class T>
+class concrete_protected_call
+ : public abstract_protected_call
+{
+public:
+ typedef bool (T::*proc_type)();
+ concrete_protected_call(T* o, proc_type p)
+ : obj(o), proc(p) {}
+private:
+ virtual bool call()const;
+ T* obj;
+ proc_type proc;
+};
+
+template <class T>
+bool concrete_protected_call<T>::call()const
+{
+ return (obj->*proc)();
+}
+
+}
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/ext/boost/regex/v4/regbase.hpp b/ext/boost/regex/v4/regbase.hpp
new file mode 100644
index 0000000000..2b737d5aba
--- /dev/null
+++ b/ext/boost/regex/v4/regbase.hpp
@@ -0,0 +1,180 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regbase.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares class regbase.
+ */
+
+#ifndef BOOST_REGEX_V4_REGBASE_HPP
+#define BOOST_REGEX_V4_REGBASE_HPP
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace boost{
+//
+// class regbase
+// handles error codes and flags
+//
+class BOOST_REGEX_DECL regbase
+{
+public:
+ enum flag_type_
+ {
+ //
+ // Divide the flags up into logical groups:
+ // bits 0-7 indicate main synatx type.
+ // bits 8-15 indicate syntax subtype.
+ // bits 16-31 indicate options that are common to all
+ // regex syntaxes.
+ // In all cases the default is 0.
+ //
+ // Main synatx group:
+ //
+ perl_syntax_group = 0, // default
+ basic_syntax_group = 1, // POSIX basic
+ literal = 2, // all characters are literals
+ main_option_type = literal | basic_syntax_group | perl_syntax_group, // everything!
+ //
+ // options specific to perl group:
+ //
+ no_bk_refs = 1 << 8, // \d not allowed
+ no_perl_ex = 1 << 9, // disable perl extensions
+ no_mod_m = 1 << 10, // disable Perl m modifier
+ mod_x = 1 << 11, // Perl x modifier
+ mod_s = 1 << 12, // force s modifier on (overrides match_not_dot_newline)
+ no_mod_s = 1 << 13, // force s modifier off (overrides match_not_dot_newline)
+
+ //
+ // options specific to basic group:
+ //
+ no_char_classes = 1 << 8, // [[:CLASS:]] not allowed
+ no_intervals = 1 << 9, // {x,y} not allowed
+ bk_plus_qm = 1 << 10, // uses \+ and \?
+ bk_vbar = 1 << 11, // use \| for alternatives
+ emacs_ex = 1 << 12, // enables emacs extensions
+
+ //
+ // options common to all groups:
+ //
+ no_escape_in_lists = 1 << 16, // '\' not special inside [...]
+ newline_alt = 1 << 17, // \n is the same as |
+ no_except = 1 << 18, // no exception on error
+ failbit = 1 << 19, // error flag
+ icase = 1 << 20, // characters are matched regardless of case
+ nocollate = 0, // don't use locale specific collation (deprecated)
+ collate = 1 << 21, // use locale specific collation
+ nosubs = 1 << 22, // don't mark sub-expressions
+ save_subexpression_location = 1 << 23, // save subexpression locations
+ no_empty_expressions = 1 << 24, // no empty expressions allowed
+ optimize = 0, // not really supported
+
+
+
+ basic = basic_syntax_group | collate | no_escape_in_lists,
+ extended = no_bk_refs | collate | no_perl_ex | no_escape_in_lists,
+ normal = 0,
+ emacs = basic_syntax_group | collate | emacs_ex | bk_vbar,
+ awk = no_bk_refs | collate | no_perl_ex,
+ grep = basic | newline_alt,
+ egrep = extended | newline_alt,
+ sed = basic,
+ perl = normal,
+ ECMAScript = normal,
+ JavaScript = normal,
+ JScript = normal
+ };
+ typedef unsigned int flag_type;
+
+ enum restart_info
+ {
+ restart_any = 0,
+ restart_word = 1,
+ restart_line = 2,
+ restart_buf = 3,
+ restart_continue = 4,
+ restart_lit = 5,
+ restart_fixed_lit = 6,
+ restart_count = 7
+ };
+};
+
+//
+// provide std lib proposal compatible constants:
+//
+namespace regex_constants{
+
+ enum flag_type_
+ {
+
+ no_except = ::boost::regbase::no_except,
+ failbit = ::boost::regbase::failbit,
+ literal = ::boost::regbase::literal,
+ icase = ::boost::regbase::icase,
+ nocollate = ::boost::regbase::nocollate,
+ collate = ::boost::regbase::collate,
+ nosubs = ::boost::regbase::nosubs,
+ optimize = ::boost::regbase::optimize,
+ bk_plus_qm = ::boost::regbase::bk_plus_qm,
+ bk_vbar = ::boost::regbase::bk_vbar,
+ no_intervals = ::boost::regbase::no_intervals,
+ no_char_classes = ::boost::regbase::no_char_classes,
+ no_escape_in_lists = ::boost::regbase::no_escape_in_lists,
+ no_mod_m = ::boost::regbase::no_mod_m,
+ mod_x = ::boost::regbase::mod_x,
+ mod_s = ::boost::regbase::mod_s,
+ no_mod_s = ::boost::regbase::no_mod_s,
+ save_subexpression_location = ::boost::regbase::save_subexpression_location,
+ no_empty_expressions = ::boost::regbase::no_empty_expressions,
+
+ basic = ::boost::regbase::basic,
+ extended = ::boost::regbase::extended,
+ normal = ::boost::regbase::normal,
+ emacs = ::boost::regbase::emacs,
+ awk = ::boost::regbase::awk,
+ grep = ::boost::regbase::grep,
+ egrep = ::boost::regbase::egrep,
+ sed = basic,
+ perl = normal,
+ ECMAScript = normal,
+ JavaScript = normal,
+ JScript = normal
+ };
+ typedef ::boost::regbase::flag_type syntax_option_type;
+
+} // namespace regex_constants
+
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/ext/boost/regex/v4/regex.hpp b/ext/boost/regex/v4/regex.hpp
new file mode 100644
index 0000000000..7cc260a3ac
--- /dev/null
+++ b/ext/boost/regex/v4/regex.hpp
@@ -0,0 +1,202 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares boost::basic_regex<> and associated
+ * functions and classes. This header is the main
+ * entry point for the template regex code.
+ */
+
+#ifndef BOOST_RE_REGEX_HPP_INCLUDED
+#define BOOST_RE_REGEX_HPP_INCLUDED
+
+#ifdef __cplusplus
+
+// what follows is all C++ don't include in C builds!!
+
+#ifndef BOOST_REGEX_CONFIG_HPP
+#include <boost/regex/config.hpp>
+#endif
+#ifndef BOOST_REGEX_WORKAROUND_HPP
+#include <boost/regex/v4/regex_workaround.hpp>
+#endif
+
+#ifndef BOOST_REGEX_FWD_HPP
+#include <boost/regex_fwd.hpp>
+#endif
+#ifndef BOOST_REGEX_TRAITS_HPP
+#include <boost/regex/regex_traits.hpp>
+#endif
+#ifndef BOOST_REGEX_RAW_BUFFER_HPP
+#include <boost/regex/v4/error_type.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_MATCH_FLAGS
+#include <boost/regex/v4/match_flags.hpp>
+#endif
+#ifndef BOOST_REGEX_RAW_BUFFER_HPP
+#include <boost/regex/v4/regex_raw_buffer.hpp>
+#endif
+#ifndef BOOST_RE_PAT_EXCEPT_HPP
+#include <boost/regex/pattern_except.hpp>
+#endif
+
+#ifndef BOOST_REGEX_V4_CHAR_REGEX_TRAITS_HPP
+#include <boost/regex/v4/char_regex_traits.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_STATES_HPP
+#include <boost/regex/v4/states.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_REGBASE_HPP
+#include <boost/regex/v4/regbase.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_ITERATOR_TRAITS_HPP
+#include <boost/regex/v4/iterator_traits.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_BASIC_REGEX_HPP
+#include <boost/regex/v4/basic_regex.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_BASIC_REGEX_CREATOR_HPP
+#include <boost/regex/v4/basic_regex_creator.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_BASIC_REGEX_PARSER_HPP
+#include <boost/regex/v4/basic_regex_parser.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_SUB_MATCH_HPP
+#include <boost/regex/v4/sub_match.hpp>
+#endif
+#ifndef BOOST_REGEX_FORMAT_HPP
+#include <boost/regex/v4/regex_format.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_MATCH_RESULTS_HPP
+#include <boost/regex/v4/match_results.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_PROTECTED_CALL_HPP
+#include <boost/regex/v4/protected_call.hpp>
+#endif
+#ifndef BOOST_REGEX_MATCHER_HPP
+#include <boost/regex/v4/perl_matcher.hpp>
+#endif
+//
+// template instances:
+//
+#define BOOST_REGEX_CHAR_T char
+#ifdef BOOST_REGEX_NARROW_INSTANTIATE
+# define BOOST_REGEX_INSTANTIATE
+#endif
+#include <boost/regex/v4/instances.hpp>
+#undef BOOST_REGEX_CHAR_T
+#ifdef BOOST_REGEX_INSTANTIATE
+# undef BOOST_REGEX_INSTANTIATE
+#endif
+
+#ifndef BOOST_NO_WREGEX
+#define BOOST_REGEX_CHAR_T wchar_t
+#ifdef BOOST_REGEX_WIDE_INSTANTIATE
+# define BOOST_REGEX_INSTANTIATE
+#endif
+#include <boost/regex/v4/instances.hpp>
+#undef BOOST_REGEX_CHAR_T
+#ifdef BOOST_REGEX_INSTANTIATE
+# undef BOOST_REGEX_INSTANTIATE
+#endif
+#endif
+
+#if !defined(BOOST_NO_WREGEX) && defined(BOOST_REGEX_HAS_OTHER_WCHAR_T)
+#define BOOST_REGEX_CHAR_T unsigned short
+#ifdef BOOST_REGEX_US_INSTANTIATE
+# define BOOST_REGEX_INSTANTIATE
+#endif
+#include <boost/regex/v4/instances.hpp>
+#undef BOOST_REGEX_CHAR_T
+#ifdef BOOST_REGEX_INSTANTIATE
+# undef BOOST_REGEX_INSTANTIATE
+#endif
+#endif
+
+
+namespace boost{
+#ifdef BOOST_REGEX_NO_FWD
+typedef basic_regex<char, regex_traits<char> > regex;
+#ifndef BOOST_NO_WREGEX
+typedef basic_regex<wchar_t, regex_traits<wchar_t> > wregex;
+#endif
+#endif
+
+typedef match_results<const char*> cmatch;
+typedef match_results<std::string::const_iterator> smatch;
+#ifndef BOOST_NO_WREGEX
+typedef match_results<const wchar_t*> wcmatch;
+typedef match_results<std::wstring::const_iterator> wsmatch;
+#endif
+
+} // namespace boost
+#ifndef BOOST_REGEX_MATCH_HPP
+#include <boost/regex/v4/regex_match.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_REGEX_SEARCH_HPP
+#include <boost/regex/v4/regex_search.hpp>
+#endif
+#ifndef BOOST_REGEX_ITERATOR_HPP
+#include <boost/regex/v4/regex_iterator.hpp>
+#endif
+#ifndef BOOST_REGEX_TOKEN_ITERATOR_HPP
+#include <boost/regex/v4/regex_token_iterator.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_REGEX_GREP_HPP
+#include <boost/regex/v4/regex_grep.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_REGEX_REPLACE_HPP
+#include <boost/regex/v4/regex_replace.hpp>
+#endif
+#ifndef BOOST_REGEX_V4_REGEX_MERGE_HPP
+#include <boost/regex/v4/regex_merge.hpp>
+#endif
+#ifndef BOOST_REGEX_SPLIT_HPP
+#include <boost/regex/v4/regex_split.hpp>
+#endif
+
+#endif // __cplusplus
+
+#endif // include
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ext/boost/regex/v4/regex_format.hpp b/ext/boost/regex/v4/regex_format.hpp
new file mode 100644
index 0000000000..4e95112f90
--- /dev/null
+++ b/ext/boost/regex/v4/regex_format.hpp
@@ -0,0 +1,829 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_format.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Provides formatting output routines for search and replace
+ * operations. Note this is an internal header file included
+ * by regex.hpp, do not include on its own.
+ */
+
+#ifndef BOOST_REGEX_FORMAT_HPP
+#define BOOST_REGEX_FORMAT_HPP
+
+
+namespace boost{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+//
+// Forward declaration:
+//
+ template <class BidiIterator, class Allocator = BOOST_DEDUCED_TYPENAME std::vector<sub_match<BidiIterator> >::allocator_type >
+class match_results;
+
+namespace re_detail{
+
+//
+// struct trivial_format_traits:
+// defines minimum localisation support for formatting
+// in the case that the actual regex traits is unavailable.
+//
+template <class charT>
+struct trivial_format_traits
+{
+ typedef charT char_type;
+
+ static std::ptrdiff_t length(const charT* p)
+ {
+ return global_length(p);
+ }
+ static charT tolower(charT c)
+ {
+ return ::boost::re_detail::global_lower(c);
+ }
+ static charT toupper(charT c)
+ {
+ return ::boost::re_detail::global_upper(c);
+ }
+ static int value(const charT c, int radix)
+ {
+ int result = global_value(c);
+ return result >= radix ? -1 : result;
+ }
+ int toi(const charT*& p1, const charT* p2, int radix)const
+ {
+ return global_toi(p1, p2, radix, *this);
+ }
+};
+
+template <class OutputIterator, class Results, class traits>
+class basic_regex_formatter
+{
+public:
+ typedef typename traits::char_type char_type;
+ basic_regex_formatter(OutputIterator o, const Results& r, const traits& t)
+ : m_traits(t), m_results(r), m_out(o), m_state(output_copy), m_restore_state(output_copy), m_have_conditional(false) {}
+ OutputIterator format(const char_type* p1, const char_type* p2, match_flag_type f);
+ OutputIterator format(const char_type* p1, match_flag_type f)
+ {
+ return format(p1, p1 + m_traits.length(p1), f);
+ }
+private:
+ typedef typename Results::value_type sub_match_type;
+ enum output_state
+ {
+ output_copy,
+ output_next_lower,
+ output_next_upper,
+ output_lower,
+ output_upper,
+ output_none
+ };
+
+ void put(char_type c);
+ void put(const sub_match_type& sub);
+ void format_all();
+ void format_perl();
+ void format_escape();
+ void format_conditional();
+ void format_until_scope_end();
+ bool handle_perl_verb(bool have_brace);
+
+ const traits& m_traits; // the traits class for localised formatting operations
+ const Results& m_results; // the match_results being used.
+ OutputIterator m_out; // where to send output.
+ const char_type* m_position; // format string, current position
+ const char_type* m_end; // format string end
+ match_flag_type m_flags; // format flags to use
+ output_state m_state; // what to do with the next character
+ output_state m_restore_state; // what state to restore to.
+ bool m_have_conditional; // we are parsing a conditional
+private:
+ basic_regex_formatter(const basic_regex_formatter&);
+ basic_regex_formatter& operator=(const basic_regex_formatter&);
+};
+
+template <class OutputIterator, class Results, class traits>
+OutputIterator basic_regex_formatter<OutputIterator, Results, traits>::format(const char_type* p1, const char_type* p2, match_flag_type f)
+{
+ m_position = p1;
+ m_end = p2;
+ m_flags = f;
+ format_all();
+ return m_out;
+}
+
+template <class OutputIterator, class Results, class traits>
+void basic_regex_formatter<OutputIterator, Results, traits>::format_all()
+{
+ // over and over:
+ while(m_position != m_end)
+ {
+ switch(*m_position)
+ {
+ case '&':
+ if(m_flags & ::boost::regex_constants::format_sed)
+ {
+ ++m_position;
+ put(m_results[0]);
+ break;
+ }
+ put(*m_position++);
+ break;
+ case '\\':
+ format_escape();
+ break;
+ case '(':
+ if(m_flags & boost::regex_constants::format_all)
+ {
+ ++m_position;
+ bool have_conditional = m_have_conditional;
+ m_have_conditional = false;
+ format_until_scope_end();
+ m_have_conditional = have_conditional;
+ if(m_position == m_end)
+ return;
+ BOOST_ASSERT(*m_position == static_cast<char_type>(')'));
+ ++m_position; // skip the closing ')'
+ break;
+ }
+ put(*m_position);
+ ++m_position;
+ break;
+ case ')':
+ if(m_flags & boost::regex_constants::format_all)
+ {
+ return;
+ }
+ put(*m_position);
+ ++m_position;
+ break;
+ case ':':
+ if((m_flags & boost::regex_constants::format_all) && m_have_conditional)
+ {
+ return;
+ }
+ put(*m_position);
+ ++m_position;
+ break;
+ case '?':
+ if(m_flags & boost::regex_constants::format_all)
+ {
+ ++m_position;
+ format_conditional();
+ break;
+ }
+ put(*m_position);
+ ++m_position;
+ break;
+ case '$':
+ if((m_flags & format_sed) == 0)
+ {
+ format_perl();
+ break;
+ }
+ // fall through, not a special character:
+ default:
+ put(*m_position);
+ ++m_position;
+ break;
+ }
+ }
+}
+
+template <class OutputIterator, class Results, class traits>
+void basic_regex_formatter<OutputIterator, Results, traits>::format_perl()
+{
+ //
+ // On entry *m_position points to a '$' character
+ // output the information that goes with it:
+ //
+ BOOST_ASSERT(*m_position == '$');
+ //
+ // see if this is a trailing '$':
+ //
+ if(++m_position == m_end)
+ {
+ --m_position;
+ put(*m_position);
+ ++m_position;
+ return;
+ }
+ //
+ // OK find out what kind it is:
+ //
+ bool have_brace = false;
+ const char_type* save_position = m_position;
+ switch(*m_position)
+ {
+ case '&':
+ ++m_position;
+ put(this->m_results[0]);
+ break;
+ case '`':
+ ++m_position;
+ put(this->m_results.prefix());
+ break;
+ case '\'':
+ ++m_position;
+ put(this->m_results.suffix());
+ break;
+ case '$':
+ put(*m_position++);
+ break;
+ case '+':
+ if((++m_position != m_end) && (*m_position == '{'))
+ {
+ const char_type* base = ++m_position;
+ while((m_position != m_end) && (*m_position != '}')) ++m_position;
+ if(m_position != m_end)
+ {
+ // Named sub-expression:
+ put(this->m_results.named_subexpression(base, m_position));
+ ++m_position;
+ break;
+ }
+ else
+ {
+ m_position = --base;
+ }
+ }
+ put((this->m_results)[this->m_results.size() > 1 ? this->m_results.size() - 1 : 1]);
+ break;
+ case '{':
+ have_brace = true;
+ ++m_position;
+ // fall through....
+ default:
+ // see if we have a number:
+ {
+ std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end);
+ //len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
+ int v = m_traits.toi(m_position, m_position + len, 10);
+ if((v < 0) || (have_brace && ((m_position == m_end) || (*m_position != '}'))))
+ {
+ // Look for a Perl-5.10 verb:
+ if(!handle_perl_verb(have_brace))
+ {
+ // leave the $ as is, and carry on:
+ m_position = --save_position;
+ put(*m_position);
+ ++m_position;
+ }
+ break;
+ }
+ // otherwise output sub v:
+ put(this->m_results[v]);
+ if(have_brace)
+ ++m_position;
+ }
+ }
+}
+
+template <class OutputIterator, class Results, class traits>
+bool basic_regex_formatter<OutputIterator, Results, traits>::handle_perl_verb(bool have_brace)
+{
+ //
+ // We may have a capitalised string containing a Perl action:
+ //
+ static const char_type MATCH[] = { 'M', 'A', 'T', 'C', 'H' };
+ static const char_type PREMATCH[] = { 'P', 'R', 'E', 'M', 'A', 'T', 'C', 'H' };
+ static const char_type POSTMATCH[] = { 'P', 'O', 'S', 'T', 'M', 'A', 'T', 'C', 'H' };
+ static const char_type LAST_PAREN_MATCH[] = { 'L', 'A', 'S', 'T', '_', 'P', 'A', 'R', 'E', 'N', '_', 'M', 'A', 'T', 'C', 'H' };
+ static const char_type LAST_SUBMATCH_RESULT[] = { 'L', 'A', 'S', 'T', '_', 'S', 'U', 'B', 'M', 'A', 'T', 'C', 'H', '_', 'R', 'E', 'S', 'U', 'L', 'T' };
+ static const char_type LAST_SUBMATCH_RESULT_ALT[] = { '^', 'N' };
+
+ if(have_brace && (*m_position == '^'))
+ ++m_position;
+
+ int max_len = m_end - m_position;
+
+ if((max_len >= 5) && std::equal(m_position, m_position + 5, MATCH))
+ {
+ m_position += 5;
+ if(have_brace)
+ {
+ if(*m_position == '}')
+ ++m_position;
+ else
+ {
+ m_position -= 5;
+ return false;
+ }
+ }
+ put(this->m_results[0]);
+ return true;
+ }
+ if((max_len >= 8) && std::equal(m_position, m_position + 8, PREMATCH))
+ {
+ m_position += 8;
+ if(have_brace)
+ {
+ if(*m_position == '}')
+ ++m_position;
+ else
+ {
+ m_position -= 8;
+ return false;
+ }
+ }
+ put(this->m_results.prefix());
+ return true;
+ }
+ if((max_len >= 9) && std::equal(m_position, m_position + 9, POSTMATCH))
+ {
+ m_position += 9;
+ if(have_brace)
+ {
+ if(*m_position == '}')
+ ++m_position;
+ else
+ {
+ m_position -= 9;
+ return false;
+ }
+ }
+ put(this->m_results.suffix());
+ return true;
+ }
+ if((max_len >= 16) && std::equal(m_position, m_position + 16, LAST_PAREN_MATCH))
+ {
+ m_position += 16;
+ if(have_brace)
+ {
+ if(*m_position == '}')
+ ++m_position;
+ else
+ {
+ m_position -= 16;
+ return false;
+ }
+ }
+ put((this->m_results)[this->m_results.size() > 1 ? this->m_results.size() - 1 : 1]);
+ return true;
+ }
+ if((max_len >= 20) && std::equal(m_position, m_position + 20, LAST_SUBMATCH_RESULT))
+ {
+ m_position += 20;
+ if(have_brace)
+ {
+ if(*m_position == '}')
+ ++m_position;
+ else
+ {
+ m_position -= 20;
+ return false;
+ }
+ }
+ put(this->m_results.get_last_closed_paren());
+ return true;
+ }
+ if((max_len >= 2) && std::equal(m_position, m_position + 2, LAST_SUBMATCH_RESULT_ALT))
+ {
+ m_position += 2;
+ if(have_brace)
+ {
+ if(*m_position == '}')
+ ++m_position;
+ else
+ {
+ m_position -= 2;
+ return false;
+ }
+ }
+ put(this->m_results.get_last_closed_paren());
+ return true;
+ }
+ return false;
+}
+
+template <class OutputIterator, class Results, class traits>
+void basic_regex_formatter<OutputIterator, Results, traits>::format_escape()
+{
+ // skip the escape and check for trailing escape:
+ if(++m_position == m_end)
+ {
+ put(static_cast<char_type>('\\'));
+ return;
+ }
+ // now switch on the escape type:
+ switch(*m_position)
+ {
+ case 'a':
+ put(static_cast<char_type>('\a'));
+ ++m_position;
+ break;
+ case 'f':
+ put(static_cast<char_type>('\f'));
+ ++m_position;
+ break;
+ case 'n':
+ put(static_cast<char_type>('\n'));
+ ++m_position;
+ break;
+ case 'r':
+ put(static_cast<char_type>('\r'));
+ ++m_position;
+ break;
+ case 't':
+ put(static_cast<char_type>('\t'));
+ ++m_position;
+ break;
+ case 'v':
+ put(static_cast<char_type>('\v'));
+ ++m_position;
+ break;
+ case 'x':
+ if(++m_position == m_end)
+ {
+ put(static_cast<char_type>('x'));
+ return;
+ }
+ // maybe have \x{ddd}
+ if(*m_position == static_cast<char_type>('{'))
+ {
+ ++m_position;
+ int val = m_traits.toi(m_position, m_end, 16);
+ if(val < 0)
+ {
+ // invalid value treat everything as literals:
+ put(static_cast<char_type>('x'));
+ put(static_cast<char_type>('{'));
+ return;
+ }
+ if(*m_position != static_cast<char_type>('}'))
+ {
+ while(*m_position != static_cast<char_type>('\\'))
+ --m_position;
+ ++m_position;
+ put(*m_position++);
+ return;
+ }
+ ++m_position;
+ put(static_cast<char_type>(val));
+ return;
+ }
+ else
+ {
+ std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end);
+ len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
+ int val = m_traits.toi(m_position, m_position + len, 16);
+ if(val < 0)
+ {
+ --m_position;
+ put(*m_position++);
+ return;
+ }
+ put(static_cast<char_type>(val));
+ }
+ break;
+ case 'c':
+ if(++m_position == m_end)
+ {
+ --m_position;
+ put(*m_position++);
+ return;
+ }
+ put(static_cast<char_type>(*m_position++ % 32));
+ break;
+ case 'e':
+ put(static_cast<char_type>(27));
+ ++m_position;
+ break;
+ default:
+ // see if we have a perl specific escape:
+ if((m_flags & boost::regex_constants::format_sed) == 0)
+ {
+ bool breakout = false;
+ switch(*m_position)
+ {
+ case 'l':
+ ++m_position;
+ m_restore_state = m_state;
+ m_state = output_next_lower;
+ breakout = true;
+ break;
+ case 'L':
+ ++m_position;
+ m_state = output_lower;
+ breakout = true;
+ break;
+ case 'u':
+ ++m_position;
+ m_restore_state = m_state;
+ m_state = output_next_upper;
+ breakout = true;
+ break;
+ case 'U':
+ ++m_position;
+ m_state = output_upper;
+ breakout = true;
+ break;
+ case 'E':
+ ++m_position;
+ m_state = output_copy;
+ breakout = true;
+ break;
+ }
+ if(breakout)
+ break;
+ }
+ // see if we have a \n sed style backreference:
+ int v = m_traits.toi(m_position, m_position+1, 10);
+ if((v > 0) || ((v == 0) && (m_flags & ::boost::regex_constants::format_sed)))
+ {
+ put(m_results[v]);
+ break;
+ }
+ else if(v == 0)
+ {
+ // octal ecape sequence:
+ --m_position;
+ std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end);
+ len = (std::min)(static_cast<std::ptrdiff_t>(4), len);
+ v = m_traits.toi(m_position, m_position + len, 8);
+ BOOST_ASSERT(v >= 0);
+ put(static_cast<char_type>(v));
+ break;
+ }
+ // Otherwise output the character "as is":
+ put(*m_position++);
+ break;
+ }
+}
+
+template <class OutputIterator, class Results, class traits>
+void basic_regex_formatter<OutputIterator, Results, traits>::format_conditional()
+{
+ if(m_position == m_end)
+ {
+ // oops trailing '?':
+ put(static_cast<char_type>('?'));
+ return;
+ }
+ int v;
+ if(*m_position == '{')
+ {
+ const char_type* base = m_position;
+ ++m_position;
+ v = m_traits.toi(m_position, m_end, 10);
+ if(v < 0)
+ {
+ // Try a named subexpression:
+ while((m_position != m_end) && (*m_position != '}'))
+ ++m_position;
+ v = m_results.named_subexpression_index(base + 1, m_position);
+ }
+ if((v < 0) || (*m_position != '}'))
+ {
+ m_position = base;
+ // oops trailing '?':
+ put(static_cast<char_type>('?'));
+ return;
+ }
+ // Skip trailing '}':
+ ++m_position;
+ }
+ else
+ {
+ std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end);
+ len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
+ v = m_traits.toi(m_position, m_position + len, 10);
+ }
+ if(v < 0)
+ {
+ // oops not a number:
+ put(static_cast<char_type>('?'));
+ return;
+ }
+
+ // output varies depending upon whether sub-expression v matched or not:
+ if(m_results[v].matched)
+ {
+ m_have_conditional = true;
+ format_all();
+ m_have_conditional = false;
+ if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
+ {
+ // skip the ':':
+ ++m_position;
+ // save output state, then turn it off:
+ output_state saved_state = m_state;
+ m_state = output_none;
+ // format the rest of this scope:
+ format_until_scope_end();
+ // restore output state:
+ m_state = saved_state;
+ }
+ }
+ else
+ {
+ // save output state, then turn it off:
+ output_state saved_state = m_state;
+ m_state = output_none;
+ // format until ':' or ')':
+ m_have_conditional = true;
+ format_all();
+ m_have_conditional = false;
+ // restore state:
+ m_state = saved_state;
+ if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
+ {
+ // skip the ':':
+ ++m_position;
+ // format the rest of this scope:
+ format_until_scope_end();
+ }
+ }
+}
+
+template <class OutputIterator, class Results, class traits>
+void basic_regex_formatter<OutputIterator, Results, traits>::format_until_scope_end()
+{
+ do
+ {
+ format_all();
+ if((m_position == m_end) || (*m_position == static_cast<char_type>(')')))
+ return;
+ put(*m_position++);
+ }while(m_position != m_end);
+}
+
+template <class OutputIterator, class Results, class traits>
+void basic_regex_formatter<OutputIterator, Results, traits>::put(char_type c)
+{
+ // write a single character to output
+ // according to which case translation mode we are in:
+ switch(this->m_state)
+ {
+ case output_none:
+ return;
+ case output_next_lower:
+ c = m_traits.tolower(c);
+ this->m_state = m_restore_state;
+ break;
+ case output_next_upper:
+ c = m_traits.toupper(c);
+ this->m_state = m_restore_state;
+ break;
+ case output_lower:
+ c = m_traits.tolower(c);
+ break;
+ case output_upper:
+ c = m_traits.toupper(c);
+ break;
+ default:
+ break;
+ }
+ *m_out = c;
+ ++m_out;
+}
+
+template <class OutputIterator, class Results, class traits>
+void basic_regex_formatter<OutputIterator, Results, traits>::put(const sub_match_type& sub)
+{
+ typedef typename sub_match_type::iterator iterator_type;
+ iterator_type i = sub.first;
+ while(i != sub.second)
+ {
+ put(*i);
+ ++i;
+ }
+}
+
+template <class S>
+class string_out_iterator
+#ifndef BOOST_NO_STD_ITERATOR
+ : public std::iterator<std::output_iterator_tag, typename S::value_type>
+#endif
+{
+ S* out;
+public:
+ string_out_iterator(S& s) : out(&s) {}
+ string_out_iterator& operator++() { return *this; }
+ string_out_iterator& operator++(int) { return *this; }
+ string_out_iterator& operator*() { return *this; }
+ string_out_iterator& operator=(typename S::value_type v)
+ {
+ out->append(1, v);
+ return *this;
+ }
+
+#ifdef BOOST_NO_STD_ITERATOR
+ typedef std::ptrdiff_t difference_type;
+ typedef typename S::value_type value_type;
+ typedef value_type* pointer;
+ typedef value_type& reference;
+ typedef std::output_iterator_tag iterator_category;
+#endif
+};
+
+template <class OutputIterator, class Iterator, class Alloc, class charT, class traits>
+OutputIterator regex_format_imp(OutputIterator out,
+ const match_results<Iterator, Alloc>& m,
+ const charT* p1, const charT* p2,
+ match_flag_type flags,
+ const traits& t
+ )
+{
+ if(flags & regex_constants::format_literal)
+ {
+ return re_detail::copy(p1, p2, out);
+ }
+
+ re_detail::basic_regex_formatter<
+ OutputIterator,
+ match_results<Iterator, Alloc>,
+ traits > f(out, m, t);
+ return f.format(p1, p2, flags);
+}
+
+
+} // namespace re_detail
+
+template <class OutputIterator, class Iterator, class charT>
+OutputIterator regex_format(OutputIterator out,
+ const match_results<Iterator>& m,
+ const charT* fmt,
+ match_flag_type flags = format_all
+ )
+{
+ re_detail::trivial_format_traits<charT> traits;
+ return re_detail::regex_format_imp(out, m, fmt, fmt + traits.length(fmt), flags, traits);
+}
+
+template <class OutputIterator, class Iterator, class charT>
+OutputIterator regex_format(OutputIterator out,
+ const match_results<Iterator>& m,
+ const std::basic_string<charT>& fmt,
+ match_flag_type flags = format_all
+ )
+{
+ re_detail::trivial_format_traits<charT> traits;
+ return re_detail::regex_format_imp(out, m, fmt.data(), fmt.data() + fmt.size(), flags, traits);
+}
+
+template <class Iterator, class charT>
+std::basic_string<charT> regex_format(const match_results<Iterator>& m,
+ const charT* fmt,
+ match_flag_type flags = format_all)
+{
+ std::basic_string<charT> result;
+ re_detail::string_out_iterator<std::basic_string<charT> > i(result);
+ re_detail::trivial_format_traits<charT> traits;
+ re_detail::regex_format_imp(i, m, fmt, fmt + traits.length(fmt), flags, traits);
+ return result;
+}
+
+template <class Iterator, class charT>
+std::basic_string<charT> regex_format(const match_results<Iterator>& m,
+ const std::basic_string<charT>& fmt,
+ match_flag_type flags = format_all)
+{
+ std::basic_string<charT> result;
+ re_detail::string_out_iterator<std::basic_string<charT> > i(result);
+ re_detail::trivial_format_traits<charT> traits;
+ re_detail::regex_format_imp(i, m, fmt.data(), fmt.data() + fmt.size(), flags, traits);
+ return result;
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace boost
+
+#endif // BOOST_REGEX_FORMAT_HPP
+
+
+
+
+
+
diff --git a/ext/boost/regex/v4/regex_fwd.hpp b/ext/boost/regex/v4/regex_fwd.hpp
new file mode 100644
index 0000000000..3076b069ac
--- /dev/null
+++ b/ext/boost/regex/v4/regex_fwd.hpp
@@ -0,0 +1,73 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_fwd.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Forward declares boost::basic_regex<> and
+ * associated typedefs.
+ */
+
+#ifndef BOOST_REGEX_FWD_HPP_INCLUDED
+#define BOOST_REGEX_FWD_HPP_INCLUDED
+
+#ifndef BOOST_REGEX_CONFIG_HPP
+#include <boost/regex/config.hpp>
+#endif
+
+//
+// define BOOST_REGEX_NO_FWD if this
+// header doesn't work!
+//
+#ifdef BOOST_REGEX_NO_FWD
+# ifndef BOOST_RE_REGEX_HPP
+# include <boost/regex.hpp>
+# endif
+#else
+
+namespace boost{
+
+template <class charT>
+class cpp_regex_traits;
+template <class charT>
+struct c_regex_traits;
+template <class charT>
+class w32_regex_traits;
+
+#ifdef BOOST_REGEX_USE_WIN32_LOCALE
+template <class charT, class implementationT = w32_regex_traits<charT> >
+struct regex_traits;
+#elif defined(BOOST_REGEX_USE_CPP_LOCALE)
+template <class charT, class implementationT = cpp_regex_traits<charT> >
+struct regex_traits;
+#else
+template <class charT, class implementationT = c_regex_traits<charT> >
+struct regex_traits;
+#endif
+
+template <class charT, class traits = regex_traits<charT> >
+class basic_regex;
+
+typedef basic_regex<char, regex_traits<char> > regex;
+#ifndef BOOST_NO_WREGEX
+typedef basic_regex<wchar_t, regex_traits<wchar_t> > wregex;
+#endif
+
+} // namespace boost
+
+#endif // BOOST_REGEX_NO_FWD
+
+#endif
+
+
+
+
diff --git a/ext/boost/regex/v4/regex_grep.hpp b/ext/boost/regex/v4/regex_grep.hpp
new file mode 100644
index 0000000000..3a3d906ecb
--- /dev/null
+++ b/ext/boost/regex/v4/regex_grep.hpp
@@ -0,0 +1,155 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_grep.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Provides regex_grep implementation.
+ */
+
+#ifndef BOOST_REGEX_V4_REGEX_GREP_HPP
+#define BOOST_REGEX_V4_REGEX_GREP_HPP
+
+
+namespace boost{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+//
+// regex_grep:
+// find all non-overlapping matches within the sequence first last:
+//
+template <class Predicate, class BidiIterator, class charT, class traits>
+inline unsigned int regex_grep(Predicate foo,
+ BidiIterator first,
+ BidiIterator last,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ if(e.flags() & regex_constants::failbit)
+ return false;
+
+ typedef typename match_results<BidiIterator>::allocator_type match_allocator_type;
+
+ match_results<BidiIterator> m;
+ re_detail::perl_matcher<BidiIterator, match_allocator_type, traits> matcher(first, last, m, e, flags, first);
+ unsigned int count = 0;
+ while(matcher.find())
+ {
+ ++count;
+ if(0 == foo(m))
+ return count; // caller doesn't want to go on
+ if(m[0].second == last)
+ return count; // we've reached the end, don't try and find an extra null match.
+ if(m.length() == 0)
+ {
+ if(m[0].second == last)
+ return count;
+ // we found a NULL-match, now try to find
+ // a non-NULL one at the same position:
+ match_results<BidiIterator, match_allocator_type> m2(m);
+ matcher.setf(match_not_null | match_continuous);
+ if(matcher.find())
+ {
+ ++count;
+ if(0 == foo(m))
+ return count;
+ }
+ else
+ {
+ // reset match back to where it was:
+ m = m2;
+ }
+ matcher.unsetf((match_not_null | match_continuous) & ~flags);
+ }
+ }
+ return count;
+}
+
+//
+// regex_grep convenience interfaces:
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+//
+// this isn't really a partial specialisation, but template function
+// overloading - if the compiler doesn't support partial specialisation
+// then it really won't support this either:
+template <class Predicate, class charT, class traits>
+inline unsigned int regex_grep(Predicate foo, const charT* str,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ return regex_grep(foo, str, str + traits::length(str), e, flags);
+}
+
+template <class Predicate, class ST, class SA, class charT, class traits>
+inline unsigned int regex_grep(Predicate foo, const std::basic_string<charT, ST, SA>& s,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ return regex_grep(foo, s.begin(), s.end(), e, flags);
+}
+#else // partial specialisation
+inline unsigned int regex_grep(bool (*foo)(const cmatch&), const char* str,
+ const regex& e,
+ match_flag_type flags = match_default)
+{
+ return regex_grep(foo, str, str + regex::traits_type::length(str), e, flags);
+}
+#ifndef BOOST_NO_WREGEX
+inline unsigned int regex_grep(bool (*foo)(const wcmatch&), const wchar_t* str,
+ const wregex& e,
+ match_flag_type flags = match_default)
+{
+ return regex_grep(foo, str, str + wregex::traits_type::length(str), e, flags);
+}
+#endif
+inline unsigned int regex_grep(bool (*foo)(const match_results<std::string::const_iterator>&), const std::string& s,
+ const regex& e,
+ match_flag_type flags = match_default)
+{
+ return regex_grep(foo, s.begin(), s.end(), e, flags);
+}
+#if !defined(BOOST_NO_WREGEX)
+inline unsigned int regex_grep(bool (*foo)(const match_results<std::basic_string<wchar_t>::const_iterator>&),
+ const std::basic_string<wchar_t>& s,
+ const wregex& e,
+ match_flag_type flags = match_default)
+{
+ return regex_grep(foo, s.begin(), s.end(), e, flags);
+}
+#endif
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace boost
+
+#endif // BOOST_REGEX_V4_REGEX_GREP_HPP
+
diff --git a/ext/boost/regex/v4/regex_iterator.hpp b/ext/boost/regex/v4/regex_iterator.hpp
new file mode 100644
index 0000000000..c2f2c49f2e
--- /dev/null
+++ b/ext/boost/regex/v4/regex_iterator.hpp
@@ -0,0 +1,201 @@
+/*
+ *
+ * Copyright (c) 2003
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_iterator.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Provides regex_iterator implementation.
+ */
+
+#ifndef BOOST_REGEX_V4_REGEX_ITERATOR_HPP
+#define BOOST_REGEX_V4_REGEX_ITERATOR_HPP
+
+#include <boost/shared_ptr.hpp>
+
+namespace boost{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <class BidirectionalIterator,
+ class charT,
+ class traits>
+class regex_iterator_implementation
+{
+ typedef basic_regex<charT, traits> regex_type;
+
+ match_results<BidirectionalIterator> what; // current match
+ BidirectionalIterator base; // start of sequence
+ BidirectionalIterator end; // end of sequence
+ const regex_type re; // the expression
+ match_flag_type flags; // flags for matching
+
+public:
+ regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f)
+ : base(), end(last), re(*p), flags(f){}
+ bool init(BidirectionalIterator first)
+ {
+ base = first;
+ return regex_search(first, end, what, re, flags);
+ }
+ bool compare(const regex_iterator_implementation& that)
+ {
+ if(this == &that) return true;
+ return (&re.get_data() == &that.re.get_data()) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);
+ }
+ const match_results<BidirectionalIterator>& get()
+ { return what; }
+ bool next()
+ {
+ //if(what.prefix().first != what[0].second)
+ // flags |= match_prev_avail;
+ BidirectionalIterator next_start = what[0].second;
+ match_flag_type f(flags);
+ if(!what.length())
+ f |= regex_constants::match_not_initial_null;
+ //if(base != next_start)
+ // f |= regex_constants::match_not_bob;
+ bool result = regex_search(next_start, end, what, re, f, base);
+ if(result)
+ what.set_base(base);
+ return result;
+ }
+private:
+ regex_iterator_implementation& operator=(const regex_iterator_implementation&);
+};
+
+template <class BidirectionalIterator,
+ class charT = BOOST_DEDUCED_TYPENAME re_detail::regex_iterator_traits<BidirectionalIterator>::value_type,
+ class traits = regex_traits<charT> >
+class regex_iterator
+#ifndef BOOST_NO_STD_ITERATOR
+ : public std::iterator<
+ std::forward_iterator_tag,
+ match_results<BidirectionalIterator>,
+ typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type,
+ const match_results<BidirectionalIterator>*,
+ const match_results<BidirectionalIterator>& >
+#endif
+{
+private:
+ typedef regex_iterator_implementation<BidirectionalIterator, charT, traits> impl;
+ typedef shared_ptr<impl> pimpl;
+public:
+ typedef basic_regex<charT, traits> regex_type;
+ typedef match_results<BidirectionalIterator> value_type;
+ typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type
+ difference_type;
+ typedef const value_type* pointer;
+ typedef const value_type& reference;
+ typedef std::forward_iterator_tag iterator_category;
+
+ regex_iterator(){}
+ regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
+ const regex_type& re,
+ match_flag_type m = match_default)
+ : pdata(new impl(&re, b, m))
+ {
+ if(!pdata->init(a))
+ {
+ pdata.reset();
+ }
+ }
+ regex_iterator(const regex_iterator& that)
+ : pdata(that.pdata) {}
+ regex_iterator& operator=(const regex_iterator& that)
+ {
+ pdata = that.pdata;
+ return *this;
+ }
+ bool operator==(const regex_iterator& that)const
+ {
+ if((pdata.get() == 0) || (that.pdata.get() == 0))
+ return pdata.get() == that.pdata.get();
+ return pdata->compare(*(that.pdata.get()));
+ }
+ bool operator!=(const regex_iterator& that)const
+ { return !(*this == that); }
+ const value_type& operator*()const
+ { return pdata->get(); }
+ const value_type* operator->()const
+ { return &(pdata->get()); }
+ regex_iterator& operator++()
+ {
+ cow();
+ if(0 == pdata->next())
+ {
+ pdata.reset();
+ }
+ return *this;
+ }
+ regex_iterator operator++(int)
+ {
+ regex_iterator result(*this);
+ ++(*this);
+ return result;
+ }
+private:
+
+ pimpl pdata;
+
+ void cow()
+ {
+ // copy-on-write
+ if(pdata.get() && !pdata.unique())
+ {
+ pdata.reset(new impl(*(pdata.get())));
+ }
+ }
+};
+
+typedef regex_iterator<const char*> cregex_iterator;
+typedef regex_iterator<std::string::const_iterator> sregex_iterator;
+#ifndef BOOST_NO_WREGEX
+typedef regex_iterator<const wchar_t*> wcregex_iterator;
+typedef regex_iterator<std::wstring::const_iterator> wsregex_iterator;
+#endif
+
+// make_regex_iterator:
+template <class charT, class traits>
+inline regex_iterator<const charT*, charT, traits> make_regex_iterator(const charT* p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return regex_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, m);
+}
+template <class charT, class traits, class ST, class SA>
+inline regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, m);
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace boost
+
+#endif // BOOST_REGEX_V4_REGEX_ITERATOR_HPP
+
diff --git a/ext/boost/regex/v4/regex_match.hpp b/ext/boost/regex/v4/regex_match.hpp
new file mode 100644
index 0000000000..e947a15225
--- /dev/null
+++ b/ext/boost/regex/v4/regex_match.hpp
@@ -0,0 +1,382 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_match.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Regular expression matching algorithms.
+ * Note this is an internal header file included
+ * by regex.hpp, do not include on its own.
+ */
+
+
+#ifndef BOOST_REGEX_MATCH_HPP
+#define BOOST_REGEX_MATCH_HPP
+
+namespace boost{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+//
+// proc regex_match
+// returns true if the specified regular expression matches
+// the whole of the input. Fills in what matched in m.
+//
+template <class BidiIterator, class Allocator, class charT, class traits>
+bool regex_match(BidiIterator first, BidiIterator last,
+ match_results<BidiIterator, Allocator>& m,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ re_detail::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags, first);
+ return matcher.match();
+}
+template <class iterator, class charT, class traits>
+bool regex_match(iterator first, iterator last,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ match_results<iterator> m;
+ return regex_match(first, last, m, e, flags | regex_constants::match_any);
+}
+//
+// query_match convenience interfaces:
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+//
+// this isn't really a partial specialisation, but template function
+// overloading - if the compiler doesn't support partial specialisation
+// then it really won't support this either:
+template <class charT, class Allocator, class traits>
+inline bool regex_match(const charT* str,
+ match_results<const charT*, Allocator>& m,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(str, str + traits::length(str), m, e, flags);
+}
+
+template <class ST, class SA, class Allocator, class charT, class traits>
+inline bool regex_match(const std::basic_string<charT, ST, SA>& s,
+ match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(s.begin(), s.end(), m, e, flags);
+}
+template <class charT, class traits>
+inline bool regex_match(const charT* str,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const charT*> m;
+ return regex_match(str, str + traits::length(str), m, e, flags | regex_constants::match_any);
+}
+
+template <class ST, class SA, class charT, class traits>
+inline bool regex_match(const std::basic_string<charT, ST, SA>& s,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ typedef typename std::basic_string<charT, ST, SA>::const_iterator iterator;
+ match_results<iterator> m;
+ return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#else // partial ordering
+inline bool regex_match(const char* str,
+ cmatch& m,
+ const regex& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const char* str,
+ const regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const char*> m;
+ return regex_match(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#ifndef BOOST_NO_STD_LOCALE
+inline bool regex_match(const char* str,
+ cmatch& m,
+ const basic_regex<char, cpp_regex_traits<char> >& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const char* str,
+ const basic_regex<char, cpp_regex_traits<char> >& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const char*> m;
+ return regex_match(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#endif
+inline bool regex_match(const char* str,
+ cmatch& m,
+ const basic_regex<char, c_regex_traits<char> >& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const char* str,
+ const basic_regex<char, c_regex_traits<char> >& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const char*> m;
+ return regex_match(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
+inline bool regex_match(const char* str,
+ cmatch& m,
+ const basic_regex<char, w32_regex_traits<char> >& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(str, str + regex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const char* str,
+ const basic_regex<char, w32_regex_traits<char> >& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const char*> m;
+ return regex_match(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#endif
+#ifndef BOOST_NO_WREGEX
+inline bool regex_match(const wchar_t* str,
+ wcmatch& m,
+ const wregex& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const wchar_t* str,
+ const wregex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const wchar_t*> m;
+ return regex_match(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#ifndef BOOST_NO_STD_LOCALE
+inline bool regex_match(const wchar_t* str,
+ wcmatch& m,
+ const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const wchar_t* str,
+ const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const wchar_t*> m;
+ return regex_match(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#endif
+inline bool regex_match(const wchar_t* str,
+ wcmatch& m,
+ const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const wchar_t* str,
+ const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const wchar_t*> m;
+ return regex_match(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
+inline bool regex_match(const wchar_t* str,
+ wcmatch& m,
+ const basic_regex<wchar_t, w32_regex_traits<wchar_t> >& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_match(const wchar_t* str,
+ const basic_regex<wchar_t, w32_regex_traits<wchar_t> >& e,
+ match_flag_type flags = match_default)
+{
+ match_results<const wchar_t*> m;
+ return regex_match(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#endif
+#endif
+inline bool regex_match(const std::string& s,
+ smatch& m,
+ const regex& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::string& s,
+ const regex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<std::string::const_iterator> m;
+ return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#ifndef BOOST_NO_STD_LOCALE
+inline bool regex_match(const std::string& s,
+ smatch& m,
+ const basic_regex<char, cpp_regex_traits<char> >& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::string& s,
+ const basic_regex<char, cpp_regex_traits<char> >& e,
+ match_flag_type flags = match_default)
+{
+ match_results<std::string::const_iterator> m;
+ return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#endif
+inline bool regex_match(const std::string& s,
+ smatch& m,
+ const basic_regex<char, c_regex_traits<char> >& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::string& s,
+ const basic_regex<char, c_regex_traits<char> >& e,
+ match_flag_type flags = match_default)
+{
+ match_results<std::string::const_iterator> m;
+ return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
+inline bool regex_match(const std::string& s,
+ smatch& m,
+ const basic_regex<char, w32_regex_traits<char> >& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::string& s,
+ const basic_regex<char, w32_regex_traits<char> >& e,
+ match_flag_type flags = match_default)
+{
+ match_results<std::string::const_iterator> m;
+ return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#endif
+#if !defined(BOOST_NO_WREGEX)
+inline bool regex_match(const std::basic_string<wchar_t>& s,
+ match_results<std::basic_string<wchar_t>::const_iterator>& m,
+ const wregex& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::basic_string<wchar_t>& s,
+ const wregex& e,
+ match_flag_type flags = match_default)
+{
+ match_results<std::basic_string<wchar_t>::const_iterator> m;
+ return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#ifndef BOOST_NO_STD_LOCALE
+inline bool regex_match(const std::basic_string<wchar_t>& s,
+ match_results<std::basic_string<wchar_t>::const_iterator>& m,
+ const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::basic_string<wchar_t>& s,
+ const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e,
+ match_flag_type flags = match_default)
+{
+ match_results<std::basic_string<wchar_t>::const_iterator> m;
+ return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#endif
+inline bool regex_match(const std::basic_string<wchar_t>& s,
+ match_results<std::basic_string<wchar_t>::const_iterator>& m,
+ const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::basic_string<wchar_t>& s,
+ const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e,
+ match_flag_type flags = match_default)
+{
+ match_results<std::basic_string<wchar_t>::const_iterator> m;
+ return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
+inline bool regex_match(const std::basic_string<wchar_t>& s,
+ match_results<std::basic_string<wchar_t>::const_iterator>& m,
+ const basic_regex<wchar_t, w32_regex_traits<wchar_t> >& e,
+ match_flag_type flags = match_default)
+{
+ return regex_match(s.begin(), s.end(), m, e, flags);
+}
+inline bool regex_match(const std::basic_string<wchar_t>& s,
+ const basic_regex<wchar_t, w32_regex_traits<wchar_t> >& e,
+ match_flag_type flags = match_default)
+{
+ match_results<std::basic_string<wchar_t>::const_iterator> m;
+ return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#endif
+#endif
+
+#endif
+
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace boost
+
+#endif // BOOST_REGEX_MATCH_HPP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ext/boost/regex/v4/regex_merge.hpp b/ext/boost/regex/v4/regex_merge.hpp
new file mode 100644
index 0000000000..404ca77501
--- /dev/null
+++ b/ext/boost/regex/v4/regex_merge.hpp
@@ -0,0 +1,93 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_format.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Provides formatting output routines for search and replace
+ * operations. Note this is an internal header file included
+ * by regex.hpp, do not include on its own.
+ */
+
+#ifndef BOOST_REGEX_V4_REGEX_MERGE_HPP
+#define BOOST_REGEX_V4_REGEX_MERGE_HPP
+
+
+namespace boost{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <class OutputIterator, class Iterator, class traits, class charT>
+inline OutputIterator regex_merge(OutputIterator out,
+ Iterator first,
+ Iterator last,
+ const basic_regex<charT, traits>& e,
+ const charT* fmt,
+ match_flag_type flags = match_default)
+{
+ return regex_replace(out, first, last, e, fmt, flags);
+}
+
+template <class OutputIterator, class Iterator, class traits, class charT>
+inline OutputIterator regex_merge(OutputIterator out,
+ Iterator first,
+ Iterator last,
+ const basic_regex<charT, traits>& e,
+ const std::basic_string<charT>& fmt,
+ match_flag_type flags = match_default)
+{
+ return regex_merge(out, first, last, e, fmt.c_str(), flags);
+}
+
+template <class traits, class charT>
+inline std::basic_string<charT> regex_merge(const std::basic_string<charT>& s,
+ const basic_regex<charT, traits>& e,
+ const charT* fmt,
+ match_flag_type flags = match_default)
+{
+ return regex_replace(s, e, fmt, flags);
+}
+
+template <class traits, class charT>
+inline std::basic_string<charT> regex_merge(const std::basic_string<charT>& s,
+ const basic_regex<charT, traits>& e,
+ const std::basic_string<charT>& fmt,
+ match_flag_type flags = match_default)
+{
+ return regex_replace(s, e, fmt, flags);
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace boost
+
+#endif // BOOST_REGEX_V4_REGEX_MERGE_HPP
+
+
diff --git a/ext/boost/regex/v4/regex_raw_buffer.hpp b/ext/boost/regex/v4/regex_raw_buffer.hpp
new file mode 100644
index 0000000000..52d45a250b
--- /dev/null
+++ b/ext/boost/regex/v4/regex_raw_buffer.hpp
@@ -0,0 +1,210 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_raw_buffer.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Raw character buffer for regex code.
+ * Note this is an internal header file included
+ * by regex.hpp, do not include on its own.
+ */
+
+#ifndef BOOST_REGEX_RAW_BUFFER_HPP
+#define BOOST_REGEX_RAW_BUFFER_HPP
+
+#ifndef BOOST_REGEX_CONFIG_HPP
+#include <boost/regex/config.hpp>
+#endif
+
+#include <algorithm>
+#include <cstddef>
+
+namespace boost{
+ namespace re_detail{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+struct empty_padding{};
+
+union padding
+{
+ void* p;
+ unsigned int i;
+};
+
+template <int N>
+struct padding3
+{
+ enum{
+ padding_size = 8,
+ padding_mask = 7
+ };
+};
+
+template<>
+struct padding3<2>
+{
+ enum{
+ padding_size = 2,
+ padding_mask = 1
+ };
+};
+
+template<>
+struct padding3<4>
+{
+ enum{
+ padding_size = 4,
+ padding_mask = 3
+ };
+};
+
+template<>
+struct padding3<8>
+{
+ enum{
+ padding_size = 8,
+ padding_mask = 7
+ };
+};
+
+template<>
+struct padding3<16>
+{
+ enum{
+ padding_size = 16,
+ padding_mask = 15
+ };
+};
+
+enum{
+ padding_size = padding3<sizeof(padding)>::padding_size,
+ padding_mask = padding3<sizeof(padding)>::padding_mask
+};
+
+//
+// class raw_storage
+// basically this is a simplified vector<unsigned char>
+// this is used by basic_regex for expression storage
+//
+
+class BOOST_REGEX_DECL raw_storage
+{
+public:
+ typedef std::size_t size_type;
+ typedef unsigned char* pointer;
+private:
+ pointer last, start, end;
+public:
+
+ raw_storage();
+ raw_storage(size_type n);
+
+ ~raw_storage()
+ {
+ ::operator delete(start);
+ }
+
+ void BOOST_REGEX_CALL resize(size_type n);
+
+ void* BOOST_REGEX_CALL extend(size_type n)
+ {
+ if(size_type(last - end) < n)
+ resize(n + (end - start));
+ register pointer result = end;
+ end += n;
+ return result;
+ }
+
+ void* BOOST_REGEX_CALL insert(size_type pos, size_type n);
+
+ size_type BOOST_REGEX_CALL size()
+ {
+ return end - start;
+ }
+
+ size_type BOOST_REGEX_CALL capacity()
+ {
+ return last - start;
+ }
+
+ void* BOOST_REGEX_CALL data()const
+ {
+ return start;
+ }
+
+ size_type BOOST_REGEX_CALL index(void* ptr)
+ {
+ return static_cast<pointer>(ptr) - static_cast<pointer>(data());
+ }
+
+ void BOOST_REGEX_CALL clear()
+ {
+ end = start;
+ }
+
+ void BOOST_REGEX_CALL align()
+ {
+ // move end up to a boundary:
+ end = start + (((end - start) + padding_mask) & ~padding_mask);
+ }
+ void swap(raw_storage& that)
+ {
+ std::swap(start, that.start);
+ std::swap(end, that.end);
+ std::swap(last, that.last);
+ }
+};
+
+inline raw_storage::raw_storage()
+{
+ last = start = end = 0;
+}
+
+inline raw_storage::raw_storage(size_type n)
+{
+ start = end = static_cast<pointer>(::operator new(n));
+ BOOST_REGEX_NOEH_ASSERT(start)
+ last = start + n;
+}
+
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace re_detail
+} // namespace boost
+
+#endif
+
+
+
+
+
+
diff --git a/ext/boost/regex/v4/regex_replace.hpp b/ext/boost/regex/v4/regex_replace.hpp
new file mode 100644
index 0000000000..c4544c05b9
--- /dev/null
+++ b/ext/boost/regex/v4/regex_replace.hpp
@@ -0,0 +1,122 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_format.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Provides formatting output routines for search and replace
+ * operations. Note this is an internal header file included
+ * by regex.hpp, do not include on its own.
+ */
+
+#ifndef BOOST_REGEX_V4_REGEX_REPLACE_HPP
+#define BOOST_REGEX_V4_REGEX_REPLACE_HPP
+
+
+namespace boost{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <class OutputIterator, class BidirectionalIterator, class traits, class charT>
+OutputIterator regex_replace(OutputIterator out,
+ BidirectionalIterator first,
+ BidirectionalIterator last,
+ const basic_regex<charT, traits>& e,
+ const charT* fmt,
+ match_flag_type flags = match_default)
+{
+ regex_iterator<BidirectionalIterator, charT, traits> i(first, last, e, flags);
+ regex_iterator<BidirectionalIterator, charT, traits> j;
+ if(i == j)
+ {
+ if(!(flags & regex_constants::format_no_copy))
+ out = re_detail::copy(first, last, out);
+ }
+ else
+ {
+ BidirectionalIterator last_m(first);
+ while(i != j)
+ {
+ if(!(flags & regex_constants::format_no_copy))
+ out = re_detail::copy(i->prefix().first, i->prefix().second, out);
+ out = i->format(out, fmt, flags, e);
+ last_m = (*i)[0].second;
+ if(flags & regex_constants::format_first_only)
+ break;
+ ++i;
+ }
+ if(!(flags & regex_constants::format_no_copy))
+ out = re_detail::copy(last_m, last, out);
+ }
+ return out;
+}
+
+template <class OutputIterator, class Iterator, class traits, class charT>
+inline OutputIterator regex_replace(OutputIterator out,
+ Iterator first,
+ Iterator last,
+ const basic_regex<charT, traits>& e,
+ const std::basic_string<charT>& fmt,
+ match_flag_type flags = match_default)
+{
+ return regex_replace(out, first, last, e, fmt.c_str(), flags);
+}
+
+template <class traits, class charT>
+std::basic_string<charT> regex_replace(const std::basic_string<charT>& s,
+ const basic_regex<charT, traits>& e,
+ const charT* fmt,
+ match_flag_type flags = match_default)
+{
+ std::basic_string<charT> result;
+ re_detail::string_out_iterator<std::basic_string<charT> > i(result);
+ regex_replace(i, s.begin(), s.end(), e, fmt, flags);
+ return result;
+}
+
+template <class traits, class charT>
+std::basic_string<charT> regex_replace(const std::basic_string<charT>& s,
+ const basic_regex<charT, traits>& e,
+ const std::basic_string<charT>& fmt,
+ match_flag_type flags = match_default)
+{
+ std::basic_string<charT> result;
+ re_detail::string_out_iterator<std::basic_string<charT> > i(result);
+ regex_replace(i, s.begin(), s.end(), e, fmt.c_str(), flags);
+ return result;
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace boost
+
+#endif // BOOST_REGEX_V4_REGEX_REPLACE_HPP
+
+
diff --git a/ext/boost/regex/v4/regex_search.hpp b/ext/boost/regex/v4/regex_search.hpp
new file mode 100644
index 0000000000..cf5579d2c7
--- /dev/null
+++ b/ext/boost/regex/v4/regex_search.hpp
@@ -0,0 +1,217 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_search.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Provides regex_search implementation.
+ */
+
+#ifndef BOOST_REGEX_V4_REGEX_SEARCH_HPP
+#define BOOST_REGEX_V4_REGEX_SEARCH_HPP
+
+
+namespace boost{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <class BidiIterator, class Allocator, class charT, class traits>
+bool regex_search(BidiIterator first, BidiIterator last,
+ match_results<BidiIterator, Allocator>& m,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ return regex_search(first, last, m, e, flags, first);
+}
+
+template <class BidiIterator, class Allocator, class charT, class traits>
+bool regex_search(BidiIterator first, BidiIterator last,
+ match_results<BidiIterator, Allocator>& m,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags,
+ BidiIterator base)
+{
+ if(e.flags() & regex_constants::failbit)
+ return false;
+
+ re_detail::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags, base);
+ return matcher.find();
+}
+
+//
+// regex_search convenience interfaces:
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+//
+// this isn't really a partial specialisation, but template function
+// overloading - if the compiler doesn't support partial specialisation
+// then it really won't support this either:
+template <class charT, class Allocator, class traits>
+inline bool regex_search(const charT* str,
+ match_results<const charT*, Allocator>& m,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ return regex_search(str, str + traits::length(str), m, e, flags);
+}
+
+template <class ST, class SA, class Allocator, class charT, class traits>
+inline bool regex_search(const std::basic_string<charT, ST, SA>& s,
+ match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ return regex_search(s.begin(), s.end(), m, e, flags);
+}
+#else // partial overloads:
+inline bool regex_search(const char* str,
+ cmatch& m,
+ const regex& e,
+ match_flag_type flags = match_default)
+{
+ return regex_search(str, str + regex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_search(const char* first, const char* last,
+ const regex& e,
+ match_flag_type flags = match_default)
+{
+ cmatch m;
+ return regex_search(first, last, m, e, flags | regex_constants::match_any);
+}
+
+#ifndef BOOST_NO_WREGEX
+inline bool regex_search(const wchar_t* str,
+ wcmatch& m,
+ const wregex& e,
+ match_flag_type flags = match_default)
+{
+ return regex_search(str, str + wregex::traits_type::length(str), m, e, flags);
+}
+inline bool regex_search(const wchar_t* first, const wchar_t* last,
+ const wregex& e,
+ match_flag_type flags = match_default)
+{
+ wcmatch m;
+ return regex_search(first, last, m, e, flags | regex_constants::match_any);
+}
+#endif
+inline bool regex_search(const std::string& s,
+ smatch& m,
+ const regex& e,
+ match_flag_type flags = match_default)
+{
+ return regex_search(s.begin(), s.end(), m, e, flags);
+}
+#if !defined(BOOST_NO_WREGEX)
+inline bool regex_search(const std::basic_string<wchar_t>& s,
+ wsmatch& m,
+ const wregex& e,
+ match_flag_type flags = match_default)
+{
+ return regex_search(s.begin(), s.end(), m, e, flags);
+}
+#endif
+
+#endif
+
+template <class BidiIterator, class charT, class traits>
+bool regex_search(BidiIterator first, BidiIterator last,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ if(e.flags() & regex_constants::failbit)
+ return false;
+
+ match_results<BidiIterator> m;
+ typedef typename match_results<BidiIterator>::allocator_type match_alloc_type;
+ re_detail::perl_matcher<BidiIterator, match_alloc_type, traits> matcher(first, last, m, e, flags | regex_constants::match_any, first);
+ return matcher.find();
+}
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+template <class charT, class traits>
+inline bool regex_search(const charT* str,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ return regex_search(str, str + traits::length(str), e, flags);
+}
+
+template <class ST, class SA, class charT, class traits>
+inline bool regex_search(const std::basic_string<charT, ST, SA>& s,
+ const basic_regex<charT, traits>& e,
+ match_flag_type flags = match_default)
+{
+ return regex_search(s.begin(), s.end(), e, flags);
+}
+#else // non-template function overloads
+inline bool regex_search(const char* str,
+ const regex& e,
+ match_flag_type flags = match_default)
+{
+ cmatch m;
+ return regex_search(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#ifndef BOOST_NO_WREGEX
+inline bool regex_search(const wchar_t* str,
+ const wregex& e,
+ match_flag_type flags = match_default)
+{
+ wcmatch m;
+ return regex_search(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);
+}
+#endif
+inline bool regex_search(const std::string& s,
+ const regex& e,
+ match_flag_type flags = match_default)
+{
+ smatch m;
+ return regex_search(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+#if !defined(BOOST_NO_WREGEX)
+inline bool regex_search(const std::basic_string<wchar_t>& s,
+ const wregex& e,
+ match_flag_type flags = match_default)
+{
+ wsmatch m;
+ return regex_search(s.begin(), s.end(), m, e, flags | regex_constants::match_any);
+}
+
+#endif // BOOST_NO_WREGEX
+
+#endif // partial overload
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace boost
+
+#endif // BOOST_REGEX_V4_REGEX_SEARCH_HPP
+
+
diff --git a/ext/boost/regex/v4/regex_split.hpp b/ext/boost/regex/v4/regex_split.hpp
new file mode 100644
index 0000000000..a7ae350f4a
--- /dev/null
+++ b/ext/boost/regex/v4/regex_split.hpp
@@ -0,0 +1,172 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_split.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Implements regex_split and associated functions.
+ * Note this is an internal header file included
+ * by regex.hpp, do not include on its own.
+ */
+
+#ifndef BOOST_REGEX_SPLIT_HPP
+#define BOOST_REGEX_SPLIT_HPP
+
+namespace boost{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable: 4800)
+#endif
+
+namespace re_detail{
+
+template <class charT>
+const basic_regex<charT>& get_default_expression(charT)
+{
+ static const charT expression_text[4] = { '\\', 's', '+', '\00', };
+ static const basic_regex<charT> e(expression_text);
+ return e;
+}
+
+template <class OutputIterator, class charT, class Traits1, class Alloc1>
+class split_pred
+{
+ typedef std::basic_string<charT, Traits1, Alloc1> string_type;
+ typedef typename string_type::const_iterator iterator_type;
+ iterator_type* p_last;
+ OutputIterator* p_out;
+ std::size_t* p_max;
+ std::size_t initial_max;
+public:
+ split_pred(iterator_type* a, OutputIterator* b, std::size_t* c)
+ : p_last(a), p_out(b), p_max(c), initial_max(*c) {}
+
+ bool operator()(const match_results<iterator_type>& what);
+};
+
+template <class OutputIterator, class charT, class Traits1, class Alloc1>
+bool split_pred<OutputIterator, charT, Traits1, Alloc1>::operator()
+ (const match_results<iterator_type>& what)
+{
+ *p_last = what[0].second;
+ if(what.size() > 1)
+ {
+ // output sub-expressions only:
+ for(unsigned i = 1; i < what.size(); ++i)
+ {
+ *(*p_out) = what.str(i);
+ ++(*p_out);
+ if(0 == --*p_max) return false;
+ }
+ return *p_max != 0;
+ }
+ else
+ {
+ // output $` only if it's not-null or not at the start of the input:
+ const sub_match<iterator_type>& sub = what[-1];
+ if((sub.first != sub.second) || (*p_max != initial_max))
+ {
+ *(*p_out) = sub.str();
+ ++(*p_out);
+ return --*p_max;
+ }
+ }
+ //
+ // initial null, do nothing:
+ return true;
+}
+
+} // namespace re_detail
+
+template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
+std::size_t regex_split(OutputIterator out,
+ std::basic_string<charT, Traits1, Alloc1>& s,
+ const basic_regex<charT, Traits2>& e,
+ match_flag_type flags,
+ std::size_t max_split)
+{
+ typedef typename std::basic_string<charT, Traits1, Alloc1>::const_iterator ci_t;
+ typedef typename match_results<ci_t>::allocator_type match_allocator;
+ ci_t last = s.begin();
+ std::size_t init_size = max_split;
+ re_detail::split_pred<OutputIterator, charT, Traits1, Alloc1> pred(&last, &out, &max_split);
+ ci_t i, j;
+ i = s.begin();
+ j = s.end();
+ regex_grep(pred, i, j, e, flags);
+ //
+ // if there is still input left, do a final push as long as max_split
+ // is not exhausted, and we're not splitting sub-expressions rather
+ // than whitespace:
+ if(max_split && (last != s.end()) && (e.mark_count() == 1))
+ {
+ *out = std::basic_string<charT, Traits1, Alloc1>((ci_t)last, (ci_t)s.end());
+ ++out;
+ last = s.end();
+ --max_split;
+ }
+ //
+ // delete from the string everything that has been processed so far:
+ s.erase(0, last - s.begin());
+ //
+ // return the number of new records pushed:
+ return init_size - max_split;
+}
+
+template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
+inline std::size_t regex_split(OutputIterator out,
+ std::basic_string<charT, Traits1, Alloc1>& s,
+ const basic_regex<charT, Traits2>& e,
+ match_flag_type flags = match_default)
+{
+ return regex_split(out, s, e, flags, UINT_MAX);
+}
+
+template <class OutputIterator, class charT, class Traits1, class Alloc1>
+inline std::size_t regex_split(OutputIterator out,
+ std::basic_string<charT, Traits1, Alloc1>& s)
+{
+ return regex_split(out, s, re_detail::get_default_expression(charT(0)), match_default, UINT_MAX);
+}
+
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace boost
+
+#endif
+
+
diff --git a/ext/boost/regex/v4/regex_token_iterator.hpp b/ext/boost/regex/v4/regex_token_iterator.hpp
new file mode 100644
index 0000000000..4e8bc36fef
--- /dev/null
+++ b/ext/boost/regex/v4/regex_token_iterator.hpp
@@ -0,0 +1,342 @@
+/*
+ *
+ * Copyright (c) 2003
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_token_iterator.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Provides regex_token_iterator implementation.
+ */
+
+#ifndef BOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP
+#define BOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP
+
+#include <boost/shared_ptr.hpp>
+#include <boost/detail/workaround.hpp>
+#if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
+ || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
+ || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
+//
+// Borland C++ Builder 6, and Visual C++ 6,
+// can't cope with the array template constructor
+// so we have a template member that will accept any type as
+// argument, and then assert that is really is an array:
+//
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_array.hpp>
+#endif
+
+namespace boost{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+#if BOOST_WORKAROUND(BOOST_MSVC, > 1300)
+# pragma warning(push)
+# pragma warning(disable:4700)
+#endif
+
+template <class BidirectionalIterator,
+ class charT,
+ class traits>
+class regex_token_iterator_implementation
+{
+ typedef basic_regex<charT, traits> regex_type;
+ typedef sub_match<BidirectionalIterator> value_type;
+
+ match_results<BidirectionalIterator> what; // current match
+ BidirectionalIterator base; // start of search area
+ BidirectionalIterator end; // end of search area
+ const regex_type re; // the expression
+ match_flag_type flags; // match flags
+ value_type result; // the current string result
+ int N; // the current sub-expression being enumerated
+ std::vector<int> subs; // the sub-expressions to enumerate
+
+public:
+ regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, int sub, match_flag_type f)
+ : end(last), re(*p), flags(f){ subs.push_back(sub); }
+ regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const std::vector<int>& v, match_flag_type f)
+ : end(last), re(*p), flags(f), subs(v){}
+#if !BOOST_WORKAROUND(__HP_aCC, < 60700)
+#if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
+ || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
+ || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \
+ || BOOST_WORKAROUND(__HP_aCC, < 60700)
+ template <class T>
+ regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const T& submatches, match_flag_type f)
+ : end(last), re(*p), flags(f)
+ {
+ // assert that T really is an array:
+ BOOST_STATIC_ASSERT(::boost::is_array<T>::value);
+ const std::size_t array_size = sizeof(T) / sizeof(submatches[0]);
+ for(std::size_t i = 0; i < array_size; ++i)
+ {
+ subs.push_back(submatches[i]);
+ }
+ }
+#else
+ template <std::size_t CN>
+ regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const int (&submatches)[CN], match_flag_type f)
+ : end(last), re(*p), flags(f)
+ {
+ for(std::size_t i = 0; i < CN; ++i)
+ {
+ subs.push_back(submatches[i]);
+ }
+ }
+#endif
+#endif
+ bool init(BidirectionalIterator first)
+ {
+ N = 0;
+ base = first;
+ if(regex_search(first, end, what, re, flags, base) == true)
+ {
+ N = 0;
+ result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);
+ return true;
+ }
+ else if((subs[N] == -1) && (first != end))
+ {
+ result.first = first;
+ result.second = end;
+ result.matched = (first != end);
+ N = -1;
+ return true;
+ }
+ return false;
+ }
+ bool compare(const regex_token_iterator_implementation& that)
+ {
+ if(this == &that) return true;
+ return (&re.get_data() == &that.re.get_data())
+ && (end == that.end)
+ && (flags == that.flags)
+ && (N == that.N)
+ && (what[0].first == that.what[0].first)
+ && (what[0].second == that.what[0].second);
+ }
+ const value_type& get()
+ { return result; }
+ bool next()
+ {
+ if(N == -1)
+ return false;
+ if(N+1 < (int)subs.size())
+ {
+ ++N;
+ result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
+ return true;
+ }
+ //if(what.prefix().first != what[0].second)
+ // flags |= /*match_prev_avail |*/ regex_constants::match_not_bob;
+ BidirectionalIterator last_end(what[0].second);
+ if(regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))
+ {
+ N =0;
+ result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
+ return true;
+ }
+ else if((last_end != end) && (subs[0] == -1))
+ {
+ N =-1;
+ result.first = last_end;
+ result.second = end;
+ result.matched = (last_end != end);
+ return true;
+ }
+ return false;
+ }
+private:
+ regex_token_iterator_implementation& operator=(const regex_token_iterator_implementation&);
+};
+
+template <class BidirectionalIterator,
+ class charT = BOOST_DEDUCED_TYPENAME re_detail::regex_iterator_traits<BidirectionalIterator>::value_type,
+ class traits = regex_traits<charT> >
+class regex_token_iterator
+#ifndef BOOST_NO_STD_ITERATOR
+ : public std::iterator<
+ std::forward_iterator_tag,
+ sub_match<BidirectionalIterator>,
+ typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type,
+ const sub_match<BidirectionalIterator>*,
+ const sub_match<BidirectionalIterator>& >
+#endif
+{
+private:
+ typedef regex_token_iterator_implementation<BidirectionalIterator, charT, traits> impl;
+ typedef shared_ptr<impl> pimpl;
+public:
+ typedef basic_regex<charT, traits> regex_type;
+ typedef sub_match<BidirectionalIterator> value_type;
+ typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type
+ difference_type;
+ typedef const value_type* pointer;
+ typedef const value_type& reference;
+ typedef std::forward_iterator_tag iterator_category;
+
+ regex_token_iterator(){}
+ regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
+ int submatch = 0, match_flag_type m = match_default)
+ : pdata(new impl(&re, b, submatch, m))
+ {
+ if(!pdata->init(a))
+ pdata.reset();
+ }
+ regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
+ const std::vector<int>& submatches, match_flag_type m = match_default)
+ : pdata(new impl(&re, b, submatches, m))
+ {
+ if(!pdata->init(a))
+ pdata.reset();
+ }
+#if !BOOST_WORKAROUND(__HP_aCC, < 60700)
+#if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
+ || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
+ || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \
+ || BOOST_WORKAROUND(__HP_aCC, < 60700)
+ template <class T>
+ regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
+ const T& submatches, match_flag_type m = match_default)
+ : pdata(new impl(&re, b, submatches, m))
+ {
+ if(!pdata->init(a))
+ pdata.reset();
+ }
+#else
+ template <std::size_t N>
+ regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
+ const int (&submatches)[N], match_flag_type m = match_default)
+ : pdata(new impl(&re, b, submatches, m))
+ {
+ if(!pdata->init(a))
+ pdata.reset();
+ }
+#endif
+#endif
+ regex_token_iterator(const regex_token_iterator& that)
+ : pdata(that.pdata) {}
+ regex_token_iterator& operator=(const regex_token_iterator& that)
+ {
+ pdata = that.pdata;
+ return *this;
+ }
+ bool operator==(const regex_token_iterator& that)const
+ {
+ if((pdata.get() == 0) || (that.pdata.get() == 0))
+ return pdata.get() == that.pdata.get();
+ return pdata->compare(*(that.pdata.get()));
+ }
+ bool operator!=(const regex_token_iterator& that)const
+ { return !(*this == that); }
+ const value_type& operator*()const
+ { return pdata->get(); }
+ const value_type* operator->()const
+ { return &(pdata->get()); }
+ regex_token_iterator& operator++()
+ {
+ cow();
+ if(0 == pdata->next())
+ {
+ pdata.reset();
+ }
+ return *this;
+ }
+ regex_token_iterator operator++(int)
+ {
+ regex_token_iterator result(*this);
+ ++(*this);
+ return result;
+ }
+private:
+
+ pimpl pdata;
+
+ void cow()
+ {
+ // copy-on-write
+ if(pdata.get() && !pdata.unique())
+ {
+ pdata.reset(new impl(*(pdata.get())));
+ }
+ }
+};
+
+typedef regex_token_iterator<const char*> cregex_token_iterator;
+typedef regex_token_iterator<std::string::const_iterator> sregex_token_iterator;
+#ifndef BOOST_NO_WREGEX
+typedef regex_token_iterator<const wchar_t*> wcregex_token_iterator;
+typedef regex_token_iterator<std::wstring::const_iterator> wsregex_token_iterator;
+#endif
+
+template <class charT, class traits>
+inline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);
+}
+template <class charT, class traits, class ST, class SA>
+inline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);
+}
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+template <class charT, class traits, std::size_t N>
+inline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);
+}
+template <class charT, class traits, class ST, class SA, std::size_t N>
+inline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);
+}
+#endif
+template <class charT, class traits>
+inline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);
+}
+template <class charT, class traits, class ST, class SA>
+inline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);
+}
+
+#if BOOST_WORKAROUND(BOOST_MSVC, > 1300)
+# pragma warning(pop)
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+} // namespace boost
+
+#endif // BOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP
+
+
+
+
diff --git a/ext/boost/regex/v4/regex_traits.hpp b/ext/boost/regex/v4/regex_traits.hpp
new file mode 100644
index 0000000000..f5f0402cab
--- /dev/null
+++ b/ext/boost/regex/v4/regex_traits.hpp
@@ -0,0 +1,189 @@
+/*
+ *
+ * Copyright (c) 2003
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_traits.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares regular expression traits classes.
+ */
+
+#ifndef BOOST_REGEX_TRAITS_HPP_INCLUDED
+#define BOOST_REGEX_TRAITS_HPP_INCLUDED
+
+#ifndef BOOST_REGEX_CONFIG_HPP
+#include <boost/regex/config.hpp>
+#endif
+#ifndef BOOST_REGEX_WORKAROUND_HPP
+#include <boost/regex/v4/regex_workaround.hpp>
+#endif
+#ifndef BOOST_REGEX_SYNTAX_TYPE_HPP
+#include <boost/regex/v4/syntax_type.hpp>
+#endif
+#ifndef BOOST_REGEX_ERROR_TYPE_HPP
+#include <boost/regex/v4/error_type.hpp>
+#endif
+#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
+#include <boost/regex/v4/regex_traits_defaults.hpp>
+#endif
+#ifndef BOOST_NO_STD_LOCALE
+# ifndef BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
+# include <boost/regex/v4/cpp_regex_traits.hpp>
+# endif
+#endif
+#if !BOOST_WORKAROUND(__BORLANDC__, < 0x560)
+# ifndef BOOST_C_REGEX_TRAITS_HPP_INCLUDED
+# include <boost/regex/v4/c_regex_traits.hpp>
+# endif
+#endif
+#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
+# ifndef BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
+# include <boost/regex/v4/w32_regex_traits.hpp>
+# endif
+#endif
+#ifndef BOOST_REGEX_FWD_HPP_INCLUDED
+#include <boost/regex_fwd.hpp>
+#endif
+
+#include "boost/mpl/has_xxx.hpp"
+#include <boost/static_assert.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace boost{
+
+template <class charT, class implementationT >
+struct regex_traits : public implementationT
+{
+ regex_traits() : implementationT() {}
+};
+
+//
+// class regex_traits_wrapper.
+// this is what our implementation will actually store;
+// it provides default implementations of the "optional"
+// interfaces that we support, in addition to the
+// required "standard" ones:
+//
+namespace re_detail{
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !BOOST_WORKAROUND(__HP_aCC, < 60000)
+BOOST_MPL_HAS_XXX_TRAIT_DEF(boost_extensions_tag)
+#else
+template<class T>
+struct has_boost_extensions_tag
+{
+ BOOST_STATIC_CONSTANT(bool, value = false);
+};
+#endif
+
+template <class BaseT>
+struct default_wrapper : public BaseT
+{
+ typedef typename BaseT::char_type char_type;
+ std::string error_string(::boost::regex_constants::error_type e)const
+ {
+ return ::boost::re_detail::get_default_error_string(e);
+ }
+ ::boost::regex_constants::syntax_type syntax_type(char_type c)const
+ {
+ return ((c & 0x7f) == c) ? get_default_syntax_type(static_cast<char>(c)) : ::boost::regex_constants::syntax_char;
+ }
+ ::boost::regex_constants::escape_syntax_type escape_syntax_type(char_type c)const
+ {
+ return ((c & 0x7f) == c) ? get_default_escape_syntax_type(static_cast<char>(c)) : ::boost::regex_constants::escape_type_identity;
+ }
+ int toi(const char_type*& p1, const char_type* p2, int radix)const
+ {
+ return ::boost::re_detail::global_toi(p1, p2, radix, *this);
+ }
+ char_type translate(char_type c, bool icase)const
+ {
+ return (icase ? this->translate_nocase(c) : this->translate(c));
+ }
+ char_type translate(char_type c)const
+ {
+ return BaseT::translate(c);
+ }
+ char_type tolower(char_type c)const
+ {
+ return ::boost::re_detail::global_lower(c);
+ }
+ char_type toupper(char_type c)const
+ {
+ return ::boost::re_detail::global_upper(c);
+ }
+};
+
+template <class BaseT, bool has_extensions>
+struct compute_wrapper_base
+{
+ typedef BaseT type;
+};
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !BOOST_WORKAROUND(__HP_aCC, < 60000)
+template <class BaseT>
+struct compute_wrapper_base<BaseT, false>
+{
+ typedef default_wrapper<BaseT> type;
+};
+#else
+template <>
+struct compute_wrapper_base<c_regex_traits<char>, false>
+{
+ typedef default_wrapper<c_regex_traits<char> > type;
+};
+#ifndef BOOST_NO_WREGEX
+template <>
+struct compute_wrapper_base<c_regex_traits<wchar_t>, false>
+{
+ typedef default_wrapper<c_regex_traits<wchar_t> > type;
+};
+#endif
+#endif
+
+} // namespace re_detail
+
+template <class BaseT>
+struct regex_traits_wrapper
+ : public ::boost::re_detail::compute_wrapper_base<
+ BaseT,
+ ::boost::re_detail::has_boost_extensions_tag<BaseT>::value
+ >::type
+{
+ regex_traits_wrapper(){}
+private:
+ regex_traits_wrapper(const regex_traits_wrapper&);
+ regex_traits_wrapper& operator=(const regex_traits_wrapper&);
+};
+
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif // include
+
diff --git a/ext/boost/regex/v4/regex_traits_defaults.hpp b/ext/boost/regex/v4/regex_traits_defaults.hpp
new file mode 100644
index 0000000000..5b2c6bc338
--- /dev/null
+++ b/ext/boost/regex/v4/regex_traits_defaults.hpp
@@ -0,0 +1,371 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_traits_defaults.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares API's for access to regex_traits default properties.
+ */
+
+#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
+#define BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifndef BOOST_REGEX_SYNTAX_TYPE_HPP
+#include <boost/regex/v4/syntax_type.hpp>
+#endif
+#ifndef BOOST_REGEX_ERROR_TYPE_HPP
+#include <boost/regex/v4/error_type.hpp>
+#endif
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std{
+ using ::strlen;
+}
+#endif
+
+namespace boost{ namespace re_detail{
+
+
+//
+// helpers to suppress warnings:
+//
+template <class charT>
+inline bool is_extended(charT c)
+{ return c > 256; }
+inline bool is_extended(char)
+{ return false; }
+
+
+BOOST_REGEX_DECL const char* BOOST_REGEX_CALL get_default_syntax(regex_constants::syntax_type n);
+BOOST_REGEX_DECL const char* BOOST_REGEX_CALL get_default_error_string(regex_constants::error_type n);
+BOOST_REGEX_DECL regex_constants::syntax_type BOOST_REGEX_CALL get_default_syntax_type(char c);
+BOOST_REGEX_DECL regex_constants::escape_syntax_type BOOST_REGEX_CALL get_default_escape_syntax_type(char c);
+
+// is charT c a combining character?
+BOOST_REGEX_DECL bool BOOST_REGEX_CALL is_combining_implementation(uint_least16_t s);
+
+template <class charT>
+inline bool is_combining(charT c)
+{
+ return (c <= static_cast<charT>(0)) ? false : ((c >= static_cast<charT>((std::numeric_limits<uint_least16_t>::max)())) ? false : is_combining_implementation(static_cast<unsigned short>(c)));
+}
+template <>
+inline bool is_combining<char>(char)
+{
+ return false;
+}
+template <>
+inline bool is_combining<signed char>(signed char)
+{
+ return false;
+}
+template <>
+inline bool is_combining<unsigned char>(unsigned char)
+{
+ return false;
+}
+#ifndef __hpux // can't use WCHAR_MAX/MIN in pp-directives
+#ifdef _MSC_VER
+template<>
+inline bool is_combining<wchar_t>(wchar_t c)
+{
+ return is_combining_implementation(static_cast<unsigned short>(c));
+}
+#elif !defined(__DECCXX) && !defined(__osf__) && !defined(__OSF__) && defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+#if defined(WCHAR_MAX) && (WCHAR_MAX <= USHRT_MAX)
+template<>
+inline bool is_combining<wchar_t>(wchar_t c)
+{
+ return is_combining_implementation(static_cast<unsigned short>(c));
+}
+#else
+template<>
+inline bool is_combining<wchar_t>(wchar_t c)
+{
+ return (c >= (std::numeric_limits<uint_least16_t>::max)()) ? false : is_combining_implementation(static_cast<unsigned short>(c));
+}
+#endif
+#endif
+#endif
+
+//
+// is a charT c a line separator?
+//
+template <class charT>
+inline bool is_separator(charT c)
+{
+ return BOOST_REGEX_MAKE_BOOL(
+ (c == static_cast<charT>('\n'))
+ || (c == static_cast<charT>('\r'))
+ || (c == static_cast<charT>('\f'))
+ || (static_cast<boost::uint16_t>(c) == 0x2028u)
+ || (static_cast<boost::uint16_t>(c) == 0x2029u)
+ || (static_cast<boost::uint16_t>(c) == 0x85u));
+}
+template <>
+inline bool is_separator<char>(char c)
+{
+ return BOOST_REGEX_MAKE_BOOL((c == '\n') || (c == '\r') || (c == '\f'));
+}
+
+//
+// get a default collating element:
+//
+BOOST_REGEX_DECL std::string BOOST_REGEX_CALL lookup_default_collate_name(const std::string& name);
+
+//
+// get the state_id of a character clasification, the individual
+// traits classes then transform that state_id into a bitmask:
+//
+template <class charT>
+struct character_pointer_range
+{
+ const charT* p1;
+ const charT* p2;
+
+ bool operator < (const character_pointer_range& r)const
+ {
+ return std::lexicographical_compare(p1, p2, r.p1, r.p2);
+ }
+ bool operator == (const character_pointer_range& r)const
+ {
+ // Not only do we check that the ranges are of equal size before
+ // calling std::equal, but there is no other algorithm available:
+ // not even a non-standard MS one. So forward to unchecked_equal
+ // in the MS case.
+ return ((p2 - p1) == (r.p2 - r.p1)) && re_detail::equal(p1, p2, r.p1);
+ }
+};
+template <class charT>
+int get_default_class_id(const charT* p1, const charT* p2)
+{
+ static const charT data[73] = {
+ 'a', 'l', 'n', 'u', 'm',
+ 'a', 'l', 'p', 'h', 'a',
+ 'b', 'l', 'a', 'n', 'k',
+ 'c', 'n', 't', 'r', 'l',
+ 'd', 'i', 'g', 'i', 't',
+ 'g', 'r', 'a', 'p', 'h',
+ 'l', 'o', 'w', 'e', 'r',
+ 'p', 'r', 'i', 'n', 't',
+ 'p', 'u', 'n', 'c', 't',
+ 's', 'p', 'a', 'c', 'e',
+ 'u', 'n', 'i', 'c', 'o', 'd', 'e',
+ 'u', 'p', 'p', 'e', 'r',
+ 'v',
+ 'w', 'o', 'r', 'd',
+ 'x', 'd', 'i', 'g', 'i', 't',
+ };
+
+ static const character_pointer_range<charT> ranges[21] =
+ {
+ {data+0, data+5,}, // alnum
+ {data+5, data+10,}, // alpha
+ {data+10, data+15,}, // blank
+ {data+15, data+20,}, // cntrl
+ {data+20, data+21,}, // d
+ {data+20, data+25,}, // digit
+ {data+25, data+30,}, // graph
+ {data+29, data+30,}, // h
+ {data+30, data+31,}, // l
+ {data+30, data+35,}, // lower
+ {data+35, data+40,}, // print
+ {data+40, data+45,}, // punct
+ {data+45, data+46,}, // s
+ {data+45, data+50,}, // space
+ {data+57, data+58,}, // u
+ {data+50, data+57,}, // unicode
+ {data+57, data+62,}, // upper
+ {data+62, data+63,}, // v
+ {data+63, data+64,}, // w
+ {data+63, data+67,}, // word
+ {data+67, data+73,}, // xdigit
+ };
+ static const character_pointer_range<charT>* ranges_begin = ranges;
+ static const character_pointer_range<charT>* ranges_end = ranges + (sizeof(ranges)/sizeof(ranges[0]));
+
+ character_pointer_range<charT> t = { p1, p2, };
+ const character_pointer_range<charT>* p = std::lower_bound(ranges_begin, ranges_end, t);
+ if((p != ranges_end) && (t == *p))
+ return static_cast<int>(p - ranges);
+ return -1;
+}
+
+//
+// helper functions:
+//
+template <class charT>
+std::ptrdiff_t global_length(const charT* p)
+{
+ std::ptrdiff_t n = 0;
+ while(*p)
+ {
+ ++p;
+ ++n;
+ }
+ return n;
+}
+template<>
+inline std::ptrdiff_t global_length<char>(const char* p)
+{
+ return (std::strlen)(p);
+}
+#ifndef BOOST_NO_WREGEX
+template<>
+inline std::ptrdiff_t global_length<wchar_t>(const wchar_t* p)
+{
+ return (std::wcslen)(p);
+}
+#endif
+template <class charT>
+inline charT BOOST_REGEX_CALL global_lower(charT c)
+{
+ return c;
+}
+template <class charT>
+inline charT BOOST_REGEX_CALL global_upper(charT c)
+{
+ return c;
+}
+
+BOOST_REGEX_DECL char BOOST_REGEX_CALL do_global_lower(char c);
+BOOST_REGEX_DECL char BOOST_REGEX_CALL do_global_upper(char c);
+#ifndef BOOST_NO_WREGEX
+BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL do_global_lower(wchar_t c);
+BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL do_global_upper(wchar_t c);
+#endif
+#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
+BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL do_global_lower(unsigned short c);
+BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL do_global_upper(unsigned short c);
+#endif
+//
+// This sucks: declare template specialisations of global_lower/global_upper
+// that just forward to the non-template implementation functions. We do
+// this because there is one compiler (Compaq Tru64 C++) that doesn't seem
+// to differentiate between templates and non-template overloads....
+// what's more, the primary template, plus all overloads have to be
+// defined in the same translation unit (if one is inline they all must be)
+// otherwise the "local template instantiation" compiler option can pick
+// the wrong instantiation when linking:
+//
+template<> inline char BOOST_REGEX_CALL global_lower<char>(char c){ return do_global_lower(c); }
+template<> inline char BOOST_REGEX_CALL global_upper<char>(char c){ return do_global_upper(c); }
+#ifndef BOOST_NO_WREGEX
+template<> inline wchar_t BOOST_REGEX_CALL global_lower<wchar_t>(wchar_t c){ return do_global_lower(c); }
+template<> inline wchar_t BOOST_REGEX_CALL global_upper<wchar_t>(wchar_t c){ return do_global_upper(c); }
+#endif
+#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
+template<> inline unsigned short BOOST_REGEX_CALL global_lower<unsigned short>(unsigned short c){ return do_global_lower(c); }
+template<> inline unsigned short BOOST_REGEX_CALL global_upper<unsigned short>(unsigned short c){ return do_global_upper(c); }
+#endif
+
+template <class charT>
+int global_value(charT c)
+{
+ static const charT zero = '0';
+ static const charT nine = '9';
+ static const charT a = 'a';
+ static const charT f = 'f';
+ static const charT A = 'A';
+ static const charT F = 'F';
+
+ if(c > f) return -1;
+ if(c >= a) return 10 + (c - a);
+ if(c > F) return -1;
+ if(c >= A) return 10 + (c - A);
+ if(c > nine) return -1;
+ if(c >= zero) return c - zero;
+ return -1;
+}
+template <class charT, class traits>
+int global_toi(const charT*& p1, const charT* p2, int radix, const traits& t)
+{
+ (void)t; // warning suppression
+ int next_value = t.value(*p1, radix);
+ if((p1 == p2) || (next_value < 0) || (next_value >= radix))
+ return -1;
+ int result = 0;
+ while(p1 != p2)
+ {
+ next_value = t.value(*p1, radix);
+ if((next_value < 0) || (next_value >= radix))
+ break;
+ result *= radix;
+ result += next_value;
+ ++p1;
+ }
+ return result;
+}
+
+template <class charT>
+inline const charT* get_escape_R_string()
+{
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable:4309)
+#endif
+ static const charT e1[] = { '(', '?', '>', '\x0D', '\x0A', '?',
+ '|', '[', '\x0A', '\x0B', '\x0C', '\x85', '\\', 'x', '{', '2', '0', '2', '8', '}',
+ '\\', 'x', '{', '2', '0', '2', '9', '}', ']', ')', '\0' };
+ static const charT e2[] = { '(', '?', '>', '\x0D', '\x0A', '?',
+ '|', '[', '\x0A', '\x0B', '\x0C', '\x85', ']', ')', '\0' };
+
+ charT c = static_cast<charT>(0x2029u);
+ bool b = (static_cast<unsigned>(c) == 0x2029u);
+
+ return (b ? e1 : e2);
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+}
+
+template <>
+inline const char* get_escape_R_string<char>()
+{
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable:4309)
+#endif
+ static const char e2[] = { '(', '?', '>', '\x0D', '\x0A', '?',
+ '|', '[', '\x0A', '\x0B', '\x0C', '\x85', ']', ')', '\0' };
+ return e2;
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+}
+
+} // re_detail
+} // boost
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/ext/boost/regex/v4/regex_workaround.hpp b/ext/boost/regex/v4/regex_workaround.hpp
new file mode 100644
index 0000000000..06527f1a1f
--- /dev/null
+++ b/ext/boost/regex/v4/regex_workaround.hpp
@@ -0,0 +1,202 @@
+/*
+ *
+ * Copyright (c) 1998-2005
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE regex_workarounds.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares Misc workarounds.
+ */
+
+#ifndef BOOST_REGEX_WORKAROUND_HPP
+#define BOOST_REGEX_WORKAROUND_HPP
+
+
+#include <new>
+#include <cstring>
+#include <cstdlib>
+#include <cstddef>
+#include <cassert>
+#include <cstdio>
+#include <climits>
+#include <string>
+#include <stdexcept>
+#include <iterator>
+#include <algorithm>
+#include <iosfwd>
+#include <vector>
+#include <map>
+#include <boost/limits.hpp>
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/mpl/bool_fwd.hpp>
+#ifndef BOOST_NO_STD_LOCALE
+# include <locale>
+#endif
+
+#if defined(BOOST_NO_STDC_NAMESPACE)
+namespace std{
+ using ::sprintf; using ::strcpy; using ::strcat; using ::strlen;
+}
+#endif
+
+namespace boost{ namespace re_detail{
+#ifdef BOOST_NO_STD_DISTANCE
+template <class T>
+std::ptrdiff_t distance(const T& x, const T& y)
+{ return y - x; }
+#else
+using std::distance;
+#endif
+}}
+
+
+#ifdef BOOST_REGEX_NO_BOOL
+# define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>((x) ? true : false)
+#else
+# define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>(x)
+#endif
+
+/*****************************************************************************
+ *
+ * Fix broken broken namespace support:
+ *
+ ****************************************************************************/
+
+#if defined(BOOST_NO_STDC_NAMESPACE) && defined(__cplusplus)
+
+namespace std{
+ using ::ptrdiff_t;
+ using ::size_t;
+ using ::abs;
+ using ::memset;
+ using ::memcpy;
+}
+
+#endif
+
+/*****************************************************************************
+ *
+ * helper functions pointer_construct/pointer_destroy:
+ *
+ ****************************************************************************/
+
+#ifdef __cplusplus
+namespace boost{ namespace re_detail{
+
+#ifdef BOOST_MSVC
+#pragma warning (push)
+#pragma warning (disable : 4100)
+#endif
+
+template <class T>
+inline void pointer_destroy(T* p)
+{ p->~T(); (void)p; }
+
+#ifdef BOOST_MSVC
+#pragma warning (pop)
+#endif
+
+template <class T>
+inline void pointer_construct(T* p, const T& t)
+{ new (p) T(t); }
+
+}} // namespaces
+#endif
+
+/*****************************************************************************
+ *
+ * helper function copy:
+ *
+ ****************************************************************************/
+
+#ifdef __cplusplus
+namespace boost{ namespace re_detail{
+#if BOOST_WORKAROUND(BOOST_MSVC,>=1400) && BOOST_WORKAROUND(BOOST_MSVC, <1600) && defined(_CPPLIB_VER) && defined(BOOST_DINKUMWARE_STDLIB) && !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))
+ //
+ // MSVC 8 will either emit warnings or else refuse to compile
+ // code that makes perfectly legitimate use of std::copy, when
+ // the OutputIterator type is a user-defined class (apparently all user
+ // defined iterators are "unsafe"). This code works around that:
+ //
+ template<class InputIterator, class OutputIterator>
+ inline OutputIterator copy(
+ InputIterator first,
+ InputIterator last,
+ OutputIterator dest
+ )
+ {
+ return stdext::unchecked_copy(first, last, dest);
+ }
+ template<class InputIterator1, class InputIterator2>
+ inline bool equal(
+ InputIterator1 first,
+ InputIterator1 last,
+ InputIterator2 with
+ )
+ {
+ return stdext::unchecked_equal(first, last, with);
+ }
+
+#else
+ using std::copy;
+ using std::equal;
+#endif
+#if BOOST_WORKAROUND(BOOST_MSVC,>=1400) && defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__
+
+ // use safe versions of strcpy etc:
+ using ::strcpy_s;
+ using ::strcat_s;
+#else
+ inline std::size_t strcpy_s(
+ char *strDestination,
+ std::size_t sizeInBytes,
+ const char *strSource
+ )
+ {
+ if(std::strlen(strSource)+1 > sizeInBytes)
+ return 1;
+ std::strcpy(strDestination, strSource);
+ return 0;
+ }
+ inline std::size_t strcat_s(
+ char *strDestination,
+ std::size_t sizeInBytes,
+ const char *strSource
+ )
+ {
+ if(std::strlen(strSource) + std::strlen(strDestination) + 1 > sizeInBytes)
+ return 1;
+ std::strcat(strDestination, strSource);
+ return 0;
+ }
+
+#endif
+
+ inline void overflow_error_if_not_zero(std::size_t i)
+ {
+ if(i)
+ {
+ std::overflow_error e("String buffer too small");
+ boost::throw_exception(e);
+ }
+ }
+
+}} // namespaces
+
+#endif // __cplusplus
+
+#endif // include guard
+
diff --git a/ext/boost/regex/v4/states.hpp b/ext/boost/regex/v4/states.hpp
new file mode 100644
index 0000000000..efdebbe59f
--- /dev/null
+++ b/ext/boost/regex/v4/states.hpp
@@ -0,0 +1,293 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE states.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares internal state machine structures.
+ */
+
+#ifndef BOOST_REGEX_V4_STATES_HPP
+#define BOOST_REGEX_V4_STATES_HPP
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace boost{
+namespace re_detail{
+
+/*** mask_type *******************************************************
+Whenever we have a choice of two alternatives, we use an array of bytes
+to indicate which of the two alternatives it is possible to take for any
+given input character. If mask_take is set, then we can take the next
+state, and if mask_skip is set then we can take the alternative.
+***********************************************************************/
+enum mask_type
+{
+ mask_take = 1,
+ mask_skip = 2,
+ mask_init = 4,
+ mask_any = mask_skip | mask_take,
+ mask_all = mask_any
+};
+
+/*** helpers **********************************************************
+These helpers let us use function overload resolution to detect whether
+we have narrow or wide character strings:
+***********************************************************************/
+struct _narrow_type{};
+struct _wide_type{};
+template <class charT> struct is_byte;
+template<> struct is_byte<char> { typedef _narrow_type width_type; };
+template<> struct is_byte<unsigned char>{ typedef _narrow_type width_type; };
+template<> struct is_byte<signed char> { typedef _narrow_type width_type; };
+template <class charT> struct is_byte { typedef _wide_type width_type; };
+
+/*** enum syntax_element_type ******************************************
+Every record in the state machine falls into one of the following types:
+***********************************************************************/
+enum syntax_element_type
+{
+ // start of a marked sub-expression, or perl-style (?...) extension
+ syntax_element_startmark = 0,
+ // end of a marked sub-expression, or perl-style (?...) extension
+ syntax_element_endmark = syntax_element_startmark + 1,
+ // any sequence of literal characters
+ syntax_element_literal = syntax_element_endmark + 1,
+ // start of line assertion: ^
+ syntax_element_start_line = syntax_element_literal + 1,
+ // end of line assertion $
+ syntax_element_end_line = syntax_element_start_line + 1,
+ // match any character: .
+ syntax_element_wild = syntax_element_end_line + 1,
+ // end of expression: we have a match when we get here
+ syntax_element_match = syntax_element_wild + 1,
+ // perl style word boundary: \b
+ syntax_element_word_boundary = syntax_element_match + 1,
+ // perl style within word boundary: \B
+ syntax_element_within_word = syntax_element_word_boundary + 1,
+ // start of word assertion: \<
+ syntax_element_word_start = syntax_element_within_word + 1,
+ // end of word assertion: \>
+ syntax_element_word_end = syntax_element_word_start + 1,
+ // start of buffer assertion: \`
+ syntax_element_buffer_start = syntax_element_word_end + 1,
+ // end of buffer assertion: \'
+ syntax_element_buffer_end = syntax_element_buffer_start + 1,
+ // backreference to previously matched sub-expression
+ syntax_element_backref = syntax_element_buffer_end + 1,
+ // either a wide character set [..] or one with multicharacter collating elements:
+ syntax_element_long_set = syntax_element_backref + 1,
+ // narrow character set: [...]
+ syntax_element_set = syntax_element_long_set + 1,
+ // jump to a new state in the machine:
+ syntax_element_jump = syntax_element_set + 1,
+ // choose between two production states:
+ syntax_element_alt = syntax_element_jump + 1,
+ // a repeat
+ syntax_element_rep = syntax_element_alt + 1,
+ // match a combining character sequence
+ syntax_element_combining = syntax_element_rep + 1,
+ // perl style soft buffer end: \z
+ syntax_element_soft_buffer_end = syntax_element_combining + 1,
+ // perl style continuation: \G
+ syntax_element_restart_continue = syntax_element_soft_buffer_end + 1,
+ // single character repeats:
+ syntax_element_dot_rep = syntax_element_restart_continue + 1,
+ syntax_element_char_rep = syntax_element_dot_rep + 1,
+ syntax_element_short_set_rep = syntax_element_char_rep + 1,
+ syntax_element_long_set_rep = syntax_element_short_set_rep + 1,
+ // a backstep for lookbehind repeats:
+ syntax_element_backstep = syntax_element_long_set_rep + 1,
+ // an assertion that a mark was matched:
+ syntax_element_assert_backref = syntax_element_backstep + 1,
+ syntax_element_toggle_case = syntax_element_assert_backref + 1,
+ // a recursive expression:
+ syntax_element_recurse = syntax_element_toggle_case + 1
+};
+
+#ifdef BOOST_REGEX_DEBUG
+// dwa 09/26/00 - This is needed to suppress warnings about an ambiguous conversion
+std::ostream& operator<<(std::ostream&, syntax_element_type);
+#endif
+
+struct re_syntax_base;
+
+/*** union offset_type ************************************************
+Points to another state in the machine. During machine construction
+we use integral offsets, but these are converted to pointers before
+execution of the machine.
+***********************************************************************/
+union offset_type
+{
+ re_syntax_base* p;
+ std::ptrdiff_t i;
+};
+
+/*** struct re_syntax_base ********************************************
+Base class for all states in the machine.
+***********************************************************************/
+struct re_syntax_base
+{
+ syntax_element_type type; // what kind of state this is
+ offset_type next; // next state in the machine
+};
+
+/*** struct re_brace **************************************************
+A marked parenthesis.
+***********************************************************************/
+struct re_brace : public re_syntax_base
+{
+ // The index to match, can be zero (don't mark the sub-expression)
+ // or negative (for perl style (?...) extentions):
+ int index;
+ bool icase;
+};
+
+/*** struct re_dot **************************************************
+Match anything.
+***********************************************************************/
+enum
+{
+ dont_care = 1,
+ force_not_newline = 0,
+ force_newline = 2,
+
+ test_not_newline = 2,
+ test_newline = 3
+};
+struct re_dot : public re_syntax_base
+{
+ unsigned char mask;
+};
+
+/*** struct re_literal ************************************************
+A string of literals, following this structure will be an
+array of characters: charT[length]
+***********************************************************************/
+struct re_literal : public re_syntax_base
+{
+ unsigned int length;
+};
+
+/*** struct re_case ************************************************
+Indicates whether we are moving to a case insensive block or not
+***********************************************************************/
+struct re_case : public re_syntax_base
+{
+ bool icase;
+};
+
+/*** struct re_set_long ***********************************************
+A wide character set of characters, following this structure will be
+an array of type charT:
+First csingles null-terminated strings
+Then 2 * cranges NULL terminated strings
+Then cequivalents NULL terminated strings
+***********************************************************************/
+template <class mask_type>
+struct re_set_long : public re_syntax_base
+{
+ unsigned int csingles, cranges, cequivalents;
+ mask_type cclasses;
+ mask_type cnclasses;
+ bool isnot;
+ bool singleton;
+};
+
+/*** struct re_set ****************************************************
+A set of narrow-characters, matches any of _map which is none-zero
+***********************************************************************/
+struct re_set : public re_syntax_base
+{
+ unsigned char _map[1 << CHAR_BIT];
+};
+
+/*** struct re_jump ***************************************************
+Jump to a new location in the machine (not next).
+***********************************************************************/
+struct re_jump : public re_syntax_base
+{
+ offset_type alt; // location to jump to
+};
+
+/*** struct re_alt ***************************************************
+Jump to a new location in the machine (possibly next).
+***********************************************************************/
+struct re_alt : public re_jump
+{
+ unsigned char _map[1 << CHAR_BIT]; // which characters can take the jump
+ unsigned int can_be_null; // true if we match a NULL string
+};
+
+/*** struct re_repeat *************************************************
+Repeat a section of the machine
+***********************************************************************/
+struct re_repeat : public re_alt
+{
+ std::size_t min, max; // min and max allowable repeats
+ int state_id; // Unique identifier for this repeat
+ bool leading; // True if this repeat is at the start of the machine (lets us optimize some searches)
+ bool greedy; // True if this is a greedy repeat
+};
+
+/*** enum re_jump_size_type *******************************************
+Provides compiled size of re_jump structure (allowing for trailing alignment).
+We provide this so we know how manybytes to insert when constructing the machine
+(The value of padding_mask is defined in regex_raw_buffer.hpp).
+***********************************************************************/
+enum re_jump_size_type
+{
+ re_jump_size = (sizeof(re_jump) + padding_mask) & ~(padding_mask),
+ re_repeater_size = (sizeof(re_repeat) + padding_mask) & ~(padding_mask),
+ re_alt_size = (sizeof(re_alt) + padding_mask) & ~(padding_mask)
+};
+
+/*** proc re_is_set_member *********************************************
+Forward declaration: we'll need this one later...
+***********************************************************************/
+
+template<class charT, class traits>
+struct regex_data;
+
+template <class iterator, class charT, class traits_type, class char_classT>
+iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
+ iterator last,
+ const re_set_long<char_classT>* set_,
+ const regex_data<charT, traits_type>& e, bool icase);
+
+} // namespace re_detail
+
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
+
diff --git a/ext/boost/regex/v4/sub_match.hpp b/ext/boost/regex/v4/sub_match.hpp
new file mode 100644
index 0000000000..1c79e39a9a
--- /dev/null
+++ b/ext/boost/regex/v4/sub_match.hpp
@@ -0,0 +1,509 @@
+/*
+ *
+ * Copyright (c) 1998-2002
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE sub_match.cpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares template class sub_match.
+ */
+
+#ifndef BOOST_REGEX_V4_SUB_MATCH_HPP
+#define BOOST_REGEX_V4_SUB_MATCH_HPP
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+namespace boost{
+
+template <class BidiIterator>
+struct sub_match : public std::pair<BidiIterator, BidiIterator>
+{
+ typedef typename re_detail::regex_iterator_traits<BidiIterator>::value_type value_type;
+#if defined(BOOST_NO_STD_ITERATOR_TRAITS) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+ typedef std::ptrdiff_t difference_type;
+#else
+ typedef typename re_detail::regex_iterator_traits<BidiIterator>::difference_type difference_type;
+#endif
+ typedef BidiIterator iterator_type;
+ typedef BidiIterator iterator;
+ typedef BidiIterator const_iterator;
+
+ bool matched;
+
+ sub_match() : std::pair<BidiIterator, BidiIterator>(), matched(false) {}
+ sub_match(BidiIterator i) : std::pair<BidiIterator, BidiIterator>(i, i), matched(false) {}
+#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
+ && !BOOST_WORKAROUND(BOOST_MSVC, < 1310)\
+ && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)\
+ && !BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
+ template <class T, class A>
+ operator std::basic_string<value_type, T, A> ()const
+ {
+ return std::basic_string<value_type, T, A>(this->first, this->second);
+ }
+#else
+ operator std::basic_string<value_type> ()const
+ {
+ return str();
+ }
+#endif
+ difference_type BOOST_REGEX_CALL length()const
+ {
+ difference_type n = ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second);
+ return n;
+ }
+ std::basic_string<value_type> str()const
+ {
+ std::basic_string<value_type> result;
+ std::size_t len = ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second);
+ result.reserve(len);
+ BidiIterator i = this->first;
+ while(i != this->second)
+ {
+ result.append(1, *i);
+ ++i;
+ }
+ return result;
+ }
+ int compare(const sub_match& s)const
+ {
+ if(matched != s.matched)
+ return static_cast<int>(matched) - static_cast<int>(s.matched);
+ return str().compare(s.str());
+ }
+ int compare(const std::basic_string<value_type>& s)const
+ {
+ return str().compare(s);
+ }
+ int compare(const value_type* p)const
+ {
+ return str().compare(p);
+ }
+
+ bool operator==(const sub_match& that)const
+ { return compare(that) == 0; }
+ bool BOOST_REGEX_CALL operator !=(const sub_match& that)const
+ { return compare(that) != 0; }
+ bool operator<(const sub_match& that)const
+ { return compare(that) < 0; }
+ bool operator>(const sub_match& that)const
+ { return compare(that) > 0; }
+ bool operator<=(const sub_match& that)const
+ { return compare(that) <= 0; }
+ bool operator>=(const sub_match& that)const
+ { return compare(that) >= 0; }
+
+#ifdef BOOST_REGEX_MATCH_EXTRA
+ typedef std::vector<sub_match<BidiIterator> > capture_sequence_type;
+
+ const capture_sequence_type& captures()const
+ {
+ if(!m_captures)
+ m_captures.reset(new capture_sequence_type());
+ return *m_captures;
+ }
+ //
+ // Private implementation API: DO NOT USE!
+ //
+ capture_sequence_type& get_captures()const
+ {
+ if(!m_captures)
+ m_captures.reset(new capture_sequence_type());
+ return *m_captures;
+ }
+
+private:
+ mutable boost::scoped_ptr<capture_sequence_type> m_captures;
+public:
+
+#endif
+ sub_match(const sub_match& that, bool
+#ifdef BOOST_REGEX_MATCH_EXTRA
+ deep_copy
+#endif
+ = true
+ )
+ : std::pair<BidiIterator, BidiIterator>(that),
+ matched(that.matched)
+ {
+#ifdef BOOST_REGEX_MATCH_EXTRA
+ if(that.m_captures)
+ if(deep_copy)
+ m_captures.reset(new capture_sequence_type(*(that.m_captures)));
+#endif
+ }
+ sub_match& operator=(const sub_match& that)
+ {
+ this->first = that.first;
+ this->second = that.second;
+ matched = that.matched;
+#ifdef BOOST_REGEX_MATCH_EXTRA
+ if(that.m_captures)
+ get_captures() = *(that.m_captures);
+#endif
+ return *this;
+ }
+
+
+#ifdef BOOST_OLD_REGEX_H
+ //
+ // the following are deprecated, do not use!!
+ //
+ operator int()const;
+ operator unsigned int()const;
+ operator short()const
+ {
+ return (short)(int)(*this);
+ }
+ operator unsigned short()const
+ {
+ return (unsigned short)(unsigned int)(*this);
+ }
+#endif
+};
+
+typedef sub_match<const char*> csub_match;
+typedef sub_match<std::string::const_iterator> ssub_match;
+#ifndef BOOST_NO_WREGEX
+typedef sub_match<const wchar_t*> wcsub_match;
+typedef sub_match<std::wstring::const_iterator> wssub_match;
+#endif
+
+// comparison to std::basic_string<> part 1:
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator == (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+ const sub_match<RandomAccessIterator>& m)
+{ return s.compare(m.str()) == 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator != (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+ const sub_match<RandomAccessIterator>& m)
+{ return s.compare(m.str()) != 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator < (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+ const sub_match<RandomAccessIterator>& m)
+{ return s.compare(m.str()) < 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator <= (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+ const sub_match<RandomAccessIterator>& m)
+{ return s.compare(m.str()) <= 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator >= (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+ const sub_match<RandomAccessIterator>& m)
+{ return s.compare(m.str()) >= 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator > (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+ const sub_match<RandomAccessIterator>& m)
+{ return s.compare(m.str()) > 0; }
+// comparison to std::basic_string<> part 2:
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator == (const sub_match<RandomAccessIterator>& m,
+ const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{ return m.str().compare(s) == 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator != (const sub_match<RandomAccessIterator>& m,
+ const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{ return m.str().compare(s) != 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator < (const sub_match<RandomAccessIterator>& m,
+ const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{ return m.str().compare(s) < 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator > (const sub_match<RandomAccessIterator>& m,
+ const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{ return m.str().compare(s) > 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator <= (const sub_match<RandomAccessIterator>& m,
+ const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{ return m.str().compare(s) <= 0; }
+template <class RandomAccessIterator, class traits, class Allocator>
+inline bool operator >= (const sub_match<RandomAccessIterator>& m,
+ const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{ return m.str().compare(s) >= 0; }
+// comparison to const charT* part 1:
+template <class RandomAccessIterator>
+inline bool operator == (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
+{ return m.str().compare(s) == 0; }
+template <class RandomAccessIterator>
+inline bool operator != (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
+{ return m.str().compare(s) != 0; }
+template <class RandomAccessIterator>
+inline bool operator > (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
+{ return m.str().compare(s) > 0; }
+template <class RandomAccessIterator>
+inline bool operator < (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
+{ return m.str().compare(s) < 0; }
+template <class RandomAccessIterator>
+inline bool operator >= (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
+{ return m.str().compare(s) >= 0; }
+template <class RandomAccessIterator>
+inline bool operator <= (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
+{ return m.str().compare(s) <= 0; }
+// comparison to const charT* part 2:
+template <class RandomAccessIterator>
+inline bool operator == (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+ const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(s) == 0; }
+template <class RandomAccessIterator>
+inline bool operator != (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+ const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(s) != 0; }
+template <class RandomAccessIterator>
+inline bool operator < (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+ const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(s) > 0; }
+template <class RandomAccessIterator>
+inline bool operator > (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+ const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(s) < 0; }
+template <class RandomAccessIterator>
+inline bool operator <= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+ const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(s) >= 0; }
+template <class RandomAccessIterator>
+inline bool operator >= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+ const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(s) <= 0; }
+
+// comparison to const charT& part 1:
+template <class RandomAccessIterator>
+inline bool operator == (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{ return m.str().compare(0, m.length(), &s, 1) == 0; }
+template <class RandomAccessIterator>
+inline bool operator != (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{ return m.str().compare(0, m.length(), &s, 1) != 0; }
+template <class RandomAccessIterator>
+inline bool operator > (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{ return m.str().compare(0, m.length(), &s, 1) > 0; }
+template <class RandomAccessIterator>
+inline bool operator < (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{ return m.str().compare(0, m.length(), &s, 1) < 0; }
+template <class RandomAccessIterator>
+inline bool operator >= (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{ return m.str().compare(0, m.length(), &s, 1) >= 0; }
+template <class RandomAccessIterator>
+inline bool operator <= (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{ return m.str().compare(0, m.length(), &s, 1) <= 0; }
+// comparison to const charT* part 2:
+template <class RandomAccessIterator>
+inline bool operator == (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+ const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(0, m.length(), &s, 1) == 0; }
+template <class RandomAccessIterator>
+inline bool operator != (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+ const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(0, m.length(), &s, 1) != 0; }
+template <class RandomAccessIterator>
+inline bool operator < (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+ const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(0, m.length(), &s, 1) > 0; }
+template <class RandomAccessIterator>
+inline bool operator > (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+ const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(0, m.length(), &s, 1) < 0; }
+template <class RandomAccessIterator>
+inline bool operator <= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+ const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(0, m.length(), &s, 1) >= 0; }
+template <class RandomAccessIterator>
+inline bool operator >= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+ const sub_match<RandomAccessIterator>& m)
+{ return m.str().compare(0, m.length(), &s, 1) <= 0; }
+
+// addition operators:
+template <class RandomAccessIterator, class traits, class Allocator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>
+operator + (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
+ const sub_match<RandomAccessIterator>& m)
+{
+ std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;
+ result.reserve(s.size() + m.length() + 1);
+ return result.append(s).append(m.first, m.second);
+}
+template <class RandomAccessIterator, class traits, class Allocator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>
+operator + (const sub_match<RandomAccessIterator>& m,
+ const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
+{
+ std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;
+ result.reserve(s.size() + m.length() + 1);
+ return result.append(m.first, m.second).append(s);
+}
+#if !(defined(__GNUC__) && defined(BOOST_NO_STD_LOCALE))
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
+operator + (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+ const sub_match<RandomAccessIterator>& m)
+{
+ std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
+ result.reserve(std::char_traits<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);
+ return result.append(s).append(m.first, m.second);
+}
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
+operator + (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const * s)
+{
+ std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
+ result.reserve(std::char_traits<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);
+ return result.append(m.first, m.second).append(s);
+}
+#else
+// worwaround versions:
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
+operator + (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
+ const sub_match<RandomAccessIterator>& m)
+{
+ return s + m.str();
+}
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
+operator + (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const * s)
+{
+ return m.str() + s;
+}
+#endif
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
+operator + (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
+ const sub_match<RandomAccessIterator>& m)
+{
+ std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
+ result.reserve(m.length() + 2);
+ return result.append(1, s).append(m.first, m.second);
+}
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
+operator + (const sub_match<RandomAccessIterator>& m,
+ typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
+{
+ std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
+ result.reserve(m.length() + 2);
+ return result.append(m.first, m.second).append(1, s);
+}
+template <class RandomAccessIterator>
+inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
+operator + (const sub_match<RandomAccessIterator>& m1,
+ const sub_match<RandomAccessIterator>& m2)
+{
+ std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
+ result.reserve(m1.length() + m2.length() + 1);
+ return result.append(m1.first, m1.second).append(m2.first, m2.second);
+}
+#ifndef BOOST_NO_STD_LOCALE
+template <class charT, class traits, class RandomAccessIterator>
+std::basic_ostream<charT, traits>&
+ operator << (std::basic_ostream<charT, traits>& os,
+ const sub_match<RandomAccessIterator>& s)
+{
+ return (os << s.str());
+}
+#else
+template <class RandomAccessIterator>
+std::ostream& operator << (std::ostream& os,
+ const sub_match<RandomAccessIterator>& s)
+{
+ return (os << s.str());
+}
+#endif
+
+#ifdef BOOST_OLD_REGEX_H
+namespace re_detail{
+template <class BidiIterator, class charT>
+int do_toi(BidiIterator i, BidiIterator j, char c, int radix)
+{
+ std::string s(i, j);
+ char* p;
+ int result = std::strtol(s.c_str(), &p, radix);
+ if(*p)raise_regex_exception("Bad sub-expression");
+ return result;
+}
+
+//
+// helper:
+template <class I, class charT>
+int do_toi(I& i, I j, charT c)
+{
+ int result = 0;
+ while((i != j) && (isdigit(*i)))
+ {
+ result = result*10 + (*i - '0');
+ ++i;
+ }
+ return result;
+}
+}
+
+
+template <class BidiIterator>
+sub_match<BidiIterator>::operator int()const
+{
+ BidiIterator i = first;
+ BidiIterator j = second;
+ if(i == j)raise_regex_exception("Bad sub-expression");
+ int neg = 1;
+ if((i != j) && (*i == '-'))
+ {
+ neg = -1;
+ ++i;
+ }
+ neg *= re_detail::do_toi(i, j, *i);
+ if(i != j)raise_regex_exception("Bad sub-expression");
+ return neg;
+}
+template <class BidiIterator>
+sub_match<BidiIterator>::operator unsigned int()const
+{
+ BidiIterator i = first;
+ BidiIterator j = second;
+ if(i == j)
+ raise_regex_exception("Bad sub-expression");
+ return re_detail::do_toi(i, j, *first);
+}
+#endif
+
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/ext/boost/regex/v4/syntax_type.hpp b/ext/boost/regex/v4/syntax_type.hpp
new file mode 100644
index 0000000000..3efdf0b0f9
--- /dev/null
+++ b/ext/boost/regex/v4/syntax_type.hpp
@@ -0,0 +1,105 @@
+/*
+ *
+ * Copyright (c) 2003
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE syntax_type.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares regular expression synatx type enumerator.
+ */
+
+#ifndef BOOST_REGEX_SYNTAX_TYPE_HPP
+#define BOOST_REGEX_SYNTAX_TYPE_HPP
+
+namespace boost{
+namespace regex_constants{
+
+typedef unsigned char syntax_type;
+
+//
+// values chosen are binary compatible with previous version:
+//
+static const syntax_type syntax_char = 0;
+static const syntax_type syntax_open_mark = 1;
+static const syntax_type syntax_close_mark = 2;
+static const syntax_type syntax_dollar = 3;
+static const syntax_type syntax_caret = 4;
+static const syntax_type syntax_dot = 5;
+static const syntax_type syntax_star = 6;
+static const syntax_type syntax_plus = 7;
+static const syntax_type syntax_question = 8;
+static const syntax_type syntax_open_set = 9;
+static const syntax_type syntax_close_set = 10;
+static const syntax_type syntax_or = 11;
+static const syntax_type syntax_escape = 12;
+static const syntax_type syntax_dash = 14;
+static const syntax_type syntax_open_brace = 15;
+static const syntax_type syntax_close_brace = 16;
+static const syntax_type syntax_digit = 17;
+static const syntax_type syntax_comma = 27;
+static const syntax_type syntax_equal = 37;
+static const syntax_type syntax_colon = 36;
+static const syntax_type syntax_not = 53;
+
+// extensions:
+
+static const syntax_type syntax_hash = 13;
+static const syntax_type syntax_newline = 26;
+
+// escapes:
+
+typedef syntax_type escape_syntax_type;
+
+static const escape_syntax_type escape_type_word_assert = 18;
+static const escape_syntax_type escape_type_not_word_assert = 19;
+static const escape_syntax_type escape_type_control_f = 29;
+static const escape_syntax_type escape_type_control_n = 30;
+static const escape_syntax_type escape_type_control_r = 31;
+static const escape_syntax_type escape_type_control_t = 32;
+static const escape_syntax_type escape_type_control_v = 33;
+static const escape_syntax_type escape_type_ascii_control = 35;
+static const escape_syntax_type escape_type_hex = 34;
+static const escape_syntax_type escape_type_unicode = 0; // not used
+static const escape_syntax_type escape_type_identity = 0; // not used
+static const escape_syntax_type escape_type_backref = syntax_digit;
+static const escape_syntax_type escape_type_decimal = syntax_digit; // not used
+static const escape_syntax_type escape_type_class = 22;
+static const escape_syntax_type escape_type_not_class = 23;
+
+// extensions:
+
+static const escape_syntax_type escape_type_left_word = 20;
+static const escape_syntax_type escape_type_right_word = 21;
+static const escape_syntax_type escape_type_start_buffer = 24; // for \`
+static const escape_syntax_type escape_type_end_buffer = 25; // for \'
+static const escape_syntax_type escape_type_control_a = 28; // for \a
+static const escape_syntax_type escape_type_e = 38; // for \e
+static const escape_syntax_type escape_type_E = 47; // for \Q\E
+static const escape_syntax_type escape_type_Q = 48; // for \Q\E
+static const escape_syntax_type escape_type_X = 49; // for \X
+static const escape_syntax_type escape_type_C = 50; // for \C
+static const escape_syntax_type escape_type_Z = 51; // for \Z
+static const escape_syntax_type escape_type_G = 52; // for \G
+
+static const escape_syntax_type escape_type_property = 54; // for \p
+static const escape_syntax_type escape_type_not_property = 55; // for \P
+static const escape_syntax_type escape_type_named_char = 56; // for \N
+static const escape_syntax_type escape_type_extended_backref = 57; // for \g
+static const escape_syntax_type escape_type_reset_start_mark = 58; // for \K
+static const escape_syntax_type escape_type_line_ending = 59; // for \R
+
+static const escape_syntax_type syntax_max = 60;
+
+}
+}
+
+
+#endif
diff --git a/ext/boost/regex/v4/u32regex_iterator.hpp b/ext/boost/regex/v4/u32regex_iterator.hpp
new file mode 100644
index 0000000000..7e893e6951
--- /dev/null
+++ b/ext/boost/regex/v4/u32regex_iterator.hpp
@@ -0,0 +1,193 @@
+/*
+ *
+ * Copyright (c) 2003
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE u32regex_iterator.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Provides u32regex_iterator implementation.
+ */
+
+#ifndef BOOST_REGEX_V4_U32REGEX_ITERATOR_HPP
+#define BOOST_REGEX_V4_U32REGEX_ITERATOR_HPP
+
+namespace boost{
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+template <class BidirectionalIterator>
+class u32regex_iterator_implementation
+{
+ typedef u32regex regex_type;
+
+ match_results<BidirectionalIterator> what; // current match
+ BidirectionalIterator base; // start of sequence
+ BidirectionalIterator end; // end of sequence
+ const regex_type re; // the expression
+ match_flag_type flags; // flags for matching
+
+public:
+ u32regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f)
+ : base(), end(last), re(*p), flags(f){}
+ bool init(BidirectionalIterator first)
+ {
+ base = first;
+ return u32regex_search(first, end, what, re, flags, base);
+ }
+ bool compare(const u32regex_iterator_implementation& that)
+ {
+ if(this == &that) return true;
+ return (&re.get_data() == &that.re.get_data()) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);
+ }
+ const match_results<BidirectionalIterator>& get()
+ { return what; }
+ bool next()
+ {
+ //if(what.prefix().first != what[0].second)
+ // flags |= match_prev_avail;
+ BidirectionalIterator next_start = what[0].second;
+ match_flag_type f(flags);
+ if(!what.length())
+ f |= regex_constants::match_not_initial_null;
+ //if(base != next_start)
+ // f |= regex_constants::match_not_bob;
+ bool result = u32regex_search(next_start, end, what, re, f, base);
+ if(result)
+ what.set_base(base);
+ return result;
+ }
+private:
+ u32regex_iterator_implementation& operator=(const u32regex_iterator_implementation&);
+};
+
+template <class BidirectionalIterator>
+class u32regex_iterator
+#ifndef BOOST_NO_STD_ITERATOR
+ : public std::iterator<
+ std::forward_iterator_tag,
+ match_results<BidirectionalIterator>,
+ typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type,
+ const match_results<BidirectionalIterator>*,
+ const match_results<BidirectionalIterator>& >
+#endif
+{
+private:
+ typedef u32regex_iterator_implementation<BidirectionalIterator> impl;
+ typedef shared_ptr<impl> pimpl;
+public:
+ typedef u32regex regex_type;
+ typedef match_results<BidirectionalIterator> value_type;
+ typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type
+ difference_type;
+ typedef const value_type* pointer;
+ typedef const value_type& reference;
+ typedef std::forward_iterator_tag iterator_category;
+
+ u32regex_iterator(){}
+ u32regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
+ const regex_type& re,
+ match_flag_type m = match_default)
+ : pdata(new impl(&re, b, m))
+ {
+ if(!pdata->init(a))
+ {
+ pdata.reset();
+ }
+ }
+ u32regex_iterator(const u32regex_iterator& that)
+ : pdata(that.pdata) {}
+ u32regex_iterator& operator=(const u32regex_iterator& that)
+ {
+ pdata = that.pdata;
+ return *this;
+ }
+ bool operator==(const u32regex_iterator& that)const
+ {
+ if((pdata.get() == 0) || (that.pdata.get() == 0))
+ return pdata.get() == that.pdata.get();
+ return pdata->compare(*(that.pdata.get()));
+ }
+ bool operator!=(const u32regex_iterator& that)const
+ { return !(*this == that); }
+ const value_type& operator*()const
+ { return pdata->get(); }
+ const value_type* operator->()const
+ { return &(pdata->get()); }
+ u32regex_iterator& operator++()
+ {
+ cow();
+ if(0 == pdata->next())
+ {
+ pdata.reset();
+ }
+ return *this;
+ }
+ u32regex_iterator operator++(int)
+ {
+ u32regex_iterator result(*this);
+ ++(*this);
+ return result;
+ }
+private:
+
+ pimpl pdata;
+
+ void cow()
+ {
+ // copy-on-write
+ if(pdata.get() && !pdata.unique())
+ {
+ pdata.reset(new impl(*(pdata.get())));
+ }
+ }
+};
+
+typedef u32regex_iterator<const char*> utf8regex_iterator;
+typedef u32regex_iterator<const UChar*> utf16regex_iterator;
+typedef u32regex_iterator<const UChar32*> utf32regex_iterator;
+
+inline u32regex_iterator<const char*> make_u32regex_iterator(const char* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_iterator<const char*>(p, p+std::strlen(p), e, m);
+}
+#ifndef BOOST_NO_WREGEX
+inline u32regex_iterator<const wchar_t*> make_u32regex_iterator(const wchar_t* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_iterator<const wchar_t*>(p, p+std::wcslen(p), e, m);
+}
+#endif
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
+inline u32regex_iterator<const UChar*> make_u32regex_iterator(const UChar* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_iterator<const UChar*>(p, p+u_strlen(p), e, m);
+}
+#endif
+template <class charT, class Traits, class Alloc>
+inline u32regex_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
+ return u32regex_iterator<iter_type>(p.begin(), p.end(), e, m);
+}
+inline u32regex_iterator<const UChar*> make_u32regex_iterator(const UnicodeString& s, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, m);
+}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+} // namespace boost
+
+#endif // BOOST_REGEX_V4_REGEX_ITERATOR_HPP
+
diff --git a/ext/boost/regex/v4/u32regex_token_iterator.hpp b/ext/boost/regex/v4/u32regex_token_iterator.hpp
new file mode 100644
index 0000000000..2726d486fd
--- /dev/null
+++ b/ext/boost/regex/v4/u32regex_token_iterator.hpp
@@ -0,0 +1,377 @@
+/*
+ *
+ * Copyright (c) 2003
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE u32regex_token_iterator.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Provides u32regex_token_iterator implementation.
+ */
+
+#ifndef BOOST_REGEX_V4_U32REGEX_TOKEN_ITERATOR_HPP
+#define BOOST_REGEX_V4_U32REGEX_TOKEN_ITERATOR_HPP
+
+#if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
+ || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
+ || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
+//
+// Borland C++ Builder 6, and Visual C++ 6,
+// can't cope with the array template constructor
+// so we have a template member that will accept any type as
+// argument, and then assert that is really is an array:
+//
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_array.hpp>
+#endif
+
+namespace boost{
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#if BOOST_WORKAROUND(BOOST_MSVC, > 1300)
+# pragma warning(push)
+# pragma warning(disable:4700)
+#endif
+
+template <class BidirectionalIterator>
+class u32regex_token_iterator_implementation
+{
+ typedef u32regex regex_type;
+ typedef sub_match<BidirectionalIterator> value_type;
+
+ match_results<BidirectionalIterator> what; // current match
+ BidirectionalIterator end; // end of search area
+ BidirectionalIterator base; // start of search area
+ const regex_type re; // the expression
+ match_flag_type flags; // match flags
+ value_type result; // the current string result
+ int N; // the current sub-expression being enumerated
+ std::vector<int> subs; // the sub-expressions to enumerate
+
+public:
+ u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, int sub, match_flag_type f)
+ : end(last), re(*p), flags(f){ subs.push_back(sub); }
+ u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const std::vector<int>& v, match_flag_type f)
+ : end(last), re(*p), flags(f), subs(v){}
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+ // can't reliably get this to work....
+#elif (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
+ || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
+ || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \
+ || BOOST_WORKAROUND(__HP_aCC, < 60700)
+ template <class T>
+ u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const T& submatches, match_flag_type f)
+ : end(last), re(*p), flags(f)
+ {
+ // assert that T really is an array:
+ BOOST_STATIC_ASSERT(::boost::is_array<T>::value);
+ const std::size_t array_size = sizeof(T) / sizeof(submatches[0]);
+ for(std::size_t i = 0; i < array_size; ++i)
+ {
+ subs.push_back(submatches[i]);
+ }
+ }
+#else
+ template <std::size_t CN>
+ u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const int (&submatches)[CN], match_flag_type f)
+ : end(last), re(*p), flags(f)
+ {
+ for(std::size_t i = 0; i < CN; ++i)
+ {
+ subs.push_back(submatches[i]);
+ }
+ }
+#endif
+
+ bool init(BidirectionalIterator first)
+ {
+ base = first;
+ N = 0;
+ if(u32regex_search(first, end, what, re, flags, base) == true)
+ {
+ N = 0;
+ result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);
+ return true;
+ }
+ else if((subs[N] == -1) && (first != end))
+ {
+ result.first = first;
+ result.second = end;
+ result.matched = (first != end);
+ N = -1;
+ return true;
+ }
+ return false;
+ }
+ bool compare(const u32regex_token_iterator_implementation& that)
+ {
+ if(this == &that) return true;
+ return (&re.get_data() == &that.re.get_data())
+ && (end == that.end)
+ && (flags == that.flags)
+ && (N == that.N)
+ && (what[0].first == that.what[0].first)
+ && (what[0].second == that.what[0].second);
+ }
+ const value_type& get()
+ { return result; }
+ bool next()
+ {
+ if(N == -1)
+ return false;
+ if(N+1 < (int)subs.size())
+ {
+ ++N;
+ result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
+ return true;
+ }
+ //if(what.prefix().first != what[0].second)
+ // flags |= match_prev_avail | regex_constants::match_not_bob;
+ BidirectionalIterator last_end(what[0].second);
+ if(u32regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))
+ {
+ N =0;
+ result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
+ return true;
+ }
+ else if((last_end != end) && (subs[0] == -1))
+ {
+ N =-1;
+ result.first = last_end;
+ result.second = end;
+ result.matched = (last_end != end);
+ return true;
+ }
+ return false;
+ }
+private:
+ u32regex_token_iterator_implementation& operator=(const u32regex_token_iterator_implementation&);
+};
+
+template <class BidirectionalIterator>
+class u32regex_token_iterator
+#ifndef BOOST_NO_STD_ITERATOR
+ : public std::iterator<
+ std::forward_iterator_tag,
+ sub_match<BidirectionalIterator>,
+ typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type,
+ const sub_match<BidirectionalIterator>*,
+ const sub_match<BidirectionalIterator>& >
+#endif
+{
+private:
+ typedef u32regex_token_iterator_implementation<BidirectionalIterator> impl;
+ typedef shared_ptr<impl> pimpl;
+public:
+ typedef u32regex regex_type;
+ typedef sub_match<BidirectionalIterator> value_type;
+ typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type
+ difference_type;
+ typedef const value_type* pointer;
+ typedef const value_type& reference;
+ typedef std::forward_iterator_tag iterator_category;
+
+ u32regex_token_iterator(){}
+ u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
+ int submatch = 0, match_flag_type m = match_default)
+ : pdata(new impl(&re, b, submatch, m))
+ {
+ if(!pdata->init(a))
+ pdata.reset();
+ }
+ u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
+ const std::vector<int>& submatches, match_flag_type m = match_default)
+ : pdata(new impl(&re, b, submatches, m))
+ {
+ if(!pdata->init(a))
+ pdata.reset();
+ }
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+ // can't reliably get this to work....
+#elif (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
+ || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
+ || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \
+ || BOOST_WORKAROUND(__HP_aCC, < 60700)
+ template <class T>
+ u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
+ const T& submatches, match_flag_type m = match_default)
+ : pdata(new impl(&re, b, submatches, m))
+ {
+ if(!pdata->init(a))
+ pdata.reset();
+ }
+#else
+ template <std::size_t N>
+ u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
+ const int (&submatches)[N], match_flag_type m = match_default)
+ : pdata(new impl(&re, b, submatches, m))
+ {
+ if(!pdata->init(a))
+ pdata.reset();
+ }
+#endif
+ u32regex_token_iterator(const u32regex_token_iterator& that)
+ : pdata(that.pdata) {}
+ u32regex_token_iterator& operator=(const u32regex_token_iterator& that)
+ {
+ pdata = that.pdata;
+ return *this;
+ }
+ bool operator==(const u32regex_token_iterator& that)const
+ {
+ if((pdata.get() == 0) || (that.pdata.get() == 0))
+ return pdata.get() == that.pdata.get();
+ return pdata->compare(*(that.pdata.get()));
+ }
+ bool operator!=(const u32regex_token_iterator& that)const
+ { return !(*this == that); }
+ const value_type& operator*()const
+ { return pdata->get(); }
+ const value_type* operator->()const
+ { return &(pdata->get()); }
+ u32regex_token_iterator& operator++()
+ {
+ cow();
+ if(0 == pdata->next())
+ {
+ pdata.reset();
+ }
+ return *this;
+ }
+ u32regex_token_iterator operator++(int)
+ {
+ u32regex_token_iterator result(*this);
+ ++(*this);
+ return result;
+ }
+private:
+
+ pimpl pdata;
+
+ void cow()
+ {
+ // copy-on-write
+ if(pdata.get() && !pdata.unique())
+ {
+ pdata.reset(new impl(*(pdata.get())));
+ }
+ }
+};
+
+typedef u32regex_token_iterator<const char*> utf8regex_token_iterator;
+typedef u32regex_token_iterator<const UChar*> utf16regex_token_iterator;
+typedef u32regex_token_iterator<const UChar32*> utf32regex_token_iterator;
+
+// construction from an integral sub_match state_id:
+inline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);
+}
+#ifndef BOOST_NO_WREGEX
+inline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);
+}
+#endif
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
+inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);
+}
+#endif
+template <class charT, class Traits, class Alloc>
+inline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
+ return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, m);
+}
+inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UnicodeString& s, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);
+}
+
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+// construction from a reference to an array:
+template <std::size_t N>
+inline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);
+}
+#ifndef BOOST_NO_WREGEX
+template <std::size_t N>
+inline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);
+}
+#endif
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
+template <std::size_t N>
+inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, m);
+}
+#endif
+template <class charT, class Traits, class Alloc, std::size_t N>
+inline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
+ return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, m);
+}
+template <std::size_t N>
+inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UnicodeString& s, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);
+}
+#endif // BOOST_MSVC < 1300
+
+// construction from a vector of sub_match state_id's:
+inline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);
+}
+#ifndef BOOST_NO_WREGEX
+inline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);
+}
+#endif
+#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
+inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);
+}
+#endif
+template <class charT, class Traits, class Alloc>
+inline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
+ return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, m);
+}
+inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UnicodeString& s, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
+{
+ return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);
+}
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+# pragma warning(pop)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+} // namespace boost
+
+#endif // BOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP
+
+
+
+
diff --git a/ext/boost/regex/v4/w32_regex_traits.hpp b/ext/boost/regex/v4/w32_regex_traits.hpp
new file mode 100644
index 0000000000..d55620726d
--- /dev/null
+++ b/ext/boost/regex/v4/w32_regex_traits.hpp
@@ -0,0 +1,741 @@
+/*
+ *
+ * Copyright (c) 2004
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+ /*
+ * LOCATION: see http://www.boost.org for most recent version.
+ * FILE w32_regex_traits.hpp
+ * VERSION see <boost/version.hpp>
+ * DESCRIPTION: Declares regular expression traits class w32_regex_traits.
+ */
+
+#ifndef BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
+#define BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
+
+#ifndef BOOST_RE_PAT_EXCEPT_HPP
+#include <boost/regex/pattern_except.hpp>
+#endif
+#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
+#include <boost/regex/v4/regex_traits_defaults.hpp>
+#endif
+#ifdef BOOST_HAS_THREADS
+#include <boost/regex/pending/static_mutex.hpp>
+#endif
+#ifndef BOOST_REGEX_PRIMARY_TRANSFORM
+#include <boost/regex/v4/primary_transform.hpp>
+#endif
+#ifndef BOOST_REGEX_OBJECT_CACHE_HPP
+#include <boost/regex/pending/object_cache.hpp>
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4786)
+#pragma warning(disable:4800)
+#endif
+
+namespace boost{
+
+//
+// forward declaration is needed by some compilers:
+//
+template <class charT>
+class w32_regex_traits;
+
+namespace re_detail{
+
+//
+// start by typedeffing the types we'll need:
+//
+typedef ::boost::uint32_t lcid_type; // placeholder for LCID.
+typedef ::boost::shared_ptr<void> cat_type; // placeholder for dll HANDLE.
+
+//
+// then add wrappers around the actual Win32 API's (ie implementation hiding):
+//
+BOOST_REGEX_DECL lcid_type BOOST_REGEX_CALL w32_get_default_locale();
+BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(char, lcid_type);
+#ifndef BOOST_NO_WREGEX
+BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(wchar_t, lcid_type);
+#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
+BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(unsigned short ca, lcid_type state_id);
+#endif
+#endif
+BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(char, lcid_type);
+#ifndef BOOST_NO_WREGEX
+BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(wchar_t, lcid_type);
+#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
+BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(unsigned short ca, lcid_type state_id);
+#endif
+#endif
+BOOST_REGEX_DECL cat_type BOOST_REGEX_CALL w32_cat_open(const std::string& name);
+BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::string& def);
+#ifndef BOOST_NO_WREGEX
+BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::wstring& def);
+#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
+BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type, int i, const std::basic_string<unsigned short>& def);
+#endif
+#endif
+BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type state_id, const char* p1, const char* p2);
+#ifndef BOOST_NO_WREGEX
+BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_transform(lcid_type state_id, const wchar_t* p1, const wchar_t* p2);
+#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
+BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_transform(lcid_type state_id, const unsigned short* p1, const unsigned short* p2);
+#endif
+#endif
+BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_tolower(char c, lcid_type);
+#ifndef BOOST_NO_WREGEX
+BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_tolower(wchar_t c, lcid_type);
+#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
+BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL w32_tolower(unsigned short c, lcid_type state_id);
+#endif
+#endif
+BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_toupper(char c, lcid_type);
+#ifndef BOOST_NO_WREGEX
+BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_toupper(wchar_t c, lcid_type);
+#endif
+BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type, boost::uint32_t mask, char c);
+#ifndef BOOST_NO_WREGEX
+BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type, boost::uint32_t mask, wchar_t c);
+#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
+BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type state_id, boost::uint32_t m, unsigned short c);
+#endif
+#endif
+//
+// class w32_regex_traits_base:
+// acts as a container for locale and the facets we are using.
+//
+template <class charT>
+struct w32_regex_traits_base
+{
+ w32_regex_traits_base(lcid_type l)
+ { imbue(l); }
+ lcid_type imbue(lcid_type l);
+
+ lcid_type m_locale;
+};
+
+template <class charT>
+inline lcid_type w32_regex_traits_base<charT>::imbue(lcid_type l)
+{
+ lcid_type result(m_locale);
+ m_locale = l;
+ return result;
+}
+
+//
+// class w32_regex_traits_char_layer:
+// implements methods that require specialisation for narrow characters:
+//
+template <class charT>
+class w32_regex_traits_char_layer : public w32_regex_traits_base<charT>
+{
+ typedef std::basic_string<charT> string_type;
+ typedef std::map<charT, regex_constants::syntax_type> map_type;
+ typedef typename map_type::const_iterator map_iterator_type;
+public:
+ w32_regex_traits_char_layer(const lcid_type l);
+
+ regex_constants::syntax_type syntax_type(charT c)const
+ {
+ map_iterator_type i = m_char_map.find(c);
+ return ((i == m_char_map.end()) ? 0 : i->second);
+ }
+ regex_constants::escape_syntax_type escape_syntax_type(charT c) const
+ {
+ map_iterator_type i = m_char_map.find(c);
+ if(i == m_char_map.end())
+ {
+ if(::boost::re_detail::w32_is_lower(c, this->m_locale)) return regex_constants::escape_type_class;
+ if(::boost::re_detail::w32_is_upper(c, this->m_locale)) return regex_constants::escape_type_not_class;
+ return 0;
+ }
+ return i->second;
+ }
+ charT tolower(charT c)const
+ {
+ return ::boost::re_detail::w32_tolower(c, this->m_locale);
+ }
+ bool isctype(boost::uint32_t mask, charT c)const
+ {
+ return ::boost::re_detail::w32_is(this->m_locale, mask, c);
+ }
+
+private:
+ string_type get_default_message(regex_constants::syntax_type);
+ // TODO: use a hash table when available!
+ map_type m_char_map;
+};
+
+template <class charT>
+w32_regex_traits_char_layer<charT>::w32_regex_traits_char_layer(::boost::re_detail::lcid_type l)
+ : w32_regex_traits_base<charT>(l)
+{
+ // we need to start by initialising our syntax map so we know which
+ // character is used for which purpose:
+ cat_type cat;
+ std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
+ if(cat_name.size())
+ {
+ cat = ::boost::re_detail::w32_cat_open(cat_name);
+ if(!cat)
+ {
+ std::string m("Unable to open message catalog: ");
+ std::runtime_error err(m + cat_name);
+ boost::re_detail::raise_runtime_error(err);
+ }
+ }
+ //
+ // if we have a valid catalog then load our messages:
+ //
+ if(cat)
+ {
+ for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
+ {
+ string_type mss = ::boost::re_detail::w32_cat_get(cat, this->m_locale, i, get_default_message(i));
+ for(typename string_type::size_type j = 0; j < mss.size(); ++j)
+ {
+ this->m_char_map[mss[j]] = i;
+ }
+ }
+ }
+ else
+ {
+ for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
+ {
+ const char* ptr = get_default_syntax(i);
+ while(ptr && *ptr)
+ {
+ this->m_char_map[static_cast<charT>(*ptr)] = i;
+ ++ptr;
+ }
+ }
+ }
+}
+
+template <class charT>
+typename w32_regex_traits_char_layer<charT>::string_type
+ w32_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
+{
+ const char* ptr = get_default_syntax(i);
+ string_type result;
+ while(ptr && *ptr)
+ {
+ result.append(1, static_cast<charT>(*ptr));
+ ++ptr;
+ }
+ return result;
+}
+
+//
+// specialised version for narrow characters:
+//
+template <>
+class BOOST_REGEX_DECL w32_regex_traits_char_layer<char> : public w32_regex_traits_base<char>
+{
+ typedef std::string string_type;
+public:
+ w32_regex_traits_char_layer(::boost::re_detail::lcid_type l)
+ : w32_regex_traits_base<char>(l)
+ {
+ init();
+ }
+
+ regex_constants::syntax_type syntax_type(char c)const
+ {
+ return m_char_map[static_cast<unsigned char>(c)];
+ }
+ regex_constants::escape_syntax_type escape_syntax_type(char c) const
+ {
+ return m_char_map[static_cast<unsigned char>(c)];
+ }
+ char tolower(char c)const
+ {
+ return m_lower_map[static_cast<unsigned char>(c)];
+ }
+ bool isctype(boost::uint32_t mask, char c)const
+ {
+ return m_type_map[static_cast<unsigned char>(c)] & mask;
+ }
+
+private:
+ regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
+ char m_lower_map[1u << CHAR_BIT];
+ boost::uint16_t m_type_map[1u << CHAR_BIT];
+ void init();
+};
+
+//
+// class w32_regex_traits_implementation:
+// provides pimpl implementation for w32_regex_traits.
+//
+template <class charT>
+class w32_regex_traits_implementation : public w32_regex_traits_char_layer<charT>
+{
+public:
+ typedef typename w32_regex_traits<charT>::char_class_type char_class_type;
+ BOOST_STATIC_CONSTANT(char_class_type, mask_word = 0x0400); // must be C1_DEFINED << 1
+ BOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 0x0800); // must be C1_DEFINED << 2
+ BOOST_STATIC_CONSTANT(char_class_type, mask_horizontal = 0x1000); // must be C1_DEFINED << 3
+ BOOST_STATIC_CONSTANT(char_class_type, mask_vertical = 0x2000); // must be C1_DEFINED << 4
+ BOOST_STATIC_CONSTANT(char_class_type, mask_base = 0x3ff); // all the masks used by the CT_CTYPE1 group
+
+ typedef std::basic_string<charT> string_type;
+ typedef charT char_type;
+ w32_regex_traits_implementation(::boost::re_detail::lcid_type l);
+ std::string error_string(regex_constants::error_type n) const
+ {
+ if(!m_error_strings.empty())
+ {
+ std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
+ return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
+ }
+ return get_default_error_string(n);
+ }
+ char_class_type lookup_classname(const charT* p1, const charT* p2) const
+ {
+ char_class_type result = lookup_classname_imp(p1, p2);
+ if(result == 0)
+ {
+ typedef typename string_type::size_type size_type;
+ string_type temp(p1, p2);
+ for(size_type i = 0; i < temp.size(); ++i)
+ temp[i] = this->tolower(temp[i]);
+ result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
+ }
+ return result;
+ }
+ string_type lookup_collatename(const charT* p1, const charT* p2) const;
+ string_type transform_primary(const charT* p1, const charT* p2) const;
+ string_type transform(const charT* p1, const charT* p2) const
+ {
+ return ::boost::re_detail::w32_transform(this->m_locale, p1, p2);
+ }
+private:
+ std::map<int, std::string> m_error_strings; // error messages indexed by numberic ID
+ std::map<string_type, char_class_type> m_custom_class_names; // character class names
+ std::map<string_type, string_type> m_custom_collate_names; // collating element names
+ unsigned m_collate_type; // the form of the collation string
+ charT m_collate_delim; // the collation group delimiter
+ //
+ // helpers:
+ //
+ char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
+};
+
+template <class charT>
+typename w32_regex_traits_implementation<charT>::string_type
+ w32_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
+{
+ string_type result;
+ //
+ // What we do here depends upon the format of the sort key returned by
+ // sort key returned by this->transform:
+ //
+ switch(m_collate_type)
+ {
+ case sort_C:
+ case sort_unknown:
+ // the best we can do is translate to lower case, then get a regular sort key:
+ {
+ result.assign(p1, p2);
+ typedef typename string_type::size_type size_type;
+ for(size_type i = 0; i < result.size(); ++i)
+ result[i] = this->tolower(result[i]);
+ result = this->transform(&*result.begin(), &*result.begin() + result.size());
+ break;
+ }
+ case sort_fixed:
+ {
+ // get a regular sort key, and then truncate it:
+ result.assign(this->transform(p1, p2));
+ result.erase(this->m_collate_delim);
+ break;
+ }
+ case sort_delim:
+ // get a regular sort key, and then truncate everything after the delim:
+ result.assign(this->transform(p1, p2));
+ std::size_t i;
+ for(i = 0; i < result.size(); ++i)
+ {
+ if(result[i] == m_collate_delim)
+ break;
+ }
+ result.erase(i);
+ break;
+ }
+ if(result.empty())
+ result = string_type(1, charT(0));
+ return result;
+}
+
+template <class charT>
+typename w32_regex_traits_implementation<charT>::string_type
+ w32_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
+{
+ typedef typename std::map<string_type, string_type>::const_iterator iter_type;
+ if(m_custom_collate_names.size())
+ {
+ iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
+ if(pos != m_custom_collate_names.end())
+ return pos->second;
+ }
+#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
+ && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)\
+ && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
+ std::string name(p1, p2);
+#else
+ std::string name;
+ const charT* p0 = p1;
+ while(p0 != p2)
+ name.append(1, char(*p0++));
+#endif
+ name = lookup_default_collate_name(name);
+#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
+ && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)\
+ && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
+ if(name.size())
+ return string_type(name.begin(), name.end());
+#else
+ if(name.size())
+ {
+ string_type result;
+ typedef std::string::const_iterator iter;
+ iter b = name.begin();
+ iter e = name.end();
+ while(b != e)
+ result.append(1, charT(*b++));
+ return result;
+ }
+#endif
+ if(p2 - p1 == 1)
+ return string_type(1, *p1);
+ return string_type();
+}
+
+template <class charT>
+w32_regex_traits_implementation<charT>::w32_regex_traits_implementation(::boost::re_detail::lcid_type l)
+: w32_regex_traits_char_layer<charT>(l)
+{
+ cat_type cat;
+ std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
+ if(cat_name.size())
+ {
+ cat = ::boost::re_detail::w32_cat_open(cat_name);
+ if(!cat)
+ {
+ std::string m("Unable to open message catalog: ");
+ std::runtime_error err(m + cat_name);
+ boost::re_detail::raise_runtime_error(err);
+ }
+ }
+ //
+ // if we have a valid catalog then load our messages:
+ //
+ if(cat)
+ {
+ //
+ // Error messages:
+ //
+ for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0);
+ i <= boost::regex_constants::error_unknown;
+ i = static_cast<boost::regex_constants::error_type>(i + 1))
+ {
+ const char* p = get_default_error_string(i);
+ string_type default_message;
+ while(*p)
+ {
+ default_message.append(1, static_cast<charT>(*p));
+ ++p;
+ }
+ string_type s = ::boost::re_detail::w32_cat_get(cat, this->m_locale, i+200, default_message);
+ std::string result;
+ for(std::string::size_type j = 0; j < s.size(); ++j)
+ {
+ result.append(1, static_cast<char>(s[j]));
+ }
+ m_error_strings[i] = result;
+ }
+ //
+ // Custom class names:
+ //
+ static const char_class_type masks[14] =
+ {
+ 0x0104u, // C1_ALPHA | C1_DIGIT
+ 0x0100u, // C1_ALPHA
+ 0x0020u, // C1_CNTRL
+ 0x0004u, // C1_DIGIT
+ (~(0x0020u|0x0008u) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE
+ 0x0002u, // C1_LOWER
+ (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL
+ 0x0010u, // C1_PUNCT
+ 0x0008u, // C1_SPACE
+ 0x0001u, // C1_UPPER
+ 0x0080u, // C1_XDIGIT
+ 0x0040u, // C1_BLANK
+ w32_regex_traits_implementation<charT>::mask_word,
+ w32_regex_traits_implementation<charT>::mask_unicode,
+ };
+ static const string_type null_string;
+ for(unsigned int j = 0; j <= 13; ++j)
+ {
+ string_type s(::boost::re_detail::w32_cat_get(cat, this->m_locale, j+300, null_string));
+ if(s.size())
+ this->m_custom_class_names[s] = masks[j];
+ }
+ }
+ //
+ // get the collation format used by m_pcollate:
+ //
+ m_collate_type = re_detail::find_sort_syntax(this, &m_collate_delim);
+}
+
+template <class charT>
+typename w32_regex_traits_implementation<charT>::char_class_type
+ w32_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
+{
+ static const char_class_type masks[22] =
+ {
+ 0,
+ 0x0104u, // C1_ALPHA | C1_DIGIT
+ 0x0100u, // C1_ALPHA
+ 0x0040u, // C1_BLANK
+ 0x0020u, // C1_CNTRL
+ 0x0004u, // C1_DIGIT
+ 0x0004u, // C1_DIGIT
+ (~(0x0020u|0x0008u|0x0040) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE or C1_BLANK
+ w32_regex_traits_implementation<charT>::mask_horizontal,
+ 0x0002u, // C1_LOWER
+ 0x0002u, // C1_LOWER
+ (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL
+ 0x0010u, // C1_PUNCT
+ 0x0008u, // C1_SPACE
+ 0x0008u, // C1_SPACE
+ 0x0001u, // C1_UPPER
+ w32_regex_traits_implementation<charT>::mask_unicode,
+ 0x0001u, // C1_UPPER
+ w32_regex_traits_implementation<charT>::mask_vertical,
+ 0x0104u | w32_regex_traits_implementation<charT>::mask_word,
+ 0x0104u | w32_regex_traits_implementation<charT>::mask_word,
+ 0x0080u, // C1_XDIGIT
+ };
+ if(m_custom_class_names.size())
+ {
+ typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
+ map_iter pos = m_custom_class_names.find(string_type(p1, p2));
+ if(pos != m_custom_class_names.end())
+ return pos->second;
+ }
+ std::size_t state_id = 1 + re_detail::get_default_class_id(p1, p2);
+ if(state_id < sizeof(masks) / sizeof(masks[0]))
+ return masks[state_id];
+ return masks[0];
+}
+
+
+template <class charT>
+boost::shared_ptr<const w32_regex_traits_implementation<charT> > create_w32_regex_traits(::boost::re_detail::lcid_type l BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(charT))
+{
+ // TODO: create a cache for previously constructed objects.
+ return boost::object_cache< ::boost::re_detail::lcid_type, w32_regex_traits_implementation<charT> >::get(l, 5);
+}
+
+} // re_detail
+
+template <class charT>
+class w32_regex_traits
+{
+public:
+ typedef charT char_type;
+ typedef std::size_t size_type;
+ typedef std::basic_string<char_type> string_type;
+ typedef ::boost::re_detail::lcid_type locale_type;
+ typedef boost::uint_least32_t char_class_type;
+
+ struct boost_extensions_tag{};
+
+ w32_regex_traits()
+ : m_pimpl(re_detail::create_w32_regex_traits<charT>(::boost::re_detail::w32_get_default_locale()))
+ { }
+ static size_type length(const char_type* p)
+ {
+ return std::char_traits<charT>::length(p);
+ }
+ regex_constants::syntax_type syntax_type(charT c)const
+ {
+ return m_pimpl->syntax_type(c);
+ }
+ regex_constants::escape_syntax_type escape_syntax_type(charT c) const
+ {
+ return m_pimpl->escape_syntax_type(c);
+ }
+ charT translate(charT c) const
+ {
+ return c;
+ }
+ charT translate_nocase(charT c) const
+ {
+ return this->m_pimpl->tolower(c);
+ }
+ charT translate(charT c, bool icase) const
+ {
+ return icase ? this->m_pimpl->tolower(c) : c;
+ }
+ charT tolower(charT c) const
+ {
+ return this->m_pimpl->tolower(c);
+ }
+ charT toupper(charT c) const
+ {
+ return ::boost::re_detail::w32_toupper(c, this->m_pimpl->m_locale);
+ }
+ string_type transform(const charT* p1, const charT* p2) const
+ {
+ return ::boost::re_detail::w32_transform(this->m_pimpl->m_locale, p1, p2);
+ }
+ string_type transform_primary(const charT* p1, const charT* p2) const
+ {
+ return m_pimpl->transform_primary(p1, p2);
+ }
+ char_class_type lookup_classname(const charT* p1, const charT* p2) const
+ {
+ return m_pimpl->lookup_classname(p1, p2);
+ }
+ string_type lookup_collatename(const charT* p1, const charT* p2) const
+ {
+ return m_pimpl->lookup_collatename(p1, p2);
+ }
+ bool isctype(charT c, char_class_type f) const
+ {
+ if((f & re_detail::w32_regex_traits_implementation<charT>::mask_base)
+ && (this->m_pimpl->isctype(f & re_detail::w32_regex_traits_implementation<charT>::mask_base, c)))
+ return true;
+ else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_unicode) && re_detail::is_extended(c))
+ return true;
+ else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_word) && (c == '_'))
+ return true;
+ else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_vertical)
+ && (::boost::re_detail::is_separator(c) || (c == '\v')))
+ return true;
+ else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_horizontal)
+ && this->isctype(c, 0x0008u) && !this->isctype(c, re_detail::w32_regex_traits_implementation<charT>::mask_vertical))
+ return true;
+ return false;
+ }
+ int toi(const charT*& p1, const charT* p2, int radix)const
+ {
+ return ::boost::re_detail::global_toi(p1, p2, radix, *this);
+ }
+ int value(charT c, int radix)const
+ {
+ int result = ::boost::re_detail::global_value(c);
+ return result < radix ? result : -1;
+ }
+ locale_type imbue(locale_type l)
+ {
+ ::boost::re_detail::lcid_type result(getloc());
+ m_pimpl = re_detail::create_w32_regex_traits<charT>(l);
+ return result;
+ }
+ locale_type getloc()const
+ {
+ return m_pimpl->m_locale;
+ }
+ std::string error_string(regex_constants::error_type n) const
+ {
+ return m_pimpl->error_string(n);
+ }
+
+ //
+ // extension:
+ // set the name of the message catalog in use (defaults to "boost_regex").
+ //
+ static std::string catalog_name(const std::string& name);
+ static std::string get_catalog_name();
+
+private:
+ boost::shared_ptr<const re_detail::w32_regex_traits_implementation<charT> > m_pimpl;
+ //
+ // catalog name handler:
+ //
+ static std::string& get_catalog_name_inst();
+
+#ifdef BOOST_HAS_THREADS
+ static static_mutex& get_mutex_inst();
+#endif
+};
+
+template <class charT>
+std::string w32_regex_traits<charT>::catalog_name(const std::string& name)
+{
+#ifdef BOOST_HAS_THREADS
+ static_mutex::scoped_lock lk(get_mutex_inst());
+#endif
+ std::string result(get_catalog_name_inst());
+ get_catalog_name_inst() = name;
+ return result;
+}
+
+template <class charT>
+std::string& w32_regex_traits<charT>::get_catalog_name_inst()
+{
+ static std::string s_name;
+ return s_name;
+}
+
+template <class charT>
+std::string w32_regex_traits<charT>::get_catalog_name()
+{
+#ifdef BOOST_HAS_THREADS
+ static_mutex::scoped_lock lk(get_mutex_inst());
+#endif
+ std::string result(get_catalog_name_inst());
+ return result;
+}
+
+#ifdef BOOST_HAS_THREADS
+template <class charT>
+static_mutex& w32_regex_traits<charT>::get_mutex_inst()
+{
+ static static_mutex s_mutex = BOOST_STATIC_MUTEX_INIT;
+ return s_mutex;
+}
+#endif
+
+
+} // boost
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4103)
+#endif
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif