cxx: Implement more of EnumValue in template.

This commit is contained in:
Martin Ling 2014-10-29 14:31:31 +00:00 committed by Uwe Hermann
parent 3250d8c7e0
commit 9d229ecb9e
4 changed files with 41 additions and 36 deletions

View File

@ -400,7 +400,7 @@ bool Configurable::config_check(const ConfigKey *key,
for (gsize i = 0; i < num_opts; i++)
{
if ((opts[i] & SR_CONF_MASK) == key->id())
if ((opts[i] & SR_CONF_MASK) == (uint32_t) key->id())
{
g_variant_unref(gvar_opts);
return true;

View File

@ -73,33 +73,15 @@ for file in (header, code):
# Template for beginning of class declaration and public members.
header_public_template = """
/** {brief} */
class SR_API {classname} : public EnumValue<enum {enumname}>
class SR_API {classname} : public EnumValue<{classname}, enum {enumname}>
{{
public:
static const {classname} *get(int id);
"""
# Template for beginning of private members.
header_private_template = """
private:
static const std::map<enum {enumname}, const {classname} *> _values;
{classname}(enum {enumname} id, const char name[]);
"""
# Template for class method definitions.
code_template = """
{classname}::{classname}(enum {enumname} id, const char name[]) :
EnumValue<enum {enumname}>(id, name)
{{
}}
const {classname} *{classname}::get(int id)
{{
if (_values.find(static_cast<{enumname}>(id)) == _values.end())
throw Error(SR_ERR_ARG);
return {classname}::_values.at(static_cast<{enumname}>(id));
}}
protected:
{classname}(enum {enumname} id, const char name[]) : EnumValue(id, name) {{}}
"""
def get_text(node):
@ -141,10 +123,6 @@ for enum, (classname, classbrief) in classes.items():
# End class declaration
print >> header, '};'
# Begin class code
print >> code, code_template.format(
classname=classname, enumname=enum_name)
# Define private constants for each enum value
for name, trimmed_name in zip(member_names, trimmed_names):
print >> code, 'const %s %s::_%s = %s(%s, "%s");' % (
@ -156,8 +134,8 @@ for enum, (classname, classbrief) in classes.items():
classname, classname, trimmed_name, classname, trimmed_name)
# Define map of enum values to constants
print >> code, 'const std::map<enum %s, const %s *> %s::_values = {' % (
enum_name, classname, classname)
print >> code, 'template<> const std::map<const enum %s, const %s * const> EnumValue<%s, enum %s>::_values = {' % (
enum_name, classname, classname, enum_name)
for name, trimmed_name in zip(member_names, trimmed_names):
print >> code, '\t{%s, %s::%s},' % (name, classname, trimmed_name)
print >> code, '};'

View File

@ -935,17 +935,44 @@ protected:
};
/** Base class for objects which wrap an enumeration value from libsigrok */
template <typename T> class SR_API EnumValue
template <class Class, typename Enum> class SR_API EnumValue
{
public:
/** The enum constant associated with this value. */
T id() const { return _id; }
/** The integer constant associated with this value. */
int id() const
{
return static_cast<int>(_id);
}
/** The name associated with this value. */
string name() const { return _name; }
string name() const
{
return _name;
}
/** Get value associated with a given integer constant. */
static const Class *get(int id)
{
auto key = static_cast<Enum>(id);
if (_values.find(key) == _values.end())
throw Error(SR_ERR_ARG);
return _values.at(key);
}
/** Get possible values. */
static std::vector<const Class *> values()
{
std::vector<const Class *> result;
for (auto entry : _values)
result.push_back(entry.second);
return result;
}
protected:
EnumValue(T id, const char name[]) : _id(id), _name(name) {}
~EnumValue() {}
const T _id;
EnumValue(Enum id, const char name[]) : _id(id), _name(name)
{
}
~EnumValue()
{
}
static const std::map<const Enum, const Class * const> _values;
const Enum _id;
const string _name;
};

View File

@ -287,7 +287,7 @@ std::map<std::string, std::string> dict_to_map_string(PyObject *dict)
/* Convert from a Python type to Glib::Variant, according to config key data type. */
Glib::VariantBase python_to_variant_by_key(PyObject *input, const sigrok::ConfigKey *key)
{
enum sr_datatype type = key->data_type()->id();
enum sr_datatype type = (enum sr_datatype) key->data_type()->id();
if (type == SR_T_UINT64 && PyInt_Check(input))
return Glib::Variant<guint64>::create(PyInt_AsLong(input));