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_enable_requires.h>
16#include <daw/daw_move.h>
17
18#include <cstddef>
19#include <iterator>
20#include <memory>
21#include <type_traits>
22
23namespace daw::json {
24 inline namespace DAW_JSON_VER {
25 namespace json_details {
26 DAW_MAKE_REQ_TRAIT2(
27 has_push_back_v, std::declval<T &>( ).push_back( std::declval<U>( ) ) );
28
29#if defined( DAW_HAS_CPP20_CONCEPTS )
30 template<typename Container, typename Value>
31 concept has_insert_end_v = requires( Container & c, Value v ) {
32 c.insert( std::end( c ), v );
33 };
34#else
35 template<typename, typename, typename = void>
36 inline constexpr bool has_insert_end_v = false;
37
38 template<typename Container, typename Value>
39 inline constexpr bool has_insert_end_v<
40 Container, Value,
41 std::void_t<decltype( std::declval<Container &>( ).insert(
42 std::end( std::declval<Container &>( ) ),
43 std::declval<Value>( ) ) )>> = true;
44#endif
45 } // namespace json_details
46 /***
47 * @brief A generic output iterator that can push_back or insert depending
48 * on what the type supports. This is like std::back_inserter
49 * @tparam Container Container object to append to
50 */
51 template<typename Container>
53 using value_type = typename Container::value_type;
55 using pointer = value_type const *;
56 using difference_type = std::ptrdiff_t;
57 using iterator_category = std::output_iterator_tag;
58
59 private:
60 Container *m_container;
61
62 public:
63 explicit constexpr basic_appender( Container &container )
64 : m_container( &container ) {}
65
66 template<typename Value>
67 DAW_ATTRIB_FLATINLINE constexpr void operator( )( Value &&value ) {
68 if constexpr( json_details::has_push_back_v<
69 Container,
70 daw::remove_cvref_t<Value>> ) {
71 m_container->push_back( DAW_FWD( value ) );
72 } else if constexpr( json_details::has_insert_end_v<
73 Container,
74 daw::remove_cvref_t<Value>> ) {
75 m_container->insert( std::end( *m_container ), DAW_FWD( value ) );
76 } else {
77 static_assert(
78 json_details::has_push_back_v<Container,
79 daw::remove_cvref_t<Value>> or
80 json_details::has_insert_end_v<Container,
81 daw::remove_cvref_t<Value>>,
82 "basic_appender requires a Container that either has push_back "
83 "or "
84 "insert with the end iterator as first argument" );
85 }
86 }
87
88 template<typename Value DAW_ENABLEIF(
89 not std::is_same_v<basic_appender, daw::remove_cvref_t<Value>> )>
91 not std::is_same_v<basic_appender, daw::remove_cvref_t<Value>> )
92 DAW_ATTRIB_INLINE constexpr basic_appender &
93 operator=( Value &&v ) {
94 operator( )( DAW_FWD( v ) );
95 return *this;
96 }
97
98 DAW_ATTRIB_INLINE constexpr basic_appender &operator++( ) {
99 return *this;
100 }
101
102 DAW_ATTRIB_INLINE constexpr basic_appender operator++( int ) & {
103 return *this;
104 }
105
106 DAW_ATTRIB_INLINE constexpr basic_appender &operator*( ) {
107 return *this;
108 }
109 };
110 } // namespace DAW_JSON_VER
111} // namespace daw::json
DAW_REQUIRES(daw::json::json_details::is_container_opted_into_json_iostreams_v< Container >) std
An opt in ostream interface for containers of types that have JSON mappings.
Customization point traits.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition version.h:20