Skip to content

Instantly share code, notes, and snippets.

@ltjax
Created January 13, 2020 17:51
Show Gist options
  • Select an option

  • Save ltjax/a86f9bf3107f25d758283d3b62a2059d to your computer and use it in GitHub Desktop.

Select an option

Save ltjax/a86f9bf3107f25d758283d3b62a2059d to your computer and use it in GitHub Desktop.

Revisions

  1. ltjax created this gist Jan 13, 2020.
    76 changes: 76 additions & 0 deletions scoped_flags.hpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,76 @@
    #pragma once

    template <class T>
    class scoped_flags
    {
    public:
    using value_type = std::underlying_type_t<T>;

    scoped_flags(std::initializer_list<T> flag_list)
    : value_(combine_(flag_list))
    {
    }

    scoped_flags()
    : value_(0)
    {
    }

    bool test(T flag) const
    {
    return value_ & static_cast<value_type>(flag);
    }

    bool test(std::initializer_list<T> flag_list) const
    {
    auto other = combine_(flag_list);
    return (value_ & other) == other;
    }

    scoped_flags<T> with(T flag) const
    {
    return { value_ | static_cast<value_type>(flag) };
    }

    scoped_flags<T> changed(T flag, bool enabled) const
    {
    return enabled ? with(flag) : without(flag);
    }

    scoped_flags<T> with(std::initializer_list<T> flag_list) const
    {
    return { value_ | combine_(flag_list) };
    }

    scoped_flags<T> without(T flag) const
    {
    return { value_ & ~(static_cast<value_type>(flag)) };
    }

    value_type to_underlying_type() const
    {
    return value_;
    }

    static scoped_flags<T> from_underlying_type(value_type value)
    {
    return {value};
    }

    private:

    static value_type combine_(std::initializer_list<T> flag_list)
    {
    auto value = 0;
    for (auto each : flag_list)
    value |= static_cast<value_type>(each);
    return value;
    }

    scoped_flags(value_type value)
    : value_(value)
    {
    }

    value_type value_;
    };