Skip to content

Commit

Permalink
Fixed const detection in containers assuming subscript operator
Browse files Browse the repository at this point in the history
  • Loading branch information
eyalz800 committed Nov 4, 2024
1 parent 17fe998 commit 129a9e3
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 2 deletions.
162 changes: 162 additions & 0 deletions test/src/test_list.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#include "test.h"

#include <list>

namespace test_list
{

TEST(list, integer)
{
auto [data, in, out] = zpp::bits::data_in_out();
out(std::list{1,2,3,4}).or_throw();

EXPECT_EQ(encode_hex(data),
"04000000"
"01000000"
"02000000"
"03000000"
"04000000");

std::list<int> v;
in(v).or_throw();

EXPECT_EQ(v, (std::list{1,2,3,4}));
}

TEST(list, const_integer)
{
auto [data, in, out] = zpp::bits::data_in_out();
const std::list<int> o{1,2,3,4};
out(o).or_throw();

EXPECT_EQ(encode_hex(data),
"04000000"
"01000000"
"02000000"
"03000000"
"04000000");

std::list<int> v;
in(v).or_throw();

EXPECT_EQ(v, (std::list{1,2,3,4}));
}

TEST(list, string)
{
using namespace std::string_literals;
auto [data, in, out] = zpp::bits::data_in_out();
out(std::list{"1"s,"2"s,"3"s,"4"s}).or_throw();

EXPECT_EQ(encode_hex(data),
"04000000"
"01000000"
"31"
"01000000"
"32"
"01000000"
"33"
"01000000"
"34");

std::list<std::string> v;
in(v).or_throw();

EXPECT_EQ(v, (std::list{"1"s,"2"s,"3"s,"4"s}));
}

TEST(list, const_string)
{
using namespace std::string_literals;
auto [data, in, out] = zpp::bits::data_in_out();
const std::list<std::string> o{"1"s, "2"s, "3"s, "4"s};
out(o).or_throw();

EXPECT_EQ(encode_hex(data),
"04000000"
"01000000"
"31"
"01000000"
"32"
"01000000"
"33"
"01000000"
"34");

std::list<std::string> v;
in(v).or_throw();

EXPECT_EQ(v, (std::list{"1"s,"2"s,"3"s,"4"s}));
}

TEST(list, sized_1b_integer)
{
auto [data, in, out] = zpp::bits::data_in_out();
out(zpp::bits::sized<std::uint8_t>(std::list{1,2,3,4})).or_throw();

EXPECT_EQ(encode_hex(data),
"04"
"01000000"
"02000000"
"03000000"
"04000000");

std::list<int> v;
in(zpp::bits::sized<std::uint8_t>(v)).or_throw();

EXPECT_EQ(v, (std::list{1,2,3,4}));
}

TEST(list, unsized_integer)
{
auto [data, in, out] = zpp::bits::data_in_out();
out(zpp::bits::unsized(std::list{1,2,3,4})).or_throw();

EXPECT_EQ(encode_hex(data),
"01000000"
"02000000"
"03000000"
"04000000");

std::list<int> v(4);
in(zpp::bits::unsized(v)).or_throw();

EXPECT_EQ(v, (std::list{1,2,3,4}));
}

TEST(list, sized_t_1b_integer)
{
auto [data, in, out] = zpp::bits::data_in_out();
out(zpp::bits::sized_t<std::list<int>, std::uint8_t>{1,2,3,4}).or_throw();

EXPECT_EQ(encode_hex(data),
"04"
"01000000"
"02000000"
"03000000"
"04000000");

zpp::bits::sized_t<std::list<int>, std::uint8_t> v;
in(v).or_throw();

EXPECT_EQ(v, (std::list{1,2,3,4}));
}

TEST(list, unsized_t_integer)
{
auto [data, in, out] = zpp::bits::data_in_out();
out(zpp::bits::unsized_t<std::list<int>>{1,2,3,4}).or_throw();

EXPECT_EQ(encode_hex(data),
"01000000"
"02000000"
"03000000"
"04000000");

zpp::bits::unsized_t<std::list<int>> v(4);
in(v).or_throw();

EXPECT_EQ(v, (std::list{1,2,3,4}));
}

} // namespace test_list
20 changes: 20 additions & 0 deletions test/src/test_stdarray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,26 @@ TEST(stdarray, integer)
}
}

TEST(stdarray, const_integer)
{
auto [data, in, out] = zpp::bits::data_in_out();
const std::array a1 = {1,2,3,4};
out(a1).or_throw();

EXPECT_EQ(encode_hex(data),
"01000000"
"02000000"
"03000000"
"04000000");

std::array<int, 4> a2{};
in(a2).or_throw();

for (std::size_t i = 0; i < std::extent_v<decltype(a1)>; ++i) {
EXPECT_EQ(a1[i], a2[i]);
}
}

TEST(stdarray, string)
{
using namespace std::string_literals;
Expand Down
8 changes: 6 additions & 2 deletions zpp_bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -2680,8 +2680,12 @@ class in
{
using type = std::remove_cvref_t<decltype(container)>;
using value_type = typename type::value_type;
constexpr auto is_const = std::is_const_v<
std::remove_reference_t<decltype(container[0])>>;
constexpr auto is_const =
std::is_const_v<std::remove_reference_t<value_type>> ||
requires {
requires std::is_const_v<
std::remove_reference_t<decltype(container[0])>>;
};

if constexpr (!std::is_void_v<SizeType> &&
(requires(type container) { container.resize(1); } ||
Expand Down

0 comments on commit 129a9e3

Please sign in to comment.