@@ -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