szpool.h
1 #ifndef __POOL_FOR_STRINGS_TERMINATED_BY_ZERO_H_
2 #define __POOL_FOR_STRINGS_TERMINATED_BY_ZERO_H_
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include <cassert>
18
19 #include <cstddef>
20
21
22 #include <vector>
23
24
25 namespace StringPool {
26
27 using std::size_t;
28
29
30 template <typename Letter>
31 inline size_t GetStringLength(const Letter *s) {
32 const Letter *p = s;
33 while (*p != '\0')
34 ++p;
35 return static_cast<size_t>(p - s);
36 }
37
38
39 template <typename LetterTo, typename LetterFrom>
40 inline LetterTo *CopyString(LetterTo *dst, const LetterFrom *src,
41 size_t size) {
42 for (size_t i = 0; i < size; ++i)
43 dst[i] = src[i];
44 return dst;
45 }
46
47
48 template <typename Letter>
49 class Pool {
50 private:
51 typedef std::vector<Letter *> BlockVector;
52 typedef typename BlockVector::iterator BlockIterator;
53
54 public:
55 Pool(size_t block_size = 4096)
56 : blocks_(), next_(0), end_(0),
57 num_strs_(0), total_size_(0), block_size_(block_size) {}
58 ~Pool() {
59 for (BlockIterator it = blocks_.begin(); it != blocks_.end(); ++it)
60 delete [] *it;
61 }
62
63
64 Letter *alloc(size_t size) {
65 if (size > static_cast<size_t>(end_ - next_))
66 expand_(size);
67 Letter *start = next_;
68 next_ += size;
69 ++num_strs_;
70 return start;
71 }
72
73
74 template <typename LetterFrom>
75 Letter *add(const LetterFrom *s, size_t size) {
76 assert(s);
77 return CopyString(alloc(size), s, size);
78 }
79 template <typename LetterFrom>
80 Letter *add(const LetterFrom *s) {
81 assert(s);
82 return add(s, GetStringLength(s) + 1);
83 }
84
85
86 size_t num_strs() const { return num_strs_; }
87 size_t total_size() const { return total_size_; }
88
89 private:
90 BlockVector blocks_;
91 Letter *next_;
92 Letter *end_;
93 size_t num_strs_;
94 size_t total_size_;
95 size_t block_size_;
96
97
98 void expand_(size_t size) {
99 size = (size > block_size_) ? size : block_size_;
100 blocks_.push_back(new Letter[size]);
101 next_ = blocks_.back();
102 end_ = next_ + size;
103 total_size_ += sizeof(Letter) * size;
104 }
105
106
107 Pool(const Pool &rhs);
108 Pool &operator=(const Pool<Letter> &rhs);
109 };
110
111 }
112
113
114 #endif