1 //
2 // Copyright (c) 2021 Travis Geiselbrecht
3 //
4 // Use of this source code is governed by a MIT-style
5 // license that can be found in the LICENSE file or at
6 // https://opensource.org/licenses/MIT
7 //
8 // Copyright 2016 The Fuchsia Authors. All rights reserved.
9 // Use of this source code is governed by a BSD-style license that can be
10 // found in the LICENSE file.
11 #pragma once
12 
13 #include <type_traits>
14 
15 // Helper routines used in C++ code in LK
16 
17 // Macro used to simplify the task of deleting all of the default copy
18 // constructors and assignment operators.
19 #define DISALLOW_COPY_ASSIGN_AND_MOVE(_class_name)       \
20     _class_name(const _class_name&) = delete;            \
21     _class_name(_class_name&&) = delete;                 \
22     _class_name& operator=(const _class_name&) = delete; \
23     _class_name& operator=(_class_name&&) = delete
24 
25 // Macro used to simplify the task of deleting the non rvalue reference copy
26 // constructors and assignment operators.  (IOW - forcing move semantics)
27 #define DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(_class_name) \
28     _class_name(const _class_name&) = delete;            \
29     _class_name& operator=(const _class_name&) = delete
30 
31 // Macro used to simplify the task of deleting the new and new[]
32 // operators. (IOW - disallow heap allocations)
33 #define DISALLOW_NEW                       \
34     static void* operator new(size_t) = delete;   \
35     static void* operator new[](size_t) = delete
36 
37 // TODO: find a better place for this
38 namespace lk {
39 
40 template <typename T>
41 class auto_call {
42 public:
auto_call(T c)43     constexpr explicit auto_call(T c) : call_(std::move(c)) {}
~auto_call()44     ~auto_call() { call(); }
45 
auto_call(auto_call && c)46     auto_call(auto_call && c) : call_(std::move(c.call_)), armed_(c.armed_) {
47         c.cancel();
48     }
49     auto_call& operator=(auto_call&& c) {
50         call();
51         call_ = std::move(c.call_);
52         armed_ = c.armed_;
53         c.cancel();
54         return *this;
55     }
56 
57     DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(auto_call);
58 
call()59     void call() {
60         bool armed = armed_;
61         cancel();
62         if (armed) {
63             call_();
64         }
65     }
cancel()66     void cancel() {
67         armed_ = false;
68     }
69 
70 private:
71     T call_;
72     bool armed_ = true;
73 };
74 
75 template <typename T>
make_auto_call(T c)76 inline auto_call<T> make_auto_call(T c) {
77     return auto_call<T>(std::move(c));
78 }
79 
80 } // namespace lk
81 
82 
83