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