diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a007fea --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..03a9a4b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.14) +project(enum_name_example VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) + +include(FetchContent) + +FetchContent_Declare( + DocTest + GIT_REPOSITORY "https://github.com/onqtam/doctest" + GIT_TAG "v2.4.11" +) + +FetchContent_MakeAvailable(DocTest) + +add_executable(${PROJECT_NAME} example/main.cpp) +target_include_directories(${PROJECT_NAME} AFTER PUBLIC ${CMAKE_SOURCE_DIR}/include) + +enable_testing() +add_subdirectory(test) \ No newline at end of file diff --git a/example/main.cpp b/example/main.cpp new file mode 100644 index 0000000..4f0b051 --- /dev/null +++ b/example/main.cpp @@ -0,0 +1,33 @@ +#include +#include "enum_name.hpp" + + +enum class rgb_color { red, green, blue, unknown = -1}; + +// you can specialize enum ranges with specialize struct per enum types (option 1) +namespace mgutility{ + template<> + struct enum_range + { + static constexpr auto min = -1; + static constexpr auto max = 3; + }; +} + +// you can specialize enum ranges with overload per enum types (option 2) +auto enum_name = [](rgb_color c){ return mgutility::enum_name<-1, 3>(c); }; + + +int main() +{ + auto x = rgb_color::blue; + auto y = mgutility::to_enum("green"); + + // default signature: enum_name(Enum&&) + // Changing max_value to not too much greater than enum's max value, it will compiles faster + std::cout << mgutility::enum_name(x) << '\n'; // will print "blue" to output + + // calling specialized enum ranges function for rgb_color type + // will print "green" to output, if y can't convert to rgb_color prints "unknown" + std::cout << enum_name(y.value_or(rgb_color::unknown)) << '\n'; +} \ No newline at end of file diff --git a/enum_name.hpp b/include/enum_name.hpp similarity index 100% rename from enum_name.hpp rename to include/enum_name.hpp diff --git a/scripts/ci_setup_clang.sh b/scripts/ci_setup_clang.sh new file mode 100755 index 0000000..faf60fe --- /dev/null +++ b/scripts/ci_setup_clang.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -ex + +VERSION=$1 + +apt-get update +apt-get install -y libc++-${VERSION}-dev libc++abi-${VERSION}-dev + +if [[ "${VERSION}" -ge 12 ]]; then + apt-get install -y --no-install-recommends libunwind-${VERSION}-dev +fi \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..3d68426 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.14) +project(enum_name_test VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) + +include_directories(AFTER PUBLIC ${CMAKE_SOURCE_DIR}/include) + +add_executable(${PROJECT_NAME} enum_name_test.cpp) +target_link_libraries(${PROJECT_NAME} doctest) + +add_test(NAME enum_name_test COMMAND enum_name_test) \ No newline at end of file diff --git a/test/enum_name_test.cpp b/test/enum_name_test.cpp new file mode 100644 index 0000000..36a25d4 --- /dev/null +++ b/test/enum_name_test.cpp @@ -0,0 +1,29 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest/doctest.h" +#include "enum_name.hpp" + +enum class rgb_color { red, green, blue, unknown = -1}; + +// you can specialize enum ranges with specialize struct per enum types (option 1) +namespace mgutility{ + template<> + struct enum_range + { + static constexpr auto min = -1; + static constexpr auto max = 3; + }; +} + + +TEST_CASE("testing the enum name serialization") { + CHECK(mgutility::enum_name(rgb_color::blue) == "blue"); + CHECK(mgutility::enum_name(rgb_color::unknown) == "unknown"); + CHECK(mgutility::enum_name<0, 2>(rgb_color::unknown) == ""); +} + +TEST_CASE("testing the enum name deserialization") { + CHECK(mgutility::to_enum("blue").value() == rgb_color::blue); + CHECK(mgutility::to_enum("unknown").value() == rgb_color::unknown); + CHECK(mgutility::to_enum("unknown").value_or(rgb_color::red) == rgb_color::red); + REQUIRE_THROWS(mgutility::to_enum("unknown").value()); +} \ No newline at end of file