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  throw general_error("delete_block: failed to delete a block of unknown type.");
187  }
188 }
189 
190 void element_block_func_base::resize_block(base_element_block& block, size_t new_size)
191 {
192  switch (get_block_type(block))
193  {
194  case element_type_numeric:
195  numeric_element_block::resize_block(block, new_size);
196  break;
197  case element_type_string:
198  string_element_block::resize_block(block, new_size);
199  break;
200  case element_type_short:
201  short_element_block::resize_block(block, new_size);
202  break;
203  case element_type_ushort:
204  ushort_element_block::resize_block(block, new_size);
205  break;
206  case element_type_int:
207  int_element_block::resize_block(block, new_size);
208  break;
209  case element_type_uint:
210  uint_element_block::resize_block(block, new_size);
211  break;
212  case element_type_long:
213  long_element_block::resize_block(block, new_size);
214  break;
215  case element_type_ulong:
216  ulong_element_block::resize_block(block, new_size);
217  break;
218  case element_type_boolean:
219  boolean_element_block::resize_block(block, new_size);
220  break;
221  case element_type_char:
222  char_element_block::resize_block(block, new_size);
223  break;
224  case element_type_uchar:
225  uchar_element_block::resize_block(block, new_size);
226  break;
227  default:
228  throw general_error("resize_block: failed to resize a block of unknown type.");
229  }
230 }
231 
232 void element_block_func_base::print_block(const base_element_block& block)
233 {
234  switch (get_block_type(block))
235  {
236  case element_type_numeric:
237  numeric_element_block::print_block(block);
238  break;
239  case element_type_string:
240  string_element_block::print_block(block);
241  break;
242  case element_type_short:
243  short_element_block::print_block(block);
244  break;
245  case element_type_ushort:
246  ushort_element_block::print_block(block);
247  break;
248  case element_type_int:
249  int_element_block::print_block(block);
250  break;
251  case element_type_uint:
252  uint_element_block::print_block(block);
253  break;
254  case element_type_long:
255  long_element_block::print_block(block);
256  break;
257  case element_type_ulong:
258  ulong_element_block::print_block(block);
259  break;
260  case element_type_boolean:
261  boolean_element_block::print_block(block);
262  break;
263  case element_type_char:
264  char_element_block::print_block(block);
265  break;
266  case element_type_uchar:
267  uchar_element_block::print_block(block);
268  break;
269  default:
270  throw general_error("print_block: failed to print a block of unknown type.");
271  }
272 }
273 
274 void element_block_func_base::erase(base_element_block& block, size_t pos)
275 {
276  switch (get_block_type(block))
277  {
278  case element_type_numeric:
279  numeric_element_block::erase_block(block, pos);
280  break;
281  case element_type_string:
282  string_element_block::erase_block(block, pos);
283  break;
284  case element_type_short:
285  short_element_block::erase_block(block, pos);
286  break;
287  case element_type_ushort:
288  ushort_element_block::erase_block(block, pos);
289  break;
290  case element_type_int:
291  int_element_block::erase_block(block, pos);
292  break;
293  case element_type_uint:
294  uint_element_block::erase_block(block, pos);
295  break;
296  case element_type_long:
297  long_element_block::erase_block(block, pos);
298  break;
299  case element_type_ulong:
300  ulong_element_block::erase_block(block, pos);
301  break;
302  case element_type_boolean:
303  boolean_element_block::erase_block(block, pos);
304  break;
305  case element_type_char:
306  char_element_block::erase_block(block, pos);
307  break;
308  case element_type_uchar:
309  uchar_element_block::erase_block(block, pos);
310  break;
311  default:
312  throw general_error("erase: failed to erase an element from a block of unknown type.");
313  }
314 }
315 
316 void element_block_func_base::erase(base_element_block& block, size_t pos, size_t size)
317 {
318  switch (get_block_type(block))
319  {
320  case element_type_numeric:
321  numeric_element_block::erase_block(block, pos, size);
322  break;
323  case element_type_string:
324  string_element_block::erase_block(block, pos, size);
325  break;
326  case element_type_short:
327  short_element_block::erase_block(block, pos, size);
328  break;
329  case element_type_ushort:
330  ushort_element_block::erase_block(block, pos, size);
331  break;
332  case element_type_int:
333  int_element_block::erase_block(block, pos, size);
334  break;
335  case element_type_uint:
336  uint_element_block::erase_block(block, pos, size);
337  break;
338  case element_type_long:
339  long_element_block::erase_block(block, pos, size);
340  break;
341  case element_type_ulong:
342  ulong_element_block::erase_block(block, pos, size);
343  break;
344  case element_type_boolean:
345  boolean_element_block::erase_block(block, pos, size);
346  break;
347  case element_type_char:
348  char_element_block::erase_block(block, pos, size);
349  break;
350  case element_type_uchar:
351  uchar_element_block::erase_block(block, pos, size);
352  break;
353  default:
354  throw general_error("erase: failed to erase elements from a block of unknown type.");
355  }
356 }
357 
358 void element_block_func_base::append_values_from_block(base_element_block& dest, const base_element_block& src)
359 {
360  switch (get_block_type(dest))
361  {
362  case element_type_numeric:
363  numeric_element_block::append_values_from_block(dest, src);
364  break;
365  case element_type_string:
366  string_element_block::append_values_from_block(dest, src);
367  break;
368  case element_type_short:
369  short_element_block::append_values_from_block(dest, src);
370  break;
371  case element_type_ushort:
372  ushort_element_block::append_values_from_block(dest, src);
373  break;
374  case element_type_int:
375  int_element_block::append_values_from_block(dest, src);
376  break;
377  case element_type_uint:
378  uint_element_block::append_values_from_block(dest, src);
379  break;
380  case element_type_long:
381  long_element_block::append_values_from_block(dest, src);
382  break;
383  case element_type_ulong:
384  ulong_element_block::append_values_from_block(dest, src);
385  break;
386  case element_type_boolean:
387  boolean_element_block::append_values_from_block(dest, src);
388  break;
389  case element_type_char:
390  char_element_block::append_values_from_block(dest, src);
391  break;
392  case element_type_uchar:
393  uchar_element_block::append_values_from_block(dest, src);
394  break;
395  default:
396  throw general_error("append_values: failed to append values to a block of unknown type.");
397  }
398 }
399 
400 void element_block_func_base::append_values_from_block(
401  base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len)
402 {
403  switch (get_block_type(dest))
404  {
405  case element_type_numeric:
406  numeric_element_block::append_values_from_block(dest, src, begin_pos, len);
407  break;
408  case element_type_string:
409  string_element_block::append_values_from_block(dest, src, begin_pos, len);
410  break;
411  case element_type_short:
412  short_element_block::append_values_from_block(dest, src, begin_pos, len);
413  break;
414  case element_type_ushort:
415  ushort_element_block::append_values_from_block(dest, src, begin_pos, len);
416  break;
417  case element_type_int:
418  int_element_block::append_values_from_block(dest, src, begin_pos, len);
419  break;
420  case element_type_uint:
421  uint_element_block::append_values_from_block(dest, src, begin_pos, len);
422  break;
423  case element_type_long:
424  long_element_block::append_values_from_block(dest, src, begin_pos, len);
425  break;
426  case element_type_ulong:
427  ulong_element_block::append_values_from_block(dest, src, begin_pos, len);
428  break;
429  case element_type_boolean:
430  boolean_element_block::append_values_from_block(dest, src, begin_pos, len);
431  break;
432  case element_type_char:
433  char_element_block::append_values_from_block(dest, src, begin_pos, len);
434  break;
435  case element_type_uchar:
436  uchar_element_block::append_values_from_block(dest, src, begin_pos, len);
437  break;
438  default:
439  throw general_error("append_values: failed to append values to a block of unknown type.");
440  }
441 }
442 
443 void element_block_func_base::assign_values_from_block(
444  base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len)
445 {
446  switch (get_block_type(dest))
447  {
448  case element_type_numeric:
449  numeric_element_block::assign_values_from_block(dest, src, begin_pos, len);
450  break;
451  case element_type_string:
452  string_element_block::assign_values_from_block(dest, src, begin_pos, len);
453  break;
454  case element_type_short:
455  short_element_block::assign_values_from_block(dest, src, begin_pos, len);
456  break;
457  case element_type_ushort:
458  ushort_element_block::assign_values_from_block(dest, src, begin_pos, len);
459  break;
460  case element_type_int:
461  int_element_block::assign_values_from_block(dest, src, begin_pos, len);
462  break;
463  case element_type_uint:
464  uint_element_block::assign_values_from_block(dest, src, begin_pos, len);
465  break;
466  case element_type_long:
467  long_element_block::assign_values_from_block(dest, src, begin_pos, len);
468  break;
469  case element_type_ulong:
470  ulong_element_block::assign_values_from_block(dest, src, begin_pos, len);
471  break;
472  case element_type_boolean:
473  boolean_element_block::assign_values_from_block(dest, src, begin_pos, len);
474  break;
475  case element_type_char:
476  char_element_block::assign_values_from_block(dest, src, begin_pos, len);
477  break;
478  case element_type_uchar:
479  uchar_element_block::assign_values_from_block(dest, src, begin_pos, len);
480  break;
481  default:
482  throw general_error("assign_values_from_block: failed to assign values to a block of unknown type.");
483  }
484 }
485 
486 void element_block_func_base::prepend_values_from_block(
487  base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len)
488 {
489  switch (get_block_type(dest))
490  {
491  case element_type_numeric:
492  numeric_element_block::prepend_values_from_block(dest, src, begin_pos, len);
493  break;
494  case element_type_string:
495  string_element_block::prepend_values_from_block(dest, src, begin_pos, len);
496  break;
497  case element_type_short:
498  short_element_block::prepend_values_from_block(dest, src, begin_pos, len);
499  break;
500  case element_type_ushort:
501  ushort_element_block::prepend_values_from_block(dest, src, begin_pos, len);
502  break;
503  case element_type_int:
504  int_element_block::prepend_values_from_block(dest, src, begin_pos, len);
505  break;
506  case element_type_uint:
507  uint_element_block::prepend_values_from_block(dest, src, begin_pos, len);
508  break;
509  case element_type_long:
510  long_element_block::prepend_values_from_block(dest, src, begin_pos, len);
511  break;
512  case element_type_ulong:
513  ulong_element_block::prepend_values_from_block(dest, src, begin_pos, len);
514  break;
515  case element_type_boolean:
516  boolean_element_block::prepend_values_from_block(dest, src, begin_pos, len);
517  break;
518  case element_type_char:
519  char_element_block::prepend_values_from_block(dest, src, begin_pos, len);
520  break;
521  case element_type_uchar:
522  uchar_element_block::prepend_values_from_block(dest, src, begin_pos, len);
523  break;
524  default:
525  throw general_error("prepend_values_from_block: failed to prepend values to a block of unknown type.");
526  }
527 }
528 
529 void element_block_func_base::swap_values(
530  base_element_block& blk1, base_element_block& blk2, size_t pos1, size_t pos2, size_t len)
531 {
532  element_t blk1_type = get_block_type(blk1);
533  assert(blk1_type == get_block_type(blk2));
534  switch (blk1_type)
535  {
536  case element_type_numeric:
537  numeric_element_block::swap_values(blk1, blk2, pos1, pos2, len);
538  break;
539  case element_type_string:
540  string_element_block::swap_values(blk1, blk2, pos1, pos2, len);
541  break;
542  case element_type_short:
543  short_element_block::swap_values(blk1, blk2, pos1, pos2, len);
544  break;
545  case element_type_ushort:
546  ushort_element_block::swap_values(blk1, blk2, pos1, pos2, len);
547  break;
548  case element_type_int:
549  int_element_block::swap_values(blk1, blk2, pos1, pos2, len);
550  break;
551  case element_type_uint:
552  uint_element_block::swap_values(blk1, blk2, pos1, pos2, len);
553  break;
554  case element_type_long:
555  long_element_block::swap_values(blk1, blk2, pos1, pos2, len);
556  break;
557  case element_type_ulong:
558  ulong_element_block::swap_values(blk1, blk2, pos1, pos2, len);
559  break;
560  case element_type_boolean:
561  boolean_element_block::swap_values(blk1, blk2, pos1, pos2, len);
562  break;
563  case element_type_char:
564  char_element_block::swap_values(blk1, blk2, pos1, pos2, len);
565  break;
566  case element_type_uchar:
567  uchar_element_block::swap_values(blk1, blk2, pos1, pos2, len);
568  break;
569  default:
570  throw general_error("swap_values: block of unknown type.");
571  }
572 }
573 
574 bool element_block_func_base::equal_block(const base_element_block& left, const base_element_block& right)
575 {
576  element_t block_type = get_block_type(left);
577  if (block_type != get_block_type(right))
578  return false;
579 
580  switch (block_type)
581  {
582  case element_type_numeric:
583  return numeric_element_block::get(left) == numeric_element_block::get(right);
584  case element_type_string:
585  return string_element_block::get(left) == string_element_block::get(right);
586  case element_type_short:
587  return short_element_block::get(left) == short_element_block::get(right);
588  case element_type_ushort:
589  return ushort_element_block::get(left) == ushort_element_block::get(right);
590  case element_type_int:
591  return int_element_block::get(left) == int_element_block::get(right);
592  case element_type_uint:
593  return uint_element_block::get(left) == uint_element_block::get(right);
594  case element_type_long:
595  return long_element_block::get(left) == long_element_block::get(right);
596  case element_type_ulong:
597  return ulong_element_block::get(left) == ulong_element_block::get(right);
598  case element_type_boolean:
599  return boolean_element_block::get(left) == boolean_element_block::get(right);
600  case element_type_char:
601  return char_element_block::get(left) == char_element_block::get(right);
602  case element_type_uchar:
603  return uchar_element_block::get(left) == uchar_element_block::get(right);
604  default:
605  ;
606  }
607  return false;
608 }
609 
611 {
612  // Do nothing for the standard types.
613 }
614 
615 void element_block_func_base::shrink_to_fit(base_element_block& block)
616 {
617  switch (get_block_type(block))
618  {
619  case element_type_numeric:
620  numeric_element_block::shrink_to_fit(block);
621  break;
622  case element_type_string:
623  string_element_block::shrink_to_fit(block);
624  break;
625  case element_type_short:
626  short_element_block::shrink_to_fit(block);
627  break;
628  case element_type_ushort:
629  ushort_element_block::shrink_to_fit(block);
630  break;
631  case element_type_int:
632  int_element_block::shrink_to_fit(block);
633  break;
634  case element_type_uint:
635  uint_element_block::shrink_to_fit(block);
636  break;
637  case element_type_long:
638  long_element_block::shrink_to_fit(block);
639  break;
640  case element_type_ulong:
641  ulong_element_block::shrink_to_fit(block);
642  break;
643  case element_type_boolean:
644  boolean_element_block::shrink_to_fit(block);
645  break;
646  case element_type_char:
647  char_element_block::shrink_to_fit(block);
648  break;
649  case element_type_uchar:
650  uchar_element_block::shrink_to_fit(block);
651  break;
652  default:
653  throw general_error("shrink_to_fit: failed to print a block of unknown type.");
654  }
655 }
656 
657 size_t element_block_func_base::size(const base_element_block& block)
658 {
659  switch (get_block_type(block))
660  {
661  case element_type_numeric:
662  return numeric_element_block::size(block);
663  case element_type_string:
664  return string_element_block::size(block);
665  case element_type_short:
666  return short_element_block::size(block);
667  case element_type_ushort:
668  return ushort_element_block::size(block);
669  case element_type_int:
670  return int_element_block::size(block);
671  case element_type_uint:
672  return uint_element_block::size(block);
673  case element_type_long:
674  return long_element_block::size(block);
675  case element_type_ulong:
676  return ulong_element_block::size(block);
677  case element_type_boolean:
678  return boolean_element_block::size(block);
679  case element_type_char:
680  return char_element_block::size(block);
681  case element_type_uchar:
682  return uchar_element_block::size(block);
683  default:
684  throw general_error("size: failed to print a block of unknown type.");
685  }
686 }
687 
693 
694 }}
695 
696 #endif
Definition: multi_type_vector_trait.hpp:37
Definition: multi_type_vector_trait.hpp:692
Definition: multi_type_vector_types.hpp:88
Definition: global.hpp:58
Definition: default_deleter.hpp:33
static void overwrite_values(base_element_block &block, size_t pos, size_t len)
Definition: multi_type_vector_trait.hpp:610