const_propogating_ptr.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. //
  2. // const_propogating_ptr.hpp
  3. // pointers
  4. //
  5. // Created by Sam Jaffe on 12/3/16.
  6. //
  7. #pragma once
  8. #include <memory>
  9. #include "pointer_fwd.hpp"
  10. template <typename T>
  11. class const_propogating_ptr {
  12. public:
  13. using element_type = typename std::pointer_traits<T>::element_type;
  14. using pointer = element_type *;
  15. using reference = element_type &;
  16. using const_pointer = element_type const *;
  17. using const_reference = element_type const &;
  18. const_propogating_ptr() : _ptr(nullptr) {}
  19. const_propogating_ptr(T const & p) : _ptr(p) {}
  20. const_propogating_ptr(T && p) : _ptr(std::move(p)) {}
  21. const_propogating_ptr(const_propogating_ptr & other) : _ptr(other._ptr) {}
  22. const_propogating_ptr(const_propogating_ptr &&) = default;
  23. const_propogating_ptr(const_propogating_ptr const &) = delete;
  24. const_propogating_ptr& operator=(const_propogating_ptr & other) { _ptr = other._ptr; return *this; }
  25. const_propogating_ptr& operator=(const_propogating_ptr &&) = default;
  26. const_propogating_ptr& operator=(const_propogating_ptr const &) = delete;
  27. template <typename Y>
  28. explicit operator const_propogating_ptr<Y>() & {
  29. return _ptr;
  30. }
  31. template <typename Y>
  32. explicit operator const_ptr<Y>() const {
  33. return _ptr;
  34. }
  35. template <typename Y>
  36. explicit operator const_propogating_ptr<Y>() const & = delete;
  37. operator bool() const {
  38. return bool(_ptr);
  39. }
  40. reference operator*() { return *_ptr; }
  41. pointer get() { return std::addressof(operator*()); }
  42. pointer operator->() { return get(); }
  43. const_reference operator*() const { return *_ptr; }
  44. const_pointer get() const { return std::addressof(operator*()); }
  45. const_pointer operator->() const { return get(); }
  46. private:
  47. T _ptr;
  48. };
  49. template <typename T, typename U>
  50. bool operator==(const_propogating_ptr<T> const&lhs, const_propogating_ptr<U> const&rhs) {
  51. return lhs.get() == rhs.get();
  52. }
  53. template <typename T, typename U>
  54. bool operator!=(const_propogating_ptr<T> const&lhs, const_propogating_ptr<U> const&rhs) {
  55. return !(lhs == rhs);
  56. }
  57. template <typename T, typename U>
  58. bool operator< (const_propogating_ptr<T> const&lhs, const_propogating_ptr<U> const&rhs) {
  59. typedef typename std::common_type<
  60. typename const_propogating_ptr<T>::pointer,
  61. typename const_propogating_ptr<U>::pointer>::type V;
  62. return std::less<V>(lhs.get(), rhs.get());
  63. }
  64. template <typename T, typename U>
  65. bool operator> (const_propogating_ptr<T> const&lhs, const_propogating_ptr<U> const&rhs) {
  66. return rhs < lhs;
  67. }
  68. template <typename T, typename U>
  69. bool operator<=(const_propogating_ptr<T> const&lhs, const_propogating_ptr<U> const&rhs) {
  70. return !(rhs < lhs);
  71. }
  72. template <typename T, typename U>
  73. bool operator>=(const_propogating_ptr<T> const&lhs, const_propogating_ptr<U> const&rhs) {
  74. return !(lhs < rhs);
  75. }
  76. template <typename T>
  77. bool operator==(const_propogating_ptr<T> const&lhs, std::nullptr_t) {
  78. return !lhs;
  79. }
  80. template <typename T>
  81. bool operator==(std::nullptr_t, const_propogating_ptr<T> const&rhs) {
  82. return !rhs;
  83. }
  84. template <typename T>
  85. bool operator!=(const_propogating_ptr<T> const&lhs, std::nullptr_t) {
  86. return static_cast<bool>(lhs);
  87. }
  88. template <typename T>
  89. bool operator!=(std::nullptr_t, const_propogating_ptr<T> const&rhs) {
  90. return static_cast<bool>(rhs);
  91. }
  92. template <typename T>
  93. bool operator< (const_propogating_ptr<T> const&lhs, std::nullptr_t) {
  94. typedef typename const_propogating_ptr<T>::pointer V;
  95. return std::less<V>(lhs.get(), nullptr);
  96. }
  97. template <typename T>
  98. bool operator< (std::nullptr_t, const_propogating_ptr<T> const&rhs) {
  99. typedef typename const_propogating_ptr<T>::pointer V;
  100. return std::less<V>(nullptr, rhs.get());
  101. }
  102. template <typename T>
  103. bool operator> (const_propogating_ptr<T> const&lhs, std::nullptr_t) {
  104. return nullptr < lhs;
  105. }
  106. template <typename T>
  107. bool operator> (std::nullptr_t, const_propogating_ptr<T> const&rhs) {
  108. return rhs < nullptr;
  109. }
  110. template <typename T>
  111. bool operator<=(const_propogating_ptr<T> const&lhs, std::nullptr_t) {
  112. return !(nullptr < lhs);
  113. }
  114. template <typename T>
  115. bool operator<=(std::nullptr_t, const_propogating_ptr<T> const&rhs) {
  116. return !(rhs < nullptr);
  117. }
  118. template <typename T>
  119. bool operator>=(const_propogating_ptr<T> const&lhs, std::nullptr_t) {
  120. return !(lhs < nullptr);
  121. }
  122. template <typename T>
  123. bool operator>=(std::nullptr_t, const_propogating_ptr<T> const&rhs) {
  124. return !(nullptr < rhs);
  125. }