Line data Source code
1 : /*
2 : Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
3 :
4 : This file is part of libzmq, the ZeroMQ core engine in C++.
5 :
6 : libzmq is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU Lesser General Public License (LGPL) as published
8 : by the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : As a special exception, the Contributors give you permission to link
12 : this library with independent modules to produce an executable,
13 : regardless of the license terms of these independent modules, and to
14 : copy and distribute the resulting executable under terms of your choice,
15 : provided that you also meet, for each linked independent module, the
16 : terms and conditions of the license of that module. An independent
17 : module is a module which is not derived from or based on this library.
18 : If you modify this library, you must extend this exception to your
19 : version of the library.
20 :
21 : libzmq is distributed in the hope that it will be useful, but WITHOUT
22 : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
24 : License for more details.
25 :
26 : You should have received a copy of the GNU Lesser General Public License
27 : along with this program. If not, see <http://www.gnu.org/licenses/>.
28 : */
29 :
30 : #ifndef __ZMQ_ARRAY_INCLUDED__
31 : #define __ZMQ_ARRAY_INCLUDED__
32 :
33 : #include <vector>
34 : #include <algorithm>
35 :
36 : namespace zmq
37 : {
38 : // Implementation of fast arrays with O(1) access, insertion and
39 : // removal. The array stores pointers rather than objects.
40 : // O(1) is achieved by making items inheriting from
41 : // array_item_t<ID> class which internally stores the position
42 : // in the array.
43 : // The ID template argument is used to differentiate among arrays
44 : // and thus let an object be stored in different arrays.
45 :
46 : // Base class for objects stored in the array. If you want to store
47 : // same object in multiple arrays, each of those arrays has to have
48 : // different ID. The item itself has to be derived from instantiations of
49 : // array_item_t template for all relevant IDs.
50 :
51 : template <int ID = 0> class array_item_t
52 : {
53 : public:
54 :
55 : inline array_item_t () :
56 58294 : array_index (-1)
57 : {
58 : }
59 :
60 : // The destructor doesn't have to be virtual. It is made virtual
61 : // just to keep ICC and code checking tools from complaining.
62 0 : inline virtual ~array_item_t ()
63 : {
64 58270 : }
65 :
66 : inline void set_array_index (int index_)
67 : {
68 258834 : array_index = index_;
69 : }
70 :
71 : inline int get_array_index ()
72 : {
73 : return array_index;
74 : }
75 :
76 : private:
77 :
78 : int array_index;
79 :
80 : array_item_t (const array_item_t&);
81 : const array_item_t &operator = (const array_item_t&);
82 : };
83 :
84 :
85 : template <typename T, int ID = 0> class array_t
86 : {
87 : private:
88 :
89 : typedef array_item_t <ID> item_t;
90 :
91 : public:
92 :
93 : typedef typename std::vector <T*>::size_type size_type;
94 :
95 : inline array_t ()
96 20431 : {
97 : }
98 :
99 : inline ~array_t ()
100 : {
101 20431 : }
102 :
103 : inline size_type size ()
104 : {
105 47734 : return items.size ();
106 : }
107 :
108 : inline bool empty ()
109 : {
110 18330 : return items.empty ();
111 : }
112 :
113 : inline T *&operator [] (size_type index_)
114 : {
115 3999010 : return items [index_];
116 : }
117 :
118 31861 : inline void push_back (T *item_)
119 : {
120 31861 : if (item_)
121 63722 : ((item_t*) item_)->set_array_index ((int) items.size ());
122 31861 : items.push_back (item_);
123 31861 : }
124 :
125 31861 : inline void erase (T *item_) {
126 31861 : erase (((item_t*) item_)->get_array_index ());
127 31861 : }
128 :
129 : inline void erase (size_type index_) {
130 95583 : if (items.back ())
131 63722 : ((item_t*) items.back ())->set_array_index ((int) index_);
132 127444 : items [index_] = items.back ();
133 31861 : items.pop_back ();
134 : }
135 :
136 97557 : inline void swap (size_type index1_, size_type index2_)
137 : {
138 195114 : if (items [index1_])
139 97556 : ((item_t*) items [index1_])->set_array_index ((int) index2_);
140 195114 : if (items [index2_])
141 97556 : ((item_t*) items [index2_])->set_array_index ((int) index1_);
142 97557 : std::swap (items [index1_], items [index2_]);
143 97557 : }
144 :
145 : inline void clear ()
146 : {
147 : items.clear ();
148 : }
149 :
150 : inline size_type index (T *item_)
151 : {
152 242706 : return (size_type) ((item_t*) item_)->get_array_index ();
153 : }
154 :
155 : private:
156 :
157 : typedef std::vector <T*> items_t;
158 : items_t items;
159 :
160 : array_t (const array_t&);
161 : const array_t &operator = (const array_t&);
162 : };
163 :
164 : }
165 :
166 : #endif
167 :
|