mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-18 01:30:56 +00:00
Adds a prototype reflective enum.
I need to make this scopeable before it is acceptable.
This commit is contained in:
parent
a74d8bd6e8
commit
6a9b14f7d1
@ -9,19 +9,17 @@
|
|||||||
#ifndef Analyser_Static_Macintosh_Target_h
|
#ifndef Analyser_Static_Macintosh_Target_h
|
||||||
#define Analyser_Static_Macintosh_Target_h
|
#define Analyser_Static_Macintosh_Target_h
|
||||||
|
|
||||||
|
#include "../../../Reflection/Enum.h"
|
||||||
|
|
||||||
|
ReflectiveEnum(MacintoshModel, int, Mac128k, Mac512k, Mac128ke, MacPlus);
|
||||||
|
|
||||||
namespace Analyser {
|
namespace Analyser {
|
||||||
namespace Static {
|
namespace Static {
|
||||||
namespace Macintosh {
|
namespace Macintosh {
|
||||||
|
|
||||||
struct Target: public ::Analyser::Static::Target {
|
|
||||||
enum class Model {
|
|
||||||
Mac128k,
|
|
||||||
Mac512k,
|
|
||||||
Mac512ke,
|
|
||||||
MacPlus
|
|
||||||
};
|
|
||||||
|
|
||||||
Model model = Model::MacPlus;
|
struct Target: public ::Analyser::Static::Target {
|
||||||
|
MacintoshModel model = MacintoshModel::MacPlus;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1138,6 +1138,7 @@
|
|||||||
4B643F3C1D77AE5C00D431D6 /* CSMachine+Target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CSMachine+Target.h"; sourceTree = "<group>"; };
|
4B643F3C1D77AE5C00D431D6 /* CSMachine+Target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CSMachine+Target.h"; sourceTree = "<group>"; };
|
||||||
4B643F3E1D77B88000D431D6 /* DocumentController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DocumentController.swift; sourceTree = "<group>"; };
|
4B643F3E1D77B88000D431D6 /* DocumentController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DocumentController.swift; sourceTree = "<group>"; };
|
||||||
4B644ED023F0FB55006C0CC5 /* ScanSynchroniser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ScanSynchroniser.hpp; sourceTree = "<group>"; };
|
4B644ED023F0FB55006C0CC5 /* ScanSynchroniser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ScanSynchroniser.hpp; sourceTree = "<group>"; };
|
||||||
|
4B644ED123FAF162006C0CC5 /* Enum.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Enum.h; path = ../../Reflection/Enum.h; sourceTree = "<group>"; };
|
||||||
4B65085F22F4CF8D009C1100 /* Keyboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = "<group>"; };
|
4B65085F22F4CF8D009C1100 /* Keyboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = "<group>"; };
|
||||||
4B670A832401CB8400D4E002 /* z80memptr.tap */ = {isa = PBXFileReference; lastKnownFileType = file; path = z80memptr.tap; sourceTree = "<group>"; };
|
4B670A832401CB8400D4E002 /* z80memptr.tap */ = {isa = PBXFileReference; lastKnownFileType = file; path = z80memptr.tap; sourceTree = "<group>"; };
|
||||||
4B670A852401CB8400D4E002 /* z80ccf.tap */ = {isa = PBXFileReference; lastKnownFileType = file; path = z80ccf.tap; sourceTree = "<group>"; };
|
4B670A852401CB8400D4E002 /* z80ccf.tap */ = {isa = PBXFileReference; lastKnownFileType = file; path = z80ccf.tap; sourceTree = "<group>"; };
|
||||||
@ -3246,6 +3247,7 @@
|
|||||||
4BB73E951B587A5100552FC2 = {
|
4BB73E951B587A5100552FC2 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
4B644ED123FAF162006C0CC5 /* Enum.h */,
|
||||||
4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */,
|
4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */,
|
||||||
4B51F70820A521D700AFA2C1 /* Activity */,
|
4B51F70820A521D700AFA2C1 /* Activity */,
|
||||||
4B8944E2201967B4007DE474 /* Analyser */,
|
4B8944E2201967B4007DE474 /* Analyser */,
|
||||||
|
80
Reflection/Enum.h
Normal file
80
Reflection/Enum.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
//
|
||||||
|
// Enum.h
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 17/02/2020.
|
||||||
|
// Copyright © 2020 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef Enum_h
|
||||||
|
#define Enum_h
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
namespace Reflection {
|
||||||
|
|
||||||
|
template <typename EnumType> struct Enum {
|
||||||
|
static size_t size() {
|
||||||
|
return members().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@returns A @c string_view name for the enum value @c e.
|
||||||
|
*/
|
||||||
|
static std::string_view toString(EnumType e) {
|
||||||
|
return members()[size_t(e)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@returns A value of @c EnumType name for the name @c str, or @c EnumType(-1) if
|
||||||
|
the string is not found.
|
||||||
|
*/
|
||||||
|
static EnumType fromString(const std::string_view &str) {
|
||||||
|
const auto member_list = members();
|
||||||
|
auto position = std::find(member_list.begin(), member_list.end(), str);
|
||||||
|
if(position == member_list.end()) return EnumType(-1);
|
||||||
|
return EnumType(position - member_list.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@returns A vector of string_views naming the members of this enum in value order.
|
||||||
|
*/
|
||||||
|
static std::vector<std::string_view> members() {
|
||||||
|
Enum<EnumType> m;
|
||||||
|
const char *const declaration = m.declaration();
|
||||||
|
const char *d_ptr = declaration;
|
||||||
|
|
||||||
|
std::vector<std::string_view> result;
|
||||||
|
while(true) {
|
||||||
|
// Skip non-alphas, and exit if the terminator is found.
|
||||||
|
while(*d_ptr && !isalpha(*d_ptr)) ++d_ptr;
|
||||||
|
if(!*d_ptr) break;
|
||||||
|
|
||||||
|
// Note the current location and proceed for all alphas and digits.
|
||||||
|
const auto start = d_ptr;
|
||||||
|
while(isalpha(*d_ptr) || isdigit(*d_ptr)) ++d_ptr;
|
||||||
|
|
||||||
|
// Add a string view.
|
||||||
|
result.emplace_back(start, d_ptr - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
constexpr const char *declaration();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Provides a very limited subset of normal enums, with the addition of reflection.
|
||||||
|
|
||||||
|
Enum members must take default values, and this enum must be in the global scope.
|
||||||
|
*/
|
||||||
|
#define ReflectiveEnum(Name, Type, ...) \
|
||||||
|
enum class Name: Type { __VA_ARGS__ }; \
|
||||||
|
template <> constexpr const char *::Reflection::Enum<Name>::declaration() { return #__VA_ARGS__; };
|
||||||
|
|
||||||
|
#endif /* Enum_h */
|
Loading…
x
Reference in New Issue
Block a user