在文件`util.h`中,我们提供了一个名为`mystl`的命名空间,其中包含了C++标准库中`utility`头文件的简化版本。这个简化版本定义了`pair`结构体模板,它可以用来存储两个不同类型的值。我们为`pair`提供了多种构造函数,包括默认构造、拷贝构造、移动构造以及从其他类型的`pair`构造。此外,我们还提供了拷贝赋值和移动赋值运算符,以及析构函数。为了支持比较,我们重载了相等、小于、不等于等比较运算符。我们还提供了一个`swap`函数,用于交换两个`pair`对象的值,以及一个全局的`make_pair`函数,用于方便地创建`pair`对象。所有的这些功能都通过模板实现,以支持类型通用性和完美转发,确保类型安全性和效率。`

main
sunjiawei 8 months ago
parent 2275a6a510
commit ec89b4253a

@ -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_
// 结束头文件包含保护
Loading…
Cancel
Save