fork download
  1. #include <utility>
  2. #include <type_traits>
  3. #include <cstddef>
  4.  
  5. template< typename FuncSig, FuncSig func >
  6. struct Functor {
  7. template<typename... Args>
  8. auto operator()(Args&&... args) const
  9. -> decltype( func(std::forward<Args>(args)...) )
  10. { return ( func(std::forward<Args>(args)...) ); }
  11. };
  12.  
  13. struct Zeroer {
  14. template<typename T>
  15. void operator()( T& t ) const {
  16. t = 0;
  17. }
  18. };
  19. template< typename T, typename Creator, typename Destroyer, typename Nuller=Zeroer >
  20. struct RAII_handle {
  21. RAII_handle( std::nullptr_t ):
  22. data()
  23. {
  24. Nuller()(data);
  25. }
  26. RAII_handle( RAII_handle const& ) = delete;
  27. RAII_handle( RAII_handle && o ):data(std::move(o.data)) {
  28. Nuller()(o.data);
  29. }
  30. RAII_handle& operator=( RAII_handle const& ) = delete;
  31. RAII_handle& operator=( RAII_handle && o ) {
  32. data = std::move(o.data);
  33. Nuller()(o.data);
  34. return *this;
  35. }
  36. template<typename... Args>
  37. RAII_handle( Args&&... args ):
  38. data( Creator()(std::forward<Args>(args)...) )
  39. {}
  40. auto close()->decltype( Destroyer()(std::declval<T&>()) ) {
  41. auto retval = Destroyer()(data);
  42. Nuller()(data);
  43. return retval;
  44. }
  45. ~RAII_handle() {
  46. close();
  47. }
  48. T& get() { return data; }
  49. T const& get() const { return data; }
  50.  
  51. T& operator*() { return get(); }
  52. T const& operator*() const { return get(); }
  53.  
  54. T* operator->() { return &get(); }
  55. T const* operator->() const { return &get(); }
  56. private:
  57. T data;
  58. };
  59.  
  60. #include <iostream>
  61. typedef unsigned char HANDLE;
  62. HANDLE CreateFile( char const* name ) {
  63. std::cout << name << "\n";
  64. return 7;
  65. }
  66. bool CloseFile( HANDLE h ) {
  67. if (h) {
  68. --h;
  69. std::cout << (int)h << "\n";
  70. return true;
  71. } else {
  72. std::cout << "already closed\n";
  73. return false;
  74. }
  75. }
  76.  
  77. typedef RAII_handle< HANDLE, Functor< HANDLE(*)( char const* ), CreateFile >, Functor< bool(*)(HANDLE), CloseFile > > FileHandle;
  78.  
  79. int main() {
  80. FileHandle bob("hello.txt");
  81. unsigned char value = *bob;
  82. bob.close();
  83. }
Success #stdin #stdout 0s 2896KB
stdin
Standard input is empty
stdout
hello.txt
6
already closed