1 /*
2  * Copyright 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "C2Param_test"
19 
20 #include <gtest/gtest.h>
21 
22 #define __C2_GENERATE_GLOBAL_VARS__
23 #include <C2ParamDef.h>
24 
25 #include <list>
26 
PrintTo(const _C2FieldId & id,::std::ostream * os)27 void PrintTo(const _C2FieldId &id, ::std::ostream* os) {
28     *os << "@" << id._mOffset << "+" << id._mSize;
29 }
30 
PrintTo(const C2FieldDescriptor & fd,::std::ostream * os)31 void PrintTo(const C2FieldDescriptor &fd, ::std::ostream *os) {
32     using FD=C2FieldDescriptor;
33     switch (fd.type()) {
34     case FD::INT32: *os << "i32"; break;
35     case FD::INT64: *os << "i64"; break;
36     case FD::UINT32: *os << "u32"; break;
37     case FD::UINT64: *os << "u64"; break;
38     case FD::FLOAT: *os << "float"; break;
39     case FD::STRING: *os << "char"; break;
40     case FD::BLOB: *os << "u8"; break;
41     default:
42         if (fd.type() & FD::STRUCT_FLAG) {
43             *os << "struct-" << (fd.type() & ~FD::STRUCT_FLAG);
44         } else {
45             *os << "type-" << fd.type();
46         }
47     }
48     *os << " " << fd.name();
49     if (fd.extent() > 1) {
50         *os << "[" << fd.extent() << "]";
51     } else if (fd.extent() == 0) {
52         *os << "[]";
53     }
54     *os << " (";
55     PrintTo(fd._mFieldId, os);
56     *os << "*" << fd.extent() << ")";
57 }
58 
59 enum C2ParamIndexType : C2Param::type_index_t {
60     kParamIndexNumber,
61     kParamIndexNumbers,
62     kParamIndexNumber2,
63     kParamIndexVendorStart = C2Param::TYPE_INDEX_VENDOR_START,
64     kParamIndexVendorNumbers,
65 };
66 
ffff(int (*)(int))67 void ffff(int(*)(int)) {}
68 
69 /* ============================= STRUCT DECLARATION AND DESCRIPTION ============================= */
70 
71 typedef C2FieldDescriptor FD;
72 
73 class C2ParamTest : public ::testing::Test {
74 };
75 
76 class C2ParamTest_ParamFieldList
77         : public ::testing::TestWithParam<std::vector<C2FieldDescriptor>> {
78 };
79 
80 enum {
81     kParamIndexSize,
82     kParamIndexTestA,
83     kParamIndexTestB,
84     kParamIndexTestFlexS32,
85     kParamIndexTestFlexEndS32,
86     kParamIndexTestFlexS64,
87     kParamIndexTestFlexEndS64,
88     kParamIndexTestFlexSize,
89     kParamIndexTestFlexEndSize,
90 };
91 
92 struct C2SizeStruct {
93     int32_t width;
94     int32_t height;
95     enum : uint32_t { CORE_INDEX = kParamIndexSize };                        // <= needed for C2FieldDescriptor
96     const static std::vector<C2FieldDescriptor> _FIELD_LIST;
97     static const std::vector<C2FieldDescriptor> FieldList();  // <= needed for C2FieldDescriptor
98     const static FD::type_t TYPE = (FD::type_t)(CORE_INDEX | FD::STRUCT_FLAG);
99 } C2_PACK;
100 
101 DEFINE_NO_NAMED_VALUES_FOR(C2SizeStruct)
102 
103 // Test 1. define a structure without any helper methods
104 
105 bool operator==(const C2FieldDescriptor &a, const C2FieldDescriptor &b) {
106     return a.type() == b.type()
107             && a.extent() == b.extent()
108             && a.name() == b.name()
109             && a._mFieldId == b._mFieldId;
110 }
111 
112 struct C2TestStruct_A {
113     int32_t signed32;
114     // 4-byte padding
115     int64_t signed64[2];
116     uint32_t unsigned32[1];
117     // 4-byte padding
118     uint64_t unsigned64;
119     float fp32;
120     C2SizeStruct sz[3]; // 8-byte structure, but 4-byte aligned
121     uint8_t blob[100];
122     char string[100];
123     bool yesNo[100];
124 
125     const static std::vector<C2FieldDescriptor> _FIELD_LIST;
126     static const std::vector<C2FieldDescriptor> FieldList();
127     // enum : uint32_t { CORE_INDEX = kParamIndexTest };
128     // typedef C2TestStruct_A _type;
129 } __attribute__((aligned(4)));
130 
FieldList()131 const std::vector<C2FieldDescriptor> C2TestStruct_A::FieldList() {
132     return _FIELD_LIST;
133 }
134 const std::vector<C2FieldDescriptor> C2TestStruct_A::_FIELD_LIST =
135     { { FD::INT32,    1, "s32",   0, 4 },
136       { FD::INT64,    2, "s64",   8, 8 },
137       { FD::UINT32,   1, "u32",  24, 4 },
138       { FD::UINT64,   1, "u64",  32, 8 },
139       { FD::FLOAT,    1, "fp",   40, 4 },
140       { C2SizeStruct::TYPE, 3, "size", 44, 8 },
141       { FD::BLOB,   100, "blob", 68, 1 },
142       { FD::STRING, 100, "str", 168, 1 },
143       { FD::BLOB,   100, "y-n", 268, 1 } };
144 
TEST_P(C2ParamTest_ParamFieldList,VerifyStruct)145 TEST_P(C2ParamTest_ParamFieldList, VerifyStruct) {
146     std::vector<C2FieldDescriptor> fields = GetParam(), expected = C2TestStruct_A::_FIELD_LIST;
147 
148     // verify first field descriptor
149     EXPECT_EQ(FD::INT32, fields[0].type());
150     EXPECT_STREQ("s32", fields[0].name().c_str());
151     EXPECT_EQ(1u, fields[0].extent());
152     EXPECT_EQ(_C2FieldId(0, 4), fields[0]._mFieldId);
153 
154     EXPECT_EQ(expected[0], fields[0]);
155     EXPECT_EQ(expected[1], fields[1]);
156     EXPECT_EQ(expected[2], fields[2]);
157     EXPECT_EQ(expected[3], fields[3]);
158     EXPECT_EQ(expected[4], fields[4]);
159     EXPECT_EQ(expected[5], fields[5]);
160     EXPECT_EQ(expected[6], fields[6]);
161     EXPECT_EQ(expected[7], fields[7]);
162     for (size_t i = 8; i < fields.size() && i < expected.size(); ++i) {
163         EXPECT_EQ(expected[i], fields[i]);
164     }
165 }
166 
167 INSTANTIATE_TEST_CASE_P(InitializerList, C2ParamTest_ParamFieldList, ::testing::Values(C2TestStruct_A::_FIELD_LIST));
168 
169 // define fields using C2FieldDescriptor pointer constructor
170 const std::vector<C2FieldDescriptor> C2TestStruct_A_FD_PTR_fieldList =
171     { C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->signed32,   "s32"),
172       C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->signed64,   "s64"),
173       C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->unsigned32, "u32"),
174       C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->unsigned64, "u64"),
175       C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->fp32,      "fp"),
176       C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->sz,       "size"),
177       C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->blob,       "blob"),
178       C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->string,     "str"),
179     //  C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->yesNo,      "y-n")
180     };
181 
182 INSTANTIATE_TEST_CASE_P(PointerConstructor, C2ParamTest_ParamFieldList, ::testing::Values(C2TestStruct_A_FD_PTR_fieldList));
183 
184 // define fields using C2FieldDescriptor member-pointer constructor
185 const std::vector<C2FieldDescriptor> C2TestStruct_A_FD_MEM_PTR_fieldList =
186     { C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::signed32,   "s32"),
187       C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::signed64,   "s64"),
188       C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::unsigned32, "u32"),
189       C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::unsigned64, "u64"),
190       C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::fp32,      "fp"),
191       C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::sz,       "size"),
192       C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::blob,       "blob"),
193       C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::string,     "str"),
194     //  C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::yesNo,      "y-n")
195     };
196 
197 INSTANTIATE_TEST_CASE_P(MemberPointerConstructor, C2ParamTest_ParamFieldList, ::testing::Values(C2TestStruct_A_FD_MEM_PTR_fieldList));
198 
199 // Test 2. define a structure with two-step helper methods
200 
201 struct C2TestAStruct {
202     int32_t signed32;
203     // 4-byte padding
204     int64_t signed64[2];
205     uint32_t unsigned32[1];
206     // 4-byte padding
207     uint64_t unsigned64;
208     float fp32;
209     C2SizeStruct sz[3]; // 8-byte structure, but 4-byte aligned
210     uint8_t blob[100];
211     char string[100];
212     bool yesNo[100];
213 
214 private: // test access level
215     DEFINE_C2STRUCT(TestA)
216 } C2_PACK;
217 
218 DESCRIBE_C2STRUCT(TestA, {
219     C2FIELD(signed32, "s32")
220     C2FIELD(signed64, "s64")
221     C2FIELD(unsigned32, "u32")
222     C2FIELD(unsigned64, "u64")
223     C2FIELD(fp32, "fp")
224     C2FIELD(sz, "size")
225     C2FIELD(blob, "blob")
226     C2FIELD(string, "str")
227     // C2FIELD(yesNo, "y-n")
228 }) // ; optional
229 
230 INSTANTIATE_TEST_CASE_P(DescribeStruct2Step, C2ParamTest_ParamFieldList, ::testing::Values(C2TestAStruct::FieldList()));
231 
232 // Test 3. define a structure with one-step helper method
233 
234 struct C2TestBStruct {
235     int32_t signed32;
236     // 4-byte padding
237     int64_t signed64[2];
238     uint32_t unsigned32[1];
239     // 4-byte padding
240     uint64_t unsigned64;
241     float fp32;
242     C2SizeStruct sz[3]; // 8-byte structure, but 4-byte aligned
243     uint8_t blob[100];
244     char string[100];
245     bool yesNo[100];
246 
247 private: // test access level
248     DEFINE_AND_DESCRIBE_C2STRUCT(TestB)
249 
250     C2FIELD(signed32, "s32")
251     C2FIELD(signed64, "s64")
252     C2FIELD(unsigned32, "u32")
253     C2FIELD(unsigned64, "u64")
254     C2FIELD(fp32, "fp")
255     C2FIELD(sz, "size")
256     C2FIELD(blob, "blob")
257     C2FIELD(string, "str")
258     // C2FIELD(yesNo, "y-n")
259 };
260 
261 INSTANTIATE_TEST_CASE_P(DescribeStruct1Step, C2ParamTest_ParamFieldList, ::testing::Values(C2TestBStruct::FieldList()));
262 
263 // Test 4. flexible members
264 
265 template<typename T>
266 class C2ParamTest_FlexParamFieldList : public ::testing::Test {
267 protected:
268     using type_t=FD::type_t;
269 
270     // static std::vector<std::vector<C2FieldDescriptor>>
271     static std::vector<std::vector<C2FieldDescriptor>>
272             GetLists();
273 
274     constexpr static type_t FlexType =
275             std::is_same<T, int32_t>::value ? FD::INT32 :
276             std::is_same<T, int64_t>::value ? FD::INT64 :
277             std::is_same<T, uint32_t>::value ? FD::UINT32 :
278             std::is_same<T, uint64_t>::value ? FD::UINT64 :
279             std::is_same<T, float>::value ? FD::FLOAT :
280             std::is_same<T, uint8_t>::value ? FD::BLOB :
281             std::is_same<T, char>::value ? FD::STRING :
282             std::is_same<T, C2SizeStruct>::value ? C2SizeStruct::TYPE : (type_t)0;
283     constexpr static size_t FLEX_SIZE = sizeof(T);
284 };
285 
286 typedef ::testing::Types<int32_t, int64_t, C2SizeStruct> FlexTypes;
287 TYPED_TEST_CASE(C2ParamTest_FlexParamFieldList, FlexTypes);
288 
TYPED_TEST(C2ParamTest_FlexParamFieldList,VerifyStruct)289 TYPED_TEST(C2ParamTest_FlexParamFieldList, VerifyStruct) {
290     for (auto a : this->GetLists()) {
291         std::vector<C2FieldDescriptor> fields = a;
292         if (fields.size() > 1) {
293             EXPECT_EQ(2u, fields.size());
294             EXPECT_EQ(C2FieldDescriptor(FD::INT32, 1, "s32", 0, 4), fields[0]);
295             EXPECT_EQ(C2FieldDescriptor(this->FlexType, 0, "flex", alignof(TypeParam) /* offset */, this->FLEX_SIZE),
296                       fields[1]);
297         } else {
298             EXPECT_EQ(1u, fields.size());
299             EXPECT_EQ(C2FieldDescriptor(this->FlexType, 0, "flex", 0, this->FLEX_SIZE),
300                       fields[0]);
301         }
302     }
303 }
304 
305 struct C2TestStruct_FlexS32 {
306     int32_t mFlex[];
307 
308     const static std::vector<C2FieldDescriptor> _FIELD_LIST;
309     static const std::vector<C2FieldDescriptor> FieldList();
310     // enum : uint32_t { CORE_INDEX = kParamIndexTestFlex, FLEX_SIZE = 4 };
311     // typedef C2TestStruct_FlexS32 _type;
312     // typedef int32_t FlexType;
313 };
314 
FieldList()315 const std::vector<C2FieldDescriptor> C2TestStruct_FlexS32::FieldList() {
316     return _FIELD_LIST;
317 }
318 const std::vector<C2FieldDescriptor> C2TestStruct_FlexS32::_FIELD_LIST = {
319     { FD::INT32, 0, "flex", 0, 4 }
320 };
321 
322 struct C2TestStruct_FlexEndS32 {
323     int32_t signed32;
324     int32_t mFlex[];
325 
326     const static std::vector<C2FieldDescriptor> _FIELD_LIST;
327     static const std::vector<C2FieldDescriptor> FieldList();
328     // enum : uint32_t { CORE_INDEX = kParamIndexTestFlexEnd, FLEX_SIZE = 4 };
329     // typedef C2TestStruct_FlexEnd _type;
330     // typedef int32_t FlexType;
331 };
332 
FieldList()333 const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndS32::FieldList() {
334     return _FIELD_LIST;
335 }
336 const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndS32::_FIELD_LIST = {
337     { FD::INT32, 1, "s32", 0, 4 },
338     { FD::INT32, 0, "flex", 4, 4 },
339 };
340 
341 const static std::vector<C2FieldDescriptor> C2TestStruct_FlexEndS32_ptr_fieldList = {
342     C2FieldDescriptor(&((C2TestStruct_FlexEndS32*)0)->signed32, "s32"),
343     C2FieldDescriptor(&((C2TestStruct_FlexEndS32*)0)->mFlex, "flex"),
344 };
345 
346 struct C2TestFlexS32Struct {
347     int32_t mFlexSigned32[];
348 private: // test access level
C2TestFlexS32StructC2TestFlexS32Struct349     C2TestFlexS32Struct() {}
350 
351     DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(TestFlexS32, mFlexSigned32)
352     C2FIELD(mFlexSigned32, "flex")
353 };
354 
355 struct C2TestFlexEndS32Struct {
356     int32_t signed32;
357     int32_t mFlexSigned32[];
358 private: // test access level
C2TestFlexEndS32StructC2TestFlexEndS32Struct359     C2TestFlexEndS32Struct() {}
360 
361     DEFINE_FLEX_C2STRUCT(TestFlexEndS32, mFlexSigned32)
362 } C2_PACK;
363 
364 DESCRIBE_C2STRUCT(TestFlexEndS32, {
365     C2FIELD(signed32, "s32")
366     C2FIELD(mFlexSigned32, "flex")
367 }) // ; optional
368 
369 template<>
370 std::vector<std::vector<C2FieldDescriptor>>
371 //std::vector<std::vector<C2FieldDescriptor>>
GetLists()372 C2ParamTest_FlexParamFieldList<int32_t>::GetLists() {
373     return {
374         C2TestStruct_FlexS32::FieldList(),
375         C2TestStruct_FlexEndS32::FieldList(),
376         C2TestStruct_FlexEndS32_ptr_fieldList,
377         C2TestFlexS32Struct::FieldList(),
378         C2TestFlexEndS32Struct::FieldList(),
379     };
380 }
381 
382 struct C2TestStruct_FlexS64 {
383     int64_t mFlexSigned64[];
384 
385     const static std::vector<C2FieldDescriptor> _FIELD_LIST;
386     static const std::vector<C2FieldDescriptor> FieldList();
387     // enum : uint32_t { CORE_INDEX = kParamIndexTestFlexS64, FLEX_SIZE = 8 };
388     // typedef C2TestStruct_FlexS64 _type;
389     // typedef int64_t FlexType;
390 };
391 
FieldList()392 const std::vector<C2FieldDescriptor> C2TestStruct_FlexS64::FieldList() {
393     return _FIELD_LIST;
394 }
395 const std::vector<C2FieldDescriptor> C2TestStruct_FlexS64::_FIELD_LIST = {
396     { FD::INT64, 0, "flex", 0, 8 }
397 };
398 
399 struct C2TestStruct_FlexEndS64 {
400     int32_t signed32;
401     // 4-byte padding
402     int64_t mSigned64Flex[];
403 
404     const static std::vector<C2FieldDescriptor> _FIELD_LIST;
405     static const std::vector<C2FieldDescriptor> FieldList();
406     // enum : uint32_t { CORE_INDEX = C2TestStruct_FlexEndS64, FLEX_SIZE = 8 };
407     // typedef C2TestStruct_FlexEndS64 _type;
408     // typedef int64_t FlexType;
409 };
410 
FieldList()411 const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndS64::FieldList() {
412     return _FIELD_LIST;
413 }
414 const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndS64::_FIELD_LIST = {
415     { FD::INT32, 1, "s32", 0, 4 },
416     { FD::INT64, 0, "flex", 8, 8 },
417 };
418 
419 struct C2TestFlexS64Struct {
420     int64_t mFlexSigned64[];
C2TestFlexS64StructC2TestFlexS64Struct421     C2TestFlexS64Struct() {}
422 
423     DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(TestFlexS64, mFlexSigned64)
424     C2FIELD(mFlexSigned64, "flex")
425 };
426 
427 struct C2TestFlexEndS64Struct {
428     int32_t signed32;
429     // 4-byte padding
430     int64_t mFlexSigned64[];
C2TestFlexEndS64StructC2TestFlexEndS64Struct431     C2TestFlexEndS64Struct() {}
432 
433     DEFINE_FLEX_C2STRUCT(TestFlexEndS64, mFlexSigned64)
434 } C2_PACK;
435 
436 DESCRIBE_C2STRUCT(TestFlexEndS64, {
437     C2FIELD(signed32, "s32")
438     C2FIELD(mFlexSigned64, "flex")
439 }) // ; optional
440 
441 template<>
442 std::vector<std::vector<C2FieldDescriptor>>
443 //std::vector<std::vector<C2FieldDescriptor>>
GetLists()444 C2ParamTest_FlexParamFieldList<int64_t>::GetLists() {
445     return {
446         C2TestStruct_FlexS64::FieldList(),
447         C2TestStruct_FlexEndS64::FieldList(),
448         C2TestFlexS64Struct::FieldList(),
449         C2TestFlexEndS64Struct::FieldList(),
450     };
451 }
452 
453 struct C2TestStruct_FlexSize {
454     C2SizeStruct mFlexSize[];
455 
456     const static std::vector<C2FieldDescriptor> _FIELD_LIST;
457     static const std::vector<C2FieldDescriptor> FieldList();
458     // enum : uint32_t { CORE_INDEX = kParamIndexTestFlexSize, FLEX_SIZE = 8 };
459     // typedef C2TestStruct_FlexSize _type;
460     // typedef C2SizeStruct FlexType;
461 };
462 
FieldList()463 const std::vector<C2FieldDescriptor> C2TestStruct_FlexSize::FieldList() {
464     return _FIELD_LIST;
465 }
466 const std::vector<C2FieldDescriptor> C2TestStruct_FlexSize::_FIELD_LIST = {
467     { C2SizeStruct::TYPE, 0, "flex", 0, sizeof(C2SizeStruct) }
468 };
469 
470 struct C2TestStruct_FlexEndSize {
471     int32_t signed32;
472     C2SizeStruct mSizeFlex[];
473 
474     const static std::vector<C2FieldDescriptor> _FIELD_LIST;
475     static const std::vector<C2FieldDescriptor> FieldList();
476     // enum : uint32_t { CORE_INDEX = C2TestStruct_FlexEndSize, FLEX_SIZE = 8 };
477     // typedef C2TestStruct_FlexEndSize _type;
478     // typedef C2SizeStruct FlexType;
479 } __attribute__((aligned(4)));
480 
FieldList()481 const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndSize::FieldList() {
482     return _FIELD_LIST;
483 }
484 const std::vector<C2FieldDescriptor> C2TestStruct_FlexEndSize::_FIELD_LIST = {
485     { FD::INT32, 1, "s32", 0, 4 },
486     { C2SizeStruct::TYPE, 0, "flex", 4, sizeof(C2SizeStruct) },
487 };
488 
489 struct C2TestFlexSizeStruct {
490     C2SizeStruct mFlexSize[];
C2TestFlexSizeStructC2TestFlexSizeStruct491     C2TestFlexSizeStruct() {}
492 
493     DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(TestFlexSize, mFlexSize)
494     C2FIELD(mFlexSize, "flex")
495 };
496 
497 struct C2TestFlexEndSizeStruct {
498     int32_t signed32;
499     C2SizeStruct mFlexSize[];
C2TestFlexEndSizeStructC2TestFlexEndSizeStruct500     C2TestFlexEndSizeStruct() {}
501 
502     DEFINE_FLEX_C2STRUCT(TestFlexEndSize, mFlexSize)
503 } C2_PACK;
504 
505 DESCRIBE_C2STRUCT(TestFlexEndSize, {
506     C2FIELD(signed32, "s32")
507     C2FIELD(mFlexSize, "flex")
508 }) // ; optional
509 
510 struct C2TestBaseFlexEndSizeStruct {
511     int32_t signed32;
512     C2SizeStruct mFlexSize[];
C2TestBaseFlexEndSizeStructC2TestBaseFlexEndSizeStruct513     C2TestBaseFlexEndSizeStruct() {}
514 
515     DEFINE_BASE_FLEX_C2STRUCT(TestBaseFlexEndSize, mFlexSize)
516 } C2_PACK;
517 
518 DESCRIBE_C2STRUCT(TestBaseFlexEndSize, {
519     C2FIELD(signed32, "s32")
520     C2FIELD(mFlexSize, "flex")
521 }) // ; optional
522 
523 struct C2TestBaseFlexEndSize2Struct {
524     int32_t signed32;
525     C2SizeStruct mFlexSize[];
C2TestBaseFlexEndSize2StructC2TestBaseFlexEndSize2Struct526     C2TestBaseFlexEndSize2Struct() {}
527 
528     DEFINE_AND_DESCRIBE_BASE_FLEX_C2STRUCT(TestBaseFlexEndSize2, mFlexSize)
529     C2FIELD(signed32, "s32")
530     C2FIELD(mFlexSize, "flex")
531 };
532 
533 template<>
534 std::vector<std::vector<C2FieldDescriptor>>
535 //std::vector<std::vector<C2FieldDescriptor>>
GetLists()536 C2ParamTest_FlexParamFieldList<C2SizeStruct>::GetLists() {
537     return {
538         C2TestStruct_FlexSize::FieldList(),
539         C2TestStruct_FlexEndSize::FieldList(),
540         C2TestFlexSizeStruct::FieldList(),
541         C2TestFlexEndSizeStruct::FieldList(),
542         C2TestBaseFlexEndSizeStruct::FieldList(),
543         C2TestBaseFlexEndSize2Struct::FieldList(),
544     };
545 }
546 
TEST_F(C2ParamTest,FieldId)547 TEST_F(C2ParamTest, FieldId) {
548     // pointer constructor
549     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&((C2TestStruct_A*)0)->signed32));
550     EXPECT_EQ(_C2FieldId(8, 8), _C2FieldId(&((C2TestStruct_A*)0)->signed64));
551     EXPECT_EQ(_C2FieldId(24, 4), _C2FieldId(&((C2TestStruct_A*)0)->unsigned32));
552     EXPECT_EQ(_C2FieldId(32, 8), _C2FieldId(&((C2TestStruct_A*)0)->unsigned64));
553     EXPECT_EQ(_C2FieldId(40, 4), _C2FieldId(&((C2TestStruct_A*)0)->fp32));
554     EXPECT_EQ(_C2FieldId(44, 8), _C2FieldId(&((C2TestStruct_A*)0)->sz));
555     EXPECT_EQ(_C2FieldId(68, 1), _C2FieldId(&((C2TestStruct_A*)0)->blob));
556     EXPECT_EQ(_C2FieldId(168, 1), _C2FieldId(&((C2TestStruct_A*)0)->string));
557     EXPECT_EQ(_C2FieldId(268, 1), _C2FieldId(&((C2TestStruct_A*)0)->yesNo));
558 
559     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&((C2TestFlexEndSizeStruct*)0)->signed32));
560     EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&((C2TestFlexEndSizeStruct*)0)->mFlexSize));
561 
562     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&((C2TestBaseFlexEndSizeStruct*)0)->signed32));
563     EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&((C2TestBaseFlexEndSizeStruct*)0)->mFlexSize));
564 
565     // member pointer constructor
566     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::signed32));
567     EXPECT_EQ(_C2FieldId(8, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::signed64));
568     EXPECT_EQ(_C2FieldId(24, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::unsigned32));
569     EXPECT_EQ(_C2FieldId(32, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::unsigned64));
570     EXPECT_EQ(_C2FieldId(40, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::fp32));
571     EXPECT_EQ(_C2FieldId(44, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::sz));
572     EXPECT_EQ(_C2FieldId(68, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::blob));
573     EXPECT_EQ(_C2FieldId(168, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::string));
574     EXPECT_EQ(_C2FieldId(268, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::yesNo));
575 
576     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestFlexEndSizeStruct*)0, &C2TestFlexEndSizeStruct::signed32));
577     EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId((C2TestFlexEndSizeStruct*)0, &C2TestFlexEndSizeStruct::mFlexSize));
578 
579     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestBaseFlexEndSizeStruct*)0, &C2TestBaseFlexEndSizeStruct::signed32));
580     EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId((C2TestBaseFlexEndSizeStruct*)0, &C2TestBaseFlexEndSizeStruct::mFlexSize));
581 
582     // member pointer sans type pointer
583     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestStruct_A::signed32));
584     EXPECT_EQ(_C2FieldId(8, 8), _C2FieldId(&C2TestStruct_A::signed64));
585     EXPECT_EQ(_C2FieldId(24, 4), _C2FieldId(&C2TestStruct_A::unsigned32));
586     EXPECT_EQ(_C2FieldId(32, 8), _C2FieldId(&C2TestStruct_A::unsigned64));
587     EXPECT_EQ(_C2FieldId(40, 4), _C2FieldId(&C2TestStruct_A::fp32));
588     EXPECT_EQ(_C2FieldId(44, 8), _C2FieldId(&C2TestStruct_A::sz));
589     EXPECT_EQ(_C2FieldId(68, 1), _C2FieldId(&C2TestStruct_A::blob));
590     EXPECT_EQ(_C2FieldId(168, 1), _C2FieldId(&C2TestStruct_A::string));
591     EXPECT_EQ(_C2FieldId(268, 1), _C2FieldId(&C2TestStruct_A::yesNo));
592 
593     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestFlexEndSizeStruct::signed32));
594     EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&C2TestFlexEndSizeStruct::mFlexSize));
595 
596     EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestBaseFlexEndSizeStruct::signed32));
597     EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&C2TestBaseFlexEndSizeStruct::mFlexSize));
598 
599     typedef C2GlobalParam<C2Info, C2TestAStruct> C2TestAInfo;
600     typedef C2GlobalParam<C2Info, C2TestFlexEndSizeStruct> C2TestFlexEndSizeInfo;
601     typedef C2GlobalParam<C2Info, C2TestBaseFlexEndSizeStruct, kParamIndexTestFlexEndSize> C2TestFlexEndSizeInfoFromBase;
602 
603     // pointer constructor in C2Param
604     EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestAInfo*)0)->signed32));
605     EXPECT_EQ(_C2FieldId(16, 8), _C2FieldId(&((C2TestAInfo*)0)->signed64));
606     EXPECT_EQ(_C2FieldId(32, 4), _C2FieldId(&((C2TestAInfo*)0)->unsigned32));
607     EXPECT_EQ(_C2FieldId(40, 8), _C2FieldId(&((C2TestAInfo*)0)->unsigned64));
608     EXPECT_EQ(_C2FieldId(48, 4), _C2FieldId(&((C2TestAInfo*)0)->fp32));
609     EXPECT_EQ(_C2FieldId(52, 8), _C2FieldId(&((C2TestAInfo*)0)->sz));
610     EXPECT_EQ(_C2FieldId(76, 1), _C2FieldId(&((C2TestAInfo*)0)->blob));
611     EXPECT_EQ(_C2FieldId(176, 1), _C2FieldId(&((C2TestAInfo*)0)->string));
612     EXPECT_EQ(_C2FieldId(276, 1), _C2FieldId(&((C2TestAInfo*)0)->yesNo));
613 
614     EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestFlexEndSizeInfo*)0)->m.signed32));
615     EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&((C2TestFlexEndSizeInfo*)0)->m.mFlexSize));
616 
617     EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestFlexEndSizeInfoFromBase*)0)->m.signed32));
618     EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&((C2TestFlexEndSizeInfoFromBase*)0)->m.mFlexSize));
619 
620     // member pointer in C2Param
621     EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::signed32));
622     EXPECT_EQ(_C2FieldId(16, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::signed64));
623     EXPECT_EQ(_C2FieldId(32, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::unsigned32));
624     EXPECT_EQ(_C2FieldId(40, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::unsigned64));
625     EXPECT_EQ(_C2FieldId(48, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::fp32));
626     EXPECT_EQ(_C2FieldId(52, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::sz));
627     EXPECT_EQ(_C2FieldId(76, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::blob));
628     EXPECT_EQ(_C2FieldId(176, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::string));
629     EXPECT_EQ(_C2FieldId(276, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::yesNo));
630 
631     // NOTE: cannot use a member pointer for flex params due to introduction of 'm'
632     // EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&C2TestFlexEndSizeInfo::m.signed32));
633     // EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&C2TestFlexEndSizeInfo::m.mFlexSize));
634 
635     // EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&C2TestFlexEndSizeInfoFromBase::m.signed32));
636     // EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&C2TestFlexEndSizeInfoFromBase::m.mFlexSize));
637 
638 
639 }
640 
641 struct S32 {
642     template<typename T, class B=typename std::remove_extent<T>::type>
S32S32643     inline S32(const T*) {
644         static_assert(!std::is_array<T>::value, "should not be an array");
645         static_assert(std::is_same<B, int32_t>::value, "should be int32_t");
646     }
647 };
648 
649 struct FLX {
650     template<typename U, typename T, class B=typename std::remove_extent<T>::type>
FLXFLX651     inline FLX(const T*, const U*) {
652         static_assert(std::is_array<T>::value, "should be an array");
653         static_assert(std::extent<T>::value == 0, "should be an array of 0 extent");
654         static_assert(std::is_same<B, U>::value, "should be type U");
655     }
656 };
657 
658 struct MP {
659     template<typename U, typename T, typename ExpectedU, typename UnexpectedU>
MPMP660     inline MP(T U::*, const ExpectedU*, const UnexpectedU*) {
661         static_assert(!std::is_same<U, UnexpectedU>::value, "should not be member pointer of the base type");
662         static_assert(std::is_same<U, ExpectedU>::value, "should be member pointer of the derived type");
663     }
664 
665     template<typename U, typename T, typename B, typename D>
MPMP666     inline MP(T D::*, const D*) { }
667 };
668 
compiledStatic_arrayTypePropagationTest()669 void compiledStatic_arrayTypePropagationTest() {
670     (void)S32(&((C2TestFlexEndS32Struct *)0)->signed32);
671     (void)FLX(&((C2TestFlexEndS32Struct *)0)->mFlexSigned32, (int32_t*)0);
672     (void)FLX(&((C2TestFlexS32Struct *)0)->mFlexSigned32, (int32_t*)0);
673 
674     typedef C2GlobalParam<C2Info, C2TestAStruct> C2TestAInfo;
675 
676     // TRICKY: &derivedClass::baseMember has type of baseClass::*
677     static_assert(std::is_same<decltype(&C2TestAInfo::signed32), int32_t C2TestAStruct::*>::value,
678                   "base member pointer should have base class in type");
679 
680     // therefore, member pointer expands to baseClass::* in templates
681     (void)MP(&C2TestAInfo::signed32,
682              (C2TestAStruct*)0 /* expected */, (C2TestAInfo*)0 /* unexpected */);
683     // but can be cast to derivedClass::*
684     (void)MP((int32_t C2TestAInfo::*)&C2TestAInfo::signed32,
685              (C2TestAInfo*)0 /* expected */, (C2TestAStruct*)0 /* unexpected */);
686 
687     // TRICKY: baseClass::* does not autoconvert to derivedClass::* even in templates
688     // (void)MP(&C2TestAInfo::signed32, (C2TestAInfo*)0);
689 }
690 
TEST_F(C2ParamTest,MemberPointerCast)691 TEST_F(C2ParamTest, MemberPointerCast) {
692     typedef C2GlobalParam<C2Info, C2TestAStruct> C2TestAInfo;
693 
694     static_assert(offsetof(C2TestAInfo, signed32) == 8, "offset should be 8");
695     constexpr int32_t C2TestAStruct::* s32ptr = &C2TestAInfo::signed32;
696     constexpr int32_t C2TestAInfo::* s32ptr_derived = (int32_t C2TestAStruct::*)&C2TestAInfo::signed32;
697     constexpr int32_t C2TestAInfo::* s32ptr_cast2derived = (int32_t C2TestAInfo::*)s32ptr;
698     C2TestAInfo *info = (C2TestAInfo *)256;
699     C2TestAStruct *strukt = (C2TestAStruct *)info;
700     int32_t *info_s32_derived = &(info->*s32ptr_derived);
701     int32_t *info_s32_cast2derived = &(info->*s32ptr_cast2derived);
702     int32_t *info_s32 = &(info->*s32ptr);
703     int32_t *strukt_s32 = &(strukt->*s32ptr);
704 
705     EXPECT_EQ(256u, (uintptr_t)info);
706     EXPECT_EQ(264u, (uintptr_t)strukt);
707     EXPECT_EQ(264u, (uintptr_t)info_s32_derived);
708     EXPECT_EQ(264u, (uintptr_t)info_s32_cast2derived);
709     EXPECT_EQ(264u, (uintptr_t)info_s32);
710     EXPECT_EQ(264u, (uintptr_t)strukt_s32);
711 
712     typedef C2GlobalParam<C2Info, C2TestFlexEndSizeStruct> C2TestFlexEndSizeInfo;
713     static_assert(offsetof(C2TestFlexEndSizeInfo, m.signed32) == 8, "offset should be 8");
714     static_assert(offsetof(C2TestFlexEndSizeInfo, m.mFlexSize) == 12, "offset should be 12");
715 
716     typedef C2GlobalParam<C2Info, C2TestBaseFlexEndSizeStruct, kParamIndexTestFlexEndSize> C2TestFlexEndSizeInfoFromBase;
717     static_assert(offsetof(C2TestFlexEndSizeInfoFromBase, m.signed32) == 8, "offset should be 8");
718     static_assert(offsetof(C2TestFlexEndSizeInfoFromBase, m.mFlexSize) == 12, "offset should be 12");
719 }
720 
721 /* ===================================== PARAM USAGE TESTS ===================================== */
722 
723 struct C2NumberStruct {
724     int32_t mNumber;
C2NumberStructC2NumberStruct725     C2NumberStruct() {}
C2NumberStructC2NumberStruct726     C2NumberStruct(int32_t _number) : mNumber(_number) {}
727 
728     DEFINE_AND_DESCRIBE_C2STRUCT(Number)
729     C2FIELD(mNumber, "number")
730 };
731 
732 struct C2NumberBaseStruct {
733     int32_t mNumber;
C2NumberBaseStructC2NumberBaseStruct734     C2NumberBaseStruct() {}
C2NumberBaseStructC2NumberBaseStruct735     C2NumberBaseStruct(int32_t _number) : mNumber(_number) {}
736 
737     DEFINE_AND_DESCRIBE_BASE_C2STRUCT(NumberBase)
738     C2FIELD(mNumber, "number")
739 };
740 
741 struct C2NumbersStruct {
742     int32_t mNumbers[];
C2NumbersStructC2NumbersStruct743     C2NumbersStruct() {}
744 
745     DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(Numbers, mNumbers)
746     C2FIELD(mNumbers, "numbers")
747 };
748 static_assert(sizeof(C2NumbersStruct) == 0, "C2NumbersStruct has incorrect size");
749 
750 typedef C2GlobalParam<C2Info, C2NumberStruct> C2NumberInfo;
751 
752 typedef C2GlobalParam<C2Tuning, C2NumberStruct> C2NumberTuning;
753 typedef   C2PortParam<C2Tuning, C2NumberStruct> C2NumberPortTuning;
754 typedef C2StreamParam<C2Tuning, C2NumberStruct> C2NumberStreamTuning;
755 
756 typedef C2GlobalParam<C2Tuning, C2NumbersStruct> C2NumbersTuning;
757 typedef   C2PortParam<C2Tuning, C2NumbersStruct> C2NumbersPortTuning;
758 typedef C2StreamParam<C2Tuning, C2NumbersStruct> C2NumbersStreamTuning;
759 
760 //
761 #if 0
762 
763 void test() {
764     C2NumberStruct s(10);
765     (void)C2NumberStruct::FieldList();
766 };
767 
768 typedef C2StreamParam<C2Tuning, C2Int64Value, kParamIndexNumberB> C2NumberConfig4;
769 typedef C2PortParam<C2Tuning, C2Int32Value, kParamIndexNumber> C2NumberConfig3;
770 typedef C2GlobalParam<C2Tuning, C2StringValue, kParamIndexNumber> C2VideoNameConfig;
771 
772 void test3() {
773     C2NumberConfig3 s(10);
774     s.value = 11;
775     s = 12;
776     (void)C2NumberConfig3::FieldList();
777     std::shared_ptr<C2VideoNameConfig> n = C2VideoNameConfig::AllocShared(25);
778     strcpy(n->m.value, "lajos");
779     C2NumberConfig4 t(false, 0, 11);
780     t.value = 15;
781 };
782 
783 struct C2NumbersStruct {
784     int32_t mNumbers[];
785     enum { CORE_INDEX = kParamIndexNumber };
786     const static std::vector<C2FieldDescriptor> FieldList();
787     static const std::vector<C2FieldDescriptor> FieldList();
788     C2NumbersStruct() {}
789 
790     FLEX(C2NumbersStruct, mNumbers);
791 };
792 
793 static_assert(sizeof(C2NumbersStruct) == 0, "yes");
794 
795 
796 typedef C2GlobalParam<C2Info, C2NumbersStruct> C2NumbersInfo;
797 
798 const std::vector<C2FieldDescriptor> C2NumbersStruct::FieldList() {
799     return _FIELD_LIST;
800 }
801 const std::vector<C2FieldDescriptor> C2NumbersStruct::_FIELD_LIST =
802 //    { { FD::INT32, 0, "widths" } };
803     { C2FieldDescriptor(&((C2NumbersStruct*)(nullptr))->mNumbers, "number") };
804 
805 typedef C2PortParam<C2Tuning, C2NumberStruct> C2NumberConfig;
806 
807 std::vector<C2FieldDescriptor> myList = C2NumberConfig::FieldList();
808 
809     std::unique_ptr<C2ParamDescriptor> __test_describe(uint32_t paramType) {
810         std::list<C2FieldDescriptor> fields = describeC2Params<C2NumberConfig>();
811 
812         auto widths = C2NumbersInfo::AllocShared(5);
813         widths->flexCount();
814         widths->m.mNumbers[4] = 1;
815 
816         test();
817         test3();
818 
819         C2NumberConfig outputWidth(false, 123);
820 
821         C2Param::Index index(paramType);
822         switch (paramType) {
823         case C2NumberConfig::CORE_INDEX:
824             return std::unique_ptr<C2ParamDescriptor>(new C2ParamDescriptor{
825                 true /* isRequired */,
826                 "number",
827                 index,
828             });
829         }
830         return nullptr;
831     }
832 
833 
834 } // namespace android
835 
836 #endif
837 //
838 
839 template<typename T>
canSetPort(T & o,bool output)840 bool canSetPort(T &o, bool output) { return o.setPort(output); }
canSetPort(...)841 bool canSetPort(...) { return false; }
842 
843 template<typename S, typename=decltype(((S*)0)->setPort(true))>
844 static std::true_type _canCallSetPort(int);
845 template<typename>
846 static std::false_type _canCallSetPort(...);
847 #define canCallSetPort(x) decltype(_canCallSetPort<std::remove_reference<decltype(x)>::type>(0))::value
848 
849 /* ======================================= STATIC TESTS ======================================= */
850 
851 static_assert(_C2Comparable<int>::value, "int is not comparable");
852 static_assert(!_C2Comparable<void>::value, "void is comparable");
853 
854 struct C2_HIDE _test0 {
855     bool operator==(const _test0&);
856     bool operator!=(const _test0&);
857 };
858 struct C2_HIDE _test1 {
859     bool operator==(const _test1&);
860 };
861 struct C2_HIDE _test2 {
862     bool operator!=(const _test2&);
863 };
864 static_assert(_C2Comparable<_test0>::value, "class with == and != is not comparable");
865 static_assert(_C2Comparable<_test1>::value, "class with == is not comparable");
866 static_assert(_C2Comparable<_test2>::value, "class with != is not comparable");
867 
868 /* ======================================= C2PARAM TESTS ======================================= */
869 
870 struct _C2ParamInspector {
871     static void StaticTest();
872     static void StaticFromBaseTest();
873     static void StaticFlexTest();
874     static void StaticFlexFromBaseTest();
875 };
876 
877 // TEST_F(_C2ParamInspector, StaticTest) {
StaticTest()878 void _C2ParamInspector::StaticTest() {
879     typedef C2Param::Index I;
880 
881     // C2NumberStruct: CORE_INDEX = kIndex                          (args)
882     static_assert(C2NumberStruct::CORE_INDEX == kParamIndexNumber, "bad index");
883     static_assert(sizeof(C2NumberStruct) == 4, "bad size");
884 
885     // C2NumberTuning:             kIndex | tun | global           (args)
886     static_assert(C2NumberTuning::CORE_INDEX == kParamIndexNumber, "bad index");
887     static_assert(C2NumberTuning::PARAM_TYPE == (kParamIndexNumber | I::KIND_TUNING | I::DIR_GLOBAL), "bad index");
888     static_assert(sizeof(C2NumberTuning) == 12, "bad size");
889 
890     static_assert(offsetof(C2NumberTuning, _mSize) == 0, "bad size");
891     static_assert(offsetof(C2NumberTuning, _mIndex) == 4, "bad offset");
892     static_assert(offsetof(C2NumberTuning, mNumber) == 8, "bad offset");
893 
894     // C2NumberPortTuning:         kIndex | tun | port             (bool, args)
895     static_assert(sizeof(C2NumberPortTuning) == 12, "bad size");
896     // C2NumberPortTuning::input:  kIndex | tun | port | input     (args)
897     // C2NumberPortTuning::output: kIndex | tun | port | output    (args)
898     static_assert(C2NumberPortTuning::input::CORE_INDEX ==
899                   kParamIndexNumber, "bad index");
900     static_assert(C2NumberPortTuning::input::PARAM_TYPE ==
901                   (kParamIndexNumber | I::KIND_TUNING | I::DIR_INPUT), "bad index");
902     static_assert(C2NumberPortTuning::output::CORE_INDEX ==
903                   kParamIndexNumber, "bad index");
904     static_assert(C2NumberPortTuning::output::PARAM_TYPE ==
905                   (kParamIndexNumber | I::KIND_TUNING | I::DIR_OUTPUT), "bad index");
906     static_assert(sizeof(C2NumberPortTuning::input) == 12, "bad size");
907     static_assert(sizeof(C2NumberPortTuning::output) == 12, "bad size");
908     static_assert(offsetof(C2NumberPortTuning::input, _mSize) == 0, "bad size");
909     static_assert(offsetof(C2NumberPortTuning::input, _mIndex) == 4, "bad offset");
910     static_assert(offsetof(C2NumberPortTuning::input, mNumber) == 8, "bad offset");
911     static_assert(offsetof(C2NumberPortTuning::output, _mSize) == 0, "bad size");
912     static_assert(offsetof(C2NumberPortTuning::output, _mIndex) == 4, "bad offset");
913     static_assert(offsetof(C2NumberPortTuning::output, mNumber) == 8, "bad offset");
914 
915     // C2NumberStreamTuning:       kIndex | tun | str              (bool, uint, args)
916     static_assert(sizeof(C2NumberStreamTuning) == 12u, "bad size");
917     // C2NumberStreamTuning::input kIndex | tun | str | input      (int, args)
918     // C2NumberStreamTuning::output kIx   | tun | str | output     (int, args)
919     static_assert(C2NumberStreamTuning::input::CORE_INDEX ==
920                   kParamIndexNumber, "bad index");
921     static_assert(C2NumberStreamTuning::input::PARAM_TYPE ==
922                   (kParamIndexNumber | I::KIND_TUNING | I::DIR_INPUT | I::IS_STREAM_FLAG), "bad index");
923     static_assert(C2NumberStreamTuning::output::CORE_INDEX ==
924                   kParamIndexNumber, "bad index");
925     static_assert(C2NumberStreamTuning::output::PARAM_TYPE ==
926                   (kParamIndexNumber | I::KIND_TUNING | I::DIR_OUTPUT | I::IS_STREAM_FLAG), "bad index");
927     static_assert(sizeof(C2NumberStreamTuning::input) == 12u, "bad size");
928     static_assert(sizeof(C2NumberStreamTuning::output) == 12u, "bad size");
929     static_assert(offsetof(C2NumberStreamTuning::input, _mSize) == 0, "bad size");
930     static_assert(offsetof(C2NumberStreamTuning::input, _mIndex) == 4, "bad offset");
931     static_assert(offsetof(C2NumberStreamTuning::input, mNumber) == 8, "bad offset");
932     static_assert(offsetof(C2NumberStreamTuning::output, _mSize) == 0, "bad size");
933     static_assert(offsetof(C2NumberStreamTuning::output, _mIndex) == 4, "bad offset");
934     static_assert(offsetof(C2NumberStreamTuning::output, mNumber) == 8, "bad offset");
935 }
936 
StaticFromBaseTest()937 void _C2ParamInspector::StaticFromBaseTest() {
938     enum { kParamIndexMy = 3102 };
939     typedef C2NumberBaseStruct C2MyStruct;
940     typedef C2GlobalParam<C2Setting, C2MyStruct, kParamIndexMy> C2MySetting;
941     typedef   C2PortParam<C2Setting, C2MyStruct, kParamIndexMy> C2MyPortSetting;
942     typedef C2StreamParam<C2Setting, C2MyStruct, kParamIndexMy> C2MyStreamSetting;
943 
944     typedef C2Param::Index I;
945 
946     // C2MyStruct has no CORE_INDEX
947     //static_assert(C2MyStruct::CORE_INDEX == kParamIndexMy, "bad index");
948     static_assert(sizeof(C2MyStruct) == 4, "bad size");
949 
950     // C2MySetting:             kIndex | tun | global           (args)
951     static_assert(C2MySetting::CORE_INDEX == kParamIndexMy, "bad index");
952     static_assert(C2MySetting::PARAM_TYPE == (kParamIndexMy | I::KIND_SETTING | I::DIR_GLOBAL), "bad index");
953     static_assert(sizeof(C2MySetting) == 12, "bad size");
954 
955     static_assert(offsetof(C2MySetting, _mSize) == 0, "bad size");
956     static_assert(offsetof(C2MySetting, _mIndex) == 4, "bad offset");
957     static_assert(offsetof(C2MySetting, mNumber) == 8, "bad offset");
958 
959     // C2MyPortSetting:         kIndex | tun | port             (bool, args)
960     static_assert(sizeof(C2MyPortSetting) == 12, "bad size");
961     // C2MyPortSetting::input:  kIndex | tun | port | input     (args)
962     // C2MyPortSetting::output: kIndex | tun | port | output    (args)
963     static_assert(C2MyPortSetting::input::CORE_INDEX ==
964                   kParamIndexMy, "bad index");
965     static_assert(C2MyPortSetting::input::PARAM_TYPE ==
966                   (kParamIndexMy | I::KIND_SETTING | I::DIR_INPUT), "bad index");
967     static_assert(C2MyPortSetting::output::CORE_INDEX ==
968                   kParamIndexMy, "bad index");
969     static_assert(C2MyPortSetting::output::PARAM_TYPE ==
970                   (kParamIndexMy | I::KIND_SETTING | I::DIR_OUTPUT), "bad index");
971     static_assert(sizeof(C2MyPortSetting::input) == 12, "bad size");
972     static_assert(sizeof(C2MyPortSetting::output) == 12, "bad size");
973     static_assert(offsetof(C2MyPortSetting::input, _mSize) == 0, "bad size");
974     static_assert(offsetof(C2MyPortSetting::input, _mIndex) == 4, "bad offset");
975     static_assert(offsetof(C2MyPortSetting::input, mNumber) == 8, "bad offset");
976     static_assert(offsetof(C2MyPortSetting::output, _mSize) == 0, "bad size");
977     static_assert(offsetof(C2MyPortSetting::output, _mIndex) == 4, "bad offset");
978     static_assert(offsetof(C2MyPortSetting::output, mNumber) == 8, "bad offset");
979 
980     // C2MyStreamSetting:       kIndex | tun | str              (bool, uint, args)
981     static_assert(sizeof(C2MyStreamSetting) == 12u, "bad size");
982     // C2MyStreamSetting::input kIndex | tun | str | input      (int, args)
983     // C2MyStreamSetting::output kIx   | tun | str | output     (int, args)
984     static_assert(C2MyStreamSetting::input::CORE_INDEX ==
985                   kParamIndexMy, "bad index");
986     static_assert(C2MyStreamSetting::input::PARAM_TYPE ==
987                   (kParamIndexMy | I::KIND_SETTING | I::DIR_INPUT | I::IS_STREAM_FLAG), "bad index");
988     static_assert(C2MyStreamSetting::output::CORE_INDEX ==
989                   kParamIndexMy, "bad index");
990     static_assert(C2MyStreamSetting::output::PARAM_TYPE ==
991                   (kParamIndexMy | I::KIND_SETTING | I::DIR_OUTPUT | I::IS_STREAM_FLAG), "bad index");
992     static_assert(sizeof(C2MyStreamSetting::input) == 12u, "bad size");
993     static_assert(sizeof(C2MyStreamSetting::output) == 12u, "bad size");
994     static_assert(offsetof(C2MyStreamSetting::input, _mSize) == 0, "bad size");
995     static_assert(offsetof(C2MyStreamSetting::input, _mIndex) == 4, "bad offset");
996     static_assert(offsetof(C2MyStreamSetting::input, mNumber) == 8, "bad offset");
997     static_assert(offsetof(C2MyStreamSetting::output, _mSize) == 0, "bad size");
998     static_assert(offsetof(C2MyStreamSetting::output, _mIndex) == 4, "bad offset");
999     static_assert(offsetof(C2MyStreamSetting::output, mNumber) == 8, "bad offset");
1000 }
1001 
StaticFlexTest()1002 void _C2ParamInspector::StaticFlexTest() {
1003     typedef C2Param::Index I;
1004 
1005     // C2NumbersStruct: CORE_INDEX = kIndex                          (args)
1006     static_assert(C2NumbersStruct::CORE_INDEX == (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
1007     static_assert(sizeof(C2NumbersStruct) == 0, "bad size");
1008 
1009     // C2NumbersTuning:             kIndex | tun | global           (args)
1010     static_assert(C2NumbersTuning::CORE_INDEX == (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
1011     static_assert(C2NumbersTuning::PARAM_TYPE == (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_GLOBAL), "bad index");
1012     static_assert(sizeof(C2NumbersTuning) == 8, "bad size");
1013 
1014     static_assert(offsetof(C2NumbersTuning, _mSize) == 0, "bad size");
1015     static_assert(offsetof(C2NumbersTuning, _mIndex) == 4, "bad offset");
1016     static_assert(offsetof(C2NumbersTuning, m.mNumbers) == 8, "bad offset");
1017 
1018     // C2NumbersPortTuning:         kIndex | tun | port             (bool, args)
1019     static_assert(sizeof(C2NumbersPortTuning) == 8, "bad size");
1020     // C2NumbersPortTuning::input:  kIndex | tun | port | input     (args)
1021     // C2NumbersPortTuning::output: kIndex | tun | port | output    (args)
1022     static_assert(C2NumbersPortTuning::input::CORE_INDEX ==
1023                   (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
1024     static_assert(C2NumbersPortTuning::input::PARAM_TYPE ==
1025                   (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_INPUT), "bad index");
1026     static_assert(C2NumbersPortTuning::output::CORE_INDEX ==
1027                   (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
1028     static_assert(C2NumbersPortTuning::output::PARAM_TYPE ==
1029                   (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_OUTPUT), "bad index");
1030     static_assert(sizeof(C2NumbersPortTuning::input) == 8, "bad size");
1031     static_assert(sizeof(C2NumbersPortTuning::output) == 8, "bad size");
1032     static_assert(offsetof(C2NumbersPortTuning::input, _mSize) == 0, "bad size");
1033     static_assert(offsetof(C2NumbersPortTuning::input, _mIndex) == 4, "bad offset");
1034     static_assert(offsetof(C2NumbersPortTuning::input, m.mNumbers) == 8, "bad offset");
1035     static_assert(offsetof(C2NumbersPortTuning::output, _mSize) == 0, "bad size");
1036     static_assert(offsetof(C2NumbersPortTuning::output, _mIndex) == 4, "bad offset");
1037     static_assert(offsetof(C2NumbersPortTuning::output, m.mNumbers) == 8, "bad offset");
1038 
1039     // C2NumbersStreamTuning:       kIndex | tun | str              (bool, uint, args)
1040     static_assert(sizeof(C2NumbersStreamTuning) == 8, "bad size");
1041     // C2NumbersStreamTuning::input kIndex | tun | str | input      (int, args)
1042     // C2NumbersStreamTuning::output kIx   | tun | str | output     (int, args)
1043     static_assert(C2NumbersStreamTuning::input::CORE_INDEX ==
1044                   (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
1045     static_assert(C2NumbersStreamTuning::input::PARAM_TYPE ==
1046                   (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_INPUT | I::IS_STREAM_FLAG), "bad index");
1047     static_assert(C2NumbersStreamTuning::output::CORE_INDEX ==
1048                   (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
1049     static_assert(C2NumbersStreamTuning::output::PARAM_TYPE ==
1050                   (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_OUTPUT | I::IS_STREAM_FLAG), "bad index");
1051     static_assert(sizeof(C2NumbersStreamTuning::input) == 8, "bad size");
1052     static_assert(sizeof(C2NumbersStreamTuning::output) == 8, "bad size");
1053     static_assert(offsetof(C2NumbersStreamTuning::input, _mSize) == 0, "bad size");
1054     static_assert(offsetof(C2NumbersStreamTuning::input, _mIndex) == 4, "bad offset");
1055     static_assert(offsetof(C2NumbersStreamTuning::input, m.mNumbers) == 8, "bad offset");
1056     static_assert(offsetof(C2NumbersStreamTuning::output, _mSize) == 0, "bad size");
1057     static_assert(offsetof(C2NumbersStreamTuning::output, _mIndex) == 4, "bad offset");
1058     static_assert(offsetof(C2NumbersStreamTuning::output, m.mNumbers) == 8, "bad offset");
1059 }
1060 
1061 template<bool, unsigned ...N>
1062 struct _print_as_warning { };
1063 
1064 template<unsigned ...N>
1065 struct _print_as_warning<true, N...> : std::true_type { };
1066 
1067 #define static_assert_equals(a, b, msg) \
1068 static_assert(_print_as_warning<(a) == (b), a, b>::value, msg)
1069 
StaticFlexFromBaseTest()1070 void _C2ParamInspector::StaticFlexFromBaseTest() {
1071     enum { kParamIndexMy = 1203 };
1072     typedef C2TestBaseFlexEndSizeStruct C2MyStruct;
1073     typedef C2GlobalParam<C2Info, C2MyStruct, kParamIndexMy> C2MyInfo;
1074     typedef   C2PortParam<C2Info, C2MyStruct, kParamIndexMy> C2MyPortInfo;
1075     typedef C2StreamParam<C2Info, C2MyStruct, kParamIndexMy> C2MyStreamInfo;
1076 
1077     typedef C2Param::Index I;
1078 
1079     // C2MyStruct has no CORE_INDEX
1080     //static_assert(C2MyStruct::CORE_INDEX == (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
1081     static_assert(sizeof(C2MyStruct) == 4, "bad size");
1082 
1083     // C2MyInfo:             kIndex | tun | global           (args)
1084     static_assert_equals(C2MyInfo::CORE_INDEX, (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
1085     static_assert_equals(C2MyInfo::PARAM_TYPE, (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_GLOBAL), "bad index");
1086     static_assert(sizeof(C2MyInfo) == 12, "bad size");
1087 
1088     static_assert(offsetof(C2MyInfo, _mSize) == 0, "bad size");
1089     static_assert(offsetof(C2MyInfo, _mIndex) == 4, "bad offset");
1090     static_assert(offsetof(C2MyInfo, m.signed32) == 8, "bad offset");
1091 
1092     // C2MyPortInfo:         kIndex | tun | port             (bool, args)
1093     static_assert(sizeof(C2MyPortInfo) == 12, "bad size");
1094     // C2MyPortInfo::input:  kIndex | tun | port | input     (args)
1095     // C2MyPortInfo::output: kIndex | tun | port | output    (args)
1096     static_assert(C2MyPortInfo::input::CORE_INDEX ==
1097                   (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
1098     static_assert(C2MyPortInfo::input::PARAM_TYPE ==
1099                   (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_INPUT), "bad index");
1100     static_assert(C2MyPortInfo::output::CORE_INDEX ==
1101                   (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
1102     static_assert(C2MyPortInfo::output::PARAM_TYPE ==
1103                   (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_OUTPUT), "bad index");
1104     static_assert(sizeof(C2MyPortInfo::input) == 12, "bad size");
1105     static_assert(sizeof(C2MyPortInfo::output) == 12, "bad size");
1106     static_assert(offsetof(C2MyPortInfo::input, _mSize) == 0, "bad size");
1107     static_assert(offsetof(C2MyPortInfo::input, _mIndex) == 4, "bad offset");
1108     static_assert(offsetof(C2MyPortInfo::input, m.signed32) == 8, "bad offset");
1109     static_assert(offsetof(C2MyPortInfo::output, _mSize) == 0, "bad size");
1110     static_assert(offsetof(C2MyPortInfo::output, _mIndex) == 4, "bad offset");
1111     static_assert(offsetof(C2MyPortInfo::output, m.signed32) == 8, "bad offset");
1112 
1113     // C2MyStreamInfo:       kIndex | tun | str              (bool, uint, args)
1114     static_assert(sizeof(C2MyStreamInfo) == 12, "bad size");
1115     // C2MyStreamInfo::input kIndex | tun | str | input      (int, args)
1116     // C2MyStreamInfo::output kIx   | tun | str | output     (int, args)
1117     static_assert(C2MyStreamInfo::input::CORE_INDEX ==
1118                   (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
1119     static_assert(C2MyStreamInfo::input::PARAM_TYPE ==
1120                   (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_INPUT | I::IS_STREAM_FLAG), "bad index");
1121     static_assert(C2MyStreamInfo::output::CORE_INDEX ==
1122                   (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
1123     static_assert(C2MyStreamInfo::output::PARAM_TYPE ==
1124                   (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_OUTPUT | I::IS_STREAM_FLAG), "bad index");
1125     static_assert(sizeof(C2MyStreamInfo::input) == 12, "bad size");
1126     static_assert(sizeof(C2MyStreamInfo::output) == 12, "bad size");
1127     static_assert(offsetof(C2MyStreamInfo::input, _mSize) == 0, "bad size");
1128     static_assert(offsetof(C2MyStreamInfo::input, _mIndex) == 4, "bad offset");
1129     static_assert(offsetof(C2MyStreamInfo::input, m.signed32) == 8, "bad offset");
1130     static_assert(offsetof(C2MyStreamInfo::output, _mSize) == 0, "bad size");
1131     static_assert(offsetof(C2MyStreamInfo::output, _mIndex) == 4, "bad offset");
1132     static_assert(offsetof(C2MyStreamInfo::output, m.signed32) == 8, "bad offset");
1133 }
1134 
TEST_F(C2ParamTest,ParamOpsTest)1135 TEST_F(C2ParamTest, ParamOpsTest) {
1136     const C2NumberStruct str(100);
1137     C2NumberStruct bstr;
1138 
1139     {
1140         EXPECT_EQ(100, str.mNumber);
1141         bstr.mNumber = 100;
1142 
1143         C2Param::CoreIndex index = C2NumberStruct::CORE_INDEX;
1144         EXPECT_FALSE(index.isVendor());
1145         EXPECT_FALSE(index.isFlexible());
1146         EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
1147         EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
1148     }
1149 
1150     const C2NumberTuning tun(100);
1151     C2NumberTuning btun;
1152 
1153     {
1154       C2NumberInfo inf(100);
1155       std::unique_ptr<C2NumbersTuning> tun_ = C2NumbersTuning::AllocUnique(1);
1156 
1157       EXPECT_EQ(tun.coreIndex(), inf.coreIndex());
1158       EXPECT_NE(tun.coreIndex(), tun_->coreIndex());
1159       EXPECT_NE(tun.type(), inf.type());
1160       EXPECT_NE(tun.type(), tun_->type());
1161     }
1162 
1163     {
1164         // flags & invariables
1165         for (const auto &p : { tun, btun }) {
1166             EXPECT_TRUE((bool)p);
1167             EXPECT_FALSE(!p);
1168             EXPECT_EQ(12u, p.size());
1169 
1170             EXPECT_FALSE(p.isVendor());
1171             EXPECT_FALSE(p.isFlexible());
1172             EXPECT_TRUE(p.isGlobal());
1173             EXPECT_FALSE(p.forInput());
1174             EXPECT_FALSE(p.forOutput());
1175             EXPECT_FALSE(p.forStream());
1176             EXPECT_FALSE(p.forPort());
1177         }
1178 
1179         // value
1180         EXPECT_EQ(100, tun.mNumber);
1181         EXPECT_EQ(0, btun.mNumber);
1182         EXPECT_FALSE(tun == btun);
1183         EXPECT_FALSE(tun.operator==(btun));
1184         EXPECT_TRUE(tun != btun);
1185         EXPECT_TRUE(tun.operator!=(btun));
1186         btun.mNumber = 100;
1187         EXPECT_EQ(tun, btun);
1188 
1189         // index
1190         EXPECT_EQ(C2Param::Type(tun.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
1191         EXPECT_EQ(C2Param::Type(tun.type()).typeIndex(), kParamIndexNumber);
1192         EXPECT_EQ(tun.type(), C2NumberTuning::PARAM_TYPE);
1193         EXPECT_EQ(tun.stream(), ~0u);
1194 
1195         C2Param::CoreIndex index = C2NumberTuning::CORE_INDEX;
1196         EXPECT_FALSE(index.isVendor());
1197         EXPECT_FALSE(index.isFlexible());
1198         EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
1199         EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
1200 
1201         C2Param::Type type = C2NumberTuning::PARAM_TYPE;
1202         EXPECT_FALSE(type.isVendor());
1203         EXPECT_FALSE(type.isFlexible());
1204         EXPECT_TRUE(type.isGlobal());
1205         EXPECT_FALSE(type.forInput());
1206         EXPECT_FALSE(type.forOutput());
1207         EXPECT_FALSE(type.forStream());
1208         EXPECT_FALSE(type.forPort());
1209 
1210         EXPECT_EQ(C2NumberTuning::From(nullptr), nullptr);
1211         EXPECT_EQ(C2NumberTuning::From(&tun), &tun);
1212         EXPECT_EQ(C2NumberPortTuning::From(&tun), nullptr);
1213         EXPECT_EQ(C2NumberPortTuning::input::From(&tun), nullptr);
1214         EXPECT_EQ(C2NumberPortTuning::output::From(&tun), nullptr);
1215         EXPECT_EQ(C2NumberStreamTuning::From(&tun), nullptr);
1216         EXPECT_EQ(C2NumberStreamTuning::input::From(&tun), nullptr);
1217         EXPECT_EQ(C2NumberStreamTuning::output::From(&tun), nullptr);
1218 
1219         EXPECT_EQ(*(C2Param::Copy(btun)), btun);
1220         btun.invalidate();
1221         EXPECT_FALSE(C2Param::Copy(btun));
1222     }
1223 
1224     const C2NumberPortTuning outp1(true, 100), inp1(false, 100);
1225     C2NumberPortTuning boutp1, binp1, binp3(false, 100);
1226     const C2NumberPortTuning::input inp2(100);
1227     C2NumberPortTuning::input binp2;
1228     const C2NumberPortTuning::output outp2(100);
1229     C2NumberPortTuning::output boutp2;
1230 
1231     EXPECT_EQ(inp1.coreIndex(), tun.coreIndex());
1232     EXPECT_EQ(outp1.coreIndex(), tun.coreIndex());
1233     EXPECT_EQ(binp1.coreIndex(), tun.coreIndex());
1234     EXPECT_EQ(boutp1.coreIndex(), tun.coreIndex());
1235     EXPECT_EQ(inp2.coreIndex(), tun.coreIndex());
1236     EXPECT_EQ(outp2.coreIndex(), tun.coreIndex());
1237 
1238     EXPECT_EQ(inp1.type(), inp2.type());
1239     EXPECT_EQ(outp1.type(), outp2.type());
1240     EXPECT_NE(inp1.type(), outp1.type());
1241     EXPECT_NE(inp2.type(), outp2.type());
1242     EXPECT_NE(inp1.type(), binp1.type());
1243     EXPECT_NE(outp1.type(), boutp1.type());
1244     EXPECT_NE(inp1.type(), tun.type());
1245     EXPECT_NE(inp2.type(), tun.type());
1246 
1247     {
1248         static_assert(canCallSetPort(binp3), "should be able to");
1249         static_assert(canCallSetPort(binp1), "should be able to");
1250         static_assert(!canCallSetPort(inp1), "should not be able to (const)");
1251         static_assert(!canCallSetPort(inp2), "should not be able to (const & type)");
1252         static_assert(!canCallSetPort(binp2), "should not be able to (type)");
1253 
1254         // flags & invariables
1255         for (const auto &p : { outp1, inp1, boutp1 }) {
1256             EXPECT_EQ(12u, p.size());
1257             EXPECT_FALSE(p.isVendor());
1258             EXPECT_FALSE(p.isFlexible());
1259             EXPECT_FALSE(p.isGlobal());
1260             EXPECT_FALSE(p.forStream());
1261             EXPECT_TRUE(p.forPort());
1262         }
1263         for (const auto &p : { inp2, binp2 }) {
1264             EXPECT_EQ(12u, p.size());
1265             EXPECT_FALSE(p.isVendor());
1266             EXPECT_FALSE(p.isFlexible());
1267             EXPECT_FALSE(p.isGlobal());
1268             EXPECT_FALSE(p.forStream());
1269             EXPECT_TRUE(p.forPort());
1270         }
1271         for (const auto &p : { outp2, boutp2 }) {
1272             EXPECT_EQ(12u, p.size());
1273             EXPECT_FALSE(p.isVendor());
1274             EXPECT_FALSE(p.isFlexible());
1275             EXPECT_FALSE(p.isGlobal());
1276             EXPECT_FALSE(p.forStream());
1277             EXPECT_TRUE(p.forPort());
1278         }
1279 
1280         // port specific flags & invariables
1281         EXPECT_FALSE(outp1.forInput());
1282         EXPECT_TRUE(outp1.forOutput());
1283 
1284         EXPECT_TRUE(inp1.forInput());
1285         EXPECT_FALSE(inp1.forOutput());
1286 
1287         for (const auto &p : { outp1, inp1 }) {
1288             EXPECT_TRUE((bool)p);
1289             EXPECT_FALSE(!p);
1290             EXPECT_EQ(100, p.mNumber);
1291         }
1292         for (const auto &p : { outp2, boutp2 }) {
1293             EXPECT_TRUE((bool)p);
1294             EXPECT_FALSE(!p);
1295 
1296             EXPECT_FALSE(p.forInput());
1297             EXPECT_TRUE(p.forOutput());
1298         }
1299         for (const auto &p : { inp2, binp2 }) {
1300             EXPECT_TRUE((bool)p);
1301             EXPECT_FALSE(!p);
1302 
1303             EXPECT_TRUE(p.forInput());
1304             EXPECT_FALSE(p.forOutput());
1305         }
1306         for (const auto &p : { boutp1 } ) {
1307             EXPECT_FALSE((bool)p);
1308             EXPECT_TRUE(!p);
1309 
1310             EXPECT_FALSE(p.forInput());
1311             EXPECT_FALSE(p.forOutput());
1312             EXPECT_EQ(0, p.mNumber);
1313         }
1314 
1315         // values
1316         EXPECT_EQ(100, inp2.mNumber);
1317         EXPECT_EQ(100, outp2.mNumber);
1318         EXPECT_EQ(0, binp1.mNumber);
1319         EXPECT_EQ(0, binp2.mNumber);
1320         EXPECT_EQ(0, boutp1.mNumber);
1321         EXPECT_EQ(0, boutp2.mNumber);
1322 
1323         EXPECT_TRUE(inp1 != outp1);
1324         EXPECT_TRUE(inp1 == inp2);
1325         EXPECT_TRUE(outp1 == outp2);
1326         EXPECT_TRUE(binp1 == boutp1);
1327         EXPECT_TRUE(binp2 != boutp2);
1328 
1329         EXPECT_TRUE(inp1 != binp1);
1330         binp1.mNumber = 100;
1331         EXPECT_TRUE(inp1 != binp1);
1332         binp1.setPort(false /* output */);
1333         EXPECT_TRUE((bool)binp1);
1334         EXPECT_FALSE(!binp1);
1335         EXPECT_TRUE(inp1 == binp1);
1336 
1337         EXPECT_TRUE(inp2 != binp2);
1338         binp2.mNumber = 100;
1339         EXPECT_TRUE(inp2 == binp2);
1340 
1341         binp1.setPort(true /* output */);
1342         EXPECT_TRUE(outp1 == binp1);
1343 
1344         EXPECT_TRUE(outp1 != boutp1);
1345         boutp1.mNumber = 100;
1346         EXPECT_TRUE(outp1 != boutp1);
1347         boutp1.setPort(true /* output */);
1348         EXPECT_TRUE((bool)boutp1);
1349         EXPECT_FALSE(!boutp1);
1350         EXPECT_TRUE(outp1 == boutp1);
1351 
1352         EXPECT_TRUE(outp2 != boutp2);
1353         boutp2.mNumber = 100;
1354         EXPECT_TRUE(outp2 == boutp2);
1355 
1356         boutp1.setPort(false /* output */);
1357         EXPECT_TRUE(inp1 == boutp1);
1358 
1359         // index
1360         EXPECT_EQ(C2Param::Type(inp1.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
1361         EXPECT_EQ(C2Param::Type(inp1.type()).typeIndex(), kParamIndexNumber);
1362         EXPECT_EQ(inp1.type(), C2NumberPortTuning::input::PARAM_TYPE);
1363         EXPECT_EQ(inp1.stream(), ~0u);
1364 
1365         EXPECT_EQ(C2Param::Type(inp2.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
1366         EXPECT_EQ(C2Param::Type(inp2.type()).typeIndex(), kParamIndexNumber);
1367         EXPECT_EQ(inp2.type(), C2NumberPortTuning::input::PARAM_TYPE);
1368         EXPECT_EQ(inp2.stream(), ~0u);
1369 
1370         EXPECT_EQ(C2Param::Type(outp1.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
1371         EXPECT_EQ(C2Param::Type(outp1.type()).typeIndex(), kParamIndexNumber);
1372         EXPECT_EQ(outp1.type(), C2NumberPortTuning::output::PARAM_TYPE);
1373         EXPECT_EQ(outp1.stream(), ~0u);
1374 
1375         EXPECT_EQ(C2Param::Type(outp2.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
1376         EXPECT_EQ(C2Param::Type(outp2.type()).typeIndex(), kParamIndexNumber);
1377         EXPECT_EQ(outp2.type(), C2NumberPortTuning::output::PARAM_TYPE);
1378         EXPECT_EQ(outp2.stream(), ~0u);
1379 
1380         C2Param::CoreIndex index = C2NumberPortTuning::input::PARAM_TYPE;
1381         EXPECT_FALSE(index.isVendor());
1382         EXPECT_FALSE(index.isFlexible());
1383         EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
1384         EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
1385 
1386         index = C2NumberPortTuning::output::PARAM_TYPE;
1387         EXPECT_FALSE(index.isVendor());
1388         EXPECT_FALSE(index.isFlexible());
1389         EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
1390         EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
1391 
1392         C2Param::Type type = C2NumberPortTuning::input::PARAM_TYPE;
1393         EXPECT_FALSE(type.isVendor());
1394         EXPECT_FALSE(type.isFlexible());
1395         EXPECT_FALSE(type.isGlobal());
1396         EXPECT_TRUE(type.forInput());
1397         EXPECT_FALSE(type.forOutput());
1398         EXPECT_FALSE(type.forStream());
1399         EXPECT_TRUE(type.forPort());
1400 
1401         type = C2NumberPortTuning::output::PARAM_TYPE;
1402         EXPECT_FALSE(type.isVendor());
1403         EXPECT_FALSE(type.isFlexible());
1404         EXPECT_FALSE(type.isGlobal());
1405         EXPECT_FALSE(type.forInput());
1406         EXPECT_TRUE(type.forOutput());
1407         EXPECT_FALSE(type.forStream());
1408         EXPECT_TRUE(type.forPort());
1409 
1410         EXPECT_EQ(C2NumberPortTuning::From(nullptr), nullptr);
1411         EXPECT_EQ(C2NumberPortTuning::input::From(nullptr), nullptr);
1412         EXPECT_EQ(C2NumberPortTuning::output::From(nullptr), nullptr);
1413         EXPECT_EQ(C2NumberTuning::From(&inp1), nullptr);
1414         EXPECT_EQ(C2NumberTuning::From(&inp2), nullptr);
1415         EXPECT_EQ(C2NumberTuning::From(&outp1), nullptr);
1416         EXPECT_EQ(C2NumberTuning::From(&outp2), nullptr);
1417         EXPECT_EQ(C2NumberPortTuning::From(&inp1), &inp1);
1418         EXPECT_EQ(C2NumberPortTuning::From(&inp2), (C2NumberPortTuning*)&inp2);
1419         EXPECT_EQ(C2NumberPortTuning::From(&outp1), &outp1);
1420         EXPECT_EQ(C2NumberPortTuning::From(&outp2), (C2NumberPortTuning*)&outp2);
1421         EXPECT_EQ(C2NumberPortTuning::input::From(&inp1), (C2NumberPortTuning::input*)&inp1);
1422         EXPECT_EQ(C2NumberPortTuning::input::From(&inp2), &inp2);
1423         EXPECT_EQ(C2NumberPortTuning::input::From(&outp1), nullptr);
1424         EXPECT_EQ(C2NumberPortTuning::input::From(&outp2), nullptr);
1425         EXPECT_EQ(C2NumberPortTuning::output::From(&inp1), nullptr);
1426         EXPECT_EQ(C2NumberPortTuning::output::From(&inp2), nullptr);
1427         EXPECT_EQ(C2NumberPortTuning::output::From(&outp1), (C2NumberPortTuning::output*)&outp1);
1428         EXPECT_EQ(C2NumberPortTuning::output::From(&outp2), &outp2);
1429         EXPECT_EQ(C2NumberStreamTuning::From(&inp1), nullptr);
1430         EXPECT_EQ(C2NumberStreamTuning::From(&inp2), nullptr);
1431         EXPECT_EQ(C2NumberStreamTuning::From(&outp1), nullptr);
1432         EXPECT_EQ(C2NumberStreamTuning::From(&outp2), nullptr);
1433         EXPECT_EQ(C2NumberStreamTuning::input::From(&inp1), nullptr);
1434         EXPECT_EQ(C2NumberStreamTuning::input::From(&inp2), nullptr);
1435         EXPECT_EQ(C2NumberStreamTuning::input::From(&outp1), nullptr);
1436         EXPECT_EQ(C2NumberStreamTuning::input::From(&outp2), nullptr);
1437         EXPECT_EQ(C2NumberStreamTuning::output::From(&inp1), nullptr);
1438         EXPECT_EQ(C2NumberStreamTuning::output::From(&inp2), nullptr);
1439         EXPECT_EQ(C2NumberStreamTuning::output::From(&outp1), nullptr);
1440         EXPECT_EQ(C2NumberStreamTuning::output::From(&outp2), nullptr);
1441 
1442         EXPECT_EQ(*(C2Param::Copy(inp1)), inp1);
1443         EXPECT_EQ(*(C2Param::Copy(inp2)), inp2);
1444         EXPECT_EQ(*(C2Param::Copy(outp1)), outp1);
1445         EXPECT_EQ(*(C2Param::Copy(outp2)), outp2);
1446     }
1447 
1448     const C2NumberStreamTuning outs1(true, 1u, 100), ins1(false, 1u, 100);
1449     C2NumberStreamTuning bouts1, bins1, bins3(false, 1u, 100);
1450     const C2NumberStreamTuning::input ins2(1u, 100);
1451     C2NumberStreamTuning::input bins2;
1452     const C2NumberStreamTuning::output outs2(1u, 100);
1453     C2NumberStreamTuning::output bouts2;
1454 
1455     EXPECT_EQ(ins1.coreIndex(), tun.coreIndex());
1456     EXPECT_EQ(outs1.coreIndex(), tun.coreIndex());
1457     EXPECT_EQ(bins1.coreIndex(), tun.coreIndex());
1458     EXPECT_EQ(bouts1.coreIndex(), tun.coreIndex());
1459     EXPECT_EQ(ins2.coreIndex(), tun.coreIndex());
1460     EXPECT_EQ(outs2.coreIndex(), tun.coreIndex());
1461 
1462     EXPECT_EQ(ins1.type(), ins2.type());
1463     EXPECT_EQ(ins1.type(), bins2.type());
1464     EXPECT_EQ(outs1.type(), outs2.type());
1465     EXPECT_EQ(outs1.type(), bouts2.type());
1466     EXPECT_NE(ins1.type(), outs1.type());
1467     EXPECT_NE(ins2.type(), outs2.type());
1468     EXPECT_NE(ins1.type(), bins1.type());
1469     EXPECT_NE(outs1.type(), bouts1.type());
1470     EXPECT_NE(ins1.type(), tun.type());
1471     EXPECT_NE(ins2.type(), tun.type());
1472 
1473     {
1474         static_assert(canCallSetPort(bins3), "should be able to");
1475         static_assert(canCallSetPort(bins1), "should be able to");
1476         static_assert(!canCallSetPort(ins1), "should not be able to (const)");
1477         static_assert(!canCallSetPort(ins2), "should not be able to (const & type)");
1478         static_assert(!canCallSetPort(bins2), "should not be able to (type)");
1479 
1480         // flags & invariables
1481         for (const auto &p : { outs1, ins1, bouts1 }) {
1482             EXPECT_EQ(12u, p.size());
1483             EXPECT_FALSE(p.isVendor());
1484             EXPECT_FALSE(p.isFlexible());
1485             EXPECT_FALSE(p.isGlobal());
1486             EXPECT_TRUE(p.forStream());
1487             EXPECT_FALSE(p.forPort());
1488         }
1489         for (const auto &p : { ins2, bins2 }) {
1490             EXPECT_EQ(12u, p.size());
1491             EXPECT_FALSE(p.isVendor());
1492             EXPECT_FALSE(p.isFlexible());
1493             EXPECT_FALSE(p.isGlobal());
1494             EXPECT_TRUE(p.forStream());
1495             EXPECT_FALSE(p.forPort());
1496         }
1497         for (const auto &p : { outs2, bouts2 }) {
1498             EXPECT_EQ(12u, p.size());
1499             EXPECT_FALSE(p.isVendor());
1500             EXPECT_FALSE(p.isFlexible());
1501             EXPECT_FALSE(p.isGlobal());
1502             EXPECT_TRUE(p.forStream());
1503             EXPECT_FALSE(p.forPort());
1504         }
1505 
1506         // port specific flags & invariables
1507         EXPECT_FALSE(outs1.forInput());
1508         EXPECT_TRUE(outs1.forOutput());
1509 
1510         EXPECT_TRUE(ins1.forInput());
1511         EXPECT_FALSE(ins1.forOutput());
1512 
1513         for (const auto &p : { outs1, ins1 }) {
1514             EXPECT_TRUE((bool)p);
1515             EXPECT_FALSE(!p);
1516             EXPECT_EQ(100, p.mNumber);
1517             EXPECT_EQ(1u, p.stream());
1518         }
1519         for (const auto &p : { outs2, bouts2 }) {
1520             EXPECT_TRUE((bool)p);
1521             EXPECT_FALSE(!p);
1522 
1523             EXPECT_FALSE(p.forInput());
1524             EXPECT_TRUE(p.forOutput());
1525         }
1526         for (const auto &p : { ins2, bins2 }) {
1527             EXPECT_TRUE((bool)p);
1528             EXPECT_FALSE(!p);
1529 
1530             EXPECT_TRUE(p.forInput());
1531             EXPECT_FALSE(p.forOutput());
1532         }
1533         for (const auto &p : { bouts1 } ) {
1534             EXPECT_FALSE((bool)p);
1535             EXPECT_TRUE(!p);
1536 
1537             EXPECT_FALSE(p.forInput());
1538             EXPECT_FALSE(p.forOutput());
1539             EXPECT_EQ(0, p.mNumber);
1540         }
1541 
1542         // values
1543         EXPECT_EQ(100, ins2.mNumber);
1544         EXPECT_EQ(100, outs2.mNumber);
1545         EXPECT_EQ(0, bins1.mNumber);
1546         EXPECT_EQ(0, bins2.mNumber);
1547         EXPECT_EQ(0, bouts1.mNumber);
1548         EXPECT_EQ(0, bouts2.mNumber);
1549 
1550         EXPECT_EQ(1u, ins2.stream());
1551         EXPECT_EQ(1u, outs2.stream());
1552         EXPECT_EQ(0u, bins1.stream());
1553         EXPECT_EQ(0u, bins2.stream());
1554         EXPECT_EQ(0u, bouts1.stream());
1555         EXPECT_EQ(0u, bouts2.stream());
1556 
1557         EXPECT_TRUE(ins1 != outs1);
1558         EXPECT_TRUE(ins1 == ins2);
1559         EXPECT_TRUE(outs1 == outs2);
1560         EXPECT_TRUE(bins1 == bouts1);
1561         EXPECT_TRUE(bins2 != bouts2);
1562 
1563         EXPECT_TRUE(ins1 != bins1);
1564         bins1.mNumber = 100;
1565         EXPECT_TRUE(ins1 != bins1);
1566         bins1.setPort(false /* output */);
1567         EXPECT_TRUE(ins1 != bins1);
1568         bins1.setStream(1u);
1569         EXPECT_TRUE(ins1 == bins1);
1570 
1571         EXPECT_TRUE(ins2 != bins2);
1572         bins2.mNumber = 100;
1573         EXPECT_TRUE(ins2 != bins2);
1574         bins2.setStream(1u);
1575         EXPECT_TRUE(ins2 == bins2);
1576 
1577         bins1.setPort(true /* output */);
1578         EXPECT_TRUE(outs1 == bins1);
1579 
1580         EXPECT_TRUE(outs1 != bouts1);
1581         bouts1.mNumber = 100;
1582         EXPECT_TRUE(outs1 != bouts1);
1583         bouts1.setPort(true /* output */);
1584         EXPECT_TRUE(outs1 != bouts1);
1585         bouts1.setStream(1u);
1586         EXPECT_TRUE(outs1 == bouts1);
1587 
1588         EXPECT_TRUE(outs2 != bouts2);
1589         bouts2.mNumber = 100;
1590         EXPECT_TRUE(outs2 != bouts2);
1591         bouts2.setStream(1u);
1592         EXPECT_TRUE(outs2 == bouts2);
1593 
1594         bouts1.setPort(false /* output */);
1595         EXPECT_TRUE(ins1 == bouts1);
1596 
1597         // index
1598         EXPECT_EQ(C2Param::Type(ins1.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
1599         EXPECT_EQ(C2Param::Type(ins1.type()).typeIndex(), kParamIndexNumber);
1600         EXPECT_EQ(ins1.type(), C2NumberStreamTuning::input::PARAM_TYPE);
1601 
1602         EXPECT_EQ(C2Param::Type(ins2.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
1603         EXPECT_EQ(C2Param::Type(ins2.type()).typeIndex(), kParamIndexNumber);
1604         EXPECT_EQ(ins2.type(), C2NumberStreamTuning::input::PARAM_TYPE);
1605 
1606         EXPECT_EQ(C2Param::Type(outs1.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
1607         EXPECT_EQ(C2Param::Type(outs1.type()).typeIndex(), kParamIndexNumber);
1608         EXPECT_EQ(outs1.type(), C2NumberStreamTuning::output::PARAM_TYPE);
1609 
1610         EXPECT_EQ(C2Param::Type(outs2.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
1611         EXPECT_EQ(C2Param::Type(outs2.type()).typeIndex(), kParamIndexNumber);
1612         EXPECT_EQ(outs2.type(), C2NumberStreamTuning::output::PARAM_TYPE);
1613 
1614         C2Param::CoreIndex index = C2NumberStreamTuning::input::PARAM_TYPE;
1615         EXPECT_FALSE(index.isVendor());
1616         EXPECT_FALSE(index.isFlexible());
1617         EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
1618         EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
1619 
1620         index = C2NumberStreamTuning::output::PARAM_TYPE;
1621         EXPECT_FALSE(index.isVendor());
1622         EXPECT_FALSE(index.isFlexible());
1623         EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
1624         EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
1625 
1626         C2Param::Type type = C2NumberStreamTuning::input::PARAM_TYPE;
1627         EXPECT_FALSE(type.isVendor());
1628         EXPECT_FALSE(type.isFlexible());
1629         EXPECT_FALSE(type.isGlobal());
1630         EXPECT_TRUE(type.forInput());
1631         EXPECT_FALSE(type.forOutput());
1632         EXPECT_TRUE(type.forStream());
1633         EXPECT_FALSE(type.forPort());
1634 
1635         type = C2NumberStreamTuning::output::PARAM_TYPE;
1636         EXPECT_FALSE(type.isVendor());
1637         EXPECT_FALSE(type.isFlexible());
1638         EXPECT_FALSE(type.isGlobal());
1639         EXPECT_FALSE(type.forInput());
1640         EXPECT_TRUE(type.forOutput());
1641         EXPECT_TRUE(type.forStream());
1642         EXPECT_FALSE(type.forPort());
1643 
1644         EXPECT_EQ(C2NumberPortTuning::From(nullptr), nullptr);
1645         EXPECT_EQ(C2NumberPortTuning::input::From(nullptr), nullptr);
1646         EXPECT_EQ(C2NumberPortTuning::output::From(nullptr), nullptr);
1647         EXPECT_EQ(C2NumberTuning::From(&ins1), nullptr);
1648         EXPECT_EQ(C2NumberTuning::From(&ins2), nullptr);
1649         EXPECT_EQ(C2NumberTuning::From(&outs1), nullptr);
1650         EXPECT_EQ(C2NumberTuning::From(&outs2), nullptr);
1651         EXPECT_EQ(C2NumberPortTuning::From(&ins1), nullptr);
1652         EXPECT_EQ(C2NumberPortTuning::From(&ins2), nullptr);
1653         EXPECT_EQ(C2NumberPortTuning::From(&outs1), nullptr);
1654         EXPECT_EQ(C2NumberPortTuning::From(&outs2), nullptr);
1655         EXPECT_EQ(C2NumberPortTuning::input::From(&ins1), nullptr);
1656         EXPECT_EQ(C2NumberPortTuning::input::From(&ins2), nullptr);
1657         EXPECT_EQ(C2NumberPortTuning::input::From(&outs1), nullptr);
1658         EXPECT_EQ(C2NumberPortTuning::input::From(&outs2), nullptr);
1659         EXPECT_EQ(C2NumberPortTuning::output::From(&ins1), nullptr);
1660         EXPECT_EQ(C2NumberPortTuning::output::From(&ins2), nullptr);
1661         EXPECT_EQ(C2NumberPortTuning::output::From(&outs1), nullptr);
1662         EXPECT_EQ(C2NumberPortTuning::output::From(&outs2), nullptr);
1663         EXPECT_EQ(C2NumberStreamTuning::From(&ins1), &ins1);
1664         EXPECT_EQ(C2NumberStreamTuning::From(&ins2), (C2NumberStreamTuning*)&ins2);
1665         EXPECT_EQ(C2NumberStreamTuning::From(&outs1), &outs1);
1666         EXPECT_EQ(C2NumberStreamTuning::From(&outs2), (C2NumberStreamTuning*)&outs2);
1667         EXPECT_EQ(C2NumberStreamTuning::input::From(&ins1), (C2NumberStreamTuning::input*)&ins1);
1668         EXPECT_EQ(C2NumberStreamTuning::input::From(&ins2), &ins2);
1669         EXPECT_EQ(C2NumberStreamTuning::input::From(&outs1), nullptr);
1670         EXPECT_EQ(C2NumberStreamTuning::input::From(&outs2), nullptr);
1671         EXPECT_EQ(C2NumberStreamTuning::output::From(&ins1), nullptr);
1672         EXPECT_EQ(C2NumberStreamTuning::output::From(&ins2), nullptr);
1673         EXPECT_EQ(C2NumberStreamTuning::output::From(&outs1), (C2NumberStreamTuning::output*)&outs1);
1674         EXPECT_EQ(C2NumberStreamTuning::output::From(&outs2), &outs2);
1675 
1676         EXPECT_EQ(*(C2Param::Copy(ins1)), ins1);
1677         EXPECT_EQ(*(C2Param::Copy(ins2)), ins2);
1678         EXPECT_EQ(*(C2Param::Copy(outs1)), outs1);
1679         EXPECT_EQ(*(C2Param::Copy(outs2)), outs2);
1680     }
1681 
1682     {
1683         uint32_t videoWidth[] = { 12u, C2NumberStreamTuning::output::PARAM_TYPE, 100 };
1684         C2Param *p1 = C2Param::From(videoWidth, sizeof(videoWidth));
1685         EXPECT_NE(p1, nullptr);
1686         EXPECT_EQ(12u, p1->size());
1687         EXPECT_EQ(p1->type(), C2NumberStreamTuning::output::PARAM_TYPE);
1688 
1689         p1 = C2Param::From(videoWidth, sizeof(videoWidth) + 2);
1690         EXPECT_EQ(p1, nullptr);
1691 
1692         p1 = C2Param::From(videoWidth, sizeof(videoWidth) - 2);
1693         EXPECT_EQ(p1, nullptr);
1694 
1695         p1 = C2Param::From(videoWidth, 3);
1696         EXPECT_EQ(p1, nullptr);
1697 
1698         p1 = C2Param::From(videoWidth, 0);
1699         EXPECT_EQ(p1, nullptr);
1700     }
1701 }
1702 
StaticTestAddCoreIndex()1703 void StaticTestAddCoreIndex() {
1704     struct nobase {};
1705     struct base { enum : uint32_t { CORE_INDEX = 1 }; };
1706     static_assert(_C2AddCoreIndex<nobase, 2>::CORE_INDEX == 2, "should be 2");
1707     static_assert(_C2AddCoreIndex<base, 1>::CORE_INDEX == 1, "should be 1");
1708 }
1709 
1710 class TestFlexHelper {
1711     struct _Flex {
1712         int32_t a;
1713         char b[];
_FlexTestFlexHelper::_Flex1714         _Flex() {}
1715         FLEX(_Flex, b);
1716     };
1717 
1718     struct _BoFlex {
1719         _Flex a;
_BoFlexTestFlexHelper::_BoFlex1720         _BoFlex() {}
1721         FLEX(_BoFlex, a);
1722     };
1723 
1724     struct _NonFlex {
1725     };
1726 
1727 
StaticTest()1728     static void StaticTest() {
1729         static_assert(std::is_same<_C2FlexHelper<char>::FlexType, void>::value, "should be void");
1730         static_assert(std::is_same<_C2FlexHelper<char[]>::FlexType, char>::value, "should be char");
1731         static_assert(std::is_same<_C2FlexHelper<_Flex>::FlexType, char>::value, "should be char");
1732 
1733         static_assert(std::is_same<_C2FlexHelper<_BoFlex>::FlexType, char>::value, "should be void");
1734 
1735         static_assert(_C2Flexible<_Flex>::value, "should be flexible");
1736         static_assert(!_C2Flexible<_NonFlex>::value, "should not be flexible");
1737     }
1738 };
1739 
TEST_F(C2ParamTest,FlexParamOpsTest)1740 TEST_F(C2ParamTest, FlexParamOpsTest) {
1741 //    const C2NumbersStruct str{100};
1742     C2NumbersStruct bstr;
1743     {
1744 //        EXPECT_EQ(100, str->m.mNumbers[0]);
1745         (void)&bstr.mNumbers[0];
1746 
1747         C2Param::CoreIndex index = C2NumbersStruct::CORE_INDEX;
1748         EXPECT_FALSE(index.isVendor());
1749         EXPECT_TRUE(index.isFlexible());
1750         EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
1751         EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
1752     }
1753 
1754     std::unique_ptr<C2NumbersTuning> tun_ = C2NumbersTuning::AllocUnique(1);
1755     tun_->m.mNumbers[0] = 100;
1756     std::unique_ptr<const C2NumbersTuning> tun = std::move(tun_);
1757     std::shared_ptr<C2NumbersTuning> btun = C2NumbersTuning::AllocShared(1);
1758 
1759     {
1760         // flags & invariables
1761         const C2NumbersTuning *T[] = { tun.get(), btun.get() };
1762         for (const auto p : T) {
1763             EXPECT_TRUE((bool)(*p));
1764             EXPECT_FALSE(!(*p));
1765             EXPECT_EQ(12u, p->size());
1766 
1767             EXPECT_FALSE(p->isVendor());
1768             EXPECT_TRUE(p->isFlexible());
1769             EXPECT_TRUE(p->isGlobal());
1770             EXPECT_FALSE(p->forInput());
1771             EXPECT_FALSE(p->forOutput());
1772             EXPECT_FALSE(p->forStream());
1773             EXPECT_FALSE(p->forPort());
1774         }
1775 
1776         // value
1777         EXPECT_EQ(100, tun->m.mNumbers[0]);
1778         EXPECT_EQ(0, btun->m.mNumbers[0]);
1779         EXPECT_FALSE(*tun == *btun);
1780         EXPECT_FALSE(tun->operator==(*btun));
1781         EXPECT_TRUE(*tun != *btun);
1782         EXPECT_TRUE(tun->operator!=(*btun));
1783         btun->m.mNumbers[0] = 100;
1784         EXPECT_EQ(*tun, *btun);
1785 
1786         // index
1787         EXPECT_EQ(C2Param::Type(tun->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
1788         EXPECT_EQ(C2Param::Type(tun->type()).typeIndex(), kParamIndexNumbers);
1789         EXPECT_EQ(tun->type(), C2NumbersTuning::PARAM_TYPE);
1790         EXPECT_EQ(tun->stream(), ~0u);
1791 
1792         C2Param::CoreIndex index = C2NumbersTuning::CORE_INDEX;
1793         EXPECT_FALSE(index.isVendor());
1794         EXPECT_TRUE(index.isFlexible());
1795         EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
1796         EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
1797 
1798         C2Param::Type type = C2NumbersTuning::PARAM_TYPE;
1799         EXPECT_FALSE(type.isVendor());
1800         EXPECT_TRUE(type.isFlexible());
1801         EXPECT_TRUE(type.isGlobal());
1802         EXPECT_FALSE(type.forInput());
1803         EXPECT_FALSE(type.forOutput());
1804         EXPECT_FALSE(type.forStream());
1805         EXPECT_FALSE(type.forPort());
1806 
1807         EXPECT_EQ(C2NumbersTuning::From(nullptr), nullptr);
1808         EXPECT_EQ(C2NumbersTuning::From(tun.get()), tun.get());
1809         EXPECT_EQ(C2NumbersPortTuning::From(tun.get()), nullptr);
1810         EXPECT_EQ(C2NumbersPortTuning::input::From(tun.get()), nullptr);
1811         EXPECT_EQ(C2NumbersPortTuning::output::From(tun.get()), nullptr);
1812         EXPECT_EQ(C2NumbersStreamTuning::From(tun.get()), nullptr);
1813         EXPECT_EQ(C2NumbersStreamTuning::input::From(tun.get()), nullptr);
1814         EXPECT_EQ(C2NumbersStreamTuning::output::From(tun.get()), nullptr);
1815 
1816         EXPECT_EQ(*(C2Param::Copy(*tun)), *tun);
1817     }
1818 
1819     std::unique_ptr<C2NumbersPortTuning> outp1_(C2NumbersPortTuning::AllocUnique(1, true)),
1820             inp1_ = C2NumbersPortTuning::AllocUnique(1, false);
1821     outp1_->m.mNumbers[0] = 100;
1822     inp1_->m.mNumbers[0] = 100;
1823     std::unique_ptr<const C2NumbersPortTuning> outp1 = std::move(outp1_);
1824     std::unique_ptr<const C2NumbersPortTuning> inp1 = std::move(inp1_);
1825     std::shared_ptr<C2NumbersPortTuning> boutp1(C2NumbersPortTuning::AllocShared(1)),
1826             binp1 = C2NumbersPortTuning::AllocShared(1),
1827             binp3 = C2NumbersPortTuning::AllocShared(1, false);
1828     binp3->m.mNumbers[0] = 100;
1829     std::unique_ptr<C2NumbersPortTuning::input> inp2_(C2NumbersPortTuning::input::AllocUnique(1));
1830     inp2_->m.mNumbers[0] = 100;
1831     std::unique_ptr<const C2NumbersPortTuning::input> inp2 = std::move(inp2_);
1832     std::shared_ptr<C2NumbersPortTuning::input> binp2(C2NumbersPortTuning::input::AllocShared(1));
1833     std::unique_ptr<C2NumbersPortTuning::output> outp2_(C2NumbersPortTuning::output::AllocUnique(1));
1834     outp2_->m.mNumbers[0] = 100;
1835     std::unique_ptr<const C2NumbersPortTuning::output> outp2 = std::move(outp2_);
1836     std::shared_ptr<C2NumbersPortTuning::output> boutp2(C2NumbersPortTuning::output::AllocShared(1));
1837 
1838     {
1839         static_assert(canCallSetPort(*binp3), "should be able to");
1840         static_assert(canCallSetPort(*binp1), "should be able to");
1841         static_assert(!canCallSetPort(*inp1), "should not be able to (const)");
1842         static_assert(!canCallSetPort(*inp2), "should not be able to (const & type)");
1843         static_assert(!canCallSetPort(*binp2), "should not be able to (type)");
1844 
1845         // flags & invariables
1846         const C2NumbersPortTuning *P[] = { outp1.get(), inp1.get(), boutp1.get() };
1847         for (const auto p : P) {
1848             EXPECT_EQ(12u, p->size());
1849             EXPECT_FALSE(p->isVendor());
1850             EXPECT_TRUE(p->isFlexible());
1851             EXPECT_FALSE(p->isGlobal());
1852             EXPECT_FALSE(p->forStream());
1853             EXPECT_TRUE(p->forPort());
1854         }
1855         const C2NumbersPortTuning::input *PI[] = { inp2.get(), binp2.get() };
1856         for (const auto p : PI) {
1857             EXPECT_EQ(12u, p->size());
1858             EXPECT_FALSE(p->isVendor());
1859             EXPECT_TRUE(p->isFlexible());
1860             EXPECT_FALSE(p->isGlobal());
1861             EXPECT_FALSE(p->forStream());
1862             EXPECT_TRUE(p->forPort());
1863         }
1864         const C2NumbersPortTuning::output *PO[] = { outp2.get(), boutp2.get() };
1865         for (const auto p : PO) {
1866             EXPECT_EQ(12u, p->size());
1867             EXPECT_FALSE(p->isVendor());
1868             EXPECT_TRUE(p->isFlexible());
1869             EXPECT_FALSE(p->isGlobal());
1870             EXPECT_FALSE(p->forStream());
1871             EXPECT_TRUE(p->forPort());
1872         }
1873 
1874         // port specific flags & invariables
1875         EXPECT_FALSE(outp1->forInput());
1876         EXPECT_TRUE(outp1->forOutput());
1877 
1878         EXPECT_TRUE(inp1->forInput());
1879         EXPECT_FALSE(inp1->forOutput());
1880 
1881         const C2NumbersPortTuning *P2[] = { outp1.get(), inp1.get() };
1882         for (const auto p : P2) {
1883             EXPECT_TRUE((bool)(*p));
1884             EXPECT_FALSE(!(*p));
1885             EXPECT_EQ(100, p->m.mNumbers[0]);
1886         }
1887         for (const auto p : PO) {
1888             EXPECT_TRUE((bool)(*p));
1889             EXPECT_FALSE(!(*p));
1890 
1891             EXPECT_FALSE(p->forInput());
1892             EXPECT_TRUE(p->forOutput());
1893         }
1894         for (const auto p : PI) {
1895             EXPECT_TRUE((bool)(*p));
1896             EXPECT_FALSE(!(*p));
1897 
1898             EXPECT_TRUE(p->forInput());
1899             EXPECT_FALSE(p->forOutput());
1900         }
1901         const C2NumbersPortTuning *P3[] = { boutp1.get() };
1902         for (const auto p : P3) {
1903             EXPECT_FALSE((bool)(*p));
1904             EXPECT_TRUE(!(*p));
1905 
1906             EXPECT_FALSE(p->forInput());
1907             EXPECT_FALSE(p->forOutput());
1908             EXPECT_EQ(0, p->m.mNumbers[0]);
1909         }
1910 
1911         // values
1912         EXPECT_EQ(100, inp2->m.mNumbers[0]);
1913         EXPECT_EQ(100, outp2->m.mNumbers[0]);
1914         EXPECT_EQ(0, binp1->m.mNumbers[0]);
1915         EXPECT_EQ(0, binp2->m.mNumbers[0]);
1916         EXPECT_EQ(0, boutp1->m.mNumbers[0]);
1917         EXPECT_EQ(0, boutp2->m.mNumbers[0]);
1918 
1919         EXPECT_TRUE(*inp1 != *outp1);
1920         EXPECT_TRUE(*inp1 == *inp2);
1921         EXPECT_TRUE(*outp1 == *outp2);
1922         EXPECT_TRUE(*binp1 == *boutp1);
1923         EXPECT_TRUE(*binp2 != *boutp2);
1924 
1925         EXPECT_TRUE(*inp1 != *binp1);
1926         binp1->m.mNumbers[0] = 100;
1927         EXPECT_TRUE(*inp1 != *binp1);
1928         binp1->setPort(false /* output */);
1929         EXPECT_TRUE((bool)*binp1);
1930         EXPECT_FALSE(!*binp1);
1931         EXPECT_TRUE(*inp1 == *binp1);
1932 
1933         EXPECT_TRUE(*inp2 != *binp2);
1934         binp2->m.mNumbers[0] = 100;
1935         EXPECT_TRUE(*inp2 == *binp2);
1936 
1937         binp1->setPort(true /* output */);
1938         EXPECT_TRUE(*outp1 == *binp1);
1939 
1940         EXPECT_TRUE(*outp1 != *boutp1);
1941         boutp1->m.mNumbers[0] = 100;
1942         EXPECT_TRUE(*outp1 != *boutp1);
1943         boutp1->setPort(true /* output */);
1944         EXPECT_TRUE((bool)*boutp1);
1945         EXPECT_FALSE(!*boutp1);
1946         EXPECT_TRUE(*outp1 == *boutp1);
1947 
1948         EXPECT_TRUE(*outp2 != *boutp2);
1949         boutp2->m.mNumbers[0] = 100;
1950         EXPECT_TRUE(*outp2 == *boutp2);
1951 
1952         boutp1->setPort(false /* output */);
1953         EXPECT_TRUE(*inp1 == *boutp1);
1954 
1955         // index
1956         EXPECT_EQ(C2Param::Type(inp1->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
1957         EXPECT_EQ(C2Param::Type(inp1->type()).typeIndex(), kParamIndexNumbers);
1958         EXPECT_EQ(inp1->type(), C2NumbersPortTuning::input::PARAM_TYPE);
1959         EXPECT_EQ(inp1->stream(), ~0u);
1960 
1961         EXPECT_EQ(C2Param::Type(inp2->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
1962         EXPECT_EQ(C2Param::Type(inp2->type()).typeIndex(), kParamIndexNumbers);
1963         EXPECT_EQ(inp2->type(), C2NumbersPortTuning::input::PARAM_TYPE);
1964         EXPECT_EQ(inp2->stream(), ~0u);
1965 
1966         EXPECT_EQ(C2Param::Type(outp1->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
1967         EXPECT_EQ(C2Param::Type(outp1->type()).typeIndex(), kParamIndexNumbers);
1968         EXPECT_EQ(outp1->type(), C2NumbersPortTuning::output::PARAM_TYPE);
1969         EXPECT_EQ(outp1->stream(), ~0u);
1970 
1971         EXPECT_EQ(C2Param::Type(outp2->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
1972         EXPECT_EQ(C2Param::Type(outp2->type()).typeIndex(), kParamIndexNumbers);
1973         EXPECT_EQ(outp2->type(), C2NumbersPortTuning::output::PARAM_TYPE);
1974         EXPECT_EQ(outp2->stream(), ~0u);
1975 
1976         C2Param::CoreIndex index = C2NumbersPortTuning::input::PARAM_TYPE;
1977         EXPECT_FALSE(index.isVendor());
1978         EXPECT_TRUE(index.isFlexible());
1979         EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
1980         EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
1981 
1982         index = C2NumbersPortTuning::output::PARAM_TYPE;
1983         EXPECT_FALSE(index.isVendor());
1984         EXPECT_TRUE(index.isFlexible());
1985         EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
1986         EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
1987 
1988         C2Param::Type type = C2NumbersPortTuning::input::PARAM_TYPE;
1989         EXPECT_FALSE(type.isVendor());
1990         EXPECT_TRUE(type.isFlexible());
1991         EXPECT_FALSE(type.isGlobal());
1992         EXPECT_TRUE(type.forInput());
1993         EXPECT_FALSE(type.forOutput());
1994         EXPECT_FALSE(type.forStream());
1995         EXPECT_TRUE(type.forPort());
1996 
1997         type = C2NumbersPortTuning::output::PARAM_TYPE;
1998         EXPECT_FALSE(type.isVendor());
1999         EXPECT_TRUE(type.isFlexible());
2000         EXPECT_FALSE(type.isGlobal());
2001         EXPECT_FALSE(type.forInput());
2002         EXPECT_TRUE(type.forOutput());
2003         EXPECT_FALSE(type.forStream());
2004         EXPECT_TRUE(type.forPort());
2005 
2006         EXPECT_EQ(C2NumbersPortTuning::From(nullptr), nullptr);
2007         EXPECT_EQ(C2NumbersPortTuning::input::From(nullptr), nullptr);
2008         EXPECT_EQ(C2NumbersPortTuning::output::From(nullptr), nullptr);
2009         EXPECT_EQ(C2NumbersTuning::From(inp1.get()), nullptr);
2010         EXPECT_EQ(C2NumbersTuning::From(inp2.get()), nullptr);
2011         EXPECT_EQ(C2NumbersTuning::From(outp1.get()), nullptr);
2012         EXPECT_EQ(C2NumbersTuning::From(outp2.get()), nullptr);
2013         EXPECT_EQ(C2NumbersPortTuning::From(inp1.get()), inp1.get());
2014         EXPECT_EQ(C2NumbersPortTuning::From(inp2.get()), (C2NumbersPortTuning*)inp2.get());
2015         EXPECT_EQ(C2NumbersPortTuning::From(outp1.get()), outp1.get());
2016         EXPECT_EQ(C2NumbersPortTuning::From(outp2.get()), (C2NumbersPortTuning*)outp2.get());
2017         EXPECT_EQ(C2NumbersPortTuning::input::From(inp1.get()), (C2NumbersPortTuning::input*)inp1.get());
2018         EXPECT_EQ(C2NumbersPortTuning::input::From(inp2.get()), inp2.get());
2019         EXPECT_EQ(C2NumbersPortTuning::input::From(outp1.get()), nullptr);
2020         EXPECT_EQ(C2NumbersPortTuning::input::From(outp2.get()), nullptr);
2021         EXPECT_EQ(C2NumbersPortTuning::output::From(inp1.get()), nullptr);
2022         EXPECT_EQ(C2NumbersPortTuning::output::From(inp2.get()), nullptr);
2023         EXPECT_EQ(C2NumbersPortTuning::output::From(outp1.get()), (C2NumbersPortTuning::output*)outp1.get());
2024         EXPECT_EQ(C2NumbersPortTuning::output::From(outp2.get()), outp2.get());
2025         EXPECT_EQ(C2NumbersStreamTuning::From(inp1.get()), nullptr);
2026         EXPECT_EQ(C2NumbersStreamTuning::From(inp2.get()), nullptr);
2027         EXPECT_EQ(C2NumbersStreamTuning::From(outp1.get()), nullptr);
2028         EXPECT_EQ(C2NumbersStreamTuning::From(outp2.get()), nullptr);
2029         EXPECT_EQ(C2NumbersStreamTuning::input::From(inp1.get()), nullptr);
2030         EXPECT_EQ(C2NumbersStreamTuning::input::From(inp2.get()), nullptr);
2031         EXPECT_EQ(C2NumbersStreamTuning::input::From(outp1.get()), nullptr);
2032         EXPECT_EQ(C2NumbersStreamTuning::input::From(outp2.get()), nullptr);
2033         EXPECT_EQ(C2NumbersStreamTuning::output::From(inp1.get()), nullptr);
2034         EXPECT_EQ(C2NumbersStreamTuning::output::From(inp2.get()), nullptr);
2035         EXPECT_EQ(C2NumbersStreamTuning::output::From(outp1.get()), nullptr);
2036         EXPECT_EQ(C2NumbersStreamTuning::output::From(outp2.get()), nullptr);
2037 
2038         EXPECT_EQ(*(C2Param::Copy(*inp1)), *inp1);
2039         EXPECT_EQ(*(C2Param::Copy(*inp2)), *inp2);
2040         EXPECT_EQ(*(C2Param::Copy(*outp1)), *outp1);
2041         EXPECT_EQ(*(C2Param::Copy(*outp2)), *outp2);
2042     }
2043 
2044     std::unique_ptr<C2NumbersStreamTuning> outs1_(C2NumbersStreamTuning::AllocUnique(1, true, 1u));
2045     outs1_->m.mNumbers[0] = 100;
2046     std::unique_ptr<const C2NumbersStreamTuning> outs1 = std::move(outs1_);
2047     std::unique_ptr<C2NumbersStreamTuning> ins1_(C2NumbersStreamTuning::AllocUnique(1, false, 1u));
2048     ins1_->m.mNumbers[0] = 100;
2049     std::unique_ptr<const C2NumbersStreamTuning> ins1 = std::move(ins1_);
2050     std::shared_ptr<C2NumbersStreamTuning> bouts1(C2NumbersStreamTuning::AllocShared(1));
2051     std::shared_ptr<C2NumbersStreamTuning> bins1(C2NumbersStreamTuning::AllocShared(1));
2052     std::shared_ptr<C2NumbersStreamTuning> bins3(C2NumbersStreamTuning::AllocShared(1, false, 1u));
2053     bins3->m.mNumbers[0] = 100;
2054     std::unique_ptr<C2NumbersStreamTuning::input> ins2_(C2NumbersStreamTuning::input::AllocUnique(1, 1u));
2055     ins2_->m.mNumbers[0] = 100;
2056     std::unique_ptr<const C2NumbersStreamTuning::input> ins2 = std::move(ins2_);
2057     std::shared_ptr<C2NumbersStreamTuning::input> bins2(C2NumbersStreamTuning::input::AllocShared(1));
2058     std::unique_ptr<C2NumbersStreamTuning::output> outs2_(C2NumbersStreamTuning::output::AllocUnique(1, 1u));
2059     outs2_->m.mNumbers[0] = 100;
2060     std::unique_ptr<const C2NumbersStreamTuning::output> outs2 = std::move(outs2_);
2061     std::shared_ptr<C2NumbersStreamTuning::output> bouts2(C2NumbersStreamTuning::output::AllocShared(1));
2062 
2063     {
2064         static_assert(canCallSetPort(*bins3), "should be able to");
2065         static_assert(canCallSetPort(*bins1), "should be able to");
2066         static_assert(!canCallSetPort(*ins1), "should not be able to (const)");
2067         static_assert(!canCallSetPort(*ins2), "should not be able to (const & type)");
2068         static_assert(!canCallSetPort(*bins2), "should not be able to (type)");
2069 
2070         // flags & invariables
2071         const C2NumbersStreamTuning *S[] = { outs1.get(), ins1.get(), bouts1.get() };
2072         for (const auto p : S) {
2073             EXPECT_EQ(12u, p->size());
2074             EXPECT_FALSE(p->isVendor());
2075             EXPECT_TRUE(p->isFlexible());
2076             EXPECT_FALSE(p->isGlobal());
2077             EXPECT_TRUE(p->forStream());
2078             EXPECT_FALSE(p->forPort());
2079         }
2080         const C2NumbersStreamTuning::input *SI[] = { ins2.get(), bins2.get() };
2081         for (const auto p : SI) {
2082             EXPECT_EQ(12u, p->size());
2083             EXPECT_FALSE(p->isVendor());
2084             EXPECT_TRUE(p->isFlexible());
2085             EXPECT_FALSE(p->isGlobal());
2086             EXPECT_TRUE(p->forStream());
2087             EXPECT_FALSE(p->forPort());
2088         }
2089         const C2NumbersStreamTuning::output *SO[] = { outs2.get(), bouts2.get() };
2090         for (const auto p : SO) {
2091             EXPECT_EQ(12u, p->size());
2092             EXPECT_FALSE(p->isVendor());
2093             EXPECT_TRUE(p->isFlexible());
2094             EXPECT_FALSE(p->isGlobal());
2095             EXPECT_TRUE(p->forStream());
2096             EXPECT_FALSE(p->forPort());
2097         }
2098 
2099         // port specific flags & invariables
2100         EXPECT_FALSE(outs1->forInput());
2101         EXPECT_TRUE(outs1->forOutput());
2102 
2103         EXPECT_TRUE(ins1->forInput());
2104         EXPECT_FALSE(ins1->forOutput());
2105 
2106         const C2NumbersStreamTuning *S2[] = { outs1.get(), ins1.get() };
2107         for (const auto p : S2) {
2108             EXPECT_TRUE((bool)(*p));
2109             EXPECT_FALSE(!(*p));
2110             EXPECT_EQ(100, p->m.mNumbers[0]);
2111             EXPECT_EQ(1u, p->stream());
2112         }
2113         for (const auto p : SO) {
2114             EXPECT_TRUE((bool)(*p));
2115             EXPECT_FALSE(!(*p));
2116 
2117             EXPECT_FALSE(p->forInput());
2118             EXPECT_TRUE(p->forOutput());
2119         }
2120         for (const auto p : SI) {
2121             EXPECT_TRUE((bool)(*p));
2122             EXPECT_FALSE(!(*p));
2123 
2124             EXPECT_TRUE(p->forInput());
2125             EXPECT_FALSE(p->forOutput());
2126         }
2127         const C2NumbersStreamTuning *S3[] = { bouts1.get() };
2128         for (const auto p : S3) {
2129             EXPECT_FALSE((bool)(*p));
2130             EXPECT_TRUE(!(*p));
2131 
2132             EXPECT_FALSE(p->forInput());
2133             EXPECT_FALSE(p->forOutput());
2134             EXPECT_EQ(0, p->m.mNumbers[0]);
2135         }
2136 
2137         // values
2138         EXPECT_EQ(100, ins2->m.mNumbers[0]);
2139         EXPECT_EQ(100, outs2->m.mNumbers[0]);
2140         EXPECT_EQ(0, bins1->m.mNumbers[0]);
2141         EXPECT_EQ(0, bins2->m.mNumbers[0]);
2142         EXPECT_EQ(0, bouts1->m.mNumbers[0]);
2143         EXPECT_EQ(0, bouts2->m.mNumbers[0]);
2144 
2145         EXPECT_EQ(1u, ins2->stream());
2146         EXPECT_EQ(1u, outs2->stream());
2147         EXPECT_EQ(0u, bins1->stream());
2148         EXPECT_EQ(0u, bins2->stream());
2149         EXPECT_EQ(0u, bouts1->stream());
2150         EXPECT_EQ(0u, bouts2->stream());
2151 
2152         EXPECT_TRUE(*ins1 != *outs1);
2153         EXPECT_TRUE(*ins1 == *ins2);
2154         EXPECT_TRUE(*outs1 == *outs2);
2155         EXPECT_TRUE(*bins1 == *bouts1);
2156         EXPECT_TRUE(*bins2 != *bouts2);
2157 
2158         EXPECT_TRUE(*ins1 != *bins1);
2159         bins1->m.mNumbers[0] = 100;
2160         EXPECT_TRUE(*ins1 != *bins1);
2161         bins1->setPort(false /* output */);
2162         EXPECT_TRUE(*ins1 != *bins1);
2163         bins1->setStream(1u);
2164         EXPECT_TRUE(*ins1 == *bins1);
2165 
2166         EXPECT_TRUE(*ins2 != *bins2);
2167         bins2->m.mNumbers[0] = 100;
2168         EXPECT_TRUE(*ins2 != *bins2);
2169         bins2->setStream(1u);
2170         EXPECT_TRUE(*ins2 == *bins2);
2171 
2172         bins1->setPort(true /* output */);
2173         EXPECT_TRUE(*outs1 == *bins1);
2174 
2175         EXPECT_TRUE(*outs1 != *bouts1);
2176         bouts1->m.mNumbers[0] = 100;
2177         EXPECT_TRUE(*outs1 != *bouts1);
2178         bouts1->setPort(true /* output */);
2179         EXPECT_TRUE(*outs1 != *bouts1);
2180         bouts1->setStream(1u);
2181         EXPECT_TRUE(*outs1 == *bouts1);
2182 
2183         EXPECT_TRUE(*outs2 != *bouts2);
2184         bouts2->m.mNumbers[0] = 100;
2185         EXPECT_TRUE(*outs2 != *bouts2);
2186         bouts2->setStream(1u);
2187         EXPECT_TRUE(*outs2 == *bouts2);
2188 
2189         bouts1->setPort(false /* output */);
2190         EXPECT_TRUE(*ins1 == *bouts1);
2191 
2192         // index
2193         EXPECT_EQ(C2Param::Type(ins1->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
2194         EXPECT_EQ(C2Param::Type(ins1->type()).typeIndex(), kParamIndexNumbers);
2195         EXPECT_EQ(ins1->type(), C2NumbersStreamTuning::input::PARAM_TYPE);
2196 
2197         EXPECT_EQ(C2Param::Type(ins2->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
2198         EXPECT_EQ(C2Param::Type(ins2->type()).typeIndex(), kParamIndexNumbers);
2199         EXPECT_EQ(ins2->type(), C2NumbersStreamTuning::input::PARAM_TYPE);
2200 
2201         EXPECT_EQ(C2Param::Type(outs1->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
2202         EXPECT_EQ(C2Param::Type(outs1->type()).typeIndex(), kParamIndexNumbers);
2203         EXPECT_EQ(outs1->type(), C2NumbersStreamTuning::output::PARAM_TYPE);
2204 
2205         EXPECT_EQ(C2Param::Type(outs2->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
2206         EXPECT_EQ(C2Param::Type(outs2->type()).typeIndex(), kParamIndexNumbers);
2207         EXPECT_EQ(outs2->type(), C2NumbersStreamTuning::output::PARAM_TYPE);
2208 
2209         C2Param::CoreIndex index = C2NumbersStreamTuning::input::PARAM_TYPE;
2210         EXPECT_FALSE(index.isVendor());
2211         EXPECT_TRUE(index.isFlexible());
2212         EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
2213         EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
2214 
2215         index = C2NumbersStreamTuning::output::PARAM_TYPE;
2216         EXPECT_FALSE(index.isVendor());
2217         EXPECT_TRUE(index.isFlexible());
2218         EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
2219         EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
2220 
2221         C2Param::Type type = C2NumbersStreamTuning::input::PARAM_TYPE;
2222         EXPECT_FALSE(type.isVendor());
2223         EXPECT_TRUE(type.isFlexible());
2224         EXPECT_FALSE(type.isGlobal());
2225         EXPECT_TRUE(type.forInput());
2226         EXPECT_FALSE(type.forOutput());
2227         EXPECT_TRUE(type.forStream());
2228         EXPECT_FALSE(type.forPort());
2229 
2230         type = C2NumbersStreamTuning::output::PARAM_TYPE;
2231         EXPECT_FALSE(type.isVendor());
2232         EXPECT_TRUE(type.isFlexible());
2233         EXPECT_FALSE(type.isGlobal());
2234         EXPECT_FALSE(type.forInput());
2235         EXPECT_TRUE(type.forOutput());
2236         EXPECT_TRUE(type.forStream());
2237         EXPECT_FALSE(type.forPort());
2238 
2239         EXPECT_EQ(C2NumbersPortTuning::From(nullptr), nullptr);
2240         EXPECT_EQ(C2NumbersPortTuning::input::From(nullptr), nullptr);
2241         EXPECT_EQ(C2NumbersPortTuning::output::From(nullptr), nullptr);
2242         EXPECT_EQ(C2NumbersTuning::From(ins1.get()), nullptr);
2243         EXPECT_EQ(C2NumbersTuning::From(ins2.get()), nullptr);
2244         EXPECT_EQ(C2NumbersTuning::From(outs1.get()), nullptr);
2245         EXPECT_EQ(C2NumbersTuning::From(outs2.get()), nullptr);
2246         EXPECT_EQ(C2NumbersPortTuning::From(ins1.get()), nullptr);
2247         EXPECT_EQ(C2NumbersPortTuning::From(ins2.get()), nullptr);
2248         EXPECT_EQ(C2NumbersPortTuning::From(outs1.get()), nullptr);
2249         EXPECT_EQ(C2NumbersPortTuning::From(outs2.get()), nullptr);
2250         EXPECT_EQ(C2NumbersPortTuning::input::From(ins1.get()), nullptr);
2251         EXPECT_EQ(C2NumbersPortTuning::input::From(ins2.get()), nullptr);
2252         EXPECT_EQ(C2NumbersPortTuning::input::From(outs1.get()), nullptr);
2253         EXPECT_EQ(C2NumbersPortTuning::input::From(outs2.get()), nullptr);
2254         EXPECT_EQ(C2NumbersPortTuning::output::From(ins1.get()), nullptr);
2255         EXPECT_EQ(C2NumbersPortTuning::output::From(ins2.get()), nullptr);
2256         EXPECT_EQ(C2NumbersPortTuning::output::From(outs1.get()), nullptr);
2257         EXPECT_EQ(C2NumbersPortTuning::output::From(outs2.get()), nullptr);
2258         EXPECT_EQ(C2NumbersStreamTuning::From(ins1.get()), ins1.get());
2259         EXPECT_EQ(C2NumbersStreamTuning::From(ins2.get()), (C2NumbersStreamTuning*)ins2.get());
2260         EXPECT_EQ(C2NumbersStreamTuning::From(outs1.get()), outs1.get());
2261         EXPECT_EQ(C2NumbersStreamTuning::From(outs2.get()), (C2NumbersStreamTuning*)outs2.get());
2262         EXPECT_EQ(C2NumbersStreamTuning::input::From(ins1.get()), (C2NumbersStreamTuning::input*)ins1.get());
2263         EXPECT_EQ(C2NumbersStreamTuning::input::From(ins2.get()), ins2.get());
2264         EXPECT_EQ(C2NumbersStreamTuning::input::From(outs1.get()), nullptr);
2265         EXPECT_EQ(C2NumbersStreamTuning::input::From(outs2.get()), nullptr);
2266         EXPECT_EQ(C2NumbersStreamTuning::output::From(ins1.get()), nullptr);
2267         EXPECT_EQ(C2NumbersStreamTuning::output::From(ins2.get()), nullptr);
2268         EXPECT_EQ(C2NumbersStreamTuning::output::From(outs1.get()), (C2NumbersStreamTuning::output*)outs1.get());
2269         EXPECT_EQ(C2NumbersStreamTuning::output::From(outs2.get()), outs2.get());
2270 
2271         EXPECT_EQ(*(C2Param::Copy(*ins1)), *ins1);
2272         EXPECT_EQ(*(C2Param::Copy(*ins2)), *ins2);
2273         EXPECT_EQ(*(C2Param::Copy(*outs1)), *outs1);
2274         EXPECT_EQ(*(C2Param::Copy(*outs2)), *outs2);
2275     }
2276 
2277     {
2278         C2Int32Value int32Value(INT32_MIN);
2279         static_assert(std::is_same<decltype(int32Value.value), int32_t>::value, "should be int32_t");
2280         EXPECT_EQ(INT32_MIN, int32Value.value);
2281         std::vector<C2FieldDescriptor> fields = int32Value.FieldList();
2282         EXPECT_EQ(1u, fields.size());
2283         EXPECT_EQ(FD::INT32, fields.cbegin()->type());
2284         EXPECT_EQ(1u, fields.cbegin()->extent());
2285         EXPECT_EQ(C2String("value"), fields.cbegin()->name());
2286     }
2287 
2288     {
2289         C2Uint32Value uint32Value(UINT32_MAX);
2290         static_assert(std::is_same<decltype(uint32Value.value), uint32_t>::value, "should be uint32_t");
2291         EXPECT_EQ(UINT32_MAX, uint32Value.value);
2292         std::vector<C2FieldDescriptor> fields = uint32Value.FieldList();
2293         EXPECT_EQ(1u, fields.size());
2294         EXPECT_EQ(FD::UINT32, fields.cbegin()->type());
2295         EXPECT_EQ(1u, fields.cbegin()->extent());
2296         EXPECT_EQ(C2String("value"), fields.cbegin()->name());
2297     }
2298 
2299     {
2300         C2Int64Value int64Value(INT64_MIN);
2301         static_assert(std::is_same<decltype(int64Value.value), int64_t>::value, "should be int64_t");
2302         EXPECT_EQ(INT64_MIN, int64Value.value);
2303         std::vector<C2FieldDescriptor> fields = int64Value.FieldList();
2304         EXPECT_EQ(1u, fields.size());
2305         EXPECT_EQ(FD::INT64, fields.cbegin()->type());
2306         EXPECT_EQ(1u, fields.cbegin()->extent());
2307         EXPECT_EQ(C2String("value"), fields.cbegin()->name());
2308     }
2309 
2310     {
2311         C2Uint64Value uint64Value(UINT64_MAX);
2312         static_assert(std::is_same<decltype(uint64Value.value), uint64_t>::value, "should be uint64_t");
2313         EXPECT_EQ(UINT64_MAX, uint64Value.value);
2314         std::vector<C2FieldDescriptor> fields = uint64Value.FieldList();
2315         EXPECT_EQ(1u, fields.size());
2316         EXPECT_EQ(FD::UINT64, fields.cbegin()->type());
2317         EXPECT_EQ(1u, fields.cbegin()->extent());
2318         EXPECT_EQ(C2String("value"), fields.cbegin()->name());
2319     }
2320 
2321     {
2322         C2FloatValue floatValue(123.4f);
2323         static_assert(std::is_same<decltype(floatValue.value), float>::value, "should be float");
2324         EXPECT_EQ(123.4f, floatValue.value);
2325         std::vector<C2FieldDescriptor> fields = floatValue.FieldList();
2326         EXPECT_EQ(1u, fields.size());
2327         EXPECT_EQ(FD::FLOAT, fields.cbegin()->type());
2328         EXPECT_EQ(1u, fields.cbegin()->extent());
2329         EXPECT_EQ(C2String("value"), fields.cbegin()->name());
2330     }
2331 
2332     {
2333         uint8_t initValue[] = "ABCD";
2334         typedef C2GlobalParam<C2Setting, C2BlobValue, 0> BlobSetting;
2335         std::unique_ptr<BlobSetting> blobValue = BlobSetting::AllocUnique(6, C2ConstMemoryBlock<uint8_t>(initValue));
2336         static_assert(std::is_same<decltype(blobValue->m.value), uint8_t[]>::value, "should be uint8_t[]");
2337         EXPECT_EQ(0, memcmp(blobValue->m.value, "ABCD\0", 6));
2338         EXPECT_EQ(6u, blobValue->flexCount());
2339         blobValue->setFlexCount(7u); // increasing the count does not change it
2340         EXPECT_EQ(6u, blobValue->flexCount());
2341         blobValue->setFlexCount(2u); // decreasing the count changes it to it
2342         EXPECT_EQ(2u, blobValue->flexCount());
2343         blobValue->setFlexCount(0u); // can decrease to 0 and blob remains valid
2344         EXPECT_EQ(0u, blobValue->flexCount());
2345         EXPECT_TRUE(*blobValue);
2346         blobValue->invalidate(); // flex params can be invalidated => results in 0 size
2347         EXPECT_FALSE(*blobValue);
2348         EXPECT_EQ(0u, blobValue->size());
2349 
2350         std::vector<C2FieldDescriptor> fields = blobValue->FieldList();
2351         EXPECT_EQ(1u, fields.size());
2352         EXPECT_EQ(FD::BLOB, fields.cbegin()->type());
2353         EXPECT_EQ(0u, fields.cbegin()->extent());
2354         EXPECT_EQ(C2String("value"), fields.cbegin()->name());
2355 
2356         blobValue = BlobSetting::AllocUnique(3, C2ConstMemoryBlock<uint8_t>(initValue));
2357         EXPECT_EQ(0, memcmp(blobValue->m.value, "ABC", 3));
2358         EXPECT_EQ(3u, blobValue->flexCount());
2359     }
2360 
2361     {
2362         constexpr char initValue[] = "ABCD";
2363         typedef C2GlobalParam<C2Setting, C2StringValue, 0> StringSetting;
2364         std::unique_ptr<StringSetting> stringValue = StringSetting::AllocUnique(6, C2ConstMemoryBlock<char>(initValue));
2365         stringValue = StringSetting::AllocUnique(6, initValue);
2366         static_assert(std::is_same<decltype(stringValue->m.value), char[]>::value, "should be char[]");
2367         EXPECT_EQ(0, memcmp(stringValue->m.value, "ABCD\0", 6));
2368         EXPECT_EQ(6u, stringValue->flexCount());
2369         std::vector<C2FieldDescriptor> fields = stringValue->FieldList();
2370         EXPECT_EQ(1u, fields.size());
2371         EXPECT_EQ(FD::STRING, fields.cbegin()->type());
2372         EXPECT_EQ(0u, fields.cbegin()->extent());
2373         EXPECT_EQ(C2String("value"), fields.cbegin()->name());
2374 
2375         stringValue = StringSetting::AllocUnique(3, C2ConstMemoryBlock<char>(initValue));
2376         EXPECT_EQ(0, memcmp(stringValue->m.value, "AB", 3));
2377         EXPECT_EQ(3u, stringValue->flexCount());
2378 
2379         stringValue = StringSetting::AllocUnique(11, "initValue");
2380         EXPECT_EQ(0, memcmp(stringValue->m.value, "initValue\0", 11));
2381         EXPECT_EQ(11u, stringValue->flexCount());
2382 
2383         stringValue = StringSetting::AllocUnique(initValue);
2384         EXPECT_EQ(0, memcmp(stringValue->m.value, "ABCD", 5));
2385         EXPECT_EQ(5u, stringValue->flexCount());
2386 
2387         stringValue = StringSetting::AllocUnique({ 'A', 'B', 'C', 'D' });
2388         EXPECT_EQ(0, memcmp(stringValue->m.value, "ABC", 4));
2389         EXPECT_EQ(4u, stringValue->flexCount());
2390     }
2391 
2392     {
2393         uint32_t videoWidth[] = { 12u, C2NumbersStreamTuning::output::PARAM_TYPE, 100 };
2394         C2Param *p1 = C2Param::From(videoWidth, sizeof(videoWidth));
2395         EXPECT_NE(nullptr, p1);
2396         EXPECT_EQ(12u, p1->size());
2397         EXPECT_EQ(p1->type(), C2NumbersStreamTuning::output::PARAM_TYPE);
2398 
2399         C2NumbersStreamTuning::output *vst = C2NumbersStreamTuning::output::From(p1);
2400         EXPECT_NE(nullptr, vst);
2401         if (vst) {
2402             EXPECT_EQ(1u, vst->flexCount());
2403             EXPECT_EQ(100, vst->m.mNumbers[0]);
2404         }
2405 
2406         p1 = C2Param::From(videoWidth, sizeof(videoWidth) + 2);
2407         EXPECT_EQ(nullptr, p1);
2408 
2409         p1 = C2Param::From(videoWidth, sizeof(videoWidth) - 2);
2410         EXPECT_EQ(nullptr, p1);
2411 
2412         p1 = C2Param::From(videoWidth, 3);
2413         EXPECT_EQ(nullptr, p1);
2414 
2415         p1 = C2Param::From(videoWidth, 0);
2416         EXPECT_EQ(nullptr, p1);
2417     }
2418 
2419     {
2420         uint32_t videoWidth[] = { 16u, C2NumbersPortTuning::input::PARAM_TYPE, 101, 102 };
2421 
2422         C2Param *p1 = C2Param::From(videoWidth, sizeof(videoWidth));
2423         EXPECT_NE(nullptr, p1);
2424         EXPECT_EQ(16u, p1->size());
2425         EXPECT_EQ(p1->type(), C2NumbersPortTuning::input::PARAM_TYPE);
2426 
2427         C2NumbersPortTuning::input *vpt = C2NumbersPortTuning::input::From(p1);
2428         EXPECT_NE(nullptr, vpt);
2429         if (vpt) {
2430             EXPECT_EQ(2u, vpt->flexCount());
2431             EXPECT_EQ(101, vpt->m.mNumbers[0]);
2432             EXPECT_EQ(102, vpt->m.mNumbers[1]);
2433         }
2434 
2435         p1 = C2Param::From(videoWidth, sizeof(videoWidth) + 2);
2436         EXPECT_EQ(nullptr, p1);
2437 
2438         p1 = C2Param::From(videoWidth, sizeof(videoWidth) - 2);
2439         EXPECT_EQ(nullptr, p1);
2440 
2441         p1 = C2Param::From(videoWidth, 3);
2442         EXPECT_EQ(nullptr, p1);
2443 
2444         p1 = C2Param::From(videoWidth, 0);
2445         EXPECT_EQ(nullptr, p1);
2446     }
2447 }
2448 
TEST_F(C2ParamTest,C2ValueTest)2449 TEST_F(C2ParamTest, C2ValueTest) {
2450     C2Value val;
2451     int32_t i32 = -32;
2452     int64_t i64 = -64;
2453     uint32_t u32 = 32;
2454     uint64_t u64 = 64;
2455     float fp = 1.5f;
2456 
2457     EXPECT_EQ(C2Value::NO_INIT, val.type());
2458     EXPECT_EQ(false, val.get(&i32));
2459     EXPECT_EQ(-32, i32);
2460     EXPECT_EQ(false, val.get(&i64));
2461     EXPECT_EQ(-64, i64);
2462     EXPECT_EQ(false, val.get(&u32));
2463     EXPECT_EQ(32u, u32);
2464     EXPECT_EQ(false, val.get(&u64));
2465     EXPECT_EQ(64u, u64);
2466     EXPECT_EQ(false, val.get(&fp));
2467     EXPECT_EQ(1.5f, fp);
2468 
2469     val = int32_t(-3216);
2470     EXPECT_EQ(C2Value::INT32, val.type());
2471     EXPECT_EQ(true, val.get(&i32));
2472     EXPECT_EQ(-3216, i32);
2473     EXPECT_EQ(false, val.get(&i64));
2474     EXPECT_EQ(-64, i64);
2475     EXPECT_EQ(false, val.get(&u32));
2476     EXPECT_EQ(32u, u32);
2477     EXPECT_EQ(false, val.get(&u64));
2478     EXPECT_EQ(64u, u64);
2479     EXPECT_EQ(false, val.get(&fp));
2480     EXPECT_EQ(1.5f, fp);
2481 
2482     val = uint32_t(3216);
2483     EXPECT_EQ(C2Value::UINT32, val.type());
2484     EXPECT_EQ(false, val.get(&i32));
2485     EXPECT_EQ(-3216, i32);
2486     EXPECT_EQ(false, val.get(&i64));
2487     EXPECT_EQ(-64, i64);
2488     EXPECT_EQ(true, val.get(&u32));
2489     EXPECT_EQ(3216u, u32);
2490     EXPECT_EQ(false, val.get(&u64));
2491     EXPECT_EQ(64u, u64);
2492     EXPECT_EQ(false, val.get(&fp));
2493     EXPECT_EQ(1.5f, fp);
2494 
2495     val = int64_t(-6432);
2496     EXPECT_EQ(C2Value::INT64, val.type());
2497     EXPECT_EQ(false, val.get(&i32));
2498     EXPECT_EQ(-3216, i32);
2499     EXPECT_EQ(true, val.get(&i64));
2500     EXPECT_EQ(-6432, i64);
2501     EXPECT_EQ(false, val.get(&u32));
2502     EXPECT_EQ(3216u, u32);
2503     EXPECT_EQ(false, val.get(&u64));
2504     EXPECT_EQ(64u, u64);
2505     EXPECT_EQ(false, val.get(&fp));
2506     EXPECT_EQ(1.5f, fp);
2507 
2508     val = uint64_t(6432);
2509     EXPECT_EQ(C2Value::UINT64, val.type());
2510     EXPECT_EQ(false, val.get(&i32));
2511     EXPECT_EQ(-3216, i32);
2512     EXPECT_EQ(false, val.get(&i64));
2513     EXPECT_EQ(-6432, i64);
2514     EXPECT_EQ(false, val.get(&u32));
2515     EXPECT_EQ(3216u, u32);
2516     EXPECT_EQ(true, val.get(&u64));
2517     EXPECT_EQ(6432u, u64);
2518     EXPECT_EQ(false, val.get(&fp));
2519     EXPECT_EQ(1.5f, fp);
2520 
2521     val = 15.25f;
2522     EXPECT_EQ(C2Value::FLOAT, val.type());
2523     EXPECT_EQ(false, val.get(&i32));
2524     EXPECT_EQ(-3216, i32);
2525     EXPECT_EQ(false, val.get(&i64));
2526     EXPECT_EQ(-6432, i64);
2527     EXPECT_EQ(false, val.get(&u32));
2528     EXPECT_EQ(3216u, u32);
2529     EXPECT_EQ(false, val.get(&u64));
2530     EXPECT_EQ(6432u, u64);
2531     EXPECT_EQ(true, val.get(&fp));
2532     EXPECT_EQ(15.25f, fp);
2533 }
2534 
2535