Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

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