1 #ifndef teca_variant_array_h
2 #define teca_variant_array_h
13 #include <type_traits>
18 #include "teca_binary_stream.h"
19 #include "teca_bad_cast.h"
27 using p_teca_string_array = std::shared_ptr<teca_variant_array_impl<std::string>>;
28 using const_p_teca_string_array = std::shared_ptr<const teca_variant_array_impl<std::string>>;
31 using p_teca_float_array = std::shared_ptr<teca_variant_array_impl<float>>;
32 using const_p_teca_float_array = std::shared_ptr<const teca_variant_array_impl<float>>;
35 using p_teca_double_array = std::shared_ptr<teca_variant_array_impl<double>>;
36 using const_p_teca_double_array = std::shared_ptr<const teca_variant_array_impl<double>>;
39 using p_teca_char_array = std::shared_ptr<teca_variant_array_impl<char>>;
40 using const_p_teca_char_array = std::shared_ptr<const teca_variant_array_impl<char>>;
43 using p_teca_unsigned_char_array = std::shared_ptr<teca_variant_array_impl<unsigned char>>;
44 using const_p_teca_unsigned_char_array = std::shared_ptr<const teca_variant_array_impl<unsigned char>>;
47 using p_teca_short_array = std::shared_ptr<teca_variant_array_impl<short>>;
48 using const_p_teca_short_array = std::shared_ptr<const teca_variant_array_impl<short>>;
51 using p_teca_unsigned_short_array = std::shared_ptr<teca_variant_array_impl<unsigned short>>;
52 using const_p_teca_unsigned_short_array = std::shared_ptr<const teca_variant_array_impl<unsigned short>>;
55 using p_teca_int_array = std::shared_ptr<teca_variant_array_impl<int>>;
56 using const_p_teca_int_array = std::shared_ptr<const teca_variant_array_impl<int>>;
59 using p_teca_unsigned_int_array = std::shared_ptr<teca_variant_array_impl<unsigned int>>;
60 using const_p_teca_unsigned_int_array = std::shared_ptr<const teca_variant_array_impl<unsigned int>>;
63 using p_teca_long_array = std::shared_ptr<teca_variant_array_impl<long>>;
64 using const_p_teca_long_array = std::shared_ptr<const teca_variant_array_impl<long>>;
67 using p_teca_unsigned_long_array = std::shared_ptr<teca_variant_array_impl<unsigned long>>;
68 using const_p_teca_unsigned_long_array = std::shared_ptr<const teca_variant_array_impl<unsigned long>>;
71 using p_teca_long_long_array = std::shared_ptr<teca_variant_array_impl<long long>>;
72 using const_p_teca_long_long_array = std::shared_ptr<const teca_variant_array_impl<long long>>;
75 using p_teca_unsigned_long_long_array = std::shared_ptr<teca_variant_array_impl<unsigned long long>>;
76 using const_p_teca_unsigned_long_long_array = std::shared_ptr<const teca_variant_array_impl<unsigned long long>>;
79 using p_teca_size_t_array = std::shared_ptr<teca_variant_array_impl<size_t>>;
80 using const_p_teca_size_t_array = std::shared_ptr<const teca_variant_array_impl<size_t>>;
88 #define TECA_VARIANT_ARRAY_STATIC_NEW(T, t) \
91 static std::shared_ptr<T<t>> New() \
93 return std::shared_ptr<T<t>>(new T<t>); \
97 static std::shared_ptr<T<t>> New(size_t n) \
99 return std::shared_ptr<T<t>>(new T<t>(n)); \
103 static std::shared_ptr<T<t>> New(size_t n, const t &v) \
105 return std::shared_ptr<T<t>>(new T<t>(n, v)); \
109 static std::shared_ptr<T<t>> New(const t *vals, size_t n) \
111 return std::shared_ptr<T<t>>(new T<t>(vals, n)); \
114 using teca_variant_array::shared_from_this; \
116 std::shared_ptr<T> shared_from_this() \
118 return std::static_pointer_cast<T>(shared_from_this()); \
121 std::shared_ptr<T const> shared_from_this() const \
123 return std::static_pointer_cast<T const>(shared_from_this()); \
135 template <
typename T>
136 struct pod_dispatch :
137 std::integral_constant<bool,
138 std::is_arithmetic<T>::value>
142 template <
typename T>
143 struct object_dispatch :
144 std::integral_constant<bool,
145 !std::is_arithmetic<T>::value>
161 #define TEMPLATE_DISPATCH_CASE(tt, nt, p, body) \
162 if (dynamic_cast<tt<nt>*>(p)) \
184 #define NESTED_TEMPLATE_DISPATCH_CASE(tt, nt, p, i, body) \
185 if (dynamic_cast<tt<nt>*>(p)) \
187 using TT##i = tt<nt>; \
193 #define TEMPLATE_DISPATCH_FP(t, p, body) \
194 TEMPLATE_DISPATCH_CASE(t, float, p, body) \
195 else TEMPLATE_DISPATCH_CASE(t, double, p, body)
198 #define TEMPLATE_DISPATCH_SI(t, p, body) \
199 TEMPLATE_DISPATCH_CASE(t, long long, p, body) \
200 else TEMPLATE_DISPATCH_CASE(t, long, p, body) \
201 else TEMPLATE_DISPATCH_CASE(t, int, p, body) \
202 else TEMPLATE_DISPATCH_CASE(t, short int, p, body) \
203 else TEMPLATE_DISPATCH_CASE(t, char, p, body)
206 #define TEMPLATE_DISPATCH_FP_SI(t, p, body) \
207 TEMPLATE_DISPATCH_CASE(t, float, p, body) \
208 else TEMPLATE_DISPATCH_CASE(t, double, p, body) \
209 else TEMPLATE_DISPATCH_SI(t, p, body)
212 #define TEMPLATE_DISPATCH_I(t, p, body) \
213 TEMPLATE_DISPATCH_CASE(t, long long, p, body) \
214 else TEMPLATE_DISPATCH_CASE(t, unsigned long long, p, body) \
215 else TEMPLATE_DISPATCH_CASE(t, long, p, body) \
216 else TEMPLATE_DISPATCH_CASE(t, int, p, body) \
217 else TEMPLATE_DISPATCH_CASE(t, unsigned int, p, body) \
218 else TEMPLATE_DISPATCH_CASE(t, unsigned long, p, body) \
219 else TEMPLATE_DISPATCH_CASE(t, short int, p, body) \
220 else TEMPLATE_DISPATCH_CASE(t, short unsigned int, p, body) \
221 else TEMPLATE_DISPATCH_CASE(t, char, p, body) \
222 else TEMPLATE_DISPATCH_CASE(t, unsigned char, p, body)
231 #define TEMPLATE_DISPATCH(t, p, body) \
232 TEMPLATE_DISPATCH_FP(t, p, body) \
233 else TEMPLATE_DISPATCH_I(t, p, body)
243 #define NESTED_TEMPLATE_DISPATCH_FP(t, p, i, body) \
244 NESTED_TEMPLATE_DISPATCH_CASE(t, float, p, i, body) \
245 else NESTED_TEMPLATE_DISPATCH_CASE(t, double, p, i, body)
255 #define NESTED_TEMPLATE_DISPATCH_I(t, p, i, body) \
256 NESTED_TEMPLATE_DISPATCH_CASE(t, long long, p, i, body) \
257 else NESTED_TEMPLATE_DISPATCH_CASE(t, unsigned long long, p, i, body) \
258 else NESTED_TEMPLATE_DISPATCH_CASE(t, long, p, i, body) \
259 else NESTED_TEMPLATE_DISPATCH_CASE(t, int, p, i, body) \
260 else NESTED_TEMPLATE_DISPATCH_CASE(t, unsigned int, p, i, body) \
261 else NESTED_TEMPLATE_DISPATCH_CASE(t, unsigned long, p, i, body) \
262 else NESTED_TEMPLATE_DISPATCH_CASE(t, short int, p, i, body) \
263 else NESTED_TEMPLATE_DISPATCH_CASE(t, short unsigned int, p, i, body) \
264 else NESTED_TEMPLATE_DISPATCH_CASE(t, char, p, i, body) \
265 else NESTED_TEMPLATE_DISPATCH_CASE(t, unsigned char, p, i, body)
276 #define NESTED_TEMPLATE_DISPATCH(t, p, i, body) \
277 NESTED_TEMPLATE_DISPATCH_FP(t, p, i, body) \
278 else NESTED_TEMPLATE_DISPATCH_I(t, p, i, body)
300 { this->copy(other);
return *
this; }
304 { this->swap(other);
return *
this; }
318 {
return this->equal(other); }
321 virtual std::string get_class_name()
const = 0;
324 virtual void initialize() = 0;
329 void get(
unsigned long i, T &val)
const
330 { this->get_dispatch<T>(i, val); }
333 void get(std::vector<T> &vals)
const
334 { this->get_dispatch<T>(vals); }
337 void get(
size_t start,
size_t end, T *vals)
const
338 { this->get_dispatch<T>(start, end, vals); }
343 void set(
const std::vector<T> &vals)
344 { this->set_dispatch<T>(vals); }
347 void set(
unsigned long i,
const T &val)
348 { this->set_dispatch<T>(i, val); }
351 void set(
size_t start,
size_t end,
const T *vals)
352 { this->set_dispatch<T>(start, end, vals); }
357 void append(
const T &val)
358 { this->append_dispatch(val); }
361 void append(
const std::vector<T> &vals)
362 { this->append_dispatch(vals); }
365 virtual unsigned long size()
const noexcept = 0;
368 virtual void resize(
unsigned long i) = 0;
372 virtual void reserve(
unsigned long i) = 0;
375 virtual void clear() noexcept = 0;
384 { this->copy(*other.get()); }
388 { this->append(*other.get()); }
395 { this->swap(*other.get()); }
400 {
return this->equal(*other.get()); }
406 virtual int to_stream(std::ostream &s)
const = 0;
407 virtual int from_stream(std::ostream &s) = 0;
410 virtual unsigned int type_code()
const noexcept = 0;
418 void append_dispatch(
const std::vector<T> &vals,
419 typename std::enable_if<pod_dispatch<T>::value, T>::type* = 0);
422 void append_dispatch(
const std::vector<T> &vals,
423 typename std::enable_if<object_dispatch<T>::value, T>::type* = 0);
426 void append_dispatch(
const T &val,
427 typename std::enable_if<pod_dispatch<T>::value, T>::type* = 0);
430 void append_dispatch(
const T &val,
431 typename std::enable_if<object_dispatch<T>::value, T>::type* = 0);
434 void set_dispatch(
const std::vector<T> &vals,
435 typename std::enable_if<pod_dispatch<T>::value, T>::type* = 0);
438 void set_dispatch(
const std::vector<T> &vals,
439 typename std::enable_if<object_dispatch<T>::value, T>::type* = 0);
442 void set_dispatch(
unsigned long i,
const T &val,
443 typename std::enable_if<pod_dispatch<T>::value, T>::type* = 0);
446 void set_dispatch(
unsigned long i,
const T &val,
447 typename std::enable_if<object_dispatch<T>::value, T>::type* = 0);
450 void set_dispatch(
size_t start,
size_t end,
const T *vals,
451 typename std::enable_if<pod_dispatch<T>::value, T>::type* = 0);
454 void set_dispatch(
size_t start,
size_t end,
const T *vals,
455 typename std::enable_if<object_dispatch<T>::value, T>::type* = 0);
458 void get_dispatch(std::vector<T> &vals,
459 typename std::enable_if<pod_dispatch<T>::value, T>::type* = 0)
const;
462 void get_dispatch(std::vector<T> &vals,
463 typename std::enable_if<object_dispatch<T>::value, T>::type* = 0)
const;
466 void get_dispatch(
unsigned long i, T &val,
467 typename std::enable_if<pod_dispatch<T>::value, T>::type* = 0)
const;
470 void get_dispatch(
unsigned long i, T &val,
471 typename std::enable_if<object_dispatch<T>::value, T>::type* = 0)
const;
474 void get_dispatch(
size_t start,
size_t end, T *vals,
475 typename std::enable_if<pod_dispatch<T>::value, T>::type* = 0)
const;
478 void get_dispatch(
size_t start,
size_t end, T *vals,
479 typename std::enable_if<object_dispatch<T>::value, T>::type* = 0)
const;
488 : std::integral_constant<bool,
489 std::is_arithmetic<T>::value ||
490 std::is_same<T, std::string>::value>
495 struct pack_object_ptr
496 : std::integral_constant<bool,
497 (std::is_pointer<T>::value ||
498 std::is_same<T, p_teca_variant_array>::value) &&
499 !pack_array<T>::value>
505 : std::integral_constant<bool,
506 !pack_array<T>::value &&
507 !std::is_pointer<T>::value &&
508 !pack_object_ptr<T>::value>
566 {
return m_data[i]; }
569 const T &
get(
unsigned long i)
const
570 {
return m_data[i]; }
574 void get(
unsigned long i, U &val)
const;
579 void get(
size_t start,
size_t end, U *vals)
const;
583 void get(std::vector<U> &val)
const;
586 T *
get(){
return &m_data[0]; }
587 const T *
get()
const {
return &m_data[0]; }
591 void set(
unsigned long i,
const U &val);
595 void set(
size_t start,
size_t end,
const U *vals);
599 void set(
const std::vector<U> &val);
603 void append(
const std::vector<U> &val);
607 void append(
const U &val);
610 virtual unsigned long size() const noexcept override;
613 virtual
void resize(
unsigned long n) override;
614 void resize(
unsigned long n, const T &val);
617 virtual
void reserve(
unsigned long n) override;
620 virtual
void clear() noexcept override;
641 this->to_binary<T>(s);
648 this->from_binary<T>(s);
655 this->to_ascii<T>(s);
662 this->from_ascii<T>(s);
695 template <
typename U = T>
697 typename std::enable_if<pack_array<U>::value, U>::type* = 0)
700 template <
typename U = T>
702 typename std::enable_if<pack_array<U>::value, U>::type* = 0);
705 template <
typename U = T>
707 typename std::enable_if<pack_object<U>::value, U>::type* = 0)
710 template <
typename U = T>
712 typename std::enable_if<pack_object<U>::value, U>::type* = 0);
715 template <
typename U = T>
717 typename std::enable_if<pack_object_ptr<U>::value, U>::type* = 0)
720 template <
typename U = T>
722 typename std::enable_if<pack_object_ptr<U>::value, U>::type* = 0);
725 template <
typename U = T>
726 void to_ascii(std::ostream &s,
727 typename std::enable_if<pack_array<U>::value, U>::type* = 0)
730 template <
typename U = T>
731 void from_ascii(std::ostream &s,
732 typename std::enable_if<pack_array<U>::value, U>::type* = 0);
735 template <
typename U = T>
736 void to_ascii(std::ostream &s,
737 typename std::enable_if<pack_object<U>::value, U>::type* = 0)
740 template <
typename U = T>
741 void from_ascii(std::ostream &s,
742 typename std::enable_if<pack_object<U>::value, U>::type* = 0);
745 template <
typename U = T>
746 void to_ascii(std::ostream &s,
747 typename std::enable_if<pack_object_ptr<U>::value, U>::type* = 0)
750 template <
typename U = T>
751 void from_ascii(std::ostream &s,
752 typename std::enable_if<pack_object_ptr<U>::value, U>::type* = 0);
755 unsigned int type_code() const noexcept override;
757 std::vector<T> m_data;
763 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
764 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
768 void teca_variant_array::get_dispatch(std::vector<T> &vals,
769 typename std::enable_if<pod_dispatch<T>::value, T>::type*)
const
772 TT *this_t =
static_cast<TT*
>(
this);
776 throw std::bad_cast();
781 void teca_variant_array::get_dispatch(std::vector<T> &vals,
782 typename std::enable_if<object_dispatch<T>::value, T>::type*)
const
785 TT *this_t =
static_cast<TT*
>(
this);
789 throw std::bad_cast();
794 void teca_variant_array::get_dispatch(
unsigned long i, T &val,
795 typename std::enable_if<pod_dispatch<T>::value, T>::type*)
const
798 TT *this_t =
static_cast<TT*
>(
this);
802 throw std::bad_cast();
807 void teca_variant_array::get_dispatch(
unsigned long i, T &val,
808 typename std::enable_if<object_dispatch<T>::value, T>::type*)
const
811 TT *this_t =
static_cast<TT*
>(
this);
815 throw std::bad_cast();
820 void teca_variant_array::get_dispatch(
size_t start,
size_t end, T *vals,
821 typename std::enable_if<pod_dispatch<T>::value, T>::type*)
const
824 TT *this_t =
static_cast<TT*
>(
this);
825 this_t->
get(start, end, vals);
828 throw std::bad_cast();
833 void teca_variant_array::get_dispatch(
size_t start,
size_t end, T *vals,
834 typename std::enable_if<object_dispatch<T>::value, T>::type*)
const
837 TT *this_t =
static_cast<TT*
>(
this);
838 this_t->
get(start, end, vals);
841 throw std::bad_cast();
846 void teca_variant_array::set_dispatch(
const std::vector<T> &vals,
847 typename std::enable_if<pod_dispatch<T>::value, T>::type*)
850 TT *this_t =
static_cast<TT*
>(
this);
854 throw std::bad_cast();
859 void teca_variant_array::set_dispatch(
const std::vector<T> &vals,
860 typename std::enable_if<object_dispatch<T>::value, T>::type*)
863 TT *this_t =
static_cast<TT*
>(
this);
867 throw std::bad_cast();
872 void teca_variant_array::set_dispatch(
unsigned long i,
const T &val,
873 typename std::enable_if<pod_dispatch<T>::value, T>::type*)
876 TT *this_t =
static_cast<TT*
>(
this);
880 throw std::bad_cast();
885 void teca_variant_array::set_dispatch(
unsigned long i,
const T &val,
886 typename std::enable_if<object_dispatch<T>::value, T>::type*)
889 TT *this_t =
static_cast<TT*
>(
this);
893 throw std::bad_cast();
898 void teca_variant_array::set_dispatch(
size_t start,
size_t end,
const T *vals,
899 typename std::enable_if<pod_dispatch<T>::value, T>::type*)
902 TT *this_t =
static_cast<TT*
>(
this);
903 this_t->
set(start, end, vals);
906 throw std::bad_cast();
911 void teca_variant_array::set_dispatch(
size_t start,
size_t end,
const T *vals,
912 typename std::enable_if<object_dispatch<T>::value, T>::type*)
915 TT *this_t =
static_cast<TT*
>(
this);
916 this_t->
set(start, end, vals);
919 throw std::bad_cast();
924 void teca_variant_array::append_dispatch(
const std::vector<T> &vals,
925 typename std::enable_if<pod_dispatch<T>::value, T>::type*)
928 TT *this_t =
static_cast<TT*
>(
this);
932 throw std::bad_cast();
937 void teca_variant_array::append_dispatch(
const std::vector<T> &vals,
938 typename std::enable_if<object_dispatch<T>::value, T>::type*)
941 TT *this_t =
static_cast<TT*
>(
this);
945 throw std::bad_cast();
950 void teca_variant_array::append_dispatch(
const T &val,
951 typename std::enable_if<pod_dispatch<T>::value, T>::type*)
954 TT *this_t =
static_cast<TT*
>(
this);
958 throw std::bad_cast();
963 void teca_variant_array::append_dispatch(
const T &val,
964 typename std::enable_if<object_dispatch<T>::value, T>::type*)
967 TT *this_t =
static_cast<TT*
>(
this);
971 throw std::bad_cast();
995 size_t start,
size_t end)
const
998 this->
get(start, end, c->get());
1003 template<
typename T>
1010 template<
typename T>
1017 template<
typename T>
1021 m_data.assign(other.m_data.begin(), other.m_data.end());
1027 template<
typename T>
1028 template<
typename U>
1032 m_data.assign(other.m_data.begin(), other.m_data.end());
1037 template<
typename T>
1040 : m_data(std::move(other.m_data))
1044 template<
typename T>
1048 m_data = std::move(other.m_data);
1053 template<
typename T>
1056 const char *element_name =
typeid(T).name();
1057 size_t element_size =
sizeof(T);
1058 std::ostringstream oss;
1059 oss <<
"teca_variant_array_impl<" << element_name
1060 << element_size <<
">";
1065 template<
typename T>
1068 m_data.assign(m_data.size(), T());
1072 template<
typename T>
1073 template<
typename U>
1080 template<
typename T>
1081 template<
typename U>
1084 for (
size_t i = start, ii = 0; i <= end; ++i, ++ii)
1085 vals[ii] = m_data[i];
1089 template<
typename T>
1090 template<
typename U>
1093 val.assign(m_data.begin(), m_data.end());
1097 template<
typename T>
1098 template<
typename U>
1105 template<
typename T>
1106 template<
typename U>
1109 for (
size_t i = start, ii = 0; i <= end; ++i, ++ii)
1110 m_data[i] = vals[ii];
1114 template<
typename T>
1115 template<
typename U>
1118 size_t n = val.size();
1120 for (
size_t i = 0; i < n; ++i)
1121 m_data[i] =
static_cast<T
>(val[i]);
1125 template<
typename T>
1126 template<
typename U>
1129 std::copy(val.begin(), val.end(), std::back_inserter(m_data));
1133 template<
typename T>
1134 template<
typename U>
1137 m_data.push_back(val);
1141 template<
typename T>
1143 {
return m_data.size(); }
1146 template<
typename T>
1153 template<
typename T>
1156 m_data.resize(n, val);
1160 template<
typename T>
1167 template<
typename T>
1174 template<
typename T>
1178 TT *other_t =
static_cast<TT*
>(&other);
1182 throw teca_bad_cast(safe_class_name(&other), safe_class_name(
this));
1186 template<
typename T>
1190 TT *other_t =
static_cast<TT*
>(&other);
1192 other_t->m_data.begin(),
1193 other_t->m_data.end(),
1194 std::back_inserter(this->m_data));
1197 throw teca_bad_cast(safe_class_name(&other), safe_class_name(
this));
1201 template<
typename T>
1205 TT *other_t =
dynamic_cast<TT*
>(&other);
1208 this->m_data.
swap(other_t->m_data);
1211 throw teca_bad_cast(safe_class_name(&other), safe_class_name(
this));
1215 template<
typename T>
1219 const TT *other_t =
dynamic_cast<const TT*
>(&other);
1222 return this->m_data == other_t->m_data;
1224 throw teca_bad_cast(safe_class_name(&other), safe_class_name(
this));
1229 template<
typename T>
1230 template <
typename U>
1233 typename std::enable_if<pack_array<U>::value, U>::type*)
const
1235 s.pack(this->m_data);
1239 template<
typename T>
1240 template <
typename U>
1243 typename std::enable_if<pack_array<U>::value, U>::type*)
1245 s.unpack(this->m_data);
1249 template<
typename T>
1250 template <
typename U>
1253 typename std::enable_if<pack_object<U>::value, U>::type*)
const
1255 unsigned long long n = this->size();
1257 for (
unsigned long long i=0; i<n; ++i)
1258 this->m_data[i].to_stream(s);
1262 template<
typename T>
1263 template <
typename U>
1266 typename std::enable_if<pack_object<U>::value, U>::type*)
1268 unsigned long long n;
1271 for (
unsigned long long i=0; i<n; ++i)
1272 this->m_data[i].from_stream(s);
1276 template<
typename T>
1277 template <
typename U>
1280 typename std::enable_if<pack_object_ptr<U>::value, U>::type*)
const
1282 unsigned long long n = this->size();
1284 for (
unsigned long long i=0; i<n; ++i)
1285 this->m_data[i]->to_stream(s);
1289 template<
typename T>
1290 template <
typename U>
1293 typename std::enable_if<pack_object_ptr<U>::value, U>::type*)
1295 unsigned long long n;
1298 for (
unsigned long long i=0; i<n; ++i)
1299 this->m_data[i]->from_stream(s);
1302 #define STR_DELIM(_a, _b) \
1303 (std::is_same<T, std::string>::value ? _a : _b)
1306 template<
typename T>
1307 template <
typename U>
1310 typename std::enable_if<pack_array<U>::value, U>::type*)
const
1312 size_t n = this->m_data.
size();
1315 s << STR_DELIM(
"\"",
"")
1316 << this->m_data[0] << STR_DELIM(
"\"",
"");
1317 for (
size_t i = 1; i < n; ++i)
1319 s << STR_DELIM(
", \"",
", ")
1320 << this->m_data[i] << STR_DELIM(
"\"",
"");
1326 template<
typename T>
1327 template <
typename U>
1330 typename std::enable_if<pack_array<U>::value, U>::type*)
1336 template<
typename T>
1337 template <
typename U>
1340 typename std::enable_if<pack_object<U>::value, U>::type*)
const
1342 size_t n = this->m_data.
size();
1346 this->m_data[0].to_stream(s);
1348 for (
size_t i = 1; i < n; ++i)
1351 this->m_data[i].to_stream(s);
1358 template<
typename T>
1359 template <
typename U>
1362 typename std::enable_if<pack_object<U>::value, U>::type*)
1368 template<
typename T>
1369 template <
typename U>
1372 typename std::enable_if<pack_object_ptr<U>::value, U>::type*)
const
1374 size_t n = this->m_data.
size();
1378 this->m_data[0]->to_stream(s);
1380 for (
size_t i = 1; i < n; ++i)
1383 this->m_data[i]->to_stream(s);
1390 template<
typename T>
1391 template <
typename U>
1394 typename std::enable_if<pack_object_ptr<U>::value, U>::type*)
1400 template <
typename T>
1401 struct teca_variant_array_code {};
1403 template <
unsigned int I>
1404 struct teca_variant_array_new {};
1406 template <
unsigned int I>
1407 struct teca_variant_array_type {};
1409 #define TECA_VARIANT_ARRAY_TT_SPEC(T, v) \
1411 struct teca_variant_array_code<T> \
1413 static constexpr unsigned int get() \
1417 struct teca_variant_array_new<v> \
1419 static p_teca_variant_array_impl<T> New() \
1420 { return teca_variant_array_impl<T>::New(); } \
1423 struct teca_variant_array_type<v> \
1427 static constexpr const char *name() \
1431 #define TECA_VARIANT_ARRAY_FACTORY_NEW(_v) \
1433 return teca_variant_array_new<_v>::New();
1435 #include "teca_metadata.h"
1438 TECA_VARIANT_ARRAY_TT_SPEC(
char, 1)
1439 TECA_VARIANT_ARRAY_TT_SPEC(
unsigned char, 2)
1440 TECA_VARIANT_ARRAY_TT_SPEC(
int, 3)
1441 TECA_VARIANT_ARRAY_TT_SPEC(
unsigned int, 4)
1442 TECA_VARIANT_ARRAY_TT_SPEC(
short int, 5)
1443 TECA_VARIANT_ARRAY_TT_SPEC(
short unsigned int, 6)
1444 TECA_VARIANT_ARRAY_TT_SPEC(
long, 7)
1445 TECA_VARIANT_ARRAY_TT_SPEC(
unsigned long, 8)
1446 TECA_VARIANT_ARRAY_TT_SPEC(
long long, 9)
1447 TECA_VARIANT_ARRAY_TT_SPEC(
unsigned long long, 10)
1448 TECA_VARIANT_ARRAY_TT_SPEC(
float, 11)
1449 TECA_VARIANT_ARRAY_TT_SPEC(
double, 12)
1450 TECA_VARIANT_ARRAY_TT_SPEC(std::
string, 13)
1462 TECA_VARIANT_ARRAY_FACTORY_NEW(1)
1463 TECA_VARIANT_ARRAY_FACTORY_NEW(2)
1464 TECA_VARIANT_ARRAY_FACTORY_NEW(3)
1465 TECA_VARIANT_ARRAY_FACTORY_NEW(4)
1466 TECA_VARIANT_ARRAY_FACTORY_NEW(5)
1467 TECA_VARIANT_ARRAY_FACTORY_NEW(6)
1468 TECA_VARIANT_ARRAY_FACTORY_NEW(7)
1469 TECA_VARIANT_ARRAY_FACTORY_NEW(8)
1470 TECA_VARIANT_ARRAY_FACTORY_NEW(9)
1471 TECA_VARIANT_ARRAY_FACTORY_NEW(10)
1472 TECA_VARIANT_ARRAY_FACTORY_NEW(11)
1473 TECA_VARIANT_ARRAY_FACTORY_NEW(12)
1474 TECA_VARIANT_ARRAY_FACTORY_NEW(13)
1475 TECA_VARIANT_ARRAY_FACTORY_NEW(14)
1476 TECA_VARIANT_ARRAY_FACTORY_NEW(15)
1479 <<
"Failed to create from "
1487 #define CODE_DISPATCH_CASE(_v, _c, _code) \
1490 using NT = teca_variant_array_type<_c>::type; \
1491 using TT = teca_variant_array_impl<NT>; \
1495 #define CODE_DISPATCH_I(_v, _code) \
1496 CODE_DISPATCH_CASE(_v, 1, _code) \
1497 else CODE_DISPATCH_CASE(_v, 2, _code) \
1498 else CODE_DISPATCH_CASE(_v, 3, _code) \
1499 else CODE_DISPATCH_CASE(_v, 4, _code) \
1500 else CODE_DISPATCH_CASE(_v, 5, _code) \
1501 else CODE_DISPATCH_CASE(_v, 6, _code) \
1502 else CODE_DISPATCH_CASE(_v, 7, _code) \
1503 else CODE_DISPATCH_CASE(_v, 8, _code) \
1504 else CODE_DISPATCH_CASE(_v, 9, _code) \
1505 else CODE_DISPATCH_CASE(_v, 10, _code)
1507 #define CODE_DISPATCH_FP(_v, _code) \
1508 CODE_DISPATCH_CASE(_v, 11, _code) \
1509 else CODE_DISPATCH_CASE(_v, 12, _code)
1511 #define CODE_DISPATCH_CLASS(_v, _code) \
1512 CODE_DISPATCH_CASE(_v, 13, _code) \
1513 else CODE_DISPATCH_CASE(_v, 14, _code) \
1514 else CODE_DISPATCH_CASE(_v, 15, _code)
1516 #define CODE_DISPATCH(_v, _code) \
1517 CODE_DISPATCH_I(_v, _code) \
1518 else CODE_DISPATCH_FP(_v, _code)
1523 template<
typename T>
1526 return teca_variant_array_code<T>::get();
1530 template <
typename num_t>
1533 num_t mn = std::numeric_limits<num_t>::max();
1536 const NT *pa = std::dynamic_pointer_cast<TT>(a)->get();
1537 size_t n = a->size();
1538 for (
size_t i = 0; i < n; ++i)
1539 mn = mn > pa[i] ? pa[i] : mn;
1545 template <
typename num_t>
1552 template <
typename num_t>
1555 num_t mx = std::numeric_limits<num_t>::lowest();
1558 const NT *pa = std::dynamic_pointer_cast<TT>(a)->get();
1559 size_t n = a->size();
1560 for (
size_t i = 0; i < n; ++i)
1561 mx = mx < pa[i] ? pa[i] : mx;
1567 template <
typename num_t>