|
|
|
@ -21,173 +21,195 @@ typename std::remove_reference<T>::type&& move(T&& arg) noexcept
|
|
|
|
|
// forward
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
T&& forward(typename std::remove_reference<T>::type& arg) noexcept
|
|
|
|
|
T&& forward(typename std::remove_reference<T>::type& arg) noexcept // noexcept 表示函数不会抛出异常
|
|
|
|
|
{
|
|
|
|
|
return static_cast<T&&>(arg);
|
|
|
|
|
// 使用 static_cast 将左值引用转换为 T 类型的右值引用(如果 T 是右值引用)或左值引用(如果 T 是左值引用)
|
|
|
|
|
// 这是因为 T&& 在模板中会根据 T 的实际类型(是否包含引用)表现为左值引用或右值引用
|
|
|
|
|
// 这种特性被称为“引用折叠”或“引用塌缩”
|
|
|
|
|
return static_cast<T&&>(arg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 第二个模板,用于右值引用的情况
|
|
|
|
|
template <class T>
|
|
|
|
|
T&& forward(typename std::remove_reference<T>::type&& arg) noexcept
|
|
|
|
|
T&& forward(typename std::remove_reference<T>::type&& arg) noexcept // 同样标记为 noexcept
|
|
|
|
|
{
|
|
|
|
|
static_assert(!std::is_lvalue_reference<T>::value, "bad forward");
|
|
|
|
|
return static_cast<T&&>(arg);
|
|
|
|
|
// 使用 static_assert 进行编译期检查,确保 T 不是左值引用
|
|
|
|
|
// 如果 T 是左值引用,那么这个函数模板就不应该被实例化,因为它只处理右值引用的情况
|
|
|
|
|
static_assert(!std::is_lvalue_reference<T>::value, "bad forward: T must not be an lvalue reference");
|
|
|
|
|
|
|
|
|
|
// 与第一个模板类似,使用 static_cast 将参数转换为 T 类型的引用
|
|
|
|
|
// 在这里,由于参数本身就是右值引用,所以转换后的类型也一定是右值引用
|
|
|
|
|
return static_cast<T&&>(arg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// swap
|
|
|
|
|
|
|
|
|
|
// 交换两个类型为 Tp 的对象 lhs 和 rhs 的值
|
|
|
|
|
template <class Tp>
|
|
|
|
|
void swap(Tp& lhs, Tp& rhs)
|
|
|
|
|
{
|
|
|
|
|
// 使用 mystl::move 来移动 lhs 的值到临时对象 tmp
|
|
|
|
|
// 这样做可以避免在 lhs 和 rhs 相等时的自我赋值问题
|
|
|
|
|
auto tmp(mystl::move(lhs));
|
|
|
|
|
// 将 rhs 的值移动到 lhs
|
|
|
|
|
lhs = mystl::move(rhs);
|
|
|
|
|
// 将 tmp(原 lhs 的值)移动到 rhs
|
|
|
|
|
rhs = mystl::move(tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 交换两个范围 [first1, last1) 和 [first2, first2 + (last1 - first1)) 的元素
|
|
|
|
|
template <class ForwardIter1, class ForwardIter2>
|
|
|
|
|
ForwardIter2 swap_range(ForwardIter1 first1, ForwardIter1 last1, ForwardIter2 first2)
|
|
|
|
|
{
|
|
|
|
|
// 遍历两个范围,使用 mystl::swap 交换对应的元素
|
|
|
|
|
for (; first1 != last1; ++first1, (void) ++first2)
|
|
|
|
|
mystl::swap(*first1, *first2);
|
|
|
|
|
// 返回第二个范围的末尾迭代器
|
|
|
|
|
return first2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 交换两个类型为 Tp 的数组 a 和 b,它们的大小都是 N
|
|
|
|
|
template <class Tp, size_t N>
|
|
|
|
|
void swap(Tp(&a)[N], Tp(&b)[N])
|
|
|
|
|
{
|
|
|
|
|
// 使用 swap_range 函数来交换两个数组的元素
|
|
|
|
|
mystl::swap_range(a, a + N, b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
|
// pair
|
|
|
|
|
|
|
|
|
|
// 结构体模板 : pair
|
|
|
|
|
// 两个模板参数分别表示两个数据的类型
|
|
|
|
|
// 用 first 和 second 来分别取出第一个数据和第二个数据
|
|
|
|
|
// 定义一个存储两个值的模板结构体 pair
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
struct pair
|
|
|
|
|
{
|
|
|
|
|
// 定义 pair 中两个元素的类型
|
|
|
|
|
typedef Ty1 first_type;
|
|
|
|
|
typedef Ty2 second_type;
|
|
|
|
|
|
|
|
|
|
// pair 的两个数据成员,存储两个不同类型的值
|
|
|
|
|
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()
|
|
|
|
|
// 默认构造函数,当两个类型都可以默认构造时
|
|
|
|
|
template <class U1 = Ty1, class U2 = Ty2,
|
|
|
|
|
typename std::enable_if<
|
|
|
|
|
std::is_default_constructible<U1>::value &&
|
|
|
|
|
std::is_default_constructible<U2>::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)
|
|
|
|
|
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>
|
|
|
|
|
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)
|
|
|
|
|
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>
|
|
|
|
|
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)
|
|
|
|
|
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>
|
|
|
|
|
constexpr pair(Other1&& a, Other2&& b)
|
|
|
|
|
: first(mystl::forward<Other1>(a)),
|
|
|
|
|
second(mystl::forward<Other2>(b))
|
|
|
|
|
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)
|
|
|
|
|
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>
|
|
|
|
|
explicit constexpr pair(Other1&& a, Other2&& b)
|
|
|
|
|
: first(mystl::forward<Other1>(a)),
|
|
|
|
|
second(mystl::forward<Other2>(b))
|
|
|
|
|
second(mystl::forward<Other2>(b))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// implicit constructiable for other pair
|
|
|
|
|
// 拷贝构造函数,用于从其他类型的 pair 构造当前 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)
|
|
|
|
|
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>
|
|
|
|
|
constexpr pair(const pair<Other1, Other2>& other)
|
|
|
|
|
: first(other.first),
|
|
|
|
|
second(other.second)
|
|
|
|
|
second(other.second)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// explicit constructiable for other pair
|
|
|
|
|
// 显式拷贝构造函数,用于从其他类型的 pair 构造当前 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)
|
|
|
|
|
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>
|
|
|
|
|
explicit constexpr pair(const pair<Other1, Other2>& other)
|
|
|
|
|
: first(other.first),
|
|
|
|
|
second(other.second)
|
|
|
|
|
second(other.second)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// implicit constructiable for other pair
|
|
|
|
|
// 完美转发构造函数,用于从其他类型的 pair 构造当前 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)
|
|
|
|
|
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>
|
|
|
|
|
constexpr pair(pair<Other1, Other2>&& other)
|
|
|
|
|
: first(mystl::forward<Other1>(other.first)),
|
|
|
|
|
second(mystl::forward<Other2>(other.second))
|
|
|
|
|
second(mystl::forward<Other2>(other.second))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// explicit constructiable for other pair
|
|
|
|
|
// 显式完美转发构造函数,用于从其他类型的 pair 构造当前 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)
|
|
|
|
|
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>
|
|
|
|
|
explicit constexpr pair(pair<Other1, Other2>&& other)
|
|
|
|
|
: first(mystl::forward<Other1>(other.first)),
|
|
|
|
|
second(mystl::forward<Other2>(other.second))
|
|
|
|
|
second(mystl::forward<Other2>(other.second))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// copy assign for this pair
|
|
|
|
|
// 拷贝赋值运算符,将 rhs 的值赋给当前 pair 对象
|
|
|
|
|
pair& operator=(const pair& rhs)
|
|
|
|
|
{
|
|
|
|
|
if (this != &rhs)
|
|
|
|
@ -197,6 +219,7 @@ struct pair
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// move assign for this pair
|
|
|
|
|
pair& operator=(pair&& rhs)
|
|
|
|
@ -219,71 +242,83 @@ struct pair
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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 对象的值移动到当前 pair 对象中
|
|
|
|
|
template <class Other1, class Other2>
|
|
|
|
|
pair& operator=(pair<Other1, Other2>&& other)
|
|
|
|
|
{
|
|
|
|
|
// 使用完美转发将 other 对象的第一个值移动到当前对象的第一个值
|
|
|
|
|
first = mystl::forward<Other1>(other.first);
|
|
|
|
|
// 使用完美转发将 other 对象的第二个值移动到当前对象的第二个值
|
|
|
|
|
second = mystl::forward<Other2>(other.second);
|
|
|
|
|
// 返回当前对象的引用
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~pair() = default;
|
|
|
|
|
// 析构函数,使用默认的析构函数
|
|
|
|
|
~pair() = default;
|
|
|
|
|
|
|
|
|
|
void swap(pair& other)
|
|
|
|
|
// 交换当前 pair 对象与另一个 pair 对象的值
|
|
|
|
|
void swap(pair& other)
|
|
|
|
|
{
|
|
|
|
|
// 如果两个 pair 对象不是同一个对象,则进行交换
|
|
|
|
|
if (this != &other)
|
|
|
|
|
{
|
|
|
|
|
if (this != &other)
|
|
|
|
|
{
|
|
|
|
|
mystl::swap(first, other.first);
|
|
|
|
|
mystl::swap(second, other.second);
|
|
|
|
|
}
|
|
|
|
|
// 交换第一个值
|
|
|
|
|
mystl::swap(first, other.first);
|
|
|
|
|
// 交换第二个值
|
|
|
|
|
mystl::swap(second, other.second);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重载比较操作符
|
|
|
|
|
// 比较两个 pair 对象是否相等
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator==(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)
|
|
|
|
|
{
|
|
|
|
|
// 如果两个 pair 对象的第一个元素和第二个元素都相等,则返回 true
|
|
|
|
|
return lhs.first == rhs.first && lhs.second == rhs.second;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 比较两个 pair 对象的大小
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator<(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)
|
|
|
|
|
{
|
|
|
|
|
// 如果第一个元素小于 rhs 的第一个元素,或者第一个元素相等且第二个元素小于 rhs 的第二个元素,则返回 true
|
|
|
|
|
return lhs.first < rhs.first || (lhs.first == rhs.first && lhs.second < rhs.second);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 比较两个 pair 对象是否不相等
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator!=(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)
|
|
|
|
|
{
|
|
|
|
|
// 如果两个 pair 对象不相等,则返回 true
|
|
|
|
|
return !(lhs == rhs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 比较两个 pair 对象的大小,反向比较
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator>(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)
|
|
|
|
|
{
|
|
|
|
|
// 如果 rhs 对象小于 lhs 对象,则返回 true
|
|
|
|
|
return rhs < lhs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 比较两个 pair 对象的大小,反向比较小于或等于
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator<=(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)
|
|
|
|
|
{
|
|
|
|
|
// 如果 rhs 对象小于 lhs 对象,则返回 false,否则返回 true
|
|
|
|
|
return !(rhs < lhs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 比较两个 pair 对象的大小,反向比较大于或等于
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator>=(const pair<Ty1, Ty2>& lhs, const pair<Ty1, Ty2>& rhs)
|
|
|
|
|
{
|
|
|
|
|
// 如果 lhs 对象小于 rhs 对象,则返回 false,否则返回 true
|
|
|
|
|
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)
|
|
|
|
|