#pragma once
|
|
|
|
#include "gp/algorithms/tmp_manip.hpp"
|
|
#include "gp/algorithms/cvref.hpp"
|
|
#include "gp/utils/range.hpp"
|
|
|
|
namespace gp{
|
|
template<typename T>
|
|
typename gp::remove_reference<T>::type&& move(T&& value)
|
|
{
|
|
return (typename gp::remove_reference<T>::type&&)value;
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr T&& forward(typename gp::remove_reference<T>::type& t) noexcept
|
|
{
|
|
return static_cast<T&&>(t);
|
|
}
|
|
template<typename T>
|
|
constexpr T&& forward(typename gp::remove_reference<T>::type&& t) noexcept
|
|
{
|
|
static_assert(!std::is_lvalue_reference_v<T>,"bad forward of rvalue as lvalue");
|
|
return static_cast<T&&>(t);
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr void swap(
|
|
T& lhs,
|
|
T& rhs
|
|
)
|
|
{
|
|
gp::remove_cvref_t<T> tmp = gp::move(lhs);
|
|
lhs = gp::move(rhs);
|
|
rhs = gp::move(tmp);
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr void swap(
|
|
T&& lhs,
|
|
T& rhs
|
|
)
|
|
{
|
|
gp::remove_cvref_t<T> tmp = gp::move(lhs);
|
|
lhs = gp::move(rhs);
|
|
rhs = gp::move(tmp);
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr void swap(
|
|
T& lhs,
|
|
T&& rhs
|
|
)
|
|
{
|
|
gp::remove_cvref_t<T> tmp = gp::move(lhs);
|
|
lhs = gp::move(rhs);
|
|
rhs = gp::move(tmp);
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr void swap(
|
|
T&& lhs,
|
|
T&& rhs
|
|
)
|
|
{
|
|
gp::remove_cvref_t<T> tmp = gp::move(lhs);
|
|
lhs = gp::move(rhs);
|
|
rhs = gp::move(tmp);
|
|
}
|
|
|
|
template<typename range_in, typename range_out>
|
|
nameless_range<typename range_out::associated_iterator> move(range_in src, range_out dest)
|
|
{
|
|
if(src.size()>dest.size())
|
|
return nameless_range<typename range_out::associated_iterator>(dest.begin(), dest.end());
|
|
auto in = src.begin();
|
|
auto in_close = src.end();
|
|
auto out = dest.begin();
|
|
while(in != in_close)
|
|
{
|
|
*(out++) = gp::move(*(in++));
|
|
}
|
|
return nameless_range<typename range_out::associated_iterator>{out, dest.end()};
|
|
}
|
|
|
|
template<typename range_in, typename range_out>
|
|
nameless_range<typename gp::remove_reference<range_out>::type::associated_iterator> move_uninitialized(range_in&& src, range_out&& dest)
|
|
{
|
|
using T = typename gp::remove_reference<decltype(*dest.begin())>::type;
|
|
if(src.size()>dest.size())
|
|
return nameless_range<typename gp::remove_reference<range_out>::type::associated_iterator>(dest.begin(), dest.end());
|
|
auto in = src.begin();
|
|
auto in_close = src.end();
|
|
auto out = dest.begin();
|
|
while(in != in_close)
|
|
{
|
|
new(&*(out++)) T{gp::move(*(in++))};
|
|
}
|
|
return nameless_range<typename gp::remove_reference<range_out>::type::associated_iterator>{out, dest.end()};
|
|
}
|
|
}
|