DAW JSON Link
Loading...
Searching...
No Matches
daw_json_container_appender.h
Go to the documentation of this file.
1// Copyright (c) Darrell Wright
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
5//
6// Official repository: https://github.com/beached/daw_json_link.h
7//
8
9#pragma once
10
11#include "version.h"
12
13#include <daw/cpp_17.h>
14#include <daw/daw_attributes.h>
15#include <daw/daw_move.h>
16
17#include <cstddef>
18#include <iterator>
19#include <memory>
20#include <type_traits>
21
22namespace daw::json {
23 inline namespace DAW_JSON_VER {
24 namespace json_details {
25 DAW_MAKE_REQ_TRAIT2(
26 has_push_back_v, std::declval<T &>( ).push_back( std::declval<U>( ) ) );
27
28 template<typename, typename, typename = void>
29 inline constexpr bool has_insert_end_v = false;
30
31 template<typename Container, typename Value>
32 inline constexpr bool has_insert_end_v<
33 Container, Value,
34 std::void_t<decltype( std::declval<Container &>( ).insert(
35 std::end( std::declval<Container &>( ) ),
36 std::declval<Value>( ) ) )>> = true;
37 } // namespace json_details
38 /***
39 * @brief A generic output iterator that can push_back or insert depending
40 * on what the type supports. This is like std::back_inserter
41 * @tparam Container Container object to append to
42 */
43 template<typename Container>
45 using value_type = typename Container::value_type;
47 using pointer = value_type const *;
48 using difference_type = std::ptrdiff_t;
49 using iterator_category = std::output_iterator_tag;
50
51 private:
52 Container *m_container;
53
54 public:
55 explicit inline constexpr basic_appender( Container &container )
56 : m_container( &container ) {}
57
58 template<typename Value>
59 DAW_ATTRIB_FLATINLINE inline constexpr void operator( )( Value &&value ) {
60 if constexpr( json_details::has_push_back_v<
61 Container, daw::remove_cvref_t<Value>> ) {
62 m_container->push_back( DAW_FWD( value ) );
63 } else if constexpr( json_details::has_insert_end_v<
64 Container, daw::remove_cvref_t<Value>> ) {
65 m_container->insert( std::end( *m_container ), DAW_FWD( value ) );
66 } else {
67 static_assert(
68 json_details::has_push_back_v<Container,
69 daw::remove_cvref_t<Value>> or
70 json_details::has_insert_end_v<Container,
71 daw::remove_cvref_t<Value>>,
72 "basic_appender requires a Container that either has push_back "
73 "or "
74 "insert with the end iterator as first argument" );
75 }
76 }
77
78 template<typename Value DAW_JSON_ENABLEIF(
79 not std::is_same_v<basic_appender, daw::remove_cvref_t<Value>> )>
81 not std::is_same_v<basic_appender, daw::remove_cvref_t<Value>> )
82 DAW_ATTRIB_INLINE constexpr basic_appender &
83 operator=( Value &&v ) {
84 operator( )( DAW_FWD( v ) );
85 return *this;
86 }
87
88 DAW_ATTRIB_INLINE constexpr basic_appender &operator++( ) {
89 return *this;
90 }
91
92 DAW_ATTRIB_INLINE constexpr basic_appender operator++( int ) & {
93 return *this;
94 }
95
96 DAW_ATTRIB_INLINE constexpr basic_appender &operator*( ) {
97 return *this;
98 }
99 };
100 } // namespace DAW_JSON_VER
101} // namespace daw::json
#define DAW_JSON_ENABLEIF(...)
#define DAW_JSON_REQUIRES(...)
Customization point traits.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition version.h:20