Skip to content

Commit 1d59774

Browse files
Fix char_traits deprecation warning (#4179)
1 parent f56c6e2 commit 1d59774

File tree

5 files changed

+172
-50
lines changed

5 files changed

+172
-50
lines changed

include/nlohmann/detail/input/binary_reader.hpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class binary_reader
7272
using binary_t = typename BasicJsonType::binary_t;
7373
using json_sax_t = SAX;
7474
using char_type = typename InputAdapterType::char_type;
75-
using char_int_type = typename std::char_traits<char_type>::int_type;
75+
using char_int_type = typename char_traits<char_type>::int_type;
7676

7777
public:
7878
/*!
@@ -145,7 +145,7 @@ class binary_reader
145145
get();
146146
}
147147

148-
if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
148+
if (JSON_HEDLEY_UNLIKELY(current != char_traits<char_type>::eof()))
149149
{
150150
return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
151151
exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
@@ -228,7 +228,7 @@ class binary_reader
228228
exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
229229
}
230230

231-
return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
231+
return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != char_traits<char_type>::eof();
232232
}
233233

234234
/*!
@@ -422,7 +422,7 @@ class binary_reader
422422
switch (get_char ? get() : current)
423423
{
424424
// EOF
425-
case std::char_traits<char_type>::eof():
425+
case char_traits<char_type>::eof():
426426
return unexpect_eof(input_format_t::cbor, "value");
427427

428428
// Integer 0x00..0x17 (0..23)
@@ -1197,7 +1197,7 @@ class binary_reader
11971197
switch (get())
11981198
{
11991199
// EOF
1200-
case std::char_traits<char_type>::eof():
1200+
case char_traits<char_type>::eof():
12011201
return unexpect_eof(input_format_t::msgpack, "value");
12021202

12031203
// positive fixint
@@ -2299,7 +2299,7 @@ class binary_reader
22992299
{
23002300
switch (prefix)
23012301
{
2302-
case std::char_traits<char_type>::eof(): // EOF
2302+
case char_traits<char_type>::eof(): // EOF
23032303
return unexpect_eof(input_format, "value");
23042304

23052305
case 'T': // true
@@ -2744,7 +2744,7 @@ class binary_reader
27442744
27452745
This function provides the interface to the used input adapter. It does
27462746
not throw in case the input reached EOF, but returns a -'ve valued
2747-
`std::char_traits<char_type>::eof()` in that case.
2747+
`char_traits<char_type>::eof()` in that case.
27482748
27492749
@return character read from the input
27502750
*/
@@ -2886,7 +2886,7 @@ class binary_reader
28862886
JSON_HEDLEY_NON_NULL(3)
28872887
bool unexpect_eof(const input_format_t format, const char* context) const
28882888
{
2889-
if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
2889+
if (JSON_HEDLEY_UNLIKELY(current == char_traits<char_type>::eof()))
28902890
{
28912891
return sax->parse_error(chars_read, "<end of file>",
28922892
parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
@@ -2953,7 +2953,7 @@ class binary_reader
29532953
InputAdapterType ia;
29542954

29552955
/// the current character
2956-
char_int_type current = std::char_traits<char_type>::eof();
2956+
char_int_type current = char_traits<char_type>::eof();
29572957

29582958
/// the number of characters read
29592959
std::size_t chars_read = 0;

include/nlohmann/detail/input/input_adapters.hpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include <nlohmann/detail/iterators/iterator_traits.hpp>
2727
#include <nlohmann/detail/macro_scope.hpp>
28+
#include <nlohmann/detail/meta/type_traits.hpp>
2829

2930
NLOHMANN_JSON_NAMESPACE_BEGIN
3031
namespace detail
@@ -144,16 +145,16 @@ class iterator_input_adapter
144145
: current(std::move(first)), end(std::move(last))
145146
{}
146147

147-
typename std::char_traits<char_type>::int_type get_character()
148+
typename char_traits<char_type>::int_type get_character()
148149
{
149150
if (JSON_HEDLEY_LIKELY(current != end))
150151
{
151-
auto result = std::char_traits<char_type>::to_int_type(*current);
152+
auto result = char_traits<char_type>::to_int_type(*current);
152153
std::advance(current, 1);
153154
return result;
154155
}
155156

156-
return std::char_traits<char_type>::eof();
157+
return char_traits<char_type>::eof();
157158
}
158159

159160
private:

include/nlohmann/detail/input/lexer.hpp

+14-13
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <nlohmann/detail/input/input_adapters.hpp>
2222
#include <nlohmann/detail/input/position_t.hpp>
2323
#include <nlohmann/detail/macro_scope.hpp>
24+
#include <nlohmann/detail/meta/type_traits.hpp>
2425

2526
NLOHMANN_JSON_NAMESPACE_BEGIN
2627
namespace detail
@@ -115,7 +116,7 @@ class lexer : public lexer_base<BasicJsonType>
115116
using number_float_t = typename BasicJsonType::number_float_t;
116117
using string_t = typename BasicJsonType::string_t;
117118
using char_type = typename InputAdapterType::char_type;
118-
using char_int_type = typename std::char_traits<char_type>::int_type;
119+
using char_int_type = typename char_traits<char_type>::int_type;
119120

120121
public:
121122
using token_type = typename lexer_base<BasicJsonType>::token_type;
@@ -265,7 +266,7 @@ class lexer : public lexer_base<BasicJsonType>
265266
switch (get())
266267
{
267268
// end of file while parsing string
268-
case std::char_traits<char_type>::eof():
269+
case char_traits<char_type>::eof():
269270
{
270271
error_message = "invalid string: missing closing quote";
271272
return token_type::parse_error;
@@ -854,7 +855,7 @@ class lexer : public lexer_base<BasicJsonType>
854855
{
855856
case '\n':
856857
case '\r':
857-
case std::char_traits<char_type>::eof():
858+
case char_traits<char_type>::eof():
858859
case '\0':
859860
return true;
860861

@@ -871,7 +872,7 @@ class lexer : public lexer_base<BasicJsonType>
871872
{
872873
switch (get())
873874
{
874-
case std::char_traits<char_type>::eof():
875+
case char_traits<char_type>::eof():
875876
case '\0':
876877
{
877878
error_message = "invalid comment; missing closing '*/'";
@@ -1300,10 +1301,10 @@ class lexer : public lexer_base<BasicJsonType>
13001301
token_type scan_literal(const char_type* literal_text, const std::size_t length,
13011302
token_type return_type)
13021303
{
1303-
JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
1304+
JSON_ASSERT(char_traits<char_type>::to_char_type(current) == literal_text[0]);
13041305
for (std::size_t i = 1; i < length; ++i)
13051306
{
1306-
if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
1307+
if (JSON_HEDLEY_UNLIKELY(char_traits<char_type>::to_char_type(get()) != literal_text[i]))
13071308
{
13081309
error_message = "invalid literal";
13091310
return token_type::parse_error;
@@ -1321,15 +1322,15 @@ class lexer : public lexer_base<BasicJsonType>
13211322
{
13221323
token_buffer.clear();
13231324
token_string.clear();
1324-
token_string.push_back(std::char_traits<char_type>::to_char_type(current));
1325+
token_string.push_back(char_traits<char_type>::to_char_type(current));
13251326
}
13261327

13271328
/*
13281329
@brief get next character from the input
13291330
13301331
This function provides the interface to the used input adapter. It does
13311332
not throw in case the input reached EOF, but returns a
1332-
`std::char_traits<char>::eof()` in that case. Stores the scanned characters
1333+
`char_traits<char>::eof()` in that case. Stores the scanned characters
13331334
for use in error messages.
13341335
13351336
@return character read from the input
@@ -1349,9 +1350,9 @@ class lexer : public lexer_base<BasicJsonType>
13491350
current = ia.get_character();
13501351
}
13511352

1352-
if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
1353+
if (JSON_HEDLEY_LIKELY(current != char_traits<char_type>::eof()))
13531354
{
1354-
token_string.push_back(std::char_traits<char_type>::to_char_type(current));
1355+
token_string.push_back(char_traits<char_type>::to_char_type(current));
13551356
}
13561357

13571358
if (current == '\n')
@@ -1390,7 +1391,7 @@ class lexer : public lexer_base<BasicJsonType>
13901391
--position.chars_read_current_line;
13911392
}
13921393

1393-
if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
1394+
if (JSON_HEDLEY_LIKELY(current != char_traits<char_type>::eof()))
13941395
{
13951396
JSON_ASSERT(!token_string.empty());
13961397
token_string.pop_back();
@@ -1584,7 +1585,7 @@ class lexer : public lexer_base<BasicJsonType>
15841585
// end of input (the null byte is needed when parsing from
15851586
// string literals)
15861587
case '\0':
1587-
case std::char_traits<char_type>::eof():
1588+
case char_traits<char_type>::eof():
15881589
return token_type::end_of_input;
15891590

15901591
// error
@@ -1602,7 +1603,7 @@ class lexer : public lexer_base<BasicJsonType>
16021603
const bool ignore_comments = false;
16031604

16041605
/// the current character
1605-
char_int_type current = std::char_traits<char_type>::eof();
1606+
char_int_type current = char_traits<char_type>::eof();
16061607

16071608
/// whether the next get() call should just return current
16081609
bool next_unget = false;

include/nlohmann/detail/meta/type_traits.hpp

+58
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
1313
#include <utility> // declval
1414
#include <tuple> // tuple
15+
#include <string> // char_traits
1516

1617
#include <nlohmann/detail/iterators/iterator_traits.hpp>
1718
#include <nlohmann/detail/macro_scope.hpp>
@@ -181,6 +182,63 @@ struct actual_object_comparator
181182
template<typename BasicJsonType>
182183
using actual_object_comparator_t = typename actual_object_comparator<BasicJsonType>::type;
183184

185+
/////////////////
186+
// char_traits //
187+
/////////////////
188+
189+
// Primary template of char_traits calls std char_traits
190+
template<typename T>
191+
struct char_traits : std::char_traits<T>
192+
{};
193+
194+
// Explicitly define char traits for unsigned char since it is not standard
195+
template<>
196+
struct char_traits<unsigned char> : std::char_traits<char>
197+
{
198+
using char_type = unsigned char;
199+
using int_type = uint64_t;
200+
201+
// Redefine to_int_type function
202+
static int_type to_int_type(char_type c) noexcept
203+
{
204+
return static_cast<int_type>(c);
205+
}
206+
207+
static char_type to_char_type(int_type i) noexcept
208+
{
209+
return static_cast<char_type>(i);
210+
}
211+
212+
static constexpr int_type eof() noexcept
213+
{
214+
return static_cast<int_type>(EOF);
215+
}
216+
};
217+
218+
// Explicitly define char traits for signed char since it is not standard
219+
template<>
220+
struct char_traits<signed char> : std::char_traits<char>
221+
{
222+
using char_type = signed char;
223+
using int_type = uint64_t;
224+
225+
// Redefine to_int_type function
226+
static int_type to_int_type(char_type c) noexcept
227+
{
228+
return static_cast<int_type>(c);
229+
}
230+
231+
static char_type to_char_type(int_type i) noexcept
232+
{
233+
return static_cast<char_type>(i);
234+
}
235+
236+
static constexpr int_type eof() noexcept
237+
{
238+
return static_cast<int_type>(EOF);
239+
}
240+
};
241+
184242
///////////////////
185243
// is_ functions //
186244
///////////////////

0 commit comments

Comments
 (0)