|
|
|
@ -1,297 +1,345 @@
|
|
|
|
|
#ifndef MYTINYSTL_UTIL_H_
|
|
|
|
|
#define MYTINYSTL_UTIL_H_
|
|
|
|
|
|
|
|
|
|
// 这个文件包含一些通用工具,包括 move, forward, swap 等函数,以及 pair 等
|
|
|
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
|
|
|
|
|
|
#include "type_traits.h"
|
|
|
|
|
|
|
|
|
|
namespace mystl
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// move
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
typename std::remove_reference<T>::type&& move(T&& arg) noexcept
|
|
|
|
|
{
|
|
|
|
|
return static_cast<typename std::remove_reference<T>::type&&>(arg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// forward
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
T&& forward(typename std::remove_reference<T>::type& arg) noexcept
|
|
|
|
|
{
|
|
|
|
|
return static_cast<T&&>(arg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
T&& forward(typename std::remove_reference<T>::type&& arg) noexcept
|
|
|
|
|
{
|
|
|
|
|
static_assert(!std::is_lvalue_reference<T>::value, "bad forward");
|
|
|
|
|
return static_cast<T&&>(arg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// swap
|
|
|
|
|
|
|
|
|
|
template <class Tp>
|
|
|
|
|
void swap(Tp& lhs, Tp& rhs)
|
|
|
|
|
{
|
|
|
|
|
auto tmp(mystl::move(lhs));
|
|
|
|
|
lhs = mystl::move(rhs);
|
|
|
|
|
rhs = mystl::move(tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class ForwardIter1, class ForwardIter2>
|
|
|
|
|
ForwardIter2 swap_range(ForwardIter1 first1, ForwardIter1 last1, ForwardIter2 first2)
|
|
|
|
|
{
|
|
|
|
|
for (; first1 != last1; ++first1, (void) ++first2)
|
|
|
|
|
mystl::swap(*first1, *first2);
|
|
|
|
|
return first2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class Tp, size_t N>
|
|
|
|
|
void swap(Tp(&a)[N], Tp(&b)[N])
|
|
|
|
|
{
|
|
|
|
|
mystl::swap_range(a, a + N, b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
|
// pair
|
|
|
|
|
|
|
|
|
|
// 结构体模板 : pair
|
|
|
|
|
// 两个模板参数分别表示两个数据的类型
|
|
|
|
|
// 用 first 和 second 来分别取出第一个数据和第二个数据
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
struct pair
|
|
|
|
|
{
|
|
|
|
|
typedef Ty1 first_type;
|
|
|
|
|
typedef Ty2 second_type;
|
|
|
|
|
|
|
|
|
|
first_type first; // 保存第一个数据
|
|
|
|
|
second_type second; // 保存第二个数据
|
|
|
|
|
|
|
|
|
|
// default constructiable
|
|
|
|
|
template <class Other1 = Ty1, class Other2 = Ty2,
|
|
|
|
|
typename = typename std::enable_if<
|
|
|
|
|
std::is_default_constructible<Other1>::value &&
|
|
|
|
|
std::is_default_constructible<Other2>::value, void>::type>
|
|
|
|
|
constexpr pair()
|
|
|
|
|
: first(), second()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// implicit constructiable for this type
|
|
|
|
|
template <class U1 = Ty1, class U2 = Ty2,
|
|
|
|
|
typename std::enable_if<
|
|
|
|
|
std::is_copy_constructible<U1>::value &&
|
|
|
|
|
std::is_copy_constructible<U2>::value &&
|
|
|
|
|
std::is_convertible<const U1&, Ty1>::value &&
|
|
|
|
|
std::is_convertible<const U2&, Ty2>::value, int>::type = 0>
|
|
|
|
|
constexpr pair(const Ty1& a, const Ty2& b)
|
|
|
|
|
: first(a), second(b)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// explicit constructible for this type
|
|
|
|
|
template <class U1 = Ty1, class U2 = Ty2,
|
|
|
|
|
typename std::enable_if<
|
|
|
|
|
std::is_copy_constructible<U1>::value &&
|
|
|
|
|
std::is_copy_constructible<U2>::value &&
|
|
|
|
|
(!std::is_convertible<const U1&, Ty1>::value ||
|
|
|
|
|
!std::is_convertible<const U2&, Ty2>::value), int>::type = 0>
|
|
|
|
|
explicit constexpr pair(const Ty1& a, const Ty2& b)
|
|
|
|
|
: first(a), second(b)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pair(const pair& rhs) = default;
|
|
|
|
|
pair(pair&& rhs) = default;
|
|
|
|
|
|
|
|
|
|
// implicit constructiable for other type
|
|
|
|
|
template <class Other1, class Other2,
|
|
|
|
|
typename std::enable_if<
|
|
|
|
|
std::is_constructible<Ty1, Other1>::value &&
|
|
|
|
|
std::is_constructible<Ty2, Other2>::value &&
|
|
|
|
|
std::is_convertible<Other1&&, Ty1>::value &&
|
|
|
|
|
std::is_convertible<Other2&&, Ty2>::value, int>::type = 0>
|
|
|
|
|
constexpr pair(Other1&& a, Other2&& b)
|
|
|
|
|
: first(mystl::forward<Other1>(a)),
|
|
|
|
|
second(mystl::forward<Other2>(b))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// explicit constructiable for other type
|
|
|
|
|
template <class Other1, class Other2,
|
|
|
|
|
typename std::enable_if<
|
|
|
|
|
std::is_constructible<Ty1, Other1>::value &&
|
|
|
|
|
std::is_constructible<Ty2, Other2>::value &&
|
|
|
|
|
(!std::is_convertible<Other1, Ty1>::value ||
|
|
|
|
|
!std::is_convertible<Other2, Ty2>::value), int>::type = 0>
|
|
|
|
|
explicit constexpr pair(Other1&& a, Other2&& b)
|
|
|
|
|
: first(mystl::forward<Other1>(a)),
|
|
|
|
|
second(mystl::forward<Other2>(b))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// implicit constructiable for other pair
|
|
|
|
|
template <class Other1, class Other2,
|
|
|
|
|
typename std::enable_if<
|
|
|
|
|
std::is_constructible<Ty1, const Other1&>::value &&
|
|
|
|
|
std::is_constructible<Ty2, const Other2&>::value &&
|
|
|
|
|
std::is_convertible<const Other1&, Ty1>::value &&
|
|
|
|
|
std::is_convertible<const Other2&, Ty2>::value, int>::type = 0>
|
|
|
|
|
constexpr pair(const pair<Other1, Other2>& other)
|
|
|
|
|
: first(other.first),
|
|
|
|
|
second(other.second)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// explicit constructiable for other pair
|
|
|
|
|
template <class Other1, class Other2,
|
|
|
|
|
typename std::enable_if<
|
|
|
|
|
std::is_constructible<Ty1, const Other1&>::value &&
|
|
|
|
|
std::is_constructible<Ty2, const Other2&>::value &&
|
|
|
|
|
(!std::is_convertible<const Other1&, Ty1>::value ||
|
|
|
|
|
!std::is_convertible<const Other2&, Ty2>::value), int>::type = 0>
|
|
|
|
|
explicit constexpr pair(const pair<Other1, Other2>& other)
|
|
|
|
|
: first(other.first),
|
|
|
|
|
second(other.second)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// implicit constructiable for other pair
|
|
|
|
|
template <class Other1, class Other2,
|
|
|
|
|
typename std::enable_if<
|
|
|
|
|
std::is_constructible<Ty1, Other1>::value &&
|
|
|
|
|
std::is_constructible<Ty2, Other2>::value &&
|
|
|
|
|
std::is_convertible<Other1, Ty1>::value &&
|
|
|
|
|
std::is_convertible<Other2, Ty2>::value, int>::type = 0>
|
|
|
|
|
constexpr pair(pair<Other1, Other2>&& other)
|
|
|
|
|
: first(mystl::forward<Other1>(other.first)),
|
|
|
|
|
second(mystl::forward<Other2>(other.second))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// explicit constructiable for other pair
|
|
|
|
|
template <class Other1, class Other2,
|
|
|
|
|
typename std::enable_if<
|
|
|
|
|
std::is_constructible<Ty1, Other1>::value &&
|
|
|
|
|
std::is_constructible<Ty2, Other2>::value &&
|
|
|
|
|
(!std::is_convertible<Other1, Ty1>::value ||
|
|
|
|
|
!std::is_convertible<Other2, Ty2>::value), int>::type = 0>
|
|
|
|
|
explicit constexpr pair(pair<Other1, Other2>&& other)
|
|
|
|
|
: first(mystl::forward<Other1>(other.first)),
|
|
|
|
|
second(mystl::forward<Other2>(other.second))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// copy assign for this pair
|
|
|
|
|
pair& operator=(const pair& rhs)
|
|
|
|
|
{
|
|
|
|
|
if (this != &rhs)
|
|
|
|
|
{
|
|
|
|
|
first = rhs.first;
|
|
|
|
|
second = rhs.second;
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// move assign for this pair
|
|
|
|
|
pair& operator=(pair&& rhs)
|
|
|
|
|
{
|
|
|
|
|
if (this != &rhs)
|
|
|
|
|
{
|
|
|
|
|
first = mystl::move(rhs.first);
|
|
|
|
|
second = mystl::move(rhs.second);
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// copy assign for other pair
|
|
|
|
|
template <class Other1, class Other2>
|
|
|
|
|
pair& operator=(const pair<Other1, Other2>& other)
|
|
|
|
|
{
|
|
|
|
|
first = other.first;
|
|
|
|
|
second = other.second;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// move assign for other pair
|
|
|
|
|
template <class Other1, class Other2>
|
|
|
|
|
pair& operator=(pair<Other1, Other2>&& other)
|
|
|
|
|
{
|
|
|
|
|
first = mystl::forward<Other1>(other.first);
|
|
|
|
|
second = mystl::forward<Other2>(other.second);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~pair() = default;
|
|
|
|
|
|
|
|
|
|
void swap(pair& other)
|
|
|
|
|
{
|
|
|
|
|
if (this != &other)
|
|
|
|
|
{
|
|
|
|
|
mystl::swap(first, other.first);
|
|
|
|
|
mystl::swap(second, other.second);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 重载比较操作符
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator==(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return lhs.first == rhs.first && lhs.second == rhs.second;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator<(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return lhs.first < rhs.first || (lhs.first == rhs.first && lhs.second < rhs.second);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator!=(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return !(lhs == rhs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator>(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return rhs < lhs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator<=(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return !(rhs < lhs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator>=(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return !(lhs < rhs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重载 mystl 的 swap
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
void swap(pair<Ty1, Ty2>& lhs, pair<Ty1, Ty2>& rhs)
|
|
|
|
|
{
|
|
|
|
|
lhs.swap(rhs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 全局函数,让两个数据成为一个 pair
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
pair<Ty1, Ty2> make_pair(Ty1&& first, Ty2&& second)
|
|
|
|
|
{
|
|
|
|
|
return pair<Ty1, Ty2>(mystl::forward<Ty1>(first), mystl::forward<Ty2>(second));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif // !MYTINYSTL_UTIL_H_
|
|
|
|
|
|
|
|
|
|
#ifndef MYTINYSTL_UTIL_H_//
|
|
|
|
|
// 防止头文件被重复包含的宏定义开始//
|
|
|
|
|
#define MYTINYSTL_UTIL_H_//
|
|
|
|
|
// 防止头文件被重复包含的宏定义结束//
|
|
|
|
|
//
|
|
|
|
|
#include <cstddef>//
|
|
|
|
|
// 包含标准库中的cstddef头文件,通常用于定义一些基本类型如size_t等//
|
|
|
|
|
//
|
|
|
|
|
#include "type_traits.h"//
|
|
|
|
|
// 包含自定义的type_traits头文件,用于提供类型特征支持//
|
|
|
|
|
//
|
|
|
|
|
namespace mystl//
|
|
|
|
|
// 定义命名空间mystl,用于封装自定义的STL实现//
|
|
|
|
|
//
|
|
|
|
|
{//
|
|
|
|
|
//
|
|
|
|
|
template <class T>//
|
|
|
|
|
typename std::remove_reference<T>::type&& move(T&& arg) noexcept//
|
|
|
|
|
// 定义move函数模板,用于将参数arg转换为右值引用//
|
|
|
|
|
{//
|
|
|
|
|
return static_cast<typename std::remove_reference<T>::type&&>(arg);//
|
|
|
|
|
// 使用static_cast将arg转换为右值引用,并返回//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class T>//
|
|
|
|
|
T&& forward(typename std::remove_reference<T>::type& arg) noexcept//
|
|
|
|
|
// 定义forward函数模板的重载版本,用于完美转发左值引用//
|
|
|
|
|
{//
|
|
|
|
|
return static_cast<T&&>(arg);//
|
|
|
|
|
// 使用static_cast将arg转换为T类型的右值引用,并返回//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class T>//
|
|
|
|
|
T&& forward(typename std::remove_reference<T>::type&& arg) noexcept//
|
|
|
|
|
// 定义forward函数模板的重载版本,用于完美转发右值引用//
|
|
|
|
|
{//
|
|
|
|
|
static_assert(!std::is_lvalue_reference<T>::value, "bad forward");//
|
|
|
|
|
// 静态断言,确保T不是左值引用类型,否则编译报错//
|
|
|
|
|
return static_cast<T&&>(arg);//
|
|
|
|
|
// 使用static_cast将arg转换为T类型的右值引用,并返回//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Tp>//
|
|
|
|
|
void swap(Tp& lhs, Tp& rhs)//
|
|
|
|
|
// 定义swap函数模板,用于交换两个变量的值//
|
|
|
|
|
{//
|
|
|
|
|
auto tmp(mystl::move(lhs));//
|
|
|
|
|
// 使用move将lhs转换为右值引用,并存储在tmp中//
|
|
|
|
|
lhs = mystl::move(rhs);//
|
|
|
|
|
// 将rhs的值赋给lhs//
|
|
|
|
|
rhs = mystl::move(tmp);//
|
|
|
|
|
// 将tmp的值赋给rhs//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class ForwardIter1, class ForwardIter2>//
|
|
|
|
|
ForwardIter2 swap_range(ForwardIter1 first1, ForwardIter1 last1, ForwardIter2 first2)//
|
|
|
|
|
// 定义swap_range函数模板,用于交换两个范围内的元素//
|
|
|
|
|
{//
|
|
|
|
|
for (; first1 != last1; ++first1, (void) ++first2)//
|
|
|
|
|
// 遍历两个范围内的元素//
|
|
|
|
|
mystl::swap(*first1, *first2);//
|
|
|
|
|
// 交换对应位置的元素//
|
|
|
|
|
return first2;//
|
|
|
|
|
// 返回第二个范围的结束迭代器//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Tp, size_t N>//
|
|
|
|
|
void swap(Tp(&a)[N], Tp(&b)[N])//
|
|
|
|
|
// 定义swap函数模板的重载版本,用于交换两个固定大小数组的值//
|
|
|
|
|
{//
|
|
|
|
|
mystl::swap_range(a, a + N, b);//
|
|
|
|
|
// 使用swap_range函数交换两个数组的元素//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Ty1, class Ty2>//
|
|
|
|
|
struct pair//
|
|
|
|
|
// 定义pair结构体模板,用于存储两个值//
|
|
|
|
|
{//
|
|
|
|
|
typedef Ty1 first_type;//
|
|
|
|
|
typedef Ty2 second_type;//
|
|
|
|
|
// 定义类型别名,分别表示第一个和第二个值的类型//
|
|
|
|
|
//
|
|
|
|
|
first_type first; //
|
|
|
|
|
second_type second; //
|
|
|
|
|
// 定义两个成员变量,分别存储第一个和第二个值//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
template <class Other1 = Ty1, class Other2 = Ty2,//
|
|
|
|
|
typename = typename std::enable_if<//
|
|
|
|
|
std::is_default_constructible<Other1>::value &&//
|
|
|
|
|
std::is_default_constructible<Other2>::value, void>::type>//
|
|
|
|
|
constexpr pair()//
|
|
|
|
|
: first(), second()//
|
|
|
|
|
// 定义默认构造函数,使用默认构造方式初始化first和second//
|
|
|
|
|
{//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class U1 = Ty1, class U2 = Ty2,//
|
|
|
|
|
typename std::enable_if<//
|
|
|
|
|
std::is_copy_constructible<U1>::value &&//
|
|
|
|
|
std::is_copy_constructible<U2>::value &&//
|
|
|
|
|
std::is_convertible<const U1&, Ty1>::value &&//
|
|
|
|
|
std::is_convertible<const U2&, Ty2>::value, int>::type = 0>//
|
|
|
|
|
constexpr pair(const Ty1& a, const Ty2& b)//
|
|
|
|
|
: first(a), second(b)//
|
|
|
|
|
// 定义拷贝构造函数,使用拷贝构造方式初始化first和second//
|
|
|
|
|
{//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class U1 = Ty1, class U2 = Ty2,//
|
|
|
|
|
typename std::enable_if<//
|
|
|
|
|
std::is_copy_constructible<U1>::value &&//
|
|
|
|
|
std::is_copy_constructible<U2>::value &&//
|
|
|
|
|
(!std::is_convertible<const U1&, Ty1>::value ||//
|
|
|
|
|
!std::is_convertible<const U2&, Ty2>::value), int>::type = 0>//
|
|
|
|
|
explicit constexpr pair(const Ty1& a, const Ty2& b)//
|
|
|
|
|
: first(a), second(b)//
|
|
|
|
|
// 定义显式拷贝构造函数,使用拷贝构造方式初始化first和second//
|
|
|
|
|
{//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
pair(const pair& rhs) = default;//
|
|
|
|
|
// 默认拷贝构造函数//
|
|
|
|
|
//
|
|
|
|
|
pair(pair&& rhs) = default;//
|
|
|
|
|
// 默认移动构造函数//
|
|
|
|
|
//
|
|
|
|
|
template <class Other1, class Other2,//
|
|
|
|
|
typename std::enable_if<//
|
|
|
|
|
std::is_constructible<Ty1, Other1>::value &&//
|
|
|
|
|
std::is_constructible<Ty2, Other2>::value &&//
|
|
|
|
|
std::is_convertible<Other1&&, Ty1>::value &&//
|
|
|
|
|
std::is_convertible<Other2&&, Ty2>::value, int>::type = 0>//
|
|
|
|
|
constexpr pair(Other1&& a, Other2&& b)//
|
|
|
|
|
: first(mystl::forward<Other1>(a)),//
|
|
|
|
|
second(mystl::forward<Other2>(b))//
|
|
|
|
|
// 定义构造函数,使用完美转发初始化first和second//
|
|
|
|
|
{//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Other1, class Other2,//
|
|
|
|
|
typename std::enable_if<//
|
|
|
|
|
std::is_constructible<Ty1, Other1>::value &&//
|
|
|
|
|
std::is_constructible<Ty2, Other2>::value &&//
|
|
|
|
|
(!std::is_convertible<Other1, Ty1>::value ||//
|
|
|
|
|
!std::is_convertible<Other2, Ty2>::value), int>::type = 0>//
|
|
|
|
|
explicit constexpr pair(Other1&& a, Other2&& b)//
|
|
|
|
|
: first(mystl::forward<Other1>(a)),//
|
|
|
|
|
second(mystl::forward<Other2>(b))//
|
|
|
|
|
// 定义显式构造函数,使用完美转发初始化first和second//
|
|
|
|
|
{//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Other1, class Other2,//
|
|
|
|
|
typename std::enable_if<//
|
|
|
|
|
std::is_constructible<Ty1, const Other1&>::value &&//
|
|
|
|
|
std::is_constructible<Ty2, const Other2&>::value &&//
|
|
|
|
|
std::is_convertible<const Other1&, Ty1>::value &&//
|
|
|
|
|
std::is_convertible<const Other2&, Ty2>::value, int>::type = 0>//
|
|
|
|
|
constexpr pair(const pair<Other1, Other2>& other)//
|
|
|
|
|
: first(other.first),//
|
|
|
|
|
second(other.second)//
|
|
|
|
|
// 定义拷贝构造函数,使用拷贝构造方式初始化first和second//
|
|
|
|
|
{//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Other1, class Other2,//
|
|
|
|
|
typename std::enable_if<//
|
|
|
|
|
std::is_constructible<Ty1, const Other1&>::value &&//
|
|
|
|
|
std::is_constructible<Ty2, const Other2&>::value &&//
|
|
|
|
|
(!std::is_convertible<const Other1&, Ty1>::value ||//
|
|
|
|
|
!std::is_convertible<const Other2&, Ty2>::value), int>::type = 0>//
|
|
|
|
|
explicit constexpr pair(const pair<Other1 &other)//
|
|
|
|
|
: first(other.first),//
|
|
|
|
|
second(other.second)//
|
|
|
|
|
// 定义显式拷贝构造函数,使用拷贝构造方式初始化first和second//
|
|
|
|
|
{//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Other1, class Other2,//
|
|
|
|
|
typename std::enable_if<//
|
|
|
|
|
std::is_constructible<Ty1, Other1>::value &&//
|
|
|
|
|
std::is_constructible<Ty2, Other2>::value &&//
|
|
|
|
|
std::is_convertible<Other1, Ty1>::value &&//
|
|
|
|
|
std::is_convertible<Other2, Ty2>::value, int>::type = 0>//
|
|
|
|
|
constexpr pair(pair<Other1, Other2>&& other)//
|
|
|
|
|
: first(mystl::forward<Other1>(other.first)),//
|
|
|
|
|
second(mystl::forward<Other2>(other.second))//
|
|
|
|
|
// 定义构造函数,使用完美转发初始化first和second//
|
|
|
|
|
{//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Other1, class Other2,//
|
|
|
|
|
typename std::enable_if<//
|
|
|
|
|
std::is_constructible<Ty1, Other1>::value &&//
|
|
|
|
|
std::is_constructible<Ty2, Other2>::value &&//
|
|
|
|
|
(!std::is_convertible<Other1, Ty1>::value ||//
|
|
|
|
|
!std::is_convertible<Other2, Ty2>::value), int>::type = 0>//
|
|
|
|
|
explicit constexpr pair(pair<Other1, Other2>&& other)//
|
|
|
|
|
: first(mystl::forward<Other1>(other.first)),//
|
|
|
|
|
second(mystl::forward<Other2>(other.second))//
|
|
|
|
|
// 继续使用完美转发初始化second成员变量//
|
|
|
|
|
{//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
pair& operator=(const pair& rhs)//
|
|
|
|
|
// 定义拷贝赋值运算符//
|
|
|
|
|
{//
|
|
|
|
|
if (this != &rhs)//
|
|
|
|
|
// 如果不是自赋值//
|
|
|
|
|
{//
|
|
|
|
|
first = rhs.first;//
|
|
|
|
|
// 将rhs的first赋值给当前对象的first//
|
|
|
|
|
second = rhs.second;//
|
|
|
|
|
// 将rhs的second赋值给当前对象的second//
|
|
|
|
|
}//
|
|
|
|
|
return *this;//
|
|
|
|
|
// 返回当前对象的引用//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
pair& operator=(pair&& rhs)//
|
|
|
|
|
// 定义移动赋值运算符//
|
|
|
|
|
{//
|
|
|
|
|
if (this != &rhs)//
|
|
|
|
|
// 如果不是自赋值//
|
|
|
|
|
{//
|
|
|
|
|
first = mystl::move(rhs.first);//
|
|
|
|
|
// 将rhs的first移动赋值给当前对象的first//
|
|
|
|
|
second = mystl::move(rhs.second);//
|
|
|
|
|
// 将rhs的second移动赋值给当前对象的second//
|
|
|
|
|
}//
|
|
|
|
|
return *this;//
|
|
|
|
|
// 返回当前对象的引用//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Other1, class Other2>//
|
|
|
|
|
pair& operator=(const pair<Other1, Other2>& other)//
|
|
|
|
|
// 定义模板化的拷贝赋值运算符//
|
|
|
|
|
{//
|
|
|
|
|
first = other.first;//
|
|
|
|
|
// 将other的first赋值给当前对象的first//
|
|
|
|
|
second = other.second;//
|
|
|
|
|
// 将other的second赋值给当前对象的second//
|
|
|
|
|
return *this;//
|
|
|
|
|
// 返回当前对象的引用//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Other1, class Other2>//
|
|
|
|
|
pair& operator=(pair<Other1, Other2>&& other)//
|
|
|
|
|
// 定义模板化的移动赋值运算符//
|
|
|
|
|
{//
|
|
|
|
|
first = mystl::forward<Other1>(other.first);//
|
|
|
|
|
// 将other的first移动赋值给当前对象的first//
|
|
|
|
|
second = mystl::forward<Other2>(other.second);//
|
|
|
|
|
// 将other的second移动赋值给当前对象的second//
|
|
|
|
|
return *this;//
|
|
|
|
|
// 返回当前对象的引用//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
~pair() = default;//
|
|
|
|
|
// 默认析构函数//
|
|
|
|
|
//
|
|
|
|
|
void swap(pair& other)//
|
|
|
|
|
// 定义成员函数swap,用于交换两个pair对象的成员变量//
|
|
|
|
|
{//
|
|
|
|
|
if (this != &other)//
|
|
|
|
|
// 如果不是自交换//
|
|
|
|
|
{//
|
|
|
|
|
mystl::swap(first, other.first);//
|
|
|
|
|
// 交换first成员变量//
|
|
|
|
|
mystl::swap(second, other.second);//
|
|
|
|
|
// 交换second成员变量//
|
|
|
|
|
}//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
};//
|
|
|
|
|
//
|
|
|
|
|
template <class Ty1, class Ty2>//
|
|
|
|
|
bool operator==(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)//
|
|
|
|
|
// 定义全局函数operator==,用于比较两个pair对象是否相等//
|
|
|
|
|
{//
|
|
|
|
|
return lhs.first == rhs.first && lhs.second == rhs.second;//
|
|
|
|
|
// 如果两个pair对象的first和second都相等,则认为两个pair对象相等//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Ty1, class Ty2>//
|
|
|
|
|
bool operator<(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)//
|
|
|
|
|
// 定义全局函数operator<,用于比较两个pair对象的大小//
|
|
|
|
|
{//
|
|
|
|
|
return lhs.first < rhs.first || (lhs.first == rhs.first && lhs.second < rhs.second);//
|
|
|
|
|
// 如果lhs的first小于rhs的first,或者lhs的first等于rhs的first且lhs的second小于rhs的second,则认为lhs小于rhs//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Ty1, class Ty2>//
|
|
|
|
|
bool operator!=(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)//
|
|
|
|
|
// 定义全局函数operator!=,用于比较两个pair对象是否不相等//
|
|
|
|
|
{//
|
|
|
|
|
return !(lhs == rhs);//
|
|
|
|
|
// 如果两个pair对象不相等,则返回true//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Ty1, class Ty2>//
|
|
|
|
|
bool operator>(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)//
|
|
|
|
|
// 定义全局函数operator>,用于比较两个pair对象的大小//
|
|
|
|
|
{//
|
|
|
|
|
return rhs < lhs;//
|
|
|
|
|
// 如果rhs小于lhs,则认为lhs大于rhs//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Ty1, class Ty2>//
|
|
|
|
|
bool operator<=(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)//
|
|
|
|
|
// 定义全局函数operator<=,用于比较两个pair对象的大小//
|
|
|
|
|
{//
|
|
|
|
|
return !(rhs < lhs);//
|
|
|
|
|
// 如果rhs不小于lhs,则认为lhs小于等于rhs//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Ty1, class Ty2>//
|
|
|
|
|
bool operator>=(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)//
|
|
|
|
|
// 定义全局函数operator>=,用于比较两个pair对象的大小//
|
|
|
|
|
{//
|
|
|
|
|
return !(lhs < rhs);//
|
|
|
|
|
// 如果lhs不小于rhs,则认为lhs大于等于rhs//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Ty1, class Ty2>//
|
|
|
|
|
void swap(pair<Ty1, Ty2>& lhs, pair<Ty1, Ty2>& rhs)//
|
|
|
|
|
// 定义全局函数swap,用于交换两个pair对象的成员变量//
|
|
|
|
|
{//
|
|
|
|
|
lhs.swap(rhs);//
|
|
|
|
|
// 调用pair对象的成员函数swap进行交换//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
template <class Ty1, class Ty2>//
|
|
|
|
|
pair<Ty1, Ty2> make_pair(Ty1&& first, Ty2&& second)//
|
|
|
|
|
// 定义全局函数make_pair,用于创建pair对象//
|
|
|
|
|
{//
|
|
|
|
|
return pair<Ty1, Ty2>(mystl::forward<Ty1>(first), mystl::forward<Ty2>(second));//
|
|
|
|
|
// 使用完美转发创建pair对象并返回//
|
|
|
|
|
}//
|
|
|
|
|
//
|
|
|
|
|
} // namespace mystl//
|
|
|
|
|
//
|
|
|
|
|
#endif // MYTINYSTL_UTIL_H_//
|
|
|
|
|
// 防止头文件被重复包含的宏定义结束//
|
|
|
|
|