BitIteratorDetail.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * Copyright 2011-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #pragma once
  17. #include <iterator>
  18. #include <type_traits>
  19. #include <boost/iterator/iterator_adaptor.hpp>
  20. namespace folly {
  21. template <class BaseIter>
  22. class BitIterator;
  23. namespace bititerator_detail {
  24. // Reference to a bit.
  25. // Templatize on both parent reference and value types to capture
  26. // const-ness correctly and to work with the case where Ref is a
  27. // reference-like type (not T&), just like our BitReference here.
  28. template <class Ref, class Value>
  29. class BitReference {
  30. public:
  31. BitReference(Ref r, size_t bit) : ref_(r), bit_(bit) {}
  32. /* implicit */ operator bool() const {
  33. return ref_ & (one_ << bit_);
  34. }
  35. BitReference& operator=(bool b) {
  36. if (b) {
  37. set();
  38. } else {
  39. clear();
  40. }
  41. return *this;
  42. }
  43. void set() {
  44. ref_ |= (one_ << bit_);
  45. }
  46. void clear() {
  47. ref_ &= ~(one_ << bit_);
  48. }
  49. void flip() {
  50. ref_ ^= (one_ << bit_);
  51. }
  52. private:
  53. // shortcut to avoid writing static_cast everywhere
  54. const static Value one_ = 1;
  55. Ref ref_;
  56. size_t bit_;
  57. };
  58. template <class BaseIter>
  59. struct BitIteratorBase {
  60. static_assert(
  61. std::is_integral<
  62. typename std::iterator_traits<BaseIter>::value_type>::value,
  63. "BitIterator may only be used with integral types");
  64. typedef boost::iterator_adaptor<
  65. BitIterator<BaseIter>, // Derived
  66. BaseIter, // Base
  67. bool, // Value
  68. boost::use_default, // CategoryOrTraversal
  69. bititerator_detail::BitReference<
  70. typename std::iterator_traits<BaseIter>::reference,
  71. typename std::iterator_traits<BaseIter>::value_type>, // Reference
  72. ssize_t>
  73. type;
  74. };
  75. } // namespace bititerator_detail
  76. } // namespace folly