Skip to content

Latest commit

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Note, consider this beta right now. Bugfixes and ideas for improvement are more than welcome.

Light-Enum

Light-Enum is an "add-on" for Magic-Enum aiming to provide the same (almost) functionality with low compile time. The idea is to introspect enums (using Magic Enum) at application start and store them all in a global hash map. This means that the heavey Magic Enum introspection only needs to be compiled in a single translation unit/cpp file rather than every time an enum is introspected. See example below.

Magic-Enum

As mentioned, this just a simple add-on for Magic Enum. All the hard work for introspecting enums shall be credited to the creator of Magic Enum. Magic Enum

Summary

light_enum.hpp - Light header file used when accessing enums. Suitable for adding to precompiled headers. light_enum_register.hpp - Heavy header file only to be used in .cpp files where enums are registered.

Interface

Introspecting enums

All these functions are similar to the corresponding function in magic_enum, but a span is returned instead of a std::array. Trying to access an enum not registred throws an out_of_bounds exception.

template <typename E> autoenum_cast(const std::string_view& name) -> std::optional<E>;
template <typename E> autoenum_values() -> detail::span<E>;
template <typename E> autoenum_names() -> detail::span<std::string_view>;
template <typename E> autoenum_name(const E& e) -> std::string_view; // Returns an empty string_view if invalid enumtemplate <typename E> autoenum_count() -> size_t;
template <typename E> autoenum_index(const E& e) -> std::optional<size_t>;
template <typename E> autoenum_contains(const E& e) -> bool;
template <typename E> autoenum_next() -> E; // Returns the next enumtemplate <typename E> autoenum_prev() -> E; // Returns the previous enum

Adding enums to registry

template <typename E> [[nodiscard]]autois_registred() -> bool;
template <typename E> autoregister_enum() -> void;
LIGHT_ENUM_REGISTER(E) // Convenience macro for putting in global namespace 

Usage example

Fruit.h

// Define enum as ususalenumclassFruit{Apple, Orange, Banana};

Fruit.cpp

// Only include light_enum_register.hpp where you register enums
#include"Fruit.h"
#include"light_enum/light_enum_register.hpp"LIGHT_ENUM_REGISTER(Fruit);
// ...or ...LIGHT_ENUM_REGISTER_RANGE(Fruit, 0, 200); // If you have a large enum you can define the range to search for values like this.// Note that the range can be larger than the values of the enum

Application.cpp

#include"Fruit.h"// Only light_enum.hpp is required for accessing enums
#include"light_enum/light_enum.hpp"autofunction() {
// Introspect enums just as Magic Enumconstauto apple = Fruit::Apple;
assert(light_enum::enum_count<Fruit>() == 3);
assert(light_enum::enum_name(apple) == "Apple");
constauto values = light_enum::enum_values<Fruit>();
assert(values[0] == Fruit::Apple);
assert(values[1] == Fruit::Orange);
assert(values[2] == Fruit::Banana);
}

Features

Stable memory

All returned spans and string_views are guaranteed to be stable in memory, even if new enums are registered. Therefore, it's perfectly store them locally for faster access.

Example:

structFruitInfo{
Fruit fruit;
std::string_view name;
};
auto fruit_info = FruitInfo {
EFruit::Apple,
light_enum::enum_name(EFruit::Apple);
};
// fruit_info.name will always be validstructFruitBasket{
span<std::string_view> names;
span<Fruit> fruits;
};
auto fruit_basket = FruitBasket{
light_enum::enum_names<Fruit>(),
light_enum::enum_values<Fruit>()
};
// fruit_basket.names and fruit_basket.fruits will always be valid

Run-time performance

Every introspection * Constructs a std::type_index * Reads a static variable holding the database * Performs a std::unordered_map lookup RTTI is required to be enabled in order to use std::type_index. Future updates will be able to use boost::type_index which does not depend on RTTI.

Installation

Light enum is almost header-only for easy installation.

  • Include light_enum_impl.ipp once in a .cpp file of your choice.
  • Include light_enum.hpp wherever you want to access enums (I recommend you to put this in you precompiled header file)
  • Include "light_enum_register.hpp" in the .cpp files where you register enums, as registering enums is slow from a compile time perspective.

Future improvements

These improvements are planned for the future

  • Ability to change std::type_index to boost::typeindex in order to not require RTTI
  • Ability to change the underlying std::unordered_map to a faster hash-map (tsl::hopscotch_map for example)

License

MIT License. Use however you like, if you're using it in something released I would be happy for a mail telling me about it :)

Contact

I'm available at viktor dot sehr (at) gmail dot com

About

No description, website, or topics provided.

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - gloinart/light_enum · GitHub
Skip to content

Latest commit

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Note, consider this beta right now. Bugfixes and ideas for improvement are more than welcome.

Light-Enum

Light-Enum is an "add-on" for Magic-Enum aiming to provide the same (almost) functionality with low compile time. The idea is to introspect enums (using Magic Enum) at application start and store them all in a global hash map. This means that the heavey Magic Enum introspection only needs to be compiled in a single translation unit/cpp file rather than every time an enum is introspected. See example below.

Magic-Enum

As mentioned, this just a simple add-on for Magic Enum. All the hard work for introspecting enums shall be credited to the creator of Magic Enum. Magic Enum

Summary

light_enum.hpp - Light header file used when accessing enums. Suitable for adding to precompiled headers. light_enum_register.hpp - Heavy header file only to be used in .cpp files where enums are registered.

Interface

Introspecting enums

All these functions are similar to the corresponding function in magic_enum, but a span is returned instead of a std::array. Trying to access an enum not registred throws an out_of_bounds exception.

template <typename E> autoenum_cast(const std::string_view& name) -> std::optional<E>;
template <typename E> autoenum_values() -> detail::span<E>;
template <typename E> autoenum_names() -> detail::span<std::string_view>;
template <typename E> autoenum_name(const E& e) -> std::string_view; // Returns an empty string_view if invalid enumtemplate <typename E> autoenum_count() -> size_t;
template <typename E> autoenum_index(const E& e) -> std::optional<size_t>;
template <typename E> autoenum_contains(const E& e) -> bool;
template <typename E> autoenum_next() -> E; // Returns the next enumtemplate <typename E> autoenum_prev() -> E; // Returns the previous enum

Adding enums to registry

template <typename E> [[nodiscard]]autois_registred() -> bool;
template <typename E> autoregister_enum() -> void;
LIGHT_ENUM_REGISTER(E) // Convenience macro for putting in global namespace 

Usage example

Fruit.h

// Define enum as ususalenumclassFruit{Apple, Orange, Banana};

Fruit.cpp

// Only include light_enum_register.hpp where you register enums
#include"Fruit.h"
#include"light_enum/light_enum_register.hpp"LIGHT_ENUM_REGISTER(Fruit);
// ...or ...LIGHT_ENUM_REGISTER_RANGE(Fruit, 0, 200); // If you have a large enum you can define the range to search for values like this.// Note that the range can be larger than the values of the enum

Application.cpp

#include"Fruit.h"// Only light_enum.hpp is required for accessing enums
#include"light_enum/light_enum.hpp"autofunction() {
// Introspect enums just as Magic Enumconstauto apple = Fruit::Apple;
assert(light_enum::enum_count<Fruit>() == 3);
assert(light_enum::enum_name(apple) == "Apple");
constauto values = light_enum::enum_values<Fruit>();
assert(values[0] == Fruit::Apple);
assert(values[1] == Fruit::Orange);
assert(values[2] == Fruit::Banana);
}

Features

Stable memory

All returned spans and string_views are guaranteed to be stable in memory, even if new enums are registered. Therefore, it's perfectly store them locally for faster access.

Example:

structFruitInfo{
Fruit fruit;
std::string_view name;
};
auto fruit_info = FruitInfo {
EFruit::Apple,
light_enum::enum_name(EFruit::Apple);
};
// fruit_info.name will always be validstructFruitBasket{
span<std::string_view> names;
span<Fruit> fruits;
};
auto fruit_basket = FruitBasket{
light_enum::enum_names<Fruit>(),
light_enum::enum_values<Fruit>()
};
// fruit_basket.names and fruit_basket.fruits will always be valid

Run-time performance

Every introspection * Constructs a std::type_index * Reads a static variable holding the database * Performs a std::unordered_map lookup RTTI is required to be enabled in order to use std::type_index. Future updates will be able to use boost::type_index which does not depend on RTTI.

Installation

Light enum is almost header-only for easy installation.

  • Include light_enum_impl.ipp once in a .cpp file of your choice.
  • Include light_enum.hpp wherever you want to access enums (I recommend you to put this in you precompiled header file)
  • Include "light_enum_register.hpp" in the .cpp files where you register enums, as registering enums is slow from a compile time perspective.

Future improvements

These improvements are planned for the future

  • Ability to change std::type_index to boost::typeindex in order to not require RTTI
  • Ability to change the underlying std::unordered_map to a faster hash-map (tsl::hopscotch_map for example)

License

MIT License. Use however you like, if you're using it in something released I would be happy for a mail telling me about it :)

Contact

I'm available at viktor dot sehr (at) gmail dot com

About

No description, website, or topics provided.

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - gloinart/light_enum · GitHub
Skip to content

Latest commit

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Note, consider this beta right now. Bugfixes and ideas for improvement are more than welcome.

Light-Enum

Light-Enum is an "add-on" for Magic-Enum aiming to provide the same (almost) functionality with low compile time. The idea is to introspect enums (using Magic Enum) at application start and store them all in a global hash map. This means that the heavey Magic Enum introspection only needs to be compiled in a single translation unit/cpp file rather than every time an enum is introspected. See example below.

Magic-Enum

As mentioned, this just a simple add-on for Magic Enum. All the hard work for introspecting enums shall be credited to the creator of Magic Enum. Magic Enum

Summary

light_enum.hpp - Light header file used when accessing enums. Suitable for adding to precompiled headers. light_enum_register.hpp - Heavy header file only to be used in .cpp files where enums are registered.

Interface

Introspecting enums

All these functions are similar to the corresponding function in magic_enum, but a span is returned instead of a std::array. Trying to access an enum not registred throws an out_of_bounds exception.

template <typename E> autoenum_cast(const std::string_view& name) -> std::optional<E>;
template <typename E> autoenum_values() -> detail::span<E>;
template <typename E> autoenum_names() -> detail::span<std::string_view>;
template <typename E> autoenum_name(const E& e) -> std::string_view; // Returns an empty string_view if invalid enumtemplate <typename E> autoenum_count() -> size_t;
template <typename E> autoenum_index(const E& e) -> std::optional<size_t>;
template <typename E> autoenum_contains(const E& e) -> bool;
template <typename E> autoenum_next() -> E; // Returns the next enumtemplate <typename E> autoenum_prev() -> E; // Returns the previous enum

Adding enums to registry

template <typename E> [[nodiscard]]autois_registred() -> bool;
template <typename E> autoregister_enum() -> void;
LIGHT_ENUM_REGISTER(E) // Convenience macro for putting in global namespace 

Usage example

Fruit.h

// Define enum as ususalenumclassFruit{Apple, Orange, Banana};

Fruit.cpp

// Only include light_enum_register.hpp where you register enums
#include"Fruit.h"
#include"light_enum/light_enum_register.hpp"LIGHT_ENUM_REGISTER(Fruit);
// ...or ...LIGHT_ENUM_REGISTER_RANGE(Fruit, 0, 200); // If you have a large enum you can define the range to search for values like this.// Note that the range can be larger than the values of the enum

Application.cpp

#include"Fruit.h"// Only light_enum.hpp is required for accessing enums
#include"light_enum/light_enum.hpp"autofunction() {
// Introspect enums just as Magic Enumconstauto apple = Fruit::Apple;
assert(light_enum::enum_count<Fruit>() == 3);
assert(light_enum::enum_name(apple) == "Apple");
constauto values = light_enum::enum_values<Fruit>();
assert(values[0] == Fruit::Apple);
assert(values[1] == Fruit::Orange);
assert(values[2] == Fruit::Banana);
}

Features

Stable memory

All returned spans and string_views are guaranteed to be stable in memory, even if new enums are registered. Therefore, it's perfectly store them locally for faster access.

Example:

structFruitInfo{
Fruit fruit;
std::string_view name;
};
auto fruit_info = FruitInfo {
EFruit::Apple,
light_enum::enum_name(EFruit::Apple);
};
// fruit_info.name will always be validstructFruitBasket{
span<std::string_view> names;
span<Fruit> fruits;
};
auto fruit_basket = FruitBasket{
light_enum::enum_names<Fruit>(),
light_enum::enum_values<Fruit>()
};
// fruit_basket.names and fruit_basket.fruits will always be valid

Run-time performance

Every introspection * Constructs a std::type_index * Reads a static variable holding the database * Performs a std::unordered_map lookup RTTI is required to be enabled in order to use std::type_index. Future updates will be able to use boost::type_index which does not depend on RTTI.

Installation

Light enum is almost header-only for easy installation.

  • Include light_enum_impl.ipp once in a .cpp file of your choice.
  • Include light_enum.hpp wherever you want to access enums (I recommend you to put this in you precompiled header file)
  • Include "light_enum_register.hpp" in the .cpp files where you register enums, as registering enums is slow from a compile time perspective.

Future improvements

These improvements are planned for the future

  • Ability to change std::type_index to boost::typeindex in order to not require RTTI
  • Ability to change the underlying std::unordered_map to a faster hash-map (tsl::hopscotch_map for example)

License

MIT License. Use however you like, if you're using it in something released I would be happy for a mail telling me about it :)

Contact

I'm available at viktor dot sehr (at) gmail dot com

About

No description, website, or topics provided.

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - gloinart/light_enum · GitHub
Skip to content

Latest commit

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Note, consider this beta right now. Bugfixes and ideas for improvement are more than welcome.

Light-Enum

Light-Enum is an "add-on" for Magic-Enum aiming to provide the same (almost) functionality with low compile time. The idea is to introspect enums (using Magic Enum) at application start and store them all in a global hash map. This means that the heavey Magic Enum introspection only needs to be compiled in a single translation unit/cpp file rather than every time an enum is introspected. See example below.

Magic-Enum

As mentioned, this just a simple add-on for Magic Enum. All the hard work for introspecting enums shall be credited to the creator of Magic Enum. Magic Enum

Summary

light_enum.hpp - Light header file used when accessing enums. Suitable for adding to precompiled headers. light_enum_register.hpp - Heavy header file only to be used in .cpp files where enums are registered.

Interface

Introspecting enums

All these functions are similar to the corresponding function in magic_enum, but a span is returned instead of a std::array. Trying to access an enum not registred throws an out_of_bounds exception.

template <typename E> autoenum_cast(const std::string_view& name) -> std::optional<E>;
template <typename E> autoenum_values() -> detail::span<E>;
template <typename E> autoenum_names() -> detail::span<std::string_view>;
template <typename E> autoenum_name(const E& e) -> std::string_view; // Returns an empty string_view if invalid enumtemplate <typename E> autoenum_count() -> size_t;
template <typename E> autoenum_index(const E& e) -> std::optional<size_t>;
template <typename E> autoenum_contains(const E& e) -> bool;
template <typename E> autoenum_next() -> E; // Returns the next enumtemplate <typename E> autoenum_prev() -> E; // Returns the previous enum

Adding enums to registry

template <typename E> [[nodiscard]]autois_registred() -> bool;
template <typename E> autoregister_enum() -> void;
LIGHT_ENUM_REGISTER(E) // Convenience macro for putting in global namespace 

Usage example

Fruit.h

// Define enum as ususalenumclassFruit{Apple, Orange, Banana};

Fruit.cpp

// Only include light_enum_register.hpp where you register enums
#include"Fruit.h"
#include"light_enum/light_enum_register.hpp"LIGHT_ENUM_REGISTER(Fruit);
// ...or ...LIGHT_ENUM_REGISTER_RANGE(Fruit, 0, 200); // If you have a large enum you can define the range to search for values like this.// Note that the range can be larger than the values of the enum

Application.cpp

#include"Fruit.h"// Only light_enum.hpp is required for accessing enums
#include"light_enum/light_enum.hpp"autofunction() {
// Introspect enums just as Magic Enumconstauto apple = Fruit::Apple;
assert(light_enum::enum_count<Fruit>() == 3);
assert(light_enum::enum_name(apple) == "Apple");
constauto values = light_enum::enum_values<Fruit>();
assert(values[0] == Fruit::Apple);
assert(values[1] == Fruit::Orange);
assert(values[2] == Fruit::Banana);
}

Features

Stable memory

All returned spans and string_views are guaranteed to be stable in memory, even if new enums are registered. Therefore, it's perfectly store them locally for faster access.

Example:

structFruitInfo{
Fruit fruit;
std::string_view name;
};
auto fruit_info = FruitInfo {
EFruit::Apple,
light_enum::enum_name(EFruit::Apple);
};
// fruit_info.name will always be validstructFruitBasket{
span<std::string_view> names;
span<Fruit> fruits;
};
auto fruit_basket = FruitBasket{
light_enum::enum_names<Fruit>(),
light_enum::enum_values<Fruit>()
};
// fruit_basket.names and fruit_basket.fruits will always be valid

Run-time performance

Every introspection * Constructs a std::type_index * Reads a static variable holding the database * Performs a std::unordered_map lookup RTTI is required to be enabled in order to use std::type_index. Future updates will be able to use boost::type_index which does not depend on RTTI.

Installation

Light enum is almost header-only for easy installation.

  • Include light_enum_impl.ipp once in a .cpp file of your choice.
  • Include light_enum.hpp wherever you want to access enums (I recommend you to put this in you precompiled header file)
  • Include "light_enum_register.hpp" in the .cpp files where you register enums, as registering enums is slow from a compile time perspective.

Future improvements

These improvements are planned for the future

  • Ability to change std::type_index to boost::typeindex in order to not require RTTI
  • Ability to change the underlying std::unordered_map to a faster hash-map (tsl::hopscotch_map for example)

License

MIT License. Use however you like, if you're using it in something released I would be happy for a mail telling me about it :)

Contact

I'm available at viktor dot sehr (at) gmail dot com

About

No description, website, or topics provided.

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - gloinart/light_enum · GitHub
Skip to content

Latest commit

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Note, consider this beta right now. Bugfixes and ideas for improvement are more than welcome.

Light-Enum

Light-Enum is an "add-on" for Magic-Enum aiming to provide the same (almost) functionality with low compile time. The idea is to introspect enums (using Magic Enum) at application start and store them all in a global hash map. This means that the heavey Magic Enum introspection only needs to be compiled in a single translation unit/cpp file rather than every time an enum is introspected. See example below.

Magic-Enum

As mentioned, this just a simple add-on for Magic Enum. All the hard work for introspecting enums shall be credited to the creator of Magic Enum. Magic Enum

Summary

light_enum.hpp - Light header file used when accessing enums. Suitable for adding to precompiled headers. light_enum_register.hpp - Heavy header file only to be used in .cpp files where enums are registered.

Interface

Introspecting enums

All these functions are similar to the corresponding function in magic_enum, but a span is returned instead of a std::array. Trying to access an enum not registred throws an out_of_bounds exception.

template <typename E> autoenum_cast(const std::string_view& name) -> std::optional<E>;
template <typename E> autoenum_values() -> detail::span<E>;
template <typename E> autoenum_names() -> detail::span<std::string_view>;
template <typename E> autoenum_name(const E& e) -> std::string_view; // Returns an empty string_view if invalid enumtemplate <typename E> autoenum_count() -> size_t;
template <typename E> autoenum_index(const E& e) -> std::optional<size_t>;
template <typename E> autoenum_contains(const E& e) -> bool;
template <typename E> autoenum_next() -> E; // Returns the next enumtemplate <typename E> autoenum_prev() -> E; // Returns the previous enum

Adding enums to registry

template <typename E> [[nodiscard]]autois_registred() -> bool;
template <typename E> autoregister_enum() -> void;
LIGHT_ENUM_REGISTER(E) // Convenience macro for putting in global namespace 

Usage example

Fruit.h

// Define enum as ususalenumclassFruit{Apple, Orange, Banana};

Fruit.cpp

// Only include light_enum_register.hpp where you register enums
#include"Fruit.h"
#include"light_enum/light_enum_register.hpp"LIGHT_ENUM_REGISTER(Fruit);
// ...or ...LIGHT_ENUM_REGISTER_RANGE(Fruit, 0, 200); // If you have a large enum you can define the range to search for values like this.// Note that the range can be larger than the values of the enum

Application.cpp

#include"Fruit.h"// Only light_enum.hpp is required for accessing enums
#include"light_enum/light_enum.hpp"autofunction() {
// Introspect enums just as Magic Enumconstauto apple = Fruit::Apple;
assert(light_enum::enum_count<Fruit>() == 3);
assert(light_enum::enum_name(apple) == "Apple");
constauto values = light_enum::enum_values<Fruit>();
assert(values[0] == Fruit::Apple);
assert(values[1] == Fruit::Orange);
assert(values[2] == Fruit::Banana);
}

Features

Stable memory

All returned spans and string_views are guaranteed to be stable in memory, even if new enums are registered. Therefore, it's perfectly store them locally for faster access.

Example:

structFruitInfo{
Fruit fruit;
std::string_view name;
};
auto fruit_info = FruitInfo {
EFruit::Apple,
light_enum::enum_name(EFruit::Apple);
};
// fruit_info.name will always be validstructFruitBasket{
span<std::string_view> names;
span<Fruit> fruits;
};
auto fruit_basket = FruitBasket{
light_enum::enum_names<Fruit>(),
light_enum::enum_values<Fruit>()
};
// fruit_basket.names and fruit_basket.fruits will always be valid

Run-time performance

Every introspection * Constructs a std::type_index * Reads a static variable holding the database * Performs a std::unordered_map lookup RTTI is required to be enabled in order to use std::type_index. Future updates will be able to use boost::type_index which does not depend on RTTI.

Installation

Light enum is almost header-only for easy installation.

  • Include light_enum_impl.ipp once in a .cpp file of your choice.
  • Include light_enum.hpp wherever you want to access enums (I recommend you to put this in you precompiled header file)
  • Include "light_enum_register.hpp" in the .cpp files where you register enums, as registering enums is slow from a compile time perspective.

Future improvements

These improvements are planned for the future

  • Ability to change std::type_index to boost::typeindex in order to not require RTTI
  • Ability to change the underlying std::unordered_map to a faster hash-map (tsl::hopscotch_map for example)

License

MIT License. Use however you like, if you're using it in something released I would be happy for a mail telling me about it :)

Contact

I'm available at viktor dot sehr (at) gmail dot com

About

No description, website, or topics provided.

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - gloinart/light_enum · GitHub
Skip to content

Latest commit

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Note, consider this beta right now. Bugfixes and ideas for improvement are more than welcome.

Light-Enum

Light-Enum is an "add-on" for Magic-Enum aiming to provide the same (almost) functionality with low compile time. The idea is to introspect enums (using Magic Enum) at application start and store them all in a global hash map. This means that the heavey Magic Enum introspection only needs to be compiled in a single translation unit/cpp file rather than every time an enum is introspected. See example below.

Magic-Enum

As mentioned, this just a simple add-on for Magic Enum. All the hard work for introspecting enums shall be credited to the creator of Magic Enum. Magic Enum

Summary

light_enum.hpp - Light header file used when accessing enums. Suitable for adding to precompiled headers. light_enum_register.hpp - Heavy header file only to be used in .cpp files where enums are registered.

Interface

Introspecting enums

All these functions are similar to the corresponding function in magic_enum, but a span is returned instead of a std::array. Trying to access an enum not registred throws an out_of_bounds exception.

template <typename E> autoenum_cast(const std::string_view& name) -> std::optional<E>;
template <typename E> autoenum_values() -> detail::span<E>;
template <typename E> autoenum_names() -> detail::span<std::string_view>;
template <typename E> autoenum_name(const E& e) -> std::string_view; // Returns an empty string_view if invalid enumtemplate <typename E> autoenum_count() -> size_t;
template <typename E> autoenum_index(const E& e) -> std::optional<size_t>;
template <typename E> autoenum_contains(const E& e) -> bool;
template <typename E> autoenum_next() -> E; // Returns the next enumtemplate <typename E> autoenum_prev() -> E; // Returns the previous enum

Adding enums to registry

template <typename E> [[nodiscard]]autois_registred() -> bool;
template <typename E> autoregister_enum() -> void;
LIGHT_ENUM_REGISTER(E) // Convenience macro for putting in global namespace 

Usage example

Fruit.h

// Define enum as ususalenumclassFruit{Apple, Orange, Banana};

Fruit.cpp

// Only include light_enum_register.hpp where you register enums
#include"Fruit.h"
#include"light_enum/light_enum_register.hpp"LIGHT_ENUM_REGISTER(Fruit);
// ...or ...LIGHT_ENUM_REGISTER_RANGE(Fruit, 0, 200); // If you have a large enum you can define the range to search for values like this.// Note that the range can be larger than the values of the enum

Application.cpp

#include"Fruit.h"// Only light_enum.hpp is required for accessing enums
#include"light_enum/light_enum.hpp"autofunction() {
// Introspect enums just as Magic Enumconstauto apple = Fruit::Apple;
assert(light_enum::enum_count<Fruit>() == 3);
assert(light_enum::enum_name(apple) == "Apple");
constauto values = light_enum::enum_values<Fruit>();
assert(values[0] == Fruit::Apple);
assert(values[1] == Fruit::Orange);
assert(values[2] == Fruit::Banana);
}

Features

Stable memory

All returned spans and string_views are guaranteed to be stable in memory, even if new enums are registered. Therefore, it's perfectly store them locally for faster access.

Example:

structFruitInfo{
Fruit fruit;
std::string_view name;
};
auto fruit_info = FruitInfo {
EFruit::Apple,
light_enum::enum_name(EFruit::Apple);
};
// fruit_info.name will always be validstructFruitBasket{
span<std::string_view> names;
span<Fruit> fruits;
};
auto fruit_basket = FruitBasket{
light_enum::enum_names<Fruit>(),
light_enum::enum_values<Fruit>()
};
// fruit_basket.names and fruit_basket.fruits will always be valid

Run-time performance

Every introspection * Constructs a std::type_index * Reads a static variable holding the database * Performs a std::unordered_map lookup RTTI is required to be enabled in order to use std::type_index. Future updates will be able to use boost::type_index which does not depend on RTTI.

Installation

Light enum is almost header-only for easy installation.

  • Include light_enum_impl.ipp once in a .cpp file of your choice.
  • Include light_enum.hpp wherever you want to access enums (I recommend you to put this in you precompiled header file)
  • Include "light_enum_register.hpp" in the .cpp files where you register enums, as registering enums is slow from a compile time perspective.

Future improvements

These improvements are planned for the future

  • Ability to change std::type_index to boost::typeindex in order to not require RTTI
  • Ability to change the underlying std::unordered_map to a faster hash-map (tsl::hopscotch_map for example)

License

MIT License. Use however you like, if you're using it in something released I would be happy for a mail telling me about it :)

Contact

I'm available at viktor dot sehr (at) gmail dot com

About

No description, website, or topics provided.

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - gloinart/light_enum · GitHub
Skip to content

Latest commit

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Note, consider this beta right now. Bugfixes and ideas for improvement are more than welcome.

Light-Enum

Light-Enum is an "add-on" for Magic-Enum aiming to provide the same (almost) functionality with low compile time. The idea is to introspect enums (using Magic Enum) at application start and store them all in a global hash map. This means that the heavey Magic Enum introspection only needs to be compiled in a single translation unit/cpp file rather than every time an enum is introspected. See example below.

Magic-Enum

As mentioned, this just a simple add-on for Magic Enum. All the hard work for introspecting enums shall be credited to the creator of Magic Enum. Magic Enum

Summary

light_enum.hpp - Light header file used when accessing enums. Suitable for adding to precompiled headers. light_enum_register.hpp - Heavy header file only to be used in .cpp files where enums are registered.

Interface

Introspecting enums

All these functions are similar to the corresponding function in magic_enum, but a span is returned instead of a std::array. Trying to access an enum not registred throws an out_of_bounds exception.

template <typename E> autoenum_cast(const std::string_view& name) -> std::optional<E>;
template <typename E> autoenum_values() -> detail::span<E>;
template <typename E> autoenum_names() -> detail::span<std::string_view>;
template <typename E> autoenum_name(const E& e) -> std::string_view; // Returns an empty string_view if invalid enumtemplate <typename E> autoenum_count() -> size_t;
template <typename E> autoenum_index(const E& e) -> std::optional<size_t>;
template <typename E> autoenum_contains(const E& e) -> bool;
template <typename E> autoenum_next() -> E; // Returns the next enumtemplate <typename E> autoenum_prev() -> E; // Returns the previous enum

Adding enums to registry

template <typename E> [[nodiscard]]autois_registred() -> bool;
template <typename E> autoregister_enum() -> void;
LIGHT_ENUM_REGISTER(E) // Convenience macro for putting in global namespace 

Usage example

Fruit.h

// Define enum as ususalenumclassFruit{Apple, Orange, Banana};

Fruit.cpp

// Only include light_enum_register.hpp where you register enums
#include"Fruit.h"
#include"light_enum/light_enum_register.hpp"LIGHT_ENUM_REGISTER(Fruit);
// ...or ...LIGHT_ENUM_REGISTER_RANGE(Fruit, 0, 200); // If you have a large enum you can define the range to search for values like this.// Note that the range can be larger than the values of the enum

Application.cpp

#include"Fruit.h"// Only light_enum.hpp is required for accessing enums
#include"light_enum/light_enum.hpp"autofunction() {
// Introspect enums just as Magic Enumconstauto apple = Fruit::Apple;
assert(light_enum::enum_count<Fruit>() == 3);
assert(light_enum::enum_name(apple) == "Apple");
constauto values = light_enum::enum_values<Fruit>();
assert(values[0] == Fruit::Apple);
assert(values[1] == Fruit::Orange);
assert(values[2] == Fruit::Banana);
}

Features

Stable memory

All returned spans and string_views are guaranteed to be stable in memory, even if new enums are registered. Therefore, it's perfectly store them locally for faster access.

Example:

structFruitInfo{
Fruit fruit;
std::string_view name;
};
auto fruit_info = FruitInfo {
EFruit::Apple,
light_enum::enum_name(EFruit::Apple);
};
// fruit_info.name will always be validstructFruitBasket{
span<std::string_view> names;
span<Fruit> fruits;
};
auto fruit_basket = FruitBasket{
light_enum::enum_names<Fruit>(),
light_enum::enum_values<Fruit>()
};
// fruit_basket.names and fruit_basket.fruits will always be valid

Run-time performance

Every introspection * Constructs a std::type_index * Reads a static variable holding the database * Performs a std::unordered_map lookup RTTI is required to be enabled in order to use std::type_index. Future updates will be able to use boost::type_index which does not depend on RTTI.

Installation

Light enum is almost header-only for easy installation.

  • Include light_enum_impl.ipp once in a .cpp file of your choice.
  • Include light_enum.hpp wherever you want to access enums (I recommend you to put this in you precompiled header file)
  • Include "light_enum_register.hpp" in the .cpp files where you register enums, as registering enums is slow from a compile time perspective.

Future improvements

These improvements are planned for the future

  • Ability to change std::type_index to boost::typeindex in order to not require RTTI
  • Ability to change the underlying std::unordered_map to a faster hash-map (tsl::hopscotch_map for example)

License

MIT License. Use however you like, if you're using it in something released I would be happy for a mail telling me about it :)

Contact

I'm available at viktor dot sehr (at) gmail dot com

About

No description, website, or topics provided.

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - gloinart/light_enum · GitHub
Skip to content

Latest commit

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Note, consider this beta right now. Bugfixes and ideas for improvement are more than welcome.

Light-Enum

Light-Enum is an "add-on" for Magic-Enum aiming to provide the same (almost) functionality with low compile time. The idea is to introspect enums (using Magic Enum) at application start and store them all in a global hash map. This means that the heavey Magic Enum introspection only needs to be compiled in a single translation unit/cpp file rather than every time an enum is introspected. See example below.

Magic-Enum

As mentioned, this just a simple add-on for Magic Enum. All the hard work for introspecting enums shall be credited to the creator of Magic Enum. Magic Enum

Summary

light_enum.hpp - Light header file used when accessing enums. Suitable for adding to precompiled headers. light_enum_register.hpp - Heavy header file only to be used in .cpp files where enums are registered.

Interface

Introspecting enums

All these functions are similar to the corresponding function in magic_enum, but a span is returned instead of a std::array. Trying to access an enum not registred throws an out_of_bounds exception.

template <typename E> autoenum_cast(const std::string_view& name) -> std::optional<E>;
template <typename E> autoenum_values() -> detail::span<E>;
template <typename E> autoenum_names() -> detail::span<std::string_view>;
template <typename E> autoenum_name(const E& e) -> std::string_view; // Returns an empty string_view if invalid enumtemplate <typename E> autoenum_count() -> size_t;
template <typename E> autoenum_index(const E& e) -> std::optional<size_t>;
template <typename E> autoenum_contains(const E& e) -> bool;
template <typename E> autoenum_next() -> E; // Returns the next enumtemplate <typename E> autoenum_prev() -> E; // Returns the previous enum

Adding enums to registry

template <typename E> [[nodiscard]]autois_registred() -> bool;
template <typename E> autoregister_enum() -> void;
LIGHT_ENUM_REGISTER(E) // Convenience macro for putting in global namespace 

Usage example

Fruit.h

// Define enum as ususalenumclassFruit{Apple, Orange, Banana};

Fruit.cpp

// Only include light_enum_register.hpp where you register enums
#include"Fruit.h"
#include"light_enum/light_enum_register.hpp"LIGHT_ENUM_REGISTER(Fruit);
// ...or ...LIGHT_ENUM_REGISTER_RANGE(Fruit, 0, 200); // If you have a large enum you can define the range to search for values like this.// Note that the range can be larger than the values of the enum

Application.cpp

#include"Fruit.h"// Only light_enum.hpp is required for accessing enums
#include"light_enum/light_enum.hpp"autofunction() {
// Introspect enums just as Magic Enumconstauto apple = Fruit::Apple;
assert(light_enum::enum_count<Fruit>() == 3);
assert(light_enum::enum_name(apple) == "Apple");
constauto values = light_enum::enum_values<Fruit>();
assert(values[0] == Fruit::Apple);
assert(values[1] == Fruit::Orange);
assert(values[2] == Fruit::Banana);
}

Features

Stable memory

All returned spans and string_views are guaranteed to be stable in memory, even if new enums are registered. Therefore, it's perfectly store them locally for faster access.

Example:

structFruitInfo{
Fruit fruit;
std::string_view name;
};
auto fruit_info = FruitInfo {
EFruit::Apple,
light_enum::enum_name(EFruit::Apple);
};
// fruit_info.name will always be validstructFruitBasket{
span<std::string_view> names;
span<Fruit> fruits;
};
auto fruit_basket = FruitBasket{
light_enum::enum_names<Fruit>(),
light_enum::enum_values<Fruit>()
};
// fruit_basket.names and fruit_basket.fruits will always be valid

Run-time performance

Every introspection * Constructs a std::type_index * Reads a static variable holding the database * Performs a std::unordered_map lookup RTTI is required to be enabled in order to use std::type_index. Future updates will be able to use boost::type_index which does not depend on RTTI.

Installation

Light enum is almost header-only for easy installation.

  • Include light_enum_impl.ipp once in a .cpp file of your choice.
  • Include light_enum.hpp wherever you want to access enums (I recommend you to put this in you precompiled header file)
  • Include "light_enum_register.hpp" in the .cpp files where you register enums, as registering enums is slow from a compile time perspective.

Future improvements

These improvements are planned for the future

  • Ability to change std::type_index to boost::typeindex in order to not require RTTI
  • Ability to change the underlying std::unordered_map to a faster hash-map (tsl::hopscotch_map for example)

License

MIT License. Use however you like, if you're using it in something released I would be happy for a mail telling me about it :)

Contact

I'm available at viktor dot sehr (at) gmail dot com

About

No description, website, or topics provided.

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages