• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2019 Huawei Technologies Co., Ltd
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 MINDSPORE_CCSRC_UTILS_CONTRACT_H
18 #define MINDSPORE_CCSRC_UTILS_CONTRACT_H
19 #include <string>
20 #include <exception>
21 #include <memory>
22 #include <utility>
23 #include <type_traits>
24 #include "utils/log_adapter.h"
25 
26 namespace mindspore {
27 class ContractError : public std::logic_error {
28  public:
ContractError(const std::string & msg)29   explicit ContractError(const std::string &msg) : std::logic_error(msg) {}
ContractError(const char * msg)30   explicit ContractError(const char *msg) : std::logic_error(msg) {}
31   ~ContractError() override = default;
32 };
33 
34 struct Signatory {
35   LocationInfo location_info;
36   const char *extra_info;
37 };
38 
39 struct NotNullRule {
40   template <class T>
CheckNotNullRule41   constexpr static bool Check(const T &val) {
42     return val != nullptr;
43   }
DescNotNullRule44   constexpr static const char *Desc() { return " must not be null"; }
45 };
46 template <class T, class R, class E = void>
47 class EnsuresAccess {};
48 
49 template <class T>
50 using RemoveCVR = std::remove_cv_t<std::remove_reference_t<T>>;
51 
52 template <class T, class R>
53 class Ensures : public EnsuresAccess<T, R> {
54  public:
Ensures(T v,const Signatory & signatory)55   Ensures(T v, const Signatory &signatory) : value_(v) {
56     if (!R::Check(value_)) {
57       LogStream contract_stream;
58       contract_stream << "contract error: " << signatory.extra_info << R::Desc();
59       LogWriter(signatory.location_info, EXCEPTION, SUBMODULE_ID, ArgumentError) ^ contract_stream;
60     }
61   }
62   template <class O, typename = std::enable_if_t<std::is_convertible_v<O, T>>>
Ensures(const Ensures<O,R> & other)63   Ensures(const Ensures<O, R> &other) : value_(other.get()) {}
64   ~Ensures() = default;
65 
get()66   const T get() const { return value_; }
get()67   T &get() { return value_; }
68 
T()69   operator const T() const { return value_; }
70 
71   T value_;
72 };
73 
74 template <class T, class R>
75 class EnsuresAccess<T, R, std::enable_if_t<std::is_pointer_v<std::remove_cv_t<T>>>> {
76  public:
77   T operator->() const {
78     auto ptr = static_cast<const Ensures<T, R> *>(this)->get();
79     return ptr;
80   }
81 };
82 
83 template <typename T>
84 struct IsSharedPtr : std::false_type {};
85 template <typename T>
86 struct IsSharedPtr<std::shared_ptr<T>> : std::true_type {};
87 template <typename T>
88 struct IsSharedPtr<const std::shared_ptr<T> &> : std::true_type {};
89 
90 template <class T, class R>
91 class EnsuresAccess<T, R, std::enable_if_t<IsSharedPtr<T>::value>> {
92   using element_type = typename std::remove_cv_t<std::remove_reference_t<T>>::element_type;
93 
94  public:
95   element_type *operator->() const {
96     auto ptr = static_cast<const Ensures<T, R> *>(this)->get();
97     return ptr.get();
98   }
99 };
100 
101 template <class T, class R>
102 using Expects = Ensures<T, R>;
103 template <class T>
104 using NotNull = Ensures<T, NotNullRule>;
105 #define ENSURE(_v, _rule) Ensures<decltype(_v), _rule>(_v, {{__FILE__, __LINE__, __FUNCTION__}, #_v})
106 #define NOT_NULL(_v) ENSURE(_v, NotNullRule)
107 }  // namespace mindspore
108 #endif  // MINDSPORE_CCSRC_UTILS_CONTRACT_H
109