Move enum/flags option functions to option_types.hh

This commit is contained in:
Maxime Coste 2017-03-15 18:28:32 +00:00
parent 7d9f1df73a
commit 7eaa058450
2 changed files with 60 additions and 64 deletions

View File

@ -1,11 +1,7 @@
#ifndef enum_hh_INCLUDED #ifndef enum_hh_INCLUDED
#define enum_hh_INCLUDED #define enum_hh_INCLUDED
#include "flags.hh"
#include "string.hh" #include "string.hh"
#include "exception.hh"
#include "containers.hh"
#include "meta.hh"
namespace Kakoune namespace Kakoune
{ {
@ -23,66 +19,6 @@ struct Array
template<typename T> struct EnumDesc { T value; StringView name; }; template<typename T> struct EnumDesc { T value; StringView name; };
template<typename Flags, typename = decltype(enum_desc(Meta::Type<Flags>{}))>
EnableIfWithBitOps<Flags, String> option_to_string(Flags flags)
{
constexpr auto desc = enum_desc(Meta::Type<Flags>{});
String res;
for (int i = 0; i < desc.size(); ++i)
{
if (not (flags & desc[i].value))
continue;
if (not res.empty())
res += "|";
res += desc[i].name;
}
return res;
}
template<typename Enum, typename = decltype(enum_desc(Meta::Type<Enum>{}))>
EnableIfWithoutBitOps<Enum, String> option_to_string(Enum e)
{
constexpr auto desc = enum_desc(Meta::Type<Enum>{});
auto it = find_if(desc, [e](const EnumDesc<Enum>& d) { return d.value == e; });
if (it != desc.end())
return it->name.str();
kak_assert(false);
return {};
}
template<typename Flags, typename = decltype(enum_desc(Meta::Type<Flags>{}))>
EnableIfWithBitOps<Flags> option_from_string(StringView str, Flags& flags)
{
constexpr auto desc = enum_desc(Meta::Type<Flags>{});
flags = Flags{};
for (auto s : str | split<StringView>('|'))
{
auto it = find_if(desc, [s](const EnumDesc<Flags>& d) { return d.name == s; });
if (it == desc.end())
throw runtime_error(format("invalid flag value '{}'", s));
flags |= it->value;
}
}
template<typename Enum, typename = decltype(enum_desc(Meta::Type<Enum>{}))>
EnableIfWithoutBitOps<Enum> option_from_string(StringView str, Enum& e)
{
constexpr auto desc = enum_desc(Meta::Type<Enum>{});
auto it = find_if(desc, [str](const EnumDesc<Enum>& d) { return d.name == str; });
if (it == desc.end())
throw runtime_error(format("invalid enum value '{}'", str));
e = it->value;
}
template<typename Flags, typename = decltype(enum_desc(Meta::Type<Flags>{}))>
EnableIfWithBitOps<Flags, bool> option_add(Flags& opt, StringView str)
{
Flags res = Flags{};
option_from_string(str, res);
opt |= res;
return res != (Flags)0;
}
} }
#endif // enum_hh_INCLUDED #endif // enum_hh_INCLUDED

View File

@ -254,6 +254,66 @@ constexpr Array<EnumDesc<DebugFlags>, 4> enum_desc(Meta::Type<DebugFlags>)
} }; } };
} }
template<typename Flags, typename = decltype(enum_desc(Meta::Type<Flags>{}))>
EnableIfWithBitOps<Flags, String> option_to_string(Flags flags)
{
constexpr auto desc = enum_desc(Meta::Type<Flags>{});
String res;
for (int i = 0; i < desc.size(); ++i)
{
if (not (flags & desc[i].value))
continue;
if (not res.empty())
res += "|";
res += desc[i].name;
}
return res;
}
template<typename Enum, typename = decltype(enum_desc(Meta::Type<Enum>{}))>
EnableIfWithoutBitOps<Enum, String> option_to_string(Enum e)
{
constexpr auto desc = enum_desc(Meta::Type<Enum>{});
auto it = find_if(desc, [e](const EnumDesc<Enum>& d) { return d.value == e; });
if (it != desc.end())
return it->name.str();
kak_assert(false);
return {};
}
template<typename Flags, typename = decltype(enum_desc(Meta::Type<Flags>{}))>
EnableIfWithBitOps<Flags> option_from_string(StringView str, Flags& flags)
{
constexpr auto desc = enum_desc(Meta::Type<Flags>{});
flags = Flags{};
for (auto s : str | split<StringView>('|'))
{
auto it = find_if(desc, [s](const EnumDesc<Flags>& d) { return d.name == s; });
if (it == desc.end())
throw runtime_error(format("invalid flag value '{}'", s));
flags |= it->value;
}
}
template<typename Enum, typename = decltype(enum_desc(Meta::Type<Enum>{}))>
EnableIfWithoutBitOps<Enum> option_from_string(StringView str, Enum& e)
{
constexpr auto desc = enum_desc(Meta::Type<Enum>{});
auto it = find_if(desc, [str](const EnumDesc<Enum>& d) { return d.name == str; });
if (it == desc.end())
throw runtime_error(format("invalid enum value '{}'", str));
e = it->value;
}
template<typename Flags, typename = decltype(enum_desc(Meta::Type<Flags>{}))>
EnableIfWithBitOps<Flags, bool> option_add(Flags& opt, StringView str)
{
Flags res = Flags{};
option_from_string(str, res);
opt |= res;
return res != (Flags)0;
}
template<typename P, typename T> template<typename P, typename T>
struct PrefixedList struct PrefixedList
{ {