diff options
author | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2017-06-11 12:56:36 +0200 |
---|---|---|
committer | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2017-06-11 12:56:36 +0200 |
commit | be0177f8b8705a7df8c65feedda8ecda234dbd65 (patch) | |
tree | f0ac4d5b7d0a66e2fee3a326baa457c0302337cb /tools | |
parent | 53384fc8c4c1de4ca518052866fdd17311332468 (diff) | |
download | glibmm-be0177f8b8705a7df8c65feedda8ecda234dbd65.tar.gz |
gmmproc, _WRAP_ENUM: Add optional CONV_TO_INT parameter
CONV_TO_INT "Convertible to int": Generate a plain enum (not an enum class)
within a class. Such an enum is scoped like an enum class, and it can be
implicitly converted to int like a plain enum. Bug 86864
Diffstat (limited to 'tools')
-rw-r--r-- | tools/m4/enum.m4 | 101 | ||||
-rw-r--r-- | tools/pm/Output.pm | 17 | ||||
-rw-r--r-- | tools/pm/WrapParser.pm | 24 |
3 files changed, 82 insertions, 60 deletions
diff --git a/tools/m4/enum.m4 b/tools/m4/enum.m4 index 5e908dc8..ab7e8163 100644 --- a/tools/m4/enum.m4 +++ b/tools/m4/enum.m4 @@ -1,25 +1,17 @@ dnl -dnl _ENUM(cpp_type, c_type, value_suffix, `element_list', `no_gtype', in_class, -dnl $1 $2 $3 $4 $5 $6 -dnl `optional_refdoc_comment', 'deprecated') -dnl $7 $8 +dnl _ENUM(cpp_type, c_type, value_suffix, `element_list', `no_gtype', `conv_to_int', +dnl $1 $2 $3 $4 $5 $6 +dnl in_class, `optional_refdoc_comment', 'deprecated') +dnl $7 $8 $9 dnl m4_define(`_ENUM',`dnl _PUSH() -dnl Concerning __ENUM_CLASS_NOLINK__: -dnl The percent signs prevent Doxygen from creating links in the html files. -dnl If a % precedes the class name, another % must precede the enum name, -dnl otherwise Doxygen removes the double colons. -dnl Possibly the percent signs are unnecessary. Even without them Doxygen -dnl version 1.7.1 does not create links from the enum descriptions. -dnl Other versions may behave differently. - m4_define(`__ENUM_CPPNAME__',`$1') m4_define(`__ENUM_CNAME__',`$2') -m4_define(`__ENUM_CLASS_CPPNAME__',m4_ifelse($6,0,,`__CPPNAME__::')`__ENUM_CPPNAME__') -m4_define(`__ENUM_CLASS_NOLINK__',m4_ifelse($6,0,,`%__CPPNAME__::')`%__ENUM_CPPNAME__') -m4_define(`__ENUM_INDENT__',m4_ifelse($6,0,,` ')) +m4_define(`__ENUM_CLASS_CPPNAME__',m4_ifelse($7,0,,`__CPPNAME__::')`__ENUM_CPPNAME__') +m4_define(`__ENUM_INDENT1__',m4_ifelse($7,0,,` ')) +m4_define(`__ENUM_INDENT2__',__ENUM_INDENT1__`'m4_ifelse($6,,,` ')) m4_define(`__ENUM_VALUE_BASE__',`Glib::Value_$3<__NAMESPACE__::__ENUM_CLASS_CPPNAME__>') _POP() @@ -30,33 +22,54 @@ m4_ifdef(`__DOCGROUP_'__MODULE_CANONICAL__`_ENUMS__',,`dnl else m4_define(`__DOCGROUP_'__MODULE_CANONICAL__`_ENUMS__')dnl /** @addtogroup '__MODULE_CANONICAL__`Enums __MODULE_CANONICAL__ Enums and Flags */ -__ENUM_INDENT__')`'dnl endif +__ENUM_INDENT1__')`'dnl endif dnl dnl -ifelse(`$8',,,`_DEPRECATE_IFDEF_START'`'__ENUM_INDENT__)`'dnl The expansion of _DEPRECATE_IFDEF_START ends with a newline -/** $7 -__ENUM_INDENT__ * -__ENUM_INDENT__ * @ingroup __MODULE_CANONICAL__`'Enums +ifelse(`$9',,,`_DEPRECATE_IFDEF_START'`'__ENUM_INDENT1__)`'dnl The expansion of _DEPRECATE_IFDEF_START ends with a newline +ifelse($6,,,`/** Wrapper for enum __ENUM_CPPNAME__. +__ENUM_INDENT1__ * __ENUM_CPPNAME__ enumerators are scoped and can be implicitly converted to int. +__ENUM_INDENT1__ * The scope is __NAMESPACE__::__ENUM_CLASS_CPPNAME__:: +__ENUM_INDENT1__ * +__ENUM_INDENT1__ * @ingroup __MODULE_CANONICAL__`'Enums +__ENUM_INDENT1__ */ +__ENUM_INDENT1__`'class __ENUM_CPPNAME__`'_Wrapper final +__ENUM_INDENT1__{ +__ENUM_INDENT1__`'public: +__ENUM_INDENT2__')`'dnl endif conv_to_int +/** $8 +__ENUM_INDENT2__ * +__ENUM_INDENT2__ * @ingroup __MODULE_CANONICAL__`'Enums m4_ifelse($3,`Flags',`dnl -__ENUM_INDENT__ * @par Bitwise operators: -__ENUM_INDENT__ * <tt>__ENUM_CLASS_NOLINK__ operator|(__ENUM_CLASS_CPPNAME__, __ENUM_CLASS_CPPNAME__)</tt><br> -__ENUM_INDENT__ * <tt>__ENUM_CLASS_NOLINK__ operator&(__ENUM_CLASS_CPPNAME__, __ENUM_CLASS_CPPNAME__)</tt><br> -__ENUM_INDENT__ * <tt>__ENUM_CLASS_NOLINK__ operator^(__ENUM_CLASS_CPPNAME__, __ENUM_CLASS_CPPNAME__)</tt><br> -__ENUM_INDENT__ * <tt>__ENUM_CLASS_NOLINK__ operator~(__ENUM_CLASS_CPPNAME__)</tt><br> -__ENUM_INDENT__ * <tt>__ENUM_CLASS_NOLINK__& operator|=(__ENUM_CLASS_CPPNAME__&, __ENUM_CLASS_CPPNAME__)</tt><br> -__ENUM_INDENT__ * <tt>__ENUM_CLASS_NOLINK__& operator&=(__ENUM_CLASS_CPPNAME__&, __ENUM_CLASS_CPPNAME__)</tt><br> -__ENUM_INDENT__ * <tt>__ENUM_CLASS_NOLINK__& operator^=(__ENUM_CLASS_CPPNAME__&, __ENUM_CLASS_CPPNAME__)</tt><br> +__ENUM_INDENT2__ * @par Bitwise operators: +__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__ operator|(__ENUM_CLASS_CPPNAME__, __ENUM_CLASS_CPPNAME__)</tt><br> +__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__ operator&(__ENUM_CLASS_CPPNAME__, __ENUM_CLASS_CPPNAME__)</tt><br> +__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__ operator^(__ENUM_CLASS_CPPNAME__, __ENUM_CLASS_CPPNAME__)</tt><br> +__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__ operator~(__ENUM_CLASS_CPPNAME__)</tt><br> +__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__& operator|=(__ENUM_CLASS_CPPNAME__&, __ENUM_CLASS_CPPNAME__)</tt><br> +__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__& operator&=(__ENUM_CLASS_CPPNAME__&, __ENUM_CLASS_CPPNAME__)</tt><br> +__ENUM_INDENT2__ * <tt>__ENUM_CLASS_CPPNAME__& operator^=(__ENUM_CLASS_CPPNAME__&, __ENUM_CLASS_CPPNAME__)</tt><br> ')dnl endif -__ENUM_INDENT__ */ -__ENUM_INDENT__`'enum class __ENUM_CPPNAME__ -__ENUM_INDENT__{ +__ENUM_INDENT2__ */ +__ENUM_INDENT2__`'enum ifelse($6,,`class ',)`'__ENUM_CPPNAME__ +__ENUM_INDENT2__{ $4 -__ENUM_INDENT__}; +__ENUM_INDENT2__}; +ifelse($6,,,`__ENUM_INDENT2__`'#ifndef DOXYGEN_SHOULD_SKIP_THIS +__ENUM_INDENT2__`'__ENUM_CPPNAME__`'_Wrapper`'() = delete; +__ENUM_INDENT2__`'#endif +__ENUM_INDENT1__}; +__ENUM_INDENT1__/** __ENUM_CPPNAME__ enumerators are scoped by the wrapper class +__ENUM_INDENT1__ * and can be implicitly converted to int. +__ENUM_INDENT1__ * +__ENUM_INDENT1__ * @ingroup __MODULE_CANONICAL__`'Enums +__ENUM_INDENT1__ */ +__ENUM_INDENT1__`'using __ENUM_CPPNAME__ = __ENUM_CPPNAME__`'_Wrapper::__ENUM_CPPNAME__; +')`'dnl endif conv_to_int m4_ifelse($3,`Flags',`dnl -m4_ifelse($6,0,,`dnl in_class +m4_ifelse($7,0,,`dnl in_class _PUSH(SECTION_HEADER3) __NAMESPACE_BEGIN__ -ifelse(`$8',,,`_DEPRECATE_IFDEF_START')`'dnl +ifelse(`$9',,,`_DEPRECATE_IFDEF_START')`'dnl ')dnl endif /** @ingroup __MODULE_CANONICAL__`'Enums */ @@ -86,17 +99,17 @@ inline __ENUM_CLASS_CPPNAME__& operator&=(__ENUM_CLASS_CPPNAME__& lhs, __ENUM_CL /** @ingroup __MODULE_CANONICAL__`'Enums */ inline __ENUM_CLASS_CPPNAME__& operator^=(__ENUM_CLASS_CPPNAME__& lhs, __ENUM_CLASS_CPPNAME__ rhs) { return (lhs = static_cast<__ENUM_CLASS_CPPNAME__>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); } -m4_ifelse($6,0,,`dnl in_class -ifelse(`$8',,,`_DEPRECATE_IFDEF_END')`'dnl +m4_ifelse($7,0,,`dnl in_class +ifelse(`$9',,,`_DEPRECATE_IFDEF_END')`'dnl __NAMESPACE_END__ _POP() ')dnl endif -')dnl endif !NO_OPERATORS +')dnl endif Flags -ifelse(`$8',,,`_DEPRECATE_IFDEF_END')`'dnl The expansion of _DEPRECATE_IFDEF_END ends with a newline +ifelse(`$9',,,`_DEPRECATE_IFDEF_END')`'dnl The expansion of _DEPRECATE_IFDEF_END ends with a newline m4_ifelse($5,`NO_GTYPE',,`dnl else -m4_ifelse($6,0,`dnl not in_class +m4_ifelse($7,0,`dnl not in_class __NAMESPACE_END__ ',`dnl else _PUSH(SECTION_HEADER3) @@ -106,31 +119,31 @@ _PUSH(SECTION_HEADER3) namespace Glib { -ifelse(`$8',,,`_DEPRECATE_IFDEF_START')`'dnl +ifelse(`$9',,,`_DEPRECATE_IFDEF_START')`'dnl template <> class Value<__NAMESPACE__::__ENUM_CLASS_CPPNAME__> : public __ENUM_VALUE_BASE__ { public: static GType value_type() G_GNUC_CONST; }; -ifelse(`$8',,,`_DEPRECATE_IFDEF_END')`'dnl +ifelse(`$9',,,`_DEPRECATE_IFDEF_END')`'dnl } // namespace Glib #endif /* DOXYGEN_SHOULD_SKIP_THIS */ -m4_ifelse($6,0,`dnl not in_class +m4_ifelse($7,0,`dnl not in_class __NAMESPACE_BEGIN__ ',`dnl else _POP() ')dnl endif _PUSH(SECTION_SRC_GENERATED) -ifelse(`$8',,,`_DEPRECATE_IFDEF_START')`'dnl +ifelse(`$9',,,`_DEPRECATE_IFDEF_START')`'dnl // static GType Glib::Value<__NAMESPACE__::__ENUM_CLASS_CPPNAME__>::value_type() { return _GET_TYPE_FUNC(__ENUM_CNAME__); } -ifelse(`$8',,,`_DEPRECATE_IFDEF_END')`'dnl +ifelse(`$9',,,`_DEPRECATE_IFDEF_END')`'dnl _POP() ')dnl endif !NO_GTYPE diff --git a/tools/pm/Output.pm b/tools/pm/Output.pm index d266e631..1913f016 100644 --- a/tools/pm/Output.pm +++ b/tools/pm/Output.pm @@ -690,13 +690,13 @@ sub output_wrap_sig_decl($$$$$$$$$$$$$$) } # void output_wrap_enum($filename, $line_num, $cpp_type, $c_type, -# $comment, $ref_subst_in, $ref_subst_out, $no_gtype, $in_class, -# $deprecated, $deprecation_docs, $newin) -sub output_wrap_enum($$$$$$$$$$$$$) +# $comment, $ref_subst_in, $ref_subst_out, $no_gtype, $conv_to_int, +# $in_class, $deprecated, $deprecation_docs, $newin) +sub output_wrap_enum($$$$$$$$$$$$$$) { my ($self, $filename, $line_num, $cpp_type, $c_type, - $comment, $ref_subst_in, $ref_subst_out, $no_gtype, $in_class, - $deprecated, $deprecation_docs, $newin) = @_; + $comment, $ref_subst_in, $ref_subst_out, $no_gtype, $conv_to_int, + $in_class, $deprecated, $deprecation_docs, $newin) = @_; my $objEnum = GtkDefs::lookup_enum($c_type); if(!$objEnum) @@ -709,6 +709,7 @@ sub output_wrap_enum($$$$$$$$$$$$$) my $indent = " "; $indent .= " " if ($in_class); + $indent .= " " if ($conv_to_int); my $elements = $objEnum->build_element_list(1, $ref_subst_in, $ref_subst_out, $indent); if(!$elements) @@ -723,8 +724,7 @@ sub output_wrap_enum($$$$$$$$$$$$$) unshift(@$ref_subst_out, ""); # Get the enum documentation from the parsed docs. - $indent = " "; - $indent .= " " if ($in_class); + $indent = substr($indent, 1); # Remove one blank my $enum_docs = DocsParser::lookup_enum_documentation("$c_type", "$cpp_type", $indent, $ref_subst_in, $ref_subst_out, $deprecation_docs, $newin); @@ -734,12 +734,13 @@ sub output_wrap_enum($$$$$$$$$$$$$) my $value_suffix = "Enum"; $value_suffix = "Flags" if ($$objEnum{flags}); - my $str = sprintf("_ENUM(%s,%s,%s,\`%s\',\`%s\',%d,\`%s\',\`%s\')dnl\n", + my $str = sprintf("_ENUM(%s,%s,%s,\`%s\',\`%s\',\`%s\',%d,\`%s\',\`%s\')dnl\n", $cpp_type, $c_type, $value_suffix, $elements, $no_gtype, + $conv_to_int, $in_class, $comment, $deprecated diff --git a/tools/pm/WrapParser.pm b/tools/pm/WrapParser.pm index 829f9b1a..b99c5b06 100644 --- a/tools/pm/WrapParser.pm +++ b/tools/pm/WrapParser.pm @@ -1436,6 +1436,7 @@ sub on_wrap_any_enum($$) my @subst_in = []; my @subst_out = []; my $no_gtype = ""; + my $conv_to_int = ""; my $argDeprecated = ""; my $deprecation_docs = ""; my $newin = ""; @@ -1447,7 +1448,11 @@ sub on_wrap_any_enum($$) if ($arg eq "NO_GTYPE") { - $no_gtype = "NO_GTYPE"; + $no_gtype = $arg; + } + elsif (!$is_gerror and $arg eq "CONV_TO_INT") + { + $conv_to_int = $arg; } elsif ($arg =~ /^s#([^#]+)#([^#]*)#$/) { @@ -1469,15 +1474,18 @@ sub on_wrap_any_enum($$) } } return ($cpp_type, $c_type, $domain, \@subst_in, \@subst_out, $no_gtype, - $argDeprecated, $deprecation_docs, $newin); + $conv_to_int, $argDeprecated, $deprecation_docs, $newin); } # void on_wrap_enum() -# _WRAP_ENUM(cpp_type, c_type [,NO_GTYPE] [,s#regexpr#subst#]*) +# _WRAP_ENUM(cpp_type, c_type [,NO_GTYPE] [,CONV_TO_INT] [,s#regexpr#subst#]*) # Optional arguments: # NO_GTYPE Don't generate code for a specialization of the template # Glib::Value_Enum or Glib::Value_Flags. # Necessary, if the C type enum is not registered as a GType. +# CONV_TO_INT "Convertible to int" Generate a plain enum (not an enum class) +# within a class. Such an enum is scoped like an enum class, +# and it can be implicitly converted to int like a plain enum. # s#regexpr#subst# Zero or more substitutions in names of enum constants, e.g. s#^DATE_##. # # _WRAP_ENUM can be located either in a class or outside all classes. @@ -1497,13 +1505,13 @@ sub on_wrap_enum($) my $comment = $self->extract_preceding_documentation(); # get the arguments - my ($cpp_type, $c_type, undef, $ref_subst_in, $ref_subst_out, $no_gtype, + my ($cpp_type, $c_type, undef, $ref_subst_in, $ref_subst_out, $no_gtype, $conv_to_int, $argDeprecated, $deprecation_docs, $newin) = $self->on_wrap_any_enum(0); $$self{objOutputter}->output_wrap_enum( $$self{filename}, $$self{line_num}, $cpp_type, $c_type, - $comment, $ref_subst_in, $ref_subst_out, $no_gtype, $$self{in_class}, - $argDeprecated, $deprecation_docs, $newin); + $comment, $ref_subst_in, $ref_subst_out, $no_gtype, $conv_to_int, + $$self{in_class}, $argDeprecated, $deprecation_docs, $newin); } sub on_wrap_enum_docs_only($) @@ -1515,7 +1523,7 @@ sub on_wrap_enum_docs_only($) my $comment = $self->extract_preceding_documentation(); # get the arguments - my ($cpp_type, $c_type, undef, $ref_subst_in, $ref_subst_out, undef, + my ($cpp_type, $c_type, undef, $ref_subst_in, $ref_subst_out, undef, undef, $argDeprecated, $deprecation_docs, $newin) = $self->on_wrap_any_enum(0); # Get the module name so the enum docs can be included in the module's @@ -1539,7 +1547,7 @@ sub on_wrap_gerror($) my $class_docs = $self->extract_preceding_documentation(); # get the arguments - my ($cpp_type, $c_type, $domain, $ref_subst_in, $ref_subst_out, $no_gtype, + my ($cpp_type, $c_type, $domain, $ref_subst_in, $ref_subst_out, $no_gtype, undef, $argDeprecated, $deprecation_docs, $newin) = $self->on_wrap_any_enum(1); $$self{objOutputter}->output_wrap_gerror( |