summaryrefslogtreecommitdiff
path: root/src/components/include/utils/scope_guard.h
diff options
context:
space:
mode:
authorAlexander Kutsan <AKutsan@luxoft.com>2016-08-26 18:48:22 +0300
committerAlexander Kutsan <AKutsan@luxoft.com>2016-08-26 18:48:57 +0300
commitd73e6dc8724c5799fae14efd4dcb214af74e4904 (patch)
tree9ebed8b422490c4d669e90e70783e4f5b55b65c9 /src/components/include/utils/scope_guard.h
parentc201c11a35d360c0b96f36b103a2590bfaeb6026 (diff)
parent61ef8c42badb879216f53d240e1101b9f83a9bb7 (diff)
downloadsdl_core-d73e6dc8724c5799fae14efd4dcb214af74e4904.tar.gz
Merge branch 'release/4.1.0'
Diffstat (limited to 'src/components/include/utils/scope_guard.h')
-rw-r--r--src/components/include/utils/scope_guard.h326
1 files changed, 326 insertions, 0 deletions
diff --git a/src/components/include/utils/scope_guard.h b/src/components/include/utils/scope_guard.h
new file mode 100644
index 0000000000..bc60a7d288
--- /dev/null
+++ b/src/components/include/utils/scope_guard.h
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_INCLUDE_UTILS_SCOPE_GUARD_H
+#define SRC_COMPONENTS_INCLUDE_UTILS_SCOPE_GUARD_H
+
+namespace utils {
+
+/**
+ * @brief The ScopeGuardImplBase class the class which allows to keep safety
+ * raw pointer within local scope. The same ScopeGuard has been provided by
+ * Andrej Alexandresku in the Loki library.
+ *
+ * The usage area example:
+ *
+ * Suppose user have to create some pointer in function call Init(). And in case
+ * of some fail condition this pointer has to be freed. So in order to avoid
+ * code duplicate as follows:
+ *
+ * bool SomeClass::Init() {
+ * memberObject_ = custom_allocate() // initialize member object with some
+ *value
+ * if(!some_condition) {
+ * custom_release(memberObject();
+ * return false;
+ * }
+ *
+ * if(!other_condition) {
+ * custom_release(memberObject)
+ * return false;
+ * }
+ * return true;
+ * }
+ *
+ * The user is able to use ScopeGuard, where possible to automatically call
+ * custom release function. See example bellow:
+ *
+ * bool SomeClass::Init() {
+ * memberObject_ = custom_allocate() // initialize member object with some
+ *value
+ * // The guard will call custom release function when it goes out of scope.
+ * ScopeGaurd guard = MakeGuard(custom_release, memberObject);
+ * if(!some_condition) {
+ * return false;
+ * }
+ *
+ * if(!other_condition) {
+ * return false;
+ * }
+ * // Here to avoid object releasing the user has to call Dismiss method.
+ * // So no custom release function will be called after return statement.
+ * guard.Dismiss();
+ * return true;
+ * }
+ */
+class ScopeGuardImplBase {
+ public:
+ /**
+ * @brief ScopeGuardImplBase the ScopeGuards constructor.
+ */
+ ScopeGuardImplBase() : dismissed_(false) {}
+
+ /**
+ * @brief Dismiss function which allows to dismiss releasing of stored object.
+ */
+ void Dismiss() const {
+ dismissed_ = true;
+ }
+
+ protected:
+ /**
+ * @brief ScopeGuardImplBase the copy constructor
+ *
+ * @param other the object that should be copied.
+ */
+ ScopeGuardImplBase(const ScopeGuardImplBase& other)
+ : dismissed_(other.dismissed_) {
+ other.Dismiss();
+ }
+
+ /**
+ * Allows to safely execute release function(i.e. it will be called only
+ * in case of releasing wasn't dismiss.)
+ */
+ template <typename T>
+ void SafeExecute(T& t) {
+ if (!t.dismissed_) {
+ t.Execute();
+ }
+ }
+
+ ~ScopeGuardImplBase() {}
+
+ mutable bool dismissed_;
+
+ private:
+ // Disallow copying via assign operator.
+ ScopeGuardImplBase& operator=(const ScopeGuardImplBase&);
+};
+
+/**
+ * The class which allows to bind some parameter with free function.
+ * I.E.
+ * void release(char* p){delete p;}
+ *
+ * ScopeGuard guard = MakeGuard(release, p);
+ *
+ * So the parameter p will be passed to the specified function.
+ */
+template <typename Function, typename Parameter1>
+class ScopeGuardImpl1 : public ScopeGuardImplBase {
+ public:
+ /**
+ * @brief MakeGuard allows to create ScopeGuard object.
+ *
+ * @param fun function to call, when out of scope.
+ *
+ * @param p1 parameter which will be passed to the certain function.
+ *
+ * @return ScopeGuard object.
+ */
+ static ScopeGuardImpl1<Function, Parameter1> MakeGuard(Function fun,
+ const Parameter1& p1) {
+ return ScopeGuardImpl1<Function, Parameter1>(fun, p1);
+ }
+
+ /**
+ Execute the SafeExecute function in destructor.
+ */
+ ~ScopeGuardImpl1() {
+ SafeExecute(*this);
+ }
+
+ protected:
+ /**
+ * @brief Execute allows to execute certain function with certain parameter.
+ */
+ void Execute() {
+ fun_(p1_);
+ }
+
+ /**
+ * @brief ScopeGuardImpl1 create ScopeGuard object.
+ *
+ * @param f function object.
+ *
+ * @param p1 parameter to to pass to the function object.
+ */
+ ScopeGuardImpl1(const Function& f, const Parameter1& p1) : fun_(f), p1_(p1) {}
+
+ private:
+ Function fun_;
+ const Parameter1 p1_;
+
+ friend class ScopeGuardImplBase;
+};
+
+/**
+ * The class which allows to call some member function in case of
+ * ScopeGuard object out of scope.
+ * I.E.
+ * vector<int> vec;
+ *
+ * // When function returns, the pop_back method for vector will be called.
+ * void foo() {
+ * ScopeGuard guard = MakeObjGuard(vec, &vector::pop_back);
+ * vec.push_back(5);
+ * }
+ */
+template <typename Obj, typename MemFun>
+class ObjScopeGuardImpl0 : public ScopeGuardImplBase {
+ public:
+ /**
+ * @brief MakeObjGuard creates ScopeGuard object.
+ *
+ * @param obj object whose method will be called.
+ *
+ * @param memFun the method to call.
+ *
+ * @return ScopeGuard object.
+ */
+ static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun) {
+ return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
+ }
+
+ /**
+ Execute the SafeExecute function in destructor.
+ */
+ ~ObjScopeGuardImpl0() {
+ SafeExecute(*this);
+ }
+
+ protected:
+ /**
+ * @brief Execute allows to execute certain function with certain parameter.
+ */
+ void Execute() {
+ (obj_.*memFun_)();
+ }
+
+ /**
+ * @brief ObjScopeGuardImpl0 Create ScopeGuard object.
+ *
+ * @param obj object whose method will be called.
+ *
+ * @param memFun the method to call.
+ *
+ * @return ScopeGuard object.
+ */
+ ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun) {}
+
+ private:
+ Obj& obj_;
+ MemFun memFun_;
+ friend class ScopeGuardImplBase;
+};
+
+/**
+ * The class which allows to call some member function with certain parameter
+ * in case of ScopeGuard object out of scope.
+
+ */
+template <typename Obj, typename MemFun, typename Parameter1>
+class ObjScopeGuardImpl1 : public ScopeGuardImplBase {
+ public:
+ /**
+ * @brief MakeObjGuard creates ScopeGuard object.
+ *
+ * @param obj object whose method will be called.
+ *
+ * @param memFun the method to call.
+ *
+ * @param p1 the parameter to pass to the member function.
+ *
+ * @return ScopeGuard object.
+ */
+ static ObjScopeGuardImpl1<Obj, MemFun, Parameter1> MakeObjGuard(
+ Obj& obj, MemFun memFun, const Parameter1& p1) {
+ return ObjScopeGuardImpl1<Obj, MemFun, Parameter1>(obj, memFun, p1);
+ }
+
+ /**
+ Execute the SafeExecute function in destructor.
+ */
+ ~ObjScopeGuardImpl1() {
+ SafeExecute(*this);
+ }
+
+ protected:
+ /**
+ * @brief Execute allows to execute certain function with certain parameter.
+ */
+ void Execute() {
+ (obj_.*memFun_)(p1_);
+ }
+
+ /**
+ * @brief MakeObjGuard creates ScopeGuard object.
+ *
+ * @param obj object whose method will be called.
+ *
+ * @param memFun the method to call.
+ *
+ * @param p1 the parameter to pass to the member function.
+ *
+ * @return ScopeGuard object.
+ */
+ ObjScopeGuardImpl1(Obj& obj, MemFun memFun, const Parameter1& p1)
+ : obj_(obj), memFun_(memFun), p1_(p1) {}
+
+ private:
+ Obj& obj_;
+ MemFun memFun_;
+ const Parameter1 p1_;
+ friend class ScopeGuardImplBase;
+};
+
+typedef const ScopeGuardImplBase& ScopeGuard;
+
+template <typename F, typename P1>
+ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1) {
+ return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
+}
+
+template <typename Obj, typename MemFun>
+ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun) {
+ return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(obj, memFun);
+}
+
+template <typename Obj, typename MemFun, typename P1>
+ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj,
+ MemFun memFun,
+ const P1& p1) {
+ return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(obj, memFun, p1);
+}
+}
+#endif // SRC_COMPONENTS_INCLUDE_UTILS_SCOPE_GUARD_H