stack.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //
  2. // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/json
  8. //
  9. #ifndef BOOST_JSON_DETAIL_STACK_HPP
  10. #define BOOST_JSON_DETAIL_STACK_HPP
  11. #include <boost/json/detail/config.hpp>
  12. #include <boost/json/storage_ptr.hpp>
  13. #include <boost/mp11/integral.hpp>
  14. #include <cstring>
  15. #include <type_traits>
  16. namespace boost {
  17. namespace json {
  18. namespace detail {
  19. #if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000
  20. template<class T>
  21. struct is_trivially_copy_assignable
  22. : mp11::mp_bool<
  23. std::is_copy_assignable<T>::value &&
  24. std::has_trivial_copy_assign<T>::value >
  25. {};
  26. #else
  27. using std::is_trivially_copy_assignable;
  28. #endif
  29. class stack
  30. {
  31. template< class T = void >
  32. struct non_trivial;
  33. storage_ptr sp_;
  34. std::size_t cap_ = 0;
  35. std::size_t size_ = 0;
  36. non_trivial<>* head_ = nullptr;
  37. unsigned char* base_ = nullptr;
  38. unsigned char* buf_ = nullptr;
  39. public:
  40. BOOST_JSON_DECL
  41. ~stack();
  42. stack() = default;
  43. stack(
  44. storage_ptr sp,
  45. unsigned char* buf,
  46. std::size_t buf_size) noexcept;
  47. bool
  48. empty() const noexcept
  49. {
  50. return size_ == 0;
  51. }
  52. BOOST_JSON_DECL
  53. void
  54. clear() noexcept;
  55. void
  56. reserve(std::size_t n)
  57. {
  58. if(n > cap_)
  59. reserve_impl(n);
  60. }
  61. template<class T>
  62. void
  63. push(T&& t)
  64. {
  65. using U = remove_cvref<T>;
  66. push( static_cast<T&&>(t), is_trivially_copy_assignable<U>() );
  67. }
  68. template<class T>
  69. void
  70. push_unchecked(
  71. T const& t);
  72. template<class T>
  73. void
  74. peek(T& t);
  75. template<class T>
  76. void
  77. pop(T& t)
  78. {
  79. using U = remove_cvref<T>;
  80. pop( t, is_trivially_copy_assignable<U>() );
  81. }
  82. private:
  83. template<class T> void push(
  84. T const& t, std::true_type);
  85. template<class T> void push(
  86. T&& t, std::false_type);
  87. template<class T> void pop(
  88. T& t, std::true_type);
  89. template<class T> void pop(
  90. T& t, std::false_type);
  91. BOOST_JSON_DECL
  92. void
  93. reserve_impl(
  94. std::size_t n);
  95. };
  96. } // detail
  97. } // namespace json
  98. } // namespace boost
  99. #include <boost/json/detail/impl/stack.hpp>
  100. #endif