store_policy.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #pragma once
  2. #include <utility>
  3. #include "ptr.h"
  4. template <class TBase, class TCounter>
  5. struct TWithRefCount: public TBase, public TRefCounted<TWithRefCount<TBase, TCounter>, TCounter> {
  6. template <typename... Args>
  7. inline TWithRefCount(Args&&... args)
  8. : TBase(std::forward<Args>(args)...)
  9. {
  10. }
  11. };
  12. template <class T>
  13. struct TPtrPolicy {
  14. inline TPtrPolicy(T* t)
  15. : T_(t)
  16. {
  17. }
  18. inline T* Ptr() noexcept {
  19. return T_;
  20. }
  21. inline const T* Ptr() const noexcept {
  22. return T_;
  23. }
  24. T* T_;
  25. };
  26. template <class T>
  27. struct TEmbedPolicy {
  28. template <typename... Args>
  29. inline TEmbedPolicy(Args&&... args)
  30. : T_(std::forward<Args>(args)...)
  31. {
  32. }
  33. inline T* Ptr() noexcept {
  34. return &T_;
  35. }
  36. inline const T* Ptr() const noexcept {
  37. return &T_;
  38. }
  39. T T_;
  40. };
  41. template <class T, class TCounter>
  42. struct TRefPolicy {
  43. using THelper = TWithRefCount<T, TCounter>;
  44. template <typename... Args>
  45. inline TRefPolicy(Args&&... args)
  46. : T_(new THelper(std::forward<Args>(args)...))
  47. {
  48. }
  49. inline T* Ptr() noexcept {
  50. return T_.Get();
  51. }
  52. inline const T* Ptr() const noexcept {
  53. return T_.Get();
  54. }
  55. TIntrusivePtr<THelper> T_;
  56. };
  57. /**
  58. * Storage class that can be handy for implementing proxies / adaptors that can
  59. * accept both lvalues and rvalues. In the latter case it's often required to
  60. * extend the lifetime of the passed rvalue, and the only option is to store it
  61. * in your proxy / adaptor.
  62. *
  63. * Example usage:
  64. * \code
  65. * template<class T>
  66. * struct TProxy {
  67. * TAutoEmbedOrPtrPolicy<T> Value_;
  68. * // Your proxy code...
  69. * };
  70. *
  71. * template<class T>
  72. * TProxy<T> MakeProxy(T&& value) {
  73. * // Rvalues are automagically moved-from, and stored inside the proxy.
  74. * return {std::forward<T>(value)};
  75. * }
  76. * \endcode
  77. *
  78. * Look at `Reversed` in `adaptor.h` for real example.
  79. */
  80. template <class T, bool IsReference = std::is_reference<T>::value>
  81. struct TAutoEmbedOrPtrPolicy: TPtrPolicy<std::remove_reference_t<T>> {
  82. using TBase = TPtrPolicy<std::remove_reference_t<T>>;
  83. TAutoEmbedOrPtrPolicy(T& reference)
  84. : TBase(&reference)
  85. {
  86. }
  87. };
  88. template <class T>
  89. struct TAutoEmbedOrPtrPolicy<T, false>: TEmbedPolicy<T> {
  90. using TBase = TEmbedPolicy<T>;
  91. TAutoEmbedOrPtrPolicy(T&& object)
  92. : TBase(std::move(object))
  93. {
  94. }
  95. };
  96. template <class T>
  97. using TAtomicRefPolicy = TRefPolicy<T, TAtomicCounter>;
  98. template <class T>
  99. using TSimpleRefPolicy = TRefPolicy<T, TSimpleCounter>;