// itlib-utility v1.01 // // Utility functions to extend // // SPDX-License-Identifier: MIT // MIT License: // Copyright(c) 2022-2023 Borislav Stanimirov // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files(the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and / or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions : // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // // VERSION HISTORY // // 1.01 (2023-02-08) Added make_nullptr // 1.00 (2022-11-28) Initial release // // // DOCUMENTATION // // Simply include this file wherever you need. // It defines several utility functions with generally unrelated features // // * force_move: // A function which guarantees that a move (and not a copy) happens. // If the op would result in copy construction or assignment, the call // produces a compilation error. // * owner_from_member: // A "hacky" ofsetof-like func which allows you to get a pointer to the // owner from a pointer to a member. // * make_nullptr: // A function to make a null pointer from a (potentially incomplete) type // Equivalent to static_cast(nullptr), but with a clearer intent #pragma once #include #include namespace itlib { template constexpr typename std::remove_reference::type&& force_move(T&& t) noexcept { using NoRefT = typename std::remove_reference::type; static_assert(!std::is_const::value, "cannot force_move a const object"); return static_cast(t); } template const Owner* owner_from_member(const Member& member, Member(Owner::* ptr)) noexcept { auto m_p = reinterpret_cast(&member); Owner* null_owner = nullptr; auto m_offset = reinterpret_cast(&(null_owner->*ptr)); return reinterpret_cast(m_p - m_offset); } template T* make_nullptr() { return static_cast(nullptr); } }