@@ -55,5 +55,67 @@ class static_var {
5555 }
5656};
5757
58+ template <typename T>
59+ class static_var <T[]> {
60+ public:
61+ static_assert (std::is_same<T, short int >::value || std::is_same<T, unsigned short int >::value ||
62+ std::is_same<T, int >::value || std::is_same<T, unsigned int >::value ||
63+ std::is_same<T, long int >::value || std::is_same<T, unsigned long int >::value ||
64+ std::is_same<T, long long int >::value || std::is_same<T, unsigned long long int >::value ||
65+ std::is_same<T, char >::value || std::is_same<T, unsigned char >::value ||
66+ std::is_same<T, float >::value || std::is_same<T, double >::value || std::is_pointer<T>::value,
67+ " Currently builder::static_var arrays is only supported for basic types\n " );
68+ static_assert (sizeof (T) < MAX_TRACKING_VAR_SIZE, " Currently builder::static_var supports variables of max size "
69+ " = " TOSTRING(MAX_TRACKING_VARIABLE_SIZE));
70+ // Disable copy-assignment and initialization
71+ static_var (const static_var& x) = delete ;
72+ static_var& operator = (const static_var& x) = delete ;
73+ T* val = nullptr ;
74+
75+ T& operator [] (size_t index) {
76+ return val[index];
77+ }
78+ const T& operator [] (size_t index) const {
79+ return val[index];
80+ }
81+ static_var () {
82+ assert (builder_context::current_builder_context != nullptr );
83+ // This val _should_ not be used. But we will insert it to hold place
84+ // for this static var in the list of tuples, otherwise destructor order will be weird
85+ val = new T[1 ];
86+
87+ builder_context::current_builder_context->static_var_tuples .push_back (
88+ tracking_tuple ((unsigned char *)val, 1 ));
89+ }
90+ static_var (const std::initializer_list<T> &list) {
91+ assert (builder_context::current_builder_context != nullptr );
92+ val = new T[list.size ()];
93+ builder_context::current_builder_context->static_var_tuples .push_back (
94+ tracking_tuple ((unsigned char *)val, sizeof (T) * list.size ()));
95+ for (int i = 0 ; i < list.size (); i++) {
96+ val[i] = list[i];
97+ }
98+ }
99+ void resize (size_t s) {
100+ T* new_ptr = new T[s];
101+ assert (builder_context::current_builder_context != nullptr );
102+ assert (builder_context::current_builder_context->static_var_tuples .size () > 0 );
103+ for (size_t i = 0 ; i < builder_context::current_builder_context->static_var_tuples .size (); i++) {
104+ if (builder_context::current_builder_context->static_var_tuples [i].ptr == (unsigned char *)val) {
105+ builder_context::current_builder_context->static_var_tuples [i] = tracking_tuple ((unsigned char *)new_ptr, sizeof (T) * s);
106+ break ;
107+ }
108+ }
109+ delete[] val;
110+ val = new_ptr;
111+ }
112+ ~static_var () {
113+ assert (builder_context::current_builder_context != nullptr );
114+ assert (builder_context::current_builder_context->static_var_tuples .size () > 0 );
115+ assert (builder_context::current_builder_context->static_var_tuples .back ().ptr == (unsigned char *)val);
116+ builder_context::current_builder_context->static_var_tuples .pop_back ();
117+ delete[] val;
118+ }
119+ };
58120} // namespace builder
59121#endif
0 commit comments