From 6b84814f3ca69a445c83a9cb8e673f50d7a0d7b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Gullik=20Bj=C3=B8nnes?= Date: Sat, 21 Oct 2006 14:52:25 +0000 Subject: [PATCH] Update to latest boost 1.34 svn. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@15451 a592a061-630c-0410-9148-cb99ea01b6c8 --- boost/boost/rational.hpp | 19 +++++- boost/boost/regex/v4/perl_matcher.hpp | 4 +- boost/boost/regex/v4/perl_matcher_common.hpp | 68 +++++++++++++++++--- 3 files changed, 80 insertions(+), 11 deletions(-) diff --git a/boost/boost/rational.hpp b/boost/boost/rational.hpp index c53bc41859..5986a62997 100644 --- a/boost/boost/rational.hpp +++ b/boost/boost/rational.hpp @@ -17,6 +17,9 @@ // Nickolay Mladenov, for the implementation of operator+= // Revision History +// 20 Oct 06 Fix operator bool_type for CW 8.3 (Joaquín M López Muñoz) +// 18 Oct 06 Use EXPLICIT_TEMPLATE_TYPE helper macros from Boost.Config +// (Joaquín M López Muñoz) // 27 Dec 05 Add Boolean conversion operator (Daryle Walker) // 28 Sep 02 Use _left versions of operators from operators.hpp // 05 Jul 01 Recode gcd(), avoiding std::swap (Helmut Zeisel) @@ -48,6 +51,7 @@ #include // for std::abs #include // for boost::call_traits #include // for BOOST_NO_STDC_NAMESPACE, BOOST_MSVC +#include // for BOOST_WORKAROUND namespace boost { @@ -171,8 +175,20 @@ public: bool operator!() const { return !num; } // Boolean conversion + +#if BOOST_WORKAROUND(__MWERKS__,<=0x3003) + // The "ISO C++ Template Parser" option in CW 8.3 chokes on the + // following, hence we selectively disable that option for the + // offending memfun. +#pragma parse_mfunc_templ off +#endif + operator bool_type() const { return operator !() ? 0 : &helper::parts; } +#if BOOST_WORKAROUND(__MWERKS__,<=0x3003) +#pragma parse_mfunc_templ reset +#endif + // Comparison operators bool operator< (const rational& r) const; bool operator== (const rational& r) const; @@ -508,7 +524,8 @@ std::ostream& operator<< (std::ostream& os, const rational& r) // Type conversion template -inline T rational_cast(const rational& src) +inline T rational_cast( + const rational& src BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) { return static_cast(src.numerator())/src.denominator(); } diff --git a/boost/boost/regex/v4/perl_matcher.hpp b/boost/boost/regex/v4/perl_matcher.hpp index d68943cd10..73a046c6b8 100644 --- a/boost/boost/regex/v4/perl_matcher.hpp +++ b/boost/boost/regex/v4/perl_matcher.hpp @@ -427,9 +427,9 @@ private: // matching flags in use: match_flag_type m_match_flags; // how many states we have examined so far: - difference_type state_count; + boost::uintmax_t state_count; // max number of states to examine before giving up: - difference_type max_state_count; + 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: diff --git a/boost/boost/regex/v4/perl_matcher_common.hpp b/boost/boost/regex/v4/perl_matcher_common.hpp index d43422b0c6..1c222b87dd 100644 --- a/boost/boost/regex/v4/perl_matcher_common.hpp +++ b/boost/boost/regex/v4/perl_matcher_common.hpp @@ -77,15 +77,67 @@ void perl_matcher::construct_init(const basic_r template void perl_matcher::estimate_max_state_count(std::random_access_iterator_tag*) { - static const difference_type k = 100000; - difference_type dist = boost::re_detail::distance(base, last); - traits_size_type states = static_cast(re.size()); + // + // 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; - difference_type lim = ((std::numeric_limits::max)() - k) / states; - if(dist >= lim) - max_state_count = (std::numeric_limits::max)(); - else - max_state_count = k + states * dist; + if((std::numeric_limits::max)() / dist < states) + { + max_state_count = (std::numeric_limits::max)() - 2; + return; + } + states *= dist; + if((std::numeric_limits::max)() - k < states) + { + max_state_count = (std::numeric_limits::max)() - 2; + return; + } + states += k; + + max_state_count = states; + + // + // Now calculate N^2: + // + states = dist; + if((std::numeric_limits::max)() / dist < states) + { + max_state_count = (std::numeric_limits::max)() - 2; + return; + } + states *= dist; + if((std::numeric_limits::max)() - k < states) + { + max_state_count = (std::numeric_limits::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