util.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #ifndef UTIL_H
  2. #define UTIL_H
  3. #include <string>
  4. #include <functional>
  5. #include <memory>
  6. #include <mutex>
  7. #include <utility>
  8. #include <boost/asio.hpp>
  9. #ifdef ANDROID
  10. #ifndef __clang__
  11. #include <boost/lexical_cast.hpp>
  12. namespace std
  13. {
  14. template <typename T>
  15. std::string to_string(T value)
  16. {
  17. return boost::lexical_cast<std::string>(value);
  18. }
  19. inline int stoi(const std::string& str)
  20. {
  21. return boost::lexical_cast<int>(str);
  22. }
  23. }
  24. #endif
  25. #endif
  26. namespace i2p
  27. {
  28. namespace util
  29. {
  30. template<class T>
  31. class MemoryPool
  32. {
  33. //BOOST_STATIC_ASSERT_MSG(sizeof(T) >= sizeof(void*), "size cannot be less that general pointer size");
  34. public:
  35. MemoryPool (): m_Head (nullptr) {}
  36. ~MemoryPool ()
  37. {
  38. while (m_Head)
  39. {
  40. auto tmp = m_Head;
  41. m_Head = static_cast<T*>(*(void * *)m_Head); // next
  42. ::operator delete ((void *)tmp);
  43. }
  44. }
  45. template<typename... TArgs>
  46. T * Acquire (TArgs&&... args)
  47. {
  48. if (!m_Head) return new T(std::forward<TArgs>(args)...);
  49. else
  50. {
  51. auto tmp = m_Head;
  52. m_Head = static_cast<T*>(*(void * *)m_Head); // next
  53. return new (tmp)T(std::forward<TArgs>(args)...);
  54. }
  55. }
  56. void Release (T * t)
  57. {
  58. if (!t) return;
  59. t->~T ();
  60. *(void * *)t = m_Head; // next
  61. m_Head = t;
  62. }
  63. template<typename... TArgs>
  64. std::unique_ptr<T, std::function<void(T*)> > AcquireUnique (TArgs&&... args)
  65. {
  66. return std::unique_ptr<T, std::function<void(T*)> >(Acquire (std::forward<TArgs>(args)...),
  67. std::bind (&MemoryPool<T>::Release, this, std::placeholders::_1));
  68. }
  69. template<typename... TArgs>
  70. std::shared_ptr<T> AcquireShared (TArgs&&... args)
  71. {
  72. return std::shared_ptr<T>(Acquire (std::forward<TArgs>(args)...),
  73. std::bind (&MemoryPool<T>::Release, this, std::placeholders::_1));
  74. }
  75. protected:
  76. T * m_Head;
  77. };
  78. template<class T>
  79. class MemoryPoolMt: public MemoryPool<T>
  80. {
  81. public:
  82. MemoryPoolMt () {}
  83. template<typename... TArgs>
  84. T * AcquireMt (TArgs&&... args)
  85. {
  86. if (!this->m_Head) return new T(std::forward<TArgs>(args)...);
  87. std::lock_guard<std::mutex> l(m_Mutex);
  88. return this->Acquire (std::forward<TArgs>(args)...);
  89. }
  90. void ReleaseMt (T * t)
  91. {
  92. std::lock_guard<std::mutex> l(m_Mutex);
  93. this->Release (t);
  94. }
  95. template<template<typename, typename...>class C, typename... R>
  96. void ReleaseMt(const C<T *, R...>& c)
  97. {
  98. std::lock_guard<std::mutex> l(m_Mutex);
  99. for (auto& it: c)
  100. this->Release (it);
  101. }
  102. private:
  103. std::mutex m_Mutex;
  104. };
  105. namespace net
  106. {
  107. int GetMTU (const boost::asio::ip::address& localAddress);
  108. const boost::asio::ip::address GetInterfaceAddress(const std::string & ifname, bool ipv6=false);
  109. }
  110. }
  111. }
  112. #endif