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.

98 lines
2.3 KiB

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