mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-25 03:26:24 +08:00
add clang-format
This introduces clang-format to enforce a consistent code style for Stockfish. Having a documented and consistent style across the code will make contributing easier for new developers, and will make larger changes to the codebase easier to make. To facilitate formatting, this PR includes a Makefile target (`make format`) to format the code, this requires clang-format (version 17 currently) to be installed locally. Installing clang-format is straightforward on most OS and distros (e.g. with https://apt.llvm.org/, brew install clang-format, etc), as this is part of quite commonly used suite of tools and compilers (llvm / clang). Additionally, a CI action is present that will verify if the code requires formatting, and comment on the PR as needed. Initially, correct formatting is not required, it will be done by maintainers as part of the merge or in later commits, but obviously this is encouraged. fixes https://github.com/official-stockfish/Stockfish/issues/3608 closes https://github.com/official-stockfish/Stockfish/pull/4790 Co-Authored-By: Joost VandeVondele <Joost.VandeVondele@gmail.com>
This commit is contained in:
committed by
Joost VandeVondele
parent
8366ec48ae
commit
2d0237db3f
159
src/tune.h
159
src/tune.h
@@ -22,28 +22,29 @@
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits> // IWYU pragma: keep
|
||||
#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; }
|
||||
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;
|
||||
RangeFun* fun;
|
||||
Range range;
|
||||
};
|
||||
|
||||
#define SetDefaultRange SetRange(default_range)
|
||||
@@ -76,88 +77,102 @@ struct SetRange {
|
||||
|
||||
class Tune {
|
||||
|
||||
using PostUpdate = void (); // Post-update function
|
||||
using PostUpdate = void(); // Post-update function
|
||||
|
||||
Tune() { read_results(); }
|
||||
Tune(const Tune&) = delete;
|
||||
void operator=(const Tune&) = delete;
|
||||
void read_results();
|
||||
Tune() { read_results(); }
|
||||
Tune(const Tune&) = delete;
|
||||
void operator=(const Tune&) = delete;
|
||||
void read_results();
|
||||
|
||||
static Tune& instance() { static Tune t; return t; } // Singleton
|
||||
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;
|
||||
};
|
||||
// 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 {
|
||||
template<typename T>
|
||||
struct Entry: public EntryBase {
|
||||
|
||||
static_assert(!std::is_const_v<T>, "Parameter cannot be const!");
|
||||
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!");
|
||||
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;
|
||||
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;
|
||||
};
|
||||
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);
|
||||
// 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; }
|
||||
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, 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 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...);
|
||||
}
|
||||
// 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;
|
||||
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;
|
||||
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 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
|
||||
|
||||
Reference in New Issue
Block a user