File indexing completed on 2024-03-24 03:48:08
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