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_UTILS_H_ 18 #define C2UTILS_INTERFACE_UTILS_H_ 19 20 #include <C2Component.h> 21 #include <C2Param.h> 22 #include <C2Work.h> 23 24 #include <cmath> 25 #include <iterator> 26 #include <limits> 27 #include <type_traits> 28 29 /** 30 * Helper class to map underlying types to C2Value types as well as to print field values. This is 31 * generally the same as simply the underlying type except for characters (STRING) and bytes (BLOB). 32 */ 33 template<typename T> 34 struct C2_HIDE _C2FieldValueHelper { 35 typedef T ValueType; put_C2FieldValueHelper36 inline static std::ostream& put(std::ostream &os, const C2Value::Primitive &p) { 37 return os << p.ref<T>(); 38 } 39 }; 40 41 template<> 42 struct C2_HIDE _C2FieldValueHelper<uint8_t> { 43 typedef uint32_t ValueType; 44 static std::ostream& put(std::ostream &os, const C2Value::Primitive &p); 45 }; 46 47 template<> 48 struct C2_HIDE _C2FieldValueHelper<char> { 49 typedef int32_t ValueType; 50 static std::ostream& put(std::ostream &os, const C2Value::Primitive &p); 51 }; 52 53 /** 54 * Supported value range utility for a field of a given type. 55 * 56 * This mimics C2FieldSupportedValue for RANGE type. 57 */ 58 template<typename T> 59 class C2SupportedRange { 60 typedef typename _C2FieldValueHelper<T>::ValueType ValueType; 61 62 //private: 63 constexpr static T MIN_VALUE = std::numeric_limits<T>::min(); 64 constexpr static T MAX_VALUE = std::numeric_limits<T>::max(); 65 constexpr static T MIN_STEP = std::is_floating_point<T>::value ? 0 : 1; 66 67 public: 68 /** 69 * Constructs an empty range with no supported values. 70 * 71 * \note This is a specializated supported range representation that is only used for 72 * this object - it is equivalent to the EMPTY type in C2FieldSupportedValues. 73 */ 74 inline static constexpr C2SupportedRange<T> None() { 75 return C2SupportedRange(MAX_VALUE, MIN_VALUE); 76 } 77 78 /** 79 * Constructs a range with all values supported. 80 */ 81 inline static constexpr C2SupportedRange<T> Any() { 82 return C2SupportedRange(MIN_VALUE, MAX_VALUE); 83 } 84 85 /** 86 * Constructs a range with a single supported value. 87 * 88 * \param value the sole supported value 89 */ 90 inline static constexpr C2SupportedRange<T> EqualTo(T value) { 91 return C2SupportedRange(value, value); 92 } 93 94 /** 95 * Constructs a range with supported values greater than a given value. 96 * 97 * \param value the given value 98 */ 99 inline static C2SupportedRange<T> GreaterThan(T value) { 100 return (value == MAX_VALUE ? None() : 101 std::is_floating_point<T>::value ? 102 C2SupportedRange(std::nextafter(value, MAX_VALUE), MAX_VALUE) : 103 C2SupportedRange(value + MIN_STEP, MAX_VALUE)); 104 } 105 106 /** 107 * Constructs a range with supported values greater than or equal to a given value. 108 * 109 * \param value the given value 110 */ 111 inline static constexpr C2SupportedRange<T> GreaterThanOrEqualTo(T value) { 112 return C2SupportedRange(value, MAX_VALUE); 113 } 114 115 /** 116 * Constructs a range with supported values greater than or equal to (aka not less than) a given 117 * value. 118 * 119 * \param value the given value 120 */ 121 inline static constexpr C2SupportedRange<T> NotLessThan(T value) { 122 return GreaterThanOrEqualTo(value); 123 } 124 125 /** 126 * Constructs a range with supported values less than or equal to a given value. 127 * 128 * \param value the given value 129 */ 130 inline static constexpr C2SupportedRange<T> LessThanOrEqualTo(T value) { 131 return C2SupportedRange(MIN_VALUE, value); 132 } 133 134 /** 135 * Constructs a range with supported values less than or equal to (aka not greater than) a given 136 * value. 137 * 138 * \param value the given value 139 */ 140 inline static constexpr C2SupportedRange<T> NotGreaterThan(T value) { 141 return LessThanOrEqualTo(value); 142 } 143 144 /** 145 * Constructs a range with supported values less than a given value. 146 * 147 * \param value the given value 148 */ 149 inline static C2SupportedRange<T> LessThan(T value) { 150 return (value == MIN_VALUE ? None() : 151 std::is_floating_point<T>::value ? 152 C2SupportedRange(MIN_VALUE, std::nextafter(value, MIN_VALUE)) : 153 C2SupportedRange(MIN_VALUE, value - MIN_STEP)); 154 } 155 156 /** 157 * Constructs a continuous or arithmetic range between two values. 158 * 159 * \param min the lower value 160 * \param max the higher value (if this is lower than |min| the range will be empty) 161 * \param step the step of the arithmetic range. (If this is 0 for floating point types or 1 for 162 * integer types, the constructed range is continuous) 163 */ 164 inline static constexpr 165 C2SupportedRange<T> InRange(T min, T max, T step = MIN_STEP) { 166 return C2SupportedRange(min, max, step); 167 } 168 169 /** 170 * Constructs a range over a geometric series between two values. 171 * 172 * \param min the lower bound of the range. This value is always part of the constructed range 173 * as long as it is not greater than |max|. 174 * \param max the upper bound of the range. This value is only part of the constructed 175 * range if it is part of the geometric series. 176 * \param num the numerator of the geometric series. 177 * \param denom the denominator of the geometric series. 178 */ 179 inline static constexpr 180 C2SupportedRange<T> InSeries(T min, T max, T num, T denom) { 181 return C2SupportedRange(min, max, 0, num, denom); 182 } 183 184 /** 185 * Constructs a range over a multiply-accumulate series between two values. 186 * 187 * \param min the lower bound of the range. This value is always part of the constructed range 188 * as long as it is not greater than |max|. 189 * \param max the upper bound of the range. This value is only part of the constructed 190 * range if it is part of the series. 191 * \param step the accumulator of the multiply-accumulate series 192 * \param num the numerator of the multiply-accumulate series. 193 * \param denom the denominator of the multiply-accumulate series. 194 */ 195 inline static constexpr 196 C2SupportedRange<T> InMacSeries(T min, T max, T step, T num, T denom) { 197 return C2SupportedRange(min, max, step, num, denom); 198 } 199 200 /** 201 * Constructs a range from a generic C2FieldSupportedValues object. This will be an empty 202 * range if the supported values are not of RANGE type. 203 * 204 * \param values the supported values object 205 */ 206 C2SupportedRange(const C2FieldSupportedValues &values); 207 208 /** 209 * Returns whether this range is empty. 210 */ 211 inline constexpr bool isEmpty() const { 212 return _mMin > _mMax; 213 } 214 215 /** 216 * Returns whether this range is valid. 217 * 218 * Ranges are valid if they are continuous or monotonic. 219 */ 220 inline constexpr bool isValid() const { 221 // TODO: handle overflow or negative series 222 return _mDenom > 0 && _mNum >= _mDenom && _mMin * (_mDenom - _mNum) < _mStep * _mDenom; 223 } 224 225 /** 226 * Returns whether a value is part of this range. 227 * 228 * \param value the value to check. 229 */ 230 bool contains(T value) const; 231 232 /** 233 * Returns a new range that is the intersection of this range and another, if it is 234 * representable as a range object. 235 * 236 * \param limit the other range 237 */ 238 C2SupportedRange<T> limitedTo(const C2SupportedRange<T> &limit) const; 239 240 /** 241 * Converts this object to a C2FieldSupportedValues object. 242 */ 243 inline operator C2FieldSupportedValues() const { 244 return C2FieldSupportedValues(_mMin, _mMax, _mStep, _mNum, _mDenom); 245 } 246 247 /** 248 * Returns the lower bound and starting point of this range. 249 */ 250 inline C2_HIDE constexpr T min() const { return _mMin; } 251 252 /** 253 * Returns the upper bound of this range. 254 */ 255 inline C2_HIDE constexpr T max() const { return _mMax; } 256 257 /** 258 * Returns the step of this range. 259 */ 260 inline C2_HIDE constexpr T step() const { return _mStep; } 261 262 /** 263 * Returns the numerator of this range. 264 */ 265 inline C2_HIDE constexpr T num() const { return _mNum; } 266 267 /** 268 * Returns the denominator of this range. 269 */ 270 inline C2_HIDE constexpr T denom() const { return _mDenom; } 271 272 private: 273 /** 274 * Returns whether x[i...] is all values between _mMin and _mMax. 275 */ 276 inline C2_HIDE constexpr bool isSimpleRange() const { 277 return _mStep == MIN_STEP && _mNum == 1 && _mDenom == 1; 278 } 279 280 /** 281 * Returns whether x[i...] is defined as such: 282 * x[i + 1] = x[i] + _mStep, where _mStep > 0 and _mMin <= x[i] <= _mMax 283 */ 284 inline C2_HIDE constexpr bool isArithmeticSeries() const { 285 return _mStep > MIN_STEP && _mNum == 1 && _mDenom == 1; 286 } 287 288 /** 289 * Returns whether x[i...] is defined as such: 290 * x[i] = x[0] * (_mNum / _mDenom) ^ i (with rounding), where _mNum > _mDenom > 0 and x[0] > 0 291 */ 292 inline C2_HIDE constexpr bool isGeometricSeries() const { 293 return _mMin > 0 && _mStep == 0 && _mNum > _mDenom && _mDenom > 0; 294 } 295 296 /** 297 * Returns whether x[i...] is defined as such: 298 * x[i + 1] = x[i] * _mNum / _mDenom + _mStep (with rounding), while x[i + 1] > x[i], where 299 * _mStep != 0, _mDenom > 0 and _mNum > 0 300 */ 301 inline C2_HIDE constexpr bool isMacSeries() const { 302 return _mStep != 0 && _mNum > 0 && _mDenom > 0; 303 } 304 305 /** 306 * Constructs an arithmetic or continuous range. 307 * 308 * \param min the lower value 309 * \param max the higher value (if this is lower than |min| the range will be empty) 310 * \param step the step of the arithmetic range. (If this is 0 for floating point types or 1 for 311 * integer types, the constructed range is continuous) 312 */ 313 constexpr C2_HIDE C2SupportedRange(T min, T max, T step = T(std::is_floating_point<T>::value ? 0 : 1)) 314 : _mMin(min), _mMax(max), _mStep(step), _mNum(1), _mDenom(1) { } 315 316 /** 317 * Constructs a range over a geomertic sor multiply-accumulate series. 318 * 319 * \param min the lower bound of the range. This value is always part of the constructed range 320 * as long as it is not greater than |max|. 321 * \param max the upper bound of the range. This value is only part of the constructed 322 * range if it is part of the geometric series. 323 * \param step the accumulator of the multiply-accumulate series. This is 0 for a pure geometric 324 * series 325 * \param num the numerator of the geometric series. 326 * \param denom the denominator of the geometric series. 327 */ 328 constexpr C2_HIDE C2SupportedRange(T min, T max, T step, T num, T den) 329 : _mMin(min), _mMax(max), _mStep(step), _mNum(num), _mDenom(den) { } 330 331 T _mMin; ///< lower bound and starting point 332 T _mMax; ///< upper bound 333 T _mStep; ///< step of an arithmetic series (0 if continuous floating point range) 334 T _mNum; ///< numerator of a geometric series 335 T _mDenom; ///< denominator of a geometric series 336 }; 337 338 /** 339 * Ordered supported flag set for a field of a given type. 340 */ 341 template<typename T> 342 class C2SupportedFlags { 343 typedef typename _C2FieldValueHelper<T>::ValueType ValueType; 344 345 public: 346 /** 347 * Constructs an empty flag set. 348 * 349 * \note This is a specializated supported flags representation that is only used for 350 * this object - it is equivalent to the EMPTY type in C2FieldSupportedValues. 351 */ 352 static inline C2SupportedFlags<T> None() { 353 return C2SupportedFlags(std::initializer_list<C2Value::Primitive>()); 354 } 355 356 /** 357 * Constructs a flags set of given flags. 358 * 359 * \param flags the ordered set of flags as an initializer list. 360 * \param min minimum set of flags to be set. 361 */ 362 static inline C2SupportedFlags<T> Flags(const std::initializer_list<T> flags, T min = T(0)) { 363 return C2SupportedFlags(min, flags); 364 } 365 366 /** 367 * Constructs a flags set of given flags. 368 * 369 * \param flags the ordered set of flags. 370 * \param min minimum set of flags to be set. 371 */ 372 static inline C2SupportedFlags<T> Flags(const std::vector<T> &flags, T min = T(0)) { 373 return C2SupportedFlags(min, flags); 374 } 375 376 /** 377 * Constructs a flag set from a generic C2FieldSupportedValues object. This will be an empty 378 * set if the supported values are not of FLAGS type. 379 * 380 * \param values the supported values object 381 */ 382 C2SupportedFlags<T>(const C2FieldSupportedValues &values) { 383 if (values.type == C2FieldSupportedValues::FLAGS) { 384 _mValues.insert(_mValues.end(), values.values.begin(), values.values.end()); 385 } 386 } 387 388 /** 389 * Returns whether this set is empty. 390 */ 391 constexpr bool isEmpty() const { 392 return _mValues.empty(); 393 } 394 395 /** 396 * Returns whether a value is part of this set. 397 * 398 * \param value the value to check. 399 */ 400 bool contains(T value) const; 401 402 /** 403 * Returns a new flag set that is the intersection of this set and another. 404 * 405 * \param limit the other value set 406 */ 407 C2SupportedFlags<T> limitedTo(const C2SupportedFlags<T> &limit) const; 408 409 /** 410 * Converts this object to a C2FieldSupportedValues object. 411 */ 412 operator C2FieldSupportedValues() const { 413 return C2FieldSupportedValues(!isEmpty() /* flags */, _mValues); 414 } 415 416 /** 417 * Returns the ordered set of flags of this object. 418 */ 419 const std::vector<T> flags() const; 420 421 /** 422 * Returns the minimum set of flags for this object. 423 */ 424 T min() const; 425 426 /** 427 * Clears this supported value set. 428 */ 429 inline void clear() { 430 _mValues.clear(); 431 } 432 433 private: 434 /** 435 * Constructs a flag set directly from an internal representation. 436 * 437 * \param values a vector containing the minimum flag set followed by the set of flags 438 */ 439 C2SupportedFlags(std::vector<C2Value::Primitive> &&values) 440 : _mValues(values) { 441 } 442 443 /** 444 * Constructs a flag set from a set of flags and a minimum flag set. 445 * 446 * \param flags the set 447 */ 448 C2SupportedFlags(T min, const std::vector<T> &flags) { 449 _mValues.emplace_back(min); 450 for (T elem : flags) { 451 _mValues.emplace_back(elem); 452 } 453 } 454 455 /** 456 * Constructs a flag set from a set of initializer list values and a minimum flag set 457 * 458 * \param flags the set 459 */ 460 C2SupportedFlags(T min, const std::initializer_list<T> flags) { 461 _mValues.emplace_back(min); 462 for (T elem : flags) { 463 _mValues.emplace_back(elem); 464 } 465 } 466 467 std::vector<C2Value::Primitive> _mValues; ///< the minimum flag set followed by the set of flags 468 }; 469 470 /** 471 * Ordered supported value set for a field of a given type. 472 */ 473 template<typename T> 474 class C2SupportedValueSet { 475 typedef typename _C2FieldValueHelper<T>::ValueType ValueType; 476 477 public: 478 /** 479 * Constructs an empty value set. 480 * 481 * \note This is a specializated supported range representation that is only used for 482 * this object - it is equivalent to the EMPTY type in C2FieldSupportedValues. 483 */ 484 static inline C2SupportedValueSet<T> None() { 485 return C2SupportedValueSet({ }); 486 } 487 488 /** 489 * Constructs a value set of given values. 490 * 491 * \param values the ordered set of values as an initializer list. 492 */ 493 static inline C2SupportedValueSet<T> OneOf(const std::initializer_list<T> values) { 494 return C2SupportedValueSet(values); 495 } 496 497 /** 498 * Constructs a value set of given values. 499 * 500 * \param values the ordered set of values. 501 */ 502 static inline C2SupportedValueSet<T> OneOf(const std::vector<T> &values) { 503 return C2SupportedValueSet(values); 504 } 505 506 /** 507 * Constructs a value set from a generic C2FieldSupportedValues object. This will be an empty 508 * set if the supported values are not of VALUES type. 509 * 510 * \param values the supported values object 511 */ 512 C2SupportedValueSet<T>(const C2FieldSupportedValues &values) { 513 if (values.type == C2FieldSupportedValues::VALUES) { 514 _mValues.insert(_mValues.end(), values.values.begin(), values.values.end()); 515 } 516 } 517 518 /** 519 * Returns whether this range is empty. 520 */ 521 constexpr bool isEmpty() const { 522 return _mValues.empty(); 523 } 524 525 /** 526 * Returns whether a value is part of this set. 527 * 528 * \param value the value to check. 529 */ 530 bool contains(T value) const; 531 532 /** 533 * Returns a new value set that is the intersection of this set and another. 534 * 535 * \param limit the other value set 536 */ 537 C2SupportedValueSet<T> limitedTo(const C2SupportedValueSet<T> &limit) const; 538 539 /** 540 * Returns a new value set that is the intersection of this set and a value range. 541 * 542 * \param limit the other range 543 */ 544 C2SupportedValueSet<T> limitedTo(const C2SupportedRange<T> &limit) const; 545 546 /** 547 * Returns a new value set that is the intersection of this set and a flag set. 548 * 549 * \param limit the other flag set 550 */ 551 C2SupportedValueSet<T> limitedTo(const C2SupportedFlags<T> &limit) const; 552 553 /** 554 * Converts this object to a C2FieldSupportedValues object. 555 */ 556 operator C2FieldSupportedValues() const { 557 return C2FieldSupportedValues(false /* flags */, _mValues); 558 } 559 560 /** 561 * Returns the ordered set of values of this object. 562 */ 563 const std::vector<T> values() const; 564 565 /** 566 * Clears this supported value set. 567 */ 568 inline void clear() { 569 _mValues.clear(); 570 } 571 572 private: 573 /** 574 * Constructs a value set from a set of C2Value::Primitive values. 575 * 576 * \param values the set 577 */ 578 C2SupportedValueSet(std::vector<C2Value::Primitive> &&values) 579 : _mValues(values) { 580 } 581 582 /** 583 * Constructs a value set from a set of values. 584 * 585 * \param values the set 586 */ 587 C2SupportedValueSet(const std::vector<T> &values) { 588 for (T elem : values) { 589 _mValues.emplace_back(elem); 590 } 591 } 592 593 /** 594 * Constructs a value set from a set of initializer list values 595 * 596 * \param values the set 597 */ 598 C2SupportedValueSet(const std::initializer_list<T> values) { 599 for (T elem : values) { 600 _mValues.emplace_back(elem); 601 } 602 } 603 604 std::vector<C2Value::Primitive> _mValues; ///< the supported set of values 605 }; 606 607 /** 608 * Helper class to handle C2FieldSupporteValues object for fields of various types. 609 */ 610 template<typename T> 611 class C2FieldSupportedValuesHelper; 612 613 // templated operator must be predeclared for friend declaration 614 template<typename T> 615 std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<T> &i); 616 617 template<typename T> 618 class C2FieldSupportedValuesHelper { 619 public: 620 /** 621 * Creates a helper for a specific type from a generic C2FieldSupportedValues struct. 622 */ 623 C2FieldSupportedValuesHelper(const C2FieldSupportedValues &values); 624 625 // TRICKY: needed for std::unique_ptr<Impl> declaration 626 ~C2FieldSupportedValuesHelper(); 627 628 // support copy constructor/operator 629 C2FieldSupportedValuesHelper(const C2FieldSupportedValuesHelper &); 630 C2FieldSupportedValuesHelper& operator=(const C2FieldSupportedValuesHelper &); 631 632 bool supports(T value) const; 633 634 private: 635 // use pimpl as implementation may change in the future 636 struct Impl; 637 std::unique_ptr<Impl> _mImpl; 638 639 friend std::ostream& operator<< <T>(std::ostream& os, const C2FieldSupportedValuesHelper<T> &i); 640 //friend std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper &i); 641 }; 642 643 /** 644 * Builder for supported values for a field of a given type. 645 * 646 * This builder can be used to successively restrict the supported values for a field. Upon 647 * creation, there are no supported values specified - which for this builder means that all 648 * values are supported. 649 */ 650 template<typename T> 651 class C2ParamFieldValuesBuilder { 652 public: 653 /** 654 * Creates a builder with no defined values - but implicitly any value allowed. 655 */ 656 C2ParamFieldValuesBuilder(const C2ParamField &field); 657 658 /** 659 * Get C2ParamFieldValues from this builder. 660 */ 661 operator C2ParamFieldValues() const; 662 663 /** 664 * Define the supported values as the currently supported values of this builder. 665 */ 666 C2ParamFieldValuesBuilder<T> &any(); 667 668 /** 669 * Restrict (and thus define) the supported values to none. 670 * 671 * \note This really should not be used from the builder as all params must have supported 672 * values, but is here in case this is really the case. 673 */ 674 C2ParamFieldValuesBuilder<T> &none(); 675 676 /** 677 * Restrict (and thus define) the supported values to |value| alone. 678 */ 679 C2ParamFieldValuesBuilder<T> &equalTo(T value); 680 681 /** 682 * Restrict (and thus define) the supported values to values greater than |value|. 683 */ 684 inline C2ParamFieldValuesBuilder<T> &greaterThan(T value) { 685 return limitTo(C2SupportedRange<T>::GreaterThan(value)); 686 } 687 688 /** 689 * Restrict (and thus define) the supported values to values greater than or equal to |value|. 690 */ 691 C2ParamFieldValuesBuilder<T> &greaterThanOrEqualTo(T value) { 692 return limitTo(C2SupportedRange<T>::GreaterThanOrEqualTo(value)); 693 } 694 695 /** 696 * Restrict (and thus define) the supported values to values greater than or equal to |value|. 697 */ 698 C2ParamFieldValuesBuilder<T> ¬LessThan(T value) { 699 return limitTo(C2SupportedRange<T>::NotLessThan(value)); 700 } 701 702 /** 703 * Restrict (and thus define) the supported values to values less than or equal to |value|. 704 */ 705 C2ParamFieldValuesBuilder<T> &lessThanOrEqualTo(T value) { 706 return limitTo(C2SupportedRange<T>::LessThanOrEqualTo(value)); 707 } 708 709 /** 710 * Restrict (and thus define) the supported values to values less than or equal to |value|. 711 */ 712 C2ParamFieldValuesBuilder<T> ¬GreaterThan(T value) { 713 return limitTo(C2SupportedRange<T>::NotGreaterThan(value)); 714 } 715 716 /** 717 * Restrict (and thus define) the supported values to values less than |value|. 718 */ 719 C2ParamFieldValuesBuilder<T> &lessThan(T value) { 720 return limitTo(C2SupportedRange<T>::LessThan(value)); 721 } 722 723 /** 724 * Restrict (and thus define) the supported values to values in the range of [ |min|, |max| ] 725 * with optional |step|. 726 */ 727 C2ParamFieldValuesBuilder<T> &inRange( 728 T min, T max, T step = std::is_floating_point<T>::value ? T(0) : T(1)) { 729 return limitTo(C2SupportedRange<T>::InRange(min, max, step)); 730 } 731 732 /** 733 * Restrict (and thus define) the supported values to values in the geometric series starting 734 * from |min| with factor |num| / |denom|, not greater than |max|. 735 */ 736 C2ParamFieldValuesBuilder<T> &inSeries(T min, T max, T num, T denom) { 737 return limitTo(C2SupportedRange<T>::InSeries(min, max, num, denom)); 738 } 739 740 /** 741 * Restrict (and thus define) the supported values to values in the multiply-accumulate series 742 * starting from |min| with factor |num| / |denom| and |step|, not greater than |max|. 743 */ 744 C2ParamFieldValuesBuilder<T> &inMacSeries(T min, T max, T step, T num, T denom) { 745 return limitTo(C2SupportedRange<T>::InMacSeries(min, max, step, num, denom)); 746 } 747 748 /** 749 * Restrict (and thus define) the supported values to values in |values|. 750 */ 751 C2ParamFieldValuesBuilder<T> &oneOf(const std::initializer_list<T> values) { 752 return limitTo(C2SupportedValueSet<T>::OneOf(values)); 753 } 754 755 /** 756 * Restrict (and thus define) the supported values to values in |values|. 757 */ 758 C2ParamFieldValuesBuilder<T> &oneOf(const std::vector<T> &values) { 759 return limitTo(C2SupportedValueSet<T>::OneOf(values)); 760 } 761 762 /** 763 * Restrict (and thus define) the supported values to flags in |flags| with at least |min| 764 * set. 765 */ 766 C2ParamFieldValuesBuilder<T> &flags(const std::vector<T> &flags, T min = T(0)) { 767 return limitTo(C2SupportedFlags<T>::Flags(flags, min)); 768 } 769 770 /** 771 * Restrict (and thus define) the supported values to flags in |values| with at least |min| 772 * set. 773 */ 774 C2ParamFieldValuesBuilder<T> &flags(const std::initializer_list<T> flags, T min = T(0)) { 775 return limitTo(C2SupportedFlags<T>::Flags(flags, min)); 776 } 777 778 virtual ~C2ParamFieldValuesBuilder(); 779 780 // support copy constructor/operator 781 C2ParamFieldValuesBuilder(const C2ParamFieldValuesBuilder &); 782 C2ParamFieldValuesBuilder& operator=(const C2ParamFieldValuesBuilder &); 783 784 private: 785 /** 786 * Restrict (and thus define) the supported values to a value set. 787 */ 788 C2ParamFieldValuesBuilder<T> &limitTo(const C2SupportedValueSet<T> &limit); 789 790 /** 791 * Restrict (and thus define) the supported values to a value set. 792 */ 793 C2ParamFieldValuesBuilder<T> &limitTo(const C2SupportedFlags<T> &limit); 794 795 /** 796 * Restrict (and thus define) the supported values to a range. 797 */ 798 C2ParamFieldValuesBuilder<T> &limitTo(const C2SupportedRange<T> &limit); 799 800 struct Impl; 801 std::unique_ptr<Impl> _mImpl; 802 }; 803 804 /** 805 * Builder for a list of setting conflicts. 806 */ 807 class C2SettingConflictsBuilder { 808 public: 809 /** 810 * Creates an empty list of setting conflicts. 811 */ 812 C2SettingConflictsBuilder(); 813 814 /** 815 * Creates a list containing a single setting conflict. 816 */ 817 C2SettingConflictsBuilder(C2ParamFieldValues &&conflict); 818 819 /** 820 * Adds a conflict to the current list of conflicts and returns this 821 */ 822 C2SettingConflictsBuilder& with(C2ParamFieldValues &&conflict); 823 824 /** 825 * Gets the current list of conflicts (and moves them out of this builder.) 826 * (this is why it is not const) 827 */ 828 std::vector<C2ParamFieldValues> retrieveConflicts(); 829 830 /** 831 * Returns whether the current list is empty. 832 */ 833 inline bool empty() const { return _mConflicts.empty(); } 834 835 inline operator bool() const { return empty(); } 836 837 private: 838 std::vector<C2ParamFieldValues> _mConflicts; 839 }; 840 841 /** 842 * Setting result builder for a parameter. 843 */ 844 struct C2SettingResultBuilder { 845 /** 846 * Creates a read-only setting result failure. 847 * 848 * This does not take FSV as only the current value of the field is supported. 849 */ 850 static C2SettingResult ReadOnly(const C2ParamField ¶m); 851 852 /** 853 * Creates a bad-value or infoinformational bad-value setting result failure. 854 * 855 * This does not take FSV as the value is outside of the possible values. As such, there are no 856 * conflicts for this case either. 857 */ 858 static C2SettingResult BadValue(const C2ParamField ¶mField, bool isInfo = false); 859 860 /** 861 * Creates a conflict (or informational conflict) setting result failure. 862 * 863 * This takes FSV so use paramFieldValues and optional conflicts. 864 */ 865 static C2SettingResult Conflict( 866 C2ParamFieldValues &¶mFieldValues, C2SettingConflictsBuilder &conflicts, 867 bool isInfo = false); 868 869 // TODO: retrieve results 870 871 872 private: 873 C2ParamField _mParamField; 874 C2SettingResult _mResult; 875 876 C2SettingResultBuilder(const C2SettingResultBuilder &) = delete; 877 }; 878 879 /** 880 * Setting results (PLURAL) builder. 881 * 882 * Setting results contain a failure status along with a list of failing fields or params. 883 */ 884 struct C2SettingResultsBuilder { 885 C2SettingResultsBuilder(const C2SettingResultsBuilder&) = delete; 886 C2SettingResultsBuilder(C2SettingResultsBuilder&&) = default; 887 C2SettingResultsBuilder &operator=(C2SettingResultsBuilder&&) = default; 888 889 /** \returns (default) successful result with no details. */ 890 inline static C2SettingResultsBuilder Ok() { 891 return C2SettingResultsBuilder(C2_OK); 892 } 893 894 /** \returns Interface is in bad state, with no further details. */ 895 inline static C2SettingResultsBuilder BadState() { 896 return C2SettingResultsBuilder(C2_BAD_STATE); 897 } 898 899 /** \returns Interface connection timed out, with no further details. */ 900 inline static C2SettingResultsBuilder TimedOut() { 901 return C2SettingResultsBuilder(C2_TIMED_OUT); 902 } 903 904 /** \returns Interface connection is corrupted, with no further details. */ 905 inline static C2SettingResultsBuilder Corrupted() { 906 return C2SettingResultsBuilder(C2_CORRUPTED); 907 } 908 909 inline static C2SettingResultsBuilder NoMemory(C2Param::Index index_ __unused) { 910 // TODO: try to add failure result 911 return C2SettingResultsBuilder(C2_NO_MEMORY); 912 } 913 914 // TODO: this should not be a constructor 915 /** Creates a builder with a single bad value setting result. */ 916 C2SettingResultsBuilder(C2SettingResult &&result); 917 918 /** Combines this results with other results. */ 919 C2SettingResultsBuilder plus(C2SettingResultsBuilder&& results); 920 921 /** Retrieve (get and move out) failures and return the failure status. */ 922 c2_status_t retrieveFailures(std::vector<std::unique_ptr<C2SettingResult>>* const failures); 923 924 private: 925 /** Setting results based on a single status. This is used when actual setting could not be 926 * attempted to get a single C2SettingResult, or when a setting succeeded without 927 * 'complaints'. */ 928 C2SettingResultsBuilder(c2_status_t status); 929 // status must be one of OK, BAD_STATE, TIMED_OUT, CORRUPTED or NO_MEMORY 930 // mainly: BLOCKING, BAD_INDEX, BAD_VALUE and NO_MEMORY requires a setting attempt, but 931 // NO_MEMORY may not allow us to create a results structure. 932 933 /** 934 * One of OK, BAD_INDEX, BAD_VALUE, BAD_STATE, NO_MEMORY, TIMED_OUT, BLOCKING or CORRUPTED. 935 */ 936 c2_status_t _mStatus __unused; 937 938 /** 939 * Vector of individual setting result details. 940 */ 941 std::vector<std::unique_ptr<C2SettingResult>> _mResults; 942 }; 943 944 /** 945 * Utility class to enumerate fields of parameters. 946 */ 947 struct C2FieldUtils { 948 struct _Inspector; 949 950 /** 951 * An extended field descriptor object with structural information (lineage back to the root of 952 * the param). 953 */ 954 struct Info { 955 typedef C2FieldDescriptor::type_t type_t; ///< field type 956 typedef C2FieldDescriptor::NamedValuesType NamedValuesType; ///< named values list type 957 958 /// returns the name of the field 959 C2String name() const; 960 961 /// returns the type of this field 962 type_t type() const; 963 964 /** 965 * Returns the defined name-value pairings for this field. The returned reference is 966 * only valid during the validity of this object 967 */ 968 const NamedValuesType &namedValues() const; 969 970 /** 971 * The index of this field. E.g. param.field or param.field[0] has an index of 0, and 972 * param.struct[2].field[3] has an index of 3. 973 */ 974 size_t index() const; 975 976 /// returns the length of the field in case it is an array. Returns 0 for 977 /// T[] arrays if this info comes from a C2Param::Index object, and the currently used 978 /// extent if it comes from a C2Param object. Returns 1 for T[1] arrays as well as if the 979 /// field is not an array. 980 size_t extent() const; 981 982 /** 983 * The (structural) depth of this field. E.g. param.field or param.field[0] has a depth of 984 * 0, and param.struct.field or param.struct[0].field[0] has a depth of 1. 985 */ 986 size_t depth() const; 987 988 /** 989 * Returns the offset of this field in the parameter in bytes. 990 */ 991 size_t offset() const; 992 993 /** 994 * Returns the size of this field in bytes. 995 */ 996 size_t size() const; 997 998 /** 999 * The offset of this field's array. E.g. for param.struct[2].field[3] this is the offset 1000 * of its smallest sibling: param.struct[2].field[0]. 1001 */ 1002 size_t arrayOffset() const; 1003 1004 /** 1005 * Returns the size of this field's array. This is equivalent to extent() * size() 1006 */ 1007 size_t arraySize() const; 1008 1009 /** 1010 * The offset of the base field. The base field is a cousin of the current field where 1011 * all indices are 0. E.g. the the base field for param.struct[2].field[3] is 1012 * param.struct[0].field[0]. Base fields are used to specify supported values for 1013 * all cousin fields. 1014 */ 1015 size_t baseFieldOffset() const; 1016 1017 /** 1018 * Returns whether this field is an arithmetic (integral, counter or float) field. 1019 */ 1020 bool isArithmetic() const; 1021 1022 /** 1023 * Returns whether this field can have a flexible extent. extent() returns the current 1024 * extent. 1025 */ 1026 bool isFlexible() const; 1027 1028 /// returns whether this info is valid 1029 inline bool isValid() const { return _mImpl != nullptr; } 1030 1031 /// returns the info for the parent of this field, or an invalid Info object if it has no 1032 /// parents 1033 Info parent() const; 1034 1035 /// returns whether this info is valid 1036 inline operator bool() const { return isValid(); } 1037 1038 struct Impl; 1039 Info(std::shared_ptr<Impl>); 1040 1041 private: 1042 std::shared_ptr<Impl> _mImpl; 1043 friend struct _Inspector; 1044 }; 1045 1046 /** 1047 * An (input) iterator object over fields using Info objects. 1048 */ 1049 struct Iterator { 1050 typedef Info const value_type; 1051 typedef ptrdiff_t difference_type; 1052 typedef Info const * pointer; 1053 typedef Info const reference; 1054 typedef std::input_iterator_tag iterator_category; 1055 1056 /// return Info at current position 1057 virtual reference operator*() const; 1058 1059 /// move to the next field 1060 virtual Iterator& operator++(); 1061 1062 virtual bool operator==(const Iterator &) const; 1063 inline bool operator!=(const Iterator &other) const { return !operator==(other); } 1064 1065 virtual ~Iterator() = default; 1066 1067 struct Impl; 1068 Iterator(std::shared_ptr<Impl>); 1069 1070 protected: 1071 std::shared_ptr<Impl> mImpl; 1072 }; 1073 1074 /** 1075 * An (input) iterable object representing a list of fields. 1076 */ 1077 struct List { 1078 /// returns an iterator to the beginning of the list 1079 virtual Iterator begin() const; 1080 1081 /// returns an iterator to the end of the list 1082 virtual Iterator end() const; 1083 1084 virtual ~List() = default; 1085 1086 struct Impl; 1087 List(std::shared_ptr<Impl>); 1088 1089 protected: 1090 std::shared_ptr<Impl> mImpl; 1091 }; 1092 1093 /** 1094 * Enumerates all (base) fields at index 0 of the parameter. The order of iteration is the 1095 * following: 1096 * Fields of a structure are enumerated in field order. However, sub-fields of a structure 1097 * are enumerated directly after the structure field, and prior to sibling fields. 1098 * 1099 * In essence the order of enumeration is first by increasing offset, then by decreasing size. 1100 * 1101 * \param param parameter to enumerate its fields 1102 * \param reflector parameter reflector used for enumeration 1103 * 1104 * \return an iterable object 1105 */ 1106 static List enumerateFields( 1107 const C2Param ¶m, 1108 const std::shared_ptr<C2ParamReflector> &reflector); 1109 1110 /** 1111 * Enumerates all cousin fields up to depth - level for a field. If level is 0, it enumerates 1112 * only the field. For level 1, it enumerates all fields in its current array (which may be 1113 * itself if extent is 1). The order of iteration is by increasing field offset. 1114 */ 1115 static List enumerateCousins( 1116 const Info &field, 1117 uint32_t level = ~0); 1118 1119 /** 1120 * Locates the field in a parameter and returns a list of 2 elements - the most-specific field 1121 * array of the parameter that contains the entire field. If the field is not a valid field 1122 * specifier for this parameter (e.g. it is outside the bounds of the parameter), it returns 1123 * an empty list. 1124 */ 1125 static std::vector<Info> locateField( 1126 const C2Param ¶m, const _C2FieldId &field, 1127 const std::shared_ptr<C2ParamReflector> &reflector); 1128 1129 static std::vector<Info> locateField( 1130 const C2ParamField &pf, const std::shared_ptr<C2ParamReflector> &reflector); 1131 1132 }; 1133 1134 /** 1135 * Utility class for C2ComponentInterface 1136 */ 1137 struct C2InterfaceUtils { 1138 /** 1139 * Create traits from C2ComponentInterface. Note that rank cannot be queried from interfaces, 1140 * so left untouched. 1141 */ 1142 static bool FillTraitsFromInterface( 1143 C2Component::Traits *traits, 1144 const std::shared_ptr<C2ComponentInterface> &intf); 1145 }; 1146 1147 #include <util/C2Debug-interface.h> 1148 1149 #endif // C2UTILS_INTERFACE_UTILS_H_ 1150