DAW JSON Link
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 
22 namespace 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>
44  struct basic_appender {
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(...)
Customization point traits.
DAW_JSON_REQUIRES(boost::describe::has_describe_members< T >::value and use_boost_describe_v< T >) struct json_data_contract< T >
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:25