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