store_policy.h 2.6 KB

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