You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datasketches.apache.org by al...@apache.org on 2022/11/08 00:42:50 UTC
[datasketches-cpp] branch operator_arrow created (now ef69eba)
This is an automated email from the ASF dual-hosted git repository.
alsay pushed a change to branch operator_arrow
in repository https://gitbox.apache.org/repos/asf/datasketches-cpp.git
at ef69eba operator->
This branch includes the following new commits:
new ef69eba operator->
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org
[datasketches-cpp] 01/01: operator->
Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
alsay pushed a commit to branch operator_arrow
in repository https://gitbox.apache.org/repos/asf/datasketches-cpp.git
commit ef69ebaef08ab6ecbf553da13e8482ffeee1afd2
Author: AlexanderSaydakov <Al...@users.noreply.github.com>
AuthorDate: Mon Nov 7 16:42:44 2022 -0800
operator->
---
common/include/common_defs.hpp | 10 ++++
common/include/quantiles_sorted_view.hpp | 16 ++----
common/test/quantiles_sorted_view_test.cpp | 4 ++
kll/include/kll_sketch.hpp | 4 +-
kll/include/kll_sketch_impl.hpp | 87 +++++++++++++++--------------
kll/test/kll_sketch_test.cpp | 17 ++++--
quantiles/include/quantiles_sketch.hpp | 4 +-
quantiles/include/quantiles_sketch_impl.hpp | 10 +++-
quantiles/test/quantiles_sketch_test.cpp | 25 +++++----
req/include/req_sketch.hpp | 4 +-
req/include/req_sketch_impl.hpp | 9 ++-
req/test/req_sketch_test.cpp | 13 +++--
12 files changed, 123 insertions(+), 80 deletions(-)
diff --git a/common/include/common_defs.hpp b/common/include/common_defs.hpp
index a1ab6cf..7437536 100644
--- a/common/include/common_defs.hpp
+++ b/common/include/common_defs.hpp
@@ -86,6 +86,16 @@ static inline void write(std::ostream& os, const T* ptr, size_t size_bytes) {
os.write(reinterpret_cast<const char*>(ptr), size_bytes);
}
+// wrapper for iterators to implement operator-> returning temporary value
+template<typename T>
+class return_value_holder {
+public:
+ return_value_holder(T value): value_(value) {}
+ const T* operator->() const { return std::addressof(value_); }
+private:
+ T value_;
+};
+
} // namespace
#endif // _COMMON_DEFS_HPP_
diff --git a/common/include/quantiles_sorted_view.hpp b/common/include/quantiles_sorted_view.hpp
index fffee87..e965cb1 100755
--- a/common/include/quantiles_sorted_view.hpp
+++ b/common/include/quantiles_sorted_view.hpp
@@ -23,6 +23,8 @@
#include <functional>
#include <cmath>
+#include "common_defs.hpp"
+
namespace datasketches {
template<
@@ -123,24 +125,16 @@ public:
const_iterator(const Base& it, const Base& begin): Base(it), begin(begin) {}
template<typename TT = T, typename std::enable_if<std::is_arithmetic<TT>::value, int>::type = 0>
- value_type operator*() const { return Base::operator*(); }
+ const value_type operator*() const { return Base::operator*(); }
template<typename TT = T, typename std::enable_if<!std::is_arithmetic<TT>::value, int>::type = 0>
- value_type operator*() const { return value_type(*(Base::operator*().first), Base::operator*().second); }
-
- class return_value_holder {
- public:
- return_value_holder(value_type value): value_(value) {}
- const value_type* operator->() const { return &value_; }
- private:
- value_type value_;
- };
+ const value_type operator*() const { return value_type(*(Base::operator*().first), Base::operator*().second); }
template<typename TT = T, typename std::enable_if<std::is_arithmetic<TT>::value, int>::type = 0>
const value_type* operator->() const { return Base::operator->(); }
template<typename TT = T, typename std::enable_if<!std::is_arithmetic<TT>::value, int>::type = 0>
- return_value_holder operator->() const { return **this; }
+ const return_value_holder<value_type> operator->() const { return **this; }
uint64_t get_weight() const {
if (*this == begin) return Base::operator*().second;
diff --git a/common/test/quantiles_sorted_view_test.cpp b/common/test/quantiles_sorted_view_test.cpp
index a9ecfbd..609408d 100644
--- a/common/test/quantiles_sorted_view_test.cpp
+++ b/common/test/quantiles_sorted_view_test.cpp
@@ -45,8 +45,12 @@ TEST_CASE("set 0", "sorted view") {
REQUIRE(view.size() == 1);
auto it = view.begin();
+ // using operator->
REQUIRE(it->first == 10);
REQUIRE(it->second == 1);
+ // using operator*
+ REQUIRE((*it).first == 10);
+ REQUIRE((*it).second == 1);
REQUIRE(it.get_weight() == 1);
REQUIRE(it.get_cumulative_weight() == 1);
REQUIRE(it.get_cumulative_weight(false) == 0);
diff --git a/kll/include/kll_sketch.hpp b/kll/include/kll_sketch.hpp
index d0cadc8..3407afc 100644
--- a/kll/include/kll_sketch.hpp
+++ b/kll/include/kll_sketch.hpp
@@ -588,12 +588,14 @@ class kll_sketch {
template<typename T, typename C, typename A>
class kll_sketch<T, C, A>::const_iterator: public std::iterator<std::input_iterator_tag, T> {
public:
+ using value_type = std::pair<const T&, const uint64_t>;
friend class kll_sketch<T, C, A>;
const_iterator& operator++();
const_iterator& operator++(int);
bool operator==(const const_iterator& other) const;
bool operator!=(const const_iterator& other) const;
- const std::pair<const T&, const uint64_t> operator*() const;
+ const value_type operator*() const;
+ const return_value_holder<value_type> operator->() const;
private:
const T* items;
const uint32_t* levels;
diff --git a/kll/include/kll_sketch_impl.hpp b/kll/include/kll_sketch_impl.hpp
index 894d7b2..933640b 100644
--- a/kll/include/kll_sketch_impl.hpp
+++ b/kll/include/kll_sketch_impl.hpp
@@ -1019,47 +1019,6 @@ typename kll_sketch<T, C, A>::const_iterator kll_sketch<T, C, A>::end() const {
return kll_sketch<T, C, A>::const_iterator(nullptr, levels_.data(), num_levels_);
}
-// kll_sketch::const_iterator implementation
-
-template<typename T, typename C, typename A>
-kll_sketch<T, C, A>::const_iterator::const_iterator(const T* items, const uint32_t* levels, const uint8_t num_levels):
-items(items), levels(levels), num_levels(num_levels), index(items == nullptr ? levels[num_levels] : levels[0]), level(items == nullptr ? num_levels : 0), weight(1)
-{}
-
-template<typename T, typename C, typename A>
-typename kll_sketch<T, C, A>::const_iterator& kll_sketch<T, C, A>::const_iterator::operator++() {
- ++index;
- if (index == levels[level + 1]) { // go to the next non-empty level
- do {
- ++level;
- weight *= 2;
- } while (level < num_levels && levels[level] == levels[level + 1]);
- }
- return *this;
-}
-
-template<typename T, typename C, typename A>
-typename kll_sketch<T, C, A>::const_iterator& kll_sketch<T, C, A>::const_iterator::operator++(int) {
- const_iterator tmp(*this);
- operator++();
- return tmp;
-}
-
-template<typename T, typename C, typename A>
-bool kll_sketch<T, C, A>::const_iterator::operator==(const const_iterator& other) const {
- return index == other.index;
-}
-
-template<typename T, typename C, typename A>
-bool kll_sketch<T, C, A>::const_iterator::operator!=(const const_iterator& other) const {
- return !operator==(other);
-}
-
-template<typename T, typename C, typename A>
-const std::pair<const T&, const uint64_t> kll_sketch<T, C, A>::const_iterator::operator*() const {
- return std::pair<const T&, const uint64_t>(items[index], weight);
-}
-
template<typename T, typename C, typename A>
class kll_sketch<T, C, A>::item_deleter {
public:
@@ -1109,6 +1068,52 @@ void kll_sketch<T, C, A>::reset_sorted_view() {
}
}
+// kll_sketch::const_iterator implementation
+
+template<typename T, typename C, typename A>
+kll_sketch<T, C, A>::const_iterator::const_iterator(const T* items, const uint32_t* levels, const uint8_t num_levels):
+items(items), levels(levels), num_levels(num_levels), index(items == nullptr ? levels[num_levels] : levels[0]), level(items == nullptr ? num_levels : 0), weight(1)
+{}
+
+template<typename T, typename C, typename A>
+typename kll_sketch<T, C, A>::const_iterator& kll_sketch<T, C, A>::const_iterator::operator++() {
+ ++index;
+ if (index == levels[level + 1]) { // go to the next non-empty level
+ do {
+ ++level;
+ weight *= 2;
+ } while (level < num_levels && levels[level] == levels[level + 1]);
+ }
+ return *this;
+}
+
+template<typename T, typename C, typename A>
+typename kll_sketch<T, C, A>::const_iterator& kll_sketch<T, C, A>::const_iterator::operator++(int) {
+ const_iterator tmp(*this);
+ operator++();
+ return tmp;
+}
+
+template<typename T, typename C, typename A>
+bool kll_sketch<T, C, A>::const_iterator::operator==(const const_iterator& other) const {
+ return index == other.index;
+}
+
+template<typename T, typename C, typename A>
+bool kll_sketch<T, C, A>::const_iterator::operator!=(const const_iterator& other) const {
+ return !operator==(other);
+}
+
+template<typename T, typename C, typename A>
+auto kll_sketch<T, C, A>::const_iterator::operator*() const -> const value_type {
+ return value_type(items[index], weight);
+}
+
+template<typename T, typename C, typename A>
+auto kll_sketch<T, C, A>::const_iterator::operator->() const -> const return_value_holder<value_type> {
+ return **this;
+}
+
} /* namespace datasketches */
#endif
diff --git a/kll/test/kll_sketch_test.cpp b/kll/test/kll_sketch_test.cpp
index 48b64e9..7ce92c9 100644
--- a/kll/test/kll_sketch_test.cpp
+++ b/kll/test/kll_sketch_test.cpp
@@ -73,8 +73,8 @@ TEST_CASE("kll sketch", "[kll_sketch]") {
REQUIRE_THROWS_AS(sketch.get_PMF(split_points, 1), std::runtime_error);
REQUIRE_THROWS_AS(sketch.get_CDF(split_points, 1), std::runtime_error);
- for (auto it: sketch) {
- (void) it; // to suppress "unused" warning
+ for (auto pair: sketch) {
+ unused(pair); // to suppress "unused" warning
FAIL("should be no iterations over an empty sketch");
}
}
@@ -107,11 +107,16 @@ TEST_CASE("kll sketch", "[kll_sketch]") {
REQUIRE(quantiles[2] == 1.0);
int count = 0;
- for (auto it: sketch) {
- REQUIRE(it.second == 1);
+ for (auto pair: sketch) {
+ REQUIRE(pair.second == 1);
++count;
}
REQUIRE(count == 1);
+
+ // iterator dereferencing
+ auto it = sketch.begin();
+ REQUIRE(it->first == 1.0f);
+ REQUIRE((*it).first == 1.0f);
}
SECTION("NaN") {
@@ -211,9 +216,9 @@ TEST_CASE("kll sketch", "[kll_sketch]") {
uint32_t count = 0;
uint64_t total_weight = 0;
- for (auto it: sketch) {
+ for (auto pair: sketch) {
++count;
- total_weight += it.second;
+ total_weight += pair.second;
}
REQUIRE(count == sketch.get_num_retained());
REQUIRE(total_weight == sketch.get_n());
diff --git a/quantiles/include/quantiles_sketch.hpp b/quantiles/include/quantiles_sketch.hpp
index da80766..184b784 100644
--- a/quantiles/include/quantiles_sketch.hpp
+++ b/quantiles/include/quantiles_sketch.hpp
@@ -582,11 +582,13 @@ private:
template<typename T, typename C, typename A>
class quantiles_sketch<T, C, A>::const_iterator: public std::iterator<std::input_iterator_tag, T> {
public:
+ using value_type = std::pair<const T&, const uint64_t>;
const_iterator& operator++();
const_iterator& operator++(int);
bool operator==(const const_iterator& other) const;
bool operator!=(const const_iterator& other) const;
- std::pair<const T&, const uint64_t> operator*() const;
+ const value_type operator*() const;
+ const return_value_holder<value_type> operator->() const;
private:
friend class quantiles_sketch<T, C, A>;
using Level = std::vector<T, A>;
diff --git a/quantiles/include/quantiles_sketch_impl.hpp b/quantiles/include/quantiles_sketch_impl.hpp
index d0d972f..bb90005 100644
--- a/quantiles/include/quantiles_sketch_impl.hpp
+++ b/quantiles/include/quantiles_sketch_impl.hpp
@@ -26,7 +26,6 @@
#include <iomanip>
#include <sstream>
-#include "common_defs.hpp"
#include "count_zeros.hpp"
#include "conditional_forward.hpp"
@@ -1355,8 +1354,13 @@ bool quantiles_sketch<T, C, A>::const_iterator::operator!=(const const_iterator&
}
template<typename T, typename C, typename A>
-std::pair<const T&, const uint64_t> quantiles_sketch<T, C, A>::const_iterator::operator*() const {
- return std::pair<const T&, const uint64_t>(level_ == -1 ? base_buffer_[index_] : levels_[level_][index_], weight_);
+auto quantiles_sketch<T, C, A>::const_iterator::operator*() const -> const value_type {
+ return value_type(level_ == -1 ? base_buffer_[index_] : levels_[level_][index_], weight_);
+}
+
+template<typename T, typename C, typename A>
+auto quantiles_sketch<T, C, A>::const_iterator::operator->() const -> const return_value_holder<value_type> {
+ return **this;
}
} /* namespace datasketches */
diff --git a/quantiles/test/quantiles_sketch_test.cpp b/quantiles/test/quantiles_sketch_test.cpp
index 3e3a884..3e47c33 100644
--- a/quantiles/test/quantiles_sketch_test.cpp
+++ b/quantiles/test/quantiles_sketch_test.cpp
@@ -71,11 +71,11 @@ TEST_CASE("quantiles sketch", "[quantiles_sketch]") {
REQUIRE_THROWS_AS(sketch.get_PMF(split_points, 1), std::runtime_error);
REQUIRE_THROWS_AS(sketch.get_CDF(split_points, 1), std::runtime_error);
- for (auto it: sketch) {
- unused(it);
+ for (auto pair: sketch) {
+ unused(pair);
FAIL("should be no iterations over an empty sketch");
}
- }
+}
SECTION("get bad quantile") {
quantiles_float_sketch sketch(64, std::less<float>(), 0);
@@ -106,12 +106,17 @@ TEST_CASE("quantiles sketch", "[quantiles_sketch]") {
REQUIRE(quantiles[2] == 1.0);
int count = 0;
- for (auto it: sketch) {
- REQUIRE(it.second == 1);
+ for (auto pair: sketch) {
+ REQUIRE(pair.second == 1);
++count;
}
REQUIRE(count == 1);
- }
+
+ // iterator dereferencing
+ auto it = sketch.begin();
+ REQUIRE(it->first == 1.0f);
+ REQUIRE((*it).first == 1.0f);
+}
SECTION("NaN") {
quantiles_float_sketch sketch(256, std::less<float>(), 0);
@@ -163,8 +168,8 @@ TEST_CASE("quantiles sketch", "[quantiles_sketch]") {
REQUIRE(quantiles[2] == quantiles2[2]);
int count = 0;
- for (auto it: sketch) {
- REQUIRE(it.second == 1);
+ for (auto pair: sketch) {
+ REQUIRE(pair.second == 1);
++count;
}
REQUIRE(count == n);
@@ -228,9 +233,9 @@ TEST_CASE("quantiles sketch", "[quantiles_sketch]") {
uint32_t count = 0;
uint64_t total_weight = 0;
- for (auto it: sketch) {
+ for (auto pair: sketch) {
++count;
- total_weight += it.second;
+ total_weight += pair.second;
}
REQUIRE(count == sketch.get_num_retained());
REQUIRE(total_weight == sketch.get_n());
diff --git a/req/include/req_sketch.hpp b/req/include/req_sketch.hpp
index f033b6a..b6375c5 100755
--- a/req/include/req_sketch.hpp
+++ b/req/include/req_sketch.hpp
@@ -401,11 +401,13 @@ private:
template<typename T, typename C, typename A>
class req_sketch<T, C, A>::const_iterator: public std::iterator<std::input_iterator_tag, T> {
public:
+ using value_type = std::pair<const T&, const uint64_t>;
const_iterator& operator++();
const_iterator& operator++(int);
bool operator==(const const_iterator& other) const;
bool operator!=(const const_iterator& other) const;
- std::pair<const T&, const uint64_t> operator*() const;
+ const value_type operator*() const;
+ const return_value_holder<value_type> operator->() const;
private:
using LevelsIterator = typename std::vector<Compactor, AllocCompactor>::const_iterator;
LevelsIterator levels_it_;
diff --git a/req/include/req_sketch_impl.hpp b/req/include/req_sketch_impl.hpp
index 62aed71..7634a80 100755
--- a/req/include/req_sketch_impl.hpp
+++ b/req/include/req_sketch_impl.hpp
@@ -848,8 +848,13 @@ bool req_sketch<T, C, A>::const_iterator::operator!=(const const_iterator& other
}
template<typename T, typename C, typename A>
-std::pair<const T&, const uint64_t> req_sketch<T, C, A>::const_iterator::operator*() const {
- return std::pair<const T&, const uint64_t>(*compactor_it_, 1ULL << (*levels_it_).get_lg_weight());
+auto req_sketch<T, C, A>::const_iterator::operator*() const -> const value_type {
+ return value_type(*compactor_it_, 1ULL << (*levels_it_).get_lg_weight());
+}
+
+template<typename T, typename C, typename A>
+auto req_sketch<T, C, A>::const_iterator::operator->() const -> const return_value_holder<value_type> {
+ return **this;
}
} /* namespace datasketches */
diff --git a/req/test/req_sketch_test.cpp b/req/test/req_sketch_test.cpp
index 9515962..9a8daa1 100755
--- a/req/test/req_sketch_test.cpp
+++ b/req/test/req_sketch_test.cpp
@@ -79,11 +79,16 @@ TEST_CASE("req sketch: single value, lra", "[req_sketch]") {
REQUIRE(quantiles[2] == 1);
unsigned count = 0;
- for (auto it: sketch) {
- REQUIRE(it.second == 1);
+ for (auto pair: sketch) {
+ REQUIRE(pair.second == 1);
++count;
}
REQUIRE(count == 1);
+
+ // iterator dereferencing
+ auto it = sketch.begin();
+ REQUIRE(it->first == 1.0f);
+ REQUIRE((*it).first == 1.0f);
}
TEST_CASE("req sketch: repeated values", "[req_sketch]") {
@@ -182,8 +187,8 @@ TEST_CASE("req sketch: estimation mode", "[req_sketch]") {
REQUIRE(sketch.get_rank_upper_bound(0.5, 1) > 0.5);
unsigned count = 0;
- for (auto it: sketch) {
- REQUIRE(it.second >= 1);
+ for (auto pair: sketch) {
+ REQUIRE(pair.second >= 1);
++count;
}
REQUIRE(count == sketch.get_num_retained());
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org