You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
3.4 KiB

  1. //==============================================================================
  2. //
  3. // Copyright (c) 2015-
  4. // Authors:
  5. // * Joachim Klein <klein@tcs.inf.tu-dresden.de>
  6. // * David Mueller <david.mueller@tcs.inf.tu-dresden.de>
  7. //
  8. //------------------------------------------------------------------------------
  9. //
  10. // This file is part of the cpphoafparser library,
  11. // http://automata.tools/hoa/cpphoafparser/
  12. //
  13. // The cpphoafparser library is free software; you can redistribute it and/or
  14. // modify it under the terms of the GNU Lesser General Public
  15. // License as published by the Free Software Foundation; either
  16. // version 2.1 of the License, or (at your option) any later version.
  17. //
  18. // The cpphoafparser library is distributed in the hope that it will be useful,
  19. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  21. // Lesser General Public License for more details.
  22. //
  23. // You should have received a copy of the GNU Lesser General Public
  24. // License along with this library; if not, write to the Free Software
  25. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  26. //
  27. //==============================================================================
  28. #ifndef CPPHOAFPARSER_DYNAMICBITSET_H
  29. #define CPPHOAFPARSER_DYNAMICBITSET_H
  30. #include <vector>
  31. namespace cpphoafparser {
  32. /**
  33. * A dynamic bitset that grows automatically.
  34. * Inherits the functionality of std::vector<bool>, adding
  35. * convenience functions.
  36. **/
  37. class dynamic_bitset : public std::vector<bool> {
  38. public:
  39. /**
  40. * Set the bit at the given `index` to `value`.
  41. * It `index` is larger than the highest set bit,
  42. * the intermediate bits are set to `false`.
  43. */
  44. void set(std::size_t index, bool value=true) {
  45. if (index >= size()) {
  46. resize(index+1, false);
  47. }
  48. at(index) = value;
  49. }
  50. /**
  51. * Get the bit at the given `index`.
  52. * If `index` is beyond the highest set bit
  53. * then return false.
  54. */
  55. bool get(std::size_t index) const {
  56. if (index >= size()) {
  57. return false;
  58. }
  59. return at(index);
  60. }
  61. /**
  62. * Returns the index of the highest set bit.
  63. * The actual return value is a pair, where the first
  64. * element is the index of the highest set bit (if there
  65. * are any) and the second element being false
  66. * if there is no set bit at all.
  67. */
  68. std::pair<std::size_t,bool> getHighestSetBit() const {
  69. if (size() == 0) {
  70. return std::make_pair(0, false);
  71. }
  72. for (std::size_t index = size(); index > 0; index--) {
  73. if ((*this)[index-1]) {
  74. return std::make_pair(index-1, true);
  75. }
  76. }
  77. return std::make_pair(0, false);
  78. }
  79. /**
  80. * Returns the cardinality (the number of set bits) of this
  81. * bitset.
  82. */
  83. std::size_t cardinality() const {
  84. std::size_t result = 0;
  85. for (bool b : *this) {
  86. if (b) result++;
  87. }
  88. return result;
  89. }
  90. /**
  91. * Perform andNot operator on this bitset.
  92. * After calling this function a bit is set in this bitset
  93. * if it was set before and if the corresponding bit in
  94. * `other` is not set.
  95. */
  96. void andNot(const dynamic_bitset& other) {
  97. for (std::size_t index = 0; index < size() && index < other.size(); index++) {
  98. at(index) = at(index) & !other.at(index);
  99. }
  100. }
  101. /** Returns `true` if there are not set bits */
  102. bool isEmpty() const {
  103. for (bool b : *this) {
  104. if (b) return false;
  105. }
  106. return true;
  107. }
  108. };
  109. }
  110. #endif