1 | /* |
2 | * Licensed to the Apache Software Foundation (ASF) under one |
3 | * or more contributor license agreements. See the NOTICE file |
4 | * distributed with this work for additional information |
5 | * regarding copyright ownership. The ASF licenses this file |
6 | * to you under the Apache License, Version 2.0 (the |
7 | * "License"); you may not use this file except in compliance |
8 | * with the License. You may obtain a copy of the License at |
9 | * |
10 | * http://www.apache.org/licenses/LICENSE-2.0 |
11 | * |
12 | * Unless required by applicable law or agreed to in writing, |
13 | * software distributed under the License is distributed on an |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
15 | * KIND, either express or implied. See the License for the |
16 | * specific language governing permissions and limitations |
17 | * under the License. |
18 | */ |
19 | |
20 | /*! |
21 | * \file tvm/support/with.h |
22 | * \brief RAII wrapper function to enter and exit a context object |
23 | * similar to python's with syntax. |
24 | */ |
25 | #ifndef TVM_SUPPORT_WITH_H_ |
26 | #define TVM_SUPPORT_WITH_H_ |
27 | |
28 | #include <dmlc/common.h> |
29 | |
30 | #include <functional> |
31 | #include <utility> |
32 | |
33 | namespace tvm { |
34 | |
35 | /*! |
36 | * \brief RAII wrapper function to enter and exit a context object |
37 | * similar to python's with syntax. |
38 | * |
39 | * \code |
40 | * // context class |
41 | * class MyContext { |
42 | * private: |
43 | * friend class With<MyContext>; |
44 | MyContext(arguments); |
45 | * void EnterWithScope(); |
46 | * void ExitWithScope(); |
47 | * }; |
48 | * |
49 | * { |
50 | * With<MyContext> scope(arguments); |
51 | * // effect take place. |
52 | * } |
53 | * \endcode |
54 | * |
55 | * \tparam ContextType Type of the context object. |
56 | */ |
57 | template <typename ContextType> |
58 | class With { |
59 | public: |
60 | /*! |
61 | * \brief constructor. |
62 | * Enter the scope of the context. |
63 | */ |
64 | template <typename... Args> |
65 | explicit With(Args&&... args) : ctx_(std::forward<Args>(args)...) { |
66 | ctx_.EnterWithScope(); |
67 | } |
68 | /*! \brief destructor, leaves the scope of the context. */ |
69 | ~With() DMLC_THROW_EXCEPTION { ctx_.ExitWithScope(); } |
70 | |
71 | // Disable copy and move construction. `With` is intended only for |
72 | // use in nested contexts that are exited in the reverse order of |
73 | // entry. Allowing context to be copied or moved would break this |
74 | // expectation. |
75 | With(const With& other) = delete; |
76 | With& operator=(const With& other) = delete; |
77 | With(With&& other) = delete; |
78 | With& operator=(With&& other) = delete; |
79 | |
80 | ContextType* get() { return &ctx_; } |
81 | const ContextType* get() const { return &ctx_; } |
82 | |
83 | ContextType* operator->() { return get(); } |
84 | const ContextType* operator->() const { return get(); } |
85 | ContextType& operator*() { return *get(); } |
86 | const ContextType* operator*() const { return *get(); } |
87 | |
88 | ContextType operator()() { return ctx_; } |
89 | |
90 | private: |
91 | /*! \brief internal context type. */ |
92 | ContextType ctx_; |
93 | }; |
94 | |
95 | } // namespace tvm |
96 | #endif // TVM_SUPPORT_WITH_H_ |
97 | |