Skip to content

Commit b7397fe

Browse files
authored
Merge pull request #288 from OutpostUniverse/cleanupStreamReadMethodGuards
Cleanup stream read method guards
2 parents f6db1e2 + 95ae9a6 commit b7397fe

1 file changed

Lines changed: 30 additions & 42 deletions

File tree

src/Stream/Reader.h

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -34,65 +34,53 @@ namespace Stream
3434

3535
// Trivially copyable data types
3636
template<typename T>
37-
inline std::enable_if_t<std::is_trivially_copyable<T>::value> Read(T& object) {
37+
inline
38+
std::enable_if_t<std::is_trivially_copyable<T>::value>
39+
Read(T& object) {
3840
ReadImplementation(&object, sizeof(object));
3941
}
4042

41-
// Vector data types
42-
// Reads into entire length of passed vector. Call vector.resize(vectorSize) before
43-
// passing vector into this function to ensure proper vector size is read
44-
template<typename T, typename A>
45-
inline void Read(std::vector<T, A>& vector) {
46-
// Size calculation can't possibly overflow since the vector size necessarily fits in memory
47-
ReadImplementation(vector.data(), vector.size() * sizeof(T));
48-
}
49-
50-
// Size prefixed vector data types
51-
// Ex: Read<uint32_t>(vector); // Read 32-bit vector size, allocate space, then read vector data
52-
template<typename SizeType, typename T, typename A>
53-
void Read(std::vector<T, A>& vector) {
54-
SizeType vectorSize;
55-
Read(vectorSize);
56-
// This check is trivially false for unsigned SizeType
57-
if (vectorSize < 0) {
58-
throw std::runtime_error("Vector's size may not be a negative number");
59-
}
60-
// This check may be trivially false when SizeType is much smaller than max vector size
61-
if (vectorSize > vector.max_size()) {
62-
throw std::runtime_error("Vector's size is too big to fit in memory");
63-
}
64-
vector.clear();
65-
vector.resize(vectorSize);
66-
Read(vector);
43+
// Non-trivial contiguous container of trivially copyable data types
44+
// Reads into entire length of passed container. Call container.resize(size) before
45+
// passing container into this function to ensure proper container size is read
46+
template<typename T>
47+
inline
48+
std::enable_if_t<
49+
!std::is_trivially_copyable<T>::value &&
50+
std::is_trivially_copyable<typename T::value_type>::value
51+
>
52+
Read(T& container) {
53+
// Size calculation can't possibly overflow since the container size necessarily fits in memory
54+
ReadImplementation(container.data(), container.size() * sizeof(typename T::value_type));
6755
}
6856

6957
// String data types
7058
// Reads into entire length of passed string. Call string.resize(stringSize) before
7159
// passing string into this function to ensure proper string size is read
60+
// Note: C++17 added a non-const overload of `string.data()`, needed to collapse this with the above
7261
template<typename CharT, typename Traits, typename Allocator>
7362
void Read(std::basic_string<CharT, Traits, Allocator>& string) {
7463
// Size calculation can't possibly overflow since the string size necessarily fits in memory
7564
Read(&string[0], string.size() * sizeof(CharT));
7665
}
7766

78-
// Size prefixed string data types
79-
// Ex: Read<uint32_t>(string); // Read 32-bit string length, allocate space, then read string data
80-
template<typename SizeType, typename CharT, typename Traits, typename Allocator>
81-
void Read(std::basic_string<CharT, Traits, Allocator>& string) {
82-
SizeType stringSize;
83-
Read(stringSize);
67+
// Size prefixed container data types
68+
// Ex: Read<uint32_t>(vector); // Read 32-bit vector size, allocate space, then read vector data
69+
template<typename SizeType, typename T>
70+
void Read(T& container) {
71+
SizeType containerSize;
72+
Read(containerSize);
8473
// This check is trivially false for unsigned SizeType
85-
if (stringSize < 0) {
86-
throw std::runtime_error("String's size may not be a negative number");
74+
if (containerSize < 0) {
75+
throw std::runtime_error("Container's size may not be a negative number");
8776
}
88-
// This check may be trivially false when SizeType is too small to overflow string size for CharT types
89-
if (stringSize > string.max_size()) {
90-
throw std::runtime_error("String's size is too big to fit in memory");
77+
// This check may be trivially false when SizeType is much smaller than max container size
78+
if (containerSize > container.max_size()) {
79+
throw std::runtime_error("Container's size is too big to fit in memory");
9180
}
92-
93-
string.clear();
94-
string.resize(stringSize);
95-
Read(string);
81+
container.clear();
82+
container.resize(containerSize);
83+
Read(container);
9684
}
9785
};
9886
}

0 commit comments

Comments
 (0)