fork(3) download
  1. #include <cstdint>
  2. #include <iostream> // for test
  3. #include <type_traits>
  4. #include <utility>
  5.  
  6. template<class T>
  7. class pointer
  8. {
  9. using this_type = pointer<T>;
  10. T* _ptr;
  11.  
  12. public:
  13. using value_type = T;
  14. using reference = value_type&;
  15. using const_reference = const value_type&;
  16. using difference_type = std::ptrdiff_t;
  17.  
  18. pointer() noexcept : _ptr() {}
  19. pointer(T* p) noexcept : _ptr(p) {}
  20.  
  21. T* get() const noexcept { return _ptr; }
  22.  
  23. T* operator->() const noexcept { return _ptr; }
  24. reference operator*() const noexcept { return (*_ptr); }
  25.  
  26. // この場合の添え字演算子は関節参照演算子のシンタックスシュガー
  27. reference operator[](std::ptrdiff_t diff) { return *(_ptr + diff); }
  28. const_reference operator[](std::ptrdiff_t diff) const { return *(_ptr + diff); }
  29.  
  30. reference operator++() { ++_ptr; return (*this); }
  31. reference operator--() { --_ptr; return (*this); }
  32. value_type operator++(int) { this_type temp(*this); ++*this; return temp; }
  33. value_type operator--(int) { this_type temp(*this); --*this; return temp; }
  34.  
  35. explicit operator bool() const noexcept { return _ptr; }
  36. bool operator!() const noexcept { return !static_cast<bool>(*this); }
  37.  
  38. template<class U,
  39. std::enable_if_t<std::is_member_function_pointer<U>::value, std::nullptr_t> = nullptr>
  40. auto operator->*(U u) const noexcept
  41. {
  42. return [u, this](auto... args)
  43. { // lambda
  44. return (_ptr->*u)(std::forward<decltype(args)>(args)...);
  45. };
  46. }
  47.  
  48. template<class U,
  49. std::enable_if_t<std::is_member_object_pointer<U>::value, std::nullptr_t> = nullptr>
  50. auto& operator->*(U u) const noexcept
  51. {
  52. return _ptr->*u;
  53. }
  54.  
  55. reference operator+=(difference_type diff)
  56. { _ptr += diff; return (*this); }
  57. reference operator-=(difference_type diff)
  58. { _ptr -= diff; return (*this); }
  59.  
  60. };
  61.  
  62. template<class T, class U>
  63. static inline bool operator==(const pointer<T>& p1, const pointer<U>& p2) noexcept
  64. {
  65. return p1.get() == p2.get();
  66. }
  67.  
  68. // この減算は例の厄介なやつ。
  69. template<class T, class U>
  70. static inline auto operator-(const pointer<T>& p1, const pointer<U>& p2)
  71. ->typename pointer<T>::difference_type
  72. {
  73. return typename pointer<T>::difference_type(p1.get() - p2.get());
  74. }
  75.  
  76.  
  77.  
  78. struct something
  79. {
  80. void great_function() const { std::cout <<"I am great." << std::endl; }
  81. int great_n = 0;
  82. };
  83.  
  84. int main()
  85. {
  86. something s;
  87. pointer<something> ps(&s);
  88. ps->great_function();
  89.  
  90. auto pgreat_func = &something::great_function;
  91. (ps->*pgreat_func)();
  92.  
  93. auto pgreat_n = &something::great_n;
  94. ps->*pgreat_n = 10;
  95. int n = ps->*pgreat_n;
  96. std::cout << n << std::endl;
  97. }
Success #stdin #stdout 0s 3468KB
stdin
Standard input is empty
stdout
I am great.
I am great.
10