/* Functions to support fixed-length bitmaps. Copyright (C) 2024 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #ifndef GCC_BBITMAP_H #define GCC_BBITMAP_H /* Implementation of bounded (fixed length) bitmaps. This provides a drop-in replacement for bitmaps that have outgrown the storage capacity of a single integer. Sets are stored as a fixed length array of uint64_t elements. The length of this array is given as a template parameter. */ /* Use recusive templated functions to define constexpr operations. */ template struct bbitmap_operators { /* Return a result that maps binary operator OP to elements [0, M) of X and Y, and takes the remaining elements from REST. */ template static constexpr Result binary(Operator op, const Arg &x, const Arg &y, Rest ...rest) { return bbitmap_operators::template binary (op, x, y, op (x.val[M - 1], y.val[M - 1]), rest...); } /* Return a result that contains the bitwise inverse of elements [0, M) of X, and takes the remaining elements from REST. */ template static constexpr Result bit_not(const Arg &x, Rest ...rest) { return bbitmap_operators::template bit_not (x, ~(x.val[M - 1]), rest...); } /* Return true if any element [0, M) of X is nonzero. */ template static constexpr bool non_zero(const Arg &x) { return (bool) x.val[M - 1] || bbitmap_operators::template non_zero (x); } /* Return true if elements [0, M) of X are all equal to the corresponding elements of Y. */ template static constexpr bool equal(const Arg &x, const Arg &y) { return x.val[M - 1] == y.val[M - 1] && bbitmap_operators::template equal (x, y); } /* If bit index INDEX selects a bit in the first M elements, return a Result with that bit set and the other bits of the leading M elements clear. Clear the leading M elements otherwise. Take the remaining elements of the Result from REST. */ template static constexpr Result from_index(int index, Rest ...rest) { return bbitmap_operators::template from_index (index, uint64_t ((index - (M - 1) * 64) == (index & 63)) << (index & 63), rest...); } }; /* These functions form the base for the recursive functions above. They return either bitmap containing the elements passed in REST, or a default bool result. */ template<> struct bbitmap_operators<0> { template static constexpr Result binary(Operator, const Arg, const Arg, Rest ...rest) { return Result { rest... }; } template static constexpr Result bit_not(const Arg, Rest ...rest) { return Result { rest... }; } template static constexpr bool non_zero(const Arg) { return false; } template static constexpr bool equal(const Arg, const Arg) { return true; } template static constexpr Result from_index(int, Rest ...rest) { return Result { rest... }; } }; template constexpr T bbitmap_element_or(T x, T y) { return x | y;} template constexpr T bbitmap_element_and(T x, T y) { return x & y;} template constexpr T bbitmap_element_xor(T x, T y) { return x ^ y;} template class GTY((user)) bbitmap { public: uint64_t val[N]; template constexpr bbitmap(Rest ...rest) : val{(uint64_t) rest...} {} constexpr bbitmap operator|(const bbitmap other) const { return bbitmap_operators::template binary> (bbitmap_element_or, *this, other); } bbitmap operator|=(const bbitmap other) { for (int i = 0; i < N; i++) val[i] |= other.val[i]; return this; } constexpr bbitmap operator&(const bbitmap other) const { return bbitmap_operators::template binary> (bbitmap_element_and, *this, other); } bbitmap operator&=(const bbitmap other) { for (int i = 0; i < N; i++) val[i] &= other.val[i]; return this; } constexpr bbitmap operator^(const bbitmap other) const { return bbitmap_operators::template binary> (bbitmap_element_xor, *this, other); } bbitmap operator^=(const bbitmap other) { for (int i = 0; i < N; i++) val[i] ^= other.val[i]; return this; } constexpr bbitmap operator~() const { return bbitmap_operators::template bit_not>(*this); } constexpr bool operator!() const { return !(bbitmap_operators::template non_zero>(*this)); } constexpr explicit operator bool() const { return bbitmap_operators::template non_zero>(*this); } constexpr bool operator==(const bbitmap other) const { return bbitmap_operators::template equal>(*this, other); } constexpr bool operator!=(const bbitmap other) const { return !(bbitmap_operators::template equal>(*this, other)); } /* Return a bitmap with bit INDEX set and all other bits clear. */ static constexpr bbitmap from_index (int index) { return bbitmap_operators::template from_index> (index); } }; template void gt_ggc_mx (bbitmap *) { } template void gt_pch_nx (bbitmap *) { } template void gt_pch_nx (bbitmap *, gt_pointer_operator, void *) { } #endif