arg_router  1.4.0
C++ command line argument parsing and routing
dynamic_string_view.hpp
1 // Copyright (C) 2023 by Camden Mannett.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
4 
5 #pragma once
6 
7 #include "arg_router/basic_types.hpp"
8 
9 #include <string_view>
10 
11 namespace arg_router::utility
12 {
18 // NOLINTNEXTLINE(hicpp-special-member-functions)
20 {
21 public:
22  using value_type = string::value_type;
23  using allocator_type = string::allocator_type;
24  using size_type = string::size_type;
25  using difference_type = string::difference_type;
26  using const_reference = string::const_reference;
27  using const_pointer = string::const_pointer;
28  using const_iterator = std::string_view::const_iterator;
29 
35  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
36  dynamic_string_view(std::string_view sv = {}) noexcept : view_{sv} {}
37 
43  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
44  dynamic_string_view(const char* str) noexcept : view_{str} {}
45 
51  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
52  dynamic_string_view(string&& str) noexcept : str_{std::move(str)} { update_view(); }
53 
60  dynamic_string_view(const dynamic_string_view& other) : view_{other.view_}, str_{other.str_}
61  {
62  if (!str_.empty()) {
63  update_view();
64  }
65  }
66 
72  {
73  swap(*this, other);
74  }
75 
82  {
83  swap(*this, other);
84  return *this;
85  }
86 
92  {
93  if (str_.empty()) {
94  str_ = view_;
95  update_view();
96  }
97  }
98 
103  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
104  [[nodiscard]] operator std::string_view() const noexcept { return view_; }
105 
111  [[nodiscard]] bool operator==(const dynamic_string_view& other) const noexcept
112  {
113  return view_ == other.view_;
114  }
115 
121  [[nodiscard]] bool operator!=(const dynamic_string_view& other) const noexcept
122  {
123  return !(*this == other);
124  }
125 
132  template <typename T,
133  typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, dynamic_string_view>>>
135  {
137  str_ += std::forward<T>(other);
138  update_view();
139 
140  return *this;
141  }
142 
144  {
146  str_ += other.view_;
147  update_view();
148 
149  return *this;
150  }
151 
153  [[nodiscard]] size_type size() const noexcept { return view_.size(); }
155  [[nodiscard]] size_type internal_storage_size() const noexcept { return str_.size(); }
157  [[nodiscard]] bool empty() const noexcept { return view_.empty(); }
158 
160  [[nodiscard]] const_iterator begin() const noexcept { return view_.begin(); }
162  [[nodiscard]] const_iterator end() const noexcept { return view_.end(); }
163 
170  {
171  using std::swap;
172 
173  swap(a.view_, b.view_);
174  swap(a.str_, b.str_);
175 
176  if (!a.str_.empty()) {
177  a.update_view();
178  }
179  if (!b.str_.empty()) {
180  b.update_view();
181  }
182  }
183 
184 private:
185  void update_view() { view_ = str_; }
186 
187  std::string_view view_;
188  string str_;
189 };
190 
197 inline std::ostream& operator<<(std::ostream& stream, const dynamic_string_view& dsv)
198 {
199  return stream << static_cast<std::string_view>(dsv);
200 }
201 
210 template <typename T>
211 [[nodiscard]] inline dynamic_string_view operator+(dynamic_string_view a, T&& b)
212 {
213  a += std::forward<T>(b);
214  return a;
215 }
216 } // namespace arg_router::utility
dynamic_string_view(dynamic_string_view &&other) noexcept
string::const_reference const_reference
! Reference type
bool operator!=(const dynamic_string_view &other) const noexcept
string::difference_type difference_type
! Difference type
friend void swap(dynamic_string_view &a, dynamic_string_view &b)
string::const_pointer const_pointer
! Pointer type
bool operator==(const dynamic_string_view &other) const noexcept
string::value_type value_type
! Value type
string::allocator_type allocator_type
! Allocator type
dynamic_string_view & operator=(dynamic_string_view other)
dynamic_string_view(const dynamic_string_view &other)
dynamic_string_view & operator+=(T &&other)
size_type internal_storage_size() const noexcept
dynamic_string_view(std::string_view sv={}) noexcept
std::string_view::const_iterator const_iterator
! Iterator type
std::ostream & operator<<(std::ostream &stream, const dynamic_string_view &dsv)
dynamic_string_view operator+(dynamic_string_view a, T &&b)