OpenDDS  Snapshot(2023/04/28-20:55)
Util.h
Go to the documentation of this file.
1 /*
2  * Distributed under the OpenDDS License.
3  * See: http://www.opendds.org/license.html
4  */
5 
6 #ifndef OPENDDS_DCPS_UTIL_H
7 #define OPENDDS_DCPS_UTIL_H
8 
9 #include <ace/CDR_Base.h>
10 
11 #include <cstring>
12 
14 
15 namespace OpenDDS {
16 namespace DCPS {
17 
18 // bind reproduces the ACE_Hash_Map_Manager_Ex's bind behavior
19 template <typename Container, typename FirstType, typename SecondType>
20 int bind(
21  Container& c,
22  const FirstType& first,
23  const SecondType& second)
24 {
25  if (c.find(first) == c.end()) {
26  typedef typename Container::value_type container_value_type;
27 
28  if (c.insert(container_value_type(first, second)).second) {
29  return 0;
30  }
31 
32  return -1;
33  }
34 
35  return 1;
36 }
37 
38 // unbind reproduces the ACE_Hash_Map_Manager_Ex's unbind behavior
39 template <typename Container>
40 int unbind(
41  Container& c,
42  const typename Container::key_type& k,
43  typename Container::mapped_type& v)
44 {
45  typename Container::const_iterator iter = c.find(k);
46 
47  if (iter != c.end()) {
48  v = iter->second;
49 
50  if (c.erase(k) == 1) {
51  return 0;
52  }
53 
54  return -1;
55  }
56 
57  return -1;
58 }
59 
60 // unbind reproduces the ACE_Hash_Map_Manager_Ex's unbind behavior
61 template <typename Container>
62 int unbind(
63  Container& c,
64  const typename Container::key_type& k)
65 {
66  typename Container::mapped_type v;
67  return unbind(c, k, v);
68 }
69 
70 template <typename Container, typename Key>
71 int find(
72  Container& c,
73  const Key& key,
74  typename Container::mapped_type*& value)
75 {
76  typename Container::iterator iter =
77  c.find(key);
78 
79  if (iter == c.end()) {
80  return -1;
81  }
82 
83  value = &iter->second;
84  return 0;
85 }
86 
87 template <typename Container, typename Key>
88 int find(
89  const Container& c,
90  const Key& key,
91  typename Container::mapped_type& value)
92 {
93  typename Container::const_iterator iter =
94  c.find(key);
95 
96  if (iter == c.end()) {
97  return -1;
98  }
99 
100  value = iter->second;
101  return 0;
102 }
103 
104 template <typename Container, typename ValueType>
105 int insert(
106  Container& c,
107  const ValueType& v)
108 {
109  if (c.find(v) == c.end()) {
110  if (c.insert(v).second) {
111  return 0;
112  }
113 
114  return -1;
115  }
116 
117  return 1;
118 }
119 
120 template <typename Container, typename ValueType>
121 int remove(
122  Container& c,
123  const ValueType& v)
124 {
125  if (c.find(v) != c.end()) {
126  if (c.erase(v) == 1) {
127  return 0;
128  }
129 
130  return -1;
131  }
132 
133  return -1;
134 }
135 
136 /// std::vector-style push_back() for CORBA Sequences
137 template <typename Seq>
138 void push_back(Seq& seq, const typename Seq::value_type& val)
139 {
140  const ACE_CDR::ULong len = seq.length();
141  // Grow by factor of 2 when length is a power of 2 in order to prevent every call to length(+1)
142  // allocating a new buffer & copying previous results. The maximum is kept when length is reduced.
143  if (len && !(len & (len - 1))) {
144  seq.length(2 * len);
145  }
146  seq.length(len + 1);
147  seq[len] = val;
148 }
149 
150 template <typename Seq>
151 typename Seq::size_type grow(Seq& seq)
152 {
153  const ACE_CDR::ULong len = seq.length();
154  // Grow by factor of 2 when length is a power of 2 in order to prevent every call to length(+1)
155  // allocating a new buffer & copying previous results. The maximum is kept when length is reduced.
156  if (len && !(len & (len - 1))) {
157  seq.length(2 * len);
158  }
159  seq.length(len + 1);
160  return len + 1;
161 }
162 
163 // Constructs a sorted intersect of the given two sorted ranges [a,aEnd) and [b,bEnd).
164 // (for pre-c++17 code for the similar effect of std::set_intersection in c++17)
165 template <typename InputIteratorA, typename InputIteratorB, typename OutputIterator>
166 OutputIterator intersect_sorted_ranges(InputIteratorA a, InputIteratorA aEnd,
167  InputIteratorB b, InputIteratorB bEnd,
168  OutputIterator intersect)
169 {
170  while (a != aEnd && b != bEnd) {
171  if (*a < *b) { ++a; }
172  else if (*b < *a) { ++b; }
173  else { *intersect++ = *a++; ++b; }
174  }
175  return intersect;
176 }
177 
178 // Constructs a sorted intersect of the given two sorted ranges [a,aEnd) and [b,bEnd).
179 // (for pre-c++17 code for the similar effect of std::set_intersection in c++17)
180 template <typename InputIteratorA, typename InputIteratorB, typename OutputIterator, typename LessThan>
181 OutputIterator intersect_sorted_ranges(InputIteratorA a, InputIteratorA aEnd,
182  InputIteratorB b, InputIteratorB bEnd,
183  OutputIterator intersect, LessThan lessThan)
184 {
185  while (a != aEnd && b != bEnd) {
186  if (lessThan(*a, *b)) { ++a; }
187  else if (lessThan(*b, *a)) { ++b; }
188  else { *intersect++ = *a++; ++b; }
189  }
190  return intersect;
191 }
192 
193 // Keeps the intersection of the two sorted collections in the first one,
194 // and returns whether an intersection exists between the two colloctions.
195 // Note:
196 // The generic scope of the first template parameter is narrowed down to std::set<T> because
197 // the pre-c++11 erase() may not work here with some collections (e.g. a sorted std::vector).
198 // The since-c++11 erase() works properly with both an std::set and a sorted std::vector.
199 template <typename SetA, typename SortedB, typename LessThan>
200 bool set_intersect(SetA& sA, const SortedB& sB, LessThan lessThan)
201 {
202  typename SetA::iterator a = sA.begin();
203  typename SortedB::const_iterator b = sB.begin();
204  while (a != sA.end()) {
205  if (b != sB.end()) {
206  if (lessThan(*a, *b)) {
207  sA.erase(a++);
208  } else {
209  if (!lessThan(*b, *a)) { ++a; }
210  ++b;
211  }
212  } else {
213  sA.erase(a, sA.end());
214  break;
215  }
216  }
217  return !sA.empty();
218 }
219 
220 template <typename Type, size_t count>
221 size_t array_count(Type(&)[count])
222 {
223  return count;
224 }
225 
226 template <typename T>
227 inline int mem_cmp(const T& a, const T& b)
228 {
229  return std::memcmp(&a, &b, sizeof(T));
230 }
231 
232 } // namespace DCPS
233 } // namespace OpenDDS
234 
236 
237 #endif /* OPENDDS_DCPS_UTIL_H */
const LogLevel::Value value
Definition: debug.cpp:61
int bind(Container &c, const FirstType &first, const SecondType &second)
Definition: Util.h:20
sequence< octet > key
size_t array_count(Type(&)[count])
Definition: Util.h:221
int mem_cmp(const T &a, const T &b)
Definition: Util.h:227
Seq::size_type grow(Seq &seq)
Definition: Util.h:151
ACE_UINT32 ULong
void push_back(Seq &seq, const typename Seq::value_type &val)
std::vector-style push_back() for CORBA Sequences
Definition: Util.h:138
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
bool set_intersect(SetA &sA, const SortedB &sB, LessThan lessThan)
Definition: Util.h:200
void intersect(const GuidSet &a, const GuidSet &b, GuidSet &result)
Definition: GuidUtils.cpp:60
int insert(Container &c, const ValueType &v)
Definition: Util.h:105
OutputIterator intersect_sorted_ranges(InputIteratorA a, InputIteratorA aEnd, InputIteratorB b, InputIteratorB bEnd, OutputIterator intersect)
Definition: Util.h:166
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
int unbind(Container &c, const typename Container::key_type &k, typename Container::mapped_type &v)
Definition: Util.h:40
int find(Container &c, const Key &key, typename Container::mapped_type *&value)
Definition: Util.h:71