Home | History | Annotate | Download | only in netdutils
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      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 #ifndef NETUTILS_HANDLE_H
     18 #define NETUTILS_HANDLE_H
     19 
     20 #include <ostream>
     21 
     22 namespace android {
     23 namespace netdutils {
     24 
     25 // Opaque, strongly typed wrapper for integer-like handles.
     26 // Explicitly avoids implementing arithmetic operations.
     27 //
     28 // This class is intended to avoid common errors when reordering
     29 // arguments to functions, typos and other cases where plain integer
     30 // types would silently cover up the mistake.
     31 //
     32 // usage:
     33 // DEFINE_HANDLE(ProductId, uint64_t);
     34 // DEFINE_HANDLE(ThumbnailHash, uint64_t);
     35 // void foo(ProductId p, ThumbnailHash th) {...}
     36 //
     37 // void test() {
     38 //     ProductId p(88);
     39 //     ThumbnailHash th1(100), th2(200);
     40 //
     41 //     foo(p, th1);        <- ok!
     42 //     foo(th1, p);        <- disallowed!
     43 //     th1 += 10;          <- disallowed!
     44 //     p = th2;            <- disallowed!
     45 //     assert(th1 != th2); <- ok!
     46 // }
     47 template <typename T, typename TagT>
     48 class Handle {
     49   public:
     50     constexpr Handle() = default;
     51     constexpr Handle(const T& value) : mValue(value) {}
     52 
     53     const T get() const { return mValue; }
     54 
     55     bool operator==(const Handle& that) const { return get() == that.get(); }
     56     bool operator!=(const Handle& that) const { return get() != that.get(); }
     57 
     58   private:
     59     T mValue;
     60 };
     61 
     62 #define DEFINE_HANDLE(name, type) \
     63     struct _##name##Tag {};       \
     64     using name = ::android::netdutils::Handle<type, _##name##Tag>;
     65 
     66 template <typename T, typename TagT>
     67 inline std::ostream& operator<<(std::ostream& os, const Handle<T, TagT>& handle) {
     68     return os << handle.get();
     69 }
     70 
     71 }  // namespace netdutils
     72 }  // namespace android
     73 
     74 #endif /* NETUTILS_HANDLE_H */
     75