1150 lines
37 KiB
C++
1150 lines
37 KiB
C++
/*
|
|
* Copyright (C) 2018 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef C2UTILS_INTERFACE_UTILS_H_
|
|
#define C2UTILS_INTERFACE_UTILS_H_
|
|
|
|
#include <C2Component.h>
|
|
#include <C2Param.h>
|
|
#include <C2Work.h>
|
|
|
|
#include <cmath>
|
|
#include <iterator>
|
|
#include <limits>
|
|
#include <type_traits>
|
|
|
|
/**
|
|
* Helper class to map underlying types to C2Value types as well as to print field values. This is
|
|
* generally the same as simply the underlying type except for characters (STRING) and bytes (BLOB).
|
|
*/
|
|
template<typename T>
|
|
struct C2_HIDE _C2FieldValueHelper {
|
|
typedef T ValueType;
|
|
inline static std::ostream& put(std::ostream &os, const C2Value::Primitive &p) {
|
|
return os << p.ref<T>();
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct C2_HIDE _C2FieldValueHelper<uint8_t> {
|
|
typedef uint32_t ValueType;
|
|
static std::ostream& put(std::ostream &os, const C2Value::Primitive &p);
|
|
};
|
|
|
|
template<>
|
|
struct C2_HIDE _C2FieldValueHelper<char> {
|
|
typedef int32_t ValueType;
|
|
static std::ostream& put(std::ostream &os, const C2Value::Primitive &p);
|
|
};
|
|
|
|
/**
|
|
* Supported value range utility for a field of a given type.
|
|
*
|
|
* This mimics C2FieldSupportedValue for RANGE type.
|
|
*/
|
|
template<typename T>
|
|
class C2SupportedRange {
|
|
typedef typename _C2FieldValueHelper<T>::ValueType ValueType;
|
|
|
|
//private:
|
|
constexpr static T MIN_VALUE = std::numeric_limits<T>::min();
|
|
constexpr static T MAX_VALUE = std::numeric_limits<T>::max();
|
|
constexpr static T MIN_STEP = std::is_floating_point<T>::value ? 0 : 1;
|
|
|
|
public:
|
|
/**
|
|
* Constructs an empty range with no supported values.
|
|
*
|
|
* \note This is a specializated supported range representation that is only used for
|
|
* this object - it is equivalent to the EMPTY type in C2FieldSupportedValues.
|
|
*/
|
|
inline static constexpr C2SupportedRange<T> None() {
|
|
return C2SupportedRange(MAX_VALUE, MIN_VALUE);
|
|
}
|
|
|
|
/**
|
|
* Constructs a range with all values supported.
|
|
*/
|
|
inline static constexpr C2SupportedRange<T> Any() {
|
|
return C2SupportedRange(MIN_VALUE, MAX_VALUE);
|
|
}
|
|
|
|
/**
|
|
* Constructs a range with a single supported value.
|
|
*
|
|
* \param value the sole supported value
|
|
*/
|
|
inline static constexpr C2SupportedRange<T> EqualTo(T value) {
|
|
return C2SupportedRange(value, value);
|
|
}
|
|
|
|
/**
|
|
* Constructs a range with supported values greater than a given value.
|
|
*
|
|
* \param value the given value
|
|
*/
|
|
inline static C2SupportedRange<T> GreaterThan(T value) {
|
|
return (value == MAX_VALUE ? None() :
|
|
std::is_floating_point<T>::value ?
|
|
C2SupportedRange(std::nextafter(value, MAX_VALUE), MAX_VALUE) :
|
|
C2SupportedRange(value + MIN_STEP, MAX_VALUE));
|
|
}
|
|
|
|
/**
|
|
* Constructs a range with supported values greater than or equal to a given value.
|
|
*
|
|
* \param value the given value
|
|
*/
|
|
inline static constexpr C2SupportedRange<T> GreaterThanOrEqualTo(T value) {
|
|
return C2SupportedRange(value, MAX_VALUE);
|
|
}
|
|
|
|
/**
|
|
* Constructs a range with supported values greater than or equal to (aka not less than) a given
|
|
* value.
|
|
*
|
|
* \param value the given value
|
|
*/
|
|
inline static constexpr C2SupportedRange<T> NotLessThan(T value) {
|
|
return GreaterThanOrEqualTo(value);
|
|
}
|
|
|
|
/**
|
|
* Constructs a range with supported values less than or equal to a given value.
|
|
*
|
|
* \param value the given value
|
|
*/
|
|
inline static constexpr C2SupportedRange<T> LessThanOrEqualTo(T value) {
|
|
return C2SupportedRange(MIN_VALUE, value);
|
|
}
|
|
|
|
/**
|
|
* Constructs a range with supported values less than or equal to (aka not greater than) a given
|
|
* value.
|
|
*
|
|
* \param value the given value
|
|
*/
|
|
inline static constexpr C2SupportedRange<T> NotGreaterThan(T value) {
|
|
return LessThanOrEqualTo(value);
|
|
}
|
|
|
|
/**
|
|
* Constructs a range with supported values less than a given value.
|
|
*
|
|
* \param value the given value
|
|
*/
|
|
inline static C2SupportedRange<T> LessThan(T value) {
|
|
return (value == MIN_VALUE ? None() :
|
|
std::is_floating_point<T>::value ?
|
|
C2SupportedRange(MIN_VALUE, std::nextafter(value, MIN_VALUE)) :
|
|
C2SupportedRange(MIN_VALUE, value - MIN_STEP));
|
|
}
|
|
|
|
/**
|
|
* Constructs a continuous or arithmetic range between two values.
|
|
*
|
|
* \param min the lower value
|
|
* \param max the higher value (if this is lower than |min| the range will be empty)
|
|
* \param step the step of the arithmetic range. (If this is 0 for floating point types or 1 for
|
|
* integer types, the constructed range is continuous)
|
|
*/
|
|
inline static constexpr
|
|
C2SupportedRange<T> InRange(T min, T max, T step = MIN_STEP) {
|
|
return C2SupportedRange(min, max, step);
|
|
}
|
|
|
|
/**
|
|
* Constructs a range over a geometric series between two values.
|
|
*
|
|
* \param min the lower bound of the range. This value is always part of the constructed range
|
|
* as long as it is not greater than |max|.
|
|
* \param max the upper bound of the range. This value is only part of the constructed
|
|
* range if it is part of the geometric series.
|
|
* \param num the numerator of the geometric series.
|
|
* \param denom the denominator of the geometric series.
|
|
*/
|
|
inline static constexpr
|
|
C2SupportedRange<T> InSeries(T min, T max, T num, T denom) {
|
|
return C2SupportedRange(min, max, 0, num, denom);
|
|
}
|
|
|
|
/**
|
|
* Constructs a range over a multiply-accumulate series between two values.
|
|
*
|
|
* \param min the lower bound of the range. This value is always part of the constructed range
|
|
* as long as it is not greater than |max|.
|
|
* \param max the upper bound of the range. This value is only part of the constructed
|
|
* range if it is part of the series.
|
|
* \param step the accumulator of the multiply-accumulate series
|
|
* \param num the numerator of the multiply-accumulate series.
|
|
* \param denom the denominator of the multiply-accumulate series.
|
|
*/
|
|
inline static constexpr
|
|
C2SupportedRange<T> InMacSeries(T min, T max, T step, T num, T denom) {
|
|
return C2SupportedRange(min, max, step, num, denom);
|
|
}
|
|
|
|
/**
|
|
* Constructs a range from a generic C2FieldSupportedValues object. This will be an empty
|
|
* range if the supported values are not of RANGE type.
|
|
*
|
|
* \param values the supported values object
|
|
*/
|
|
C2SupportedRange(const C2FieldSupportedValues &values);
|
|
|
|
/**
|
|
* Returns whether this range is empty.
|
|
*/
|
|
inline constexpr bool isEmpty() const {
|
|
return _mMin > _mMax;
|
|
}
|
|
|
|
/**
|
|
* Returns whether this range is valid.
|
|
*
|
|
* Ranges are valid if they are continuous or monotonic.
|
|
*/
|
|
inline constexpr bool isValid() const {
|
|
// TODO: handle overflow or negative series
|
|
return _mDenom > 0 && _mNum >= _mDenom && _mMin * (_mDenom - _mNum) < _mStep * _mDenom;
|
|
}
|
|
|
|
/**
|
|
* Returns whether a value is part of this range.
|
|
*
|
|
* \param value the value to check.
|
|
*/
|
|
bool contains(T value) const;
|
|
|
|
/**
|
|
* Returns a new range that is the intersection of this range and another, if it is
|
|
* representable as a range object.
|
|
*
|
|
* \param limit the other range
|
|
*/
|
|
C2SupportedRange<T> limitedTo(const C2SupportedRange<T> &limit) const;
|
|
|
|
/**
|
|
* Converts this object to a C2FieldSupportedValues object.
|
|
*/
|
|
inline operator C2FieldSupportedValues() const {
|
|
return C2FieldSupportedValues(_mMin, _mMax, _mStep, _mNum, _mDenom);
|
|
}
|
|
|
|
/**
|
|
* Returns the lower bound and starting point of this range.
|
|
*/
|
|
inline C2_HIDE constexpr T min() const { return _mMin; }
|
|
|
|
/**
|
|
* Returns the upper bound of this range.
|
|
*/
|
|
inline C2_HIDE constexpr T max() const { return _mMax; }
|
|
|
|
/**
|
|
* Returns the step of this range.
|
|
*/
|
|
inline C2_HIDE constexpr T step() const { return _mStep; }
|
|
|
|
/**
|
|
* Returns the numerator of this range.
|
|
*/
|
|
inline C2_HIDE constexpr T num() const { return _mNum; }
|
|
|
|
/**
|
|
* Returns the denominator of this range.
|
|
*/
|
|
inline C2_HIDE constexpr T denom() const { return _mDenom; }
|
|
|
|
private:
|
|
/**
|
|
* Returns whether x[i...] is all values between _mMin and _mMax.
|
|
*/
|
|
inline C2_HIDE constexpr bool isSimpleRange() const {
|
|
return _mStep == MIN_STEP && _mNum == 1 && _mDenom == 1;
|
|
}
|
|
|
|
/**
|
|
* Returns whether x[i...] is defined as such:
|
|
* x[i + 1] = x[i] + _mStep, where _mStep > 0 and _mMin <= x[i] <= _mMax
|
|
*/
|
|
inline C2_HIDE constexpr bool isArithmeticSeries() const {
|
|
return _mStep > MIN_STEP && _mNum == 1 && _mDenom == 1;
|
|
}
|
|
|
|
/**
|
|
* Returns whether x[i...] is defined as such:
|
|
* x[i] = x[0] * (_mNum / _mDenom) ^ i (with rounding), where _mNum > _mDenom > 0 and x[0] > 0
|
|
*/
|
|
inline C2_HIDE constexpr bool isGeometricSeries() const {
|
|
return _mMin > 0 && _mStep == 0 && _mNum > _mDenom && _mDenom > 0;
|
|
}
|
|
|
|
/**
|
|
* Returns whether x[i...] is defined as such:
|
|
* x[i + 1] = x[i] * _mNum / _mDenom + _mStep (with rounding), while x[i + 1] > x[i], where
|
|
* _mStep != 0, _mDenom > 0 and _mNum > 0
|
|
*/
|
|
inline C2_HIDE constexpr bool isMacSeries() const {
|
|
return _mStep != 0 && _mNum > 0 && _mDenom > 0;
|
|
}
|
|
|
|
/**
|
|
* Constructs an arithmetic or continuous range.
|
|
*
|
|
* \param min the lower value
|
|
* \param max the higher value (if this is lower than |min| the range will be empty)
|
|
* \param step the step of the arithmetic range. (If this is 0 for floating point types or 1 for
|
|
* integer types, the constructed range is continuous)
|
|
*/
|
|
constexpr C2_HIDE C2SupportedRange(T min, T max, T step = T(std::is_floating_point<T>::value ? 0 : 1))
|
|
: _mMin(min), _mMax(max), _mStep(step), _mNum(1), _mDenom(1) { }
|
|
|
|
/**
|
|
* Constructs a range over a geomertic sor multiply-accumulate series.
|
|
*
|
|
* \param min the lower bound of the range. This value is always part of the constructed range
|
|
* as long as it is not greater than |max|.
|
|
* \param max the upper bound of the range. This value is only part of the constructed
|
|
* range if it is part of the geometric series.
|
|
* \param step the accumulator of the multiply-accumulate series. This is 0 for a pure geometric
|
|
* series
|
|
* \param num the numerator of the geometric series.
|
|
* \param denom the denominator of the geometric series.
|
|
*/
|
|
constexpr C2_HIDE C2SupportedRange(T min, T max, T step, T num, T den)
|
|
: _mMin(min), _mMax(max), _mStep(step), _mNum(num), _mDenom(den) { }
|
|
|
|
T _mMin; ///< lower bound and starting point
|
|
T _mMax; ///< upper bound
|
|
T _mStep; ///< step of an arithmetic series (0 if continuous floating point range)
|
|
T _mNum; ///< numerator of a geometric series
|
|
T _mDenom; ///< denominator of a geometric series
|
|
};
|
|
|
|
/**
|
|
* Ordered supported flag set for a field of a given type.
|
|
*/
|
|
template<typename T>
|
|
class C2SupportedFlags {
|
|
typedef typename _C2FieldValueHelper<T>::ValueType ValueType;
|
|
|
|
public:
|
|
/**
|
|
* Constructs an empty flag set.
|
|
*
|
|
* \note This is a specializated supported flags representation that is only used for
|
|
* this object - it is equivalent to the EMPTY type in C2FieldSupportedValues.
|
|
*/
|
|
static inline C2SupportedFlags<T> None() {
|
|
return C2SupportedFlags(std::initializer_list<C2Value::Primitive>());
|
|
}
|
|
|
|
/**
|
|
* Constructs a flags set of given flags.
|
|
*
|
|
* \param flags the ordered set of flags as an initializer list.
|
|
* \param min minimum set of flags to be set.
|
|
*/
|
|
static inline C2SupportedFlags<T> Flags(const std::initializer_list<T> flags, T min = T(0)) {
|
|
return C2SupportedFlags(min, flags);
|
|
}
|
|
|
|
/**
|
|
* Constructs a flags set of given flags.
|
|
*
|
|
* \param flags the ordered set of flags.
|
|
* \param min minimum set of flags to be set.
|
|
*/
|
|
static inline C2SupportedFlags<T> Flags(const std::vector<T> &flags, T min = T(0)) {
|
|
return C2SupportedFlags(min, flags);
|
|
}
|
|
|
|
/**
|
|
* Constructs a flag set from a generic C2FieldSupportedValues object. This will be an empty
|
|
* set if the supported values are not of FLAGS type.
|
|
*
|
|
* \param values the supported values object
|
|
*/
|
|
C2SupportedFlags<T>(const C2FieldSupportedValues &values) {
|
|
if (values.type == C2FieldSupportedValues::FLAGS) {
|
|
_mValues.insert(_mValues.end(), values.values.begin(), values.values.end());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns whether this set is empty.
|
|
*/
|
|
constexpr bool isEmpty() const {
|
|
return _mValues.empty();
|
|
}
|
|
|
|
/**
|
|
* Returns whether a value is part of this set.
|
|
*
|
|
* \param value the value to check.
|
|
*/
|
|
bool contains(T value) const;
|
|
|
|
/**
|
|
* Returns a new flag set that is the intersection of this set and another.
|
|
*
|
|
* \param limit the other value set
|
|
*/
|
|
C2SupportedFlags<T> limitedTo(const C2SupportedFlags<T> &limit) const;
|
|
|
|
/**
|
|
* Converts this object to a C2FieldSupportedValues object.
|
|
*/
|
|
operator C2FieldSupportedValues() const {
|
|
return C2FieldSupportedValues(!isEmpty() /* flags */, _mValues);
|
|
}
|
|
|
|
/**
|
|
* Returns the ordered set of flags of this object.
|
|
*/
|
|
const std::vector<T> flags() const;
|
|
|
|
/**
|
|
* Returns the minimum set of flags for this object.
|
|
*/
|
|
T min() const;
|
|
|
|
/**
|
|
* Clears this supported value set.
|
|
*/
|
|
inline void clear() {
|
|
_mValues.clear();
|
|
}
|
|
|
|
private:
|
|
/**
|
|
* Constructs a flag set directly from an internal representation.
|
|
*
|
|
* \param values a vector containing the minimum flag set followed by the set of flags
|
|
*/
|
|
C2SupportedFlags(std::vector<C2Value::Primitive> &&values)
|
|
: _mValues(values) {
|
|
}
|
|
|
|
/**
|
|
* Constructs a flag set from a set of flags and a minimum flag set.
|
|
*
|
|
* \param flags the set
|
|
*/
|
|
C2SupportedFlags(T min, const std::vector<T> &flags) {
|
|
_mValues.emplace_back(min);
|
|
for (T elem : flags) {
|
|
_mValues.emplace_back(elem);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Constructs a flag set from a set of initializer list values and a minimum flag set
|
|
*
|
|
* \param flags the set
|
|
*/
|
|
C2SupportedFlags(T min, const std::initializer_list<T> flags) {
|
|
_mValues.emplace_back(min);
|
|
for (T elem : flags) {
|
|
_mValues.emplace_back(elem);
|
|
}
|
|
}
|
|
|
|
std::vector<C2Value::Primitive> _mValues; ///< the minimum flag set followed by the set of flags
|
|
};
|
|
|
|
/**
|
|
* Ordered supported value set for a field of a given type.
|
|
*/
|
|
template<typename T>
|
|
class C2SupportedValueSet {
|
|
typedef typename _C2FieldValueHelper<T>::ValueType ValueType;
|
|
|
|
public:
|
|
/**
|
|
* Constructs an empty value set.
|
|
*
|
|
* \note This is a specializated supported range representation that is only used for
|
|
* this object - it is equivalent to the EMPTY type in C2FieldSupportedValues.
|
|
*/
|
|
static inline C2SupportedValueSet<T> None() {
|
|
return C2SupportedValueSet({ });
|
|
}
|
|
|
|
/**
|
|
* Constructs a value set of given values.
|
|
*
|
|
* \param values the ordered set of values as an initializer list.
|
|
*/
|
|
static inline C2SupportedValueSet<T> OneOf(const std::initializer_list<T> values) {
|
|
return C2SupportedValueSet(values);
|
|
}
|
|
|
|
/**
|
|
* Constructs a value set of given values.
|
|
*
|
|
* \param values the ordered set of values.
|
|
*/
|
|
static inline C2SupportedValueSet<T> OneOf(const std::vector<T> &values) {
|
|
return C2SupportedValueSet(values);
|
|
}
|
|
|
|
/**
|
|
* Constructs a value set from a generic C2FieldSupportedValues object. This will be an empty
|
|
* set if the supported values are not of VALUES type.
|
|
*
|
|
* \param values the supported values object
|
|
*/
|
|
C2SupportedValueSet<T>(const C2FieldSupportedValues &values) {
|
|
if (values.type == C2FieldSupportedValues::VALUES) {
|
|
_mValues.insert(_mValues.end(), values.values.begin(), values.values.end());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns whether this range is empty.
|
|
*/
|
|
constexpr bool isEmpty() const {
|
|
return _mValues.empty();
|
|
}
|
|
|
|
/**
|
|
* Returns whether a value is part of this set.
|
|
*
|
|
* \param value the value to check.
|
|
*/
|
|
bool contains(T value) const;
|
|
|
|
/**
|
|
* Returns a new value set that is the intersection of this set and another.
|
|
*
|
|
* \param limit the other value set
|
|
*/
|
|
C2SupportedValueSet<T> limitedTo(const C2SupportedValueSet<T> &limit) const;
|
|
|
|
/**
|
|
* Returns a new value set that is the intersection of this set and a value range.
|
|
*
|
|
* \param limit the other range
|
|
*/
|
|
C2SupportedValueSet<T> limitedTo(const C2SupportedRange<T> &limit) const;
|
|
|
|
/**
|
|
* Returns a new value set that is the intersection of this set and a flag set.
|
|
*
|
|
* \param limit the other flag set
|
|
*/
|
|
C2SupportedValueSet<T> limitedTo(const C2SupportedFlags<T> &limit) const;
|
|
|
|
/**
|
|
* Converts this object to a C2FieldSupportedValues object.
|
|
*/
|
|
operator C2FieldSupportedValues() const {
|
|
return C2FieldSupportedValues(false /* flags */, _mValues);
|
|
}
|
|
|
|
/**
|
|
* Returns the ordered set of values of this object.
|
|
*/
|
|
const std::vector<T> values() const;
|
|
|
|
/**
|
|
* Clears this supported value set.
|
|
*/
|
|
inline void clear() {
|
|
_mValues.clear();
|
|
}
|
|
|
|
private:
|
|
/**
|
|
* Constructs a value set from a set of C2Value::Primitive values.
|
|
*
|
|
* \param values the set
|
|
*/
|
|
C2SupportedValueSet(std::vector<C2Value::Primitive> &&values)
|
|
: _mValues(values) {
|
|
}
|
|
|
|
/**
|
|
* Constructs a value set from a set of values.
|
|
*
|
|
* \param values the set
|
|
*/
|
|
C2SupportedValueSet(const std::vector<T> &values) {
|
|
for (T elem : values) {
|
|
_mValues.emplace_back(elem);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Constructs a value set from a set of initializer list values
|
|
*
|
|
* \param values the set
|
|
*/
|
|
C2SupportedValueSet(const std::initializer_list<T> values) {
|
|
for (T elem : values) {
|
|
_mValues.emplace_back(elem);
|
|
}
|
|
}
|
|
|
|
std::vector<C2Value::Primitive> _mValues; ///< the supported set of values
|
|
};
|
|
|
|
/**
|
|
* Helper class to handle C2FieldSupporteValues object for fields of various types.
|
|
*/
|
|
template<typename T>
|
|
class C2FieldSupportedValuesHelper;
|
|
|
|
// templated operator must be predeclared for friend declaration
|
|
template<typename T>
|
|
std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<T> &i);
|
|
|
|
template<typename T>
|
|
class C2FieldSupportedValuesHelper {
|
|
public:
|
|
/**
|
|
* Creates a helper for a specific type from a generic C2FieldSupportedValues struct.
|
|
*/
|
|
C2FieldSupportedValuesHelper(const C2FieldSupportedValues &values);
|
|
|
|
// TRICKY: needed for std::unique_ptr<Impl> declaration
|
|
~C2FieldSupportedValuesHelper();
|
|
|
|
// support copy constructor/operator
|
|
C2FieldSupportedValuesHelper(const C2FieldSupportedValuesHelper &);
|
|
C2FieldSupportedValuesHelper& operator=(const C2FieldSupportedValuesHelper &);
|
|
|
|
bool supports(T value) const;
|
|
|
|
private:
|
|
// use pimpl as implementation may change in the future
|
|
struct Impl;
|
|
std::unique_ptr<Impl> _mImpl;
|
|
|
|
friend std::ostream& operator<< <T>(std::ostream& os, const C2FieldSupportedValuesHelper<T> &i);
|
|
//friend std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper &i);
|
|
};
|
|
|
|
/**
|
|
* Builder for supported values for a field of a given type.
|
|
*
|
|
* This builder can be used to successively restrict the supported values for a field. Upon
|
|
* creation, there are no supported values specified - which for this builder means that all
|
|
* values are supported.
|
|
*/
|
|
template<typename T>
|
|
class C2ParamFieldValuesBuilder {
|
|
public:
|
|
/**
|
|
* Creates a builder with no defined values - but implicitly any value allowed.
|
|
*/
|
|
C2ParamFieldValuesBuilder(const C2ParamField &field);
|
|
|
|
/**
|
|
* Get C2ParamFieldValues from this builder.
|
|
*/
|
|
operator C2ParamFieldValues() const;
|
|
|
|
/**
|
|
* Define the supported values as the currently supported values of this builder.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &any();
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to none.
|
|
*
|
|
* \note This really should not be used from the builder as all params must have supported
|
|
* values, but is here in case this is really the case.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &none();
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to |value| alone.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &equalTo(T value);
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to values greater than |value|.
|
|
*/
|
|
inline C2ParamFieldValuesBuilder<T> &greaterThan(T value) {
|
|
return limitTo(C2SupportedRange<T>::GreaterThan(value));
|
|
}
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to values greater than or equal to |value|.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &greaterThanOrEqualTo(T value) {
|
|
return limitTo(C2SupportedRange<T>::GreaterThanOrEqualTo(value));
|
|
}
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to values greater than or equal to |value|.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> ¬LessThan(T value) {
|
|
return limitTo(C2SupportedRange<T>::NotLessThan(value));
|
|
}
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to values less than or equal to |value|.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &lessThanOrEqualTo(T value) {
|
|
return limitTo(C2SupportedRange<T>::LessThanOrEqualTo(value));
|
|
}
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to values less than or equal to |value|.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> ¬GreaterThan(T value) {
|
|
return limitTo(C2SupportedRange<T>::NotGreaterThan(value));
|
|
}
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to values less than |value|.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &lessThan(T value) {
|
|
return limitTo(C2SupportedRange<T>::LessThan(value));
|
|
}
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to values in the range of [ |min|, |max| ]
|
|
* with optional |step|.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &inRange(
|
|
T min, T max, T step = std::is_floating_point<T>::value ? T(0) : T(1)) {
|
|
return limitTo(C2SupportedRange<T>::InRange(min, max, step));
|
|
}
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to values in the geometric series starting
|
|
* from |min| with factor |num| / |denom|, not greater than |max|.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &inSeries(T min, T max, T num, T denom) {
|
|
return limitTo(C2SupportedRange<T>::InSeries(min, max, num, denom));
|
|
}
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to values in the multiply-accumulate series
|
|
* starting from |min| with factor |num| / |denom| and |step|, not greater than |max|.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &inMacSeries(T min, T max, T step, T num, T denom) {
|
|
return limitTo(C2SupportedRange<T>::InMacSeries(min, max, step, num, denom));
|
|
}
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to values in |values|.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &oneOf(const std::initializer_list<T> values) {
|
|
return limitTo(C2SupportedValueSet<T>::OneOf(values));
|
|
}
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to values in |values|.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &oneOf(const std::vector<T> &values) {
|
|
return limitTo(C2SupportedValueSet<T>::OneOf(values));
|
|
}
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to flags in |flags| with at least |min|
|
|
* set.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &flags(const std::vector<T> &flags, T min = T(0)) {
|
|
return limitTo(C2SupportedFlags<T>::Flags(flags, min));
|
|
}
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to flags in |values| with at least |min|
|
|
* set.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &flags(const std::initializer_list<T> flags, T min = T(0)) {
|
|
return limitTo(C2SupportedFlags<T>::Flags(flags, min));
|
|
}
|
|
|
|
virtual ~C2ParamFieldValuesBuilder();
|
|
|
|
// support copy constructor/operator
|
|
C2ParamFieldValuesBuilder(const C2ParamFieldValuesBuilder &);
|
|
C2ParamFieldValuesBuilder& operator=(const C2ParamFieldValuesBuilder &);
|
|
|
|
private:
|
|
/**
|
|
* Restrict (and thus define) the supported values to a value set.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &limitTo(const C2SupportedValueSet<T> &limit);
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to a value set.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &limitTo(const C2SupportedFlags<T> &limit);
|
|
|
|
/**
|
|
* Restrict (and thus define) the supported values to a range.
|
|
*/
|
|
C2ParamFieldValuesBuilder<T> &limitTo(const C2SupportedRange<T> &limit);
|
|
|
|
struct Impl;
|
|
std::unique_ptr<Impl> _mImpl;
|
|
};
|
|
|
|
/**
|
|
* Builder for a list of setting conflicts.
|
|
*/
|
|
class C2SettingConflictsBuilder {
|
|
public:
|
|
/**
|
|
* Creates an empty list of setting conflicts.
|
|
*/
|
|
C2SettingConflictsBuilder();
|
|
|
|
/**
|
|
* Creates a list containing a single setting conflict.
|
|
*/
|
|
C2SettingConflictsBuilder(C2ParamFieldValues &&conflict);
|
|
|
|
/**
|
|
* Adds a conflict to the current list of conflicts and returns this
|
|
*/
|
|
C2SettingConflictsBuilder& with(C2ParamFieldValues &&conflict);
|
|
|
|
/**
|
|
* Gets the current list of conflicts (and moves them out of this builder.)
|
|
* (this is why it is not const)
|
|
*/
|
|
std::vector<C2ParamFieldValues> retrieveConflicts();
|
|
|
|
/**
|
|
* Returns whether the current list is empty.
|
|
*/
|
|
inline bool empty() const { return _mConflicts.empty(); }
|
|
|
|
inline operator bool() const { return empty(); }
|
|
|
|
private:
|
|
std::vector<C2ParamFieldValues> _mConflicts;
|
|
};
|
|
|
|
/**
|
|
* Setting result builder for a parameter.
|
|
*/
|
|
struct C2SettingResultBuilder {
|
|
/**
|
|
* Creates a read-only setting result failure.
|
|
*
|
|
* This does not take FSV as only the current value of the field is supported.
|
|
*/
|
|
static C2SettingResult ReadOnly(const C2ParamField ¶m);
|
|
|
|
/**
|
|
* Creates a bad-value or infoinformational bad-value setting result failure.
|
|
*
|
|
* This does not take FSV as the value is outside of the possible values. As such, there are no
|
|
* conflicts for this case either.
|
|
*/
|
|
static C2SettingResult BadValue(const C2ParamField ¶mField, bool isInfo = false);
|
|
|
|
/**
|
|
* Creates a conflict (or informational conflict) setting result failure.
|
|
*
|
|
* This takes FSV so use paramFieldValues and optional conflicts.
|
|
*/
|
|
static C2SettingResult Conflict(
|
|
C2ParamFieldValues &¶mFieldValues, C2SettingConflictsBuilder &conflicts,
|
|
bool isInfo = false);
|
|
|
|
// TODO: retrieve results
|
|
|
|
|
|
private:
|
|
C2ParamField _mParamField;
|
|
C2SettingResult _mResult;
|
|
|
|
C2SettingResultBuilder(const C2SettingResultBuilder &) = delete;
|
|
};
|
|
|
|
/**
|
|
* Setting results (PLURAL) builder.
|
|
*
|
|
* Setting results contain a failure status along with a list of failing fields or params.
|
|
*/
|
|
struct C2SettingResultsBuilder {
|
|
C2SettingResultsBuilder(const C2SettingResultsBuilder&) = delete;
|
|
C2SettingResultsBuilder(C2SettingResultsBuilder&&) = default;
|
|
C2SettingResultsBuilder &operator=(C2SettingResultsBuilder&&) = default;
|
|
|
|
/** \returns (default) successful result with no details. */
|
|
inline static C2SettingResultsBuilder Ok() {
|
|
return C2SettingResultsBuilder(C2_OK);
|
|
}
|
|
|
|
/** \returns Interface is in bad state, with no further details. */
|
|
inline static C2SettingResultsBuilder BadState() {
|
|
return C2SettingResultsBuilder(C2_BAD_STATE);
|
|
}
|
|
|
|
/** \returns Interface connection timed out, with no further details. */
|
|
inline static C2SettingResultsBuilder TimedOut() {
|
|
return C2SettingResultsBuilder(C2_TIMED_OUT);
|
|
}
|
|
|
|
/** \returns Interface connection is corrupted, with no further details. */
|
|
inline static C2SettingResultsBuilder Corrupted() {
|
|
return C2SettingResultsBuilder(C2_CORRUPTED);
|
|
}
|
|
|
|
inline static C2SettingResultsBuilder NoMemory(C2Param::Index index_ __unused) {
|
|
// TODO: try to add failure result
|
|
return C2SettingResultsBuilder(C2_NO_MEMORY);
|
|
}
|
|
|
|
// TODO: this should not be a constructor
|
|
/** Creates a builder with a single bad value setting result. */
|
|
C2SettingResultsBuilder(C2SettingResult &&result);
|
|
|
|
/** Combines this results with other results. */
|
|
C2SettingResultsBuilder plus(C2SettingResultsBuilder&& results);
|
|
|
|
/** Retrieve (get and move out) failures and return the failure status. */
|
|
c2_status_t retrieveFailures(std::vector<std::unique_ptr<C2SettingResult>>* const failures);
|
|
|
|
private:
|
|
/** Setting results based on a single status. This is used when actual setting could not be
|
|
* attempted to get a single C2SettingResult, or when a setting succeeded without
|
|
* 'complaints'. */
|
|
C2SettingResultsBuilder(c2_status_t status);
|
|
// status must be one of OK, BAD_STATE, TIMED_OUT, CORRUPTED or NO_MEMORY
|
|
// mainly: BLOCKING, BAD_INDEX, BAD_VALUE and NO_MEMORY requires a setting attempt, but
|
|
// NO_MEMORY may not allow us to create a results structure.
|
|
|
|
/**
|
|
* One of OK, BAD_INDEX, BAD_VALUE, BAD_STATE, NO_MEMORY, TIMED_OUT, BLOCKING or CORRUPTED.
|
|
*/
|
|
c2_status_t _mStatus __unused;
|
|
|
|
/**
|
|
* Vector of individual setting result details.
|
|
*/
|
|
std::vector<std::unique_ptr<C2SettingResult>> _mResults;
|
|
};
|
|
|
|
/**
|
|
* Utility class to enumerate fields of parameters.
|
|
*/
|
|
struct C2FieldUtils {
|
|
struct _Inspector;
|
|
|
|
/**
|
|
* An extended field descriptor object with structural information (lineage back to the root of
|
|
* the param).
|
|
*/
|
|
struct Info {
|
|
typedef C2FieldDescriptor::type_t type_t; ///< field type
|
|
typedef C2FieldDescriptor::NamedValuesType NamedValuesType; ///< named values list type
|
|
|
|
/// returns the name of the field
|
|
C2String name() const;
|
|
|
|
/// returns the type of this field
|
|
type_t type() const;
|
|
|
|
/**
|
|
* Returns the defined name-value pairings for this field. The returned reference is
|
|
* only valid during the validity of this object
|
|
*/
|
|
const NamedValuesType &namedValues() const;
|
|
|
|
/**
|
|
* The index of this field. E.g. param.field or param.field[0] has an index of 0, and
|
|
* param.struct[2].field[3] has an index of 3.
|
|
*/
|
|
size_t index() const;
|
|
|
|
/// returns the length of the field in case it is an array. Returns 0 for
|
|
/// T[] arrays if this info comes from a C2Param::Index object, and the currently used
|
|
/// extent if it comes from a C2Param object. Returns 1 for T[1] arrays as well as if the
|
|
/// field is not an array.
|
|
size_t extent() const;
|
|
|
|
/**
|
|
* The (structural) depth of this field. E.g. param.field or param.field[0] has a depth of
|
|
* 0, and param.struct.field or param.struct[0].field[0] has a depth of 1.
|
|
*/
|
|
size_t depth() const;
|
|
|
|
/**
|
|
* Returns the offset of this field in the parameter in bytes.
|
|
*/
|
|
size_t offset() const;
|
|
|
|
/**
|
|
* Returns the size of this field in bytes.
|
|
*/
|
|
size_t size() const;
|
|
|
|
/**
|
|
* The offset of this field's array. E.g. for param.struct[2].field[3] this is the offset
|
|
* of its smallest sibling: param.struct[2].field[0].
|
|
*/
|
|
size_t arrayOffset() const;
|
|
|
|
/**
|
|
* Returns the size of this field's array. This is equivalent to extent() * size()
|
|
*/
|
|
size_t arraySize() const;
|
|
|
|
/**
|
|
* The offset of the base field. The base field is a cousin of the current field where
|
|
* all indices are 0. E.g. the the base field for param.struct[2].field[3] is
|
|
* param.struct[0].field[0]. Base fields are used to specify supported values for
|
|
* all cousin fields.
|
|
*/
|
|
size_t baseFieldOffset() const;
|
|
|
|
/**
|
|
* Returns whether this field is an arithmetic (integral, counter or float) field.
|
|
*/
|
|
bool isArithmetic() const;
|
|
|
|
/**
|
|
* Returns whether this field can have a flexible extent. extent() returns the current
|
|
* extent.
|
|
*/
|
|
bool isFlexible() const;
|
|
|
|
/// returns whether this info is valid
|
|
inline bool isValid() const { return _mImpl != nullptr; }
|
|
|
|
/// returns the info for the parent of this field, or an invalid Info object if it has no
|
|
/// parents
|
|
Info parent() const;
|
|
|
|
/// returns whether this info is valid
|
|
inline operator bool() const { return isValid(); }
|
|
|
|
struct Impl;
|
|
Info(std::shared_ptr<Impl>);
|
|
|
|
private:
|
|
std::shared_ptr<Impl> _mImpl;
|
|
friend struct _Inspector;
|
|
};
|
|
|
|
/**
|
|
* An (input) iterator object over fields using Info objects.
|
|
*/
|
|
struct Iterator {
|
|
typedef Info const value_type;
|
|
typedef ptrdiff_t difference_type;
|
|
typedef Info const * pointer;
|
|
typedef Info const reference;
|
|
typedef std::input_iterator_tag iterator_category;
|
|
|
|
/// return Info at current position
|
|
virtual reference operator*() const;
|
|
|
|
/// move to the next field
|
|
virtual Iterator& operator++();
|
|
|
|
virtual bool operator==(const Iterator &) const;
|
|
inline bool operator!=(const Iterator &other) const { return !operator==(other); }
|
|
|
|
virtual ~Iterator() = default;
|
|
|
|
struct Impl;
|
|
Iterator(std::shared_ptr<Impl>);
|
|
|
|
protected:
|
|
std::shared_ptr<Impl> mImpl;
|
|
};
|
|
|
|
/**
|
|
* An (input) iterable object representing a list of fields.
|
|
*/
|
|
struct List {
|
|
/// returns an iterator to the beginning of the list
|
|
virtual Iterator begin() const;
|
|
|
|
/// returns an iterator to the end of the list
|
|
virtual Iterator end() const;
|
|
|
|
virtual ~List() = default;
|
|
|
|
struct Impl;
|
|
List(std::shared_ptr<Impl>);
|
|
|
|
protected:
|
|
std::shared_ptr<Impl> mImpl;
|
|
};
|
|
|
|
/**
|
|
* Enumerates all (base) fields at index 0 of the parameter. The order of iteration is the
|
|
* following:
|
|
* Fields of a structure are enumerated in field order. However, sub-fields of a structure
|
|
* are enumerated directly after the structure field, and prior to sibling fields.
|
|
*
|
|
* In essence the order of enumeration is first by increasing offset, then by decreasing size.
|
|
*
|
|
* \param param parameter to enumerate its fields
|
|
* \param reflector parameter reflector used for enumeration
|
|
*
|
|
* \return an iterable object
|
|
*/
|
|
static List enumerateFields(
|
|
const C2Param ¶m,
|
|
const std::shared_ptr<C2ParamReflector> &reflector);
|
|
|
|
/**
|
|
* Enumerates all cousin fields up to depth - level for a field. If level is 0, it enumerates
|
|
* only the field. For level 1, it enumerates all fields in its current array (which may be
|
|
* itself if extent is 1). The order of iteration is by increasing field offset.
|
|
*/
|
|
static List enumerateCousins(
|
|
const Info &field,
|
|
uint32_t level = ~0);
|
|
|
|
/**
|
|
* Locates the field in a parameter and returns a list of 2 elements - the most-specific field
|
|
* array of the parameter that contains the entire field. If the field is not a valid field
|
|
* specifier for this parameter (e.g. it is outside the bounds of the parameter), it returns
|
|
* an empty list.
|
|
*/
|
|
static std::vector<Info> locateField(
|
|
const C2Param ¶m, const _C2FieldId &field,
|
|
const std::shared_ptr<C2ParamReflector> &reflector);
|
|
|
|
static std::vector<Info> locateField(
|
|
const C2ParamField &pf, const std::shared_ptr<C2ParamReflector> &reflector);
|
|
|
|
};
|
|
|
|
/**
|
|
* Utility class for C2ComponentInterface
|
|
*/
|
|
struct C2InterfaceUtils {
|
|
/**
|
|
* Create traits from C2ComponentInterface. Note that rank cannot be queried from interfaces,
|
|
* so left untouched.
|
|
*/
|
|
static bool FillTraitsFromInterface(
|
|
C2Component::Traits *traits,
|
|
const std::shared_ptr<C2ComponentInterface> &intf);
|
|
};
|
|
|
|
#include <util/C2Debug-interface.h>
|
|
|
|
#endif // C2UTILS_INTERFACE_UTILS_H_
|