Skip to content

Instantly share code, notes, and snippets.

@ned14
Created February 3, 2016 08:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ned14/89ee39c6b8eb5254116a to your computer and use it in GitHub Desktop.
Save ned14/89ee39c6b8eb5254116a to your computer and use it in GitHub Desktop.
AFIO v2 style of C++ bitfields
#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