/* * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu * * This software is distributed under the terms of the GNU General Public * Licence version 3 (GPL Version 3). See file LICENSE for a full version of * the license. */ #pragma once /** \author Hans Dembinski \author Lukas Nellen \author Darko Veberic \date 27 Jan 2014 \version $Id: Bit.h 25126 2014-02-03 22:13:10Z darko $ */ #include <exception> // #include <utl/AugerException.h> namespace corsika::utl { namespace Bit { template <typename T> class Array { public: Array(T& target) : fTarget(target) {} class Bit { public: Bit(T& target, T mask) : fTarget(target) , fMask(mask) {} operator bool() const { return fTarget & fMask; } bool operator~() const { return !bool(*this); } Bit& operator=(const bool value) { if (value) fTarget |= fMask; else fTarget &= ~fMask; return *this; } Bit& Flip() { return *this = ~(*this); } private: T& fTarget; T fMask; }; Bit operator[](unsigned int position) { return Bit(fTarget, T(1) << position); } Bit At(unsigned int position) { if (position >= 8 * sizeof(T)) // throw std::exceptionOutOfBoundException("Running out of bits."); throw std::exception("Running out of bits."); return (*this)[position]; } template <typename M> Array& Mask(const M mask, const bool value) { Bit(fTarget, mask) = value; return *this; } template <typename M> T Get(const M mask) { return fTarget & T(mask); } private: T& fTarget; }; } // namespace Bit // helper template <typename T> inline Bit::Array<T> AsBitArray(T& target) { return Bit::Array<T>(target); } } // namespace corsika::utl