From 49df5844209b8682e755122be6fb07f00803b9b7 Mon Sep 17 00:00:00 2001 From: Gammasoft Date: Sun, 19 May 2024 22:45:57 +0200 Subject: [PATCH] Revue code --- src/xtd.core/include/xtd/call_once.h | 56 +++++++++++++++++++++++++-- src/xtd.core/include/xtd/scope_exit.h | 49 ++++++++++++++++++++--- 2 files changed, 96 insertions(+), 9 deletions(-) diff --git a/src/xtd.core/include/xtd/call_once.h b/src/xtd.core/include/xtd/call_once.h index 721bf10567d7..7848a4d35971 100644 --- a/src/xtd.core/include/xtd/call_once.h +++ b/src/xtd.core/include/xtd/call_once.h @@ -6,16 +6,62 @@ /// @brief The xtd namespace contains all fundamental classes to access Hardware, Os, System, and more. namespace xtd { - /// @cond - struct __xtd_call_once_helper__ { }; + /// @brief The xtd::call_once struct can be used to execute a routine exactly once. This can be used to initialise data in a thread-safe way. + /// @par Namespace + /// xtd + /// @par Library + /// xtd.core + /// @ingroup xtd_core + /// @remarks See also #call_once_ keyword helper. + /// + /// @code + /// #include + /// + /// using namespace xtd; + /// using namespace xtd::threading; + /// + /// auto main() -> int { + /// console::write_line("(main) begin"); + /// + /// auto mre = manual_reset_event {}; + /// + /// auto thread_proc = [&] { + /// static auto cpt = 0; + /// [[maybe_unused]] auto co = call_once {} + [&] { + /// console::write_line(" (thread_proc) call once {} times", cpt + 1); + /// }; + /// console::write_line(" (thread_proc) running {} times", ++cpt); + /// if (cpt == 3) mre.set(); + /// }; + /// + /// thread_pool::register_wait_for_single_object(mre, thread_proc, {}, 100, false); + /// + /// mre.wait_one(); + /// + /// thread::join_all(); + /// console::write_line("(main) end"); + /// } + /// + /// // This code produces the following output: + /// // + /// // (main) begin + /// // (thread_proc) call once 1 times + /// // (thread_proc) running 1 times + /// // (thread_proc) running 2 times + /// // (thread_proc) running 3 times + /// // (main) end + /// @endcode + struct call_once { + }; + /// @cond template struct __xtd_call_once_object__ { __xtd_call_once_object__(function_t function) { function(); } }; template - auto operator +(__xtd_call_once_helper__, function_t&& function) { + auto operator +(call_once, function_t&& function) { return __xtd_call_once_object__{std::forward(function)}; } /// @endcond @@ -32,6 +78,8 @@ namespace xtd { /// @par Library /// xtd.core /// @ingroup xtd_core keywords +/// @remarks See also xtd::call_once struct. +/// /// @code /// #include /// @@ -69,4 +117,4 @@ namespace xtd { /// // (thread_proc) running 3 times /// // (main) end /// @endcode -#define call_once_ [[maybe_unused]] static auto __xtd_call_once_id__(__xtd__call_once__, __LINE__) = xtd::__xtd_call_once_helper__{} + [&] +#define call_once_ [[maybe_unused]] static auto __xtd_call_once_id__(__xtd__call_once__, __LINE__) = xtd::call_once {} + [&] diff --git a/src/xtd.core/include/xtd/scope_exit.h b/src/xtd.core/include/xtd/scope_exit.h index c57ce8cd9e92..0034e548b4bf 100644 --- a/src/xtd.core/include/xtd/scope_exit.h +++ b/src/xtd.core/include/xtd/scope_exit.h @@ -6,9 +6,46 @@ /// @brief The xtd namespace contains all fundamental classes to access Hardware, Os, System, and more. namespace xtd { - /// @cond - struct __xtd_scope_exit_helper__ { }; + /// @brief Nowadays, every C++ developer is familiar with the Resource Acquisition Is Initialization ([RAII](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization)) technique. It binds resource acquisition and release to initialization and destruction of a variable that holds the resource. There are times when writing a special class for such a variable is not worth the effort. This is when xtd xtd::scope_exit comes into play. + /// @par Namespace + /// xtd + /// @par Library + /// xtd.core + /// @ingroup xtd_core + /// @remarks See also #scope_exit_ keyword helper. + /// @warning Prefer use [RAII](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization) then xtd::scope_exit. + /// + /// @code + /// #include + /// + /// using namespace xtd; + /// + /// auto main() -> int { + /// static auto se = scope_exit {} + [&] { + /// console::write_line("scope_exit"); + /// }; + /// console::write_line("begin"); + /// //... + /// console::write_line(); + /// console::write_line("do something..."); + /// console::write_line(); + /// //... + /// console::write_line("end"); + /// } + /// + /// // This code produces the following output: + /// // + /// // begin + /// // + /// // do something... + /// // + /// // end + /// // scope_exit + /// @endcode + struct scope_exit { + }; + /// @cond template struct __xtd_scope_exit_object__ { ~__xtd_scope_exit_object__() { function(); } @@ -16,7 +53,7 @@ namespace xtd { }; template - auto operator +(__xtd_scope_exit_helper__, function_t&& function) { + auto operator +(scope_exit, function_t&& function) { return __xtd_scope_exit_object__{std::forward(function)}; } /// @endcond @@ -28,12 +65,14 @@ namespace xtd { /// @endcond /// @brief Nowadays, every C++ developer is familiar with the Resource Acquisition Is Initialization ([RAII](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization)) technique. It binds resource acquisition and release to initialization and destruction of a variable that holds the resource. There are times when writing a special class for such a variable is not worth the effort. This is when xtd #scope_exit_ comes into play. -/// @warning Prefer use [RAII](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization) then #scope_exit_. /// @par Namespace /// xtd /// @par Library /// xtd.core /// @ingroup xtd_core keywords +/// @remarks See also xtd::scope_exit struct. +/// @warning Prefer use [RAII](https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization) then #scope_exit_. +/// /// @code /// #include /// @@ -61,4 +100,4 @@ namespace xtd { /// // end /// // scope_exit /// @endcode -#define scope_exit_ [[maybe_unused]] auto __xtd_scope_exit_id__(__xtd__scope_exit__, __LINE__) = xtd::__xtd_scope_exit_helper__{} + [&] +#define scope_exit_ [[maybe_unused]] auto __xtd_scope_exit_id__(__xtd__scope_exit__, __LINE__) = xtd::scope_exit {} + [&]