You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
2.9 KiB

2 years ago
  1. //
  2. // Created by zwsd
  3. //
  4. #pragma once
  5. #include <algorithm>
  6. #include <fstream>
  7. #include <iostream>
  8. #include <list>
  9. #include <map>
  10. #include <memory>
  11. #include <set>
  12. #include <sstream>
  13. #include <string>
  14. #include <typeindex>
  15. #include <typeinfo>
  16. #include <vector>
  17. /**
  18. * @brief
  19. *
  20. * service: ServiceContrainer
  21. *
  22. * :
  23. * :
  24. * :
  25. * :
  26. *
  27. */
  28. // std::shared_ptr<Buffer> buf(new Buffer());
  29. // Any any(buf);
  30. // std::shared_ptr<Buffer> b = any.Get<std::shared_ptr<Buffer>>();
  31. // assert(buf.get() == b.get());
  32. namespace iflytop {
  33. namespace core {
  34. using namespace std;
  35. class Any {
  36. public:
  37. Any() : content_(nullptr) {}
  38. ~Any() { delete content_; }
  39. template <typename ValueType>
  40. explicit Any(const ValueType& value) : content_(new AnyHolder<ValueType>(value)) {}
  41. Any(const Any& other) : content_(other.content_ ? other.content_->clone() : nullptr) {}
  42. public:
  43. Any& swap(Any& rhs) {
  44. std::swap(content_, rhs.content_);
  45. return *this;
  46. }
  47. template <typename ValueType>
  48. Any& operator=(const ValueType& rhs) {
  49. Any(rhs).swap(*this);
  50. return *this;
  51. }
  52. Any& operator=(const Any& rhs) {
  53. Any(rhs).swap(*this);
  54. return *this;
  55. }
  56. bool IsEmpty() const { return !content_; }
  57. const std::type_info& GetType() const { return content_ ? content_->GetType() : typeid(void); }
  58. template <typename ValueType>
  59. ValueType operator()() const {
  60. return Get<ValueType>();
  61. }
  62. template <typename ValueType>
  63. ValueType Get() const {
  64. if (GetType() == typeid(ValueType)) {
  65. return static_cast<Any::AnyHolder<ValueType>*>(content_)->held_;
  66. } else {
  67. return ValueType();
  68. }
  69. }
  70. protected:
  71. class AnyPlaceHolder {
  72. public:
  73. virtual ~AnyPlaceHolder() {}
  74. public:
  75. virtual const std::type_info& GetType() const = 0;
  76. virtual AnyPlaceHolder* clone() const = 0;
  77. };
  78. template <typename ValueType>
  79. class AnyHolder : public AnyPlaceHolder {
  80. public:
  81. AnyHolder(const ValueType& value) : held_(value) {}
  82. virtual const std::type_info& GetType() const { return typeid(ValueType); }
  83. virtual AnyPlaceHolder* clone() const { return new AnyHolder(held_); }
  84. ValueType held_;
  85. };
  86. protected:
  87. AnyPlaceHolder* content_;
  88. template <typename ValueType>
  89. friend ValueType* any_cast(Any*);
  90. };
  91. template <typename ValueType>
  92. ValueType* any_cast(Any* any) {
  93. if (any && any->GetType() == typeid(ValueType)) {
  94. return &(static_cast<Any::AnyHolder<ValueType>*>(any->content_)->held_);
  95. }
  96. return nullptr;
  97. }
  98. template <typename ValueType>
  99. const ValueType* any_cast(const Any* any) {
  100. return any_cast<ValueType>(const_cast<Any*>(any));
  101. }
  102. template <typename ValueType>
  103. ValueType any_cast(const Any& any) {
  104. const ValueType* result = any_cast<ValueType>(&any);
  105. assert(result);
  106. if (!result) {
  107. return ValueType();
  108. }
  109. return *result;
  110. }
  111. } // namespace core
  112. } // namespace iflytop