General Purpose library for Freestanding C++ and POSIX systems
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.

99 lines
2.4 KiB

  1. #pragma once
  2. #include "gp/algorithms/tmp_manip.hpp"
  3. #include "gp/algorithms/cvref.hpp"
  4. #include "gp/utils/range.hpp"
  5. namespace gp{
  6. template<typename T>
  7. typename gp::remove_reference<T>::type&& move(T&& value)
  8. {
  9. return (typename gp::remove_reference<T>::type&&)value;
  10. }
  11. template<typename T>
  12. constexpr T&& forward(typename gp::remove_reference<T>::type& t) noexcept
  13. {
  14. return static_cast<T&&>(t);
  15. }
  16. template<typename T>
  17. constexpr T&& forward(typename gp::remove_reference<T>::type&& t) noexcept
  18. {
  19. static_assert(!std::is_lvalue_reference_v<T>,"bad forward of rvalue as lvalue");
  20. return static_cast<T&&>(t);
  21. }
  22. template<typename T>
  23. constexpr void swap(
  24. T& lhs,
  25. T& rhs
  26. )
  27. {
  28. gp::remove_cvref_t<T> tmp = gp::move(lhs);
  29. lhs = gp::move(rhs);
  30. rhs = gp::move(tmp);
  31. }
  32. template<typename T>
  33. constexpr void swap(
  34. T&& lhs,
  35. T& rhs
  36. )
  37. {
  38. gp::remove_cvref_t<T> tmp = gp::move(lhs);
  39. lhs = gp::move(rhs);
  40. rhs = gp::move(tmp);
  41. }
  42. template<typename T>
  43. constexpr void swap(
  44. T& lhs,
  45. T&& rhs
  46. )
  47. {
  48. gp::remove_cvref_t<T> tmp = gp::move(lhs);
  49. lhs = gp::move(rhs);
  50. rhs = gp::move(tmp);
  51. }
  52. template<typename T>
  53. constexpr void swap(
  54. T&& lhs,
  55. T&& rhs
  56. )
  57. {
  58. gp::remove_cvref_t<T> tmp = gp::move(lhs);
  59. lhs = gp::move(rhs);
  60. rhs = gp::move(tmp);
  61. }
  62. template<typename range_in, typename range_out>
  63. nameless_range<typename range_out::associated_iterator> move(range_in src, range_out dest)
  64. {
  65. if(src.size()>dest.size())
  66. return nameless_range<typename range_out::associated_iterator>(dest.begin(), dest.end());
  67. auto in = src.begin();
  68. auto in_close = src.end();
  69. auto out = dest.begin();
  70. while(in != in_close)
  71. {
  72. *(out++) = gp::move(*(in++));
  73. }
  74. return nameless_range<typename range_out::associated_iterator>{out, dest.end()};
  75. }
  76. template<typename range_in, typename range_out>
  77. nameless_range<typename gp::remove_reference<range_out>::type::associated_iterator> move_uninitialized(range_in&& src, range_out&& dest)
  78. {
  79. using T = typename gp::remove_reference<decltype(*dest.begin())>::type;
  80. if(src.size()>dest.size())
  81. return nameless_range<typename gp::remove_reference<range_out>::type::associated_iterator>(dest.begin(), dest.end());
  82. auto in = src.begin();
  83. auto in_close = src.end();
  84. auto out = dest.begin();
  85. while(in != in_close)
  86. {
  87. new(&*(out++)) T{gp::move(*(in++))};
  88. }
  89. return nameless_range<typename gp::remove_reference<range_out>::type::associated_iterator>{out, dest.end()};
  90. }
  91. }