/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#ifndef cmake_h
#define cmake_h

#include "cmConfigure.h" // IWYU pragma: keep

#include <cstddef>
#include <functional>
#include <map>
#include <memory>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

#include <cm/string_view>

#include "cmGeneratedFileStream.h"
#include "cmInstalledFile.h"
#include "cmListFileCache.h"
#include "cmMessageType.h"
#include "cmProperty.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"

#if !defined(CMAKE_BOOTSTRAP)
#  include <cm3p/json/value.h>
#endif

class cmExternalMakefileProjectGeneratorFactory;
class cmFileAPI;
class cmFileTimeCache;
class cmGlobalGenerator;
class cmGlobalGeneratorFactory;
class cmMakefile;
#if !defined(CMAKE_BOOTSTRAP)
class cmMakefileProfilingData;
#endif
class cmMessenger;
class cmVariableWatch;
struct cmDocumentationEntry;

/** \brief Represents a cmake invocation.
 *
 * This class represents a cmake invocation. It is the top level class when
 * running cmake. Most cmake based GUIs should primarily create an instance
 * of this class and communicate with it.
 *
 * The basic process for a GUI is as follows:
 *
 * -# Create a cmake instance
 * -# Set the Home directories, generator, and cmake command. this
 *    can be done using the Set methods or by using SetArgs and passing in
 *    command line arguments.
 * -# Load the cache by calling LoadCache (duh)
 * -# if you are using command line arguments with -D or -C flags then
 *    call SetCacheArgs (or if for some other reason you want to modify the
 *    cache), do it now.
 * -# Finally call Configure
 * -# Let the user change values and go back to step 5
 * -# call Generate

 * If your GUI allows the user to change the home directories then
 * you must at a minimum redo steps 2 through 7.
 */

class cmake
{
public:
  enum Role
  {
    RoleInternal, // no commands
    RoleScript,   // script commands
    RoleProject   // all commands
  };

  enum DiagLevel
  {
    DIAG_IGNORE,
    DIAG_WARN,
    DIAG_ERROR
  };

  /** \brief Describes the working modes of cmake */
  enum WorkingMode
  {
    NORMAL_MODE, ///< Cmake runs to create project files
                 /** \brief Script mode (started by using -P).
                  *
                  * In script mode there is no generator and no cache. Also,
                  * languages are not enabled, so add_executable and things do
                  * nothing.
                  */
    SCRIPT_MODE,
    /** \brief A pkg-config like mode
     *
     * In this mode cmake just searches for a package and prints the results to
     * stdout. This is similar to SCRIPT_MODE, but commands like add_library()
     * work too, since they may be used e.g. in exported target files. Started
     * via --find-package.
     */
    FIND_PACKAGE_MODE
  };

  /** \brief Define log level constants. */
  enum LogLevel
  {
    LOG_UNDEFINED,
    LOG_ERROR,
    LOG_WARNING,
    LOG_NOTICE,
    LOG_STATUS,
    LOG_VERBOSE,
    LOG_DEBUG,
    LOG_TRACE
  };

  /** \brief Define supported trace formats **/
  enum TraceFormat
  {
    TRACE_UNDEFINED,
    TRACE_HUMAN,
    TRACE_JSON_V1,
  };

  struct GeneratorInfo
  {
    std::string name;
    std::string baseName;
    std::string extraName;
    bool supportsToolset;
    bool supportsPlatform;
    std::vector<std::string> supportedPlatforms;
    std::string defaultPlatform;
    bool isAlias;
  };

  struct FileExtensions
  {
    bool Test(cm::string_view ext) const
    {
      return (this->unordered.find(ext) != this->unordered.end());
    }

    std::vector<std::string> ordered;
    std::unordered_set<cm::string_view> unordered;
  };

  using InstalledFilesMap = std::map<std::string, cmInstalledFile>;

  static const int NO_BUILD_PARALLEL_LEVEL = -1;
  static const int DEFAULT_BUILD_PARALLEL_LEVEL = 0;

  /// Default constructor
  cmake(Role role, cmState::Mode mode);
  /// Destructor
  ~cmake();

  cmake(cmake const&) = delete;
  cmake& operator=(cmake const&) = delete;

#if !defined(CMAKE_BOOTSTRAP)
  Json::Value ReportVersionJson() const;
  Json::Value ReportCapabilitiesJson() const;
#endif
  std::string ReportCapabilities() const;

  //@{
  /**
   * Set/Get the home directory (or output directory) in the project. The
   * home directory is the top directory of the project. It is the
   * path-to-source cmake was run with.
   */
  void SetHomeDirectory(const std::string& dir);
  std::string const& GetHomeDirectory() const;
  void SetHomeOutputDirectory(const std::string& dir);
  std::string const& GetHomeOutputDirectory() const;
  //@}

  /**
   * Handle a command line invocation of cmake.
   */
  int Run(const std::vector<std::string>& args)
  {
    return this->Run(args, false);
  }
  int Run(const std::vector<std::string>& args, bool noconfigure);

  /**
   * Run the global generator Generate step.
   */
  int Generate();

  /**
   * Configure the cmMakefiles. This routine will create a GlobalGenerator if
   * one has not already been set. It will then Call Configure on the
   * GlobalGenerator. This in turn will read in an process all the CMakeList
   * files for the tree. It will not produce any actual Makefiles, or
   * workspaces. Generate does that.  */
  int Configure();
  int ActualConfigure();

  //! Break up a line like VAR:type="value" into var, type and value
  static bool ParseCacheEntry(const std::string& entry, std::string& var,
                              std::string& value,
                              cmStateEnums::CacheEntryType& type);

  int LoadCache();
  bool LoadCache(const std::string& path);
  bool LoadCache(const std::string& path, bool internal,
                 std::set<std::string>& excludes,
                 std::set<std::string>& includes);
  bool SaveCache(const std::string& path);
  bool DeleteCache(const std::string& path);
  void PreLoadCMakeFiles();

  //! Create a GlobalGenerator
  std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
    const std::string& name);

  //! Return the global generator assigned to this instance of cmake
  cmGlobalGenerator* GetGlobalGenerator()
  {
    return this->GlobalGenerator.get();
  }
  //! Return the global generator assigned to this instance of cmake, const
  const cmGlobalGenerator* GetGlobalGenerator() const
  {
    return this->GlobalGenerator.get();
  }

  //! Return the full path to where the CMakeCache.txt file should be.
  static std::string FindCacheFile(const std::string& binaryDir);

  //! Return the global generator assigned to this instance of cmake
  void SetGlobalGenerator(std::unique_ptr<cmGlobalGenerator>);

  //! Get the names of the current registered generators
  void GetRegisteredGenerators(std::vector<GeneratorInfo>& generators,
                               bool includeNamesWithPlatform = true) const;

  //! Set the name of the selected generator-specific instance.
  void SetGeneratorInstance(std::string const& instance)
  {
    this->GeneratorInstance = instance;
    this->GeneratorInstanceSet = true;
  }

  //! Set the name of the selected generator-specific platform.
  void SetGeneratorPlatform(std::string const& ts)
  {
    this->GeneratorPlatform = ts;
    this->GeneratorPlatformSet = true;
  }

  //! Set the name of the selected generator-specific toolset.
  void SetGeneratorToolset(std::string const& ts)
  {
    this->GeneratorToolset = ts;
    this->GeneratorToolsetSet = true;
  }

  bool IsAKnownSourceExtension(cm::string_view ext) const
  {
    return this->CLikeSourceFileExtensions.Test(ext) ||
      this->CudaFileExtensions.Test(ext) ||
      this->FortranFileExtensions.Test(ext);
  }

  bool IsACLikeSourceExtension(cm::string_view ext) const
  {
    return this->CLikeSourceFileExtensions.Test(ext);
  }

  bool IsAKnownExtension(cm::string_view ext) const
  {
    return this->IsAKnownSourceExtension(ext) || this->IsAHeaderExtension(ext);
  }

  std::vector<std::string> GetAllExtensions() const;

  const std::vector<std::string>& GetHeaderExtensions() const
  {
    return this->HeaderFileExtensions.ordered;
  }

  bool IsAHeaderExtension(cm::string_view ext) const
  {
    return this->HeaderFileExtensions.Test(ext);
  }

  // Strips the extension (if present and known) from a filename
  std::string StripExtension(const std::string& file) const;

  /**
   * Given a variable name, return its value (as a string).
   */
  const char* GetCacheDefinition(const std::string&) const;
  //! Add an entry into the cache
  void AddCacheEntry(const std::string& key, const char* value,
                     const char* helpString, int type);

  bool DoWriteGlobVerifyTarget() const;
  std::string const& GetGlobVerifyScript() const;
  std::string const& GetGlobVerifyStamp() const;
  void AddGlobCacheEntry(bool recurse, bool listDirectories,
                         bool followSymlinks, const std::string& relative,
                         const std::string& expression,
                         const std::vector<std::string>& files,
                         const std::string& variable,
                         cmListFileBacktrace const& bt);

  /**
   * Get the system information and write it to the file specified
   */
  int GetSystemInformation(std::vector<std::string>&);

  //! Parse environment variables
  void LoadEnvironmentPresets();

  //! Parse command line arguments
  void SetArgs(const std::vector<std::string>& args);

  //! Is this cmake running as a result of a TRY_COMPILE command
  bool GetIsInTryCompile() const;
  void SetIsInTryCompile(bool b);

  //! Parse command line arguments that might set cache values
  bool SetCacheArgs(const std::vector<std::string>&);

  using ProgressCallbackType = std::function<void(const std::string&, float)>;
  /**
   *  Set the function used by GUIs to receive progress updates
   *  Function gets passed: message as a const char*, a progress
   *  amount ranging from 0 to 1.0 and client data. The progress
   *  number provided may be negative in cases where a message is
   *  to be displayed without any progress percentage.
   */
  void SetProgressCallback(ProgressCallbackType f);

  //! this is called by generators to update the progress
  void UpdateProgress(const std::string& msg, float prog);

#if !defined(CMAKE_BOOTSTRAP)
  //! Get the variable watch object
  cmVariableWatch* GetVariableWatch() { return this->VariableWatch.get(); }
#endif

  std::vector<cmDocumentationEntry> GetGeneratorsDocumentation();

  //! Set/Get a property of this target file
  void SetProperty(const std::string& prop, const char* value);
  void AppendProperty(const std::string& prop, const std::string& value,
                      bool asString = false);
  cmProp GetProperty(const std::string& prop);
  bool GetPropertyAsBool(const std::string& prop);

  //! Get or create an cmInstalledFile instance and return a pointer to it
  cmInstalledFile* GetOrCreateInstalledFile(cmMakefile* mf,
                                            const std::string& name);

  cmInstalledFile const* GetInstalledFile(const std::string& name) const;

  InstalledFilesMap const& GetInstalledFiles() const
  {
    return this->InstalledFiles;
  }

  //! Do all the checks before running configure
  int DoPreConfigureChecks();

  void SetWorkingMode(WorkingMode mode) { this->CurrentWorkingMode = mode; }
  WorkingMode GetWorkingMode() { return this->CurrentWorkingMode; }

  //! Debug the try compile stuff by not deleting the files
  bool GetDebugTryCompile() { return this->DebugTryCompile; }
  void DebugTryCompileOn() { this->DebugTryCompile = true; }

  /**
   * Generate CMAKE_ROOT and CMAKE_COMMAND cache entries
   */
  int AddCMakePaths();

  /**
   * Get the file comparison class
   */
  cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache.get(); }

  bool WasLogLevelSetViaCLI() const { return this->LogLevelWasSetViaCLI; }

  //! Get the selected log level for `message()` commands during the cmake run.
  LogLevel GetLogLevel() const { return this->MessageLogLevel; }
  void SetLogLevel(LogLevel level) { this->MessageLogLevel = level; }
  static LogLevel StringToLogLevel(const std::string& levelStr);
  static TraceFormat StringToTraceFormat(const std::string& levelStr);

  bool HasCheckInProgress() const
  {
    return !this->CheckInProgressMessages.empty();
  }
  std::size_t GetCheckInProgressSize() const
  {
    return this->CheckInProgressMessages.size();
  }
  std::string GetTopCheckInProgressMessage()
  {
    auto message = this->CheckInProgressMessages.top();
    this->CheckInProgressMessages.pop();
    return message;
  }
  void PushCheckInProgressMessage(std::string message)
  {
    this->CheckInProgressMessages.emplace(std::move(message));
  }

  //! Should `message` command display context.
  bool GetShowLogContext() const { return this->LogContext; }
  void SetShowLogContext(bool b) { this->LogContext = b; }

  //! Do we want debug output during the cmake run.
  bool GetDebugOutput() { return this->DebugOutput; }
  void SetDebugOutputOn(bool b) { this->DebugOutput = b; }

  //! Do we want debug output from the find commands during the cmake run.
  bool GetDebugFindOutput() { return this->DebugFindOutput; }
  void SetDebugFindOutputOn(bool b) { this->DebugFindOutput = b; }

  //! Do we want trace output during the cmake run.
  bool GetTrace() const { return this->Trace; }
  void SetTrace(bool b) { this->Trace = b; }
  bool GetTraceExpand() const { return this->TraceExpand; }
  void SetTraceExpand(bool b) { this->TraceExpand = b; }
  TraceFormat GetTraceFormat() const { return this->TraceFormatVar; }
  void SetTraceFormat(TraceFormat f) { this->TraceFormatVar = f; }
  void AddTraceSource(std::string const& file)
  {
    this->TraceOnlyThisSources.push_back(file);
  }
  std::vector<std::string> const& GetTraceSources() const
  {
    return this->TraceOnlyThisSources;
  }
  cmGeneratedFileStream& GetTraceFile() { return this->TraceFile; }
  void SetTraceFile(std::string const& file);
  void PrintTraceFormatVersion();

  bool GetWarnUninitialized() { return this->WarnUninitialized; }
  void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; }
  bool GetWarnUnusedCli() { return this->WarnUnusedCli; }
  void SetWarnUnusedCli(bool b) { this->WarnUnusedCli = b; }
  bool GetCheckSystemVars() { return this->CheckSystemVars; }
  void SetCheckSystemVars(bool b) { this->CheckSystemVars = b; }

  void MarkCliAsUsed(const std::string& variable);

  /** Get the list of configurations (in upper case) considered to be
      debugging configurations.*/
  std::vector<std::string> GetDebugConfigs();

  void SetCMakeEditCommand(std::string const& s)
  {
    this->CMakeEditCommand = s;
  }
  std::string const& GetCMakeEditCommand() const
  {
    return this->CMakeEditCommand;
  }

  cmMessenger* GetMessenger() const { return this->Messenger.get(); }

  /**
   * Get the state of the suppression of developer (author) warnings.
   * Returns false, by default, if developer warnings should be shown, true
   * otherwise.
   */
  bool GetSuppressDevWarnings() const;
  /**
   * Set the state of the suppression of developer (author) warnings.
   */
  void SetSuppressDevWarnings(bool v);

  /**
   * Get the state of the suppression of deprecated warnings.
   * Returns false, by default, if deprecated warnings should be shown, true
   * otherwise.
   */
  bool GetSuppressDeprecatedWarnings() const;
  /**
   * Set the state of the suppression of deprecated warnings.
   */
  void SetSuppressDeprecatedWarnings(bool v);

  /**
   * Get the state of treating developer (author) warnings as errors.
   * Returns false, by default, if warnings should not be treated as errors,
   * true otherwise.
   */
  bool GetDevWarningsAsErrors() const;
  /**
   * Set the state of treating developer (author) warnings as errors.
   */
  void SetDevWarningsAsErrors(bool v);

  /**
   * Get the state of treating deprecated warnings as errors.
   * Returns false, by default, if warnings should not be treated as errors,
   * true otherwise.
   */
  bool GetDeprecatedWarningsAsErrors() const;
  /**
   * Set the state of treating developer (author) warnings as errors.
   */
  void SetDeprecatedWarningsAsErrors(bool v);

  /** Display a message to the user.  */
  void IssueMessage(
    MessageType t, std::string const& text,
    cmListFileBacktrace const& backtrace = cmListFileBacktrace()) const;

  //! run the --build option
  int Build(int jobs, const std::string& dir,
            const std::vector<std::string>& targets, const std::string& config,
            const std::vector<std::string>& nativeOptions, bool clean,
            bool verbose);

  //! run the --open option
  bool Open(const std::string& dir, bool dryRun);

  void UnwatchUnusedCli(const std::string& var);
  void WatchUnusedCli(const std::string& var);

  cmState* GetState() const { return this->State.get(); }
  void SetCurrentSnapshot(cmStateSnapshot const& snapshot)
  {
    this->CurrentSnapshot = snapshot;
  }
  cmStateSnapshot GetCurrentSnapshot() const { return this->CurrentSnapshot; }

  bool GetRegenerateDuringBuild() const { return this->RegenerateDuringBuild; }

#if !defined(CMAKE_BOOTSTRAP)
  cmMakefileProfilingData& GetProfilingOutput();
  bool IsProfilingEnabled() const;
#endif

protected:
  void RunCheckForUnusedVariables();
  int HandleDeleteCacheVariables(const std::string& var);

  using RegisteredGeneratorsVector =
    std::vector<std::unique_ptr<cmGlobalGeneratorFactory>>;
  RegisteredGeneratorsVector Generators;
  using RegisteredExtraGeneratorsVector =
    std::vector<cmExternalMakefileProjectGeneratorFactory*>;
  RegisteredExtraGeneratorsVector ExtraGenerators;
  void AddScriptingCommands();
  void AddProjectCommands();
  void AddDefaultGenerators();
  void AddDefaultExtraGenerators();

  std::map<std::string, DiagLevel> DiagLevels;
  std::string GeneratorInstance;
  std::string GeneratorPlatform;
  std::string GeneratorToolset;
  bool GeneratorInstanceSet = false;
  bool GeneratorPlatformSet = false;
  bool GeneratorToolsetSet = false;

  //! read in a cmake list file to initialize the cache
  void ReadListFile(const std::vector<std::string>& args,
                    const std::string& path);
  bool FindPackage(const std::vector<std::string>& args);

  //! Check if CMAKE_CACHEFILE_DIR is set. If it is not, delete the log file.
  ///  If it is set, truncate it to 50kb
  void TruncateOutputLog(const char* fname);

  /**
   * Method called to check build system integrity at build time.
   * Returns 1 if CMake should rerun and 0 otherwise.
   */
  int CheckBuildSystem();

  void SetDirectoriesFromFile(const std::string& arg);

  //! Make sure all commands are what they say they are and there is no
  /// macros.
  void CleanupCommandsAndMacros();

  void GenerateGraphViz(const std::string& fileName) const;

private:
  ProgressCallbackType ProgressCallback;
  WorkingMode CurrentWorkingMode = NORMAL_MODE;
  bool DebugOutput = false;
  bool DebugFindOutput = false;
  bool Trace = false;
  bool TraceExpand = false;
  TraceFormat TraceFormatVar = TRACE_HUMAN;
  cmGeneratedFileStream TraceFile;
  bool WarnUninitialized = false;
  bool WarnUnusedCli = true;
  bool CheckSystemVars = false;
  std::map<std::string, bool> UsedCliVariables;
  std::string CMakeEditCommand;
  std::string CXXEnvironment;
  std::string CCEnvironment;
  std::string CheckBuildSystemArgument;
  std::string CheckStampFile;
  std::string CheckStampList;
  std::string VSSolutionFile;
  std::string EnvironmentGenerator;
  FileExtensions CLikeSourceFileExtensions;
  FileExtensions HeaderFileExtensions;
  FileExtensions CudaFileExtensions;
  FileExtensions FortranFileExtensions;
  bool ClearBuildSystem = false;
  bool DebugTryCompile = false;
  bool RegenerateDuringBuild = false;
  std::unique_ptr<cmFileTimeCache> FileTimeCache;
  std::string GraphVizFile;
  InstalledFilesMap InstalledFiles;

#if !defined(CMAKE_BOOTSTRAP)
  std::unique_ptr<cmVariableWatch> VariableWatch;
  std::unique_ptr<cmFileAPI> FileAPI;
#endif

  std::unique_ptr<cmState> State;
  cmStateSnapshot CurrentSnapshot;
  std::unique_ptr<cmMessenger> Messenger;

  std::vector<std::string> TraceOnlyThisSources;

  LogLevel MessageLogLevel = LogLevel::LOG_STATUS;
  bool LogLevelWasSetViaCLI = false;
  bool LogContext = false;

  std::stack<std::string> CheckInProgressMessages;

  std::unique_ptr<cmGlobalGenerator> GlobalGenerator;

  void UpdateConversionPathTable();

  //! Print a list of valid generators to stderr.
  void PrintGeneratorList();

  std::unique_ptr<cmGlobalGenerator> EvaluateDefaultGlobalGenerator();
  void CreateDefaultGlobalGenerator();

  void AppendGlobalGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
  void AppendExtraGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);

#if !defined(CMAKE_BOOTSTRAP)
  std::unique_ptr<cmMakefileProfilingData> ProfilingOutput;
#endif
};

#define CMAKE_STANDARD_OPTIONS_TABLE                                          \
  { "-S <path-to-source>", "Explicitly specify a source directory." },        \
    { "-B <path-to-build>", "Explicitly specify a build directory." },        \
    { "-C <initial-cache>", "Pre-load a script to populate the cache." },     \
    { "-D <var>[:<type>]=<value>", "Create or update a cmake cache entry." }, \
    { "-U <globbing_expr>", "Remove matching entries from CMake cache." },    \
    { "-G <generator-name>", "Specify a build system generator." },           \
    { "-T <toolset-name>",                                                    \
      "Specify toolset name if supported by generator." },                    \
    { "-A <platform-name>",                                                   \
      "Specify platform name if supported by generator." },                   \
    { "-Wdev", "Enable developer warnings." },                                \
    { "-Wno-dev", "Suppress developer warnings." },                           \
    { "-Werror=dev", "Make developer warnings errors." },                     \
    { "-Wno-error=dev", "Make developer warnings not errors." },              \
    { "-Wdeprecated", "Enable deprecation warnings." },                       \
    { "-Wno-deprecated", "Suppress deprecation warnings." },                  \
    { "-Werror=deprecated",                                                   \
      "Make deprecated macro and function warnings "                          \
      "errors." },                                                            \
  {                                                                           \
    "-Wno-error=deprecated",                                                  \
      "Make deprecated macro and function warnings "                          \
      "not errors."                                                           \
  }

#define FOR_EACH_C90_FEATURE(F) F(c_function_prototypes)

#define FOR_EACH_C99_FEATURE(F)                                               \
  F(c_restrict)                                                               \
  F(c_variadic_macros)

#define FOR_EACH_C11_FEATURE(F) F(c_static_assert)

#define FOR_EACH_C_FEATURE(F)                                                 \
  F(c_std_90)                                                                 \
  F(c_std_99)                                                                 \
  F(c_std_11)                                                                 \
  FOR_EACH_C90_FEATURE(F)                                                     \
  FOR_EACH_C99_FEATURE(F)                                                     \
  FOR_EACH_C11_FEATURE(F)

#define FOR_EACH_CXX98_FEATURE(F) F(cxx_template_template_parameters)

#define FOR_EACH_CXX11_FEATURE(F)                                             \
  F(cxx_alias_templates)                                                      \
  F(cxx_alignas)                                                              \
  F(cxx_alignof)                                                              \
  F(cxx_attributes)                                                           \
  F(cxx_auto_type)                                                            \
  F(cxx_constexpr)                                                            \
  F(cxx_decltype)                                                             \
  F(cxx_decltype_incomplete_return_types)                                     \
  F(cxx_default_function_template_args)                                       \
  F(cxx_defaulted_functions)                                                  \
  F(cxx_defaulted_move_initializers)                                          \
  F(cxx_delegating_constructors)                                              \
  F(cxx_deleted_functions)                                                    \
  F(cxx_enum_forward_declarations)                                            \
  F(cxx_explicit_conversions)                                                 \
  F(cxx_extended_friend_declarations)                                         \
  F(cxx_extern_templates)                                                     \
  F(cxx_final)                                                                \
  F(cxx_func_identifier)                                                      \
  F(cxx_generalized_initializers)                                             \
  F(cxx_inheriting_constructors)                                              \
  F(cxx_inline_namespaces)                                                    \
  F(cxx_lambdas)                                                              \
  F(cxx_local_type_template_args)                                             \
  F(cxx_long_long_type)                                                       \
  F(cxx_noexcept)                                                             \
  F(cxx_nonstatic_member_init)                                                \
  F(cxx_nullptr)                                                              \
  F(cxx_override)                                                             \
  F(cxx_range_for)                                                            \
  F(cxx_raw_string_literals)                                                  \
  F(cxx_reference_qualified_functions)                                        \
  F(cxx_right_angle_brackets)                                                 \
  F(cxx_rvalue_references)                                                    \
  F(cxx_sizeof_member)                                                        \
  F(cxx_static_assert)                                                        \
  F(cxx_strong_enums)                                                         \
  F(cxx_thread_local)                                                         \
  F(cxx_trailing_return_types)                                                \
  F(cxx_unicode_literals)                                                     \
  F(cxx_uniform_initialization)                                               \
  F(cxx_unrestricted_unions)                                                  \
  F(cxx_user_literals)                                                        \
  F(cxx_variadic_macros)                                                      \
  F(cxx_variadic_templates)

#define FOR_EACH_CXX14_FEATURE(F)                                             \
  F(cxx_aggregate_default_initializers)                                       \
  F(cxx_attribute_deprecated)                                                 \
  F(cxx_binary_literals)                                                      \
  F(cxx_contextual_conversions)                                               \
  F(cxx_decltype_auto)                                                        \
  F(cxx_digit_separators)                                                     \
  F(cxx_generic_lambdas)                                                      \
  F(cxx_lambda_init_captures)                                                 \
  F(cxx_relaxed_constexpr)                                                    \
  F(cxx_return_type_deduction)                                                \
  F(cxx_variable_templates)

#define FOR_EACH_CXX_FEATURE(F)                                               \
  F(cxx_std_98)                                                               \
  F(cxx_std_11)                                                               \
  F(cxx_std_14)                                                               \
  F(cxx_std_17)                                                               \
  F(cxx_std_20)                                                               \
  FOR_EACH_CXX98_FEATURE(F)                                                   \
  FOR_EACH_CXX11_FEATURE(F)                                                   \
  FOR_EACH_CXX14_FEATURE(F)

#define FOR_EACH_CUDA_FEATURE(F)                                              \
  F(cuda_std_03)                                                              \
  F(cuda_std_11)                                                              \
  F(cuda_std_14)                                                              \
  F(cuda_std_17)                                                              \
  F(cuda_std_20)

#endif
