14344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/* 24344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Copyright (C) 2016 The Android Open Source Project 34344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 44344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Licensed under the Apache License, Version 2.0 (the "License"); 54344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * you may not use this file except in compliance with the License. 64344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * You may obtain a copy of the License at 74344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 84344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * http://www.apache.org/licenses/LICENSE-2.0 94344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Unless required by applicable law or agreed to in writing, software 114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * distributed under the License is distributed on an "AS IS" BASIS, 124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * See the License for the specific language governing permissions and 144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * limitations under the License. 154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** \file 184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Templates used to declare parameters. 194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#ifndef C2PARAM_DEF_H_ 214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define C2PARAM_DEF_H_ 224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <type_traits> 244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2Param.h> 264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// \addtogroup Parameters 284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// @{ 294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/* ======================== UTILITY TEMPLATES FOR PARAMETER DEFINITIONS ======================== */ 314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// \addtogroup internal 334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// @{ 344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// Helper class that checks if a type has equality and inequality operators. 364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2_HIDE _C2Comparable_impl 374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim{ 384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename S, typename=decltype(S() == S())> 394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static std::true_type TestEqual(int); 404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename> 414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static std::false_type TestEqual(...); 424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename S, typename=decltype(S() != S())> 444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static std::true_type TestNotEqual(int); 454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename> 464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static std::false_type TestNotEqual(...); 474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Helper template that returns if a type has equality and inequality operators. 514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Use as _C2Comparable<typename S>::value. 534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename S> 554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2_HIDE _C2Comparable 564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : public std::integral_constant<bool, decltype(_C2Comparable_impl::TestEqual<S>(0))::value 574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim || decltype(_C2Comparable_impl::TestNotEqual<S>(0))::value> { 584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// Helper class that checks if a type has a CORE_INDEX constant. 614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2_HIDE _C2CoreIndexHelper_impl 624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim{ 634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename S, int=S::CORE_INDEX> 644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static std::true_type TestCoreIndex(int); 654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename> 664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static std::false_type TestCoreIndex(...); 674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 69587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar/// Macro that defines and thus overrides a type's CORE_INDEX for a setting 70587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar#define _C2_CORE_INDEX_OVERRIDE(coreIndex) \ 71587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnarpublic: \ 72587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar enum : uint32_t { CORE_INDEX = coreIndex }; 734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 75587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar/// Helper template that adds a CORE_INDEX to a type if it does not have one (for testing) 764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename S, int CoreIndex> 77587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnarstruct C2_HIDE _C2AddCoreIndex : public S { 78587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar _C2_CORE_INDEX_OVERRIDE(CoreIndex) 79587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar}; 804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \brief Helper class to check struct requirements for parameters. 834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Features: 854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * - verify default constructor, no virtual methods, and no equality operators. 864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * - expose PARAM_TYPE, and non-flex FLEX_SIZE. 874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename S, int CoreIndex, unsigned TypeFlags> 894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2_HIDE _C2StructCheck { 904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static_assert( 914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim std::is_default_constructible<S>::value, "C2 structure must have default constructor"); 924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static_assert(!std::is_polymorphic<S>::value, "C2 structure must not have virtual methods"); 934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static_assert(!_C2Comparable<S>::value, "C2 structure must not have operator== or !="); 944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic: 964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim enum : uint32_t { 974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim PARAM_TYPE = CoreIndex | TypeFlags 984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim }; 994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 1004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprotected: 1014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim enum : uint32_t { 10289f1966353272db3ba08eba936652e94dcab7289Lajos Molnar FLEX_SIZE = 0, 1034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim }; 1044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 1054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 1064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// Helper class that checks if a type has an integer FLEX_SIZE member. 1074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2_HIDE _C2Flexible_impl { 1084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// specialization for types that have a FLEX_SIZE member 1094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename S, unsigned=S::FLEX_SIZE> 1104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static std::true_type TestFlexSize(int); 1114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename> 1124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static std::false_type TestFlexSize(...); 1134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 1144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 1154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// Helper template that returns if a type has an integer FLEX_SIZE member. 1164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename S> 1174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2_HIDE _C2Flexible 1184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : public std::integral_constant<bool, decltype(_C2Flexible_impl::TestFlexSize<S>(0))::value> { 1194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 1204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 1214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// Macro to test if a type is flexible (has a FLEX_SIZE member). 1224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define IF_FLEXIBLE(S) ENABLE_IF(_C2Flexible<S>::value) 1234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// Shorthand for std::enable_if 1244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define ENABLE_IF(cond) typename std::enable_if<cond>::type 1254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 12689f1966353272db3ba08eba936652e94dcab7289Lajos Molnartemplate<typename T, typename V=void> 12789f1966353272db3ba08eba936652e94dcab7289Lajos Molnarstruct C2_HIDE _c2_enable_if_type { 12889f1966353272db3ba08eba936652e94dcab7289Lajos Molnar typedef V type; 12989f1966353272db3ba08eba936652e94dcab7289Lajos Molnar}; 13089f1966353272db3ba08eba936652e94dcab7289Lajos Molnar 1314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// Helper template that exposes the flexible subtype of a struct. 1324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename S, typename E=void> 1334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2_HIDE _C2FlexHelper { 1344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim typedef void FlexType; 1354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim enum : uint32_t { FLEX_SIZE = 0 }; 1364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 1374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 13889f1966353272db3ba08eba936652e94dcab7289Lajos Molnar/// Specialization for flexible types. This only works if _FlexMemberType is public. 1394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename S> 1404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2_HIDE _C2FlexHelper<S, 14189f1966353272db3ba08eba936652e94dcab7289Lajos Molnar typename _c2_enable_if_type<typename S::_FlexMemberType>::type> { 14289f1966353272db3ba08eba936652e94dcab7289Lajos Molnar typedef typename _C2FlexHelper<typename S::_FlexMemberType>::FlexType FlexType; 14389f1966353272db3ba08eba936652e94dcab7289Lajos Molnar enum : uint32_t { FLEX_SIZE = _C2FlexHelper<typename S::_FlexMemberType>::FLEX_SIZE }; 1444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 1454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 1464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// Specialization for flex arrays. 1474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename S> 1484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2_HIDE _C2FlexHelper<S[], 1494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim typename std::enable_if<std::is_void<typename _C2FlexHelper<S>::FlexType>::value>::type> { 1504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim typedef S FlexType; 1514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim enum : uint32_t { FLEX_SIZE = sizeof(S) }; 1524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 1534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 1544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 1554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \brief Helper class to check flexible struct requirements and add common operations. 1564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 1574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Features: 1581cbff72e1f2998f175fe23b79737e4cdb8ddd33aLajos Molnar * - expose CORE_INDEX and FieldList (this is normally inherited from the struct, but flexible 1594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * structs cannot be base classes and thus inherited from) 1604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * - disable copy assignment and construction (TODO: this is already done in the FLEX macro for the 1614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * flexible struct, so may not be needed here) 1624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 1634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename S, int ParamIndex, unsigned TypeFlags> 1644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2_HIDE _C2FlexStructCheck : 1654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// add flexible flag as _C2StructCheck defines PARAM_TYPE 1664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public _C2StructCheck<S, ParamIndex | C2Param::CoreIndex::IS_FLEX_FLAG, TypeFlags> { 1674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic: 1684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim enum : uint32_t { 1694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// \hideinitializer 1704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim CORE_INDEX = ParamIndex | C2Param::CoreIndex::IS_FLEX_FLAG, ///< flexible struct core-index 1714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim }; 1724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 1731cbff72e1f2998f175fe23b79737e4cdb8ddd33aLajos Molnar inline static const std::vector<C2FieldDescriptor> FieldList() { return S::FieldList(); } 1744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 1754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim // default constructor needed because of the disabled copy constructor 1764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline _C2FlexStructCheck() = default; 1774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 1784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprotected: 1794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim // cannot copy flexible params 1804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim _C2FlexStructCheck(const _C2FlexStructCheck<S, ParamIndex, TypeFlags> &) = delete; 1814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim _C2FlexStructCheck& operator= (const _C2FlexStructCheck<S, ParamIndex, TypeFlags> &) = delete; 1824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 1834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim // constants used for helper methods 1844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim enum : uint32_t { 1854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// \hideinitializer 1864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim FLEX_SIZE = _C2FlexHelper<S>::FLEX_SIZE, ///< size of flexible type 1874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// \hideinitializer 1884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim MAX_SIZE = (uint32_t)std::min((size_t)UINT32_MAX, SIZE_MAX), // TODO: is this always u32 max? 1894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// \hideinitializer 1904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim BASE_SIZE = sizeof(S) + sizeof(C2Param), ///< size of the base param 1914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim }; 1924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 1934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// returns the allocated size of this param with flexCount, or 0 if it would overflow. 1944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline static size_t CalcSize(size_t flexCount, size_t size = BASE_SIZE) { 1954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim if (flexCount <= (MAX_SIZE - size) / S::FLEX_SIZE) { 1964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim return size + S::FLEX_SIZE * flexCount; 1974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 1984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim return 0; 1994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 2004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 2014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// dynamic new operator usable for params of type S 2024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline void* operator new(size_t size, size_t flexCount) noexcept { 2034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim // TODO: assert(size == BASE_SIZE); 2044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim size = CalcSize(flexCount, size); 2054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim if (size > 0) { 2064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim return ::operator new(size); 2074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 2084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim return nullptr; 2094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 2104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 2114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 2124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// Define From() cast operators for params. 2134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define DEFINE_CAST_OPERATORS(_Type) \ 2144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline static _Type* From(C2Param *other) { \ 2154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim return (_Type*)C2Param::IfSuitable( \ 2164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim other, sizeof(_Type), _Type::PARAM_TYPE, _Type::FLEX_SIZE, \ 2174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim (_Type::PARAM_TYPE & T::Index::DIR_UNDEFINED) != T::Index::DIR_UNDEFINED); \ 2184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } \ 2194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline static const _Type* From(const C2Param *other) { \ 2204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim return const_cast<const _Type*>(From(const_cast<C2Param *>(other))); \ 2214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } \ 2224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline static _Type* From(std::nullptr_t) { return nullptr; } \ 2234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 2244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 2254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Define flexible allocators (AllocShared or AllocUnique) for flexible params. 22646b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar * - P::AllocXyz(flexCount, args...): allocate for given flex-count. This maps to 22746b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar * T(flexCount, args...)\ 22846b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar * 22946b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar * Clang does not support args... followed by templated param as args... eats it. Hence, 23046b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar * provide specializations where the initializer replaces the flexCount. 23146b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar * 23246b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar * Specializations that deduce flexCount: 23346b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar * - P::AllocXyz(T[], args...): allocate for size of (and with) init array. 23446b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar * - P::AllocXyz(std::initializer_list<T>, args...): allocate for size of (and with) initializer 23546b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar * list. 23646b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar * - P::AllocXyz(std::vector<T>, args...): allocate for size of (and with) init vector. 23746b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar * These specializations map to T(flexCount = size-of-init, args..., init) 2384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 2394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define DEFINE_FLEXIBLE_ALLOC(_Type, S, ptr, Ptr) \ 2404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> \ 2414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline static std::ptr##_ptr<_Type> Alloc##Ptr(size_t flexCount, const Args(&... args)) { \ 2424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim return std::ptr##_ptr<_Type>(new(flexCount) _Type(flexCount, args...)); \ 2434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } \ 24446b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar template<typename ...Args, typename U=typename S::FlexType> \ 24546b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar inline static std::ptr##_ptr<_Type> Alloc##Ptr( \ 24646b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar const std::initializer_list<U> &init, const Args(&... args)) { \ 24746b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar return std::ptr##_ptr<_Type>(new(init.size()) _Type(init.size(), args..., init)); \ 2484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } \ 2494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args, typename U=typename S::FlexType> \ 2504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline static std::ptr##_ptr<_Type> Alloc##Ptr( \ 25146b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar const std::vector<U> &init, const Args(&... args)) { \ 2524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim return std::ptr##_ptr<_Type>(new(init.size()) _Type(init.size(), args..., init)); \ 2534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } \ 25446b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar template<typename ...Args, typename U=typename S::FlexType, unsigned N> \ 25546b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar inline static std::ptr##_ptr<_Type> Alloc##Ptr(const U(&init)[N], const Args(&... args)) { \ 25646b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar return std::ptr##_ptr<_Type>(new(N) _Type(N, args..., init)); \ 25746b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar } \ 2584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 2594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 2604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Define flexible methods AllocShared, AllocUnique and flexCount. 2614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 2624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define DEFINE_FLEXIBLE_METHODS(_Type, S) \ 2634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_FLEXIBLE_ALLOC(_Type, S, shared, Shared) \ 2644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_FLEXIBLE_ALLOC(_Type, S, unique, Unique) \ 2654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline size_t flexCount() const { \ 2664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static_assert(sizeof(_Type) == _Type::BASE_SIZE, "incorrect BASE_SIZE"); \ 2674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim size_t sz = this->size(); \ 2684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim if (sz >= sizeof(_Type)) { \ 2694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim return (sz - sizeof(_Type)) / _Type::FLEX_SIZE; \ 2704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } \ 2714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim return 0; \ 2724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } \ 2734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 2744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// Mark flexible member variable and make structure flexible. 2754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define FLEX(cls, m) \ 2764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim C2_DO_NOT_COPY(cls) \ 2774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate: \ 2784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim C2PARAM_MAKE_FRIENDS \ 2794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /** \if 0 */ \ 2804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename, typename> friend struct _C2FlexHelper; \ 2814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic: \ 28289f1966353272db3ba08eba936652e94dcab7289Lajos Molnar typedef decltype(m) _FlexMemberType; \ 28389f1966353272db3ba08eba936652e94dcab7289Lajos Molnar /* default constructor with flexCount */ \ 28489f1966353272db3ba08eba936652e94dcab7289Lajos Molnar inline cls(size_t) : cls() {} \ 28589f1966353272db3ba08eba936652e94dcab7289Lajos Molnar /* constexpr static _FlexMemberType cls::* flexMember = &cls::m; */ \ 28689f1966353272db3ba08eba936652e94dcab7289Lajos Molnar typedef typename _C2FlexHelper<_FlexMemberType>::FlexType FlexType; \ 2874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static_assert(\ 2884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim !std::is_void<FlexType>::value, \ 2894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim "member is not flexible, or a flexible array of a flexible type"); \ 29089f1966353272db3ba08eba936652e94dcab7289Lajos Molnar enum : uint32_t { FLEX_SIZE = _C2FlexHelper<_FlexMemberType>::FLEX_SIZE }; \ 2914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /** \endif */ \ 2924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 2934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// @} 2944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 2954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 2964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Global-parameter template. 2974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 2984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Base template to define a global setting/tuning or info based on a structure and 2994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * an optional ParamIndex. Global parameters are not tied to a port (input or output). 3004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 3014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Parameters wrap structures by prepending a (parameter) header. The fields of the wrapped 3024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * structure can be accessed directly, and constructors and potential public methods are also 3034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * wrapped. 3044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 3054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam T param type C2Setting, C2Tuning or C2Info 3064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam S wrapped structure 3074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam ParamIndex optional parameter index override. Must be specified for base/reused 3084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * structures. 3094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 3104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T, typename S, int ParamIndex=S::CORE_INDEX, class Flex=void> 311587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnarstruct C2_HIDE C2GlobalParam : public T, public S, 3124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public _C2StructCheck<S, ParamIndex, T::PARAM_KIND | T::Type::DIR_GLOBAL> { 313587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar _C2_CORE_INDEX_OVERRIDE(ParamIndex) 3144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate: 3154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim typedef C2GlobalParam<T, S, ParamIndex> _Type; 3164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 3174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic: 3184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor. 3194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 3204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2GlobalParam(const Args(&... args)) : T(sizeof(_Type), _Type::PARAM_TYPE), S(args...) { } 3214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 3224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(_Type) 3234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 3244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 3254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 3264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Global-parameter template for flexible structures. 3274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 3284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Base template to define a global setting/tuning or info based on a flexible structure and 3294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * an optional ParamIndex. Global parameters are not tied to a port (input or output). 3304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 3314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam T param type C2Setting, C2Tuning or C2Info 3324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam S wrapped flexible structure 3334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam ParamIndex optional parameter index override. Must be specified for base/reused 3344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * structures. 3354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 3364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Parameters wrap structures by prepending a (parameter) header. The fields and methods of flexible 3374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * structures can be accessed via the m member variable; however, the constructors of the structure 3384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * are wrapped directly. (This is because flexible types cannot be subclassed.) 3394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 3404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T, typename S, int ParamIndex> 3414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2_HIDE C2GlobalParam<T, S, ParamIndex, IF_FLEXIBLE(S)> 3424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : public T, public _C2FlexStructCheck<S, ParamIndex, T::PARAM_KIND | T::Type::DIR_GLOBAL> { 3434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate: 3444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim typedef C2GlobalParam<T, S, ParamIndex> _Type; 3454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 3464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor. 3474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 3484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2GlobalParam(size_t flexCount, const Args(&... args)) 3494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : T(_Type::CalcSize(flexCount), _Type::PARAM_TYPE), m(flexCount, args...) { } 3504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 3514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic: 3524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim S m; ///< wrapped flexible structure 3534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 3544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_FLEXIBLE_METHODS(_Type, S) 3554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(_Type) 3564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 3574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 3584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 3594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Port-parameter template. 3604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 3614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Base template to define a port setting/tuning or info based on a structure and 3624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * an optional ParamIndex. Port parameters are tied to a port (input or output), but not to a 3634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * specific stream. 3644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 3654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam T param type C2Setting, C2Tuning or C2Info 3664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam S wrapped structure 3674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam ParamIndex optional parameter index override. Must be specified for base/reused 3684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * structures. 3694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 3704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Parameters wrap structures by prepending a (parameter) header. The fields of the wrapped 3714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * structure can be accessed directly, and constructors and potential public methods are also 3724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * wrapped. 3734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 3744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * There are 3 flavors of port parameters: unspecified, input and output. Parameters with 3754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * unspecified port expose a setPort method, and add an initial port parameter to the constructor. 3764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 3774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T, typename S, int ParamIndex=S::CORE_INDEX, class Flex=void> 378587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnarstruct C2_HIDE C2PortParam : public T, public S, 3794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim private _C2StructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_UNDEFINED> { 380587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar _C2_CORE_INDEX_OVERRIDE(ParamIndex) 3814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate: 3824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim typedef C2PortParam<T, S, ParamIndex> _Type; 3834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 3844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic: 3854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Default constructor. 3864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2PortParam() : T(sizeof(_Type), _Type::PARAM_TYPE) { } 3874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 3884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor while specifying port/direction. 3894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2PortParam(bool _output, const Args(&... args)) 3904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : T(sizeof(_Type), _output ? output::PARAM_TYPE : input::PARAM_TYPE), S(args...) { } 3914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Set port/direction. 3924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline void setPort(bool output) { C2Param::setPort(output); } 3934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 3944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(_Type) 3954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 3964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Specialization for an input port parameter. 397587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar struct input : public T, public S, 3984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public _C2StructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_INPUT> { 399587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar _C2_CORE_INDEX_OVERRIDE(ParamIndex) 4004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor. 4014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 4024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline input(const Args(&... args)) : T(sizeof(_Type), input::PARAM_TYPE), S(args...) { } 4034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(input) 4054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim }; 4074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Specialization for an output port parameter. 409587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar struct output : public T, public S, 4104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public _C2StructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_OUTPUT> { 411587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar _C2_CORE_INDEX_OVERRIDE(ParamIndex) 4124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor. 4134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 4144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline output(const Args(&... args)) : T(sizeof(_Type), output::PARAM_TYPE), S(args...) { } 4154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(output) 4174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim }; 4184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 4194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 4214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Port-parameter template for flexible structures. 4224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 4234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Base template to define a port setting/tuning or info based on a flexible structure and 4244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * an optional ParamIndex. Port parameters are tied to a port (input or output), but not to a 4254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * specific stream. 4264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 4274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam T param type C2Setting, C2Tuning or C2Info 4284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam S wrapped flexible structure 4294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam ParamIndex optional parameter index override. Must be specified for base/reused 4304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * structures. 4314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 4324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Parameters wrap structures by prepending a (parameter) header. The fields and methods of flexible 4334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * structures can be accessed via the m member variable; however, the constructors of the structure 4344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * are wrapped directly. (This is because flexible types cannot be subclassed.) 4354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 4364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * There are 3 flavors of port parameters: unspecified, input and output. Parameters with 4374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * unspecified port expose a setPort method, and add an initial port parameter to the constructor. 4384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 4394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T, typename S, int ParamIndex> 4404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2_HIDE C2PortParam<T, S, ParamIndex, IF_FLEXIBLE(S)> 4414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : public T, public _C2FlexStructCheck<S, ParamIndex, T::PARAM_KIND | T::Type::DIR_UNDEFINED> { 4424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate: 4434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim typedef C2PortParam<T, S, ParamIndex> _Type; 4444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Default constructor for basic allocation: new(flexCount) P. 4464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2PortParam(size_t flexCount) : T(_Type::CalcSize(flexCount), _Type::PARAM_TYPE) { } 4474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 4484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor while also specifying port/direction. 4494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2PortParam(size_t flexCount, bool _output, const Args(&... args)) 4504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : T(_Type::CalcSize(flexCount), _output ? output::PARAM_TYPE : input::PARAM_TYPE), 4514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim m(flexCount, args...) { } 4524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic: 4544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Set port/direction. 4554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline void setPort(bool output) { C2Param::setPort(output); } 4564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim S m; ///< wrapped flexible structure 4584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_FLEXIBLE_METHODS(_Type, S) 4604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(_Type) 4614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Specialization for an input port parameter. 4634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim struct input : public T, 4644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public _C2FlexStructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_INPUT> { 4654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim private: 4664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor while also specifying port/direction. 4674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 4684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline input(size_t flexCount, const Args(&... args)) 4694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : T(_Type::CalcSize(flexCount), input::PARAM_TYPE), m(flexCount, args...) { } 4704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public: 4724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim S m; ///< wrapped flexible structure 4734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_FLEXIBLE_METHODS(input, S) 4754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(input) 4764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim }; 4774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Specialization for an output port parameter. 4794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim struct output : public T, 4804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public _C2FlexStructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_OUTPUT> { 4814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim private: 4824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor while also specifying port/direction. 4834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 4844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline output(size_t flexCount, const Args(&... args)) 4854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : T(_Type::CalcSize(flexCount), output::PARAM_TYPE), m(flexCount, args...) { } 4864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public: 4884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim S m; ///< wrapped flexible structure 4894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_FLEXIBLE_METHODS(output, S) 4914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(output) 4924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim }; 4934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 4944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 4954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 4964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Stream-parameter template. 4974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 4984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Base template to define a stream setting/tuning or info based on a structure and 4994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * an optional ParamIndex. Stream parameters are tied to a specific stream on a port (input or 5004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * output). 5014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 5024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam T param type C2Setting, C2Tuning or C2Info 5034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam S wrapped structure 5044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam ParamIndex optional paramter index override. Must be specified for base/reused 5054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * structures. 5064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 5074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Parameters wrap structures by prepending a (parameter) header. The fields of the wrapped 5084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * structure can be accessed directly, and constructors and potential public methods are also 5094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * wrapped. 5104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 5114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * There are 3 flavors of stream parameters: unspecified port, input and output. All of these expose 5124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * a setStream method and an extra initial streamID parameter for the constructor. Moreover, 5134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * parameters with unspecified port expose a setPort method, and add an additional initial port 5144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * parameter to the constructor. 5154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 5164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T, typename S, int ParamIndex=S::CORE_INDEX, class Flex=void> 517587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnarstruct C2_HIDE C2StreamParam : public T, public S, 5184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim private _C2StructCheck<S, ParamIndex, 5194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Index::DIR_UNDEFINED> { 520587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar _C2_CORE_INDEX_OVERRIDE(ParamIndex) 5214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate: 5224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim typedef C2StreamParam<T, S, ParamIndex> _Type; 5234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 5244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic: 5254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Default constructor. Port/direction and stream-ID is undefined. 5264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2StreamParam() : T(sizeof(_Type), _Type::PARAM_TYPE) { } 5274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor while also specifying port/direction and 5284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// stream-ID. 5294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 5304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2StreamParam(bool _output, unsigned stream, const Args(&... args)) 5314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : T(sizeof(_Type), _output ? output::PARAM_TYPE : input::PARAM_TYPE, stream), 5324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim S(args...) { } 5334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Set port/direction. 5344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline void setPort(bool output) { C2Param::setPort(output); } 5354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Set stream-id. \retval true if the stream-id was successfully set. 5364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline bool setStream(unsigned stream) { return C2Param::setStream(stream); } 5374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 5384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(_Type) 5394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 5404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Specialization for an input stream parameter. 541587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar struct input : public T, public S, 5424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public _C2StructCheck<S, ParamIndex, 5434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Type::DIR_INPUT> { 544587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar _C2_CORE_INDEX_OVERRIDE(ParamIndex) 545587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar 5464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Default constructor. Stream-ID is undefined. 5474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline input() : T(sizeof(_Type), input::PARAM_TYPE) { } 5484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor while also specifying stream-ID. 5494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 5504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline input(unsigned stream, const Args(&... args)) 5514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : T(sizeof(_Type), input::PARAM_TYPE, stream), S(args...) { } 5524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Set stream-id. \retval true if the stream-id was successfully set. 5534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline bool setStream(unsigned stream) { return C2Param::setStream(stream); } 5544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 5554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(input) 5564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim }; 5574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 5584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Specialization for an output stream parameter. 559587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar struct output : public T, public S, 5604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public _C2StructCheck<S, ParamIndex, 5614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Type::DIR_OUTPUT> { 562587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar _C2_CORE_INDEX_OVERRIDE(ParamIndex) 563587c47f10c14b7d24efdf9f36bebc1d62c24bd49Lajos Molnar 5644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Default constructor. Stream-ID is undefined. 5654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline output() : T(sizeof(_Type), output::PARAM_TYPE) { } 5664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor while also specifying stream-ID. 5674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 5684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline output(unsigned stream, const Args(&... args)) 5694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : T(sizeof(_Type), output::PARAM_TYPE, stream), S(args...) { } 5704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Set stream-id. \retval true if the stream-id was successfully set. 5714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline bool setStream(unsigned stream) { return C2Param::setStream(stream); } 5724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 5734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(output) 5744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim }; 5754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 5764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 5774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 5784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Stream-parameter template for flexible structures. 5794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 5804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Base template to define a stream setting/tuning or info based on a flexible structure and 5814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * an optional ParamIndex. Stream parameters are tied to a specific stream on a port (input or 5824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * output). 5834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 5844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam T param type C2Setting, C2Tuning or C2Info 5854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam S wrapped flexible structure 5864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \tparam ParamIndex optional parameter index override. Must be specified for base/reused 5874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * structures. 5884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 5894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Parameters wrap structures by prepending a (parameter) header. The fields and methods of flexible 5904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * structures can be accessed via the m member variable; however, the constructors of the structure 5914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * are wrapped directly. (This is because flexible types cannot be subclassed.) 5924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 5934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * There are 3 flavors of stream parameters: unspecified port, input and output. All of these expose 5944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * a setStream method and an extra initial streamID parameter for the constructor. Moreover, 5954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * parameters with unspecified port expose a setPort method, and add an additional initial port 5964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * parameter to the constructor. 5974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 5984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T, typename S, int ParamIndex> 5994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2_HIDE C2StreamParam<T, S, ParamIndex, IF_FLEXIBLE(S)> 6004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : public T, 6014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public _C2FlexStructCheck<S, ParamIndex, 6024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Index::DIR_UNDEFINED> { 6034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate: 6044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim typedef C2StreamParam<T, S, ParamIndex> _Type; 6054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Default constructor. Port/direction and stream-ID is undefined. 6064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2StreamParam(size_t flexCount) : T(_Type::CalcSize(flexCount), _Type::PARAM_TYPE, 0u) { } 6074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor while also specifying port/direction and 6084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// stream-ID. 6094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 6104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2StreamParam(size_t flexCount, bool _output, unsigned stream, const Args(&... args)) 6114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : T(_Type::CalcSize(flexCount), _output ? output::PARAM_TYPE : input::PARAM_TYPE, stream), 6124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim m(flexCount, args...) { } 6134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic: 6154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim S m; ///< wrapped flexible structure 6164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Set port/direction. 6184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline void setPort(bool output) { C2Param::setPort(output); } 6194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Set stream-id. \retval true if the stream-id was successfully set. 6204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline bool setStream(unsigned stream) { return C2Param::setStream(stream); } 6214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_FLEXIBLE_METHODS(_Type, S) 6234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(_Type) 6244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Specialization for an input stream parameter. 6264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim struct input : public T, 6274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public _C2FlexStructCheck<S, ParamIndex, 6284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Type::DIR_INPUT> { 6294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim private: 6304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Default constructor. Stream-ID is undefined. 6314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline input(size_t flexCount) : T(_Type::CalcSize(flexCount), input::PARAM_TYPE) { } 6324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor while also specifying stream-ID. 6334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 6344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline input(size_t flexCount, unsigned stream, const Args(&... args)) 6354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : T(_Type::CalcSize(flexCount), input::PARAM_TYPE, stream), m(flexCount, args...) { } 6364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public: 6384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim S m; ///< wrapped flexible structure 6394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Set stream-id. \retval true if the stream-id was successfully set. 6414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline bool setStream(unsigned stream) { return C2Param::setStream(stream); } 6424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_FLEXIBLE_METHODS(input, S) 6444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(input) 6454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim }; 6464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Specialization for an output stream parameter. 6484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim struct output : public T, 6494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public _C2FlexStructCheck<S, ParamIndex, 6504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Type::DIR_OUTPUT> { 6514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim private: 6524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Default constructor. Stream-ID is undefined. 6534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline output(size_t flexCount) : T(_Type::CalcSize(flexCount), output::PARAM_TYPE) { } 6544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Wrapper around base structure's constructor while also specifying stream-ID. 6554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename ...Args> 6564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline output(size_t flexCount, unsigned stream, const Args(&... args)) 6574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim : T(_Type::CalcSize(flexCount), output::PARAM_TYPE, stream), m(flexCount, args...) { } 6584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim public: 6604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim S m; ///< wrapped flexible structure 6614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Set stream-id. \retval true if the stream-id was successfully set. 6634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline bool setStream(unsigned stream) { return C2Param::setStream(stream); } 6644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_FLEXIBLE_METHODS(output, S) 6664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_CAST_OPERATORS(output) 6674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim }; 6684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 6694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/* ======================== SIMPLE VALUE PARAMETERS ======================== */ 6714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 6734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \ingroup internal 6744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * A structure template encapsulating a single element with default constructors and no core-index. 6754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 6764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T> 6774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2SimpleValueStruct { 6784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim T value; ///< simple value of the structure 6794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim // Default constructor. 6804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2SimpleValueStruct() = default; 6814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim // Constructor with an initial value. 6824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2SimpleValueStruct(T value) : value(value) {} 6834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_BASE_C2STRUCT(SimpleValue) 6844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 6854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 6864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// TODO: move this and next to some generic place 6874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 6884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Interface to a block of (mapped) memory containing an array of some type (T). 6894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 6904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T> 6914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2MemoryBlock { 6924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// \returns the number of elements in this block. 6934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim virtual size_t size() const = 0; 6944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// \returns a const pointer to the start of this block. Care must be taken to not read outside 6954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// the block. 6964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim virtual const T *data() const = 0; // TODO: should this be friend access only in some C2Memory module? 6974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// \returns a pointer to the start of this block. Care must be taken to not read or write 6984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// outside the block. 6995d68ad843c75e22a6163a9fe4941e8e861a1016eLajos Molnar inline T *data() { return const_cast<T*>(const_cast<const C2MemoryBlock*>(this)->data()); } 7005d68ad843c75e22a6163a9fe4941e8e861a1016eLajos Molnar 7014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprotected: 7024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim // TODO: for now it should never be deleted as C2MemoryBlock 7034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim virtual ~C2MemoryBlock() = default; 7044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 7054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 7064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 7074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Interface to a block of memory containing a constant (constexpr) array of some type (T). 7084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 7094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T> 7104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2ConstMemoryBlock : public C2MemoryBlock<T> { 7114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim virtual const T * data() const { return _mData; } 7124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim virtual size_t size() const { return _mSize; } 7134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 7144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Constructor. 7154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<unsigned N> 7164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline constexpr C2ConstMemoryBlock(const T(&init)[N]) : _mData(init), _mSize(N) {} 7174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 7184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate: 7194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim const T *_mData; 7204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim const size_t _mSize; 7214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 7224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 7234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// \addtogroup internal 7244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// @{ 7254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 7264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// Helper class to initialize flexible arrays with various initalizers. 7274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct _C2ValueArrayHelper { 7284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim // char[]-s are used as null terminated strings, so the last element is never inited. 7294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 7304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Initialize a flexible array using a constexpr memory block. 7314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename T> 7324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static void init(T(&array)[], size_t arrayLen, const C2MemoryBlock<T> &block) { 7334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim // reserve last element for terminal 0 for strings 7344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim if (arrayLen && std::is_same<T, char>::value) { 7354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim --arrayLen; 7364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 7374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim if (block.data()) { 7384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim memcpy(array, block.data(), std::min(arrayLen, block.size()) * sizeof(T)); 7394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 7404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 7414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 7424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Initialize a flexible array using an initializer list. 7434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename T> 7444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static void init(T(&array)[], size_t arrayLen, const std::initializer_list<T> &init) { 7454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim size_t ix = 0; 7464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim // reserve last element for terminal 0 for strings 7474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim if (arrayLen && std::is_same<T, char>::value) { 7484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim --arrayLen; 7494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 7504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim for (const T &item : init) { 7514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim if (ix == arrayLen) { 7524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim break; 7534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 7544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim array[ix++] = item; 7554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 7564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 7574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 7588849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar /// Initialize a flexible array using a vector. 7598849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar template<typename T> 7608849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar static void init(T(&array)[], size_t arrayLen, const std::vector<T> &init) { 7618849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar size_t ix = 0; 7628849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar // reserve last element for terminal 0 for strings 7638849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar if (arrayLen && std::is_same<T, char>::value) { 7648849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar --arrayLen; 7658849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar } 7668849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar for (const T &item : init) { 7678849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar if (ix == arrayLen) { 7688849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar break; 7698849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar } 7708849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar array[ix++] = item; 7718849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar } 7728849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar } 7738849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar 7744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Initialize a flexible array using another flexible array. 7754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<typename T, unsigned N> 7764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static void init(T(&array)[], size_t arrayLen, const T(&str)[N]) { 7774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim // reserve last element for terminal 0 for strings 7784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim if (arrayLen && std::is_same<T, char>::value) { 7794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim --arrayLen; 7804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 7814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim if (arrayLen) { 78246b790622fc4e1d90966f41f5e7f5ee3a3b1ca0aLajos Molnar memcpy(array, str, std::min(arrayLen, (size_t)N) * sizeof(T)); 7834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 7844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 7854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 7864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 7874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 7884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Specialization for a flexible blob and string arrays. A structure template encapsulating a single 7894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * flexible array member with default flexible constructors and no core-index. This type cannot be 7904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * constructed on its own as it's size is 0. 7914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 7924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \internal This is different from C2SimpleArrayStruct<T[]> simply because its member has the name 7934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * as value to reflect this is a single value. 7944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 7954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T> 7964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2SimpleValueStruct<T[]> { 7974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static_assert(std::is_same<T, char>::value || std::is_same<T, uint8_t>::value, 7984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim "C2SimpleValueStruct<T[]> is only for BLOB or STRING"); 7994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim T value[]; 8004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 8014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2SimpleValueStruct() = default; 8024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_BASE_C2STRUCT(SimpleValue) 8034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim FLEX(C2SimpleValueStruct, value) 8044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 8054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate: 8064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2SimpleValueStruct(size_t flexCount, const C2MemoryBlock<T> &block) { 8074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim _C2ValueArrayHelper::init(value, flexCount, block); 8084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 8094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 8104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2SimpleValueStruct(size_t flexCount, const std::initializer_list<T> &init) { 8114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim _C2ValueArrayHelper::init(value, flexCount, init); 8124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 8134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 8148849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar inline C2SimpleValueStruct(size_t flexCount, const std::vector<T> &init) { 8158849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar _C2ValueArrayHelper::init(value, flexCount, init); 8168849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar } 8178849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar 8184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<unsigned N> 8194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2SimpleValueStruct(size_t flexCount, const T(&init)[N]) { 8204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim _C2ValueArrayHelper::init(value, flexCount, init); 8214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 8224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 8234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 8244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// @} 8254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 8264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 8274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * A structure template encapsulating a single flexible array element of a specific type (T) with 8284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * default constructors and no core-index. This type cannot be constructed on its own as it's size 8294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * is 0. Instead, it is meant to be used as a parameter, e.g. 8304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 8314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * typedef C2StreamParam<C2Info, C2SimpleArrayStruct<C2MyFancyStruct>, 8324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * kParamIndexMyFancyArrayStreamParam> C2MyFancyArrayStreamInfo; 8334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 8344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T> 8354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct C2SimpleArrayStruct { 8364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim static_assert(!std::is_same<T, char>::value && !std::is_same<T, uint8_t>::value, 8374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim "use C2SimpleValueStruct<T[]> is for BLOB or STRING"); 8384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 8394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim T values[]; ///< array member 8404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Default constructor 8414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2SimpleArrayStruct() = default; 8424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim DEFINE_BASE_FLEX_C2STRUCT(SimpleArray, values) 8434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim //FLEX(C2SimpleArrayStruct, values) 8444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 8454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate: 8464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Construct from a C2MemoryBlock. 8474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Used only by the flexible parameter allocators (AllocUnique & AllocShared). 8484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2SimpleArrayStruct(size_t flexCount, const C2MemoryBlock<T> &block) { 8494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim _C2ValueArrayHelper::init(values, flexCount, block); 8504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 8514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 8524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Construct from an initializer list. 8534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Used only by the flexible parameter allocators (AllocUnique & AllocShared). 8544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2SimpleArrayStruct(size_t flexCount, const std::initializer_list<T> &init) { 8554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim _C2ValueArrayHelper::init(values, flexCount, init); 8564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 8574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 8588849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar /// Construct from an vector. 8598849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar /// Used only by the flexible parameter allocators (AllocUnique & AllocShared). 8608849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar inline C2SimpleArrayStruct(size_t flexCount, const std::vector<T> &init) { 8618849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar _C2ValueArrayHelper::init(values, flexCount, init); 8628849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar } 8638849f0398e866ce2af9b71be11023f85b2c6d0a2Lajos Molnar 8644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Construct from another flexible array. 8654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim /// Used only by the flexible parameter allocators (AllocUnique & AllocShared). 8664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim template<unsigned N> 8674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim inline C2SimpleArrayStruct(size_t flexCount, const T(&init)[N]) { 8684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim _C2ValueArrayHelper::init(values, flexCount, init); 8694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim } 8704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}; 8714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 8724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/** 8734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \addtogroup simplevalue Simple value and array structures. 8744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * @{ 8754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 8764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Simple value structures. 8774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 8784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Structures containing a single simple value. These can be reused to easily define simple 8794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * parameters of various types: 8804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 8814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * typedef C2PortParam<C2Tuning, C2Int32Value, kParamIndexMyIntegerPortParam> 8824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * C2MyIntegerPortParamTuning; 8834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * 8844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * They contain a single member (value or values) that is described as "value" or "values". 8855528a2a16628fec50ebb1f42b5fecf4589aa5233Lajos Molnar * 8865528a2a16628fec50ebb1f42b5fecf4589aa5233Lajos Molnar * These structures don't define a core index, and as such, they cannot be used in structure 8875528a2a16628fec50ebb1f42b5fecf4589aa5233Lajos Molnar * declarations. Use type[] instead, such as int32_t field[]. 8884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */ 8894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// A 32-bit signed integer parameter in value, described as "value" 8904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtypedef C2SimpleValueStruct<int32_t> C2Int32Value; 8914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// A 32-bit signed integer array parameter in values, described as "values" 8924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtypedef C2SimpleArrayStruct<int32_t> C2Int32Array; 8934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// A 32-bit unsigned integer parameter in value, described as "value" 8944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtypedef C2SimpleValueStruct<uint32_t> C2Uint32Value; 8954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// A 32-bit unsigned integer array parameter in values, described as "values" 8964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtypedef C2SimpleArrayStruct<uint32_t> C2Uint32Array; 8974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// A 64-bit signed integer parameter in value, described as "value" 8984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtypedef C2SimpleValueStruct<int64_t> C2Int64Value; 8994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// A 64-bit signed integer array parameter in values, described as "values" 9004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtypedef C2SimpleArrayStruct<int64_t> C2Int64Array; 9014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// A 64-bit unsigned integer parameter in value, described as "value" 9024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtypedef C2SimpleValueStruct<uint64_t> C2Uint64Value; 9034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// A 64-bit unsigned integer array parameter in values, described as "values" 9044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtypedef C2SimpleArrayStruct<uint64_t> C2Uint64Array; 9054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// A float parameter in value, described as "value" 9064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtypedef C2SimpleValueStruct<float> C2FloatValue; 9074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// A float array parameter in values, described as "values" 9084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtypedef C2SimpleArrayStruct<float> C2FloatArray; 9094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// A blob flexible parameter in value, described as "value" 9104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtypedef C2SimpleValueStruct<uint8_t[]> C2BlobValue; 9114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// A string flexible parameter in value, described as "value" 9124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtypedef C2SimpleValueStruct<char[]> C2StringValue; 9134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 9144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T> 9151cbff72e1f2998f175fe23b79737e4cdb8ddd33aLajos Molnarconst std::vector<C2FieldDescriptor> C2SimpleValueStruct<T>::FieldList() { 9161cbff72e1f2998f175fe23b79737e4cdb8ddd33aLajos Molnar return { DESCRIBE_C2FIELD(value, "value") }; 9171cbff72e1f2998f175fe23b79737e4cdb8ddd33aLajos Molnar} 9184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T> 9191cbff72e1f2998f175fe23b79737e4cdb8ddd33aLajos Molnarconst std::vector<C2FieldDescriptor> C2SimpleValueStruct<T[]>::FieldList() { 9201cbff72e1f2998f175fe23b79737e4cdb8ddd33aLajos Molnar return { DESCRIBE_C2FIELD(value, "value") }; 9211cbff72e1f2998f175fe23b79737e4cdb8ddd33aLajos Molnar} 9224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimtemplate<typename T> 9231cbff72e1f2998f175fe23b79737e4cdb8ddd33aLajos Molnarconst std::vector<C2FieldDescriptor> C2SimpleArrayStruct<T>::FieldList() { 9241cbff72e1f2998f175fe23b79737e4cdb8ddd33aLajos Molnar return { DESCRIBE_C2FIELD(values, "values") }; 9251cbff72e1f2998f175fe23b79737e4cdb8ddd33aLajos Molnar} 9264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 9274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// @} 9284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 9294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/// @} 9304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim 9314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#endif // C2PARAM_DEF_H_ 932