Created
February 3, 2016 08:30
-
-
Save ned14/89ee39c6b8eb5254116a to your computer and use it in GitHub Desktop.
AFIO v2 style of C++ bitfields
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#define BOOST_CXX14_CONSTEXPR constexpr | |
//! Constexpr bitwise flags support | |
template<class Derived, class T = unsigned> class bitwise_flags | |
{ | |
T _value; | |
public: | |
//! The underlying type | |
using underlying_type = T; | |
//! The implementation type | |
using implementation_type = Derived; | |
//protected: | |
//! Default constructs to all bits zero | |
constexpr bitwise_flags() noexcept : _value(0) { } | |
//! Constructs to a predetermined value | |
explicit constexpr bitwise_flags(underlying_type _v) noexcept : _value(_v) { } | |
static constexpr implementation_type bit(int b) noexcept { return bitwise_flags(1<<b); } | |
public: | |
//! Returns the underlying value | |
explicit constexpr operator underlying_type() const noexcept { return _value; } | |
//! True if value is not all bits zero | |
explicit constexpr operator bool() const noexcept { return !!_value; } | |
//! True if value is all bits zero | |
constexpr bool operator !() const noexcept { return !_value; } | |
//! True if value has the specified bit set | |
constexpr bool operator&&(implementation_type o) const noexcept { return !!(_value&&o._value); } | |
//! Performs a bitwise NOT | |
constexpr implementation_type operator ~() const noexcept { return bitwise_flags(~_value); } | |
//! Performs a bitwise AND | |
constexpr implementation_type operator &(implementation_type o) const noexcept { return bitwise_flags(_value&o._value); } | |
//! Performs a bitwise AND | |
BOOST_CXX14_CONSTEXPR implementation_type &operator &=(implementation_type o) noexcept { _value &= o._value; return static_cast<implementation_type &>(*this); } | |
//! Performs a bitwise OR | |
constexpr implementation_type operator |(implementation_type o) const noexcept { return bitwise_flags(_value | o._value); } | |
//! Performs a bitwise OR | |
BOOST_CXX14_CONSTEXPR implementation_type &operator |=(implementation_type o) noexcept { _value |= o._value; return static_cast<implementation_type &>(*this); } | |
//! Performs a bitwise XOR | |
constexpr implementation_type operator ^(implementation_type o) const noexcept { return bitwise_flags(_value ^ o._value); } | |
//! Performs a bitwise XOR | |
BOOST_CXX14_CONSTEXPR implementation_type &operator ^=(implementation_type o) noexcept { _value ^= o._value; return static_cast<implementation_type &>(*this); } | |
}; | |
//! Bitwise flags which can be specified | |
struct flag : bitwise_flags<flag> | |
{ | |
flag() = default; | |
constexpr flag(bitwise_flags<flag> v) noexcept : bitwise_flags<flag>(v) { } | |
//! No flags | |
static constexpr auto none(){ return bit(0);} | |
//! Delete the file on last handle close | |
static constexpr auto delete_on_close(){ return bit(1); } | |
/*! Some kernel caching modes have unhelpfully inconsistent behaviours | |
in getting your data onto storage, so by default unless this flag is | |
specified AFIO adds extra fsyncs to the following operations for the | |
caching modes specified below: | |
* truncation of file length either explicitly or during file open. | |
* closing of the handle either explicitly or in the destructor. | |
This only occurs for these kernel caching modes: | |
* caching::none | |
* caching::reads | |
* caching::reads_and_metadata | |
* caching::safety_fsyncs | |
*/ | |
static constexpr auto disable_safety_fsyncs(){ return bit(2); } | |
}; | |
int main(void) | |
{ | |
flag f(flag::disable_safety_fsyncs()); | |
flag f2(f&flag::none()); | |
f2|=flag::delete_on_close(); | |
constexpr flag f3(flag::disable_safety_fsyncs()); | |
constexpr flag f4(f3&flag::none()); | |
printf("f=%d, f2=%d, f3=%d, f4=%d\n", (unsigned) f, (unsigned) f2, (unsigned) f3, (unsigned) f4); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment