File indexing completed on 2025-12-15 09:44:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef BOOST_CHRONO_DETAIL_SCAN_KEYWORD_HPP
0018 #define BOOST_CHRONO_DETAIL_SCAN_KEYWORD_HPP
0019
0020 #include <boost/chrono/config.hpp>
0021
0022 #include <boost/move/unique_ptr.hpp>
0023 #include <ios>
0024 #include <exception>
0025 #include <stdlib.h>
0026 #include <boost/throw_exception.hpp>
0027
0028 namespace boost {
0029 using movelib::unique_ptr;
0030
0031 namespace chrono {
0032 namespace chrono_detail {
0033
0034 inline void free_aux(void* ptr) { free(ptr); }
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 template <class InputIterator, class ForwardIterator>
0055 ForwardIterator
0056 scan_keyword(InputIterator& b, InputIterator e,
0057 ForwardIterator kb, ForwardIterator ke,
0058 std::ios_base::iostate& err
0059 )
0060 {
0061 typedef typename std::iterator_traits<InputIterator>::value_type CharT;
0062 size_t nkw = std::distance(kb, ke);
0063 const unsigned char doesnt_match = '\0';
0064 const unsigned char might_match = '\1';
0065 const unsigned char does_match = '\2';
0066 unsigned char statbuf[100];
0067 unsigned char* status = statbuf;
0068
0069
0070 unique_ptr<unsigned char, void(*)(void*)> stat_hold(BOOST_NULLPTR, free_aux);
0071 if (nkw > sizeof(statbuf))
0072 {
0073 status = (unsigned char*)malloc(nkw);
0074 if (status == BOOST_NULLPTR)
0075 {
0076 throw_exception(std::bad_alloc());
0077 }
0078 stat_hold.reset(status);
0079 }
0080 size_t n_might_match = nkw;
0081 size_t n_does_match = 0;
0082
0083 unsigned char* st = status;
0084 for (ForwardIterator ky = kb; ky != ke; ++ky, ++st)
0085 {
0086 if (!ky->empty())
0087 *st = might_match;
0088 else
0089 {
0090 *st = does_match;
0091 --n_might_match;
0092 ++n_does_match;
0093 }
0094 }
0095
0096 for (size_t indx = 0; b != e && n_might_match > 0; ++indx)
0097 {
0098
0099 CharT c = *b;
0100 bool consume = false;
0101
0102
0103
0104
0105
0106
0107 st = status;
0108 for (ForwardIterator ky = kb; ky != ke; ++ky, ++st)
0109 {
0110 if (*st == might_match)
0111 {
0112 CharT kc = (*ky)[indx];
0113 if (c == kc)
0114 {
0115 consume = true;
0116 if (ky->size() == indx+1)
0117 {
0118 *st = does_match;
0119 --n_might_match;
0120 ++n_does_match;
0121 }
0122 }
0123 else
0124 {
0125 *st = doesnt_match;
0126 --n_might_match;
0127 }
0128 }
0129 }
0130
0131 if (consume)
0132 {
0133 ++b;
0134
0135
0136
0137 if (n_might_match + n_does_match > 1)
0138 {
0139 st = status;
0140 for (ForwardIterator ky = kb; ky != ke; ++ky, ++st)
0141 {
0142 if (*st == does_match && ky->size() != indx+1)
0143 {
0144 *st = doesnt_match;
0145 --n_does_match;
0146 }
0147 }
0148 }
0149 }
0150 }
0151
0152 if (b == e)
0153 err |= std::ios_base::eofbit;
0154
0155 for (st = status; kb != ke; ++kb, ++st)
0156 if (*st == does_match)
0157 break;
0158 if (kb == ke)
0159 err |= std::ios_base::failbit;
0160 return kb;
0161 }
0162 }
0163 }
0164 }
0165 #endif