Added cbegin and cend to IndexedSet

Also fixed/improved /flow/IndexedSet/const_iterator test
This commit is contained in:
tclinken 2020-05-16 18:01:07 -07:00
parent e58698d6f7
commit e16ec8beca
3 changed files with 47 additions and 26 deletions

View File

@ -84,8 +84,10 @@ public:
iterator find(const StringRef& key) { return data.find(key); }
const_iterator begin() const { return data.begin(); }
iterator begin() { return data.begin(); }
const_iterator cbegin() const { return begin(); }
const_iterator end() const { return data.end(); }
iterator end() { return data.end(); }
const_iterator cend() const { return end(); }
const_iterator lower_bound(const StringRef& key) const { return data.lower_bound(key); }
iterator lower_bound(const StringRef& key) { return data.lower_bound(key); }

View File

@ -222,7 +222,7 @@ struct IndexedSetHarness {
result end() { return s.end(); }
const_result lower_bound(K const& k) const { return s.lower_bound(k); }
result lower_bound(K const& k) { return s.lower_bound(k); }
result upper_bound(K const& k) const { return s.upper_bound(k); }
const_result upper_bound(K const& k) const { return s.upper_bound(k); }
result upper_bound(K const& k) { return s.upper_bound(k); }
void erase(K const& k) { s.erase(k); }
};
@ -502,6 +502,13 @@ TEST_CASE("/flow/IndexedSet/all numbers") {
return Void();
}
template <class T>
struct is_const_ref {
static constexpr bool value = std::is_const_v<typename std::remove_reference_t<T>>;
};
template <class T>
static constexpr bool is_const_ref_v = is_const_ref<T>::value;
TEST_CASE("/flow/IndexedSet/const_iterator") {
struct Key {
int key;
@ -511,41 +518,48 @@ TEST_CASE("/flow/IndexedSet/const_iterator") {
int metric;
explicit Metric(int metric) : metric(metric) {}
};
IndexedSet<int, int64_t> is;
for (int i = 0; i < 10; ++i) is.insert(i, 1);
static_assert(!std::is_const_v<decltype(is)>);
static_assert(!std::is_const_v<decltype(*is.begin())>);
static_assert(!std::is_const_v<decltype(*is.previous(is.end()))>);
static_assert(!std::is_const_v<decltype(*is.index(Metric{ 5 }))>);
static_assert(!std::is_const_v<decltype(*is.find(Key{ 5 }))>);
static_assert(!std::is_const_v<decltype(*is.upper_bound(Key{ 5 }))>);
static_assert(!std::is_const_v<decltype(*is.lower_bound(Key{ 5 }))>);
static_assert(!std::is_const_v<decltype(*is.lastLessOrEqual(Key{ 5 }))>);
static_assert(!std::is_const_v<decltype(*is.lastItem())>);
IndexedSet<int, int64_t>& ncis = is;
static_assert(!is_const_ref_v<decltype(ncis)>);
static_assert(!is_const_ref_v<decltype(*ncis.begin())>);
static_assert(is_const_ref_v<decltype(*ncis.cbegin())>);
static_assert(!is_const_ref_v<decltype(*ncis.previous(ncis.end()))>);
static_assert(is_const_ref_v<decltype(*ncis.previous(ncis.cend()))>);
static_assert(!is_const_ref_v<decltype(*ncis.index(Metric{ 5 }))>);
static_assert(!is_const_ref_v<decltype(*ncis.find(Key{ 5 }))>);
static_assert(!is_const_ref_v<decltype(*ncis.upper_bound(Key{ 5 }))>);
static_assert(!is_const_ref_v<decltype(*ncis.lower_bound(Key{ 5 }))>);
static_assert(!is_const_ref_v<decltype(*ncis.lastLessOrEqual(Key{ 5 }))>);
static_assert(!is_const_ref_v<decltype(*ncis.lastItem())>);
const IndexedSet<int, int64_t>& cis = is;
static_assert(std::is_const_v<typename std::remove_reference_t<decltype(cis)>>);
static_assert(std::is_const_v<typename std::remove_reference_t<decltype(*cis.begin())>>);
static_assert(std::is_const_v<typename std::remove_reference_t<decltype(*cis.previous(cis.end()))>>);
static_assert(std::is_const_v<typename std::remove_reference_t<decltype(*cis.previous(is.end()))>>);
static_assert(std::is_const_v<typename std::remove_reference_t<decltype(*cis.index(Metric{ 5 }))>>);
static_assert(std::is_const_v<typename std::remove_reference_t<decltype(*cis.find(Key{ 5 }))>>);
static_assert(std::is_const_v<typename std::remove_reference_t<decltype(*cis.upper_bound(Key{ 5 }))>>);
static_assert(std::is_const_v<typename std::remove_reference_t<decltype(*cis.lower_bound(Key{ 5 }))>>);
static_assert(std::is_const_v<typename std::remove_reference_t<decltype(*cis.lastLessOrEqual(Key{ 5 }))>>);
static_assert(std::is_const_v<typename std::remove_reference_t<decltype(*cis.lastItem())>>);
static_assert(is_const_ref_v<decltype(cis)>);
static_assert(is_const_ref_v<decltype(*cis.begin())>);
static_assert(is_const_ref_v<decltype(*cis.cbegin())>);
static_assert(is_const_ref_v<decltype(*cis.previous(cis.end()))>);
static_assert(is_const_ref_v<decltype(*cis.previous(cis.cend()))>);
static_assert(is_const_ref_v<decltype(*cis.previous(ncis.end()))>);
static_assert(is_const_ref_v<decltype(*cis.previous(ncis.cend()))>);
static_assert(is_const_ref_v<decltype(*cis.index(Metric{ 5 }))>);
static_assert(is_const_ref_v<decltype(*cis.find(Key{ 5 }))>);
static_assert(is_const_ref_v<decltype(*cis.upper_bound(Key{ 5 }))>);
static_assert(is_const_ref_v<decltype(*cis.lower_bound(Key{ 5 }))>);
static_assert(is_const_ref_v<decltype(*cis.lastLessOrEqual(Key{ 5 }))>);
static_assert(is_const_ref_v<decltype(*cis.lastItem())>);
for (auto& val : is) {
static_assert(!std::is_const_v<typename std::remove_reference_t<decltype(val)>>);
for (auto& val : ncis) {
static_assert(!is_const_ref_v<decltype(val)>);
}
for (const auto& val : is) {
static_assert(std::is_const_v<typename std::remove_reference_t<decltype(val)>>);
for (const auto& val : ncis) {
static_assert(is_const_ref_v<decltype(val)>);
}
for (auto& val : cis) {
static_assert(std::is_const_v<typename std::remove_reference_t<decltype(val)>>);
static_assert(is_const_ref_v<decltype(val)>);
}
return Void();
}
void forceLinkIndexedSetTests() {}

View File

@ -166,8 +166,11 @@ public:
const_iterator begin() const { return ConstImpl::begin(*this); };
iterator begin() { return NonConstImpl::begin(*this); };
const_iterator cbegin() const { return begin(); }
const_iterator end() const { return const_iterator{}; }
iterator end() { return iterator{}; }
const_iterator cend() const { return end(); }
const_iterator previous(const_iterator i) const { return ConstImpl::previous(*this, i); }
const_iterator previous(iterator i) const { return ConstImpl::previous(*this, const_iterator{ i }); }
@ -406,8 +409,10 @@ public:
Map() {}
const_iterator begin() const { return set.begin(); }
iterator begin() { return set.begin(); }
const_iterator cbegin() const { return begin(); }
const_iterator end() const { return set.end(); }
iterator end() { return set.end(); }
const_iterator cend() const { return end(); }
const_iterator lastItem() const { return set.lastItem(); }
iterator lastItem() { return set.lastItem(); }
const_iterator previous(const_iterator i) const { return set.previous(i); }