• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 #pragma once
18 
19 #include <functional>
20 
21 namespace cuttlefish {
22 namespace selector {
23 
24 class LocalInstanceGroup;
25 class LocalInstance;
26 
27 template <typename T>
28 class ConstRef {
29   static_assert(std::is_same<T, LocalInstanceGroup>::value ||
30                 std::is_same<T, LocalInstance>::value);
31 
32  public:
33   ConstRef(ConstRef& ref) = default;
34   ConstRef(const ConstRef& ref) = default;
35   ConstRef(ConstRef&& ref) = default;
36 
ConstRef(const T & t)37   ConstRef(const T& t) : inner_wrapper_(t) {}
38   ConstRef(T&&) = delete;
39 
40   ConstRef& operator=(const ConstRef& other) {
41     inner_wrapper_ = other.inner_wrapper_;
42     return *this;
43   }
44 
45   operator const T&() const noexcept { return inner_wrapper_.get(); }
46 
Get()47   const T& Get() const noexcept { return inner_wrapper_.get(); }
48 
49   /**
50    * comparison based on the address of underlying object
51    *
52    * Note that, per instance (group), there is only one LocalInstance(Group)
53    * object is created during the program's life time. Besides, they don't
54    * offer operator==, either. ConstRef<LocalInstance(Group)> has to be in
55    * a set.
56    */
57   bool operator==(const ConstRef& rhs) const noexcept {
58     return std::addressof(Get()) == std::addressof(rhs.Get());
59   }
60 
61  private:
62   std::reference_wrapper<const T> inner_wrapper_;
63 };
64 
65 template <class T>
Cref(const T & t)66 ConstRef<T> Cref(const T& t) noexcept {
67   return ConstRef<T>(t);
68 }
69 
70 }  // namespace selector
71 }  // namespace cuttlefish
72 
73 /**
74  * the assumption is, if std::addressof(lhs) != std::addressof(rhs),
75  * the two LocalInstance objects are actually different. There is only
76  * on LocalInstance(Group) object per a given cuttlefish instance (group).
77  */
78 template <typename T>
79 struct std::hash<cuttlefish::selector::ConstRef<T>> {
80   std::size_t operator()(
81       const cuttlefish::selector::ConstRef<T>& ref) const noexcept {
82     const auto ptr = std::addressof(ref.Get());
83     return std::hash<const T*>()(ptr);
84   }
85 };
86