12 #include <type_traits>
15 #include <nlohmann/detail/iterators/iterator_traits.hpp>
16 #include <nlohmann/detail/macro_scope.hpp>
36 using char_type = char;
38 JSON_HEDLEY_NON_NULL(2)
49 std::char_traits<char>::int_type get_character() noexcept
51 return std::fgetc(m_file);
72 using char_type = char;
80 is->clear(is->rdstate() & std::ios::eofbit);
85 : is(&i), sb(i.rdbuf())
102 std::char_traits<char>::int_type get_character()
104 auto res = sb->sbumpc();
106 if (JSON_HEDLEY_UNLIKELY(res == EOF))
108 is->clear(is->rdstate() | std::ios::eofbit);
115 std::istream* is =
nullptr;
116 std::streambuf* sb =
nullptr;
121 template<
typename IteratorType>
125 using char_type =
typename std::iterator_traits<IteratorType>::value_type;
128 : current(std::move(first)), end(std::move(last)) {}
130 typename std::char_traits<char_type>::int_type get_character()
132 if (JSON_HEDLEY_LIKELY(current != end))
134 auto result = std::char_traits<char_type>::to_int_type(*current);
135 std::advance(current, 1);
140 return std::char_traits<char_type>::eof();
145 IteratorType current;
148 template<
typename BaseInputAdapter,
size_t T>
153 return current == end;
159 template<
typename BaseInputAdapter,
size_t T>
162 template<
typename BaseInputAdapter>
166 static void fill_buffer(BaseInputAdapter& input,
167 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
168 size_t& utf8_bytes_index,
169 size_t& utf8_bytes_filled)
171 utf8_bytes_index = 0;
173 if (JSON_HEDLEY_UNLIKELY(input.empty()))
175 utf8_bytes[0] = std::char_traits<char>::eof();
176 utf8_bytes_filled = 1;
181 const auto wc = input.get_character();
186 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
187 utf8_bytes_filled = 1;
189 else if (wc <= 0x7FF)
191 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xC0u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
192 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
193 utf8_bytes_filled = 2;
195 else if (wc <= 0xFFFF)
197 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xE0u | ((
static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
198 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
199 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
200 utf8_bytes_filled = 3;
202 else if (wc <= 0x10FFFF)
204 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xF0u | ((
static_cast<unsigned int>(wc) >> 18u) & 0x07u));
205 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
206 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
207 utf8_bytes[3] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
208 utf8_bytes_filled = 4;
213 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
214 utf8_bytes_filled = 1;
220 template<
typename BaseInputAdapter>
224 static void fill_buffer(BaseInputAdapter& input,
225 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
226 size_t& utf8_bytes_index,
227 size_t& utf8_bytes_filled)
229 utf8_bytes_index = 0;
231 if (JSON_HEDLEY_UNLIKELY(input.empty()))
233 utf8_bytes[0] = std::char_traits<char>::eof();
234 utf8_bytes_filled = 1;
239 const auto wc = input.get_character();
244 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
245 utf8_bytes_filled = 1;
247 else if (wc <= 0x7FF)
249 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xC0u | ((
static_cast<unsigned int>(wc) >> 6u)));
250 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
251 utf8_bytes_filled = 2;
253 else if (0xD800 > wc || wc >= 0xE000)
255 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xE0u | ((
static_cast<unsigned int>(wc) >> 12u)));
256 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
257 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
258 utf8_bytes_filled = 3;
262 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
264 const auto wc2 =
static_cast<unsigned int>(input.get_character());
265 const auto charcode = 0x10000u + (((
static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
266 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xF0u | (charcode >> 18u));
267 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((charcode >> 12u) & 0x3Fu));
268 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((charcode >> 6u) & 0x3Fu));
269 utf8_bytes[3] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (charcode & 0x3Fu));
270 utf8_bytes_filled = 4;
274 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
275 utf8_bytes_filled = 1;
283 template<
typename BaseInputAdapter,
typename W
ideCharType>
287 using char_type = char;
290 : base_adapter(base) {}
292 typename std::char_traits<char>::int_type get_character() noexcept
295 if (utf8_bytes_index == utf8_bytes_filled)
297 fill_buffer<sizeof(WideCharType)>();
299 JSON_ASSERT(utf8_bytes_filled > 0);
300 JSON_ASSERT(utf8_bytes_index == 0);
304 JSON_ASSERT(utf8_bytes_filled > 0);
305 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
306 return utf8_bytes[utf8_bytes_index++];
310 BaseInputAdapter base_adapter;
319 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
322 std::size_t utf8_bytes_index = 0;
324 std::size_t utf8_bytes_filled = 0;
328 template<
typename IteratorType,
typename Enable =
void>
331 using iterator_type = IteratorType;
332 using char_type =
typename std::iterator_traits<iterator_type>::value_type;
335 static adapter_type create(IteratorType first, IteratorType last)
344 using value_type =
typename std::iterator_traits<T>::value_type;
347 value =
sizeof(value_type) > 1
351 template<
typename IteratorType>
354 using iterator_type = IteratorType;
355 using char_type =
typename std::iterator_traits<iterator_type>::value_type;
359 static adapter_type create(IteratorType first, IteratorType last)
366 template<
typename IteratorType>
370 return factory_type::create(first, last);
374 template<
typename ContainerType>
375 auto input_adapter(
const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
381 return input_adapter(begin(container), end(container));
385 inline file_input_adapter input_adapter(std::FILE* file)
387 return file_input_adapter(file);
390 inline input_stream_adapter input_adapter(std::istream& stream)
392 return input_stream_adapter(stream);
395 inline input_stream_adapter input_adapter(std::istream&& stream)
397 return input_stream_adapter(stream);
400 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
403 template <
typename CharT,
404 typename std::enable_if <
405 std::is_pointer<CharT>::value&&
406 !std::is_array<CharT>::value&&
407 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
408 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
410 contiguous_bytes_input_adapter input_adapter(CharT b)
412 auto length = std::strlen(
reinterpret_cast<const char*
>(b));
413 const auto* ptr =
reinterpret_cast<const char*
>(b);
414 return input_adapter(ptr, ptr + length);
417 template<
typename T, std::
size_t N>
418 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
420 return input_adapter(array, array + N);
429 template <
typename CharT,
430 typename std::enable_if <
431 std::is_pointer<CharT>::value&&
432 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
433 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
436 : ia(
reinterpret_cast<const char*
>(b),
reinterpret_cast<const char*
>(b) + l) {}
438 template<
class IteratorType,
439 typename std::enable_if<
440 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
443 : ia(input_adapter(first, last)) {}
445 contiguous_bytes_input_adapter&& get()
447 return std::move(ia);
451 contiguous_bytes_input_adapter ia;
a class to store JSON values
Definition: json.hpp:170
@ value
the parser finished reading a JSON value
input_format_t
the supported input formats
Definition: input_adapters.hpp:23
namespace for Niels Lohmann
Definition: adl_serializer.hpp:9
Definition: input_adapters.hpp:343