mdds
multi_type_vector_trait.hpp
1 /*************************************************************************
2  *
3  * Copyright (c) 2012 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 __MDDS_MULTI_TYPE_VECTOR_TRAIT_HPP__
29 #define __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 
81 base_element_block* element_block_func_base::create_new_block(element_t type, size_t init_size)
82 {
83  switch (type)
84  {
85  case element_type_numeric:
86  return numeric_element_block::create_block(init_size);
87  case element_type_string:
88  return string_element_block::create_block(init_size);
89  case element_type_short:
90  return short_element_block::create_block(init_size);
91  case element_type_ushort:
92  return ushort_element_block::create_block(init_size);
93  case element_type_int:
94  return int_element_block::create_block(init_size);
95  case element_type_uint:
96  return uint_element_block::create_block(init_size);
97  case element_type_long:
98  return long_element_block::create_block(init_size);
99  case element_type_ulong:
100  return ulong_element_block::create_block(init_size);
101  case element_type_boolean:
102  return boolean_element_block::create_block(init_size);
103  case element_type_char:
104  return char_element_block::create_block(init_size);
105  case element_type_uchar:
106  return uchar_element_block::create_block(init_size);
107  default:
108  throw general_error("create_new_block: failed to create a new block of unknown type.");
109  }
110 }
111 
112 base_element_block* element_block_func_base::clone_block(const base_element_block& block)
113 {
114  switch (get_block_type(block))
115  {
116  case element_type_numeric:
117  return numeric_element_block::clone_block(block);
118  case element_type_string:
119  return string_element_block::clone_block(block);
120  case element_type_short:
121  return short_element_block::clone_block(block);
122  case element_type_ushort:
123  return ushort_element_block::clone_block(block);
124  case element_type_int:
125  return int_element_block::clone_block(block);
126  case element_type_uint:
127  return uint_element_block::clone_block(block);
128  case element_type_long:
129  return long_element_block::clone_block(block);
130  case element_type_ulong:
131  return ulong_element_block::clone_block(block);
132  case element_type_boolean:
133  return boolean_element_block::clone_block(block);
134  case element_type_char:
135  return char_element_block::clone_block(block);
136  case element_type_uchar:
137  return uchar_element_block::clone_block(block);
138  default:
139  throw general_error("clone_block: failed to clone a block of unknown type.");
140  }
141 }
142 
143 void element_block_func_base::delete_block(const base_element_block* p)
144 {
145  if (!p)
146  return;
147 
148  switch (get_block_type(*p))
149  {
150  case element_type_numeric:
151  numeric_element_block::delete_block(p);
152  break;
153  case element_type_string:
154  string_element_block::delete_block(p);
155  break;
156  case element_type_short:
157  short_element_block::delete_block(p);
158  break;
159  case element_type_ushort:
160  ushort_element_block::delete_block(p);
161  break;
162  case element_type_int:
163  int_element_block::delete_block(p);
164  break;
165  case element_type_uint:
166  uint_element_block::delete_block(p);
167  break;
168  case element_type_long:
169  long_element_block::delete_block(p);
170  break;
171  case element_type_ulong:
172  ulong_element_block::delete_block(p);
173  break;
174  case element_type_boolean:
175  boolean_element_block::delete_block(p);
176  break;
177  case element_type_char:
178  char_element_block::delete_block(p);
179  break;
180  case element_type_uchar:
181  uchar_element_block::delete_block(p);
182  break;
183  default:
184  throw general_error("delete_block: failed to delete a block of unknown type.");
185  }
186 }
187 
188 void element_block_func_base::resize_block(base_element_block& block, size_t new_size)
189 {
190  switch (get_block_type(block))
191  {
192  case element_type_numeric:
193  numeric_element_block::resize_block(block, new_size);
194  break;
195  case element_type_string:
196  string_element_block::resize_block(block, new_size);
197  break;
198  case element_type_short:
199  short_element_block::resize_block(block, new_size);
200  break;
201  case element_type_ushort:
202  ushort_element_block::resize_block(block, new_size);
203  break;
204  case element_type_int:
205  int_element_block::resize_block(block, new_size);
206  break;
207  case element_type_uint:
208  uint_element_block::resize_block(block, new_size);
209  break;
210  case element_type_long:
211  long_element_block::resize_block(block, new_size);
212  break;
213  case element_type_ulong:
214  ulong_element_block::resize_block(block, new_size);
215  break;
216  case element_type_boolean:
217  boolean_element_block::resize_block(block, new_size);
218  break;
219  case element_type_char:
220  char_element_block::resize_block(block, new_size);
221  break;
222  case element_type_uchar:
223  uchar_element_block::resize_block(block, new_size);
224  break;
225  default:
226  throw general_error("resize_block: failed to resize a block of unknown type.");
227  }
228 }
229 
230 void element_block_func_base::print_block(const base_element_block& block)
231 {
232  switch (get_block_type(block))
233  {
234  case element_type_numeric:
235  numeric_element_block::print_block(block);
236  break;
237  case element_type_string:
238  string_element_block::print_block(block);
239  break;
240  case element_type_short:
241  short_element_block::print_block(block);
242  break;
243  case element_type_ushort:
244  ushort_element_block::print_block(block);
245  break;
246  case element_type_int:
247  int_element_block::print_block(block);
248  break;
249  case element_type_uint:
250  uint_element_block::print_block(block);
251  break;
252  case element_type_long:
253  long_element_block::print_block(block);
254  break;
255  case element_type_ulong:
256  ulong_element_block::print_block(block);
257  break;
258  case element_type_boolean:
259  boolean_element_block::print_block(block);
260  break;
261  case element_type_char:
262  char_element_block::print_block(block);
263  break;
264  case element_type_uchar:
265  uchar_element_block::print_block(block);
266  break;
267  default:
268  throw general_error("print_block: failed to print a block of unknown type.");
269  }
270 }
271 
272 void element_block_func_base::erase(base_element_block& block, size_t pos)
273 {
274  switch (get_block_type(block))
275  {
276  case element_type_numeric:
277  numeric_element_block::erase_block(block, pos);
278  break;
279  case element_type_string:
280  string_element_block::erase_block(block, pos);
281  break;
282  case element_type_short:
283  short_element_block::erase_block(block, pos);
284  break;
285  case element_type_ushort:
286  ushort_element_block::erase_block(block, pos);
287  break;
288  case element_type_int:
289  int_element_block::erase_block(block, pos);
290  break;
291  case element_type_uint:
292  uint_element_block::erase_block(block, pos);
293  break;
294  case element_type_long:
295  long_element_block::erase_block(block, pos);
296  break;
297  case element_type_ulong:
298  ulong_element_block::erase_block(block, pos);
299  break;
300  case element_type_boolean:
301  boolean_element_block::erase_block(block, pos);
302  break;
303  case element_type_char:
304  char_element_block::erase_block(block, pos);
305  break;
306  case element_type_uchar:
307  uchar_element_block::erase_block(block, pos);
308  break;
309  default:
310  throw general_error("erase: failed to erase an element from a block of unknown type.");
311  }
312 }
313 
314 void element_block_func_base::erase(base_element_block& block, size_t pos, size_t size)
315 {
316  switch (get_block_type(block))
317  {
318  case element_type_numeric:
319  numeric_element_block::erase_block(block, pos, size);
320  break;
321  case element_type_string:
322  string_element_block::erase_block(block, pos, size);
323  break;
324  case element_type_short:
325  short_element_block::erase_block(block, pos, size);
326  break;
327  case element_type_ushort:
328  ushort_element_block::erase_block(block, pos, size);
329  break;
330  case element_type_int:
331  int_element_block::erase_block(block, pos, size);
332  break;
333  case element_type_uint:
334  uint_element_block::erase_block(block, pos, size);
335  break;
336  case element_type_long:
337  long_element_block::erase_block(block, pos, size);
338  break;
339  case element_type_ulong:
340  ulong_element_block::erase_block(block, pos, size);
341  break;
342  case element_type_boolean:
343  boolean_element_block::erase_block(block, pos, size);
344  break;
345  case element_type_char:
346  char_element_block::erase_block(block, pos, size);
347  break;
348  case element_type_uchar:
349  uchar_element_block::erase_block(block, pos, size);
350  break;
351  default:
352  throw general_error("erase: failed to erase elements from a block of unknown type.");
353  }
354 }
355 
356 void element_block_func_base::append_values_from_block(base_element_block& dest, const base_element_block& src)
357 {
358  switch (get_block_type(dest))
359  {
360  case element_type_numeric:
361  numeric_element_block::append_values_from_block(dest, src);
362  break;
363  case element_type_string:
364  string_element_block::append_values_from_block(dest, src);
365  break;
366  case element_type_short:
367  short_element_block::append_values_from_block(dest, src);
368  break;
369  case element_type_ushort:
370  ushort_element_block::append_values_from_block(dest, src);
371  break;
372  case element_type_int:
373  int_element_block::append_values_from_block(dest, src);
374  break;
375  case element_type_uint:
376  uint_element_block::append_values_from_block(dest, src);
377  break;
378  case element_type_long:
379  long_element_block::append_values_from_block(dest, src);
380  break;
381  case element_type_ulong:
382  ulong_element_block::append_values_from_block(dest, src);
383  break;
384  case element_type_boolean:
385  boolean_element_block::append_values_from_block(dest, src);
386  break;
387  case element_type_char:
388  char_element_block::append_values_from_block(dest, src);
389  break;
390  case element_type_uchar:
391  uchar_element_block::append_values_from_block(dest, src);
392  break;
393  default:
394  throw general_error("append_values: failed to append values to a block of unknown type.");
395  }
396 }
397 
398 void element_block_func_base::append_values_from_block(
399  base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len)
400 {
401  switch (get_block_type(dest))
402  {
403  case element_type_numeric:
404  numeric_element_block::append_values_from_block(dest, src, begin_pos, len);
405  break;
406  case element_type_string:
407  string_element_block::append_values_from_block(dest, src, begin_pos, len);
408  break;
409  case element_type_short:
410  short_element_block::append_values_from_block(dest, src, begin_pos, len);
411  break;
412  case element_type_ushort:
413  ushort_element_block::append_values_from_block(dest, src, begin_pos, len);
414  break;
415  case element_type_int:
416  int_element_block::append_values_from_block(dest, src, begin_pos, len);
417  break;
418  case element_type_uint:
419  uint_element_block::append_values_from_block(dest, src, begin_pos, len);
420  break;
421  case element_type_long:
422  long_element_block::append_values_from_block(dest, src, begin_pos, len);
423  break;
424  case element_type_ulong:
425  ulong_element_block::append_values_from_block(dest, src, begin_pos, len);
426  break;
427  case element_type_boolean:
428  boolean_element_block::append_values_from_block(dest, src, begin_pos, len);
429  break;
430  case element_type_char:
431  char_element_block::append_values_from_block(dest, src, begin_pos, len);
432  break;
433  case element_type_uchar:
434  uchar_element_block::append_values_from_block(dest, src, begin_pos, len);
435  break;
436  default:
437  throw general_error("append_values: failed to append values to a block of unknown type.");
438  }
439 }
440 
441 void element_block_func_base::assign_values_from_block(
442  base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len)
443 {
444  switch (get_block_type(dest))
445  {
446  case element_type_numeric:
447  numeric_element_block::assign_values_from_block(dest, src, begin_pos, len);
448  break;
449  case element_type_string:
450  string_element_block::assign_values_from_block(dest, src, begin_pos, len);
451  break;
452  case element_type_short:
453  short_element_block::assign_values_from_block(dest, src, begin_pos, len);
454  break;
455  case element_type_ushort:
456  ushort_element_block::assign_values_from_block(dest, src, begin_pos, len);
457  break;
458  case element_type_int:
459  int_element_block::assign_values_from_block(dest, src, begin_pos, len);
460  break;
461  case element_type_uint:
462  uint_element_block::assign_values_from_block(dest, src, begin_pos, len);
463  break;
464  case element_type_long:
465  long_element_block::assign_values_from_block(dest, src, begin_pos, len);
466  break;
467  case element_type_ulong:
468  ulong_element_block::assign_values_from_block(dest, src, begin_pos, len);
469  break;
470  case element_type_boolean:
471  boolean_element_block::assign_values_from_block(dest, src, begin_pos, len);
472  break;
473  case element_type_char:
474  char_element_block::assign_values_from_block(dest, src, begin_pos, len);
475  break;
476  case element_type_uchar:
477  uchar_element_block::assign_values_from_block(dest, src, begin_pos, len);
478  break;
479  default:
480  throw general_error("assign_values_from_block: failed to assign values to a block of unknown type.");
481  }
482 }
483 
484 void element_block_func_base::prepend_values_from_block(
485  base_element_block& dest, const base_element_block& src, size_t begin_pos, size_t len)
486 {
487  switch (get_block_type(dest))
488  {
489  case element_type_numeric:
490  numeric_element_block::prepend_values_from_block(dest, src, begin_pos, len);
491  break;
492  case element_type_string:
493  string_element_block::prepend_values_from_block(dest, src, begin_pos, len);
494  break;
495  case element_type_short:
496  short_element_block::prepend_values_from_block(dest, src, begin_pos, len);
497  break;
498  case element_type_ushort:
499  ushort_element_block::prepend_values_from_block(dest, src, begin_pos, len);
500  break;
501  case element_type_int:
502  int_element_block::prepend_values_from_block(dest, src, begin_pos, len);
503  break;
504  case element_type_uint:
505  uint_element_block::prepend_values_from_block(dest, src, begin_pos, len);
506  break;
507  case element_type_long:
508  long_element_block::prepend_values_from_block(dest, src, begin_pos, len);
509  break;
510  case element_type_ulong:
511  ulong_element_block::prepend_values_from_block(dest, src, begin_pos, len);
512  break;
513  case element_type_boolean:
514  boolean_element_block::prepend_values_from_block(dest, src, begin_pos, len);
515  break;
516  case element_type_char:
517  char_element_block::prepend_values_from_block(dest, src, begin_pos, len);
518  break;
519  case element_type_uchar:
520  uchar_element_block::prepend_values_from_block(dest, src, begin_pos, len);
521  break;
522  default:
523  throw general_error("prepend_values_from_block: failed to prepend values to a block of unknown type.");
524  }
525 }
526 
527 void element_block_func_base::swap_values(
528  base_element_block& blk1, base_element_block& blk2, size_t pos1, size_t pos2, size_t len)
529 {
530  element_t blk1_type = get_block_type(blk1);
531  assert(blk1_type == get_block_type(blk2));
532  switch (blk1_type)
533  {
534  case element_type_numeric:
535  numeric_element_block::swap_values(blk1, blk2, pos1, pos2, len);
536  break;
537  case element_type_string:
538  string_element_block::swap_values(blk1, blk2, pos1, pos2, len);
539  break;
540  case element_type_short:
541  short_element_block::swap_values(blk1, blk2, pos1, pos2, len);
542  break;
543  case element_type_ushort:
544  ushort_element_block::swap_values(blk1, blk2, pos1, pos2, len);
545  break;
546  case element_type_int:
547  int_element_block::swap_values(blk1, blk2, pos1, pos2, len);
548  break;
549  case element_type_uint:
550  uint_element_block::swap_values(blk1, blk2, pos1, pos2, len);
551  break;
552  case element_type_long:
553  long_element_block::swap_values(blk1, blk2, pos1, pos2, len);
554  break;
555  case element_type_ulong:
556  ulong_element_block::swap_values(blk1, blk2, pos1, pos2, len);
557  break;
558  case element_type_boolean:
559  boolean_element_block::swap_values(blk1, blk2, pos1, pos2, len);
560  break;
561  case element_type_char:
562  char_element_block::swap_values(blk1, blk2, pos1, pos2, len);
563  break;
564  case element_type_uchar:
565  uchar_element_block::swap_values(blk1, blk2, pos1, pos2, len);
566  break;
567  default:
568  throw general_error("swap_values: block of unknown type.");
569  }
570 }
571 
572 bool element_block_func_base::equal_block(const base_element_block& left, const base_element_block& right)
573 {
574  element_t block_type = get_block_type(left);
575  if (block_type != get_block_type(right))
576  return false;
577 
578  switch (block_type)
579  {
580  case element_type_numeric:
581  return numeric_element_block::get(left) == numeric_element_block::get(right);
582  case element_type_string:
583  return string_element_block::get(left) == string_element_block::get(right);
584  case element_type_short:
585  return short_element_block::get(left) == short_element_block::get(right);
586  case element_type_ushort:
587  return ushort_element_block::get(left) == ushort_element_block::get(right);
588  case element_type_int:
589  return int_element_block::get(left) == int_element_block::get(right);
590  case element_type_uint:
591  return uint_element_block::get(left) == uint_element_block::get(right);
592  case element_type_long:
593  return long_element_block::get(left) == long_element_block::get(right);
594  case element_type_ulong:
595  return ulong_element_block::get(left) == ulong_element_block::get(right);
596  case element_type_boolean:
597  return boolean_element_block::get(left) == boolean_element_block::get(right);
598  case element_type_char:
599  return char_element_block::get(left) == char_element_block::get(right);
600  case element_type_uchar:
601  return uchar_element_block::get(left) == uchar_element_block::get(right);
602  default:
603  ;
604  }
605  return false;
606 }
607 
609 {
610  // Do nothing for the standard types.
611 }
612 
613 void element_block_func_base::shrink_to_fit(base_element_block& block)
614 {
615  switch (get_block_type(block))
616  {
617  case element_type_numeric:
618  numeric_element_block::shrink_to_fit(block);
619  break;
620  case element_type_string:
621  string_element_block::shrink_to_fit(block);
622  break;
623  case element_type_short:
624  short_element_block::shrink_to_fit(block);
625  break;
626  case element_type_ushort:
627  ushort_element_block::shrink_to_fit(block);
628  break;
629  case element_type_int:
630  int_element_block::shrink_to_fit(block);
631  break;
632  case element_type_uint:
633  uint_element_block::shrink_to_fit(block);
634  break;
635  case element_type_long:
636  long_element_block::shrink_to_fit(block);
637  break;
638  case element_type_ulong:
639  ulong_element_block::shrink_to_fit(block);
640  break;
641  case element_type_boolean:
642  boolean_element_block::shrink_to_fit(block);
643  break;
644  case element_type_char:
645  char_element_block::shrink_to_fit(block);
646  break;
647  case element_type_uchar:
648  uchar_element_block::shrink_to_fit(block);
649  break;
650  default:
651  throw general_error("shrink_to_fit: failed to print a block of unknown type.");
652  }
653 }
654 
660 
661 }}
662 
663 #endif
Definition: multi_type_vector_trait.hpp:37
Definition: multi_type_vector_trait.hpp:659
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:608