Free Electron
fixed_char_buf.h
1 // Copyright (c) 2001 John Panzer
2 // Permission is granted to use this code without restriction as
3 // long as this copyright notice appears in all source files.
4 #ifndef FIXED_CHAR_BUF_H_INCLUDED
5 #define FIXED_CHAR_BUF_H_INCLUDED
6 
7 #include <string> // For char_traits
8 #include "xs_defs.h" // Utility macros
9 
10 XS_NAMESPACE(xstr)
11 
12 // Fixed size character buffer class.
13 /// This class implements the minimal string interface
14 /// and is intended to be used as a base class for
15 /// xstring<>, which provides the full string interface.
16 template <size_t SIZE,
17  class CharT = char,
18  class Traits = std::char_traits<CharT> >
20 public:
21  // STL container interface typedefs:
22  typedef CharT value_type;
23  typedef value_type* pointer;
24  typedef const value_type* const_pointer;
25  typedef value_type& reference;
26  typedef const value_type& const_reference;
27  typedef size_t size_type;
28  typedef ptrdiff_t difference_type;
29  typedef const value_type* const_iterator;
30  typedef value_type* iterator;
31  typedef std::reverse_iterator<const_iterator>
32  const_reverse_iterator;
33  typedef std::reverse_iterator<iterator> reverse_iterator;
34  typedef std::allocator<CharT> allocator_type;
35 
36  // String interface typedefs:
37  typedef Traits traits_type;
38  static const size_type npos;
39 
40  // Constructors:
41  fixed_char_buf(allocator_type const &a=_allocator) {
42  _end = _buffer;
43  }
44 
45  fixed_char_buf(fixed_char_buf const &s) {
46  range_initialize(s.begin(), s.end());
47  }
48 
49  // Copy operator:
50  fixed_char_buf &operator=(fixed_char_buf const &s) {
51  if (this!=&s)
52  range_initialize(s.begin(), s.end());
53  }
54 
55  // Insert:
56  template <class InputIter>
57  void insert(iterator pos, InputIter first, InputIter last) {
58  if (first!=last) {
59  size_type xtra = std::distance(first,last);
60  if (pos != _end) {
61  if (_end-_buffer + xtra >= SIZE)
62  throw std::out_of_range("fixed_char_buf");
63  Traits::move(pos+xtra,pos,_end-pos);
64  }
65  std::copy(first,last,pos);
66  _end += xtra; // Expand end point
67  }
68  }
69 
70  // Erase:
71  iterator erase(iterator first, iterator last) {
72  if (first != last) {
73  Traits::move(first, last, (_end - last) + 1);
74  const iterator new_finish = _end - (last - first);
75  _end = new_finish;
76  }
77  return first;
78  }
79 
80  /// (Replace can be defined in terms of erase and insert,
81  /// so the minimal interface can skip it.)
82 
83  // STL container member function interface:
84  const allocator_type &get_allocator() const {
85  return _allocator;
86  }
87 
88  iterator begin() {return _buffer;}
89  const_iterator begin() const {return _buffer;}
90  iterator end() {return _end;}
91  const_iterator end() const {return _end;}
92 
93  void clear() {_end = _buffer;}
94  size_t max_size() const { return SIZE; }
95  bool empty() const { return (_end == _buffer); }
96  size_type size() const {return _end - _buffer;}
97 
98  void swap(fixed_char_buf& s) {
99  /// Not as cheap as some swaps, but guaranteed
100  /// not to throw:
101  for(int i=0;i<SIZE;++i) {
102  std::swap(_buffer[i],s._buffer[i]);
103  }
104  int len = _end - _buffer;
105  _end = s.size()+_buffer;
106  s._end = len+s._buffer;
107  }
108 
109  // String interface member functions:
110  void reserve(size_type n = 0) {
111  if (n > SIZE)
112  throw std::length_error("fixed_char_buf");
113  }
114  size_type capacity() const { return max_size(); }
115 
116  const CharT* c_str() const {
117  *_end = CharT(); // Null terminate.
118  return _buffer;
119  }
120 
121  const CharT* data() const {
122  return _buffer;
123  }
124 
125 protected:
126  // Internal interface used by xstring wrapper.
127 
128  // Initializes with n copies of given element:
129  void element_initialize(size_type n, value_type c) {
130  if (n > SIZE)
131  throw std::length_error("fixed_char_buf");
132  std::uninitialized_fill_n(begin(), n, c);
133  _end = _buffer+n;
134  }
135 
136  // Initializes with given range of elements:
137  template <class InputIter>
138  void range_initialize(InputIter first, InputIter last) {
139  size_t n = std::distance(first,last);
140  if (n >= SIZE)
141  throw std::length_error("fixed_char_buf");
142  std::uninitialized_copy(first,last,_buffer);
143  _end = _buffer+n;
144  }
145 
146 private:
147  // A fixed size buffer implementation:
148  CharT _buffer[SIZE+1]; // Space for SIZE elements + null
149  mutable CharT *_end ; // End of text in _buffer
150  static const allocator_type _allocator; // Dummy constant
151 };
152 
153 /// Definition of "npos" constant:
154 template <size_t SIZE, class CharT, class Traits>
155 const fixed_char_buf<SIZE,CharT,Traits>::size_type
157  = (fixed_char_buf<SIZE,CharT,Traits>::size_type) -1;
158 
159 /// Definition of "_allocator" dummy constant:
160 template <size_t SIZE, class CharT, class Traits>
161 const fixed_char_buf<SIZE,CharT,Traits>::allocator_type
163 
164 XS_END_NAMESPACE
165 
166 #endif
const allocator_type & get_allocator() const
(Replace can be defined in terms of erase and insert, so the minimal interface can skip it...
Definition: fixed_char_buf.h:84
void swap(fixed_char_buf &s)
Definition: fixed_char_buf.h:98
static const size_type npos
Definition of "npos" constant:
Definition: fixed_char_buf.h:38
static const allocator_type _allocator
Definition of "_allocator" dummy constant:
Definition: fixed_char_buf.h:150
This class implements the minimal string interface and is intended to be used as a base class for xst...
Definition: fixed_char_buf.h:19