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

main
sunjiawei 8 months ago
parent 2275a6a510
commit ec89b4253a

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