Browse Source

cmJSONHelpers: Restructure cmJSONHelpers

Restructure cmJSONHelpers to prevent SunPro errors when passing context.
Martin Duffy 3 years ago
parent
commit
30336dab66

+ 24 - 29
Source/CTest/cmCTestResourceSpec.cxx

@@ -19,6 +19,8 @@
 #include "cmJSONHelpers.h"
 
 namespace {
+using JSONHelperBuilder =
+  cmJSONHelperBuilder<cmCTestResourceSpec::ReadFileResult>;
 const cmsys::RegularExpression IdentifierRegex{ "^[a-z_][a-z0-9_]*$" };
 const cmsys::RegularExpression IdRegex{ "^[a-z0-9_]+$" };
 
@@ -34,21 +36,19 @@ struct TopVersion
 };
 
 auto const VersionFieldHelper =
-  cmJSONIntHelper<cmCTestResourceSpec::ReadFileResult>(
-    cmCTestResourceSpec::ReadFileResult::READ_OK,
-    cmCTestResourceSpec::ReadFileResult::INVALID_VERSION);
+  JSONHelperBuilder::Int(cmCTestResourceSpec::ReadFileResult::READ_OK,
+                         cmCTestResourceSpec::ReadFileResult::INVALID_VERSION);
 
-auto const VersionHelper =
-  cmJSONRequiredHelper<Version, cmCTestResourceSpec::ReadFileResult>(
-    cmCTestResourceSpec::ReadFileResult::NO_VERSION,
-    cmJSONObjectHelper<Version, cmCTestResourceSpec::ReadFileResult>(
-      cmCTestResourceSpec::ReadFileResult::READ_OK,
-      cmCTestResourceSpec::ReadFileResult::INVALID_VERSION)
-      .Bind("major"_s, &Version::Major, VersionFieldHelper)
-      .Bind("minor"_s, &Version::Minor, VersionFieldHelper));
+auto const VersionHelper = JSONHelperBuilder::Required<Version>(
+  cmCTestResourceSpec::ReadFileResult::NO_VERSION,
+  JSONHelperBuilder::Object<Version>(
+    cmCTestResourceSpec::ReadFileResult::READ_OK,
+    cmCTestResourceSpec::ReadFileResult::INVALID_VERSION)
+    .Bind("major"_s, &Version::Major, VersionFieldHelper)
+    .Bind("minor"_s, &Version::Minor, VersionFieldHelper));
 
 auto const RootVersionHelper =
-  cmJSONObjectHelper<TopVersion, cmCTestResourceSpec::ReadFileResult>(
+  JSONHelperBuilder::Object<TopVersion>(
     cmCTestResourceSpec::ReadFileResult::READ_OK,
     cmCTestResourceSpec::ReadFileResult::INVALID_ROOT)
     .Bind("version"_s, &TopVersion::Version, VersionHelper, false);
@@ -56,7 +56,7 @@ auto const RootVersionHelper =
 cmCTestResourceSpec::ReadFileResult ResourceIdHelper(std::string& out,
                                                      const Json::Value* value)
 {
-  auto result = cmJSONStringHelper(
+  auto result = JSONHelperBuilder::String(
     cmCTestResourceSpec::ReadFileResult::READ_OK,
     cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE)(out, value);
   if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
@@ -70,27 +70,24 @@ cmCTestResourceSpec::ReadFileResult ResourceIdHelper(std::string& out,
 }
 
 auto const ResourceHelper =
-  cmJSONObjectHelper<cmCTestResourceSpec::Resource,
-                     cmCTestResourceSpec::ReadFileResult>(
+  JSONHelperBuilder::Object<cmCTestResourceSpec::Resource>(
     cmCTestResourceSpec::ReadFileResult::READ_OK,
     cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE)
     .Bind("id"_s, &cmCTestResourceSpec::Resource::Id, ResourceIdHelper)
     .Bind("slots"_s, &cmCTestResourceSpec::Resource::Capacity,
-          cmJSONUIntHelper(
+          JSONHelperBuilder::UInt(
             cmCTestResourceSpec::ReadFileResult::READ_OK,
             cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE, 1),
           false);
 
 auto const ResourceListHelper =
-  cmJSONVectorHelper<cmCTestResourceSpec::Resource,
-                     cmCTestResourceSpec::ReadFileResult>(
+  JSONHelperBuilder::Vector<cmCTestResourceSpec::Resource>(
     cmCTestResourceSpec::ReadFileResult::READ_OK,
     cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE_TYPE,
     ResourceHelper);
 
 auto const ResourceMapHelper =
-  cmJSONMapFilterHelper<std::vector<cmCTestResourceSpec::Resource>,
-                        cmCTestResourceSpec::ReadFileResult>(
+  JSONHelperBuilder::MapFilter<std::vector<cmCTestResourceSpec::Resource>>(
     cmCTestResourceSpec::ReadFileResult::READ_OK,
     cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC,
     ResourceListHelper, [](const std::string& key) -> bool {
@@ -98,7 +95,7 @@ auto const ResourceMapHelper =
       return IdentifierRegex.find(key.c_str(), match);
     });
 
-auto const SocketSetHelper = cmJSONVectorHelper<
+auto const SocketSetHelper = JSONHelperBuilder::Vector<
   std::map<std::string, std::vector<cmCTestResourceSpec::Resource>>>(
   cmCTestResourceSpec::ReadFileResult::READ_OK,
   cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC, ResourceMapHelper);
@@ -125,16 +122,14 @@ cmCTestResourceSpec::ReadFileResult SocketHelper(
 }
 
 auto const LocalRequiredHelper =
-  cmJSONRequiredHelper<cmCTestResourceSpec::Socket,
-                       cmCTestResourceSpec::ReadFileResult>(
+  JSONHelperBuilder::Required<cmCTestResourceSpec::Socket>(
     cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC, SocketHelper);
 
-auto const RootHelper =
-  cmJSONObjectHelper<cmCTestResourceSpec, cmCTestResourceSpec::ReadFileResult>(
-    cmCTestResourceSpec::ReadFileResult::READ_OK,
-    cmCTestResourceSpec::ReadFileResult::INVALID_ROOT)
-    .Bind("local", &cmCTestResourceSpec::LocalSocket, LocalRequiredHelper,
-          false);
+auto const RootHelper = JSONHelperBuilder::Object<cmCTestResourceSpec>(
+                          cmCTestResourceSpec::ReadFileResult::READ_OK,
+                          cmCTestResourceSpec::ReadFileResult::INVALID_ROOT)
+                          .Bind("local", &cmCTestResourceSpec::LocalSocket,
+                                LocalRequiredHelper, false);
 }
 
 cmCTestResourceSpec::ReadFileResult cmCTestResourceSpec::ReadFromJSONFile(

+ 43 - 52
Source/cmCMakePresetsGraphReadJSON.cxx

@@ -31,6 +31,7 @@ using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
 using BuildPreset = cmCMakePresetsGraph::BuildPreset;
 using TestPreset = cmCMakePresetsGraph::TestPreset;
 using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
+using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
 
 constexpr int MIN_VERSION = 1;
 constexpr int MAX_VERSION = 5;
@@ -59,29 +60,26 @@ std::unique_ptr<cmCMakePresetsGraphInternal::NotCondition> InvertCondition(
   return retval;
 }
 
-auto const ConditionStringHelper = cmJSONStringHelper<ReadFileResult>(
+auto const ConditionStringHelper = JSONHelperBuilder::String(
   ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION);
 
-auto const ConditionBoolHelper = cmJSONBoolHelper<ReadFileResult>(
+auto const ConditionBoolHelper = JSONHelperBuilder::Bool(
   ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION);
 
-auto const ConditionStringListHelper =
-  cmJSONVectorHelper<std::string, ReadFileResult>(
-    ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION,
-    ConditionStringHelper);
+auto const ConditionStringListHelper = JSONHelperBuilder::Vector<std::string>(
+  ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION,
+  ConditionStringHelper);
 
 auto const ConstConditionHelper =
-  cmJSONObjectHelper<cmCMakePresetsGraphInternal::ConstCondition,
-                     ReadFileResult>(ReadFileResult::READ_OK,
-                                     ReadFileResult::INVALID_CONDITION, false)
+  JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::ConstCondition>(
+    ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
     .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
     .Bind("value"_s, &cmCMakePresetsGraphInternal::ConstCondition::Value,
           ConditionBoolHelper, true);
 
 auto const EqualsConditionHelper =
-  cmJSONObjectHelper<cmCMakePresetsGraphInternal::EqualsCondition,
-                     ReadFileResult>(ReadFileResult::READ_OK,
-                                     ReadFileResult::INVALID_CONDITION, false)
+  JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::EqualsCondition>(
+    ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
     .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
     .Bind("lhs"_s, &cmCMakePresetsGraphInternal::EqualsCondition::Lhs,
           ConditionStringHelper, true)
@@ -89,9 +87,8 @@ auto const EqualsConditionHelper =
           ConditionStringHelper, true);
 
 auto const InListConditionHelper =
-  cmJSONObjectHelper<cmCMakePresetsGraphInternal::InListCondition,
-                     ReadFileResult>(ReadFileResult::READ_OK,
-                                     ReadFileResult::INVALID_CONDITION, false)
+  JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::InListCondition>(
+    ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
     .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
     .Bind("string"_s, &cmCMakePresetsGraphInternal::InListCondition::String,
           ConditionStringHelper, true)
@@ -99,9 +96,8 @@ auto const InListConditionHelper =
           ConditionStringListHelper, true);
 
 auto const MatchesConditionHelper =
-  cmJSONObjectHelper<cmCMakePresetsGraphInternal::MatchesCondition,
-                     ReadFileResult>(ReadFileResult::READ_OK,
-                                     ReadFileResult::INVALID_CONDITION, false)
+  JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::MatchesCondition>(
+    ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
     .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
     .Bind("string"_s, &cmCMakePresetsGraphInternal::MatchesCondition::String,
           ConditionStringHelper, true)
@@ -113,23 +109,20 @@ ReadFileResult SubConditionHelper(
   const Json::Value* value);
 
 auto const ListConditionVectorHelper =
-  cmJSONVectorHelper<std::unique_ptr<cmCMakePresetsGraph::Condition>,
-                     ReadFileResult>(ReadFileResult::READ_OK,
-                                     ReadFileResult::INVALID_CONDITION,
-                                     SubConditionHelper);
+  JSONHelperBuilder::Vector<std::unique_ptr<cmCMakePresetsGraph::Condition>>(
+    ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION,
+    SubConditionHelper);
 auto const AnyAllOfConditionHelper =
-  cmJSONObjectHelper<cmCMakePresetsGraphInternal::AnyAllOfCondition,
-                     ReadFileResult>(ReadFileResult::READ_OK,
-                                     ReadFileResult::INVALID_CONDITION, false)
+  JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::AnyAllOfCondition>(
+    ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
     .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
     .Bind("conditions"_s,
           &cmCMakePresetsGraphInternal::AnyAllOfCondition::Conditions,
           ListConditionVectorHelper);
 
 auto const NotConditionHelper =
-  cmJSONObjectHelper<cmCMakePresetsGraphInternal::NotCondition,
-                     ReadFileResult>(ReadFileResult::READ_OK,
-                                     ReadFileResult::INVALID_CONDITION, false)
+  JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::NotCondition>(
+    ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
     .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
     .Bind("condition"_s,
           &cmCMakePresetsGraphInternal::NotCondition::SubCondition,
@@ -251,37 +244,36 @@ ReadFileResult EnvironmentHelper(cm::optional<std::string>& out,
   return ReadFileResult::INVALID_PRESET;
 }
 
-auto const VersionIntHelper = cmJSONIntHelper<ReadFileResult>(
+auto const VersionIntHelper = JSONHelperBuilder::Int(
   ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION);
 
-auto const VersionHelper = cmJSONRequiredHelper<int, ReadFileResult>(
+auto const VersionHelper = JSONHelperBuilder::Required<int>(
   ReadFileResult::NO_VERSION, VersionIntHelper);
 
 auto const RootVersionHelper =
-  cmJSONObjectHelper<int, ReadFileResult>(ReadFileResult::READ_OK,
-                                          ReadFileResult::INVALID_ROOT)
+  JSONHelperBuilder::Object<int>(ReadFileResult::READ_OK,
+                                 ReadFileResult::INVALID_ROOT)
     .Bind("version"_s, VersionHelper, false);
 
-auto const CMakeVersionUIntHelper = cmJSONUIntHelper<ReadFileResult>(
+auto const CMakeVersionUIntHelper = JSONHelperBuilder::UInt(
   ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION);
 
 auto const CMakeVersionHelper =
-  cmJSONObjectHelper<CMakeVersion, ReadFileResult>(
+  JSONHelperBuilder::Object<CMakeVersion>(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_CMAKE_VERSION, false)
     .Bind("major"_s, &CMakeVersion::Major, CMakeVersionUIntHelper, false)
     .Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false)
     .Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false);
 
-auto const IncludeHelper = cmJSONStringHelper<ReadFileResult>(
+auto const IncludeHelper = JSONHelperBuilder::String(
   ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE);
 
-auto const IncludeVectorHelper =
-  cmJSONVectorHelper<std::string, ReadFileResult>(
-    ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE, IncludeHelper);
+auto const IncludeVectorHelper = JSONHelperBuilder::Vector<std::string>(
+  ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE, IncludeHelper);
 
 auto const RootPresetsHelper =
-  cmJSONObjectHelper<RootPresets, ReadFileResult>(
-    ReadFileResult::READ_OK, ReadFileResult::INVALID_ROOT, false)
+  JSONHelperBuilder::Object<RootPresets>(ReadFileResult::READ_OK,
+                                         ReadFileResult::INVALID_ROOT, false)
     .Bind<int>("version"_s, nullptr, VersionHelper)
     .Bind("configurePresets"_s, &RootPresets::ConfigurePresets,
           cmCMakePresetsGraphInternal::ConfigurePresetsHelper, false)
@@ -302,7 +294,7 @@ namespace cmCMakePresetsGraphInternal {
 cmCMakePresetsGraph::ReadFileResult PresetStringHelper(
   std::string& out, const Json::Value* value)
 {
-  static auto const helper = cmJSONStringHelper<ReadFileResult>(
+  static auto const helper = JSONHelperBuilder::String(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
 
   return helper(out, value);
@@ -311,7 +303,7 @@ cmCMakePresetsGraph::ReadFileResult PresetStringHelper(
 cmCMakePresetsGraph::ReadFileResult PresetVectorStringHelper(
   std::vector<std::string>& out, const Json::Value* value)
 {
-  static auto const helper = cmJSONVectorHelper<std::string, ReadFileResult>(
+  static auto const helper = JSONHelperBuilder::Vector<std::string>(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET,
     cmCMakePresetsGraphInternal::PresetStringHelper);
 
@@ -321,7 +313,7 @@ cmCMakePresetsGraph::ReadFileResult PresetVectorStringHelper(
 cmCMakePresetsGraph::ReadFileResult PresetBoolHelper(bool& out,
                                                      const Json::Value* value)
 {
-  static auto const helper = cmJSONBoolHelper<ReadFileResult>(
+  static auto const helper = JSONHelperBuilder::Bool(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
 
   return helper(out, value);
@@ -330,7 +322,7 @@ cmCMakePresetsGraph::ReadFileResult PresetBoolHelper(bool& out,
 cmCMakePresetsGraph::ReadFileResult PresetOptionalBoolHelper(
   cm::optional<bool>& out, const Json::Value* value)
 {
-  static auto const helper = cmJSONOptionalHelper<bool, ReadFileResult>(
+  static auto const helper = JSONHelperBuilder::Optional<bool>(
     ReadFileResult::READ_OK, PresetBoolHelper);
 
   return helper(out, value);
@@ -339,7 +331,7 @@ cmCMakePresetsGraph::ReadFileResult PresetOptionalBoolHelper(
 cmCMakePresetsGraph::ReadFileResult PresetIntHelper(int& out,
                                                     const Json::Value* value)
 {
-  static auto const helper = cmJSONIntHelper<ReadFileResult>(
+  static auto const helper = JSONHelperBuilder::Int(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
 
   return helper(out, value);
@@ -348,8 +340,8 @@ cmCMakePresetsGraph::ReadFileResult PresetIntHelper(int& out,
 cmCMakePresetsGraph::ReadFileResult PresetOptionalIntHelper(
   cm::optional<int>& out, const Json::Value* value)
 {
-  static auto const helper = cmJSONOptionalHelper<int, ReadFileResult>(
-    ReadFileResult::READ_OK, PresetIntHelper);
+  static auto const helper =
+    JSONHelperBuilder::Optional<int>(ReadFileResult::READ_OK, PresetIntHelper);
 
   return helper(out, value);
 }
@@ -357,7 +349,7 @@ cmCMakePresetsGraph::ReadFileResult PresetOptionalIntHelper(
 cmCMakePresetsGraph::ReadFileResult PresetVectorIntHelper(
   std::vector<int>& out, const Json::Value* value)
 {
-  static auto const helper = cmJSONVectorHelper<int, ReadFileResult>(
+  static auto const helper = JSONHelperBuilder::Vector<int>(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, PresetIntHelper);
 
   return helper(out, value);
@@ -409,10 +401,9 @@ cmCMakePresetsGraph::ReadFileResult EnvironmentMapHelper(
   std::map<std::string, cm::optional<std::string>>& out,
   const Json::Value* value)
 {
-  static auto const helper =
-    cmJSONMapHelper<cm::optional<std::string>, ReadFileResult>(
-      ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET,
-      EnvironmentHelper);
+  static auto const helper = JSONHelperBuilder::Map<cm::optional<std::string>>(
+    ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET,
+    EnvironmentHelper);
 
   return helper(out, value);
 }

+ 4 - 3
Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx

@@ -20,6 +20,7 @@
 namespace {
 using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
 using BuildPreset = cmCMakePresetsGraph::BuildPreset;
+using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
 
 ReadFileResult PackageResolveModeHelper(cm::optional<PackageResolveMode>& out,
                                         const Json::Value* value)
@@ -53,8 +54,8 @@ std::function<ReadFileResult(BuildPreset&, const Json::Value*)> const
 };
 
 auto const BuildPresetHelper =
-  cmJSONObjectHelper<BuildPreset, ReadFileResult>(
-    ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+  JSONHelperBuilder::Object<BuildPreset>(ReadFileResult::READ_OK,
+                                         ReadFileResult::INVALID_PRESET, false)
     .Bind("name"_s, &BuildPreset::Name,
           cmCMakePresetsGraphInternal::PresetStringHelper)
     .Bind("inherits"_s, &BuildPreset::Inherits,
@@ -99,7 +100,7 @@ namespace cmCMakePresetsGraphInternal {
 ReadFileResult BuildPresetsHelper(std::vector<BuildPreset>& out,
                                   const Json::Value* value)
 {
-  static auto const helper = cmJSONVectorHelper<BuildPreset, ReadFileResult>(
+  static auto const helper = JSONHelperBuilder::Vector<BuildPreset>(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
     BuildPresetHelper);
 

+ 12 - 12
Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx

@@ -21,6 +21,7 @@ using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
 using CacheVariable = cmCMakePresetsGraph::CacheVariable;
 using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
 using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
+using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
 
 ReadFileResult ArchToolsetStrategyHelper(
   cm::optional<ArchToolsetStrategy>& out, const Json::Value* value)
@@ -53,7 +54,7 @@ ArchToolsetHelper(
   cm::optional<ArchToolsetStrategy> ConfigurePreset::*strategyField)
 {
   auto const objectHelper =
-    cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
+    JSONHelperBuilder::Object<ConfigurePreset>(
       ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
       .Bind("value", valueField,
             cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -85,7 +86,7 @@ auto const ArchitectureHelper = ArchToolsetHelper(
 auto const ToolsetHelper = ArchToolsetHelper(
   &ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy);
 
-auto const VariableStringHelper = cmJSONStringHelper<ReadFileResult>(
+auto const VariableStringHelper = JSONHelperBuilder::String(
   ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE);
 
 ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value)
@@ -104,7 +105,7 @@ ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value)
 }
 
 auto const VariableObjectHelper =
-  cmJSONObjectHelper<CacheVariable, ReadFileResult>(
+  JSONHelperBuilder::Object<CacheVariable>(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false)
     .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false)
     .Bind("value"_s, &CacheVariable::Value, VariableValueHelper);
@@ -138,11 +139,11 @@ ReadFileResult VariableHelper(cm::optional<CacheVariable>& out,
 }
 
 auto const VariablesHelper =
-  cmJSONMapHelper<cm::optional<CacheVariable>, ReadFileResult>(
+  JSONHelperBuilder::Map<cm::optional<CacheVariable>>(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper);
 
 auto const PresetWarningsHelper =
-  cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
+  JSONHelperBuilder::Object<ConfigurePreset>(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
     .Bind("dev"_s, &ConfigurePreset::WarnDev,
           cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
@@ -156,7 +157,7 @@ auto const PresetWarningsHelper =
           cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
 
 auto const PresetErrorsHelper =
-  cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
+  JSONHelperBuilder::Object<ConfigurePreset>(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
     .Bind("dev"_s, &ConfigurePreset::ErrorDev,
           cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
@@ -164,7 +165,7 @@ auto const PresetErrorsHelper =
           cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
 
 auto const PresetDebugHelper =
-  cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
+  JSONHelperBuilder::Object<ConfigurePreset>(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
     .Bind("output"_s, &ConfigurePreset::DebugOutput,
           cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
@@ -174,7 +175,7 @@ auto const PresetDebugHelper =
           cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
 
 auto const ConfigurePresetHelper =
-  cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
+  JSONHelperBuilder::Object<ConfigurePreset>(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
     .Bind("name"_s, &ConfigurePreset::Name,
           cmCMakePresetsGraphInternal::PresetStringHelper)
@@ -218,10 +219,9 @@ namespace cmCMakePresetsGraphInternal {
 ReadFileResult ConfigurePresetsHelper(std::vector<ConfigurePreset>& out,
                                       const Json::Value* value)
 {
-  static auto const helper =
-    cmJSONVectorHelper<ConfigurePreset, ReadFileResult>(
-      ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
-      ConfigurePresetHelper);
+  static auto const helper = JSONHelperBuilder::Vector<ConfigurePreset>(
+    ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
+    ConfigurePresetHelper);
 
   return helper(out, value);
 }

+ 29 - 37
Source/cmCMakePresetsGraphReadJSONTestPresets.cxx

@@ -21,6 +21,7 @@
 namespace {
 using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
 using TestPreset = cmCMakePresetsGraph::TestPreset;
+using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
 
 ReadFileResult TestPresetOutputVerbosityHelper(
   TestPreset::OutputOptions::VerbosityEnum& out, const Json::Value* value)
@@ -53,9 +54,8 @@ ReadFileResult TestPresetOutputVerbosityHelper(
 }
 
 auto const TestPresetOptionalOutputVerbosityHelper =
-  cmJSONOptionalHelper<TestPreset::OutputOptions::VerbosityEnum,
-                       ReadFileResult>(ReadFileResult::READ_OK,
-                                       TestPresetOutputVerbosityHelper);
+  JSONHelperBuilder::Optional<TestPreset::OutputOptions::VerbosityEnum>(
+    ReadFileResult::READ_OK, TestPresetOutputVerbosityHelper);
 
 ReadFileResult TestPresetOutputTruncationHelper(
   cm::optional<cmCTestTypes::TruncationMode>& out, const Json::Value* value)
@@ -88,9 +88,9 @@ ReadFileResult TestPresetOutputTruncationHelper(
 }
 
 auto const TestPresetOptionalOutputHelper =
-  cmJSONOptionalHelper<TestPreset::OutputOptions, ReadFileResult>(
+  JSONHelperBuilder::Optional<TestPreset::OutputOptions>(
     ReadFileResult::READ_OK,
-    cmJSONObjectHelper<TestPreset::OutputOptions, ReadFileResult>(
+    JSONHelperBuilder::Object<TestPreset::OutputOptions>(
       ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
       .Bind("shortProgress"_s, &TestPreset::OutputOptions::ShortProgress,
             cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
@@ -122,12 +122,10 @@ auto const TestPresetOptionalOutputHelper =
             cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false));
 
 auto const TestPresetOptionalFilterIncludeIndexObjectHelper =
-  cmJSONOptionalHelper<TestPreset::IncludeOptions::IndexOptions,
-                       ReadFileResult>(
+  JSONHelperBuilder::Optional<TestPreset::IncludeOptions::IndexOptions>(
     ReadFileResult::READ_OK,
-    cmJSONObjectHelper<TestPreset::IncludeOptions::IndexOptions,
-                       ReadFileResult>(ReadFileResult::READ_OK,
-                                       ReadFileResult::INVALID_PRESET)
+    JSONHelperBuilder::Object<TestPreset::IncludeOptions::IndexOptions>(
+      ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
       .Bind("start"_s, &TestPreset::IncludeOptions::IndexOptions::Start,
             cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false)
       .Bind("end"_s, &TestPreset::IncludeOptions::IndexOptions::End,
@@ -161,9 +159,9 @@ ReadFileResult TestPresetOptionalFilterIncludeIndexHelper(
 }
 
 auto const TestPresetOptionalFilterIncludeHelper =
-  cmJSONOptionalHelper<TestPreset::IncludeOptions, ReadFileResult>(
+  JSONHelperBuilder::Optional<TestPreset::IncludeOptions>(
     ReadFileResult::READ_OK,
-    cmJSONObjectHelper<TestPreset::IncludeOptions, ReadFileResult>(
+    JSONHelperBuilder::Object<TestPreset::IncludeOptions>(
       ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
       .Bind("name"_s, &TestPreset::IncludeOptions::Name,
             cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -175,12 +173,10 @@ auto const TestPresetOptionalFilterIncludeHelper =
             cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false));
 
 auto const TestPresetOptionalFilterExcludeFixturesHelper =
-  cmJSONOptionalHelper<TestPreset::ExcludeOptions::FixturesOptions,
-                       ReadFileResult>(
+  JSONHelperBuilder::Optional<TestPreset::ExcludeOptions::FixturesOptions>(
     ReadFileResult::READ_OK,
-    cmJSONObjectHelper<TestPreset::ExcludeOptions::FixturesOptions,
-                       ReadFileResult>(ReadFileResult::READ_OK,
-                                       ReadFileResult::INVALID_PRESET)
+    JSONHelperBuilder::Object<TestPreset::ExcludeOptions::FixturesOptions>(
+      ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
       .Bind("any"_s, &TestPreset::ExcludeOptions::FixturesOptions::Any,
             cmCMakePresetsGraphInternal::PresetStringHelper, false)
       .Bind("setup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Setup,
@@ -189,9 +185,9 @@ auto const TestPresetOptionalFilterExcludeFixturesHelper =
             cmCMakePresetsGraphInternal::PresetStringHelper, false));
 
 auto const TestPresetOptionalFilterExcludeHelper =
-  cmJSONOptionalHelper<TestPreset::ExcludeOptions, ReadFileResult>(
+  JSONHelperBuilder::Optional<TestPreset::ExcludeOptions>(
     ReadFileResult::READ_OK,
-    cmJSONObjectHelper<TestPreset::ExcludeOptions, ReadFileResult>(
+    JSONHelperBuilder::Object<TestPreset::ExcludeOptions>(
       ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
       .Bind("name"_s, &TestPreset::ExcludeOptions::Name,
             cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -221,9 +217,8 @@ ReadFileResult TestPresetExecutionShowOnlyHelper(
 }
 
 auto const TestPresetOptionalExecutionShowOnlyHelper =
-  cmJSONOptionalHelper<TestPreset::ExecutionOptions::ShowOnlyEnum,
-                       ReadFileResult>(ReadFileResult::READ_OK,
-                                       TestPresetExecutionShowOnlyHelper);
+  JSONHelperBuilder::Optional<TestPreset::ExecutionOptions::ShowOnlyEnum>(
+    ReadFileResult::READ_OK, TestPresetExecutionShowOnlyHelper);
 
 ReadFileResult TestPresetExecutionModeHelper(
   TestPreset::ExecutionOptions::RepeatOptions::ModeEnum& out,
@@ -256,12 +251,10 @@ ReadFileResult TestPresetExecutionModeHelper(
 }
 
 auto const TestPresetOptionalExecutionRepeatHelper =
-  cmJSONOptionalHelper<TestPreset::ExecutionOptions::RepeatOptions,
-                       ReadFileResult>(
+  JSONHelperBuilder::Optional<TestPreset::ExecutionOptions::RepeatOptions>(
     ReadFileResult::READ_OK,
-    cmJSONObjectHelper<TestPreset::ExecutionOptions::RepeatOptions,
-                       ReadFileResult>(ReadFileResult::READ_OK,
-                                       ReadFileResult::INVALID_PRESET)
+    JSONHelperBuilder::Object<TestPreset::ExecutionOptions::RepeatOptions>(
+      ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
       .Bind("mode"_s, &TestPreset::ExecutionOptions::RepeatOptions::Mode,
             TestPresetExecutionModeHelper, true)
       .Bind("count"_s, &TestPreset::ExecutionOptions::RepeatOptions::Count,
@@ -299,14 +292,13 @@ ReadFileResult TestPresetExecutionNoTestsActionHelper(
 }
 
 auto const TestPresetOptionalExecutionNoTestsActionHelper =
-  cmJSONOptionalHelper<TestPreset::ExecutionOptions::NoTestsActionEnum,
-                       ReadFileResult>(ReadFileResult::READ_OK,
-                                       TestPresetExecutionNoTestsActionHelper);
+  JSONHelperBuilder::Optional<TestPreset::ExecutionOptions::NoTestsActionEnum>(
+    ReadFileResult::READ_OK, TestPresetExecutionNoTestsActionHelper);
 
 auto const TestPresetExecutionHelper =
-  cmJSONOptionalHelper<TestPreset::ExecutionOptions, ReadFileResult>(
+  JSONHelperBuilder::Optional<TestPreset::ExecutionOptions>(
     ReadFileResult::READ_OK,
-    cmJSONObjectHelper<TestPreset::ExecutionOptions, ReadFileResult>(
+    JSONHelperBuilder::Object<TestPreset::ExecutionOptions>(
       ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
       .Bind("stopOnFailure"_s, &TestPreset::ExecutionOptions::StopOnFailure,
             cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
@@ -334,9 +326,9 @@ auto const TestPresetExecutionHelper =
             TestPresetOptionalExecutionNoTestsActionHelper, false));
 
 auto const TestPresetFilterHelper =
-  cmJSONOptionalHelper<TestPreset::FilterOptions, ReadFileResult>(
+  JSONHelperBuilder::Optional<TestPreset::FilterOptions>(
     ReadFileResult::READ_OK,
-    cmJSONObjectHelper<TestPreset::FilterOptions, ReadFileResult>(
+    JSONHelperBuilder::Object<TestPreset::FilterOptions>(
       ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
       .Bind("include"_s, &TestPreset::FilterOptions::Include,
             TestPresetOptionalFilterIncludeHelper, false)
@@ -344,8 +336,8 @@ auto const TestPresetFilterHelper =
             TestPresetOptionalFilterExcludeHelper, false));
 
 auto const TestPresetHelper =
-  cmJSONObjectHelper<TestPreset, ReadFileResult>(
-    ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+  JSONHelperBuilder::Object<TestPreset>(ReadFileResult::READ_OK,
+                                        ReadFileResult::INVALID_PRESET, false)
     .Bind("name"_s, &TestPreset::Name,
           cmCMakePresetsGraphInternal::PresetStringHelper)
     .Bind("inherits"_s, &TestPreset::Inherits,
@@ -386,7 +378,7 @@ namespace cmCMakePresetsGraphInternal {
 cmCMakePresetsGraph::ReadFileResult TestPresetsHelper(
   std::vector<cmCMakePresetsGraph::TestPreset>& out, const Json::Value* value)
 {
-  static auto const helper = cmJSONVectorHelper<TestPreset, ReadFileResult>(
+  static auto const helper = JSONHelperBuilder::Vector<TestPreset>(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
     TestPresetHelper);
 

+ 226 - 251
Source/cmJSONHelpers.h

@@ -17,143 +17,119 @@
 template <typename T, typename E>
 using cmJSONHelper = std::function<E(T& out, const Json::Value* value)>;
 
-template <typename T, typename E>
-class cmJSONObjectHelper
+template <typename E>
+struct cmJSONHelperBuilder
 {
-public:
-  cmJSONObjectHelper(E&& success, E&& fail, bool allowExtra = true);
-
-  template <typename U, typename M, typename F>
-  cmJSONObjectHelper& Bind(const cm::string_view& name, M U::*member, F func,
-                           bool required = true);
-  template <typename M, typename F>
-  cmJSONObjectHelper& Bind(const cm::string_view& name, std::nullptr_t, F func,
-                           bool required = true);
-  template <typename F>
-  cmJSONObjectHelper& Bind(const cm::string_view& name, F func,
-                           bool required = true);
-
-  E operator()(T& out, const Json::Value* value) const;
-
-private:
-  // Not a true cmJSONHelper, it just happens to match the signature
-  using MemberFunction = std::function<E(T& out, const Json::Value* value)>;
-  struct Member
+  template <typename T>
+  class Object
   {
-    cm::string_view Name;
-    MemberFunction Function;
-    bool Required;
-  };
-  std::vector<Member> Members;
-  bool AnyRequired = false;
-  E Success;
-  E Fail;
-  bool AllowExtra;
-
-  cmJSONObjectHelper& BindPrivate(const cm::string_view& name,
-                                  MemberFunction&& func, bool required);
-};
-
-template <typename T, typename E>
-cmJSONObjectHelper<T, E>::cmJSONObjectHelper(E&& success, E&& fail,
-                                             bool allowExtra)
-  : Success(std::move(success))
-  , Fail(std::move(fail))
-  , AllowExtra(allowExtra)
-{
-}
+  public:
+    Object(E&& success, E&& fail, bool allowExtra = true)
+      : Success(std::move(success))
+      , Fail(std::move(fail))
+      , AllowExtra(allowExtra)
+    {
+    }
 
-template <typename T, typename E>
-template <typename U, typename M, typename F>
-cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::Bind(
-  const cm::string_view& name, M U::*member, F func, bool required)
-{
-  return this->BindPrivate(
-    name,
-    [func, member](T& out, const Json::Value* value) -> E {
-      return func(out.*member, value);
-    },
-    required);
-}
+    template <typename U, typename M, typename F>
+    Object& Bind(const cm::string_view& name, M U::*member, F func,
+                 bool required = true)
+    {
+      return this->BindPrivate(
+        name,
+        [func, member](T& out, const Json::Value* value) -> E {
+          return func(out.*member, value);
+        },
+        required);
+    }
+    template <typename M, typename F>
+    Object& Bind(const cm::string_view& name, std::nullptr_t, F func,
+                 bool required = true)
+    {
+      return this->BindPrivate(
+        name,
+        [func](T& /*out*/, const Json::Value* value) -> E {
+          M dummy;
+          return func(dummy, value);
+        },
+        required);
+    }
+    template <typename F>
+    Object& Bind(const cm::string_view& name, F func, bool required = true)
+    {
+      return this->BindPrivate(name, MemberFunction(func), required);
+    }
 
-template <typename T, typename E>
-template <typename M, typename F>
-cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::Bind(
-  const cm::string_view& name, std::nullptr_t, F func, bool required)
-{
-  return this->BindPrivate(name,
-                           [func](T& /*out*/, const Json::Value* value) -> E {
-                             M dummy;
-                             return func(dummy, value);
-                           },
-                           required);
-}
+    E operator()(T& out, const Json::Value* value) const
+    {
+      if (!value && this->AnyRequired) {
+        return this->Fail;
+      }
+      if (value && !value->isObject()) {
+        return this->Fail;
+      }
+      Json::Value::Members extraFields;
+      if (value) {
+        extraFields = value->getMemberNames();
+      }
 
-template <typename T, typename E>
-template <typename F>
-cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::Bind(
-  const cm::string_view& name, F func, bool required)
-{
-  return this->BindPrivate(name, MemberFunction(func), required);
-}
+      for (auto const& m : this->Members) {
+        std::string name(m.Name.data(), m.Name.size());
+        if (value && value->isMember(name)) {
+          E result = m.Function(out, &(*value)[name]);
+          if (result != this->Success) {
+            return result;
+          }
+          extraFields.erase(
+            std::find(extraFields.begin(), extraFields.end(), name));
+        } else if (!m.Required) {
+          E result = m.Function(out, nullptr);
+          if (result != this->Success) {
+            return result;
+          }
+        } else {
+          return this->Fail;
+        }
+      }
 
-template <typename T, typename E>
-cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::BindPrivate(
-  const cm::string_view& name, MemberFunction&& func, bool required)
-{
-  Member m;
-  m.Name = name;
-  m.Function = std::move(func);
-  m.Required = required;
-  this->Members.push_back(std::move(m));
-  if (required) {
-    this->AnyRequired = true;
-  }
-  return *this;
-}
+      return this->AllowExtra || extraFields.empty() ? this->Success
+                                                     : this->Fail;
+    }
 
-template <typename T, typename E>
-E cmJSONObjectHelper<T, E>::operator()(T& out, const Json::Value* value) const
-{
-  if (!value && this->AnyRequired) {
-    return this->Fail;
-  }
-  if (value && !value->isObject()) {
-    return this->Fail;
-  }
-  Json::Value::Members extraFields;
-  if (value) {
-    extraFields = value->getMemberNames();
-  }
+  private:
+    // Not a true cmJSONHelper, it just happens to match the signature
+    using MemberFunction = std::function<E(T& out, const Json::Value* value)>;
+    struct Member
+    {
+      cm::string_view Name;
+      MemberFunction Function;
+      bool Required;
+    };
+    std::vector<Member> Members;
+    bool AnyRequired = false;
+    E Success;
+    E Fail;
+    bool AllowExtra;
 
-  for (auto const& m : this->Members) {
-    std::string name(m.Name.data(), m.Name.size());
-    if (value && value->isMember(name)) {
-      E result = m.Function(out, &(*value)[name]);
-      if (result != this->Success) {
-        return result;
+    Object& BindPrivate(const cm::string_view& name, MemberFunction&& func,
+                        bool required)
+    {
+      Member m;
+      m.Name = name;
+      m.Function = std::move(func);
+      m.Required = required;
+      this->Members.push_back(std::move(m));
+      if (required) {
+        this->AnyRequired = true;
       }
-      extraFields.erase(
-        std::find(extraFields.begin(), extraFields.end(), name));
-    } else if (!m.Required) {
-      E result = m.Function(out, nullptr);
-      if (result != this->Success) {
-        return result;
-      }
-    } else {
-      return this->Fail;
+      return *this;
     }
-  }
-
-  return this->AllowExtra || extraFields.empty() ? this->Success : this->Fail;
-}
-
-template <typename E>
-cmJSONHelper<std::string, E> cmJSONStringHelper(E success, E fail,
-                                                const std::string& defval = "")
-{
-  return
-    [success, fail, defval](std::string& out, const Json::Value* value) -> E {
+  };
+  static cmJSONHelper<std::string, E> String(E success, E fail,
+                                             const std::string& defval = "")
+  {
+    return [success, fail, defval](std::string& out,
+                                   const Json::Value* value) -> E {
       if (!value) {
         out = defval;
         return success;
@@ -164,30 +140,28 @@ cmJSONHelper<std::string, E> cmJSONStringHelper(E success, E fail,
       out = value->asString();
       return success;
     };
-}
+  }
 
-template <typename E>
-cmJSONHelper<int, E> cmJSONIntHelper(E success, E fail, int defval = 0)
-{
-  return [success, fail, defval](int& out, const Json::Value* value) -> E {
-    if (!value) {
-      out = defval;
+  static cmJSONHelper<int, E> Int(E success, E fail, int defval = 0)
+  {
+    return [success, fail, defval](int& out, const Json::Value* value) -> E {
+      if (!value) {
+        out = defval;
+        return success;
+      }
+      if (!value->isInt()) {
+        return fail;
+      }
+      out = value->asInt();
       return success;
-    }
-    if (!value->isInt()) {
-      return fail;
-    }
-    out = value->asInt();
-    return success;
-  };
-}
+    };
+  }
 
-template <typename E>
-cmJSONHelper<unsigned int, E> cmJSONUIntHelper(E success, E fail,
-                                               unsigned int defval = 0)
-{
-  return
-    [success, fail, defval](unsigned int& out, const Json::Value* value) -> E {
+  static cmJSONHelper<unsigned int, E> UInt(E success, E fail,
+                                            unsigned int defval = 0)
+  {
+    return [success, fail, defval](unsigned int& out,
+                                   const Json::Value* value) -> E {
       if (!value) {
         out = defval;
         return success;
@@ -198,118 +172,119 @@ cmJSONHelper<unsigned int, E> cmJSONUIntHelper(E success, E fail,
       out = value->asUInt();
       return success;
     };
-}
+  }
 
-template <typename E>
-cmJSONHelper<bool, E> cmJSONBoolHelper(E success, E fail, bool defval = false)
-{
-  return [success, fail, defval](bool& out, const Json::Value* value) -> E {
-    if (!value) {
-      out = defval;
+  static cmJSONHelper<bool, E> Bool(E success, E fail, bool defval = false)
+  {
+    return [success, fail, defval](bool& out, const Json::Value* value) -> E {
+      if (!value) {
+        out = defval;
+        return success;
+      }
+      if (!value->isBool()) {
+        return fail;
+      }
+      out = value->asBool();
       return success;
-    }
-    if (!value->isBool()) {
-      return fail;
-    }
-    out = value->asBool();
-    return success;
-  };
-}
+    };
+  }
 
-template <typename T, typename E, typename F, typename Filter>
-cmJSONHelper<std::vector<T>, E> cmJSONVectorFilterHelper(E success, E fail,
-                                                         F func, Filter filter)
-{
-  return [success, fail, func, filter](std::vector<T>& out,
-                                       const Json::Value* value) -> E {
-    if (!value) {
-      out.clear();
-      return success;
-    }
-    if (!value->isArray()) {
-      return fail;
-    }
-    out.clear();
-    for (auto const& item : *value) {
-      T t;
-      E result = func(t, &item);
-      if (result != success) {
-        return result;
+  template <typename T, typename F, typename Filter>
+  static cmJSONHelper<std::vector<T>, E> VectorFilter(E success, E fail,
+                                                      F func, Filter filter)
+  {
+    return [success, fail, func, filter](std::vector<T>& out,
+                                         const Json::Value* value) -> E {
+      if (!value) {
+        out.clear();
+        return success;
       }
-      if (!filter(t)) {
-        continue;
+      if (!value->isArray()) {
+        return fail;
       }
-      out.push_back(std::move(t));
-    }
-    return success;
-  };
-}
-
-template <typename T, typename E, typename F>
-cmJSONHelper<std::vector<T>, E> cmJSONVectorHelper(E success, E fail, F func)
-{
-  return cmJSONVectorFilterHelper<T, E, F>(success, fail, func,
-                                           [](const T&) { return true; });
-}
-
-template <typename T, typename E, typename F, typename Filter>
-cmJSONHelper<std::map<std::string, T>, E> cmJSONMapFilterHelper(E success,
-                                                                E fail, F func,
-                                                                Filter filter)
-{
-  return [success, fail, func, filter](std::map<std::string, T>& out,
-                                       const Json::Value* value) -> E {
-    if (!value) {
       out.clear();
+      for (auto const& item : *value) {
+        T t;
+        E result = func(t, &item);
+        if (result != success) {
+          return result;
+        }
+        if (!filter(t)) {
+          continue;
+        }
+        out.push_back(std::move(t));
+      }
       return success;
-    }
-    if (!value->isObject()) {
-      return fail;
-    }
-    out.clear();
-    for (auto const& key : value->getMemberNames()) {
-      if (!filter(key)) {
-        continue;
+    };
+  }
+
+  template <typename T, typename F>
+  static cmJSONHelper<std::vector<T>, E> Vector(E success, E fail, F func)
+  {
+    return VectorFilter<T, F>(success, fail, func,
+                              [](const T&) { return true; });
+  }
+
+  template <typename T, typename F, typename Filter>
+  static cmJSONHelper<std::map<std::string, T>, E> MapFilter(E success, E fail,
+                                                             F func,
+                                                             Filter filter)
+  {
+    return [success, fail, func, filter](std::map<std::string, T>& out,
+                                         const Json::Value* value) -> E {
+      if (!value) {
+        out.clear();
+        return success;
       }
-      T t;
-      E result = func(t, &(*value)[key]);
-      if (result != success) {
-        return result;
+      if (!value->isObject()) {
+        return fail;
       }
-      out[key] = std::move(t);
-    }
-    return success;
-  };
-}
+      out.clear();
+      for (auto const& key : value->getMemberNames()) {
+        if (!filter(key)) {
+          continue;
+        }
+        T t;
+        E result = func(t, &(*value)[key]);
+        if (result != success) {
+          return result;
+        }
+        out[key] = std::move(t);
+      }
+      return success;
+    };
+  }
 
-template <typename T, typename E, typename F>
-cmJSONHelper<std::map<std::string, T>, E> cmJSONMapHelper(E success, E fail,
-                                                          F func)
-{
-  return cmJSONMapFilterHelper<T, E, F>(
-    success, fail, func, [](const std::string&) { return true; });
-}
+  template <typename T, typename F>
+  static cmJSONHelper<std::map<std::string, T>, E> Map(E success, E fail,
+                                                       F func)
+  {
+    return MapFilter<T, F>(success, fail, func,
+                           [](const std::string&) { return true; });
+  }
 
-template <typename T, typename E, typename F>
-cmJSONHelper<cm::optional<T>, E> cmJSONOptionalHelper(E success, F func)
-{
-  return [success, func](cm::optional<T>& out, const Json::Value* value) -> E {
-    if (!value) {
-      out.reset();
-      return success;
-    }
-    out.emplace();
-    return func(*out, value);
-  };
-}
+  template <typename T, typename F>
+  static cmJSONHelper<cm::optional<T>, E> Optional(E success, F func)
+  {
+    return
+      [success, func](cm::optional<T>& out, const Json::Value* value) -> E {
+        if (!value) {
+          out.reset();
+          return success;
+        }
+        out.emplace();
+        return func(*out, value);
+      };
+  }
 
-template <typename T, typename E, typename F>
-cmJSONHelper<T, E> cmJSONRequiredHelper(E fail, F func)
-{
-  return [fail, func](T& out, const Json::Value* value) -> E {
-    if (!value) {
-      return fail;
-    }
-    return func(out, value);
-  };
-}
+  template <typename T, typename F>
+  static cmJSONHelper<T, E> Required(E fail, F func)
+  {
+    return [fail, func](T& out, const Json::Value* value) -> E {
+      if (!value) {
+        return fail;
+      }
+      return func(out, value);
+    };
+  }
+};

+ 24 - 23
Tests/CMakeLib/testJSONHelpers.cxx

@@ -43,32 +43,33 @@ enum class ErrorCode
   MissingRequired,
 };
 
+using JSONHelperBuilder = cmJSONHelperBuilder<ErrorCode>;
+
 auto const IntHelper =
-  cmJSONIntHelper<ErrorCode>(ErrorCode::Success, ErrorCode::InvalidInt, 1);
+  JSONHelperBuilder::Int(ErrorCode::Success, ErrorCode::InvalidInt, 1);
 auto const RequiredIntHelper =
-  cmJSONRequiredHelper<int, ErrorCode>(ErrorCode::MissingRequired, IntHelper);
+  JSONHelperBuilder::Required<int>(ErrorCode::MissingRequired, IntHelper);
 auto const UIntHelper =
-  cmJSONUIntHelper<ErrorCode>(ErrorCode::Success, ErrorCode::InvalidInt, 1);
-auto const BoolHelper = cmJSONBoolHelper<ErrorCode>(
-  ErrorCode::Success, ErrorCode::InvalidBool, false);
-auto const StringHelper = cmJSONStringHelper<ErrorCode>(
+  JSONHelperBuilder::UInt(ErrorCode::Success, ErrorCode::InvalidInt, 1);
+auto const BoolHelper =
+  JSONHelperBuilder::Bool(ErrorCode::Success, ErrorCode::InvalidBool, false);
+auto const StringHelper = JSONHelperBuilder::String(
   ErrorCode::Success, ErrorCode::InvalidString, "default");
-auto const RequiredStringHelper = cmJSONRequiredHelper<std::string, ErrorCode>(
+auto const RequiredStringHelper = JSONHelperBuilder::Required<std::string>(
   ErrorCode::MissingRequired, StringHelper);
-auto const StringVectorHelper = cmJSONVectorHelper<std::string, ErrorCode>(
+auto const StringVectorHelper = JSONHelperBuilder::Vector<std::string>(
   ErrorCode::Success, ErrorCode::InvalidArray, StringHelper);
 auto const StringVectorFilterHelper =
-  cmJSONVectorFilterHelper<std::string, ErrorCode>(
+  JSONHelperBuilder::VectorFilter<std::string>(
     ErrorCode::Success, ErrorCode::InvalidArray, StringHelper,
     [](const std::string& value) { return value != "ignore"; });
-auto const StringMapHelper = cmJSONMapHelper<std::string, ErrorCode>(
+auto const StringMapHelper = JSONHelperBuilder::Map<std::string>(
   ErrorCode::Success, ErrorCode::InvalidObject, StringHelper);
-auto const StringMapFilterHelper =
-  cmJSONMapFilterHelper<std::string, ErrorCode>(
-    ErrorCode::Success, ErrorCode::InvalidObject, StringHelper,
-    [](const std::string& key) { return key != "ignore"; });
+auto const StringMapFilterHelper = JSONHelperBuilder::MapFilter<std::string>(
+  ErrorCode::Success, ErrorCode::InvalidObject, StringHelper,
+  [](const std::string& key) { return key != "ignore"; });
 auto const OptionalStringHelper =
-  cmJSONOptionalHelper<std::string>(ErrorCode::Success, StringHelper);
+  JSONHelperBuilder::Optional<std::string>(ErrorCode::Success, StringHelper);
 
 bool testInt()
 {
@@ -150,10 +151,10 @@ bool testString()
 bool testObject()
 {
   auto const subhelper =
-    cmJSONObjectHelper<ObjectStruct, ErrorCode>(ErrorCode::Success,
-                                                ErrorCode::InvalidSubObject)
+    JSONHelperBuilder::Object<ObjectStruct>(ErrorCode::Success,
+                                            ErrorCode::InvalidSubObject)
       .Bind("subfield"_s, &ObjectStruct::Field2, IntHelper);
-  auto const helper = cmJSONObjectHelper<ObjectStruct, ErrorCode>(
+  auto const helper = JSONHelperBuilder::Object<ObjectStruct>(
                         ErrorCode::Success, ErrorCode::InvalidObject)
                         .Bind("field1"_s, &ObjectStruct::Field1, StringHelper)
                         .Bind("field2"_s, subhelper)
@@ -206,8 +207,8 @@ bool testObject()
 bool testObjectInherited()
 {
   auto const helper =
-    cmJSONObjectHelper<InheritedStruct, ErrorCode>(ErrorCode::Success,
-                                                   ErrorCode::InvalidObject)
+    JSONHelperBuilder::Object<InheritedStruct>(ErrorCode::Success,
+                                               ErrorCode::InvalidObject)
       .Bind("field1"_s, &InheritedStruct::Field1, StringHelper)
       .Bind("field2"_s, &InheritedStruct::Field2, IntHelper)
       .Bind("field3"_s, &InheritedStruct::Field3, StringHelper);
@@ -253,7 +254,7 @@ bool testObjectInherited()
 
 bool testObjectNoExtra()
 {
-  auto const helper = cmJSONObjectHelper<ObjectStruct, ErrorCode>(
+  auto const helper = JSONHelperBuilder::Object<ObjectStruct>(
                         ErrorCode::Success, ErrorCode::InvalidObject, false)
                         .Bind("field1"_s, &ObjectStruct::Field1, StringHelper)
                         .Bind("field2"_s, &ObjectStruct::Field2, IntHelper);
@@ -277,8 +278,8 @@ bool testObjectNoExtra()
 bool testObjectOptional()
 {
   auto const helper =
-    cmJSONObjectHelper<ObjectStruct, ErrorCode>(ErrorCode::Success,
-                                                ErrorCode::InvalidObject)
+    JSONHelperBuilder::Object<ObjectStruct>(ErrorCode::Success,
+                                            ErrorCode::InvalidObject)
       .Bind("field1"_s, &ObjectStruct::Field1, StringHelper, false)
       .Bind("field2"_s, &ObjectStruct::Field2, IntHelper, false)
       .Bind<std::string>("field3_s", nullptr, StringHelper, false);