这一节我们来看看简单参数的定义方式
1、C2SimpleValueStruct
Codec2框架提供了模板类C2SimpleValueStruct来帮助我们定义非灵活数组的简单参数。C2SimpleValueStruct的定义如下:
cpp
template<typename T>
struct C2SimpleValueStruct {
T value; ///< simple value of the structure
// Default constructor.
inline C2SimpleValueStruct() = default;
// Constructor with an initial value.
inline C2SimpleValueStruct(T value) : value(value) {}
DEFINE_BASE_C2STRUCT(SimpleValue)
};
宏展开后还是很简单:
cpp
template<typename T>
struct C2SimpleValueStruct {
T value; ///< simple value of the structure
// Default constructor.
inline C2SimpleValueStruct() = default;
// Constructor with an initial value.
inline C2SimpleValueStruct(T value) : value(value) {}
private:
const static std::vector<C2FieldDescriptor> _FIELD_LIST __unused;
public:
typedef C2SimpleValueStruct _type;
static const std::vector<C2FieldDescriptor> FieldList();
};
与复杂参数不一样的是,C2SimpleValueStruct是没有CORE_INDEX(BaseIndex)的。由于只有一个参数value,FieldList返回的C2FieldDescriptor列表只有一个元素。
cpp
template<typename T>
const std::vector<C2FieldDescriptor> C2SimpleValueStruct<T>::FieldList() {
return { DESCRIBE_C2FIELD(value, "value") };
}
框架帮我们预定义了一些常用的简单参数,其中混入了两个异类C2BlobValue和C2StringValue,它们是什么?
cpp
typedef C2SimpleValueStruct<int32_t> C2Int32Value;
typedef C2SimpleValueStruct<uint32_t> C2Uint32Value;
typedef C2SimpleValueStruct<int64_t> C2Int64Value;
typedef C2SimpleValueStruct<uint64_t> C2Uint64Value;
typedef C2SimpleValueStruct<float> C2FloatValue;
typedef C2SimpleValueStruct<uint8_t[]> C2BlobValue;
typedef C2SimpleValueStruct<char[]> C2StringValue;
C2SimpleValueStruct还提供了一个模板特化,传入的模板参数为数组时会使用此特化模板:
cpp
template<typename T>
struct C2SimpleValueStruct<T[]> {
static_assert(std::is_same<T, char>::value || std::is_same<T, uint8_t>::value,
"C2SimpleValueStruct<T[]> is only for BLOB or STRING");
T value[];
inline C2SimpleValueStruct() = default;
DEFINE_BASE_C2STRUCT(SimpleValue)
FLEX(C2SimpleValueStruct, value)
private:
inline C2SimpleValueStruct(size_t flexCount, const C2MemoryBlock<T> &block) {
_C2ValueArrayHelper::init(value, flexCount, block);
}
inline C2SimpleValueStruct(size_t flexCount, const std::initializer_list<T> &init) {
_C2ValueArrayHelper::init(value, flexCount, init);
}
inline C2SimpleValueStruct(size_t flexCount, const std::vector<T> &init) {
_C2ValueArrayHelper::init(value, flexCount, init);
}
template<unsigned N>
inline C2SimpleValueStruct(size_t flexCount, const T(&init)[N]) {
_C2ValueArrayHelper::init(value, flexCount, init);
}
};
是不是所有类型的数组都能用此特化模板呢?答案是否定的,模板中有个静态断言来检查传入的模板类型是否是char或者uint8_t,如果不是将抛出error。也就是说这个模板特化是专为char数组和uint8_t数组定义的。
将模板中宏展开:
cpp
template<typename T>
struct C2SimpleValueStruct<T[]> {
static_assert(std::is_same<T, char>::value || std::is_same<T, uint8_t>::value,
"C2SimpleValueStruct<T[]> is only for BLOB or STRING");
T value[];
inline C2SimpleValueStruct() = default;
private:
const static std::vector<C2FieldDescriptor> _FIELD_LIST __unused;
public:
typedef C2SimpleValueStruct _type;
static const std::vector<C2FieldDescriptor> FieldList();
C2_DO_NOT_COPY(C2SimpleValueStruct)
private:
C2PARAM_MAKE_FRIENDS
template<typename, typename> friend struct _C2FlexHelper;
public:
typedef decltype(value) _FlexMemberType;
inline C2SimpleValueStruct(size_t) : C2SimpleValueStruct() {}
typedef typename _C2FlexHelper<_FlexMemberType>::FlexType FlexType;
static_assert(
!std::is_void<FlexType>::value,
"member is not flexible, or a flexible array of a flexible type");
enum : uint32_t { FLEX_SIZE = _C2FlexHelper<_FlexMemberType>::FLEX_SIZE };
private:
inline C2SimpleValueStruct(size_t flexCount, const C2MemoryBlock<T> &block) {
_C2ValueArrayHelper::init(value, flexCount, block);
}
inline C2SimpleValueStruct(size_t flexCount, const std::initializer_list<T> &init) {
_C2ValueArrayHelper::init(value, flexCount, init);
}
inline C2SimpleValueStruct(size_t flexCount, const std::vector<T> &init) {
_C2ValueArrayHelper::init(value, flexCount, init);
}
template<unsigned N>
inline C2SimpleValueStruct(size_t flexCount, const T(&init)[N]) {
_C2ValueArrayHelper::init(value, flexCount, init);
}
};
FieldList不是由宏提供的,代码实现位于C2ParamDef.h最后:
cpp
template<typename T>
const std::vector<C2FieldDescriptor> C2SimpleValueStruct<T[]>::FieldList() {
return { DESCRIBE_C2FIELD(value, "value") };
}