File indexing completed on 2024-04-14 14:12:12

0001 /*
0002     SPDX-FileCopyrightText: 2021 Valentin Boettcher <hiro at protagon.space; @hiro98:tchncs.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 /**
0008  * This header contains a cherry-picked version of the GSL `final_action`
0009  * as it is quite useful. You can see it in action over at
0010  * `kstars/datahandlers/catalogsdb.h`
0011  *
0012  * Further reading: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Re-finally
0013  * Source: https://github.com/Microsoft/GSL
0014  */
0015 
0016 #pragma once
0017 
0018 namespace gsl
0019 {
0020 // final_action allows you to ensure something gets run at the end of a scope
0021 template <class F>
0022 class final_action
0023 {
0024   public:
0025     static_assert(!std::is_reference<F>::value && !std::is_const<F>::value &&
0026                       !std::is_volatile<F>::value,
0027                   "Final_action should store its callable by value");
0028 
0029     explicit final_action(F f) noexcept : f_(std::move(f)) {}
0030 
0031     final_action(final_action &&other) noexcept
0032         : f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false))
0033     {
0034     }
0035 
0036     final_action(const final_action &) = delete;
0037     final_action &operator=(const final_action &) = delete;
0038     final_action &operator=(final_action &&) = delete;
0039 
0040     ~final_action() noexcept
0041     {
0042         if (invoke_)
0043             f_();
0044     }
0045 
0046   private:
0047     F f_;
0048     bool invoke_{ true };
0049 };
0050 
0051 template <class F>
0052 final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>
0053 finally(F &&f) noexcept
0054 {
0055     return final_action<
0056         typename std::remove_cv<typename std::remove_reference<F>::type>::type>(
0057         std::forward<F>(f));
0058 }
0059 } // namespace gsl