// This work derives from Vittorio Romeo's code used for cppcon 2015 licensed // under the Academic Free License. // His code is available here: https://github.com/SuperV1234/cppcon2015 #ifndef EC_BITSET_HPP #define EC_BITSET_HPP #include #include "Meta/TypeList.hpp" #include "Meta/Combine.hpp" #include "Meta/IndexOf.hpp" #include "Meta/ForEach.hpp" #include "Meta/Contains.hpp" namespace EC { // Note bitset size is sizes of components and tags + 1 // This is to use the last extra bit as the result of a query // with a Component or Tag not known to the Bitset. // Those queries should return a false bit every time as long as EC::Manager // does not change that last bit. template struct Bitset : public std::bitset { using Combined = EC::Meta::Combine; Bitset() { (*this)[Combined::size] = false; } template constexpr auto getComponentBit() const { auto index = EC::Meta::IndexOf::value; return (*this)[index]; } template constexpr auto getComponentBit() { auto index = EC::Meta::IndexOf::value; return (*this)[index]; } template constexpr auto getTagBit() const { auto index = EC::Meta::IndexOf::value; return (*this)[index]; } template constexpr auto getTagBit() { auto index = EC::Meta::IndexOf::value; return (*this)[index]; } template static constexpr Bitset generateBitset() { Bitset bitset; EC::Meta::forEach([&bitset] (auto t) { if(EC::Meta::Contains::value) { bitset[EC::Meta::IndexOf::value] = true; } }); return bitset; } template auto getCombinedBit(const IntegralType& i) { static_assert(std::is_integral::value, "Parameter must be an integral type"); if(i >= Combined::size || i < 0) { return (*this)[Combined::size]; } else { return (*this)[i]; } } template auto getCombinedBit(const IntegralType& i) const { static_assert(std::is_integral::value, "Parameter must be an integral type"); if(i >= Combined::size || i < 0) { return (*this)[Combined::size]; } else { return (*this)[i]; } } }; } #endif