ue2_literal: make nocase member a dynamic_bitset

We were previously using vector<bool>, but dynamic_bitset provides a
faster any() impl
This commit is contained in:
Justin Viiret
2017-08-10 15:02:57 +10:00
committed by Matthew Barr
parent 36136f1003
commit 1aad3b0ed1
2 changed files with 53 additions and 49 deletions

View File

@@ -37,11 +37,13 @@
#include "util/charreach.h"
#include "util/compare.h"
#include "util/hash.h"
#include "util/operators.h"
#include <iterator>
#include <string>
#include <vector>
#include <boost/dynamic_bitset.hpp>
#include <boost/iterator/iterator_facade.hpp>
namespace ue2 {
@@ -80,7 +82,7 @@ struct ue2_case_string {
bool nocase;
};
struct ue2_literal {
struct ue2_literal : totally_ordered<ue2_literal> {
public:
/// Single element proxy, pointed to by our const_iterator.
struct elem {
@@ -108,38 +110,37 @@ public:
private:
friend class boost::iterator_core_access;
void increment() {
++it; ++it_nc;
++idx;
}
void decrement() {
--it; --it_nc;
--idx;
}
void advance(size_t n) {
it += n; it_nc += n;
idx += n;
}
difference_type distance_to(const const_iterator &other) const {
return other.it - it;
return other.idx - idx;
}
bool equal(const const_iterator &other) const {
return it == other.it;
return idx == other.idx && lit == other.lit;
}
const elem dereference() const {
return elem(*it, *it_nc);
return elem(lit->s[idx], lit->nocase[idx]);
}
friend struct ue2_literal;
const_iterator(const std::string::const_iterator &it_in,
const std::vector<bool>::const_iterator &it_nc_in)
: it(it_in), it_nc(it_nc_in) {}
const_iterator(const ue2_literal &lit_in, size_t idx_in)
: lit(&lit_in), idx(idx_in) {}
std::string::const_iterator it;
std::vector<bool>::const_iterator it_nc;
const ue2_literal *lit = nullptr;
size_t idx;
};
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using size_type = std::string::size_type;
static const size_type npos = std::string::npos;
typedef std::string::size_type size_type;
ue2_literal() {}
ue2_literal() = default;
ue2_literal(const std::string &s_in, bool nc_in);
ue2_literal(char c, bool nc_in);
ue2_literal(const ue2_literal &) = default;
@@ -156,16 +157,16 @@ public:
size_type length() const { return s.length(); }
bool empty() const { return s.empty(); }
ue2_literal substr(size_type pos, size_type n = std::string::npos) const;
ue2_literal substr(size_type pos, size_type n = npos) const;
const char *c_str() const { return s.c_str(); }
bool any_nocase() const;
const_iterator begin() const {
return const_iterator(s.begin(), nocase.begin());
return const_iterator(*this, 0);
}
const_iterator end() const {
return const_iterator(s.end(), nocase.end());
return const_iterator(*this, s.size());
}
const_reverse_iterator rbegin() const {
@@ -176,22 +177,23 @@ public:
return const_reverse_iterator(begin());
}
ue2_literal &erase(size_type pos = 0, size_type n = std::string::npos);
ue2_literal &erase(size_type pos = 0, size_type n = npos);
void push_back(const elem &e) {
push_back(e.c, e.nocase);
}
void push_back(char c, bool nc);
const elem back() const { return elem(*s.rbegin(), nocase.back()); }
friend ue2_literal operator+(const ue2_literal &a, const ue2_literal &b);
const elem back() const { return *rbegin(); }
friend ue2_literal operator+(ue2_literal a, const ue2_literal &b) {
a += b;
return a;
}
void operator+=(const ue2_literal &b);
bool operator==(const ue2_literal &b) const {
return s == b.s && nocase == b.nocase;
}
bool operator!=(const ue2_literal &b) const {
return !(*this == b);
}
bool operator<(const ue2_literal &b) const;
void clear(void) { s.clear(); nocase.clear(); }
@@ -204,8 +206,9 @@ public:
}
private:
friend const_iterator;
std::string s;
std::vector<bool> nocase; /* for trolling value */
boost::dynamic_bitset<> nocase;
};
/// Return a reversed copy of this literal.