|
|
|
@ -1,297 +1,332 @@
|
|
|
|
|
#ifndef MYTINYSTL_UTIL_H_
|
|
|
|
|
#ifndef MYTINYSTL_UTIL_H_ // 如果MYTINYSTL_UTIL_H_没有被定义,则定义它,这是一种防止头文件重复包含的常用技术。
|
|
|
|
|
#define MYTINYSTL_UTIL_H_
|
|
|
|
|
|
|
|
|
|
// 这个文件包含一些通用工具,包括 move, forward, swap 等函数,以及 pair 等
|
|
|
|
|
|
|
|
|
|
// 包含标准库中的size_t类型
|
|
|
|
|
#include <cstddef>
|
|
|
|
|
|
|
|
|
|
// 包含自定义的类型特征头文件
|
|
|
|
|
#include "type_traits.h"
|
|
|
|
|
|
|
|
|
|
namespace mystl
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// move
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
typename std::remove_reference<T>::type&& move(T&& arg) noexcept
|
|
|
|
|
namespace mystl // 定义一个命名空间mystl,用于封装库的代码,避免命名冲突
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
// move函数模板
|
|
|
|
|
// 这个函数用于将参数转换为右值引用,以便可以使用移动语义。
|
|
|
|
|
template <class T>
|
|
|
|
|
typename std::remove_reference<T>::type&& move(T&& arg) noexcept
|
|
|
|
|
{
|
|
|
|
|
first = rhs.first;
|
|
|
|
|
second = rhs.second;
|
|
|
|
|
return static_cast<typename std::remove_reference<T>::type&&>(arg);
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// move assign for this pair
|
|
|
|
|
pair& operator=(pair&& rhs)
|
|
|
|
|
{
|
|
|
|
|
if (this != &rhs)
|
|
|
|
|
// forward函数模板
|
|
|
|
|
// 这个函数用于完美转发参数,保持参数的左值或右值性质。
|
|
|
|
|
template <class T>
|
|
|
|
|
T&& forward(typename std::remove_reference<T>::type& arg) noexcept
|
|
|
|
|
{
|
|
|
|
|
first = mystl::move(rhs.first);
|
|
|
|
|
second = mystl::move(rhs.second);
|
|
|
|
|
return static_cast<T&&>(arg);
|
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
// 另一个forward函数模板的重载
|
|
|
|
|
// 这个重载用于处理右值引用参数。
|
|
|
|
|
template <class T>
|
|
|
|
|
T&& forward(typename std::remove_reference<T>::type&& arg) noexcept
|
|
|
|
|
{
|
|
|
|
|
mystl::swap(first, other.first);
|
|
|
|
|
mystl::swap(second, other.second);
|
|
|
|
|
static_assert(!std::is_lvalue_reference<T>::value, "bad forward");
|
|
|
|
|
return static_cast<T&&>(arg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 重载比较操作符
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
// swap函数模板
|
|
|
|
|
// 这个函数用于交换两个对象的值。
|
|
|
|
|
template <class Tp>
|
|
|
|
|
void swap(Tp& lhs, Tp& rhs)
|
|
|
|
|
{
|
|
|
|
|
auto tmp(mystl::move(lhs)); // 使用move将lhs的值移动到tmp
|
|
|
|
|
lhs = mystl::move(rhs); // 将rhs的值移动到lhs
|
|
|
|
|
rhs = mystl::move(tmp); // 将tmp的值(原lhs的值)移动到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));
|
|
|
|
|
}
|
|
|
|
|
// swap_range函数模板
|
|
|
|
|
// 这个函数用于交换两个范围内的元素。
|
|
|
|
|
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; // 返回第二个范围的迭代器
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
// 另一个swap函数模板的重载
|
|
|
|
|
// 这个重载用于交换两个数组。
|
|
|
|
|
template <class Tp, size_t N>
|
|
|
|
|
void swap(Tp(&a)[N], Tp(&b)[N])
|
|
|
|
|
{
|
|
|
|
|
mystl::swap_range(a, a + N, b); // 使用swap_range函数交换数组元素
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif // !MYTINYSTL_UTIL_H_
|
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
|
// pair结构体模板
|
|
|
|
|
// 用于存储两个不同类型的值。
|
|
|
|
|
|
|
|
|
|
// pair结构体模板定义
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
struct pair
|
|
|
|
|
{
|
|
|
|
|
typedef Ty1 first_type; // 第一个元素的类型
|
|
|
|
|
typedef Ty2 second_type; // 第二个元素的类型
|
|
|
|
|
|
|
|
|
|
first_type first; // 第一个元素
|
|
|
|
|
second_type second; // 第二个元素
|
|
|
|
|
|
|
|
|
|
// 默认构造函数
|
|
|
|
|
// 如果两个类型都可以默认构造,则可以默认构造pair
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从相同类型的参数构造pair
|
|
|
|
|
// 如果两个类型都可以复制构造,并且参数可以隐式转换为目标类型,则可以隐式构造pair
|
|
|
|
|
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) // 使用参数a和b构造first和second
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从相同类型的参数显式构造pair
|
|
|
|
|
// 如果两个类型都可以复制构造,但参数不能隐式转换为目标类型,则需要显式构造pair
|
|
|
|
|
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) // 使用参数a和b构造first和second
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pair(const pair& rhs) = default; // 默认复制构造函数
|
|
|
|
|
pair(pair&& rhs) = default; // 默认移动构造函数
|
|
|
|
|
|
|
|
|
|
// 从不同类型的参数构造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(Other1&& a, Other2&& b)
|
|
|
|
|
: first(mystl::forward<Other1>(a)), // 使用forward完美转发参数a
|
|
|
|
|
second(mystl::forward<Other2>(b)) // 使用forward完美转发参数b
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从不同类型的参数显式构造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(Other1&& a, Other2&& b)
|
|
|
|
|
: first(mystl::forward<Other1>(a)), // 使用forward完美转发参数a
|
|
|
|
|
second(mystl::forward<Other2>(b)) // 使用forward完美转发参数b
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从另一个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)
|
|
|
|
|
: first(other.first), // 使用other的first构造first
|
|
|
|
|
second(other.second) // 使用other的second构造second
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从另一个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)
|
|
|
|
|
: first(other.first), // 使用other的first构造first
|
|
|
|
|
second(other.second) // 使用other的second构造second
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从另一个pair移动构造
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
// 从另一个pair显式构造
|
|
|
|
|
// 如果Other1和Other2类型可以构造Ty1和Ty2类型,并且Other1到Ty1和Other2到Ty2的转换不是隐式的,则显式构造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)
|
|
|
|
|
{
|
|
|
|
|
} // 使用other的first和second成员初始化当前对象的first和second成员
|
|
|
|
|
|
|
|
|
|
// 从另一个pair隐式构造
|
|
|
|
|
// 如果Other1和Other2类型可以构造Ty1和Ty2类型,并且Other1到Ty1和Other2到Ty2的转换是隐式的,则隐式构造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))
|
|
|
|
|
{
|
|
|
|
|
} // 使用完美转发技术将other的first和second成员转发给当前对象的构造函数
|
|
|
|
|
|
|
|
|
|
// 从另一个pair显式构造(右值引用)
|
|
|
|
|
// 如果Other1和Other2类型可以构造Ty1和Ty2类型,并且Other1到Ty1和Other2到Ty2的转换不是隐式的,则显式构造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))
|
|
|
|
|
{
|
|
|
|
|
} // 使用完美转发技术将other的first和second成员转发给当前对象的构造函数(右值引用)
|
|
|
|
|
|
|
|
|
|
// 拷贝赋值运算符
|
|
|
|
|
pair& operator=(const pair& rhs)
|
|
|
|
|
{
|
|
|
|
|
if (this != &rhs) // 检查自赋值
|
|
|
|
|
{
|
|
|
|
|
first = rhs.first; // 赋值first成员
|
|
|
|
|
second = rhs.second; // 赋值second成员
|
|
|
|
|
}
|
|
|
|
|
return *this; // 返回当前对象的引用
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 移动赋值运算符
|
|
|
|
|
pair& operator=(pair&& rhs)
|
|
|
|
|
{
|
|
|
|
|
if (this != &rhs) // 检查自赋值
|
|
|
|
|
{
|
|
|
|
|
first = mystl::move(rhs.first); // 使用move语义移动first成员
|
|
|
|
|
second = mystl::move(rhs.second); // 使用move语义移动second成员
|
|
|
|
|
}
|
|
|
|
|
return *this; // 返回当前对象的引用
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 拷贝赋值运算符(从另一个pair)
|
|
|
|
|
template <class Other1, class Other2>
|
|
|
|
|
pair& operator=(const pair<Other1, Other2>& other)
|
|
|
|
|
{
|
|
|
|
|
first = other.first; // 赋值first成员
|
|
|
|
|
second = other.second; // 赋值second成员
|
|
|
|
|
return *this; // 返回当前对象的引用
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 移动赋值运算符(从另一个pair)
|
|
|
|
|
template <class Other1, class Other2>
|
|
|
|
|
pair& operator=(pair<Other1, Other2>&& other)
|
|
|
|
|
{
|
|
|
|
|
first = mystl::forward<Other1>(other.first); // 使用完美转发技术移动first成员
|
|
|
|
|
second = mystl::forward<Other2>(other.second); // 使用完美转发技术移动second成员
|
|
|
|
|
return *this; // 返回当前对象的引用
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 默认析构函数
|
|
|
|
|
~pair() = default;
|
|
|
|
|
|
|
|
|
|
// 自定义swap函数
|
|
|
|
|
void swap(pair & other)
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
return lhs.first < rhs.first || (lhs.first == rhs.first && lhs.second < rhs.second); // 先比较first成员,如果相等再比较second成员
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重载比较运算符 !=
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator!=(const pair<Ty1, Ty2>&lhs, const pair<Ty1, Ty2>&rhs)
|
|
|
|
|
{
|
|
|
|
|
return !(lhs == rhs); // 比较两个pair是否不相等
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重载比较运算符 >
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator>(const pair<Ty1, Ty2>&lhs, const pair<Ty1, Ty2>&rhs)
|
|
|
|
|
{
|
|
|
|
|
return rhs < lhs; // 比较rhs是否小于lhs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重载比较运算符 <=
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator<=(const pair<Ty1, Ty2>&lhs, const pair<Ty1, Ty2>&rhs)
|
|
|
|
|
{
|
|
|
|
|
return !(rhs < lhs); // 比较rhs是否不小于lhs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重载比较运算符 >=
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
bool operator>=(const pair<Ty1, Ty2>&lhs, const pair<Ty1, Ty2>&rhs)
|
|
|
|
|
{
|
|
|
|
|
return !(lhs < rhs); // 比较lhs是否不小于rhs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重载mystl的swap函数
|
|
|
|
|
template <class Ty1, class Ty2>
|
|
|
|
|
void swap(pair<Ty1, Ty2>&lhs, pair<Ty1, Ty2>&rhs)
|
|
|
|
|
{
|
|
|
|
|
lhs.swap(rhs); // 使用pair的成员swap函数交换两个pair
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 全局函数,用于创建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)); // 使用完美转发技术创建pair
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // 结束命名空间mystl
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
// !MYTINYSTL_UTIL_H_
|
|
|
|
|
// 结束头文件包含保护
|