Skip to content

Commit d823505

Browse files
authored
Merge pull request #5391 from ab9rf/update-to-concepts
code modernization
2 parents 9f6e0cb + 3745107 commit d823505

File tree

3 files changed

+113
-135
lines changed

3 files changed

+113
-135
lines changed

library/include/DataDefs.h

Lines changed: 68 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -494,22 +494,18 @@ namespace df
494494
using DFHack::DfLinkedList;
495495
using DFHack::DfOtherVectors;
496496

497-
template<class T>
498-
typename std::enable_if<
499-
std::is_copy_assignable<T>::value,
500-
void*
501-
>::type allocator_try_assign(void *out, const void *in) {
502-
*(T*)out = *(const T*)in;
503-
return out;
504-
}
497+
template<typename T> concept copy_assignable = std::assignable_from<T&, T&> && std::assignable_from<T&, const T&>;
505498

506-
template<class T>
507-
typename std::enable_if<
508-
!std::is_copy_assignable<T>::value,
509-
void*
510-
>::type allocator_try_assign(void *out, const void *in) {
511-
// assignment is not possible; do nothing
512-
return NULL;
499+
template<typename T>
500+
void* allocator_try_assign(void *out, const void *in) {
501+
if constexpr (copy_assignable<T>) {
502+
*(T*)out = *(const T*)in;
503+
return out;
504+
}
505+
else {
506+
// assignment is not possible; do nothing
507+
return nullptr;
508+
}
513509
}
514510

515511
#pragma GCC diagnostic push
@@ -651,98 +647,87 @@ namespace DFHack {
651647
/**
652648
* Return the next item in the enum, wrapping to the first one at the end if 'wrap' is true (otherwise an invalid item).
653649
*/
654-
template<class T>
655-
inline typename std::enable_if<
656-
!df::enum_traits<T>::is_complex,
657-
typename df::enum_traits<T>::enum_type
658-
>::type next_enum_item(T v, bool wrap = true)
650+
template <typename T> concept complex_enum = (df::enum_traits<T>::is_complex);
651+
652+
template<typename T>
653+
inline auto next_enum_item(T v, bool wrap = true) -> typename df::enum_traits<T>::enum_type
659654
{
660-
typedef df::enum_traits<T> traits;
661-
typedef typename traits::base_type base_type;
662-
base_type iv = base_type(v);
663-
if (iv < traits::last_item_value)
664-
{
665-
return T(iv + 1);
666-
}
667-
else
655+
using traits = df::enum_traits<T>;
656+
657+
if constexpr (complex_enum<T>)
668658
{
669-
if (wrap)
670-
return traits::first_item;
659+
const auto& complex = traits::complex;
660+
const auto it = complex.value_index_map.find(v);
661+
if (it != complex.value_index_map.end())
662+
{
663+
if (!wrap && it->second + 1 == complex.size())
664+
{
665+
return T(traits::last_item_value + 1);
666+
}
667+
size_t next_index = (it->second + 1) % complex.size();
668+
return T(complex.index_value_map[next_index]);
669+
}
671670
else
672671
return T(traits::last_item_value + 1);
673672
}
674-
}
675-
676-
template<class T>
677-
inline typename std::enable_if<
678-
df::enum_traits<T>::is_complex,
679-
typename df::enum_traits<T>::enum_type
680-
>::type next_enum_item(T v, bool wrap = true)
681-
{
682-
typedef df::enum_traits<T> traits;
683-
const auto &complex = traits::complex;
684-
const auto it = complex.value_index_map.find(v);
685-
if (it != complex.value_index_map.end())
673+
else
686674
{
687-
if (!wrap && it->second + 1 == complex.size())
675+
using base_type = typename traits::base_type;
676+
base_type iv = base_type(v);
677+
if (iv < traits::last_item_value)
688678
{
689-
return T(traits::last_item_value + 1);
679+
return T(iv + 1);
680+
}
681+
else
682+
{
683+
if (wrap)
684+
return traits::first_item;
685+
else
686+
return T(traits::last_item_value + 1);
690687
}
691-
size_t next_index = (it->second + 1) % complex.size();
692-
return T(complex.index_value_map[next_index]);
693688
}
694-
else
695-
return T(traits::last_item_value + 1);
696689
}
697690

698691
/**
699692
* Check if the value is valid for its enum type.
700693
*/
701-
template<class T>
702-
inline typename std::enable_if<
703-
!df::enum_traits<T>::is_complex,
704-
bool
705-
>::type is_valid_enum_item(T v)
694+
template<typename T>
695+
inline bool is_valid_enum_item(T v)
706696
{
707-
return df::enum_traits<T>::is_valid(v);
697+
if constexpr (complex_enum<T>)
698+
{
699+
const auto& complex = df::enum_traits<T>::complex;
700+
return complex.value_index_map.find(v) != complex.value_index_map.end();
701+
}
702+
else
703+
{
704+
return df::enum_traits<T>::is_valid(v);
705+
}
708706
}
709707

710-
template<class T>
711-
inline typename std::enable_if<
712-
df::enum_traits<T>::is_complex,
713-
bool
714-
>::type is_valid_enum_item(T v)
715-
{
716-
const auto &complex = df::enum_traits<T>::complex;
717-
return complex.value_index_map.find(v) != complex.value_index_map.end();
718-
}
719708

720709
/**
721710
* Return the enum item key string pointer, or NULL if none.
722711
*/
723712
template<class T>
724-
inline typename std::enable_if<
725-
!df::enum_traits<T>::is_complex,
726-
const char *
727-
>::type enum_item_raw_key(T val) {
728-
typedef df::enum_traits<T> traits;
729-
return traits::is_valid(val) ? traits::key_table[(short)val - traits::first_item_value] : NULL;
730-
}
731-
732-
template<class T>
733-
inline typename std::enable_if<
734-
df::enum_traits<T>::is_complex,
735-
const char *
736-
>::type enum_item_raw_key(T val) {
737-
typedef df::enum_traits<T> traits;
738-
const auto &value_index_map = traits::complex.value_index_map;
739-
auto it = value_index_map.find(val);
740-
if (it != value_index_map.end())
741-
return traits::key_table[it->second];
713+
const char* enum_item_raw_key(T val) {
714+
using traits = df::enum_traits<T>;
715+
if constexpr (complex_enum<T>)
716+
{
717+
const auto& value_index_map = traits::complex.value_index_map;
718+
auto it = value_index_map.find(val);
719+
if (it != value_index_map.end())
720+
return traits::key_table[it->second];
721+
else
722+
return nullptr;
723+
}
742724
else
743-
return NULL;
725+
{
726+
return traits::is_valid(val) ? traits::key_table[(short)val - traits::first_item_value] : nullptr;
727+
}
744728
}
745729

730+
746731
/**
747732
* Return the enum item key string pointer, or "?" if none.
748733
*/
@@ -773,7 +758,7 @@ namespace DFHack {
773758
*/
774759
template<class T>
775760
inline bool find_enum_item(T *var, const std::string &name) {
776-
typedef df::enum_traits<T> traits;
761+
using traits = df::enum_traits<T>;
777762
int size = traits::last_item_value-traits::first_item_value+1;
778763
int idx = findEnumItem(name, size, traits::key_table);
779764
if (idx < 0) return false;

library/include/LuaTools.h

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ distribution.
3232
#include <type_traits>
3333
#include <unordered_map>
3434
#include <unordered_set>
35+
#include <concepts>
3536

3637
#include "Core.h"
3738
#include "ColorText.h"
@@ -60,7 +61,7 @@ namespace DFHack {
6061
};
6162
}
6263

63-
namespace DFHack {namespace Lua {
64+
namespace DFHack::Lua {
6465
/**
6566
* Create or initialize a lua interpreter with access to DFHack tools.
6667
*/
@@ -140,34 +141,39 @@ namespace DFHack {namespace Lua {
140141
DFHACK_EXPORT void CheckDFAssign(lua_State *state, type_identity *type,
141142
void *target, int val_index, bool exact_type = false);
142143

144+
template<typename T> concept df_object = requires(T x)
145+
{
146+
{ df::identity_traits<T>::get() } -> std::convertible_to<df::type_identity*>;
147+
};
148+
143149
/**
144150
* Push the pointer onto the stack as a wrapped DF object of a specific type.
145151
*/
146-
template<class T>
152+
template<df_object T>
147153
void PushDFObject(lua_State *state, T *ptr) {
148154
PushDFObject(state, df::identity_traits<T>::get(), ptr);
149155
}
150156

151157
/**
152158
* Check that the value is a wrapped DF object of the correct type, and if so return the pointer.
153159
*/
154-
template<class T>
160+
template<df_object T>
155161
T *GetDFObject(lua_State *state, int val_index, bool exact_type = false) {
156162
return (T*)GetDFObject(state, df::identity_traits<T>::get(), val_index, exact_type);
157163
}
158164

159165
/**
160166
* Check that the value is a wrapped DF object of the correct type, and if so return the pointer. Otherwise throw an argument type error.
161167
*/
162-
template<class T>
168+
template<df_object T>
163169
T *CheckDFObject(lua_State *state, int val_index, bool exact_type = false) {
164170
return (T*)CheckDFObject(state, df::identity_traits<T>::get(), val_index, exact_type);
165171
}
166172

167173
/**
168174
* Assign the value at val_index to the target using df.assign().
169175
*/
170-
template<class T>
176+
template<df_object T>
171177
bool AssignDFObject(color_ostream &out, lua_State *state, T *target,
172178
int val_index, bool exact_type = false, bool perr = true) {
173179
return AssignDFObject(out, state, df::identity_traits<T>::get(),
@@ -178,7 +184,7 @@ namespace DFHack {namespace Lua {
178184
* Assign the value at val_index to the target using df.assign().
179185
* Throws in case of an error.
180186
*/
181-
template<class T>
187+
template<df_object T>
182188
void CheckDFAssign(lua_State *state, T *target, int val_index, bool exact_type = false) {
183189
CheckDFAssign(state, df::identity_traits<T>::get(), target, val_index, exact_type);
184190
}
@@ -298,42 +304,33 @@ namespace DFHack {namespace Lua {
298304
/**
299305
* Push utility functions
300306
*/
301-
#if 0
302-
#define NUMBER_PUSH(type) inline void Push(lua_State *state, type value) { lua_pushnumber(state, value); }
303-
NUMBER_PUSH(char)
304-
NUMBER_PUSH(int8_t) NUMBER_PUSH(uint8_t)
305-
NUMBER_PUSH(int16_t) NUMBER_PUSH(uint16_t)
306-
NUMBER_PUSH(int32_t) NUMBER_PUSH(uint32_t)
307-
NUMBER_PUSH(int64_t) NUMBER_PUSH(uint64_t)
308-
NUMBER_PUSH(float) NUMBER_PUSH(double)
309-
#undef NUMBER_PUSH
310-
#else
311-
template<class T>
312-
inline typename std::enable_if<std::is_integral<T>::value || std::is_enum<T>::value>::type
313-
Push(lua_State *state, T value) {
307+
template<typename T> concept lua_integral = (std::is_integral_v<T> || std::is_enum_v<T>);
308+
309+
inline void Push(lua_State *state, lua_integral auto value) {
314310
lua_pushinteger(state, value);
315311
}
316-
template<class T>
317-
inline typename std::enable_if<std::is_floating_point<T>::value>::type
318-
Push(lua_State *state, T value) {
312+
inline void Push(lua_State* state, std::floating_point auto value) {
319313
lua_pushnumber(state, lua_Number(value));
320314
}
321-
#endif
322315
inline void Push(lua_State *state, bool value) {
323316
lua_pushboolean(state, value);
324317
}
325-
inline void Push(lua_State *state, const char *str) {
326-
lua_pushstring(state, str);
327-
}
328-
inline void Push(lua_State *state, const std::string &str) {
329-
lua_pushlstring(state, str.data(), str.size());
318+
319+
template<typename T> concept lua_string = (std::convertible_to<T, std::string_view>);
320+
321+
inline void Push(lua_State *state, lua_string auto str) {
322+
std::string_view sv{ str };
323+
lua_pushlstring(state, sv.data(), sv.size());
330324
}
325+
331326
DFHACK_EXPORT void Push(lua_State *state, const df::coord &obj);
332327
DFHACK_EXPORT void Push(lua_State *state, const df::coord2d &obj);
333328
void Push(lua_State *state, const Units::NoblePosition &pos);
334329
DFHACK_EXPORT void Push(lua_State *state, const MaterialInfo &info);
335330
DFHACK_EXPORT void Push(lua_State *state, const Screen::Pen &info);
336-
template<class T> inline void Push(lua_State *state, T *ptr) {
331+
332+
template<df_object T> inline void Push(lua_State *state, T *ptr)
333+
{
337334
PushDFObject(state, ptr);
338335
}
339336

@@ -472,10 +469,6 @@ namespace DFHack {namespace Lua {
472469
* All accesses must be done under CoreSuspender.
473470
*/
474471
namespace Core {
475-
// DFHACK_EXPORT extern lua_State *State;
476-
477-
// Not exported; for use by the Core class
478-
lua_State* Init(color_ostream &out);
479472
DFHACK_EXPORT void Reset(color_ostream &out, const char *where);
480473

481474
// Events signalled by the core
@@ -559,7 +552,7 @@ namespace DFHack {namespace Lua {
559552
Notification(function_identity_base *handler = NULL)
560553
: state(NULL), key(NULL), handler(handler), count(0) {}
561554

562-
int get_listener_count() { return count; }
555+
int get_listener_count() const { return count; }
563556
lua_State *get_state() { return state; }
564557
function_identity_base *get_handler() { return handler; }
565558

@@ -572,7 +565,7 @@ namespace DFHack {namespace Lua {
572565
void bind(lua_State *state, const char *name);
573566
void bind(lua_State *state, void *key);
574567
};
575-
}}
568+
}
576569

577570
#define DEFINE_LUA_EVENT_0(name, handler) \
578571
static DFHack::Lua::Notification name##_event(df::wrap_function(handler, true)); \

0 commit comments

Comments
 (0)