#pragma once #include #include #include #define REF_GETTERS(var) \ constexpr decltype(var)& get_##var() { \ return var; \ } \ constexpr decltype(var) const& get_##var() const { \ return var; \ } namespace OpenVic { struct ReturnByValueProperty {}; /* * Template function used to choose the return type and provide the implementation for the * for variable getters created using the PROPERTY macro. */ template inline constexpr decltype(auto) _get_property(const T& property) { if constexpr(std::is_reference_v) { /* Return const reference */ return property; } else if constexpr (std::same_as) { /* Return std::string_view looking at std::string */ return std::string_view { property }; } else if constexpr ( std::integral || std::floating_point || std::is_enum::value || std::derived_from ) { /* Return value */ return T { property }; } else if constexpr(std::is_pointer::value) { /* Return const pointer */ return static_cast>>>(property); } else { /* Return const reference */ return property; } } /* * Use this on a variable delcaration to generate a getter function. It assumes the variable is private and so * sets the accessibility modifier state back to private after declaring the getter as public. * Examples: * int PROPERTY(x); // int x; int get_x() const; * const std::string PROPERTY(name); // const std::string name; std::string_view get_name() const; * std::vector PROPERTY(sizes); // std::vector sizes; std::vector const& get_sizes() const; * uint8_t const* PROPERTY(data); // uint8_t const* data; uint8_t const* get_data() const; * colour_t* PROPERTY(pixels); // colour_t* pixels; colour_t const* get_pixels() const; * CultureGroup const& PROPERTY(group);// CultureGroup const& group; CultureGroup const& get_group() const; * Province& PROPERTY(province); // Province& province; Province const& get_province() const; */ #define PROPERTY(NAME) \ NAME; \ \ public: \ auto get_##NAME() const -> decltype(OpenVic::_get_property(NAME)) { \ return OpenVic::_get_property(NAME); \ } \ \ private: }