mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00
Memory management: cast functions for managed pointers
This commit is contained in:
@@ -22,7 +22,7 @@ IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^[<"]cmConfigure\.h'
|
||||
Priority: -1
|
||||
- Regex: '^(<|")cm/'
|
||||
- Regex: '^(<|")cm(ext)?/'
|
||||
Priority: 2
|
||||
- Regex: '^(<|")windows\.h'
|
||||
Priority: 3
|
||||
|
@@ -1,5 +1,5 @@
|
||||
set(CMake_CXX14_BROKEN 0)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI|Intel")
|
||||
if(NOT CMAKE_CXX14_STANDARD_COMPILE_OPTION)
|
||||
set(CMake_CXX14_WORKS 0)
|
||||
endif()
|
||||
|
@@ -1,5 +1,5 @@
|
||||
set(CMake_CXX17_BROKEN 0)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI|Intel")
|
||||
if(NOT CMAKE_CXX17_STANDARD_COMPILE_OPTION)
|
||||
set(CMake_CXX17_WORKS 0)
|
||||
endif()
|
||||
|
@@ -8,6 +8,13 @@
|
||||
# include <comdef.h>
|
||||
#endif
|
||||
|
||||
template <typename T,
|
||||
typename std::invoke_result<decltype(&T::get), T>::type = nullptr>
|
||||
typename T::pointer get_ptr(T& item)
|
||||
{
|
||||
return item.get();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a[] = { 0, 1, 2 };
|
||||
@@ -20,6 +27,9 @@ int main()
|
||||
|
||||
std::unique_ptr<int> u(new int(0));
|
||||
|
||||
// Intel compiler do not handle correctly 'decltype' inside 'invoke_result'
|
||||
get_ptr(u);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// clang-cl has problems instantiating this constructor in C++17 mode
|
||||
// error: indirection requires pointer operand ('const _GUID' invalid)
|
||||
|
@@ -25,6 +25,7 @@ set(CMakeLib_TESTS
|
||||
testUVProcessChain.cxx
|
||||
testUVRAII.cxx
|
||||
testUVStreambuf.cxx
|
||||
testCMExtMemory.cxx
|
||||
)
|
||||
|
||||
add_executable(testUVProcessChainHelper testUVProcessChainHelper.cxx)
|
||||
|
65
Tests/CMakeLib/testCMExtMemory.cxx
Normal file
65
Tests/CMakeLib/testCMExtMemory.cxx
Normal file
@@ -0,0 +1,65 @@
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include <cmext/memory>
|
||||
|
||||
namespace {
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
virtual ~Base() = default;
|
||||
};
|
||||
|
||||
class Derived : public Base
|
||||
{
|
||||
public:
|
||||
~Derived() = default;
|
||||
|
||||
void method() {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Wrapper
|
||||
{
|
||||
public:
|
||||
Wrapper(T* v)
|
||||
: value(v)
|
||||
{
|
||||
}
|
||||
~Wrapper() { delete value; }
|
||||
|
||||
T* get() const { return value; }
|
||||
|
||||
private:
|
||||
T* value;
|
||||
};
|
||||
|
||||
bool testReferenceCast()
|
||||
{
|
||||
std::cout << "testReferenceCast()" << std::endl;
|
||||
|
||||
std::unique_ptr<Base> u(new Derived);
|
||||
cm::static_reference_cast<Derived>(u).method();
|
||||
cm::dynamic_reference_cast<Derived>(u).method();
|
||||
|
||||
std::shared_ptr<Base> s(new Derived);
|
||||
cm::static_reference_cast<Derived>(s).method();
|
||||
cm::dynamic_reference_cast<Derived>(s).method();
|
||||
|
||||
// can also be used with custom wrappers
|
||||
Wrapper<Base> w(new Derived);
|
||||
cm::static_reference_cast<Derived>(w).method();
|
||||
cm::dynamic_reference_cast<Derived>(w).method();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int testCMExtMemory(int /*unused*/, char* /*unused*/ [])
|
||||
{
|
||||
if (!testReferenceCast()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
1
Utilities/std/.gitattributes
vendored
1
Utilities/std/.gitattributes
vendored
@@ -1 +1,2 @@
|
||||
cm/* our-c-style
|
||||
cmext/* our-c-style
|
||||
|
46
Utilities/std/cm/type_traits
Normal file
46
Utilities/std/cm/type_traits
Normal file
@@ -0,0 +1,46 @@
|
||||
// -*-c++-*-
|
||||
// vim: set ft=cpp:
|
||||
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#ifndef cm_type_traits
|
||||
#define cm_type_traits
|
||||
|
||||
#include <type_traits> // IWYU pragma: export
|
||||
|
||||
namespace cm {
|
||||
|
||||
#if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
|
||||
|
||||
// Miscellaneous transformations
|
||||
template <bool B, typename T = void>
|
||||
using enable_if_t = std::enable_if_t<B, T>;
|
||||
|
||||
#else
|
||||
|
||||
// Miscellaneous transformations
|
||||
template <bool B, typename T = void>
|
||||
using enable_if_t = typename std::enable_if<B, T>::type;
|
||||
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703)
|
||||
|
||||
// Miscellaneous transformations
|
||||
using std::invoke_result;
|
||||
using std::invoke_result_t;
|
||||
|
||||
#else
|
||||
|
||||
// Miscellaneous transformations
|
||||
template <typename F, typename... ArgTypes>
|
||||
using invoke_result = std::result_of<F(ArgTypes...)>;
|
||||
|
||||
template <class F, typename... ArgTypes>
|
||||
using invoke_result_t = typename invoke_result<F, ArgTypes...>::type;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace cm
|
||||
|
||||
#endif
|
32
Utilities/std/cmext/memory
Normal file
32
Utilities/std/cmext/memory
Normal file
@@ -0,0 +1,32 @@
|
||||
// -*-c++-*-
|
||||
// vim: set ft=cpp:
|
||||
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#ifndef cmext_memory
|
||||
#define cmext_memory
|
||||
|
||||
#include <cm/type_traits>
|
||||
|
||||
namespace cm {
|
||||
|
||||
template <typename T, typename O,
|
||||
cm::enable_if_t<
|
||||
std::is_pointer<cm::invoke_result_t<decltype(&O::get), O>>::value,
|
||||
int> = 0>
|
||||
T& static_reference_cast(O& item)
|
||||
{
|
||||
return *(static_cast<T*>(item.get()));
|
||||
}
|
||||
template <typename T, typename O,
|
||||
cm::enable_if_t<
|
||||
std::is_pointer<cm::invoke_result_t<decltype(&O::get), O>>::value,
|
||||
int> = 0>
|
||||
T& dynamic_reference_cast(O& item)
|
||||
{
|
||||
return *(dynamic_cast<T*>(item.get()));
|
||||
}
|
||||
|
||||
} // namespace cm
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user