Skip to content
This repository was archived by the owner on Jun 17, 2024. It is now read-only.

Commit 0d455fd

Browse files
Code review comments
1 parent 7d3f18e commit 0d455fd

File tree

7 files changed

+47
-34
lines changed

7 files changed

+47
-34
lines changed

inc/goldfish/common.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,9 @@ namespace goldfish
3838
// We implement our own that forwards to VC++ implementation or is identity depending on the compiler
3939
template <class T> auto make_unchecked_array_iterator(T&& t) { return stdext::make_unchecked_array_iterator(std::forward<T>(t)); }
4040
template <class T> auto get_array_iterator_from_unchecked(T&& t) { return t.base(); }
41+
42+
template <size_t...> struct largest {};
43+
template <size_t x> struct largest<x> { enum { value = x }; };
44+
template <size_t x, size_t y> struct largest<x, y> { enum { value = x > y ? x : y }; };
45+
template <size_t x, size_t y, size_t... z> struct largest<x, y, z...> { enum { value = largest<x, largest<y, z...>::value>::value }; };
4146
}

inc/goldfish/iostream_adaptor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace goldfish { namespace stream
1818
if (m_stream.bad() || (m_stream.fail() && !m_stream.eof()))
1919
throw io_exception{};
2020

21-
return m_stream.gcount();
21+
return static_cast<size_t>(m_stream.gcount());
2222
}
2323
private:
2424
std::istream& m_stream;

inc/goldfish/sax_writer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ namespace goldfish { namespace sax
178178
));
179179
}
180180

181-
template <class T> decltype(serialize_to_goldfish(std::declval<document_writer<inner>&>(), std::declval<T&>())) write(T&& t)
181+
template <class T> decltype(serialize_to_goldfish(std::declval<document_writer<inner>&>(), std::declval<T&&>())) write(T&& t)
182182
{
183183
return serialize_to_goldfish(*this, std::forward<T>(t));
184184
}

inc/goldfish/schema.h

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace goldfish
99
{
1010
namespace details
1111
{
12-
template <size_t N> const_buffer_ref make_key(const char(&text)[N])
12+
template <size_t N> constexpr const_buffer_ref make_key(const char(&text)[N])
1313
{
1414
static_assert(N > 0, "expect null terminated strings");
1515
assert(text[N - 1] == 0);
@@ -22,11 +22,11 @@ namespace goldfish
2222
: m_keys{ std::forward<Args>(args)... }
2323
{}
2424

25-
template <size_t N> optional<size_t> search_text(const char(&text)[N]) const
25+
optional<size_t> search_key(const_buffer_ref key, size_t start_index) const
2626
{
27-
return search_impl({ reinterpret_cast<const byte*>(text), N - 1 }, std::integral_constant<size_t, 0>{});
27+
return search_impl(key, start_index);
2828
}
29-
template <class Document> std::enable_if_t<tags::has_tag<Document, tags::document>::value, optional<size_t>> search(Document& d) const
29+
template <class Document> std::enable_if_t<tags::has_tag<Document, tags::document>::value, optional<size_t>> search(Document& d, size_t start_index) const
3030
{
3131
return d.visit(first_match(
3232
[&](auto& text, tags::string) -> optional<size_t>
@@ -36,7 +36,7 @@ namespace goldfish
3636
if (stream::seek(text, std::numeric_limits<uint64_t>::max()) != 0)
3737
return nullopt;
3838

39-
return search_impl({ buffer, length }, std::integral_constant<size_t, 0>{});
39+
return search_impl({ buffer, length }, start_index);
4040
},
4141
[&](auto&, auto) -> optional<size_t>
4242
{
@@ -45,9 +45,9 @@ namespace goldfish
4545
}));
4646
}
4747
private:
48-
template <size_t cur_index> optional<size_t> search_impl(const_buffer_ref text, std::integral_constant<size_t, cur_index>) const
48+
optional<size_t> search_impl(const_buffer_ref text, size_t start_index) const
4949
{
50-
auto it = std::find_if(m_keys.begin(), m_keys.end(), [&](auto&& key)
50+
auto it = std::find_if(m_keys.begin() + start_index, m_keys.end(), [&](auto&& key)
5151
{
5252
return key.size() == text.size() && std::equal(key.begin(), key.end(), make_unchecked_array_iterator(text.begin()));
5353
});
@@ -60,9 +60,12 @@ namespace goldfish
6060
std::array<const_buffer_ref, N> m_keys;
6161
};
6262
}
63-
template <class... T> auto make_schema(T&&... keys)
63+
template <class... T> constexpr auto make_schema(T&&... keys)
6464
{
65-
return details::schema<sizeof...(T), 1024>(details::make_key(std::forward<T>(keys))...);
65+
return details::schema<
66+
sizeof...(T),
67+
largest<sizeof(T)...>::value - 1
68+
>(details::make_key(std::forward<T>(keys))...);
6669
}
6770

6871
template <class Map, class Schema> class map_with_schema
@@ -72,8 +75,14 @@ namespace goldfish
7275
: m_map(std::move(map))
7376
, m_schema(schema)
7477
{}
75-
optional<decltype(std::declval<Map>().read_value())> read_value_by_index(size_t index)
78+
optional<decltype(std::declval<Map>().read_value())> read_by_schema_index(size_t index)
7679
{
80+
#ifndef NDEBUG
81+
if (m_last_queried_index)
82+
assert(*m_last_queried_index < index);
83+
m_last_queried_index = index;
84+
#endif
85+
7786
if (m_index > index)
7887
return nullopt;
7988

@@ -89,7 +98,7 @@ namespace goldfish
8998

9099
while (auto key = m_map.read_key())
91100
{
92-
if (auto new_index = m_schema.search(*key))
101+
if (auto new_index = m_schema.search(*key, m_index /*start_index*/))
93102
{
94103
m_index = *new_index;
95104
}
@@ -116,17 +125,17 @@ namespace goldfish
116125
}
117126
else
118127
{
119-
// We found a key that is still before us, skip the value and keep searching
128+
// We found a key that is still before the one we are looking for, skip the value and keep searching
120129
seek_to_end(m_map.read_value());
121130
}
122131
}
123132

124133
return nullopt;
125134
}
126-
template <size_t N> auto read_value(const char(&text)[N])
135+
template <class Key> auto read(Key&& key)
127136
{
128-
if (auto index = m_schema.search_text(text))
129-
return read_value_by_index(*index);
137+
if (auto index = m_schema.search_key(details::make_key(std::forward<Key>(key)), 0 /*start_index*/))
138+
return read_by_schema_index(*index);
130139
else
131140
std::terminate();
132141
}
@@ -145,6 +154,10 @@ namespace goldfish
145154
Schema m_schema;
146155
size_t m_index = 0;
147156
bool m_on_value = false;
157+
158+
#ifndef NDEBUG
159+
optional<size_t> m_last_queried_index;
160+
#endif
148161
};
149162
template <class Map, class Schema> map_with_schema<std::decay_t<Map>, Schema> apply_schema(Map&& map, const Schema& s)
150163
{

inc/goldfish/variant.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ namespace goldfish
2323

2424
template <class T> struct negate { enum { value = !T::value }; };
2525

26-
template <size_t...> struct largest {};
27-
template <size_t x> struct largest<x> { enum { value = x }; };
28-
template <size_t x, size_t y> struct largest<x, y> { enum { value = x > y ? x : y }; };
29-
template <size_t x, size_t y, size_t... z> struct largest<x, y, z...> { enum { value = largest<x, largest<y, z...>::value>::value }; };
30-
3126
template <class T, class dummy = uint8_t> struct with_padding
3227
{
3328
T data;

tests/schema.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace goldfish
99
{
1010
auto map = apply_schema(json::read(stream::read_string_non_owning("{}")).as_map(), make_schema("10", "20", "30"));
1111

12-
test(map.read_value_by_index(0) == nullopt);
12+
test(map.read_by_schema_index(0) == nullopt);
1313

1414
seek_to_end(map);
1515
}
@@ -21,24 +21,24 @@ namespace goldfish
2121
make_schema("10", "20", "30", "40", "50", "60", "70", "80", "90"));
2222

2323
// Reading the very first key
24-
test(dom::load_in_memory(*map.read_value_by_index(0)) == 1ull);
24+
test(dom::load_in_memory(*map.read_by_schema_index(0)) == 1ull);
2525

2626
// Reading index 1 will force to skip the entry 15 and go to entry 40
27-
test(map.read_value_by_index(1) == nullopt);
27+
test(map.read_by_schema_index(1) == nullopt);
2828

2929
// Reading index 2 will fail because we are already at index 3 of the schema
30-
test(map.read_value_by_index(2) == nullopt);
30+
test(map.read_by_schema_index(2) == nullopt);
3131

3232
// We are currently at index 3 but are asking for index 5, that should skip the pair 40:3 and 50:4 and find 60:5
33-
test(dom::load_in_memory(*map.read_value_by_index(5)) == 5ull);
33+
test(dom::load_in_memory(*map.read_by_schema_index(5)) == 5ull);
3434

3535
// We ask for index 6, which brings to index 7 (and returns null)
3636
// Asking for index 7 should return the value on an already read key
37-
test(map.read_value_by_index(6) == nullopt);
38-
test(dom::load_in_memory(*map.read_value_by_index(7)) == 6ull);
37+
test(map.read_by_schema_index(6) == nullopt);
38+
test(dom::load_in_memory(*map.read_by_schema_index(7)) == 6ull);
3939

4040
// finally, ask for index 8, but we reach the end of the map before we find it
41-
test(map.read_value_by_index(8) == nullopt);
41+
test(map.read_by_schema_index(8) == nullopt);
4242

4343
seek_to_end(map);
4444
}
@@ -49,14 +49,14 @@ namespace goldfish
4949
json::read(stream::read_string_non_owning("{\"20\":1}")).as_map(),
5050
make_schema("10", "20"));
5151

52-
test(map.read_value_by_index(0) == nullopt);
52+
test(map.read_by_schema_index(0) == nullopt);
5353
seek_to_end(map);
5454
}
5555

5656
TEST_CASE(test_filtered_map_by_value)
5757
{
5858
auto map = apply_schema(json::read(stream::read_string_non_owning("{\"B\":1}")).as_map(), make_schema("A", "B"));
59-
test(dom::load_in_memory(*map.read_value("B")) == 1ull);
59+
test(dom::load_in_memory(*map.read("B")) == 1ull);
6060
seek_to_end(map);
6161
}
6262
}

tests/tutorial.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ TEST_CASE(parse_complex)
5454
while (auto entry_document = document.read())
5555
{
5656
auto entry = entry_document->as_map("name", "friends");
57-
output << entry.read_value("name").value().as_string() << " has the following friends: ";
57+
output << entry.read("name").value().as_string() << " has the following friends: ";
5858

59-
auto friends = entry.read_value("friends").value().as_array();
59+
auto friends = entry.read("friends").value().as_array();
6060
while (auto friend_name = friends.read())
6161
output << friend_name->as_string() << " ";
6262

0 commit comments

Comments
 (0)