Home | History | Annotate | Download | only in tests
      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 
     27 void PrintTo(const _C2FieldId &id, ::std::ostream* os) {
     28     *os << "@" << id._mOffset << "+" << id._mSize;
     29 }
     30 
     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 
     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 
    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 
    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 
    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 
    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 
    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
    343     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
    353     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>>
    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 
    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 
    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[];
    414     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[];
    423     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>>
    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 
    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 
    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[];
    483     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[];
    492     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[];
    505     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[];
    518     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>>
    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 
    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>
    635     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>
    643     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>
    652     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>
    658     inline MP(T D::*, const D*) { }
    659 };
    660 
    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 
    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;
    717     C2NumberStruct() {}
    718     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;
    726     C2NumberBaseStruct() {}
    727     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[];
    735     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>
    832 bool canSetPort(T &o, bool output) { return o.setPort(output); }
    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) {
    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 
    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 
    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 
   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 
   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 
   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[];
   1706         _Flex() {}
   1707         FLEX(_Flex, b);
   1708     };
   1709 
   1710     struct _BoFlex {
   1711         _Flex a;
   1712         _BoFlex() {}
   1713         FLEX(_BoFlex, a);
   1714     };
   1715 
   1716     struct _NonFlex {
   1717     };
   1718 
   1719 
   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 
   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 
   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