flags: Utilize underlying_type for more expressiveness
Change-Id: Ie57b3a17d8eccd9c7701f7679102395f96670607
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include-dl/stdplus/dl.hpp b/include-dl/stdplus/dl.hpp
index 24044c1..4c653da 100644
--- a/include-dl/stdplus/dl.hpp
+++ b/include-dl/stdplus/dl.hpp
@@ -23,15 +23,15 @@
DeepBind = RTLD_DEEPBIND,
};
-class DlOpenFlags : public stdplus::BitFlags<int, DlOpenFlag>
+class DlOpenFlags : public stdplus::BitFlags<DlOpenFlag>
{
public:
inline DlOpenFlags(DlOpenType type) :
- BitFlags<int, DlOpenFlag>(static_cast<int>(type))
+ BitFlags<DlOpenFlag>(std::to_underlying(type))
{}
- inline DlOpenFlags(BitFlags<int, DlOpenFlag> flags) :
- BitFlags<int, DlOpenFlag>(flags)
+ inline DlOpenFlags(BitFlags<DlOpenFlag> flags) :
+ BitFlags<DlOpenFlag>(flags)
{}
};
diff --git a/include-fd/stdplus/fd/create.hpp b/include-fd/stdplus/fd/create.hpp
index 9bd7ede..81ebfde 100644
--- a/include-fd/stdplus/fd/create.hpp
+++ b/include-fd/stdplus/fd/create.hpp
@@ -41,16 +41,14 @@
Trunc = O_TRUNC,
};
-class OpenFlags : public BitFlags<int, OpenFlag>
+class OpenFlags : public BitFlags<OpenFlag>
{
public:
inline OpenFlags(OpenAccess access) :
- BitFlags<int, OpenFlag>(static_cast<int>(access))
+ BitFlags<OpenFlag>(std::to_underlying(access))
{}
- inline OpenFlags(BitFlags<int, OpenFlag> flags) :
- BitFlags<int, OpenFlag>(flags)
- {}
+ inline OpenFlags(BitFlags<OpenFlag> flags) : BitFlags<OpenFlag>(flags) {}
};
DupableFd open(const_zstring pathname, OpenFlags flags, mode_t mode = 0);
diff --git a/include-fd/stdplus/fd/intf.hpp b/include-fd/stdplus/fd/intf.hpp
index c4e2d7b..7f448c8 100644
--- a/include-fd/stdplus/fd/intf.hpp
+++ b/include-fd/stdplus/fd/intf.hpp
@@ -24,7 +24,7 @@
Trunc = MSG_TRUNC,
WaitAll = MSG_WAITALL,
};
-using RecvFlags = BitFlags<int, RecvFlag>;
+using RecvFlags = BitFlags<RecvFlag>;
enum class SendFlag : int
{
@@ -36,7 +36,7 @@
NoSignal = MSG_NOSIGNAL,
OutOfBounds = MSG_OOB,
};
-using SendFlags = BitFlags<int, SendFlag>;
+using SendFlags = BitFlags<SendFlag>;
enum class Whence : int
{
@@ -71,7 +71,7 @@
{
CloseOnExec = FD_CLOEXEC,
};
-using FdFlags = BitFlags<int, FdFlag>;
+using FdFlags = BitFlags<FdFlag>;
enum class FileFlag : int
{
@@ -81,7 +81,7 @@
NoAtime = O_NOATIME,
NonBlock = O_NONBLOCK,
};
-using FileFlags = BitFlags<int, FileFlag>;
+using FileFlags = BitFlags<FileFlag>;
enum class ProtFlag : int
{
@@ -89,7 +89,7 @@
Read = PROT_READ,
Write = PROT_WRITE,
};
-using ProtFlags = BitFlags<int, ProtFlag>;
+using ProtFlags = BitFlags<ProtFlag>;
enum class MMapAccess : int
{
@@ -101,16 +101,14 @@
{
};
-class MMapFlags : public BitFlags<int, MMapFlag>
+class MMapFlags : public BitFlags<MMapFlag>
{
public:
inline MMapFlags(MMapAccess access) :
- BitFlags<int, MMapFlag>(static_cast<int>(access))
+ BitFlags<MMapFlag>(std::to_underlying(access))
{}
- inline MMapFlags(BitFlags<int, MMapFlag> flags) :
- BitFlags<int, MMapFlag>(flags)
- {}
+ inline MMapFlags(BitFlags<MMapFlag> flags) : BitFlags<MMapFlag>(flags) {}
};
class MMap;
diff --git a/include/stdplus/flags.hpp b/include/stdplus/flags.hpp
index a5678f3..4fdd511 100644
--- a/include/stdplus/flags.hpp
+++ b/include/stdplus/flags.hpp
@@ -1,44 +1,52 @@
#pragma once
+#include <stdplus/concepts.hpp>
+
+#include <concepts>
+#include <type_traits>
#include <utility>
namespace stdplus
{
-template <typename Int, typename Flag = Int>
+template <Enum T, std::integral I = std::underlying_type_t<T>>
class BitFlags
{
public:
- inline explicit BitFlags(Int val = 0) noexcept : val(val) {}
+ using type = T;
+ using underlying = I;
- inline BitFlags& set(Flag flag) & noexcept
+ inline BitFlags() noexcept : val(0) {}
+ explicit inline BitFlags(underlying val) noexcept : val(val) {}
+
+ inline BitFlags& set(type flag) & noexcept
{
- val |= static_cast<Int>(flag);
+ val |= std::to_underlying(flag);
return *this;
}
- inline BitFlags&& set(Flag flag) && noexcept
+ inline BitFlags&& set(type flag) && noexcept
{
- val |= static_cast<Int>(flag);
+ val |= std::to_underlying(flag);
return std::move(*this);
}
- inline BitFlags& unset(Flag flag) & noexcept
+ inline BitFlags& unset(type flag) & noexcept
{
- val &= ~static_cast<Int>(flag);
+ val &= ~std::to_underlying(flag);
return *this;
}
- inline BitFlags&& unset(Flag flag) && noexcept
+ inline BitFlags&& unset(type flag) && noexcept
{
- val &= ~static_cast<Int>(flag);
+ val &= ~std::to_underlying(flag);
return std::move(*this);
}
- explicit inline operator Int() const noexcept
+ explicit inline operator underlying() const noexcept
{
return val;
}
private:
- Int val;
+ underlying val;
};
} // namespace stdplus