Revert D5408572: replace getnameinfo with inet_ntop in v6 string formatting
[folly.git] / folly / detail / BitIteratorDetail.h
1 /*
2  * Copyright 2017 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
17 #pragma once
18
19 #include <iterator>
20 #include <type_traits>
21 #include <boost/iterator/iterator_adaptor.hpp>
22
23 namespace folly {
24
25 template <class BaseIter> class BitIterator;
26
27 namespace bititerator_detail {
28
29 // Reference to a bit.
30 // Templatize on both parent reference and value types to capture
31 // const-ness correctly and to work with the case where Ref is a
32 // reference-like type (not T&), just like our BitReference here.
33 template <class Ref, class Value>
34 class BitReference {
35  public:
36   BitReference(Ref r, size_t bit) : ref_(r), bit_(bit) { }
37
38   /* implicit */ operator bool() const {
39     return ref_ & (one_ << bit_);
40   }
41
42   BitReference& operator=(bool b) {
43     if (b) {
44       set();
45     } else {
46       clear();
47     }
48     return *this;
49   }
50
51   void set() {
52     ref_ |= (one_ << bit_);
53   }
54
55   void clear() {
56     ref_ &= ~(one_ << bit_);
57   }
58
59   void flip() {
60     ref_ ^= (one_ << bit_);
61   }
62
63  private:
64   // shortcut to avoid writing static_cast everywhere
65   const static Value one_ = 1;
66
67   Ref ref_;
68   size_t bit_;
69 };
70
71 template <class BaseIter>
72 struct BitIteratorBase {
73   static_assert(std::is_integral<typename BaseIter::value_type>::value,
74                 "BitIterator may only be used with integral types");
75   typedef boost::iterator_adaptor<
76     BitIterator<BaseIter>,      // Derived
77     BaseIter,                   // Base
78     bool,                       // Value
79     boost::use_default,         // CategoryOrTraversal
80     bititerator_detail::BitReference<
81       typename std::iterator_traits<BaseIter>::reference,
82       typename std::iterator_traits<BaseIter>::value_type
83     >,  // Reference
84     ssize_t> type;
85 };
86
87
88 }  // namespace bititerator_detail
89 }  // namespace folly