| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #ifndef TUNE_H_INCLUDED |
| #define TUNE_H_INCLUDED |
|
|
| #include <memory> |
| #include <string> |
| #include <type_traits> |
| #include <vector> |
|
|
| namespace Stockfish { |
|
|
| typedef std::pair<int, int> Range; |
| typedef Range (RangeFun) (int); |
|
|
| |
| 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; |
| }; |
|
|
| #define SetDefaultRange SetRange(default_range) |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| class Tune { |
|
|
| typedef void (PostUpdate) (); |
|
|
| Tune() { read_results(); } |
| Tune(const Tune&) = delete; |
| void operator=(const Tune&) = delete; |
| void read_results(); |
|
|
| static Tune& instance() { static Tune t; return t; } |
|
|
| |
| 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; |
| void init_option() override; |
| void read_option() override; |
|
|
| std::string name; |
| T& value; |
| SetRange range; |
| }; |
|
|
| |
| |
| |
| 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<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<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...); |
| } |
| static void init() { for (auto& e : instance().list) e->init_option(); read_options(); } |
| static void read_options() { for (auto& e : instance().list) e->read_option(); } |
| static bool update_on_last; |
| }; |
|
|
| |
| #define STRINGIFY(x) #x |
| #define UNIQUE2(x, y) x ## y |
| #define UNIQUE(x, y) UNIQUE2(x, y) |
| #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 |
|
|
| } |
|
|
| #endif |
|
|