/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later // SPDX-FileCopyrightText: 2020 Marco Trevisan #pragma once #include #include namespace GjsEnum { template constexpr bool is_class() { if constexpr (std::is_enum_v) { return !std::is_convertible_v>; } return false; } template struct WrapperImpl { EnumType e; constexpr explicit WrapperImpl(EnumType const& en) : e(en) {} constexpr explicit WrapperImpl(std::underlying_type_t const& en) : e(static_cast(en)) {} constexpr explicit operator bool() const { return static_cast(e); } constexpr operator EnumType() const { return e; } constexpr operator std::underlying_type_t() const { return std::underlying_type_t(e); } }; #if defined (__clang__) || defined (__GNUC__) template using Wrapper = std::conditional_t(), WrapperImpl, void>; #else template using Wrapper = std::conditional_t(), std::underlying_type_t, void>; #endif } // namespace GjsEnum template > constexpr std::enable_if_t(), Wrapped> operator&( EnumType const& first, EnumType const& second) { return static_cast(static_cast(first) & static_cast(second)); } template > constexpr std::enable_if_t(), Wrapped> operator|( EnumType const& first, EnumType const& second) { return static_cast(static_cast(first) | static_cast(second)); } template > constexpr std::enable_if_t(), Wrapped> operator^( EnumType const& first, EnumType const& second) { return static_cast(static_cast(first) ^ static_cast(second)); } template > constexpr std::enable_if_t(), Wrapped&> operator|=( EnumType& first, // NOLINT(runtime/references) EnumType const& second) { first = static_cast(first | second); return reinterpret_cast(first); } template > constexpr std::enable_if_t(), Wrapped&> operator&=( EnumType& first, // NOLINT(runtime/references) EnumType const& second) { first = static_cast(first & second); return reinterpret_cast(first); } template > constexpr std::enable_if_t(), EnumType> operator~( EnumType const& first) { return static_cast(~static_cast(first)); }