boost_sqlite 1
A sqlite C++ library
Loading...
Searching...
No Matches
cstring_ref.hpp
1// Copyright (c) 2022 Klemens D. Morgenstern
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5// based on boost.process
6#ifndef BOOST_SQLITE_CSTRING_REF_HPP
7#define BOOST_SQLITE_CSTRING_REF_HPP
8
9#include <boost/config.hpp>
10#include <boost/core/detail/string_view.hpp>
11
12#include <cstddef>
13#include <type_traits>
14#include <string>
15
16namespace boost
17{
18namespace sqlite
19{
20
22
30{
31 using value_type = char;
32 using traits_type = std::char_traits<char>;
33 BOOST_CONSTEXPR cstring_ref() noexcept : view_("") {}
34 BOOST_CONSTEXPR cstring_ref(std::nullptr_t) = delete;
35
36 BOOST_CONSTEXPR cstring_ref( const value_type* s ) : view_(s) {}
37
38 template<typename Source,
39 typename =
40 typename std::enable_if<
41 std::is_same<const value_type,
42 typename std::remove_pointer<decltype(std::declval<Source>().c_str())>::type
43 >::value>::type>
44 BOOST_CONSTEXPR cstring_ref(Source && src) : view_(src.c_str()) {}
45
46 BOOST_CONSTEXPR const char * c_str() const BOOST_NOEXCEPT
47 {
48 return this->data();
49 }
50
51 using string_view_type = core::string_view;
52 constexpr operator string_view_type() const {return view_;}
53
54 using pointer = char *;
55 using const_pointer = const char *;
56 using reference = char &;
57 using const_reference = const char &;
58 using const_iterator = const_pointer;
59 using iterator = const_iterator;
60 using const_reverse_iterator = typename std::reverse_iterator<const_iterator>;
61 using reverse_iterator = typename std::reverse_iterator<iterator>;
62 using size_type = std::size_t;
63 using difference_type = std::ptrdiff_t;
64
65 static BOOST_CONSTEXPR size_type npos = -1;
66
67 BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT {return view_;};
68 BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT {return view_ + length();};
69 BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT {return view_;};
70 BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT {return view_ + length();};
71
72#if defined(BOOST_NO_CXX17)
73 const_reverse_iterator rbegin() const BOOST_NOEXCEPT {return reverse_iterator(end());};
74 const_reverse_iterator rend() const BOOST_NOEXCEPT {return reverse_iterator(begin());};
75 const_reverse_iterator crbegin() const BOOST_NOEXCEPT {return reverse_iterator(end());};
76 const_reverse_iterator crend() const BOOST_NOEXCEPT {return reverse_iterator(begin());};
77#else
78 BOOST_CONSTEXPR const_reverse_iterator rbegin() const BOOST_NOEXCEPT {return reverse_iterator(end());};
79 BOOST_CONSTEXPR const_reverse_iterator rend() const BOOST_NOEXCEPT {return reverse_iterator(begin());};
80 BOOST_CONSTEXPR const_reverse_iterator crbegin() const BOOST_NOEXCEPT {return reverse_iterator(end());};
81 BOOST_CONSTEXPR const_reverse_iterator crend() const BOOST_NOEXCEPT {return reverse_iterator(begin());};
82#endif
83
84 BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT {return length(); }
85 BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT {return length_impl_(); }
86 BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT {return static_cast<std::size_t>(-1); }
87 BOOST_ATTRIBUTE_NODISCARD BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT {return *view_ == '\0'; }
88
89 BOOST_CONSTEXPR const_reference operator[](size_type pos) const {return view_[pos] ;}
90 BOOST_CXX14_CONSTEXPR const_reference at(size_type pos) const
91 {
92 if (pos >= size())
93 throw_exception(std::out_of_range("cstring-view out of range"));
94 return view_[pos];
95 }
96 BOOST_CONSTEXPR const_reference front() const {return *view_;}
97 BOOST_CONSTEXPR const_reference back() const {return view_[length() - 1];}
98 BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT {return view_;}
99 BOOST_CXX14_CONSTEXPR void remove_prefix(size_type n) {view_ = view_ + n;}
100 void swap(cstring_ref& s) BOOST_NOEXCEPT {std::swap(view_, s.view_);}
101
102 size_type copy(value_type* s, size_type n, size_type pos = 0) const
103 {
104 return traits_type::copy(s, view_ + pos, n) - view_;
105 }
106 BOOST_CONSTEXPR cstring_ref substr(size_type pos = 0) const
107 {
108 return cstring_ref(view_ + pos);
109 }
110
111 BOOST_CXX14_CONSTEXPR string_view_type substr(size_type pos, size_type length) const
112 {
113 return string_view_type(view_).substr(pos, length);
114 }
115
116 BOOST_CXX14_CONSTEXPR int compare(cstring_ref x) const BOOST_NOEXCEPT
117 {
118 auto idx = 0u;
119 for (; view_[idx] != null_char_()[0] && x[idx] != null_char_()[0]; idx++)
120 if (!traits_type::eq(view_[idx], x[idx]))
121 return traits_type::lt(view_[idx], x[idx]) ? -1 : 1;
122
123 return traits_type::to_int_type(view_[idx]) -
124 traits_type::to_int_type(x[idx]); // will compare to null char of either.
125 }
126
127 BOOST_CXX14_CONSTEXPR bool starts_with(string_view_type x) const BOOST_NOEXCEPT
128 {
129 if (x.empty())
130 return true;
131
132 auto idx = 0u;
133 for (; view_[idx] != null_char_()[0] && idx < x.size(); idx++)
134 if (!traits_type::eq(view_[idx], x[idx]))
135 return false;
136
137 return idx == x.size() || view_[idx] != null_char_()[0];
138 }
139 BOOST_CONSTEXPR bool starts_with(value_type x) const BOOST_NOEXCEPT
140 {
141 return traits_type::eq(view_[0], x);
142 }
143
144 BOOST_CXX14_CONSTEXPR size_type find( char ch, size_type pos = 0 ) const BOOST_NOEXCEPT
145 {
146 for (auto p = view_ + pos; *p != *null_char_(); p++)
147 if (traits_type::eq(*p, ch))
148 return p - view_;
149 return npos;
150 }
151
152
153 friend BOOST_CXX14_CONSTEXPR bool operator==(cstring_ref x, cstring_ref y) BOOST_NOEXCEPT
154 {
155 std::size_t idx = 0u;
156 for (idx = 0u; x[idx] != null_char_()[0] && y[idx] != null_char_()[0]; idx++)
157 if (!traits_type::eq(x[idx], y[idx]))
158 return false;
159 return x[idx] == y[idx];
160 }
161 friend BOOST_CXX14_CONSTEXPR bool operator!=(cstring_ref x, cstring_ref y) BOOST_NOEXCEPT
162 {
163 std::size_t idx = 0u;
164 for (idx = 0u; x[idx] != null_char_()[0] &&
165 y[idx] != null_char_()[0]; idx++)
166 if (!traits_type::eq(x[idx], y[idx]))
167 return true;
168 return x[idx] != y[idx];
169 }
170 friend BOOST_CXX14_CONSTEXPR bool operator< (cstring_ref x, cstring_ref y) BOOST_NOEXCEPT {return x.compare(y) < 0;}
171 friend BOOST_CXX14_CONSTEXPR bool operator> (cstring_ref x, cstring_ref y) BOOST_NOEXCEPT {return x.compare(y) > 0;}
172 friend BOOST_CXX14_CONSTEXPR bool operator<=(cstring_ref x, cstring_ref y) BOOST_NOEXCEPT {return x.compare(y) <= 0;}
173 friend BOOST_CXX14_CONSTEXPR bool operator>=(cstring_ref x, cstring_ref y) BOOST_NOEXCEPT {return x.compare(y) >= 0;}
174
175 // modifiers
176 void clear() BOOST_NOEXCEPT { view_ = null_char_(); } // Boost extension
177
178 std::basic_string<value_type, traits_type> to_string() const
179 {
180 return std::basic_string<char, traits_type>(begin(), end());
181 }
182
183 template<typename Allocator>
184 std::basic_string<value_type, traits_type, Allocator> to_string(const Allocator& a) const
185 {
186 return std::basic_string<value_type, traits_type, Allocator>(begin(), end(), a);
187 }
188
189 template<class A> operator std::basic_string<char, std::char_traits<char>, A>() const
190 {
191 return std::basic_string<char, std::char_traits<char>, A>( view_ );
192 }
193
194 private:
195 BOOST_CONSTEXPR static const_pointer null_char_() {return "\0";}
196 constexpr std::size_t length_impl_(std::size_t n = 0) const BOOST_NOEXCEPT
197 {
198 return view_[n] == null_char_()[0] ? n : length_impl_(n+1);
199 }
200 const_pointer view_;
201};
202
203template<typename Char>
204inline std::basic_ostream<Char>& operator<<( std::basic_ostream<Char> & os, cstring_ref str )
205{
206 return os << core::string_view(str);
207}
208
209
210}
211}
212
213
214#endif //BOOST_SQLITE_CSTRING_REF_HPP
Small wrapper for a null-terminated string that can be directly passed to C APIS.