Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r67701 - in trunk/boost/chrono: . detail
From: vicente.botet_at_[hidden]
Date: 2011-01-05 19:51:46


Author: viboes
Date: 2011-01-05 19:51:44 EST (Wed, 05 Jan 2011)
New Revision: 67701
URL: http://svn.boost.org/trac/boost/changeset/67701

Log:
Boost.Chrono: Moved to trunk IO + cleanup
Added:
   trunk/boost/chrono/detail/scan_keyword.hpp (contents, props changed)
Text files modified:
   trunk/boost/chrono/chrono_io.hpp | 8 +++++---
   trunk/boost/chrono/config.hpp | 5 -----
   2 files changed, 5 insertions(+), 8 deletions(-)

Modified: trunk/boost/chrono/chrono_io.hpp
==============================================================================
--- trunk/boost/chrono/chrono_io.hpp (original)
+++ trunk/boost/chrono/chrono_io.hpp 2011-01-05 19:51:44 EST (Wed, 05 Jan 2011)
@@ -13,6 +13,8 @@
 #ifndef BOOST_CHRONO_CHRONO_IO_HPP
 #define BOOST_CHRONO_CHRONO_IO_HPP
 
+#define BOOST_CHRONO_IO_INPUT
+
 #include <boost/chrono/chrono.hpp>
 #include <boost/ratio/ratio_io.hpp>
 #include <locale>
@@ -263,7 +265,7 @@
                     std::ios_base::iostate err = std::ios_base::goodbit;
                     const std::basic_string<CharT>* k = chrono_detail::scan_keyword(i, e,
                                   units, units + sizeof(units)/sizeof(units[0]),
- std::use_facet<std::ctype<CharT> >(loc),
+ //~ std::use_facet<std::ctype<CharT> >(loc),
                                   err);
                     switch ((k - units) / 2)
                     {
@@ -321,7 +323,7 @@
                     std::ios_base::iostate err = std::ios_base::goodbit;
                     const std::basic_string<CharT>* k = chrono_detail::scan_keyword(i, e,
                                   units, units + sizeof(units)/sizeof(units[0]),
- std::use_facet<std::ctype<CharT> >(loc),
+ //~ std::use_facet<std::ctype<CharT> >(loc),
                                   err);
                     switch ((k - units) / 2)
                     {
@@ -636,7 +638,7 @@
         in_iterator e;
         std::ptrdiff_t k = chrono_detail::scan_keyword(i, e,
                       &units, &units + 1,
- std::use_facet<std::ctype<CharT> >(is.getloc()),
+ //~ std::use_facet<std::ctype<CharT> >(is.getloc()),
                       err) - &units;
         if (k == 1)
         {

Modified: trunk/boost/chrono/config.hpp
==============================================================================
--- trunk/boost/chrono/config.hpp (original)
+++ trunk/boost/chrono/config.hpp 2011-01-05 19:51:44 EST (Wed, 05 Jan 2011)
@@ -13,11 +13,6 @@
 
 #include <boost/config.hpp>
 
-
-#if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))
-#undef BOOST_NO_CONSTEXPR
-#endif
-
 // BOOST_CHRONO_POSIX_API, BOOST_CHRONO_MAC_API, or BOOST_CHRONO_WINDOWS_API
 // can be defined by the user to specify which API should be used
 

Added: trunk/boost/chrono/detail/scan_keyword.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/chrono/detail/scan_keyword.hpp 2011-01-05 19:51:44 EST (Wed, 05 Jan 2011)
@@ -0,0 +1,182 @@
+// scan_keyword.hpp --------------------------------------------------------------//
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Adaptation to Boost of the libcxx
+
+// Copyright 2010 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_CHRONO_DETAIL_SCAN_KEYWORD_HPP
+#define BOOST_CHRONO_DETAIL_SCAN_KEYWORD_HPP
+
+#include <boost/chrono/config.hpp>
+
+//#define BOOST_CORONO_IO_USES_LEX
+
+#ifdef BOOST_CORONO_IO_USES_LEX
+#else
+#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
+#include <ios>
+#include <exception>
+
+namespace boost {
+ using interprocess::unique_ptr;
+#endif
+namespace chrono {
+namespace chrono_detail {
+
+#ifdef BOOST_CORONO_IO_USES_LEX
+
+template <class Lexer>
+struct keywords : lex::lexer<Lexer>
+{
+ template <class ForwardIterator>
+ keywords(ForwardIterator kb, ForwardIterator ke)
+ {
+ // define tokens (the keyword to match and the corresponding index
+ // and add them to the lexer
+ for (int indx=0, ForwardIterator it=kb; it!=ke; ++it, ++i)
+ {
+ this->self.add(*it, i);
+ }
+ }
+};
+#endif
+// scan_keyword
+// Scans [b, e) until a match is found in the basic_strings range
+// [kb, ke) or until it can be shown that there is no match in [kb, ke).
+// b will be incremented (visibly), consuming CharT until a match is found
+// or proved to not exist. A keyword may be "", in which will match anything.
+// If one keyword is a prefix of another, and the next CharT in the input
+// might match another keyword, the algorithm will attempt to find the longest
+// matching keyword. If the longer matching keyword ends up not matching, then
+// no keyword match is found. If no keyword match is found, ke is returned
+// and failbit is set in err.
+// Else an iterator pointing to the matching keyword is found. If more than
+// one keyword matches, an iterator to the first matching keyword is returned.
+// If on exit b == e, eofbit is set in err.
+// Examples:
+// Keywords: "a", "abb"
+// If the input is "a", the first keyword matches and eofbit is set.
+// If the input is "abc", no match is found and "ab" are consumed.
+
+template <class InputIterator, class ForwardIterator>
+ForwardIterator
+scan_keyword(InputIterator& b, InputIterator e,
+ ForwardIterator kb, ForwardIterator ke,
+ std::ios_base::iostate& err
+ )
+{
+ typedef typename std::iterator_traits<InputIterator>::value_type CharT;
+#ifdef BOOST_CORONO_IO_USES_LEX
+
+#else
+ size_t nkw = std::distance(kb, ke);
+ const unsigned char doesnt_match = '\0';
+ const unsigned char might_match = '\1';
+ const unsigned char does_match = '\2';
+ unsigned char statbuf[100];
+ unsigned char* status = statbuf;
+ unique_ptr<unsigned char, void(*)(void*)> stat_hold(0, free);
+ if (nkw > sizeof(statbuf))
+ {
+ status = (unsigned char*)malloc(nkw);
+ if (status == 0)
+ throw std::bad_alloc();
+ stat_hold.reset(status);
+ }
+ size_t n_might_match = nkw; // At this point, any keyword might match
+ size_t n_does_match = 0; // but none of them definitely do
+ // Initialize all statuses to might_match, except for "" keywords are does_match
+ unsigned char* st = status;
+ for (ForwardIterator ky = kb; ky != ke; ++ky, ++st)
+ {
+ if (!ky->empty())
+ *st = might_match;
+ else
+ {
+ *st = does_match;
+ --n_might_match;
+ ++n_does_match;
+ }
+ }
+ // While there might be a match, test keywords against the next CharT
+ for (size_t indx = 0; b != e && n_might_match > 0; ++indx)
+ {
+ // Peek at the next CharT but don't consume it
+ CharT c = *b;
+ bool consume = false;
+ // For each keyword which might match, see if the indx character is c
+ // If a match if found, consume c
+ // If a match is found, and that is the last character in the keyword,
+ // then that keyword matches.
+ // If the keyword doesn't match this character, then change the keyword
+ // to doesn't match
+ st = status;
+ for (ForwardIterator ky = kb; ky != ke; ++ky, ++st)
+ {
+ if (*st == might_match)
+ {
+ CharT kc = (*ky)[indx];
+ if (c == kc)
+ {
+ consume = true;
+ if (ky->size() == indx+1)
+ {
+ *st = does_match;
+ --n_might_match;
+ ++n_does_match;
+ }
+ }
+ else
+ {
+ *st = doesnt_match;
+ --n_might_match;
+ }
+ }
+ }
+ // consume if we matched a character
+ if (consume)
+ {
+ ++b;
+ // If we consumed a character and there might be a matched keyword that
+ // was marked matched on a previous iteration, then such keywords
+ // which are now marked as not matching.
+ if (n_might_match + n_does_match > 1)
+ {
+ st = status;
+ for (ForwardIterator ky = kb; ky != ke; ++ky, ++st)
+ {
+ if (*st == does_match && ky->size() != indx+1)
+ {
+ *st = doesnt_match;
+ --n_does_match;
+ }
+ }
+ }
+ }
+ }
+ // We've exited the loop because we hit eof and/or we have no more "might matches".
+ if (b == e)
+ err |= std::ios_base::eofbit;
+ // Return the first matching result
+ for (st = status; kb != ke; ++kb, ++st)
+ if (*st == does_match)
+ break;
+ if (kb == ke)
+ err |= std::ios_base::failbit;
+ return kb;
+#endif
+}
+}
+}
+}
+#endif // BOOST_CHRONO_DETAIL_SCAN_KEYWORD_HPP


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk