]> git.sesse.net Git - stockfish/blobdiff - src/tune.h
Merge remote-tracking branch 'upstream/master'
[stockfish] / src / tune.h
index 440d950a9ec477b3b60a61a3a8f3359d39257b5f..480aea165b59d1f4b6791d096180d1940ba3ee2b 100644 (file)
 #ifndef TUNE_H_INCLUDED
 #define TUNE_H_INCLUDED
 
+#include <cstddef>
 #include <memory>
 #include <string>
-#include <type_traits>
+#include <type_traits>  // IWYU pragma: keep
+#include <utility>
 #include <vector>
 
 namespace Stockfish {
+enum Value : int;
 
-using Range = std::pair<int, int>; // Option's min-max values
-using RangeFun = Range (int);
+using Range    = std::pair<int, int>;  // Option's min-max values
+using RangeFun = Range(int);
 
 // Default Range function, to calculate Option's min-max values
-inline Range default_range(int v) {
-  return v > 0 ? Range(0, 2 * v) : Range(2 * v, 0);
-}
+inline Range default_range(int v) { return v > 0 ? Range(0, 2 * v) : Range(2 * v, 0); }
 
 struct SetRange {
-  explicit SetRange(RangeFun f) : fun(f) {}
-  SetRange(int min, int max) : fun(nullptr), range(min, max) {}
-  Range operator()(int v) const { return fun ? fun(v) : range; }
-
-  RangeFun* fun;
-  Range range;
+    explicit SetRange(RangeFun f) :
+        fun(f) {}
+    SetRange(int min, int max) :
+        fun(nullptr),
+        range(min, max) {}
+    Range operator()(int v) const { return fun ? fun(v) : range; }
+
+    RangeFun* fun;
+    Range     range;
 };
 
 #define SetDefaultRange SetRange(default_range)
 
 
-/// Tune class implements the 'magic' code that makes the setup of a fishtest
-/// tuning session as easy as it can be. Mainly you have just to remove const
-/// qualifiers from the variables you want to tune and flag them for tuning, so
-/// if you have:
-///
-///   const Score myScore = S(10, 15);
-///   const Value myValue[][2] = { { V(100), V(20) }, { V(7), V(78) } };
-///
-/// If you have a my_post_update() function to run after values have been updated,
-/// and a my_range() function to set custom Option's min-max values, then you just
-/// remove the 'const' qualifiers and write somewhere below in the file:
-///
-///   TUNE(SetRange(my_range), myScore, myValue, my_post_update);
-///
-/// You can also set the range directly, and restore the default at the end
-///
-///   TUNE(SetRange(-100, 100), myScore, SetDefaultRange);
-///
-/// In case update function is slow and you have many parameters, you can add:
-///
-///   UPDATE_ON_LAST();
-///
-/// And the values update, including post update function call, will be done only
-/// once, after the engine receives the last UCI option, that is the one defined
-/// and created as the last one, so the GUI should send the options in the same
-/// order in which have been defined.
+// Tune class implements the 'magic' code that makes the setup of a fishtest tuning
+// session as easy as it can be. Mainly you have just to remove const qualifiers
+// from the variables you want to tune and flag them for tuning, so if you have:
+//
+//   const Value myValue[][2] = { { V(100), V(20) }, { V(7), V(78) } };
+//
+// If you have a my_post_update() function to run after values have been updated,
+// and a my_range() function to set custom Option's min-max values, then you just
+// remove the 'const' qualifiers and write somewhere below in the file:
+//
+//   TUNE(SetRange(my_range), myValue, my_post_update);
+//
+// You can also set the range directly, and restore the default at the end
+//
+//   TUNE(SetRange(-100, 100), myValue, SetDefaultRange);
+//
+// In case update function is slow and you have many parameters, you can add:
+//
+//   UPDATE_ON_LAST();
+//
+// And the values update, including post update function call, will be done only
+// once, after the engine receives the last UCI option, that is the one defined
+// and created as the last one, so the GUI should send the options in the same
+// order in which have been defined.
 
 class Tune {
 
-  using PostUpdate = void (); // Post-update function
-
-  Tune() { read_results(); }
-  Tune(const Tune&) = delete;
-  void operator=(const Tune&) = delete;
-  void read_results();
-
-  static Tune& instance() { static Tune t; return t; } // Singleton
-
-  // Use polymorphism to accommodate Entry of different types in the same vector
-  struct EntryBase {
-    virtual ~EntryBase() = default;
-    virtual void init_option() = 0;
-    virtual void read_option() = 0;
-  };
-
-  template<typename T>
-  struct Entry : public EntryBase {
-
-    static_assert(!std::is_const<T>::value, "Parameter cannot be const!");
-
-    static_assert(   std::is_same<T,   int>::value
-                  || std::is_same<T, Value>::value
-                  || std::is_same<T, Score>::value
-                  || std::is_same<T, PostUpdate>::value, "Parameter type not supported!");
-
-    Entry(const std::string& n, T& v, const SetRange& r) : name(n), value(v), range(r) {}
-    void operator=(const Entry&) = delete; // Because 'value' is a reference
-    void init_option() override;
-    void read_option() override;
-
-    std::string name;
-    T& value;
-    SetRange range;
-  };
-
-  // Our facility to fill the container, each Entry corresponds to a parameter
-  // to tune. We use variadic templates to deal with an unspecified number of
-  // entries, each one of a possible different type.
-  static std::string next(std::string& names, bool pop = true);
-
-  int add(const SetRange&, std::string&&) { return 0; }
-
-  template<typename T, typename... Args>
-  int add(const SetRange& range, std::string&& names, T& value, Args&&... args) {
-    list.push_back(std::unique_ptr<EntryBase>(new Entry<T>(next(names), value, range)));
-    return add(range, std::move(names), args...);
-  }
-
-  // Template specialization for arrays: recursively handle multi-dimensional arrays
-  template<typename T, size_t N, typename... Args>
-  int add(const SetRange& range, std::string&& names, T (&value)[N], Args&&... args) {
-    for (size_t i = 0; i < N; i++)
-        add(range, next(names, i == N - 1) + "[" + std::to_string(i) + "]", value[i]);
-    return add(range, std::move(names), args...);
-  }
-
-  // Template specialization for SetRange
-  template<typename... Args>
-  int add(const SetRange&, std::string&& names, SetRange& value, Args&&... args) {
-    return add(value, (next(names), std::move(names)), args...);
-  }
-
-  std::vector<std::unique_ptr<EntryBase>> list;
-
-public:
-  template<typename... Args>
-  static int add(const std::string& names, Args&&... args) {
-    return instance().add(SetDefaultRange, names.substr(1, names.size() - 2), args...); // Remove trailing parenthesis
-  }
-  static void init() { for (auto& e : instance().list) e->init_option(); read_options(); } // Deferred, due to UCI::Options access
-  static void read_options() { for (auto& e : instance().list) e->read_option(); }
-  static bool update_on_last;
+    using PostUpdate = void();  // Post-update function
+
+    Tune() { read_results(); }
+    Tune(const Tune&)           = delete;
+    void operator=(const Tune&) = delete;
+    void read_results();
+
+    static Tune& instance() {
+        static Tune t;
+        return t;
+    }  // Singleton
+
+    // Use polymorphism to accommodate Entry of different types in the same vector
+    struct EntryBase {
+        virtual ~EntryBase()       = default;
+        virtual void init_option() = 0;
+        virtual void read_option() = 0;
+    };
+
+    template<typename T>
+    struct Entry: public EntryBase {
+
+        static_assert(!std::is_const_v<T>, "Parameter cannot be const!");
+
+        static_assert(std::is_same_v<T, int> || std::is_same_v<T, Value>
+                        || std::is_same_v<T, PostUpdate>,
+                      "Parameter type not supported!");
+
+        Entry(const std::string& n, T& v, const SetRange& r) :
+            name(n),
+            value(v),
+            range(r) {}
+        void operator=(const Entry&) = delete;  // Because 'value' is a reference
+        void init_option() override;
+        void read_option() override;
+
+        std::string name;
+        T&          value;
+        SetRange    range;
+    };
+
+    // Our facility to fill the container, each Entry corresponds to a parameter
+    // to tune. We use variadic templates to deal with an unspecified number of
+    // entries, each one of a possible different type.
+    static std::string next(std::string& names, bool pop = true);
+
+    int add(const SetRange&, std::string&&) { return 0; }
+
+    template<typename T, typename... Args>
+    int add(const SetRange& range, std::string&& names, T& value, Args&&... args) {
+        list.push_back(std::unique_ptr<EntryBase>(new Entry<T>(next(names), value, range)));
+        return add(range, std::move(names), args...);
+    }
+
+    // Template specialization for arrays: recursively handle multi-dimensional arrays
+    template<typename T, size_t N, typename... Args>
+    int add(const SetRange& range, std::string&& names, T (&value)[N], Args&&... args) {
+        for (size_t i = 0; i < N; i++)
+            add(range, next(names, i == N - 1) + "[" + std::to_string(i) + "]", value[i]);
+        return add(range, std::move(names), args...);
+    }
+
+    // Template specialization for SetRange
+    template<typename... Args>
+    int add(const SetRange&, std::string&& names, SetRange& value, Args&&... args) {
+        return add(value, (next(names), std::move(names)), args...);
+    }
+
+    std::vector<std::unique_ptr<EntryBase>> list;
+
+   public:
+    template<typename... Args>
+    static int add(const std::string& names, Args&&... args) {
+        return instance().add(SetDefaultRange, names.substr(1, names.size() - 2),
+                              args...);  // Remove trailing parenthesis
+    }
+    static void init() {
+        for (auto& e : instance().list)
+            e->init_option();
+        read_options();
+    }  // Deferred, due to UCI::Options access
+    static void read_options() {
+        for (auto& e : instance().list)
+            e->read_option();
+    }
+    static bool update_on_last;
 };
 
-// Some macro magic :-) we define a dummy int variable that compiler initializes calling Tune::add()
+// Some macro magic :-) we define a dummy int variable that the compiler initializes calling Tune::add()
 #define STRINGIFY(x) #x
-#define UNIQUE2(x, y) x ## y
-#define UNIQUE(x, y) UNIQUE2(x, y) // Two indirection levels to expand __LINE__
+#define UNIQUE2(x, y) x##y
+#define UNIQUE(x, y) UNIQUE2(x, y)  // Two indirection levels to expand __LINE__
 #define TUNE(...) int UNIQUE(p, __LINE__) = Tune::add(STRINGIFY((__VA_ARGS__)), __VA_ARGS__)
 
 #define UPDATE_ON_LAST() bool UNIQUE(p, __LINE__) = Tune::update_on_last = true
 
-} // namespace Stockfish
+}  // namespace Stockfish
 
-#endif // #ifndef TUNE_H_INCLUDED
+#endif  // #ifndef TUNE_H_INCLUDED