diff options
author | Treeston <treeston.mmoc@gmail.com> | 2018-10-26 14:43:22 +0200 |
---|---|---|
committer | Treeston <treeston.mmoc@gmail.com> | 2018-10-26 14:43:22 +0200 |
commit | 338e8ba0fea8b4b15120c96fff15a6c4b1a52593 (patch) | |
tree | b9a9fce959447317011252c4b38d5519667ab3d1 /dep | |
parent | 0a0312b705ecb1a318fd3abe545b571a3a349a9c (diff) |
Core/Misc: Partial merge of 3.3.5-dbedit:
- Added SmartEnum.h for enum iteration, stringification, and more, courtesy of krabicezpapundeklu/smart_enum
- Moved a bunch of enums in SharedDefines.h to the new system
- Miscellaneous utility methods ported
Diffstat (limited to 'dep')
-rw-r--r-- | dep/CMakeLists.txt | 7 | ||||
-rw-r--r-- | dep/smart_enum/CMakeLists.txt | 15 | ||||
-rw-r--r-- | dep/smart_enum/LICENSE_1_0.txt | 23 | ||||
-rw-r--r-- | dep/smart_enum/smart_enum.hpp | 485 |
4 files changed, 527 insertions, 3 deletions
diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt index 6811dc91437..9fda2aefca0 100644 --- a/dep/CMakeLists.txt +++ b/dep/CMakeLists.txt @@ -10,7 +10,7 @@ add_subdirectory(threads) -if(SERVERS OR TOOLS) +if (SERVERS OR TOOLS) add_subdirectory(boost) add_subdirectory(process) add_subdirectory(zlib) @@ -22,16 +22,17 @@ if(SERVERS OR TOOLS) add_subdirectory(valgrind) add_subdirectory(openssl) add_subdirectory(jemalloc) + add_subdirectory(smart_enum) endif() -if(SERVERS) +if (SERVERS) add_subdirectory(mysql) add_subdirectory(readline) add_subdirectory(gsoap) add_subdirectory(efsw) endif() -if(TOOLS) +if (TOOLS) add_subdirectory(bzip2) add_subdirectory(libmpq) endif() diff --git a/dep/smart_enum/CMakeLists.txt b/dep/smart_enum/CMakeLists.txt new file mode 100644 index 00000000000..bc9d6f112ba --- /dev/null +++ b/dep/smart_enum/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/> +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +add_library(smart_enum INTERFACE) + +target_include_directories(smart_enum + INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/dep/smart_enum/LICENSE_1_0.txt b/dep/smart_enum/LICENSE_1_0.txt new file mode 100644 index 00000000000..36b7cd93cdf --- /dev/null +++ b/dep/smart_enum/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/dep/smart_enum/smart_enum.hpp b/dep/smart_enum/smart_enum.hpp new file mode 100644 index 00000000000..6265f7ac701 --- /dev/null +++ b/dep/smart_enum/smart_enum.hpp @@ -0,0 +1,485 @@ + + +// Copyright Jarda Flieger 2016. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef SMART_ENUM_HEADER_INCLUDED +#define SMART_ENUM_HEADER_INCLUDED + +#include <cstring> +#include <stdexcept> +#include <tuple> + +#include <boost/iterator/iterator_facade.hpp> + +#include <boost/preprocessor/arithmetic/dec.hpp> +#include <boost/preprocessor/logical/not.hpp> +#include <boost/preprocessor/punctuation/remove_parens.hpp> +#include <boost/preprocessor/repetition/enum.hpp> +#include <boost/preprocessor/tuple/push_back.hpp> + +#define SMART_ENUM(...) \ + SMART_ENUM_IMPL(, __VA_ARGS__) + +#define SMART_ENUM_CLASS(...) \ + SMART_ENUM_IMPL(class, __VA_ARGS__) + +#ifdef _MSC_VER + #define SMART_ENUM_IMPL(CLASS, ...) \ + BOOST_PP_CAT \ + ( \ + BOOST_PP_OVERLOAD(SMART_ENUM_IMPL_, __VA_ARGS__)(CLASS, __VA_ARGS__), \ + BOOST_PP_EMPTY() \ + ) +#else + #define SMART_ENUM_IMPL(CLASS, ...) \ + BOOST_PP_OVERLOAD(SMART_ENUM_IMPL_, __VA_ARGS__)(CLASS, __VA_ARGS__) +#endif + +#define SMART_ENUM_IMPL_2(CLASS, NAME, MEMBERS) \ + SMART_ENUM_IMPL_DEFINITION(CLASS, _, NAME, MEMBERS) + +#define SMART_ENUM_IMPL_3(CLASS, NAMESPACES, NAME, MEMBERS) \ + SMART_ENUM_IMPL_DEFINITION(CLASS, SMART_ENUM_IMPL_ARG_TO_TUPLE(NAMESPACES), NAME, MEMBERS) + +#define SMART_ENUM_IMPL_DEFINITION(CLASS, NAMESPACES, NAME, MEMBERS) \ + SMART_ENUM_IMPL_DEFINITION_1 \ + ( \ + CLASS, NAMESPACES, SMART_ENUM_IMPL_ARG_TO_TUPLE(NAME), (SMART_ENUM_IMPL_ARGS_TO_TUPLES(MEMBERS)) \ + ) + +#define SMART_ENUM_IMPL_DEFINITION_1(CLASS, NAMESPACES, NAME, MEMBERS) \ + SMART_ENUM_IMPL_REPEAT(NAMESPACE_START, NAMESPACES) \ + enum CLASS SMART_ENUM_IMPL_NAME_SIZE(NAME) \ + { \ + SMART_ENUM_IMPL_MEMBER_DEFINITIONS(MEMBERS) \ + }; \ + SMART_ENUM_IMPL_REPEAT(NAMESPACE_END, NAMESPACES) \ + \ + SMART_ENUM_IMPL_TRAITS(NAMESPACES, BOOST_PP_TUPLE_ELEM(0, NAME), MEMBERS) + +#define SMART_ENUM_IMPL_NAME_SIZE(NAME_SIZE) \ + BOOST_PP_TUPLE_ELEM(0, NAME_SIZE) \ + BOOST_PP_IF \ + ( \ + BOOST_PP_DEC(BOOST_PP_TUPLE_SIZE(NAME_SIZE)), \ + SMART_ENUM_IMPL_NAME_SIZE_1, BOOST_PP_TUPLE_EAT(1) \ + ) \ + NAME_SIZE + +#define SMART_ENUM_IMPL_NAME_SIZE_1(NAME, SIZE) \ + : SIZE + +// traits +#define SMART_ENUM_IMPL_TRAITS(NAMESPACES, NAME, MEMBERS) \ + SMART_ENUM_IMPL_TRAITS_1 \ + ( \ + SMART_ENUM_IMPL_FULL_NAME(NAMESPACES, NAME), \ + SMART_ENUM_IMPL_FULL_NAME_STRING(NAMESPACES, NAME), \ + NAME, \ + MEMBERS \ + ) + +#define SMART_ENUM_IMPL_TRAITS_1(FULL_NAME, FULL_NAME_STRING, NAME, MEMBERS) \ + namespace smart_enum \ + { \ + template<> struct enum_traits<FULL_NAME> : detail::enum_traits_base<FULL_NAME> \ + { \ + using type = FULL_NAME; \ + using data_type = SMART_ENUM_IMPL_DATA_TYPE(BOOST_PP_TUPLE_ELEM(0, MEMBERS)); \ + \ + static constexpr const char *name = BOOST_PP_STRINGIZE(NAME); \ + static constexpr const char *full_name = FULL_NAME_STRING; \ + \ + static constexpr std::size_t count = BOOST_PP_TUPLE_SIZE(MEMBERS); \ + \ + SMART_ENUM_IMPL_DATA(FULL_NAME, MEMBERS) \ + SMART_ENUM_IMPL_FROM_STRING(FULL_NAME, MEMBERS) \ + SMART_ENUM_IMPL_INDEX_OF(FULL_NAME, MEMBERS) \ + SMART_ENUM_IMPL_TO_STRING(FULL_NAME, MEMBERS) \ + SMART_ENUM_IMPL_VALUE_OF(FULL_NAME, MEMBERS) \ + }; \ + } + +// full name +#define SMART_ENUM_IMPL_FULL_NAME(NAMESPACES, NAME) \ + SMART_ENUM_IMPL_REPEAT(FULL_NAME_1, NAMESPACES) NAME + +#define SMART_ENUM_IMPL_FULL_NAME_1(NAMESPACE) \ + NAMESPACE :: + +#define SMART_ENUM_IMPL_FULL_NAME_STRING(NAMESPACES, NAME) \ + SMART_ENUM_IMPL_REPEAT(FULL_NAME_STRING_1, NAMESPACES) BOOST_PP_STRINGIZE(NAME) + +#define SMART_ENUM_IMPL_FULL_NAME_STRING_1(NAMESPACE) \ + BOOST_PP_STRINGIZE(NAMESPACE) "::" + +// data +#define SMART_ENUM_IMPL_DATA(PREFIX, MEMBERS) \ + static constexpr data_type data(PREFIX value) \ + { \ + switch(value) \ + { \ + SMART_ENUM_IMPL_REPEAT_MEMBERS(PREFIX, MEMBERS, MEMBER_DATA) \ + } \ + \ + return {}; \ + } + +#define SMART_ENUM_IMPL_MEMBER_DATA(PREFIX, NAME, MEMBER, INDEX) \ + case PREFIX :: NAME: \ + return EnumText \ + SMART_ENUM_IMPL_MEMBER_DATA_1 \ + ( \ + SMART_ENUM_IMPL_TUPLE_LAST_ELEMENT(MEMBER) \ + ) \ + ; + +#define SMART_ENUM_IMPL_MEMBER_DATA_1(DATA) \ + BOOST_PP_IIF \ + ( \ + BOOST_PP_IS_BEGIN_PARENS(DATA), DATA, () \ + ) + +#define SMART_ENUM_IMPL_DATA_TYPE(MEMBER) \ + EnumText + +// member definitions +#define SMART_ENUM_IMPL_MEMBER_DEFINITIONS(MEMBERS) \ + SMART_ENUM_IMPL_ENUM_MEMBERS(_, MEMBERS, MEMBER_DEFINITION) + +#define SMART_ENUM_IMPL_MEMBER_DEFINITION(PREFIX, NAME, MEMBER, INDEX) \ + NAME \ + SMART_ENUM_IMPL_MEMBER_DEFINITION_1 \ + ( \ + BOOST_PP_TUPLE_ELEM(1, BOOST_PP_TUPLE_PUSH_BACK(MEMBER, ())) \ + ) + +#define SMART_ENUM_IMPL_MEMBER_DEFINITION_1(VALUE) \ + BOOST_PP_EXPR_IIF \ + ( \ + BOOST_PP_NOT(BOOST_PP_IS_BEGIN_PARENS(VALUE)), = VALUE \ + ) + +// from_string +#define SMART_ENUM_IMPL_FROM_STRING(PREFIX, MEMBERS) \ + static PREFIX from_string(const char *s) \ + { \ + return SMART_ENUM_IMPL_REPEAT_MEMBERS(PREFIX, MEMBERS, MEMBER_FROM_STRING) throw std::invalid_argument("s"); \ + } + +#define SMART_ENUM_IMPL_MEMBER_FROM_STRING(PREFIX, NAME, MEMBER, INDEX) \ + !std::strcmp(s, BOOST_PP_STRINGIZE(NAME)) ? PREFIX :: NAME : + +// index_of +#define SMART_ENUM_IMPL_INDEX_OF(PREFIX, MEMBERS) \ + static constexpr std::size_t index_of(PREFIX value) \ + { \ + return SMART_ENUM_IMPL_REPEAT_MEMBERS(PREFIX, MEMBERS, MEMBER_INDEX_OF) throw std::invalid_argument("value"); \ + } + +#define SMART_ENUM_IMPL_MEMBER_INDEX_OF(PREFIX, NAME, MEMBER, INDEX) \ + value == PREFIX :: NAME ? INDEX ## u : + +// to_string +#define SMART_ENUM_IMPL_TO_STRING(PREFIX, MEMBERS) \ + static constexpr const char *to_string(PREFIX value) \ + { \ + switch(value) \ + { \ + SMART_ENUM_IMPL_REPEAT_MEMBERS(PREFIX, MEMBERS, MEMBER_TO_STRING) \ + } \ + \ + throw std::invalid_argument("value"); \ + } + +#define SMART_ENUM_IMPL_MEMBER_TO_STRING(PREFIX, NAME, MEMBER, INDEX) \ + case PREFIX :: NAME: \ + return BOOST_PP_STRINGIZE(NAME); + +// value_of +#define SMART_ENUM_IMPL_VALUE_OF(PREFIX, MEMBERS) \ + static constexpr PREFIX value_of(std::size_t index) \ + { \ + return SMART_ENUM_IMPL_REPEAT_MEMBERS(PREFIX, MEMBERS, MEMBER_VALUE_OF) throw std::invalid_argument("index"); \ + } + +#define SMART_ENUM_IMPL_MEMBER_VALUE_OF(PREFIX, NAME, MEMBER, INDEX) \ + index == INDEX ? PREFIX :: NAME : + +// namespaces +#define SMART_ENUM_IMPL_NAMESPACE_END(_) \ + } + +#define SMART_ENUM_IMPL_NAMESPACE_START(NAMESPACE) \ + namespace NAMESPACE { + +// utils +#define SMART_ENUM_IMPL_ARG_TO_TUPLE(ARG) \ + (BOOST_PP_REMOVE_PARENS(ARG)) + +#define SMART_ENUM_IMPL_ARGS_TO_TUPLES(ARGS) \ + BOOST_PP_ENUM(BOOST_PP_TUPLE_SIZE(ARGS), SMART_ENUM_IMPL_ARGS_TO_TUPLES_1, ARGS) + +#define SMART_ENUM_IMPL_ARGS_TO_TUPLES_1(_, INDEX, ARGS) \ + SMART_ENUM_IMPL_ARG_TO_TUPLE(BOOST_PP_TUPLE_ELEM(INDEX, ARGS)) + +#define SMART_ENUM_IMPL_REPEAT(MACRO, TUPLE) \ + BOOST_PP_EXPR_IIF \ + ( \ + BOOST_PP_IS_BEGIN_PARENS(TUPLE), \ + BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE(TUPLE), SMART_ENUM_IMPL_REPEAT_1, (TUPLE, MACRO)) \ + ) + +#define SMART_ENUM_IMPL_REPEAT_1(_, INDEX, TUPLE_MACRO) \ + BOOST_PP_CAT(SMART_ENUM_IMPL_, BOOST_PP_TUPLE_ELEM(1, TUPLE_MACRO)) \ + (BOOST_PP_TUPLE_ELEM(INDEX, BOOST_PP_TUPLE_ELEM(0, TUPLE_MACRO))) + +#define SMART_ENUM_IMPL_ENUM_MEMBERS(PREFIX, MEMBERS, MACRO) \ + BOOST_PP_ENUM(BOOST_PP_TUPLE_SIZE(MEMBERS), SMART_ENUM_IMPL_PROCESS_MEMBERS_1, (PREFIX, MEMBERS, MACRO)) + +#define SMART_ENUM_IMPL_REPEAT_MEMBERS(PREFIX, MEMBERS, MACRO) \ + BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE(MEMBERS), SMART_ENUM_IMPL_PROCESS_MEMBERS_1, (PREFIX, MEMBERS, MACRO)) + +#define SMART_ENUM_IMPL_PROCESS_MEMBERS_1(_, INDEX, PREFIX_MEMBERS_MACRO) \ + SMART_ENUM_IMPL_PROCESS_MEMBERS_2 \ + ( \ + BOOST_PP_TUPLE_ELEM(0, PREFIX_MEMBERS_MACRO), \ + BOOST_PP_TUPLE_ELEM(INDEX, BOOST_PP_TUPLE_ELEM(1, PREFIX_MEMBERS_MACRO)), \ + BOOST_PP_TUPLE_ELEM(2, PREFIX_MEMBERS_MACRO), \ + INDEX \ + ) + +#define SMART_ENUM_IMPL_PROCESS_MEMBERS_2(PREFIX, MEMBER, MACRO, INDEX) \ + BOOST_PP_CAT(SMART_ENUM_IMPL_, MACRO)(PREFIX, BOOST_PP_TUPLE_ELEM(0, MEMBER), MEMBER, INDEX) + +#define SMART_ENUM_IMPL_TUPLE_LAST_ELEMENT(TUPLE) \ + BOOST_PP_TUPLE_ELEM(BOOST_PP_DEC(BOOST_PP_TUPLE_SIZE(TUPLE)), TUPLE) + +namespace smart_enum +{ + template + < + typename Enum + > + class enum_iterator; + + template + < + typename Enum + > + struct enum_range; + + namespace detail + { + template + < + typename Enum + > + struct enum_traits_base + { + static constexpr bool is_enum_class = + std::integral_constant + < + bool, std::is_enum<Enum>::value && !std::is_convertible<Enum, int>::value + > + ::value; + }; + } + + template + < + typename Enum + > + struct enum_traits {}; + + template + < + typename Enum + > + constexpr enum_iterator<Enum> begin() + { + return enum_iterator<Enum>{enum_traits<Enum>::value_of(0)}; + } + + template + < + typename Enum + > + typename enum_traits<Enum>::data_type data(Enum value) + { + return enum_traits<Enum>::data(value); + } + + template + < + typename Enum + > + constexpr enum_iterator<Enum> end() + { + return {}; + } + + template + < + typename Enum + > + constexpr std::size_t count() + { + return enum_traits<Enum>::count; + } + + template + < + typename Enum + > + Enum from_string(const char *s) + { + return enum_traits<Enum>::from_string(s); + } + + template + < + typename Enum + > + constexpr const char *full_name() + { + return enum_traits<Enum>::full_name; + } + + template + < + typename Enum + > + constexpr std::size_t index_of(Enum value) + { + return enum_traits<Enum>::index_of(value); + } + + template + < + typename Enum + > + constexpr bool is_enum_class() + { + return enum_traits<Enum>::is_enum_class; + } + + template + < + typename Enum + > + constexpr const char *name() + { + return enum_traits<Enum>::name; + } + + template + < + typename Enum + > + constexpr enum_range<Enum> range() + { + return {}; + } + + template + < + typename Enum + > + constexpr const char *to_string(Enum value) + { + return enum_traits<Enum>::to_string(value); + } + + template + < + typename Enum + > + constexpr Enum value_of(std::size_t index) + { + return enum_traits<Enum>::value_of(index); + } + + template + < + typename Enum + > + class enum_iterator : public boost::iterator_facade + < + enum_iterator<Enum>, Enum, boost::random_access_traversal_tag, Enum + > + { + public: + constexpr enum_iterator() + : index_{ count<Enum>() } + { + } + + constexpr explicit enum_iterator(Enum value) + : index_{ index_of(value) } + { + } + + constexpr bool operator!=(const enum_iterator& other) const + { + return other.index_ != index_; + } + + private: + std::size_t index_; + + void advance(std::ptrdiff_t n) + { + index_ += n; + } + + void decrement() + { + --index_; + } + + constexpr Enum dereference() const + { + return value_of<Enum>(index_); + } + + constexpr std::ptrdiff_t distance_to(const enum_iterator &other) const + { + return other.index_ - index_; + } + + constexpr bool equal(const enum_iterator &other) const + { + return other.index_ == index_; + } + + void increment() + { + ++index_; + } + + friend class boost::iterator_core_access; + }; + + template + < + typename Enum + > + struct enum_range + { + constexpr enum_iterator<Enum> begin() const + { + return smart_enum::begin<Enum>(); + } + + constexpr enum_iterator<Enum> end() const + { + return smart_enum::end<Enum>(); + } + }; +} + +#endif |