Boost.Nowide
stackstring.hpp
1//
2// Copyright (c) 2012 Artyom Beilis (Tonkikh)
3//
4// Distributed under the Boost Software License, Version 1.0.
5// https://www.boost.org/LICENSE_1_0.txt
6
7#ifndef BOOST_NOWIDE_STACKSTRING_HPP_INCLUDED
8#define BOOST_NOWIDE_STACKSTRING_HPP_INCLUDED
9
10#include <boost/nowide/convert.hpp>
11#include <boost/nowide/utf/utf.hpp>
12#include <cassert>
13#include <cstring>
14
15namespace boost {
16namespace nowide {
17
30 template<typename CharOut = wchar_t, typename CharIn = char, size_t BufferSize = 256>
32 {
33 public:
35 static const size_t buffer_size = BufferSize;
37 using output_char = CharOut;
39 using input_char = CharIn;
40
43 {
44 buffer_[0] = 0;
45 }
48 explicit basic_stackstring(const input_char* input)
49 {
50 convert(input);
51 }
54 basic_stackstring(const input_char* begin, const input_char* end)
55 {
56 convert(begin, end);
57 }
60 {
61 *this = other;
62 }
65 {
66 if(this != &other)
67 {
68 clear();
69 const size_t len = other.length();
70 if(other.uses_stack_memory())
71 data_ = buffer_;
72 else if(other.data_)
73 data_ = new output_char[len + 1];
74 else
75 {
76 data_ = nullptr;
77 return *this;
78 }
79 std::memcpy(data_, other.data_, sizeof(output_char) * (len + 1));
80 }
81 return *this;
82 }
83
85 {
86 clear();
87 }
88
92 {
93 if(input)
94 return convert(input, input + utf::strlen(input));
95 clear();
96 return get();
97 }
100 output_char* convert(const input_char* begin, const input_char* end)
101 {
102 clear();
103
104 if(begin)
105 {
106 const size_t input_len = end - begin;
107 // Minimum size required: 1 output char per input char + trailing NULL
108 const size_t min_output_size = input_len + 1;
109 // If there is a chance the converted string fits on stack, try it
110 if(min_output_size <= buffer_size && utf::convert_buffer(buffer_, buffer_size, begin, end))
111 data_ = buffer_;
112 else
113 {
114 // Fallback: Allocate a buffer that is surely large enough on heap
115 // Max size: Every input char is transcoded to the output char with maximum with + trailing NULL
116 const size_t max_output_size = input_len * utf::utf_traits<output_char>::max_width + 1;
117 data_ = new output_char[max_output_size];
118 const bool success = utf::convert_buffer(data_, max_output_size, begin, end) == data_;
119 assert(success);
120 (void)success;
121 }
122 }
123 return get();
124 }
127 {
128 return data_;
129 }
131 const output_char* get() const
132 {
133 return data_;
134 }
136 void clear()
137 {
138 if(!uses_stack_memory())
139 delete[] data_;
140 data_ = nullptr;
141 }
144 {
145 if(lhs.uses_stack_memory())
146 {
147 if(rhs.uses_stack_memory())
148 {
149 for(size_t i = 0; i < buffer_size; i++)
150 std::swap(lhs.buffer_[i], rhs.buffer_[i]);
151 } else
152 {
153 lhs.data_ = rhs.data_;
154 rhs.data_ = rhs.buffer_;
155 for(size_t i = 0; i < buffer_size; i++)
156 rhs.buffer_[i] = lhs.buffer_[i];
157 }
158 } else if(rhs.uses_stack_memory())
159 {
160 rhs.data_ = lhs.data_;
161 lhs.data_ = lhs.buffer_;
162 for(size_t i = 0; i < buffer_size; i++)
163 lhs.buffer_[i] = rhs.buffer_[i];
164 } else
165 std::swap(lhs.data_, rhs.data_);
166 }
167
168 protected:
170 bool uses_stack_memory() const
171 {
172 return data_ == buffer_;
173 }
176 size_t length() const
177 {
178 if(!data_)
179 return 0;
180 size_t len = 0;
181 while(data_[len])
182 len++;
183 return len;
184 }
185
186 private:
187 output_char buffer_[buffer_size];
188 output_char* data_ = nullptr;
189 }; // basic_stackstring
190
207
208} // namespace nowide
209} // namespace boost
210
211#endif
A class that allows to create a temporary wide or narrow UTF strings from wide or narrow UTF source.
Definition: stackstring.hpp:32
basic_stackstring()
Creates a NULL stackstring.
Definition: stackstring.hpp:42
basic_stackstring(const basic_stackstring &other)
Copy construct from other.
Definition: stackstring.hpp:59
static const size_t buffer_size
Size of the stack buffer.
Definition: stackstring.hpp:35
size_t length() const
Definition: stackstring.hpp:176
basic_stackstring(const input_char *begin, const input_char *end)
Definition: stackstring.hpp:54
bool uses_stack_memory() const
True if the stack memory is used.
Definition: stackstring.hpp:170
basic_stackstring(const input_char *input)
Definition: stackstring.hpp:48
CharIn input_char
Type of the input character (converted from)
Definition: stackstring.hpp:39
friend void swap(basic_stackstring &lhs, basic_stackstring &rhs)
Swap lhs with rhs.
Definition: stackstring.hpp:143
CharOut output_char
Type of the output character (converted to)
Definition: stackstring.hpp:37
output_char * convert(const input_char *input)
Definition: stackstring.hpp:91
void clear()
Reset the internal buffer to NULL.
Definition: stackstring.hpp:136
const output_char * get() const
Return the converted, NULL-terminated string or NULL if no string was converted.
Definition: stackstring.hpp:131
basic_stackstring & operator=(const basic_stackstring &other)
Copy assign from other.
Definition: stackstring.hpp:64
output_char * get()
Return the converted, NULL-terminated string or NULL if no string was converted.
Definition: stackstring.hpp:126
output_char * convert(const input_char *begin, const input_char *end)
Definition: stackstring.hpp:100
CharOut * convert_buffer(CharOut *buffer, size_t buffer_size, const CharIn *source_begin, const CharIn *source_end)
Definition: convert.hpp:42
size_t strlen(const Char *s)
Definition: convert.hpp:25
UTF Traits class - functions to convert UTF sequences to and from Unicode code points.
Definition: utf.hpp:57