add enum class to unify parsing/stringification

This commit is contained in:
Konstantin Käfer
2014-07-14 16:33:02 -07:00
parent 37bb2ff048
commit bdc97d55d2
13 changed files with 173 additions and 133 deletions

View File

@@ -7,7 +7,7 @@
namespace llmr {
void NSLogBackend::record(EventSeverity severity, Event event, const std::string &msg) {
NSLog(@"[%s] %s: %@", stringifyEventSeverity(severity), stringifyEvent(event),
NSLog(@"[%s] %s: %@", EventSeverityClass(severity).c_str(), EventClass(event).c_str(),
[[NSString alloc] initWithBytes:msg.data()
length:msg.size()
encoding:NSUTF8StringEncoding]);
@@ -23,15 +23,15 @@ void NSLogBackend::record(EventSeverity severity, Event event, const char* forma
va_start(args, format);
vsnprintf(buffer.get(), len + 1, format, args);
va_end(args);
NSLog(@"[%s] %s: %s", stringifyEventSeverity(severity), stringifyEvent(event), buffer.get());
NSLog(@"[%s] %s: %s", EventSeverityClass(severity).c_str(), EventClass(event).c_str(), buffer.get());
}
void NSLogBackend::record(EventSeverity severity, Event event, int64_t code) {
NSLog(@"[%s] %s: (%lld)", stringifyEventSeverity(severity), stringifyEvent(event), code);
NSLog(@"[%s] %s: (%lld)", EventSeverityClass(severity).c_str(), EventClass(event).c_str(), code);
}
void NSLogBackend::record(EventSeverity severity, Event event, int64_t code, const std::string &msg) {
NSLog(@"[%s] %s: (%lld) %@", stringifyEventSeverity(severity), stringifyEvent(event), code,
NSLog(@"[%s] %s: (%lld) %@", EventSeverityClass(severity).c_str(), EventClass(event).c_str(), code,
[[NSString alloc] initWithBytes:msg.data()
length:msg.size()
encoding:NSUTF8StringEncoding]);

View File

@@ -9,10 +9,10 @@ class StderrLogBackend : public LogBackend {
public:
inline ~StderrLogBackend() = default;
void record(EventSeverity severity, Event event, const std::string &msg);
void record(EventSeverity severity, Event event, const char* format, ...);
void record(EventSeverity severity, Event event, int64_t code);
void record(EventSeverity severity, Event event, int64_t code, const std::string &msg);
void record(EventSeverityClass severity, EventClass event, const std::string &msg);
void record(EventSeverityClass severity, EventClass event, const char* format, ...);
void record(EventSeverityClass severity, EventClass event, int64_t code);
void record(EventSeverityClass severity, EventClass event, int64_t code, const std::string &msg);
};

View File

@@ -1,8 +1,9 @@
#ifndef LLMR_PLATFORM_EVENT
#define LLMR_PLATFORM_EVENT
#include <llmr/util/enum.hpp>
#include <cstdint>
#include <ostream>
namespace llmr {
@@ -14,9 +15,14 @@ enum class EventSeverity : uint8_t {
Error,
};
EventSeverity parseEventSeverity(const char *name);
const char *stringifyEventSeverity(EventSeverity eventSeverity);
::std::ostream& operator<<(::std::ostream& os, EventSeverity eventSeverity);
LLMR_DEFINE_ENUM_CLASS(EventSeverityClass, EventSeverity, {
{ EventSeverity::Debug, "DEBUG" },
{ EventSeverity::Info, "INFO" },
{ EventSeverity::Test, "TEST" },
{ EventSeverity::Warning, "WARNING" },
{ EventSeverity::Error, "ERROR" },
{ EventSeverity(-1), "UNKNOWN" },
});
enum class Event : uint8_t {
General,
@@ -28,9 +34,17 @@ enum class Event : uint8_t {
HttpRequest,
};
Event parseEvent(const char *name);
const char *stringifyEvent(Event event);
::std::ostream& operator<<(::std::ostream& os, Event event);
LLMR_DEFINE_ENUM_CLASS(EventClass, Event, {
{ Event::General, "General" },
{ Event::Setup, "Setup" },
{ Event::Shader, "Shader" },
{ Event::ParseStyle, "ParseStyle" },
{ Event::ParseTile, "ParseTile" },
{ Event::Render, "Render" },
{ Event::HttpRequest, "HttpRequest" },
{ Event(-1), "Unknown" },
});
struct EventPermutation {
const EventSeverity severity;

View File

@@ -9,7 +9,8 @@ namespace llmr {
class Source;
struct StyleSource {
class StyleSource {
public:
const SourceType type;
const std::string url;
const uint32_t tile_size;
@@ -19,16 +20,10 @@ struct StyleSource {
bool enabled = false;
std::shared_ptr<Source> source;
StyleSource(SourceType type = SourceType::Vector,
const std::string &url = "",
uint32_t tile_size = 512, uint32_t min_zoom = 0,
uint32_t max_zoom = 22)
: type(type),
url(url),
tile_size(tile_size),
min_zoom(min_zoom),
max_zoom(max_zoom) {}
};
StyleSource(SourceType type = SourceType::Vector, const std::string &url = "",
uint32_t tile_size = 512, uint32_t min_zoom = 0, uint32_t max_zoom = 22)
: type(type), url(url), tile_size(tile_size), min_zoom(min_zoom), max_zoom(max_zoom) {}
};
};
#endif

View File

@@ -1,6 +1,8 @@
#ifndef LLMR_STYLE_TYPES
#define LLMR_STYLE_TYPES
#include <llmr/util/enum.hpp>
#include <string>
#include <array>
@@ -20,9 +22,17 @@ enum class StyleLayerType : uint8_t {
Background
};
StyleLayerType parseStyleLayerType(const std::string &type);
const char *stringifyStyleLayerType(StyleLayerType type);
std::ostream& operator<<(std::ostream&, StyleLayerType type);
LLMR_DEFINE_ENUM_CLASS(StyleLayerTypeClass, StyleLayerType, {
{ StyleLayerType::Unknown, "unknown" },
{ StyleLayerType::Fill, "fill" },
{ StyleLayerType::Line, "line" },
{ StyleLayerType::Icon, "icon" },
{ StyleLayerType::Text, "text" },
{ StyleLayerType::Raster, "raster" },
{ StyleLayerType::Composite, "composite" },
{ StyleLayerType::Background, "background" },
{ StyleLayerType(-1), "unknown" },
});
enum class WindingType : uint8_t {

View File

@@ -0,0 +1,55 @@
#ifndef LLMR_UTIL_ENUM
#define LLMR_UTIL_ENUM
#include <iosfwd>
#include <string>
namespace llmr {
template <typename Type>
struct EnumValue {
const Type value;
const char *name;
};
template <typename EnumName, const constexpr EnumValue<EnumName> *names, const size_t length>
struct Enum {
using Type = EnumName;
Type value;
static const constexpr size_t l = length;
private:
static constexpr inline bool compare(const char *a, const char *b) {
return *a == *b && (*a == '\0' || compare(a + 1, b + 1));
}
static constexpr inline const char *lookup_type(Type e, EnumValue<Type> const * const l, size_t r) {
return r == 0 ? "" : l->value == e ? l->name : lookup_type(e, l + 1, r - 1);
}
static constexpr inline Type lookup_name(const char *n, EnumValue<Type> const * const l, size_t r) {
return r == 0 ? Type(-1) : compare(l->name, n) ? l->value : lookup_name(n, l + 1, r - 1);
}
public:
inline constexpr Enum(const char *n) : value(lookup_name(n, names, length)) {}
inline constexpr Enum(const std::string &n) : value(lookup_name(n.c_str(), names, length)) {}
inline constexpr Enum(Type t) : value(t) {}
inline void operator=(const char *n) { value = lookup_name(n, names, length); }
inline void operator=(const std::string &n) { *this = n.c_str(); }
inline void operator=(Type t) { value = t; }
inline constexpr bool valid() const { return value != Type(-1); }
inline constexpr const char *c_str() const { return lookup_type(value, names, length); }
inline std::string str() const { return c_str(); }
inline constexpr operator Type() const { return value; }
};
#define LLMR_DEFINE_ENUM_CLASS(name, type, strings...) \
const constexpr ::llmr::EnumValue<type> type##_names[] = strings; \
using name = ::llmr::Enum<type, type##_names, sizeof(type##_names) / sizeof(::llmr::EnumValue<type>)>; \
inline std::ostream& operator<<(std::ostream& os, type t) { return os << name(t).str(); }
}
#endif

View File

@@ -1,60 +0,0 @@
#include <llmr/platform/event.hpp>
#include <cstring>
namespace llmr {
EventSeverity parseEventSeverity(const char *name) {
if (strcmp(name, "DEBUG") == 0) return EventSeverity::Debug;
if (strcmp(name, "INFO") == 0) return EventSeverity::Info;
if (strcmp(name, "TEST") == 0) return EventSeverity::Test;
if (strcmp(name, "WARNING") == 0) return EventSeverity::Warning;
if (strcmp(name, "ERROR") == 0) return EventSeverity::Error;
return EventSeverity(-1);
}
const char *stringifyEventSeverity(EventSeverity eventSeverity) {
switch (eventSeverity) {
case EventSeverity::Debug: return "DEBUG";
case EventSeverity::Info: return "INFO";
case EventSeverity::Test: return "TEST";
case EventSeverity::Warning: return "WARNING";
case EventSeverity::Error: return "ERROR";
default: return "UNKNOWN";
}
}
::std::ostream& operator<<(::std::ostream& os, EventSeverity eventSeverity) {
return os << stringifyEventSeverity(eventSeverity);
}
Event parseEvent(const char *name) {
if (strcmp(name, "General") == 0) return Event::General;
if (strcmp(name, "Setup") == 0) return Event::Setup;
if (strcmp(name, "Shader") == 0) return Event::Shader;
if (strcmp(name, "ParseStyle") == 0) return Event::ParseStyle;
if (strcmp(name, "ParseTile") == 0) return Event::ParseTile;
if (strcmp(name, "Render") == 0) return Event::Render;
if (strcmp(name, "HttpRequest") == 0) return Event::HttpRequest;
return Event(-1);
}
const char *stringifyEvent(Event event) {
switch (event) {
case Event::General: return "General";
case Event::Setup: return "Setup";
case Event::Shader: return "Shader";
case Event::ParseStyle: return "ParseStyle";
case Event::ParseTile: return "ParseTile";
case Event::Render: return "Render";
case Event::HttpRequest: return "HttpRequest";
default: return "Unknown";
}
}
::std::ostream& operator<<(::std::ostream& os, Event event) {
return os << stringifyEvent(event);
}
}

View File

@@ -4,6 +4,7 @@
#include <llmr/platform/log.hpp>
#include <cstring>
#include <cstdlib>
using namespace llmr;

View File

@@ -559,7 +559,7 @@ void StyleParser::parseLayer(std::pair<JSVal, std::shared_ptr<StyleLayer>> &pair
if (!type.IsString()) {
fprintf(stderr, "[WARNING] layer type of '%s' must be a string\n", layer->id.c_str());
} else {
layer->type = parseStyleLayerType({ type.GetString(), type.GetStringLength() });
layer->type = StyleLayerTypeClass(std::string { type.GetString(), type.GetStringLength() });
}
}

View File

@@ -1,35 +0,0 @@
#include <llmr/style/types.hpp>
#include <iostream>
namespace llmr {
StyleLayerType parseStyleLayerType(const std::string &type) {
if (type == "fill") return StyleLayerType::Fill;
if (type == "line") return StyleLayerType::Line;
if (type == "icon") return StyleLayerType::Icon;
if (type == "text") return StyleLayerType::Text;
if (type == "raster") return StyleLayerType::Raster;
if (type == "composite") return StyleLayerType::Composite;
if (type == "background") return StyleLayerType::Background;
return StyleLayerType::Unknown;
}
const char *stringifyStyleLayerType(StyleLayerType type) {
switch (type) {
case StyleLayerType::Fill: return "fill";
case StyleLayerType::Line: return "line";
case StyleLayerType::Icon: return "icon";
case StyleLayerType::Text: return "text";
case StyleLayerType::Raster: return "raster";
case StyleLayerType::Composite: return "composite";
case StyleLayerType::Background: return "background";
default: return "unknown";
}
}
std::ostream& operator<<(std::ostream& os, StyleLayerType type) {
return os << stringifyStyleLayerType(type);
}
}

43
test/enums.cpp Normal file
View File

@@ -0,0 +1,43 @@
#include <iostream>
#include "gtest/gtest.h"
#include <algorithm>
#include <llmr/style/types.hpp>
using namespace llmr;
TEST(Enums, StyleLayerType) {
std::cerr << StyleLayerType::Raster;
ASSERT_EQ(StyleLayerType::Unknown, StyleLayerTypeClass("unknown"));
ASSERT_EQ(StyleLayerType::Fill, StyleLayerTypeClass("fill"));
ASSERT_EQ(StyleLayerType::Line, StyleLayerTypeClass("line"));
ASSERT_EQ(StyleLayerType::Icon, StyleLayerTypeClass("icon"));
ASSERT_EQ(StyleLayerType::Text, StyleLayerTypeClass("text"));
ASSERT_EQ(StyleLayerType::Raster, StyleLayerTypeClass("rastr"));
ASSERT_EQ(StyleLayerType::Composite, StyleLayerTypeClass("composite"));
ASSERT_EQ(StyleLayerType::Background, StyleLayerTypeClass("background"));
ASSERT_EQ(StyleLayerType::Unknown, StyleLayerTypeClass(StyleLayerType::Unknown));
ASSERT_EQ(StyleLayerType::Fill, StyleLayerTypeClass(StyleLayerType::Fill));
ASSERT_EQ(StyleLayerType::Line, StyleLayerTypeClass(StyleLayerType::Line));
ASSERT_EQ(StyleLayerType::Icon, StyleLayerTypeClass(StyleLayerType::Icon));
ASSERT_EQ(StyleLayerType::Text, StyleLayerTypeClass(StyleLayerType::Text));
ASSERT_EQ(StyleLayerType::Raster, StyleLayerTypeClass(StyleLayerType::Raster));
ASSERT_EQ(StyleLayerType::Composite, StyleLayerTypeClass(StyleLayerType::Composite));
ASSERT_EQ(StyleLayerType::Background, StyleLayerTypeClass(StyleLayerType::Background));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Unknown), StyleLayerTypeClass(StyleLayerType::Unknown));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Fill), StyleLayerTypeClass(StyleLayerType::Fill));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Line), StyleLayerTypeClass(StyleLayerType::Line));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Icon), StyleLayerTypeClass(StyleLayerType::Icon));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Text), StyleLayerTypeClass(StyleLayerType::Text));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Raster), StyleLayerTypeClass(StyleLayerType::Raster));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Composite), StyleLayerTypeClass(StyleLayerType::Composite));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Background), StyleLayerTypeClass(StyleLayerType::Background));
ASSERT_EQ(false, StyleLayerTypeClass("").valid());
ASSERT_EQ(false, StyleLayerTypeClass("Backgrund").valid());
}

View File

@@ -94,8 +94,8 @@ TEST_P(HeadlessTest, render) {
if (js_entry.Size() == 5) {
const uint32_t count = js_entry[rapidjson::SizeType(0)].GetUint();
const FixtureLogBackend::LogMessage message {
parseEventSeverity(js_entry[rapidjson::SizeType(1)].GetString()),
parseEvent(js_entry[rapidjson::SizeType(2)].GetString()),
EventSeverityClass(js_entry[rapidjson::SizeType(1)].GetString()),
EventClass(js_entry[rapidjson::SizeType(2)].GetString()),
js_entry[rapidjson::SizeType(3)].GetInt64(),
js_entry[rapidjson::SizeType(4)].GetString()
};
@@ -104,15 +104,15 @@ TEST_P(HeadlessTest, render) {
const uint32_t count = js_entry[rapidjson::SizeType(0)].GetUint();
if (js_entry[rapidjson::SizeType(3)].IsString()) {
const FixtureLogBackend::LogMessage message {
parseEventSeverity(js_entry[rapidjson::SizeType(1)].GetString()),
parseEvent(js_entry[rapidjson::SizeType(2)].GetString()),
EventSeverityClass(js_entry[rapidjson::SizeType(1)].GetString()),
EventClass(js_entry[rapidjson::SizeType(2)].GetString()),
js_entry[rapidjson::SizeType(3)].GetString()
};
ASSERT_EQ(count, log.count(message)) << "Message: " << message << "Full Log: " << std::endl << log.messages;
} else {
const FixtureLogBackend::LogMessage message {
parseEventSeverity(js_entry[rapidjson::SizeType(1)].GetString()),
parseEvent(js_entry[rapidjson::SizeType(2)].GetString()),
EventSeverityClass(js_entry[rapidjson::SizeType(1)].GetString()),
EventClass(js_entry[rapidjson::SizeType(2)].GetString()),
js_entry[rapidjson::SizeType(3)].GetInt64()
};
ASSERT_EQ(count, log.count(message)) << "Message: " << message << "Full Log: " << std::endl << log.messages;
@@ -120,8 +120,8 @@ TEST_P(HeadlessTest, render) {
} else if (js_entry.Size() == 3) {
const uint32_t count = js_entry[rapidjson::SizeType(0)].GetUint();
const FixtureLogBackend::LogMessage message {
parseEventSeverity(js_entry[rapidjson::SizeType(1)].GetString()),
parseEvent(js_entry[rapidjson::SizeType(2)].GetString())
EventSeverityClass(js_entry[rapidjson::SizeType(1)].GetString()),
EventClass(js_entry[rapidjson::SizeType(2)].GetString())
};
ASSERT_EQ(count, log.count(message)) << "Message: " << message << "Full Log: " << std::endl << log.messages;
} else {

View File

@@ -90,6 +90,22 @@
"../llmr.gyp:llmr-x86"
]
},
{
"target_name": "enums",
"product_name": "test_enums",
"type": "executable",
"libraries": [
"-lpthread",
],
"sources": [
"./main.cpp",
"./enums.cpp",
],
"dependencies": [
"../deps/gtest/gtest.gyp:gtest",
"../llmr.gyp:llmr-x86"
]
},
{
"target_name": "variant",
"product_name": "test_variant",
@@ -167,6 +183,7 @@
"dependencies": [
"rotation_range",
"clip_ids",
"enums",
"variant",
"tile",
"functions",