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