1 /* 2 * Copyright (C) 2018 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 #ifndef C2UTILS_INTERFACE_HELPER_H_ 18 #define C2UTILS_INTERFACE_HELPER_H_ 19 20 #include <C2Component.h> 21 #include <util/C2InterfaceUtils.h> 22 23 #include <map> 24 #include <vector> 25 26 #include <stddef.h> 27 28 /** 29 * Interface Helper 30 */ 31 using C2R = C2SettingResultsBuilder; 32 33 template<typename T, bool E=std::is_enum<T>::value> 34 struct _c2_reduce_enum_to_underlying_type { 35 typedef T type; 36 }; 37 38 template<typename T> 39 struct _c2_reduce_enum_to_underlying_type<T, true> { 40 typedef typename std::underlying_type<T>::type type; 41 }; 42 43 /** 44 * Helper class to implement parameter reflectors. This class is dynamic and is designed to be 45 * shared by multiple interfaces. This allows interfaces to add structure descriptors as needed. 46 */ 47 class C2ReflectorHelper : public C2ParamReflector { 48 public: 49 C2ReflectorHelper() = default; 50 virtual ~C2ReflectorHelper() = default; 51 virtual std::unique_ptr<C2StructDescriptor> describe( 52 C2Param::CoreIndex paramIndex) const override; 53 54 /** 55 * Adds support for describing the given parameters. 56 * 57 * \param Params types of codec 2.0 structs (or parameters) to describe 58 */ 59 template<typename... Params> 60 C2_INLINE void addStructDescriptors() { 61 std::vector<C2StructDescriptor> structs; 62 addStructDescriptors(structs, (_Tuple<Params...> *)nullptr); 63 } 64 65 /** 66 * Adds support for describing a specific struct. 67 * 68 * \param strukt descriptor for the struct that will be moved out. 69 */ 70 void addStructDescriptor(C2StructDescriptor &&strukt); 71 72 private: 73 template<typename... Params> 74 class C2_HIDE _Tuple { }; 75 76 /** 77 * Adds support for describing the given descriptors. 78 * 79 * \param structs List of structure descriptors to add support for 80 */ 81 void addStructDescriptors( 82 std::vector<C2StructDescriptor> &structs, _Tuple<> *); 83 84 /** 85 * Utility method that adds support for describing the given descriptors in a recursive manner 86 * one structure at a time using a list of structure descriptors temporary. 87 * 88 * \param T the type of codec 2.0 struct to describe 89 * \param Params rest of the structs 90 * \param structs Temporary list of structure descriptors used to optimize the operation. 91 */ 92 template<typename T, typename... Params> 93 C2_INLINE void addStructDescriptors( 94 std::vector<C2StructDescriptor> &structs, _Tuple<T, Params...> *) { 95 structs.emplace_back((T*)nullptr); 96 addStructDescriptors(structs, (_Tuple<Params...> *)nullptr); 97 } 98 99 mutable std::mutex _mMutex; 100 std::map<C2Param::CoreIndex, const C2StructDescriptor> _mStructs; ///< descriptors 101 }; 102 103 /** 104 * Utility class that implements the codec 2.0 interface API-s for some parameters. 105 * 106 * This class must be subclassed. 107 */ 108 class C2InterfaceHelper { 109 public: 110 /** 111 * Returns the base offset of a field at |offset| that could be part of an array or part of a 112 * sub-structure. 113 * 114 * This method does not do field size verification, e.g. if offset if obtained from a structure, 115 * it will not stop at the structure boundary - this is okay, as we just want the base offset 116 * here, which is the same. 117 */ 118 static 119 size_t GetBaseOffset(const std::shared_ptr<C2ParamReflector> &reflector, 120 C2Param::CoreIndex index, size_t offset); 121 122 /** 123 * The interface helper class uses references to std::shared_ptr<T> config parameters. 124 * Internally, these need to be generalized to std::shared_ptr<C2Param> refs, but the cast is 125 * not allowed (as these are references). As such, this class never returns pointer to the 126 * shared_ptrs. 127 */ 128 struct ParamRef { 129 template<typename T, typename enable= 130 typename std::enable_if<std::is_convertible<T, C2Param>::value>::type> 131 inline C2_HIDE ParamRef(std::shared_ptr<T> ¶m) 132 : _mRef(reinterpret_cast<std::shared_ptr<C2Param>*>(¶m)) { } 133 134 // used by comparison operator for containers 135 operator std::shared_ptr<C2Param> *() const { return _mRef; } 136 137 /** 138 * Returns a shared pointer to the parameter. 139 */ 140 std::shared_ptr<C2Param> get() const { return *_mRef; } 141 142 private: 143 std::shared_ptr<C2Param> *_mRef; 144 }; 145 146 /** 147 * Field helper. 148 * 149 * Contains additional information for the field: possible values, and currently supported 150 * values. 151 */ 152 class FieldHelper { 153 public: 154 /** 155 * Creates helper for a field with given possible values. 156 * 157 * \param param parameter reference. The parameter does not have to be initialized at this 158 * point. 159 * \param field field identifier 160 * \param values possible values for the field 161 */ 162 FieldHelper(const ParamRef ¶m, const _C2FieldId &field, 163 std::unique_ptr<C2FieldSupportedValues> &&values); 164 165 /** 166 * Creates a param-field identifier for this field. This method is called after the 167 * underlying parameter has been initialized. 168 * 169 * \aram index 170 * 171 * @return C2ParamField 172 */ 173 C2ParamField makeParamField(C2Param::Index index) const; 174 175 /** 176 * Sets the currently supported values for this field. 177 * 178 * \param values currently supported values that will be moved out 179 */ 180 void setSupportedValues(std::unique_ptr<C2FieldSupportedValues> &&values); 181 182 /** 183 * Gets the currently supported values for this field. This defaults to the possible values 184 * if currently supported values were never set. 185 */ 186 const C2FieldSupportedValues *getSupportedValues() const; 187 188 /** 189 * Gets the possible values for this field. 190 */ 191 const C2FieldSupportedValues *getPossibleValues() const; 192 193 protected: 194 // TODO: move to impl for safety 195 ParamRef mParam; 196 _C2FieldId mFieldId; 197 std::unique_ptr<C2FieldSupportedValues> mPossible; 198 std::unique_ptr<C2FieldSupportedValues> mSupported; ///< if different from possible 199 }; 200 201 template<typename T> 202 struct C2_HIDE Param; 203 class ParamHelper; 204 205 /** 206 * Factory is an interface to get the parameter helpers from a std::shared_ptr<T> &. 207 */ 208 class Factory { 209 // \todo this may be already in ParamHelper 210 virtual std::shared_ptr<C2ParamReflector> getReflector() const = 0; 211 212 virtual std::shared_ptr<ParamHelper> getParamHelper(const ParamRef ¶m) const = 0; 213 214 public: 215 virtual ~Factory() = default; 216 217 template<typename T> 218 Param<T> get(std::shared_ptr<T> ¶m, std::shared_ptr<T> altValue = nullptr) const { 219 return Param<T>(getParamHelper(ParamRef(param)), 220 altValue == nullptr ? param : altValue, 221 getReflector()); 222 } 223 }; 224 225 /** 226 * Typed field helper. 227 */ 228 template<typename T> 229 struct Field { 230 /** 231 * Constructor. 232 * 233 * \param helper helper for this field 234 * \param index parameter index (this is needed as it is not available during parameter 235 * construction) \todo remove 236 */ 237 Field(std::shared_ptr<FieldHelper> helper, C2Param::Index index); 238 239 bool supportsAtAll(T value) const { 240 return C2FieldSupportedValuesHelper<T>(*_mHelper->getPossibleValues()).supports(value); 241 } 242 243 bool supportsNow(T value) const { 244 return C2FieldSupportedValuesHelper<T>(*_mHelper->getSupportedValues()).supports(value); 245 } 246 247 /** 248 * Creates a conflict resolution suggestion builder for this field. 249 */ 250 C2ParamFieldValuesBuilder<T> shouldBe() const; 251 252 /** 253 * Creates a currently supported values builder for this field. This is only supported 254 * for non-const fields to disallow setting supported values for dependencies. 255 */ 256 C2ParamFieldValuesBuilder<T> mustBe(); 257 258 operator C2ParamField() const { 259 return _mField; 260 } 261 262 // TODO 263 C2R validatePossible(const T &value __unused) const { 264 /// TODO 265 return C2R::Ok(); 266 } 267 268 private: 269 std::shared_ptr<FieldHelper> _mHelper; 270 C2ParamField _mField; 271 }; 272 273 class ParamHelper { 274 public: 275 ParamHelper(ParamRef param, C2StringLiteral name, C2StructDescriptor &&); 276 ParamHelper(ParamHelper &&); 277 ~ParamHelper(); 278 279 /** 280 * Finds a field descriptor. 281 */ 282 std::shared_ptr<FieldHelper> findField(size_t baseOffs, size_t baseSize) const; 283 284 /// returns the parameter ref for this parameter 285 const ParamRef ref() const; 286 287 /// returns the current value of this parameter as modifiable. The constness of this 288 /// object determines the constness of the returned value. 289 std::shared_ptr<C2Param> value(); 290 291 /// returns the current value of this parameter as const 292 std::shared_ptr<const C2Param> value() const; 293 294 /** 295 * Performs a configuration change request for this parameter. 296 * 297 * \param value the value that is being assigned to this parameter. 298 * This could be pointing to the current value of the 299 * parameter. This must not change. 300 * \param mayBlock whether blocking is allowed 301 * \param endValue the resulting value 302 * \param factory parameter factory (to access dependencies) 303 * \param failures vector of failures to append any failures from this 304 * operation 305 * 306 * \retval C2_OK configuration was successful 307 * \retval C2_BAD_VALUE value is incorrect (TBD) 308 * \retval C2_NO_MEMORY not enough memory to perform the assignment 309 * \retval C2_TIMED_OUT configuration timed out 310 * \retval C2_BLOCKING configuration requires blocking to be allowed 311 * \retval C2_CORRUPTED interface is corrupted 312 */ 313 c2_status_t trySet( 314 const C2Param *value, bool mayBlock, 315 bool *changed, 316 Factory &factory, 317 std::vector<std::unique_ptr<C2SettingResult>>* const failures); 318 319 /// returns parameter indices that depend on this parameter 320 const std::vector<C2Param::Index> getDownDependencies() const; 321 322 /// adds a dependent parameter 323 void addDownDependency(C2Param::Index index); 324 325 /// returns that parameter refs for parameters that depend on this 326 const std::vector<ParamRef> getDependenciesAsRefs() const; 327 328 /// returns and moves out stored struct descriptor 329 C2StructDescriptor retrieveStructDescriptor(); 330 331 /// returns the name of this parameter 332 C2String name() const; 333 334 /// returns the index of this parameter 335 C2Param::Index index() const; 336 337 /// returns the parameter descriptor 338 std::shared_ptr<const C2ParamDescriptor> getDescriptor() const; 339 340 /** 341 * Validates param helper. 342 * 343 * For now, this fills field info for const params. 344 * 345 * \retval C2_CORRUPTED the parameter cannot be added as such 346 */ 347 c2_status_t validate(const std::shared_ptr<C2ParamReflector> &reflector); 348 349 protected: 350 typedef C2ParamDescriptor::attrib_t attrib_t; 351 attrib_t& attrib(); 352 353 /// sets the default value of this parameter 354 void setDefaultValue(std::shared_ptr<C2Param> default_); 355 356 /// sets the setter method 357 void setSetter(std::function<C2R(const C2Param *, bool, bool *, Factory &)> setter); 358 359 /// sets the getter method 360 void setGetter(std::function<std::shared_ptr<C2Param>(bool)> getter); 361 362 /// sets the dependencies 363 void setDependencies(std::vector<C2Param::Index> indices, std::vector<ParamRef> refs); 364 365 /// sets the fields and their supported values 366 void setFields(std::vector<C2ParamFieldValues> &&fields); 367 368 /// build this into a final ParamHelper object 369 std::shared_ptr<ParamHelper> build(); 370 371 class Impl; 372 std::unique_ptr<Impl> mImpl; 373 }; 374 375 /** 376 * Typed parameter helper. This provides access to members as well as field helpers. 377 */ 378 template<typename T> 379 struct C2_HIDE Param { 380 Param( 381 std::shared_ptr<ParamHelper> helper, std::shared_ptr<T> ¶m, 382 std::shared_ptr<C2ParamReflector> reflector) 383 : v(*param.get()), 384 _mTypedParam(param), 385 _mHelper(helper), 386 _mReflector(reflector) { } 387 388 template<typename S> 389 using FieldType = Field< 390 typename _c2_reduce_enum_to_underlying_type< 391 typename std::remove_const< 392 typename std::remove_extent<S>::type>::type>::type>; 393 394 template<typename S> 395 FieldType<S> F(S &field) { 396 size_t offs = (uintptr_t)&field - (uintptr_t)&get(); 397 // this must fall either within sizeof(T) + FLEX_SIZE or param->size() 398 // size_t size = sizeof(field); 399 // mParam may be null 400 size_t baseSize = sizeof(typename std::remove_extent<S>::type); 401 size_t baseOffs = GetBaseOffset( 402 _mReflector, T::CORE_INDEX, offs - sizeof(C2Param)); 403 if (~baseOffs == 0) { 404 // C2_LOG(FATAL) << "unknown field at offset " << offs << " size " << sizeof(S) 405 // << " base-size " << baseSize; 406 // __builtin_trap(); 407 } else { 408 baseOffs += sizeof(C2Param); 409 } 410 411 std::shared_ptr<FieldHelper> helper = _mHelper->findField(baseOffs, baseSize); 412 return FieldType<S>(helper, _mTypedParam->index()); 413 } 414 415 // const Param have const Fields; however, remove const from S 416 template<typename S> 417 const FieldType<S> F(S &field) const { 418 return const_cast<const FieldType<S>>(const_cast<Param *>(this)->F(field)); 419 } 420 421 /// Returns a const ref value of this const param. 422 const T &get() const { 423 return *_mTypedParam.get(); 424 } 425 426 /// Returns a modifiable ref value of this non-const param. 427 T &set() { 428 return *_mTypedParam.get(); 429 } 430 431 /// Const-reference to the value.s 432 T const &v; 433 434 private: 435 std::shared_ptr<T> _mTypedParam; 436 std::shared_ptr<ParamHelper> _mHelper; 437 std::shared_ptr<C2ParamReflector> _mReflector; 438 }; 439 440 template<typename T> 441 using C2P = Param<T>; 442 443 /** 444 * Templated move builder class for a parameter helper. 445 */ 446 template<typename T> 447 class C2_HIDE ParamBuilder : private ParamHelper { 448 public: 449 /** Construct the parameter builder from minimal info required. */ 450 ParamBuilder(std::shared_ptr<T> ¶m, C2StringLiteral name) 451 : ParamHelper(param, name, C2StructDescriptor((T*)nullptr)), 452 mTypedParam(¶m) { 453 attrib() = attrib_t::IS_PERSISTENT; 454 } 455 456 /** Makes this parameter required. */ 457 inline ParamBuilder &required() { 458 attrib() |= attrib_t::IS_REQUIRED; 459 return *this; 460 } 461 462 /** Makes this parameter transient (not persistent). */ 463 inline ParamBuilder &transient() { 464 attrib() &= ~attrib_t::IS_PERSISTENT; 465 return *this; 466 } 467 468 /** Makes this parameter hidden (not exposed in JAVA API). */ 469 inline ParamBuilder &hidden() { 470 attrib() |= attrib_t::IS_HIDDEN; 471 return *this; 472 } 473 474 /** Makes this parameter internal (not exposed to query/settings). */ 475 inline ParamBuilder &internal() { 476 attrib() |= attrib_t::IS_INTERNAL; 477 return *this; 478 } 479 480 /** Adds default value. Must be added exactly once. */ 481 inline ParamBuilder &withDefault(std::shared_ptr<T> default_) { 482 // CHECK(!mDefaultValue); 483 // WARN_IF(!default_); // could be nullptr if OOM 484 // technically, this could be in the parent 485 *mTypedParam = std::shared_ptr<T>(T::From(C2Param::Copy(*default_).release())); 486 setDefaultValue(default_); 487 std::shared_ptr<T> *typedParam = mTypedParam; 488 setGetter([typedParam](bool) -> std::shared_ptr<C2Param> { 489 return std::static_pointer_cast<C2Param>(*typedParam); 490 }); 491 return *this; 492 } 493 494 /** Adds default value. Must be added exactly once. */ 495 inline ParamBuilder &withDefault(T *default_) { 496 return withDefault(std::shared_ptr<T>(default_)); 497 } 498 499 /** Adds all fields to this parameter with their possible values. */ 500 inline ParamBuilder &withFields(std::vector<C2ParamFieldValues> &&fields_) { 501 setFields(std::move(fields_)); 502 return *this; 503 } 504 505 /** 506 * Adds a constant value (also as default). Must be added exactly once. 507 * 508 * Const parameters by definition have no dependencies. 509 */ 510 inline ParamBuilder &withConstValue(std::shared_ptr<T> default_) { 511 attrib() |= attrib_t::IS_CONST; 512 setSetter([default_]( 513 const C2Param *value, bool mayBlock __unused, bool *changed, Factory &) -> C2R { 514 *changed = false; 515 const T *typedValue = T::From(value); 516 if (typedValue == nullptr) { 517 return C2R::Corrupted(); // TODO BadValue/Invalid. This should not happen here. 518 } 519 if (*typedValue != *default_) { 520 return C2R::Corrupted(); // TODO ReadOnly(*default_); 521 } 522 *changed = false; 523 return C2R::Ok(); 524 }); 525 return withDefault(default_); 526 } 527 528 /** Adds constant value (also as default). Must be added exactly once. */ 529 inline ParamBuilder &withConstValue(T *default_) { 530 return withConstValue(std::shared_ptr<T>(default_)); 531 } 532 533 /** 534 * Use a strict setter. 535 * 536 * \param fn strict setter 537 * \param deps dependencies (references) 538 */ 539 template<typename ... Deps> 540 inline ParamBuilder &withSetter( 541 C2R (*fn)(bool, const C2P<T> &, C2P<T> &, const C2P<Deps> &...), 542 std::shared_ptr<Deps>& ... deps) { 543 attrib() |= attrib_t::IS_STRICT; 544 std::shared_ptr<T> *typedParam = mTypedParam; 545 setSetter([typedParam, fn, &deps...]( 546 const C2Param *value, bool mayBlock, bool *changed, Factory &factory) -> C2R { 547 *changed = false; 548 const T *typedValue = T::From(value); 549 if (typedValue == nullptr) { 550 return C2R::Corrupted(); // TODO BadValue/Invalid. This should not happen here. 551 } 552 // Do copy-on-change for parameters in this helper so change can be detected by 553 // a change of the pointer. Do this by working on a proposed value. 554 std::shared_ptr<T> proposedValue = 555 std::shared_ptr<T>(T::From(C2Param::Copy(*value).release())); 556 if (proposedValue == nullptr) { 557 return C2R::NoMemory(value->index()); 558 } 559 C2P<T> oldValue = factory.get(*typedParam); 560 // Get a parameter helper with value pointing to proposedValue 561 C2P<T> helper = factory.get(*typedParam, proposedValue); 562 C2R result = fn(mayBlock, oldValue, helper, factory.get(deps)...); 563 564 // If value changed, copy result to current value 565 if (helper.get() != *typedParam->get()) { 566 *typedParam = proposedValue; 567 *changed = true; 568 } 569 return result; 570 }); 571 setDependencies(std::vector<C2Param::Index>{ deps->index()... }, 572 std::vector<ParamRef>{ ParamRef(deps)... }); 573 return *this; 574 } 575 576 /** 577 * Use a non-strict setter. 578 * 579 * \param fn non-strict setter 580 * \param deps dependencies (references) 581 */ 582 template<typename ... Deps> 583 inline ParamBuilder &withSetter( 584 C2R (*fn)(bool, C2P<T> &, const C2P<Deps> &...), std::shared_ptr<Deps>& ... deps) { 585 std::shared_ptr<T> *typedParam = mTypedParam; 586 setSetter([typedParam, fn, &deps...]( 587 const C2Param *value, bool mayBlock, bool *changed, Factory &factory) -> C2R { 588 *changed = false; 589 const T *typedValue = T::From(value); 590 if (typedValue == nullptr) { 591 return C2R::Corrupted(); // TODO BadValue/Invalid. This should not happen here. 592 } 593 // Do copy-on-change for parameters in this helper so change can be detected by 594 // a change of the pointer. Do this by working on a proposed value. 595 std::shared_ptr<T> proposedValue = 596 std::shared_ptr<T>(T::From(C2Param::Copy(*value).release())); 597 if (proposedValue == nullptr) { 598 return C2R::NoMemory(value->index()); 599 } 600 // Get a parameter helper with value pointing to proposedValue 601 C2P<T> helper = factory.get(*typedParam, proposedValue); 602 C2R result = fn(mayBlock, helper, factory.get(deps)...); 603 604 // If value changed, copy result to current value 605 if (helper.get() != *typedParam->get()) { 606 *typedParam = proposedValue; 607 *changed = true; 608 } 609 return result; 610 }); 611 setDependencies(std::vector<C2Param::Index>{ deps->index()... }, 612 std::vector<ParamRef>{ ParamRef(deps)... }); 613 return *this; 614 } 615 616 /** 617 * Marks this a calculated (read-only) field. 618 * 619 * \param fn non-strict setter (calculator) 620 * \param deps dependencies (references) 621 */ 622 template<typename ... Deps> 623 inline ParamBuilder &calculatedAs( 624 C2R (*fn)(bool, C2P<T> &, const C2P<Deps> &...), std::shared_ptr<Deps>& ... deps) { 625 attrib() |= attrib_t::IS_READ_ONLY; 626 return withSetter(fn, std::forward<decltype(deps)>(deps)...); 627 } 628 629 inline std::shared_ptr<ParamHelper> build() { 630 return ParamHelper::build(); 631 } 632 633 protected: 634 std::shared_ptr<T> *mTypedParam; 635 }; 636 637 template<typename T> 638 static ParamBuilder<T> DefineParam(std::shared_ptr<T> ¶m, C2StringLiteral name) { 639 return ParamBuilder<T>(param, name); 640 } 641 642 public: 643 c2_status_t query( 644 const std::vector<C2Param*> &stackParams, 645 const std::vector<C2Param::Index> &heapParamIndices, 646 c2_blocking_t mayBlock, 647 std::vector<std::unique_ptr<C2Param>>* const heapParams) const; 648 649 /** 650 * Helper implementing config calls as well as other configuration updates. 651 * 652 * \param params 653 * \param mayBlock 654 * \param failures 655 * \param updateParams if true, the updated parameter values are copied back into the arguments 656 * passed in |params| 657 * \param changes pointed to a vector to receive settings with their values changed. If not 658 * null, settings with their values changed are added to this. 659 * \return result from config 660 */ 661 c2_status_t config( 662 const std::vector<C2Param*> ¶ms, c2_blocking_t mayBlock, 663 std::vector<std::unique_ptr<C2SettingResult>>* const failures, 664 bool updateParams = true, 665 std::vector<std::shared_ptr<C2Param>> *changes = nullptr); 666 667 c2_status_t querySupportedParams( 668 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const; 669 670 c2_status_t querySupportedValues( 671 std::vector<C2FieldSupportedValuesQuery> &fields, c2_blocking_t mayBlock) const; 672 673 std::shared_ptr<C2ReflectorHelper> getReflector() { 674 return mReflector; 675 } 676 677 private: 678 void setInterfaceAddressBounds(uintptr_t start, uintptr_t end) { 679 // TODO: exclude this helper 680 (void)start; 681 (void)end; 682 } 683 684 protected: 685 std::shared_ptr<C2ReflectorHelper> mReflector; 686 struct FactoryImpl; 687 std::shared_ptr<FactoryImpl> _mFactory; 688 689 C2InterfaceHelper(std::shared_ptr<C2ReflectorHelper> reflector); 690 691 /** 692 * Adds a parameter to this interface. 693 * \note This method CHECKs. 694 * 695 * \param param parameter to add. 696 */ 697 void addParameter(std::shared_ptr<ParamHelper> param); 698 699 /** 700 * Returns the dependency index for a parameter. 701 * 702 * \param ix the index of the parameter 703 */ 704 size_t getDependencyIndex(C2Param::Index ix) const; 705 706 virtual ~C2InterfaceHelper() = default; 707 708 /** 709 * Sets subclass instance's address and size. 710 * 711 * \todo allow subclass to specify parameter address range directly (e.g. do not assume that 712 * they are local to the subclass instance) 713 * 714 * \param T type of the derived instance 715 * \param instance pointer to the derived instance 716 */ 717 template<typename T> 718 inline C2_HIDE void setDerivedInstance(T *instance) { 719 setInterfaceAddressBounds((uintptr_t)instance, (uintptr_t)(instance + 1)); 720 } 721 722 C2_DO_NOT_COPY(C2InterfaceHelper); 723 }; 724 725 /** 726 * Creates a C2ParamFieldValuesBuilder class for a field of a parameter 727 * 728 * \param spParam a configuration parameter in an interface class subclassed from C2InterfaceHelper. 729 * \param field a field of such parameter 730 */ 731 #define C2F(spParam, field) \ 732 C2ParamFieldValuesBuilder< \ 733 typename _c2_reduce_enum_to_underlying_type< \ 734 typename std::remove_reference< \ 735 typename std::remove_extent< \ 736 decltype(spParam->field)>::type>::type>::type>( \ 737 C2ParamField(spParam.get(), &spParam->field)) 738 739 #endif // C2UTILS_INTERFACE_HELPER_H_ 740