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.
 
 

112 lines
2.8 KiB

#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 const T&& forward(const typename gp::remove_reference<T>::type& t) noexcept
{
return static_cast<const T&&>(t);
}
template<typename T>
constexpr const T&& forward(const 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<const 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()};
}
}