tstring::size_type tstring::find_first_of(char_type c, size_type pos) const { if( tstring::size() > 0 ) { TINFRA_ASSERT(pos == npos || pos <= this->size() ); for( const_iterator i = begin()+pos; i != end(); ++i ) { if( *i == c ) // '== C' so return return i - begin(); } } return npos; }
// find first of tstring::size_type tstring::find_first_of(char_type const* s, size_type pos, size_type n) const { if( tstring::size() > 0 ) { TINFRA_ASSERT(pos == npos || pos <= this->size() ); for( const_iterator i = begin()+pos; i != end(); ++i ) { if( std::memchr(s, *i, n) != 0 ) // 'not in S' so return return i - begin(); } } return npos; }
tstring::size_type tstring::find(char_type const* s, size_type pos, size_type n) const { if( size() == 0 ) { if( n == 0 ) return 0; else return npos; } TINFRA_ASSERT(pos == npos || pos <= this->size() ); tstring const other = tstring(s, n, false); const_iterator result = std::search( begin()+pos, end(), other.begin(), other.end()); if( result == end() ) return npos; else return result - begin(); }
tstring::size_type tstring_find_last(tstring const& subject, Predicate p, size_t pos) { const size_t npos = tstring::npos; if( subject.size() == 0 ) return npos; if( pos != npos && pos > subject.size() ) pos = subject.size()-1; TINFRA_ASSERT(pos == npos || pos < subject.size() ); const tstring::const_iterator begin = subject.begin(); tstring::const_iterator i = (pos == npos) ? subject.end()-1 : subject.begin() + pos; do { if( p(*i) ) // predicate true, then found return i - begin; } while( i-- != begin ); return npos; }
bool vtpath_visitor::fetch_next(variant*& r) { while( self->result_queue.empty() ) { if( self->states.empty() ) return false; vtpath_parse_state& top = self->top(); if( top.matching_finished ) { TINFRA_TRACE(vtpath_exec_tracer, "vpath_visit: matching finished in " << top.current); self->states.pop(); continue; } bool recursive = false; if( top.icommand->type == CHILD ) { // nothing } else if( top.icommand->type == RECURSIVE_CHILD ) { recursive = true; } else { TINFRA_TRACE(vtpath_exec_tracer, "vpath_visit: state bad " << top.icommand->type << " popping state"); self->states.pop(); continue; } TINFRA_TRACE(vtpath_exec_tracer, "vpath_visit: node: " << (*top.current) << "(" <<top.current << ") " << *(top.icommand) << " index=" << top.index << " recursive=" << (int)recursive); // we still need at least one command TINFRA_ASSERT(top.icommand != self->commands.end()-1); vtpath_command const& child_match = *(top.icommand+1); TINFRA_TRACE(vtpath_exec_tracer, "vpath_visit: node: next_command= " << *(top.icommand+1)); std::vector<vtpath_command>::iterator inext_command = (top.icommand+2); if( top.current->is_dict()) { variant::dict_type& dict = top.current->get_dict(); if( child_match.type == WILDCARD_ALL || recursive) { // CURRENT.*, or recursive // in wildcard we MATCH all // in recursive we recurse to all if( top.idict != dict.end() ) { variant::dict_type::iterator idict = top.idict; ++top.idict; ++top.index; variant& match = idict->second; TINFRA_TRACE(vtpath_exec_tracer, "vpath_visit: trying: " << top.index-1 << ": " << idict->first << " -> " << match); if( child_match.type == WILDCARD_ALL ) { // CURRENT.*, matches everything self->match_found(&match, inext_command); } else if( child_match.type == TOKEN ) { // CURRENT.TOKEN if( child_match.expr.is_string() ) { // CURRENT.TOKEN(string) // -> check if current matches TOKEN in dict TINFRA_ASSERT(child_match.expr.is_string()); std::string const& token = child_match.expr.get_string(); if( idict->first == token ) { self->match_found(&match, inext_command); } } } else { TINFRA_ASSERT(false); } if( recursive ) { // in recursive must reapply all rules from now on all containers self->push_container(&match, top.icommand); } } else { top.matching_finished = true; } } else if( child_match.type == TOKEN ) { // CURRENT.TOKEN, non-recursive // -> search for TOKEN in dict std::string const& token = child_match.expr.get_string(); variant::dict_type::iterator i = dict.find(token); top.matching_finished = true; if( i != dict.end() ) { variant& match = i->second; self->match_found(&match, inext_command); } } } else if( top.current->is_array() ) { variant::array_type& array = top.current->get_array(); if( child_match.type == WILDCARD_ALL || recursive) { // in wildcard we MATCH all // in recursive we recurse to all if( top.iarray != array.end() ) { variant::array_type::iterator iarray = top.iarray; top.iarray++; top.index++; variant& match = *iarray; TINFRA_TRACE(vtpath_exec_tracer, "vpath_visit: trying: " << top.index-1 << ": " << match); if( child_match.type == WILDCARD_ALL ) { self->match_found(&match, inext_command); } else if( child_match.type == TOKEN ) { if( child_match.expr.is_integer()) { int current_index = (iarray - array.begin()); int index = child_match.expr.get_integer(); if( index == current_index ) { self->match_found(&match, inext_command); } } } else { TINFRA_ASSERT(false); } if( recursive ) { // in recursive must reapply all rules from now on all containers self->push_container(&match, top.icommand); } } else { top.matching_finished = true; } } else if( child_match.type == TOKEN ) { TINFRA_ASSERT(child_match.expr.is_integer()); int index = child_match.expr.get_integer(); top.matching_finished = true; if( index >= 0 && size_t(index) < array.size() ) { variant& match = array[size_t(index)]; std::vector<vtpath_command>::iterator inext_command = (top.icommand+2); self->match_found(&match, inext_command); } } } // is array } // while result_queue is empty r = self->result_queue.front(); self->result_queue.pop_front(); return true; }