From 45215e3c405a95b6f66d4bd4972bce7ec43decbb Mon Sep 17 00:00:00 2001 From: Andrei Avram Date: Sun, 11 Jun 2023 18:18:36 +0300 Subject: [PATCH] Use specific types. --- README.md | 6 ++-- examples/bazel-project/src/main.cpp | 2 +- examples/cmake-project/src/main.cpp | 2 +- examples/lambda_visitor.cpp | 8 ++--- include/msd/poly_map.hpp | 16 +++++----- tests/poly_map_test.cpp | 48 ++++++++++++++--------------- 6 files changed, 42 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index e378ada..a001f97 100644 --- a/README.md +++ b/README.md @@ -25,18 +25,18 @@ A recursive map that can have any shape and can hold multiple types for keys and #include #include -#include "msd/poly_map.hpp" +#include struct visitor { template - auto operator()(const double key, V&, M&) + bool operator()(const double key, V&, M&) { std::cout << "double = " << key << "\n"; return true; } template - auto operator()(K& key, V&, M&) + bool operator()(K& key, V&, M&) { std::cout << "other = " << key << "\n"; return true; diff --git a/examples/bazel-project/src/main.cpp b/examples/bazel-project/src/main.cpp index 3fea798..d2822ec 100644 --- a/examples/bazel-project/src/main.cpp +++ b/examples/bazel-project/src/main.cpp @@ -1,6 +1,6 @@ #include -#include "msd/poly_map.hpp" +#include int main() { diff --git a/examples/cmake-project/src/main.cpp b/examples/cmake-project/src/main.cpp index 3fea798..d2822ec 100644 --- a/examples/cmake-project/src/main.cpp +++ b/examples/cmake-project/src/main.cpp @@ -1,6 +1,6 @@ #include -#include "msd/poly_map.hpp" +#include int main() { diff --git a/examples/lambda_visitor.cpp b/examples/lambda_visitor.cpp index f2e035f..913742f 100644 --- a/examples/lambda_visitor.cpp +++ b/examples/lambda_visitor.cpp @@ -1,7 +1,7 @@ #include #include -#include "msd/poly_map.hpp" +#include // https://en.cppreference.com/w/cpp/utility/variant/visit#Example template @@ -22,17 +22,17 @@ int main() map[1][2][3.1][4.2]["g"] = 199; const auto lambda_visitor = visitor{ - [](const double key, auto& value, auto&) { + [](const double key, auto& value, auto&) -> bool { std::cout << "double key " << key << " " << (value.empty() ? "has no value" : "has a value") << "\n"; return true; }, - [](const std::string& key, auto& value, auto&) { + [](const std::string& key, auto& value, auto&) -> bool { std::cout << "string key " << key << " " << (value.empty() ? "has no value" : "has a value") << "\n"; return true; }, - [](auto key, auto& value, auto&) { + [](auto key, auto& value, auto&) -> bool { std::cout << "other key " << key << " " << (value.empty() ? "has no value" : "has a value") << "\n"; return true; }, diff --git a/include/msd/poly_map.hpp b/include/msd/poly_map.hpp index 0da3e64..45132e1 100644 --- a/include/msd/poly_map.hpp +++ b/include/msd/poly_map.hpp @@ -38,7 +38,7 @@ struct poly_map_value { * @throws std::bad_cast if cannot cast stored value to given type. */ template - [[nodiscard]] auto get() const + [[nodiscard]] T get() const { try { return std::any_cast(value_); @@ -71,10 +71,12 @@ class poly_map { * * @param v Value to add. * + * @return Reference to map. + * * @throws std::bad_alloc or the exception thrown by the assigned value's constructor. */ template - auto& operator=(T&& v) + poly_map& operator=(T&& v) { value_.set(std::forward(v)); @@ -91,7 +93,7 @@ class poly_map { * @throws std::out_of_range if key not found. */ template - [[nodiscard]] auto& at(const T& key) + [[nodiscard]] poly_map& at(const T& key) { return elements_.at(key); } @@ -122,7 +124,7 @@ class poly_map { * @throws std::out_of_range if key not found. */ template - [[nodiscard]] auto& at(const T& key, const Ts&... keys) const + [[nodiscard]] poly_map& at(const T& key, const Ts&... keys) const { return const_cast(this)->at(key, keys...); } @@ -137,7 +139,7 @@ class poly_map { * @throws std::out_of_range if key not found. */ template - auto& operator[](const T key) + poly_map& operator[](const T key) { return elements_[key]; } @@ -152,7 +154,7 @@ class poly_map { * @throws std::bad_cast if cannot cast stored value to given type. */ template - [[nodiscard]] auto get() const + [[nodiscard]] T get() const { return value_.template get(); } @@ -166,7 +168,7 @@ class poly_map { void for_each(V&& visitor) { for (auto& element : elements_) { - const auto visit = [this, &visitor, &element](auto& key) { + const auto visit = [this, &visitor, &element](auto& key) -> bool { return visitor(key, element.second.value_, elements_); }; diff --git a/tests/poly_map_test.cpp b/tests/poly_map_test.cpp index df73965..c6be267 100644 --- a/tests/poly_map_test.cpp +++ b/tests/poly_map_test.cpp @@ -1,4 +1,4 @@ -#include "msd/poly_map.hpp" +#include #include #include @@ -6,7 +6,7 @@ #include #include -#include "gtest/gtest.h" +#include using poly_map_type = msd::poly_map; @@ -106,7 +106,7 @@ struct map_visitor { TEST_F(PolyMapTest, for_each) { - auto visitor = map_visitor{}; + map_visitor visitor{}; map.for_each(visitor); EXPECT_EQ(visitor.keys.size(), 6); @@ -125,11 +125,11 @@ TEST_F(PolyMapTest, for_each) EXPECT_EQ((visitor.values[4].get>()), std::make_pair(1, 2)); EXPECT_EQ(visitor.values[5].get(), 199); - auto const_visitor = map_visitor{}; - const_map.for_each(const_visitor); + map_visitor visitor_for_const_map {}; + const_map.for_each(visitor_for_const_map); - EXPECT_EQ(const_visitor.keys.size(), 6); - EXPECT_EQ(const_visitor.values.size(), 6); + EXPECT_EQ(visitor_for_const_map.keys.size(), 6); + EXPECT_EQ(visitor_for_const_map.values.size(), 6); } struct stop_visitor { @@ -137,7 +137,7 @@ struct stop_visitor { std::size_t value_count; template - auto operator()(K&, V&, M&) + bool operator()(K&, V&, M&) { ++key_count; ++value_count; @@ -147,13 +147,13 @@ struct stop_visitor { TEST_F(PolyMapTest, for_each_stop) { - auto visitor = stop_visitor{}; + stop_visitor visitor{}; map.for_each(visitor); EXPECT_EQ(visitor.key_count, 1); EXPECT_EQ(visitor.value_count, 1); - auto const_visitor = stop_visitor{}; + stop_visitor const_visitor{}; const_map.for_each(const_visitor); EXPECT_EQ(const_visitor.key_count, 1); @@ -167,22 +167,22 @@ struct passed_map_visitor { bool operator()(const std::string& key, V&, M& map) { if (key == "f") { - auto passed_map_ptr = static_cast(&map); - auto test_map_ptr = static_cast(&test_map.at(1).at(2).at(3.1)); + const auto passed_map_ptr = static_cast(&map); + const auto test_map_ptr = static_cast(&test_map.at(1).at(2).at(3.1)); EXPECT_EQ(passed_map_ptr, test_map_ptr); - auto passed_map_value = map[key].template get(); - auto test_map_value = test_map.at(1).at(2).at(3.1).at(key).get(); + const auto passed_map_value = map[key].template get(); + const auto test_map_value = test_map.at(1).at(2).at(3.1).at(key).get(); EXPECT_EQ(passed_map_value, test_map_value); } if (key == "g") { - auto passed_map_ptr = static_cast(&map); - auto test_map_ptr = static_cast(&test_map.at(1).at(2).at(3.1).at(4.2)); + const auto passed_map_ptr = static_cast(&map); + const auto test_map_ptr = static_cast(&test_map.at(1).at(2).at(3.1).at(4.2)); EXPECT_EQ(passed_map_ptr, test_map_ptr); - auto passed_map_value = map[key].template get>(); - auto test_map_value = test_map.at(1).at(2).at(3.1).at(4.2).at(key).get>(); + const auto passed_map_value = map[key].template get>(); + const auto test_map_value = test_map.at(1).at(2).at(3.1).at(4.2).at(key).get>(); EXPECT_EQ(passed_map_value, test_map_value); } @@ -206,7 +206,7 @@ struct element_visitor { std::vector& keys; template - auto operator()(const K& key, V&, M&) + bool operator()(const K& key, V&, M&) { keys.emplace_back(key); return true; @@ -241,17 +241,17 @@ TEST_F(PolyMapTest, for_each_element) TEST_F(PolyMapTest, for_each_stop_element) { - auto visitor = stop_visitor{}; + stop_visitor visitor{}; map[1].for_each(visitor); EXPECT_EQ(visitor.key_count, 1); EXPECT_EQ(visitor.value_count, 1); - auto const_visitor = stop_visitor{}; - const_map.for_each(const_visitor); + stop_visitor visitor_for_const_map{}; + const_map.for_each(visitor_for_const_map); - EXPECT_EQ(const_visitor.key_count, 1); - EXPECT_EQ(const_visitor.value_count, 1); + EXPECT_EQ(visitor_for_const_map.key_count, 1); + EXPECT_EQ(visitor_for_const_map.value_count, 1); } TEST_F(PolyMapTest, empty)