10 #include <type_traits>
18 #include <nlohmann/detail/iterators/iterator_traits.hpp>
19 #include <nlohmann/detail/macro_scope.hpp>
40 using char_type = char;
42 JSON_HEDLEY_NON_NULL(2)
54 std::char_traits<char>::int_type get_character() noexcept
56 return std::fgetc(m_file);
77 using char_type = char;
85 is->clear(is->rdstate() & std::ios::eofbit);
90 : is(&i), sb(i.rdbuf())
99 : is(rhs.is), sb(rhs.sb)
108 std::char_traits<char>::int_type get_character()
110 auto res = sb->sbumpc();
112 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
114 is->clear(is->rdstate() | std::ios::eofbit);
121 std::istream* is =
nullptr;
122 std::streambuf* sb =
nullptr;
128 template<
typename IteratorType>
132 using char_type =
typename std::iterator_traits<IteratorType>::value_type;
135 : current(std::move(first)), end(std::move(last))
138 typename std::char_traits<char_type>::int_type get_character()
140 if (JSON_HEDLEY_LIKELY(current != end))
142 auto result = std::char_traits<char_type>::to_int_type(*current);
143 std::advance(current, 1);
147 return std::char_traits<char_type>::eof();
151 IteratorType current;
154 template<
typename BaseInputAdapter,
size_t T>
159 return current == end;
164 template<
typename BaseInputAdapter,
size_t T>
167 template<
typename BaseInputAdapter>
171 static void fill_buffer(BaseInputAdapter& input,
172 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
173 size_t& utf8_bytes_index,
174 size_t& utf8_bytes_filled)
176 utf8_bytes_index = 0;
178 if (JSON_HEDLEY_UNLIKELY(input.empty()))
180 utf8_bytes[0] = std::char_traits<char>::eof();
181 utf8_bytes_filled = 1;
186 const auto wc = input.get_character();
191 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
192 utf8_bytes_filled = 1;
194 else if (wc <= 0x7FF)
196 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xC0u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
197 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
198 utf8_bytes_filled = 2;
200 else if (wc <= 0xFFFF)
202 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xE0u | ((
static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
203 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
204 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
205 utf8_bytes_filled = 3;
207 else if (wc <= 0x10FFFF)
209 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xF0u | ((
static_cast<unsigned int>(wc) >> 18u) & 0x07u));
210 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
211 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
212 utf8_bytes[3] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
213 utf8_bytes_filled = 4;
218 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
219 utf8_bytes_filled = 1;
225 template<
typename BaseInputAdapter>
229 static void fill_buffer(BaseInputAdapter& input,
230 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
231 size_t& utf8_bytes_index,
232 size_t& utf8_bytes_filled)
234 utf8_bytes_index = 0;
236 if (JSON_HEDLEY_UNLIKELY(input.empty()))
238 utf8_bytes[0] = std::char_traits<char>::eof();
239 utf8_bytes_filled = 1;
244 const auto wc = input.get_character();
249 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
250 utf8_bytes_filled = 1;
252 else if (wc <= 0x7FF)
254 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xC0u | ((
static_cast<unsigned int>(wc) >> 6u)));
255 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
256 utf8_bytes_filled = 2;
258 else if (0xD800 > wc || wc >= 0xE000)
260 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xE0u | ((
static_cast<unsigned int>(wc) >> 12u)));
261 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
262 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
263 utf8_bytes_filled = 3;
267 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
269 const auto wc2 =
static_cast<unsigned int>(input.get_character());
270 const auto charcode = 0x10000u + (((
static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
271 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xF0u | (charcode >> 18u));
272 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((charcode >> 12u) & 0x3Fu));
273 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((charcode >> 6u) & 0x3Fu));
274 utf8_bytes[3] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (charcode & 0x3Fu));
275 utf8_bytes_filled = 4;
279 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
280 utf8_bytes_filled = 1;
288 template<
typename BaseInputAdapter,
typename W
ideCharType>
292 using char_type = char;
295 : base_adapter(base) {}
297 typename std::char_traits<char>::int_type get_character() noexcept
300 if (utf8_bytes_index == utf8_bytes_filled)
302 fill_buffer<sizeof(WideCharType)>();
304 JSON_ASSERT(utf8_bytes_filled > 0);
305 JSON_ASSERT(utf8_bytes_index == 0);
309 JSON_ASSERT(utf8_bytes_filled > 0);
310 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
311 return utf8_bytes[utf8_bytes_index++];
315 BaseInputAdapter base_adapter;
324 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
327 std::size_t utf8_bytes_index = 0;
329 std::size_t utf8_bytes_filled = 0;
333 template<
typename IteratorType,
typename Enable =
void>
336 using iterator_type = IteratorType;
337 using char_type =
typename std::iterator_traits<iterator_type>::value_type;
340 static adapter_type create(IteratorType first, IteratorType last)
349 using value_type =
typename std::iterator_traits<T>::value_type;
352 value =
sizeof(value_type) > 1
356 template<
typename IteratorType>
359 using iterator_type = IteratorType;
360 using char_type =
typename std::iterator_traits<iterator_type>::value_type;
364 static adapter_type create(IteratorType first, IteratorType last)
371 template<
typename IteratorType>
375 return factory_type::create(first, last);
382 namespace container_input_adapter_factory_impl
388 template<
typename ContainerType,
typename Enable =
void>
391 template<
typename ContainerType>
393 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
395 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
397 static adapter_type create(
const ContainerType& container)
399 return input_adapter(begin(container), end(container));
405 template<
typename ContainerType>
413 inline file_input_adapter input_adapter(std::FILE* file)
415 return file_input_adapter(file);
418 inline input_stream_adapter input_adapter(std::istream& stream)
420 return input_stream_adapter(stream);
423 inline input_stream_adapter input_adapter(std::istream&& stream)
425 return input_stream_adapter(stream);
429 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
432 template <
typename CharT,
433 typename std::enable_if <
434 std::is_pointer<CharT>::value&&
435 !std::is_array<CharT>::value&&
436 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
437 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
439 contiguous_bytes_input_adapter input_adapter(CharT b)
441 auto length = std::strlen(
reinterpret_cast<const char*
>(b));
442 const auto* ptr =
reinterpret_cast<const char*
>(b);
443 return input_adapter(ptr, ptr + length);
446 template<
typename T, std::
size_t N>
447 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
449 return input_adapter(array, array + N);
458 template <
typename CharT,
459 typename std::enable_if <
460 std::is_pointer<CharT>::value&&
461 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
462 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
465 : ia(
reinterpret_cast<const char*
>(b),
reinterpret_cast<const char*
>(b) + l) {}
467 template<
class IteratorType,
468 typename std::enable_if<
469 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
472 : ia(input_adapter(first, last)) {}
474 contiguous_bytes_input_adapter&& get()
476 return std::move(ia);
480 contiguous_bytes_input_adapter ia;
a class to store JSON values
Definition: json.hpp:177
@ value
the parser finished reading a JSON value
input_format_t
the supported input formats
Definition: input_adapters.hpp:26
namespace for Niels Lohmann
Definition: adl_serializer.hpp:12
Definition: input_adapters.hpp:348