mdds
multi_type_vector_trait.hpp
1 /*************************************************************************
2  *
3  * Copyright (c) 2012-2016 Kohei Yoshida
4  *
5  * Permission is hereby granted, free of charge, to any person
6  * obtaining a copy of this software and associated documentation
7  * files (the "Software"), to deal in the Software without
8  * restriction, including without limitation the rights to use,
9  * copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following
12  * conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24  * OTHER DEALINGS IN THE SOFTWARE.
25  *
26  ************************************************************************/
27 
28 #ifndef INCLUDED_MDDS_MULTI_TYPE_VECTOR_TRAIT_HPP
29 #define INCLUDED_MDDS_MULTI_TYPE_VECTOR_TRAIT_HPP
30 
31 #include "multi_type_vector_types.hpp"
32 
33 #include <vector>
34 
35 namespace mdds { namespace mtv {
36 
38 {
39  inline static base_element_block* create_new_block(element_t type, size_t init_size);
40 
41  inline static base_element_block* clone_block(const base_element_block& block);
42 
43  inline static void delete_block(const base_element_block* p);
44 
45  inline static void resize_block(base_element_block& block, size_t new_size);
46 
47  inline static void print_block(const base_element_block& block);
48 
49  inline static void erase(base_element_block& block, size_t pos);
50 
51  inline static void erase(base_element_block& block, size_t pos, size_t size);
52 
53  inline static void append_values_from_block(base_element_block& dest, const base_element_block& src);
54 
55  inline static void append_values_from_block(
56  base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len);
57 
58  inline static void assign_values_from_block(
59  base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len);
60 
61  inline static void prepend_values_from_block(
62  base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len);
63 
64  inline static void swap_values(
65  base_element_block& blk1, base_element_block& blk2, size_t pos1, size_t pos2, size_t len);
66 
67  inline static bool equal_block(const base_element_block& left, const base_element_block& right);
68 
76  inline static void overwrite_values(base_element_block& block, size_t pos, size_t len);
77 
78  inline static void shrink_to_fit(base_element_block& block);
79 
80  inline static size_t size(const base_element_block& block);
81 };
82 
83 base_element_block* element_block_func_base::create_new_block(element_t type, size_t init_size)
84 {
85  switch (type)
86  {
87  case element_type_numeric:
88  return numeric_element_block::create_block(init_size);
89  case element_type_string:
90  return string_element_block::create_block(init_size);
91  case element_type_short:
92  return short_element_block::create_block(init_size);
93  case element_type_ushort:
94  return ushort_element_block::create_block(init_size);
95  case element_type_int:
96  return int_element_block::create_block(init_size);
97  case element_type_uint:
98  return uint_element_block::create_block(init_size);
99  case element_type_long:
100  return long_element_block::create_block(init_size);
101  case element_type_ulong:
102  return ulong_element_block::create_block(init_size);
103  case element_type_boolean:
104  return boolean_element_block::create_block(init_size);
105  case element_type_char:
106  return char_element_block::create_block(init_size);
107  case element_type_uchar:
108  return uchar_element_block::create_block(init_size);
109  default:
110  throw general_error("create_new_block: failed to create a new block of unknown type.");
111  }
112 }
113 
114 base_element_block* element_block_func_base::clone_block(const base_element_block& block)
115 {
116  switch (get_block_type(block))
117  {
118  case element_type_numeric:
119  return numeric_element_block::clone_block(block);
120  case element_type_string:
121  return string_element_block::clone_block(block);
122  case element_type_short:
123  return short_element_block::clone_block(block);
124  case element_type_ushort:
125  return ushort_element_block::clone_block(block);
126  case element_type_int:
127  return int_element_block::clone_block(block);
128  case element_type_uint:
129  return uint_element_block::clone_block(block);
130  case element_type_long:
131  return long_element_block::clone_block(block);
132  case element_type_ulong:
133  return ulong_element_block::clone_block(block);
134  case element_type_boolean:
135  return boolean_element_block::clone_block(block);
136  case element_type_char:
137  return char_element_block::clone_block(block);
138  case element_type_uchar:
139  return uchar_element_block::clone_block(block);
140  default:
141  throw general_error("clone_block: failed to clone a block of unknown type.");
142  }
143 }
144 
145 void element_block_func_base::delete_block(const base_element_block* p)
146 {
147  if (!p)
148  return;
149 
150  switch (get_block_type(*p))
151  {
152  case element_type_numeric:
153  numeric_element_block::delete_block(p);
154  break;
155  case element_type_string:
156  string_element_block::delete_block(p);
157  break;
158  case element_type_short:
159  short_element_block::delete_block(p);
160  break;
161  case element_type_ushort:
162  ushort_element_block::delete_block(p);
163  break;
164  case element_type_int:
165  int_element_block::delete_block(p);
166  break;
167  case element_type_uint:
168  uint_element_block::delete_block(p);
169  break;
170  case element_type_long:
171  long_element_block::delete_block(p);
172  break;
173  case element_type_ulong:
174  ulong_element_block::delete_block(p);
175  break;
176  case element_type_boolean:
177  boolean_element_block::delete_block(p);
178  break;
179  case element_type_char:
180  char_element_block::delete_block(p);
181  break;
182  case element_type_uchar:
183  uchar_element_block::delete_block(p);
184  break;
185  default:
186  {
187 #ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
188  // We sould not throw an exception here as this gets called from a
189  // destructor and destructors should not throw exceptions.
190  cerr << __FILE__ << "#" << __LINE__ << " (element_block_func_base:delete_block): "
191  << "failed to delete a block of unknown type (" << get_block_type(*p) << ")"
192  << endl;
193 #endif
194  }
195  }
196 }
197 
198 void element_block_func_base::resize_block(base_element_block& block, size_t new_size)
199 {
200  switch (get_block_type(block))
201  {
202  case element_type_numeric:
203  numeric_element_block::resize_block(block, new_size);
204  break;
205  case element_type_string:
206  string_element_block::resize_block(block, new_size);
207  break;
208  case element_type_short:
209  short_element_block::resize_block(block, new_size);
210  break;
211  case element_type_ushort:
212  ushort_element_block::resize_block(block, new_size);
213  break;
214  case element_type_int:
215  int_element_block::resize_block(block, new_size);
216  break;
217  case element_type_uint:
218  uint_element_block::resize_block(block, new_size);
219  break;
220  case element_type_long:
221  long_element_block::resize_block(block, new_size);
222  break;
223  case element_type_ulong:
224  ulong_element_block::resize_block(block, new_size);
225  break;
226  case element_type_boolean:
227  boolean_element_block::resize_block(block, new_size);
228  break;
229  case element_type_char:
230  char_element_block::resize_block(block, new_size);
231  break;
232  case element_type_uchar:
233  uchar_element_block::resize_block(block, new_size);
234  break;
235  default:
236  throw general_error("resize_block: failed to resize a block of unknown type.");
237  }
238 }
239 
240 void element_block_func_base::print_block(const base_element_block& block)
241 {
242  switch (get_block_type(block))
243  {
244  case element_type_numeric:
245  numeric_element_block::print_block(block);
246  break;
247  case element_type_string:
248  string_element_block::print_block(block);
249  break;
250  case element_type_short:
251  short_element_block::print_block(block);
252  break;
253  case element_type_ushort:
254  ushort_element_block::print_block(block);
255  break;
256  case element_type_int:
257  int_element_block::print_block(block);
258  break;
259  case element_type_uint:
260  uint_element_block::print_block(block);
261  break;
262  case element_type_long:
263  long_element_block::print_block(block);
264  break;
265  case element_type_ulong:
266  ulong_element_block::print_block(block);
267  break;
268  case element_type_boolean:
269  boolean_element_block::print_block(block);
270  break;
271  case element_type_char:
272  char_element_block::print_block(block);
273  break;
274  case element_type_uchar:
275  uchar_element_block::print_block(block);
276  break;
277  default:
278  throw general_error("print_block: failed to print a block of unknown type.");
279  }
280 }
281 
282 void element_block_func_base::erase(base_element_block& block, size_t pos)
283 {
284  switch (get_block_type(block))
285  {
286  case element_type_numeric:
287  numeric_element_block::erase_block(block, pos);
288  break;
289  case element_type_string:
290  string_element_block::erase_block(block, pos);
291  break;
292  case element_type_short:
293  short_element_block::erase_block(block, pos);
294  break;
295  case element_type_ushort:
296  ushort_element_block::erase_block(block, pos);
297  break;
298  case element_type_int:
299  int_element_block::erase_block(block, pos);
300  break;
301  case element_type_uint:
302  uint_element_block::erase_block(block, pos);
303  break;
304  case element_type_long:
305  long_element_block::erase_block(block, pos);
306  break;
307  case element_type_ulong:
308  ulong_element_block::erase_block(block, pos);
309  break;
310  case element_type_boolean:
311  boolean_element_block::erase_block(block, pos);
312  break;
313  case element_type_char:
314  char_element_block::erase_block(block, pos);
315  break;
316  case element_type_uchar:
317  uchar_element_block::erase_block(block, pos);
318  break;
319  default:
320  throw general_error("erase: failed to erase an element from a block of unknown type.");
321  }
322 }
323 
324 void element_block_func_base::erase(base_element_block& block, size_t pos, size_t size)
325 {
326  switch (get_block_type(block))
327  {
328  case element_type_numeric:
329  numeric_element_block::erase_block(block, pos, size);
330  break;
331  case element_type_string:
332  string_element_block::erase_block(block, pos, size);
333  break;
334  case element_type_short:
335  short_element_block::erase_block(block, pos, size);
336  break;
337  case element_type_ushort:
338  ushort_element_block::erase_block(block, pos, size);
339  break;
340  case element_type_int:
341  int_element_block::erase_block(block, pos, size);
342  break;
343  case element_type_uint:
344  uint_element_block::erase_block(block, pos, size);
345  break;
346  case element_type_long:
347  long_element_block::erase_block(block, pos, size);
348  break;
349  case element_type_ulong:
350  ulong_element_block::erase_block(block, pos, size);
351  break;
352  case element_type_boolean:
353  boolean_element_block::erase_block(block, pos, size);
354  break;
355  case element_type_char:
356  char_element_block::erase_block(block, pos, size);
357  break;
358  case element_type_uchar:
359  uchar_element_block::erase_block(block, pos, size);
360  break;
361  default:
362  throw general_error("erase: failed to erase elements from a block of unknown type.");
363  }
364 }
365 
366 void element_block_func_base::append_values_from_block(base_element_block& dest, const base_element_block& src)
367 {
368  switch (get_block_type(dest))
369  {
370  case element_type_numeric:
371  numeric_element_block::append_values_from_block(dest, src);
372  break;
373  case element_type_string:
374  string_element_block::append_values_from_block(dest, src);
375  break;
376  case element_type_short:
377  short_element_block::append_values_from_block(dest, src);
378  break;
379  case element_type_ushort:
380  ushort_element_block::append_values_from_block(dest, src);
381  break;
382  case element_type_int:
383  int_element_block::append_values_from_block(dest, src);
384  break;
385  case element_type_uint:
386  uint_element_block::append_values_from_block(dest, src);
387  break;
388  case element_type_long:
389  long_element_block::append_values_from_block(dest, src);
390  break;
391  case element_type_ulong:
392  ulong_element_block::append_values_from_block(dest, src);
393  break;
394  case element_type_boolean:
395  boolean_element_block::append_values_from_block(dest, src);
396  break;
397  case element_type_char:
398  char_element_block::append_values_from_block(dest, src);
399  break;
400  case element_type_uchar:
401  uchar_element_block::append_values_from_block(dest, src);
402  break;
403  default:
404  throw general_error("append_values: failed to append values to a block of unknown type.");
405  }
406 }
407 
408 void element_block_func_base::append_values_from_block(
409  base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len)
410 {
411  switch (get_block_type(dest))
412  {
413  case element_type_numeric:
414  numeric_element_block::append_values_from_block(dest, src, begin_pos, len);
415  break;
416  case element_type_string:
417  string_element_block::append_values_from_block(dest, src, begin_pos, len);
418  break;
419  case element_type_short:
420  short_element_block::append_values_from_block(dest, src, begin_pos, len);
421  break;
422  case element_type_ushort:
423  ushort_element_block::append_values_from_block(dest, src, begin_pos, len);
424  break;
425  case element_type_int:
426  int_element_block::append_values_from_block(dest, src, begin_pos, len);
427  break;
428  case element_type_uint:
429  uint_element_block::append_values_from_block(dest, src, begin_pos, len);
430  break;
431  case element_type_long:
432  long_element_block::append_values_from_block(dest, src, begin_pos, len);
433  break;
434  case element_type_ulong:
435  ulong_element_block::append_values_from_block(dest, src, begin_pos, len);
436  break;
437  case element_type_boolean:
438  boolean_element_block::append_values_from_block(dest, src, begin_pos, len);
439  break;
440  case element_type_char:
441  char_element_block::append_values_from_block(dest, src, begin_pos, len);
442  break;
443  case element_type_uchar:
444  uchar_element_block::append_values_from_block(dest, src, begin_pos, len);
445  break;
446  default:
447  throw general_error("append_values: failed to append values to a block of unknown type.");
448  }
449 }
450 
451 void element_block_func_base::assign_values_from_block(
452  base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len)
453 {
454  switch (get_block_type(dest))
455  {
456  case element_type_numeric:
457  numeric_element_block::assign_values_from_block(dest, src, begin_pos, len);
458  break;
459  case element_type_string:
460  string_element_block::assign_values_from_block(dest, src, begin_pos, len);
461  break;
462  case element_type_short:
463  short_element_block::assign_values_from_block(dest, src, begin_pos, len);
464  break;
465  case element_type_ushort:
466  ushort_element_block::assign_values_from_block(dest, src, begin_pos, len);
467  break;
468  case element_type_int:
469  int_element_block::assign_values_from_block(dest, src, begin_pos, len);
470  break;
471  case element_type_uint:
472  uint_element_block::assign_values_from_block(dest, src, begin_pos, len);
473  break;
474  case element_type_long:
475  long_element_block::assign_values_from_block(dest, src, begin_pos, len);
476  break;
477  case element_type_ulong:
478  ulong_element_block::assign_values_from_block(dest, src, begin_pos, len);
479  break;
480  case element_type_boolean:
481  boolean_element_block::assign_values_from_block(dest, src, begin_pos, len);
482  break;
483  case element_type_char:
484  char_element_block::assign_values_from_block(dest, src, begin_pos, len);
485  break;
486  case element_type_uchar:
487  uchar_element_block::assign_values_from_block(dest, src, begin_pos, len);
488  break;
489  default:
490  throw general_error("assign_values_from_block: failed to assign values to a block of unknown type.");
491  }
492 }
493 
494 void element_block_func_base::prepend_values_from_block(
495  base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len)
496 {
497  switch (get_block_type(dest))
498  {
499  case element_type_numeric:
500  numeric_element_block::prepend_values_from_block(dest, src, begin_pos, len);
501  break;
502  case element_type_string:
503  string_element_block::prepend_values_from_block(dest, src, begin_pos, len);
504  break;
505  case element_type_short:
506  short_element_block::prepend_values_from_block(dest, src, begin_pos, len);
507  break;
508  case element_type_ushort:
509  ushort_element_block::prepend_values_from_block(dest, src, begin_pos, len);
510  break;
511  case element_type_int:
512  int_element_block::prepend_values_from_block(dest, src, begin_pos, len);
513  break;
514  case element_type_uint:
515  uint_element_block::prepend_values_from_block(dest, src, begin_pos, len);
516  break;
517  case element_type_long:
518  long_element_block::prepend_values_from_block(dest, src, begin_pos, len);
519  break;
520  case element_type_ulong:
521  ulong_element_block::prepend_values_from_block(dest, src, begin_pos, len);
522  break;
523  case element_type_boolean:
524  boolean_element_block::prepend_values_from_block(dest, src, begin_pos, len);
525  break;
526  case element_type_char:
527  char_element_block::prepend_values_from_block(dest, src, begin_pos, len);
528  break;
529  case element_type_uchar:
530  uchar_element_block::prepend_values_from_block(dest, src, begin_pos, len);
531  break;
532  default:
533  throw general_error("prepend_values_from_block: failed to prepend values to a block of unknown type.");
534  }
535 }
536 
537 void element_block_func_base::swap_values(
538  base_element_block& blk1, base_element_block& blk2, size_t pos1, size_t pos2, size_t len)
539 {
540  element_t blk1_type = get_block_type(blk1);
541  assert(blk1_type == get_block_type(blk2));
542  switch (blk1_type)
543  {
544  case element_type_numeric:
545  numeric_element_block::swap_values(blk1, blk2, pos1, pos2, len);
546  break;
547  case element_type_string:
548  string_element_block::swap_values(blk1, blk2, pos1, pos2, len);
549  break;
550  case element_type_short:
551  short_element_block::swap_values(blk1, blk2, pos1, pos2, len);
552  break;
553  case element_type_ushort:
554  ushort_element_block::swap_values(blk1, blk2, pos1, pos2, len);
555  break;
556  case element_type_int:
557  int_element_block::swap_values(blk1, blk2, pos1, pos2, len);
558  break;
559  case element_type_uint:
560  uint_element_block::swap_values(blk1, blk2, pos1, pos2, len);
561  break;
562  case element_type_long:
563  long_element_block::swap_values(blk1, blk2, pos1, pos2, len);
564  break;
565  case element_type_ulong:
566  ulong_element_block::swap_values(blk1, blk2, pos1, pos2, len);
567  break;
568  case element_type_boolean:
569  boolean_element_block::swap_values(blk1, blk2, pos1, pos2, len);
570  break;
571  case element_type_char:
572  char_element_block::swap_values(blk1, blk2, pos1, pos2, len);
573  break;
574  case element_type_uchar:
575  uchar_element_block::swap_values(blk1, blk2, pos1, pos2, len);
576  break;
577  default:
578  throw general_error("swap_values: block of unknown type.");
579  }
580 }
581 
582 bool element_block_func_base::equal_block(const base_element_block& left, const base_element_block& right)
583 {
584  element_t block_type = get_block_type(left);
585  if (block_type != get_block_type(right))
586  return false;
587 
588  switch (block_type)
589  {
590  case element_type_numeric:
591  return numeric_element_block::get(left) == numeric_element_block::get(right);
592  case element_type_string:
593  return string_element_block::get(left) == string_element_block::get(right);
594  case element_type_short:
595  return short_element_block::get(left) == short_element_block::get(right);
596  case element_type_ushort:
597  return ushort_element_block::get(left) == ushort_element_block::get(right);
598  case element_type_int:
599  return int_element_block::get(left) == int_element_block::get(right);
600  case element_type_uint:
601  return uint_element_block::get(left) == uint_element_block::get(right);
602  case element_type_long:
603  return long_element_block::get(left) == long_element_block::get(right);
604  case element_type_ulong:
605  return ulong_element_block::get(left) == ulong_element_block::get(right);
606  case element_type_boolean:
607  return boolean_element_block::get(left) == boolean_element_block::get(right);
608  case element_type_char:
609  return char_element_block::get(left) == char_element_block::get(right);
610  case element_type_uchar:
611  return uchar_element_block::get(left) == uchar_element_block::get(right);
612  default:
613  ;
614  }
615  return false;
616 }
617 
619 {
620  // Do nothing for the standard types.
621 }
622 
623 void element_block_func_base::shrink_to_fit(base_element_block& block)
624 {
625  switch (get_block_type(block))
626  {
627  case element_type_numeric:
628  numeric_element_block::shrink_to_fit(block);
629  break;
630  case element_type_string:
631  string_element_block::shrink_to_fit(block);
632  break;
633  case element_type_short:
634  short_element_block::shrink_to_fit(block);
635  break;
636  case element_type_ushort:
637  ushort_element_block::shrink_to_fit(block);
638  break;
639  case element_type_int:
640  int_element_block::shrink_to_fit(block);
641  break;
642  case element_type_uint:
643  uint_element_block::shrink_to_fit(block);
644  break;
645  case element_type_long:
646  long_element_block::shrink_to_fit(block);
647  break;
648  case element_type_ulong:
649  ulong_element_block::shrink_to_fit(block);
650  break;
651  case element_type_boolean:
652  boolean_element_block::shrink_to_fit(block);
653  break;
654  case element_type_char:
655  char_element_block::shrink_to_fit(block);
656  break;
657  case element_type_uchar:
658  uchar_element_block::shrink_to_fit(block);
659  break;
660  default:
661  throw general_error("shrink_to_fit: failed to print a block of unknown type.");
662  }
663 }
664 
665 size_t element_block_func_base::size(const base_element_block& block)
666 {
667  switch (get_block_type(block))
668  {
669  case element_type_numeric:
670  return numeric_element_block::size(block);
671  case element_type_string:
672  return string_element_block::size(block);
673  case element_type_short:
674  return short_element_block::size(block);
675  case element_type_ushort:
676  return ushort_element_block::size(block);
677  case element_type_int:
678  return int_element_block::size(block);
679  case element_type_uint:
680  return uint_element_block::size(block);
681  case element_type_long:
682  return long_element_block::size(block);
683  case element_type_ulong:
684  return ulong_element_block::size(block);
685  case element_type_boolean:
686  return boolean_element_block::size(block);
687  case element_type_char:
688  return char_element_block::size(block);
689  case element_type_uchar:
690  return uchar_element_block::size(block);
691  default:
692  throw general_error("size: failed to print a block of unknown type.");
693  }
694 }
695 
701 
702 }}
703 
704 #endif
Definition: multi_type_vector_trait.hpp:37
Definition: multi_type_vector_trait.hpp:700
Definition: multi_type_vector_types.hpp:87
Definition: global.hpp:58
Definition: flat_segment_tree.hpp:46
static void overwrite_values(base_element_block &block, size_t pos, size_t len)
Definition: multi_type_vector_trait.hpp:618