Add explicit option enum value __MAX_VALUE (#7547)
authorGereon Kremer <nafur42@gmail.com>
Mon, 1 Nov 2021 22:28:54 +0000 (15:28 -0700)
committerGitHub <noreply@github.com>
Mon, 1 Nov 2021 22:28:54 +0000 (22:28 +0000)
This PR fixes a subtle issue with the dict ordering changing across different python versions.
To store the flags of -o, we store a bitset with the index being the enum value cast to size_t. To specify the bitset size, we simply used the last enum value (in the toml file). This, however, assumes that the order within dictionaries is stable: toml simply puts all modes in a python dict.
This PR avoids this issue by introducing an explicit __MAX_VALUE enum value. Note that this also avoids the need to update the bitset definition when new output tags are added.

src/options/base_options.toml
src/options/mkoptions.py

index d59d9cdea2f5cf244cedc9dec9458c560d1d8299..ec3bd870d592e0188e357930adc0562f43e6771c 100644 (file)
@@ -185,7 +185,7 @@ name   = "Base"
   name       = "outputTagHolder"
   category   = "undocumented"
   includes   = ["<bitset>"]
-  type       = "std::bitset<static_cast<size_t>(OutputTag::RAW_BENCHMARK)+1>"
+  type       = "std::bitset<static_cast<size_t>(OutputTag::__MAX_VALUE)+1>"
 
 [[option]]
   name       = "printSuccess"
index dfd48d7f42a54f69da84f25fc2b128515b2215ae..0db16e7c65a2fca0bbb9eaec15bbc0940951f564 100644 (file)
@@ -292,7 +292,6 @@ def generate_get_impl(modules):
 
 def _set_handlers(option):
     """Render handler call for options::set()."""
-    optname = option.long_name if option.long else ""
     if option.handler:
         if option.type == 'void':
             return 'opts.handler().{}(name)'.format(option.handler)
@@ -307,7 +306,6 @@ def _set_predicates(option):
     """Render predicate calls for options::set()."""
     if option.type == 'void':
         return []
-    optname = option.long_name if option.long else ""
     assert option.type != 'void'
     res = []
     if option.minimum:
@@ -419,7 +417,8 @@ def generate_module_includes(module):
 
 TPL_MODE_DECL = '''enum class {type}
 {{
-  {values}
+  {values},
+  __MAX_VALUE = {maxvalue}
 }};
 std::ostream& operator<<(std::ostream& os, {type} mode);
 {type} stringTo{type}(const std::string& optarg);
@@ -432,10 +431,11 @@ def generate_module_mode_decl(module):
     for option in module.options:
         if option.name is None or not option.mode:
             continue
+        values = list(option.mode.keys())
         res.append(
             TPL_MODE_DECL.format(type=option.type,
-                                 values=wrap_line(
-                                     ', '.join(option.mode.keys()), 2)))
+                                 values=wrap_line(', '.join(values), 2),
+                                 maxvalue=values[-1]))
     return '\n'.join(res)