@@ -15,99 +15,139 @@ limitations under the License.
1515
1616#include " tensorflow/lite/core/c/common.h"
1717
18+ #ifndef TF_LITE_STATIC_MEMORY
19+ #include < cstdlib>
20+ #endif // TF_LITE_STATIC_MEMORY
21+
22+ #include < cstring>
23+ #include < type_traits>
24+ #include < utility>
25+
1826#include " tensorflow/lite/core/c/c_api_types.h"
1927#ifdef TF_LITE_TENSORFLOW_PROFILER
2028#include " tensorflow/lite/tensorflow_profiler_logger.h"
2129#endif
2230
31+ namespace {
32+
33+ template <class T >
34+ size_t TfLiteVarArrayGetSizeInBytes (const int size) {
35+ constexpr size_t data_size = sizeof (std::declval<T>().data [0 ]);
36+ size_t computed_size = sizeof (T) + data_size * size;
37+ #if defined(_MSC_VER)
38+ // Context for why this is needed is in http://b/189926408#comment21
39+ computed_size -= data_size;
40+ #endif
41+ return computed_size;
42+ }
43+
44+ template <class T , class U >
45+ int TfLiteVarArrayEqualsArray (const T* const a, const int b_size,
46+ const U* const b_data) {
47+ static_assert (std::is_same<decltype (a->data [0 ]), const U&>::value,
48+ " TfLiteVarArrayEqualsArray can only compare same type arrays" );
49+ if (a == nullptr ) {
50+ return b_size == 0 ;
51+ }
52+ if (a->size != b_size) {
53+ return 0 ;
54+ }
55+ return !memcmp (a->data , b_data, a->size * sizeof (a->data [0 ]));
56+ }
57+
58+ template <class T >
59+ int TfLiteVarArrayEqual (const T* const a, const T* const b) {
60+ // This goes first because null arrays must compare equal.
61+ if (a == b) {
62+ return 1 ;
63+ }
64+ if (a == nullptr || b == nullptr ) {
65+ return 0 ;
66+ }
67+ return TfLiteVarArrayEqualsArray (a, b->size , b->data );
68+ }
69+
2370#ifndef TF_LITE_STATIC_MEMORY
24- #include < stdlib.h>
25- #include < string.h>
71+
72+ template <class T >
73+ T* TfLiteVarArrayCreate (const int size) {
74+ const size_t alloc_size = TfLiteVarArrayGetSizeInBytes<T>(size);
75+ if (alloc_size <= 0 ) {
76+ return nullptr ;
77+ }
78+ T* ret = (T*)malloc (alloc_size);
79+ if (!ret) {
80+ return nullptr ;
81+ }
82+ ret->size = size;
83+ return ret;
84+ }
85+
86+ template <class T >
87+ T* TfLiteVarArrayCopy (const T* const src) {
88+ if (!src) {
89+ return nullptr ;
90+ }
91+ T* const ret = TfLiteVarArrayCreate<T>(src->size );
92+ if (ret) {
93+ memcpy (ret->data , src->data , src->size * sizeof (src->data [0 ]));
94+ }
95+ return ret;
96+ }
97+
2698#endif // TF_LITE_STATIC_MEMORY
2799
100+ template <class T >
101+ void TfLiteVarArrayFree (T* a) {
102+ free (a);
103+ }
104+
105+ } // namespace
106+
28107extern " C" {
29108
30109size_t TfLiteIntArrayGetSizeInBytes (int size) {
31- static TfLiteIntArray dummy;
32-
33- size_t computed_size = sizeof (dummy) + sizeof (dummy.data [0 ]) * size;
34- #if defined(_MSC_VER)
35- // Context for why this is needed is in http://b/189926408#comment21
36- computed_size -= sizeof (dummy.data [0 ]);
37- #endif
38- return computed_size;
110+ return TfLiteVarArrayGetSizeInBytes<TfLiteIntArray>(size);
39111}
40112
41113int TfLiteIntArrayEqual (const TfLiteIntArray* a, const TfLiteIntArray* b) {
42- if (a == b) return 1 ;
43- if (a == nullptr || b == nullptr ) return 0 ;
44- return TfLiteIntArrayEqualsArray (a, b->size , b->data );
114+ return TfLiteVarArrayEqual (a, b);
45115}
46116
47117int TfLiteIntArrayEqualsArray (const TfLiteIntArray* a, int b_size,
48118 const int b_data[]) {
49- if (a == nullptr ) return (b_size == 0 );
50- if (a->size != b_size) return 0 ;
51- int i = 0 ;
52- for (; i < a->size ; i++)
53- if (a->data [i] != b_data[i]) return 0 ;
54- return 1 ;
119+ return TfLiteVarArrayEqualsArray (a, b_size, b_data);
55120}
56121
57122#ifndef TF_LITE_STATIC_MEMORY
58123
59124TfLiteIntArray* TfLiteIntArrayCreate (int size) {
60- size_t alloc_size = TfLiteIntArrayGetSizeInBytes (size);
61- if (alloc_size <= 0 ) return nullptr ;
62- TfLiteIntArray* ret = (TfLiteIntArray*)malloc (alloc_size);
63- if (!ret) return ret;
64- ret->size = size;
65- return ret;
125+ return TfLiteVarArrayCreate<TfLiteIntArray>(size);
66126}
67127
68128TfLiteIntArray* TfLiteIntArrayCopy (const TfLiteIntArray* src) {
69- if (!src) return nullptr ;
70- TfLiteIntArray* ret = TfLiteIntArrayCreate (src->size );
71- if (ret) {
72- memcpy (ret->data , src->data , src->size * sizeof (int ));
73- }
74- return ret;
129+ return TfLiteVarArrayCopy (src);
75130}
76131
77- void TfLiteIntArrayFree (TfLiteIntArray* a) { free (a); }
132+ void TfLiteIntArrayFree (TfLiteIntArray* a) { TfLiteVarArrayFree (a); }
78133
79134#endif // TF_LITE_STATIC_MEMORY
80135
81136int TfLiteFloatArrayGetSizeInBytes (int size) {
82- static TfLiteFloatArray dummy;
83-
84- int computed_size = sizeof (dummy) + sizeof (dummy.data [0 ]) * size;
85- #if defined(_MSC_VER)
86- // Context for why this is needed is in http://b/189926408#comment21
87- computed_size -= sizeof (dummy.data [0 ]);
88- #endif
89- return computed_size;
137+ return TfLiteVarArrayGetSizeInBytes<TfLiteFloatArray>(size);
90138}
91139
92140#ifndef TF_LITE_STATIC_MEMORY
93141
94142TfLiteFloatArray* TfLiteFloatArrayCreate (int size) {
95- TfLiteFloatArray* ret =
96- (TfLiteFloatArray*)malloc (TfLiteFloatArrayGetSizeInBytes (size));
97- ret->size = size;
98- return ret;
143+ return TfLiteVarArrayCreate<TfLiteFloatArray>(size);
99144}
100145
101146TfLiteFloatArray* TfLiteFloatArrayCopy (const TfLiteFloatArray* src) {
102- if (!src) return nullptr ;
103- TfLiteFloatArray* ret = TfLiteFloatArrayCreate (src->size );
104- if (ret) {
105- memcpy (ret->data , src->data , src->size * sizeof (float ));
106- }
107- return ret;
147+ return TfLiteVarArrayCopy (src);
108148}
109149
110- void TfLiteFloatArrayFree (TfLiteFloatArray* a) { free (a); }
150+ void TfLiteFloatArrayFree (TfLiteFloatArray* a) { TfLiteVarArrayFree (a); }
111151
112152void TfLiteTensorDataFree (TfLiteTensor* t) {
113153 if (t->allocation_type == kTfLiteVariantObject ) {
0 commit comments