Skip to content

Commit

Permalink
Use specific types.
Browse files Browse the repository at this point in the history
  • Loading branch information
andreiavrammsd committed Jun 11, 2023
1 parent 0b689e2 commit 45215e3
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 40 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ A recursive map that can have any shape and can hold multiple types for keys and
#include <string>
#include <utility>

#include "msd/poly_map.hpp"
#include <msd/poly_map.hpp>

struct visitor {
template <typename V, typename M>
auto operator()(const double key, V&, M&)
bool operator()(const double key, V&, M&)
{
std::cout << "double = " << key << "\n";
return true;
}

template <typename K, typename V, typename M>
auto operator()(K& key, V&, M&)
bool operator()(K& key, V&, M&)
{
std::cout << "other = " << key << "\n";
return true;
Expand Down
2 changes: 1 addition & 1 deletion examples/bazel-project/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <cassert>

#include "msd/poly_map.hpp"
#include <msd/poly_map.hpp>

int main()
{
Expand Down
2 changes: 1 addition & 1 deletion examples/cmake-project/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <cassert>

#include "msd/poly_map.hpp"
#include <msd/poly_map.hpp>

int main()
{
Expand Down
8 changes: 4 additions & 4 deletions examples/lambda_visitor.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <iostream>
#include <string>

#include "msd/poly_map.hpp"
#include <msd/poly_map.hpp>

// https://en.cppreference.com/w/cpp/utility/variant/visit#Example
template <class... Ts>
Expand All @@ -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;
},
Expand Down
16 changes: 9 additions & 7 deletions include/msd/poly_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ struct poly_map_value {
* @throws std::bad_cast if cannot cast stored value to given type.
*/
template <typename T>
[[nodiscard]] auto get() const
[[nodiscard]] T get() const
{
try {
return std::any_cast<T>(value_);
Expand Down Expand Up @@ -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 <typename T>
auto& operator=(T&& v)
poly_map& operator=(T&& v)
{
value_.set(std::forward<T>(v));

Expand All @@ -91,7 +93,7 @@ class poly_map {
* @throws std::out_of_range if key not found.
*/
template <typename T>
[[nodiscard]] auto& at(const T& key)
[[nodiscard]] poly_map& at(const T& key)
{
return elements_.at(key);
}
Expand Down Expand Up @@ -122,7 +124,7 @@ class poly_map {
* @throws std::out_of_range if key not found.
*/
template <typename T, typename... Ts>
[[nodiscard]] auto& at(const T& key, const Ts&... keys) const
[[nodiscard]] poly_map& at(const T& key, const Ts&... keys) const
{
return const_cast<poly_map*>(this)->at(key, keys...);
}
Expand All @@ -137,7 +139,7 @@ class poly_map {
* @throws std::out_of_range if key not found.
*/
template <typename T>
auto& operator[](const T key)
poly_map& operator[](const T key)
{
return elements_[key];
}
Expand All @@ -152,7 +154,7 @@ class poly_map {
* @throws std::bad_cast if cannot cast stored value to given type.
*/
template <typename T>
[[nodiscard]] auto get() const
[[nodiscard]] T get() const
{
return value_.template get<T>();
}
Expand All @@ -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_);
};

Expand Down
48 changes: 24 additions & 24 deletions tests/poly_map_test.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#include "msd/poly_map.hpp"
#include <msd/poly_map.hpp>

#include <any>
#include <limits>
#include <string>
#include <tuple>
#include <vector>

#include "gtest/gtest.h"
#include <gtest/gtest.h>

using poly_map_type = msd::poly_map<int, double, std::string>;

Expand Down Expand Up @@ -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);
Expand All @@ -125,19 +125,19 @@ TEST_F(PolyMapTest, for_each)
EXPECT_EQ((visitor.values[4].get<std::pair<int, int>>()), std::make_pair(1, 2));
EXPECT_EQ(visitor.values[5].get<int>(), 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 {
std::size_t key_count;
std::size_t value_count;

template <typename K, typename V, typename M>
auto operator()(K&, V&, M&)
bool operator()(K&, V&, M&)
{
++key_count;
++value_count;
Expand All @@ -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);
Expand All @@ -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<void*>(&map);
auto test_map_ptr = static_cast<void*>(&test_map.at(1).at(2).at(3.1));
const auto passed_map_ptr = static_cast<void*>(&map);
const auto test_map_ptr = static_cast<void*>(&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<int>();
auto test_map_value = test_map.at(1).at(2).at(3.1).at(key).get<int>();
const auto passed_map_value = map[key].template get<int>();
const auto test_map_value = test_map.at(1).at(2).at(3.1).at(key).get<int>();
EXPECT_EQ(passed_map_value, test_map_value);
}

if (key == "g") {
auto passed_map_ptr = static_cast<void*>(&map);
auto test_map_ptr = static_cast<void*>(&test_map.at(1).at(2).at(3.1).at(4.2));
const auto passed_map_ptr = static_cast<void*>(&map);
const auto test_map_ptr = static_cast<void*>(&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<std::pair<int, int>>();
auto test_map_value = test_map.at(1).at(2).at(3.1).at(4.2).at(key).get<std::pair<int, int>>();
const auto passed_map_value = map[key].template get<std::pair<int, int>>();
const auto test_map_value = test_map.at(1).at(2).at(3.1).at(4.2).at(key).get<std::pair<int, int>>();
EXPECT_EQ(passed_map_value, test_map_value);
}

Expand All @@ -206,7 +206,7 @@ struct element_visitor {
std::vector<std::any>& keys;

template <typename K, typename V, typename M>
auto operator()(const K& key, V&, M&)
bool operator()(const K& key, V&, M&)
{
keys.emplace_back(key);
return true;
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 45215e3

Please sign in to comment.