diff --git a/MyTinySTL b/MyTinySTL
deleted file mode 160000
index 4ed9c76..0000000
--- a/MyTinySTL
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 4ed9c7641c9989f8d79c0b86c89327d5e987f610
diff --git a/MyTinySTL/README.md b/MyTinySTL/README.md
new file mode 100644
index 0000000..fb400ca
--- /dev/null
+++ b/MyTinySTL/README.md
@@ -0,0 +1,2 @@
+# https://bdgit.educoder.net/pfuc5ij8g/ciallo.git
+
diff --git a/MyTinySTL/doc/MyTinySTL+泛读报告.docx b/MyTinySTL/doc/MyTinySTL+泛读报告.docx
new file mode 100644
index 0000000..480511d
Binary files /dev/null and b/MyTinySTL/doc/MyTinySTL+泛读报告.docx differ
diff --git a/MyTinySTL/doc/MyTinySTL.png b/MyTinySTL/doc/MyTinySTL.png
new file mode 100644
index 0000000..2a2b57f
Binary files /dev/null and b/MyTinySTL/doc/MyTinySTL.png differ
diff --git a/MyTinySTL/src/MyTinySTL-master.zip b/MyTinySTL/src/MyTinySTL-master.zip
new file mode 100644
index 0000000..4939220
Binary files /dev/null and b/MyTinySTL/src/MyTinySTL-master.zip differ
diff --git a/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/.gitattributes b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/.gitignore b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/.gitignore
new file mode 100644
index 0000000..9de2987
--- /dev/null
+++ b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/.gitignore
@@ -0,0 +1,253 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# Local build files
+*c.cmd
+*a.exe
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+[Xx]64/
+[Xx]86/
+[Bb]uild/
+bld/
+[Bb]in/
+[Oo]bj/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+
+# Visual Studio Code
+.vscode/
+
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+
+# TODO: Un-comment the next line if you do not want to checkin
+# your web deploy settings because they may include unencrypted
+# passwords
+#*.pubxml
+*.publishproj
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Microsoft Azure ApplicationInsights config file
+ApplicationInsights.config
+
+# Windows Store app package directory
+AppPackages/
+BundleArtifacts/
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# LightSwitch generated files
+GeneratedArtifacts/
+ModelManifest.xml
+
+# Paket dependency manager
+.paket/paket.exe
+
+# FAKE - F# Make
+.fake/
diff --git a/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/.travis.yml b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/.travis.yml
new file mode 100644
index 0000000..b83ac2a
--- /dev/null
+++ b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/.travis.yml
@@ -0,0 +1,72 @@
+language: cpp
+
+# ubuntu 14.04 version
+sudo: required
+dist: trusty
+
+matrix:
+ include:
+ - os: linux
+ compiler: gcc
+ addons:
+ apt:
+ sources: ['ubuntu-toolchain-r-test']
+ packages: ['g++-5']
+ env:
+ - MATRIX_EVAL="CC=gcc-5 && CXX=g++-5"
+
+ - os: linux
+ compiler: gcc
+ addons:
+ apt:
+ sources: ['ubuntu-toolchain-r-test']
+ packages: ['g++-6']
+ env:
+ - MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
+
+ - os: linux
+ compiler: gcc
+ addons:
+ apt:
+ sources: ['ubuntu-toolchain-r-test']
+ packages: ['g++-7']
+ env:
+ - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
+
+ - os: osx
+ osx_image: xcode5
+ env:
+ - MATRIX_EVAL="CC=clang && CXX=clang++"
+
+ - os: osx
+ osx_image: xcode6
+ env:
+ - MATRIX_EVAL="CC=clang && CXX=clang++"
+
+ - os: osx
+ osx_image: xcode7
+ env:
+ - MATRIX_EVAL="CC=clang && CXX=clang++"
+
+ - os: osx
+ osx_image: xcode8
+ env:
+ - MATRIX_EVAL="CC=clang && CXX=clang++"
+
+
+before_script:
+ - eval "${MATRIX_EVAL}"
+ - $CXX --version
+
+script:
+ - mkdir build && cd ./build
+ - cmake ..
+ - make
+ - cd ../bin && ./stltest
+
+branches:
+ only:
+ - master
+
+notifications:
+ email: false
diff --git a/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/CMakeLists.txt b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/CMakeLists.txt
new file mode 100644
index 0000000..e4c8662
--- /dev/null
+++ b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/CMakeLists.txt
@@ -0,0 +1,35 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(MyTinySTL)
+
+# version
+set(MyTinySTL_VERSION_MAJOR 2)
+set(MyTinySTL_VERSION_MINOR 0)
+set(MyTinySTL_VERSION_PATCH 0)
+set(MyTinySTL_VERSION "${MyTinySTL_VERSION_MAJOR}.${MyTinySTL_VERSION_MINOR}.${MyTinySTL_VERSION_PATCH}")
+message(STATUS "The version of this project is: ${MyTinySTL_VERSION}")
+
+# build type
+set(CMAKE_BUILD_TYPE release)
+
+if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wall -Wextra -Wno-sign-compare -Wno-unused-but-set-variable -Wno-array-bounds")
+ # set(EXTRA_CXX_FLAGS -Weffc++ -Wswitch-default -Wfloat-equal -Wconversion -Wsign-conversion)
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0.0")
+ message(FATAL_ERROR "required GCC 5.0 or later")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ endif()
+elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wall -Wextra -Wno-sign-compare")
+ # set(EXTRA_CXX_FLAGS -Weffc++ -Wswitch-default -Wfloat-equal -Wconversion -Wimplicit-fallthrough)
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.5.0")
+ message(FATAL_ERROR "required Clang 3.5 or later")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ endif()
+endif()
+
+message(STATUS "The cmake_cxx_flags is: ${CMAKE_CXX_FLAGS}")
+
+add_subdirectory(${PROJECT_SOURCE_DIR}/Test)
diff --git a/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/License.txt b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/License.txt
new file mode 100644
index 0000000..aef65ba
--- /dev/null
+++ b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/License.txt
@@ -0,0 +1,11 @@
+Copyright (c) 2016-2017 Alinshans. All rights reserved.
+
+First published on github, see https://github.com/Alinshans/MyTinySTL
+
+The MyTinySTL source code is licensed under the MIT License.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MSVC/MyTinySTL_VS2015.sln b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MSVC/MyTinySTL_VS2015.sln
new file mode 100644
index 0000000..8c22749
--- /dev/null
+++ b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MSVC/MyTinySTL_VS2015.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyTinySTL", "MyTinySTL_VS2015.vcxproj", "{E88807F6-B07C-4371-BD38-FB1569F894E4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E88807F6-B07C-4371-BD38-FB1569F894E4}.Debug|x64.ActiveCfg = Debug|x64
+ {E88807F6-B07C-4371-BD38-FB1569F894E4}.Debug|x64.Build.0 = Debug|x64
+ {E88807F6-B07C-4371-BD38-FB1569F894E4}.Debug|x86.ActiveCfg = Debug|Win32
+ {E88807F6-B07C-4371-BD38-FB1569F894E4}.Debug|x86.Build.0 = Debug|Win32
+ {E88807F6-B07C-4371-BD38-FB1569F894E4}.Release|x64.ActiveCfg = Release|x64
+ {E88807F6-B07C-4371-BD38-FB1569F894E4}.Release|x64.Build.0 = Release|x64
+ {E88807F6-B07C-4371-BD38-FB1569F894E4}.Release|x86.ActiveCfg = Release|Win32
+ {E88807F6-B07C-4371-BD38-FB1569F894E4}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MSVC/MyTinySTL_VS2015.vcxproj b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MSVC/MyTinySTL_VS2015.vcxproj
new file mode 100644
index 0000000..aa70a5e
--- /dev/null
+++ b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MSVC/MyTinySTL_VS2015.vcxproj
@@ -0,0 +1,201 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {E88807F6-B07C-4371-BD38-FB1569F894E4}
+ Win32Proj
+ MyTinySTL
+ 8.1
+ MyTinySTL
+
+
+
+ Application
+ true
+ v140
+ Unicode
+
+
+ Application
+ false
+ v140
+ true
+ Unicode
+
+
+ Application
+ true
+ v140
+ Unicode
+
+
+ Application
+ false
+ v140
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+
+
+ Level4
+ Disabled
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MSVC/MyTinySTL_VS2015.vcxproj.filters b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MSVC/MyTinySTL_VS2015.vcxproj.filters
new file mode 100644
index 0000000..aea4c50
--- /dev/null
+++ b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MSVC/MyTinySTL_VS2015.vcxproj.filters
@@ -0,0 +1,162 @@
+
+
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {ec314ff3-dcde-4cac-a63a-4f6827750d0a}
+
+
+ {c6f24d77-e6f0-439e-954a-c0ca577689d5}
+
+
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+ test
+
+
+ test
+
+
+ test
+
+
+ test
+
+
+ test
+
+
+ test
+
+
+ test
+
+
+ test
+
+
+ test
+
+
+ test
+
+
+ test
+
+
+ test
+
+
+ test
+
+
+ test\Lib
+
+
+ test\Lib
+
+
+ include
+
+
+ include
+
+
+ include
+
+
+
+
+ test
+
+
+
\ No newline at end of file
diff --git a/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/algo.h b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/algo.h
new file mode 100644
index 0000000..b9d9660
--- /dev/null
+++ b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/algo.h
@@ -0,0 +1,2744 @@
+#ifndef MYTINYSTL_ALGO_H_
+#define MYTINYSTL_ALGO_H_
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4244)
+#endif
+
+// 这个头文件包含了 mystl 的一系列算法
+
+#include
+#include
+
+#include "algobase.h"
+#include "memory.h"
+#include "heap_algo.h"
+#include "functional.h"
+
+namespace mystl
+{
+
+/*****************************************************************************************/
+// all_of
+// 检查[first, last)内是否全部元素都满足一元操作 unary_pred 为 true 的情况,满足则返回 true
+/*****************************************************************************************/
+template
+bool all_of(InputIter first, InputIter last, UnaryPredicate unary_pred)
+{
+ for (; first != last; ++first)
+ {
+ if (!unary_pred(*first))
+ return false;
+ }
+ return true;
+}
+
+/*****************************************************************************************/
+// any_of
+// 检查[first, last)内是否存在某个元素满足一元操作 unary_pred 为 true 的情况,满足则返回 true
+/*****************************************************************************************/
+template
+bool any_of(InputIter first, InputIter last, UnaryPredicate unary_pred)
+{
+ for (; first != last; ++first)
+ {
+ if (unary_pred(*first))
+ return true;
+ }
+ return false;
+}
+
+/*****************************************************************************************/
+// none_of
+// 检查[first, last)内是否全部元素都不满足一元操作 unary_pred 为 true 的情况,满足则返回 true
+/*****************************************************************************************/
+template
+bool none_of(InputIter first, InputIter last, UnaryPredicate unary_pred)
+{
+ for (; first != last; ++first)
+ {
+ if (unary_pred(*first))
+ return false;
+ }
+ return true;
+}
+
+/*****************************************************************************************/
+// count
+// 对[first, last)区间内的元素与给定值进行比较,缺省使用 operator==,返回元素相等的个数
+/*****************************************************************************************/
+template
+size_t count(InputIter first, InputIter last, const T& value)
+{
+ size_t n = 0;
+ for (; first != last; ++first)
+ {
+ if (*first == value)
+ ++n;
+ }
+ return n;
+}
+
+/*****************************************************************************************/
+// count_if
+// 对[first, last)区间内的每个元素都进行一元 unary_pred 操作,返回结果为 true 的个数
+/*****************************************************************************************/
+template
+size_t count_if(InputIter first, InputIter last, UnaryPredicate unary_pred)
+{
+ size_t n = 0;
+ for (; first != last; ++first)
+ {
+ if (unary_pred(*first))
+ ++n;
+ }
+ return n;
+}
+
+/*****************************************************************************************/
+// find
+// 在[first, last)区间内找到等于 value 的元素,返回指向该元素的迭代器
+/*****************************************************************************************/
+template
+InputIter
+find(InputIter first, InputIter last, const T& value)
+{
+ while (first != last && *first != value)
+ ++first;
+ return first;
+}
+
+/*****************************************************************************************/
+// find_if
+// 在[first, last)区间内找到第一个令一元操作 unary_pred 为 true 的元素并返回指向该元素的迭代器
+/*****************************************************************************************/
+template
+InputIter
+find_if(InputIter first, InputIter last, UnaryPredicate unary_pred)
+{
+ while (first != last && !unary_pred(*first))
+ ++first;
+ return first;
+}
+
+/*****************************************************************************************/
+// find_if_not
+// 在[first, last)区间内找到第一个令一元操作 unary_pred 为 false 的元素并返回指向该元素的迭代器
+/*****************************************************************************************/
+template
+InputIter
+find_if_not(InputIter first, InputIter last, UnaryPredicate unary_pred)
+{
+ while (first != last && unary_pred(*first))
+ ++first;
+ return first;
+}
+
+/*****************************************************************************************/
+// search
+// 在[first1, last1)中查找[first2, last2)的首次出现点
+/*****************************************************************************************/
+template
+ForwardIter1
+search(ForwardIter1 first1, ForwardIter1 last1,
+ ForwardIter2 first2, ForwardIter2 last2)
+{
+ auto d1 = mystl::distance(first1, last1);
+ auto d2 = mystl::distance(first2, last2);
+ if (d1 < d2)
+ return last1;
+ auto current1 = first1;
+ auto current2 = first2;
+ while (current2 != last2)
+ {
+ if (*current1 == *current2)
+ {
+ ++current1;
+ ++current2;
+ }
+ else
+ {
+ if (d1 == d2)
+ {
+ return last1;
+ }
+ else
+ {
+ current1 = ++first1;
+ current2 = first2;
+ --d1;
+ }
+ }
+ }
+ return first1;
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+ForwardIter1
+search(ForwardIter1 first1, ForwardIter1 last1,
+ ForwardIter2 first2, ForwardIter2 last2, Compared comp)
+{
+ auto d1 = mystl::distance(first1, last1);
+ auto d2 = mystl::distance(first2, last2);
+ if (d1 < d2)
+ return last1;
+ auto current1 = first1;
+ auto current2 = first2;
+ while (current2 != last2)
+ {
+ if (comp(*current1, *current2))
+ {
+ ++current1;
+ ++current2;
+ }
+ else
+ {
+ if (d1 == d2)
+ {
+ return last1;
+ }
+ else
+ {
+ current1 = ++first1;
+ current2 = first2;
+ --d1;
+ }
+ }
+ }
+ return first1;
+}
+
+/*****************************************************************************************/
+// search_n
+// 在[first, last)中查找连续 n 个 value 所形成的子序列,返回一个迭代器指向该子序列的起始处
+/*****************************************************************************************/
+template
+ForwardIter
+search_n(ForwardIter first, ForwardIter last, Size n, const T& value)
+{
+ if (n <= 0)
+ {
+ return first;
+ }
+ else
+ {
+ first = mystl::find(first, last, value);
+ while (first != last)
+ {
+ auto m = n - 1;
+ auto i = first;
+ ++i;
+ while (i != last && m != 0 && *i == value)
+ {
+ ++i;
+ --m;
+ }
+ if (m == 0)
+ {
+ return first;
+ }
+ else
+ {
+ first = mystl::find(i, last, value);
+ }
+ }
+ return last;
+ }
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+ForwardIter
+search_n(ForwardIter first, ForwardIter last,
+ Size n, const T& value, Compared comp)
+{
+ if (n <= 0)
+ {
+ return first;
+ }
+ else
+ {
+ while (first != last)
+ {
+ if (comp(*first, value))
+ break;
+ ++first;
+ }
+ while (first != last)
+ {
+ auto m = n - 1;
+ auto i = first;
+ ++i;
+ while (i != last && m != 0 && comp(*i, value))
+ {
+ ++i;
+ --m;
+ }
+ if (m == 0)
+ {
+ return first;
+ }
+ else
+ {
+ while (i != last)
+ {
+ if (comp(*i, value))
+ break;
+ ++i;
+ }
+ first = i;
+ }
+ }
+ return last;
+ }
+}
+
+/*****************************************************************************************/
+// find_end
+// 在[first1, last1)区间中查找[first2, last2)最后一次出现的地方,若不存在返回 last1
+/*****************************************************************************************/
+// find_end_dispatch 的 forward_iterator_tag 版本
+template
+ForwardIter1
+find_end_dispatch(ForwardIter1 first1, ForwardIter1 last1,
+ ForwardIter2 first2, ForwardIter2 last2,
+ forward_iterator_tag, forward_iterator_tag)
+{
+ if (first2 == last2)
+ {
+ return last1;
+ }
+ else
+ {
+ auto result = last1;
+ while (true)
+ {
+ // 利用 search 查找某个子序列的首次出现点,找不到则返回 last1
+ auto new_result = mystl::search(first1, last1, first2, last2);
+ if (new_result == last1)
+ {
+ return result;
+ }
+ else
+ {
+ result = new_result;
+ first1 = new_result;
+ ++first1;
+ }
+ }
+ }
+}
+
+// find_end_dispatch 的 bidirectional_iterator_tag 版本
+template
+BidirectionalIter1
+find_end_dispatch(BidirectionalIter1 first1, BidirectionalIter1 last1,
+ BidirectionalIter2 first2, BidirectionalIter2 last2,
+ bidirectional_iterator_tag, bidirectional_iterator_tag)
+{
+ typedef reverse_iterator reviter1;
+ typedef reverse_iterator reviter2;
+ reviter1 rlast1(first1);
+ reviter2 rlast2(first2);
+ reviter1 rresult = mystl::search(reviter1(last1), rlast1, reviter2(last2), rlast2);
+ if (rresult == rlast1)
+ {
+ return last1;
+ }
+ else
+ {
+ auto result = rresult.base();
+ mystl::advance(result, -mystl::distance(first2, last2));
+ return result;
+ }
+}
+
+template
+ForwardIter1
+find_end(ForwardIter1 first1, ForwardIter1 last1,
+ ForwardIter2 first2, ForwardIter2 last2)
+{
+ typedef typename iterator_traits::iterator_category Category1;
+ typedef typename iterator_traits::iterator_category Category2;
+ return mystl::find_end_dispatch(first1, last1, first2, last2, Category1(), Category2());
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+// find_end_dispatch 的 forward_iterator_tag 版本
+template
+ForwardIter1
+find_end_dispatch(ForwardIter1 first1, ForwardIter1 last1,
+ ForwardIter2 first2, ForwardIter2 last2,
+ forward_iterator_tag, forward_iterator_tag, Compared comp)
+{
+ if (first2 == last2)
+ {
+ return last1;
+ }
+ else
+ {
+ auto result = last1;
+ while (true)
+ {
+ // 利用 search 查找某个子序列的首次出现点,找不到则返回 last1
+ auto new_result = mystl::search(first1, last1, first2, last2, comp);
+ if (new_result == last1)
+ {
+ return result;
+ }
+ else
+ {
+ result = new_result;
+ first1 = new_result;
+ ++first1;
+ }
+ }
+ }
+}
+
+// find_end_dispatch 的 bidirectional_iterator_tag 版本
+template
+BidirectionalIter1
+find_end_dispatch(BidirectionalIter1 first1, BidirectionalIter1 last1,
+ BidirectionalIter2 first2, BidirectionalIter2 last2,
+ bidirectional_iterator_tag, bidirectional_iterator_tag, Compared comp)
+{
+ typedef reverse_iterator reviter1;
+ typedef reverse_iterator reviter2;
+ reviter1 rlast1(first1);
+ reviter2 rlast2(first2);
+ reviter1 rresult = mystl::search(reviter1(last1), rlast1, reviter2(last2), rlast2, comp);
+ if (rresult == rlast1)
+ {
+ return last1;
+ }
+ else
+ {
+ auto result = rresult.base();
+ mystl::advance(result, -mystl::distance(first2, last2));
+ return result;
+ }
+}
+
+template
+ForwardIter1
+find_end(ForwardIter1 first1, ForwardIter1 last1,
+ ForwardIter2 first2, ForwardIter2 last2, Compared comp)
+{
+ typedef typename iterator_traits::iterator_category Category1;
+ typedef typename iterator_traits::iterator_category Category2;
+ return mystl::find_end_dispatch(first1, last1, first2, last2, Category1(), Category2(), comp);
+}
+
+/*****************************************************************************************/
+// find_first_of
+// 在[first1, last1)中查找[first2, last2)中的某些元素,返回指向第一次出现的元素的迭代器
+/*****************************************************************************************/
+template
+InputIter
+find_first_of(InputIter first1, InputIter last1,
+ ForwardIter first2, ForwardIter last2)
+{
+ for (; first1 != last1; ++first1)
+ {
+ for (auto iter = first2; iter != last2; ++iter)
+ {
+ if (*first1 == *iter)
+ return first1;
+ }
+ }
+ return last1;
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+InputIter
+find_first_of(InputIter first1, InputIter last1,
+ ForwardIter first2, ForwardIter last2, Compared comp)
+{
+ for (; first1 != last1; ++first1)
+ {
+ for (auto iter = first2; iter != last2; ++iter)
+ {
+ if (comp(*first1, *iter))
+ return first1;
+ }
+ }
+ return last1;
+}
+
+/*****************************************************************************************/
+// for_each
+// 使用一个函数对象 f 对[first, last)区间内的每个元素执行一个 operator() 操作,但不能改变元素内容
+// f() 可返回一个值,但该值会被忽略
+/*****************************************************************************************/
+template
+Function for_each(InputIter first, InputIter last, Function f)
+{
+ for (; first != last; ++first)
+ {
+ f(*first);
+ }
+ return f;
+}
+
+/*****************************************************************************************/
+// adjacent_find
+// 找出第一对匹配的相邻元素,缺省使用 operator== 比较,如果找到返回一个迭代器,指向这对元素的第一个元素
+/*****************************************************************************************/
+template
+ForwardIter adjacent_find(ForwardIter first, ForwardIter last)
+{
+ if (first == last) return last;
+ auto next = first;
+ while (++next != last)
+ {
+ if (*first == *next) return first;
+ first = next;
+ }
+ return last;
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+ForwardIter adjacent_find(ForwardIter first, ForwardIter last, Compared comp)
+{
+ if (first == last) return last;
+ auto next = first;
+ while (++next != last)
+ {
+ if (comp(*first, *next)) return first;
+ first = next;
+ }
+ return last;
+}
+
+/*****************************************************************************************/
+// lower_bound
+// 在[first, last)中查找第一个不小于 value 的元素,并返回指向它的迭代器,若没有则返回 last
+/*****************************************************************************************/
+// lbound_dispatch 的 forward_iterator_tag 版本
+template
+ForwardIter
+lbound_dispatch(ForwardIter first, ForwardIter last,
+ const T& value, forward_iterator_tag)
+{
+ auto len = mystl::distance(first, last);
+ auto half = len;
+ ForwardIter middle;
+ while (len > 0)
+ {
+ half = len >> 1;
+ middle = first;
+ mystl::advance(middle, half);
+ if (*middle < value)
+ {
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ }
+ else
+ {
+ len = half;
+ }
+ }
+ return first;
+}
+
+// lbound_dispatch 的 random_access_iterator_tag 版本
+template
+RandomIter
+lbound_dispatch(RandomIter first, RandomIter last,
+ const T& value, random_access_iterator_tag)
+{
+ auto len = last - first;
+ auto half = len;
+ RandomIter middle;
+ while (len > 0)
+ {
+ half = len >> 1;
+ middle = first + half;
+ if (*middle < value)
+ {
+ first = middle + 1;
+ len = len - half - 1;
+ }
+ else
+ {
+ len = half;
+ }
+ }
+ return first;
+}
+
+template
+ForwardIter
+lower_bound(ForwardIter first, ForwardIter last, const T& value)
+{
+ return mystl::lbound_dispatch(first, last, value, iterator_category(first));
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+// lbound_dispatch 的 forward_iterator_tag 版本
+template
+ForwardIter
+lbound_dispatch(ForwardIter first, ForwardIter last,
+ const T& value, forward_iterator_tag, Compared comp)
+{
+ auto len = mystl::distance(first, last);
+ auto half = len;
+ ForwardIter middle;
+ while (len > 0)
+ {
+ half = len >> 1;
+ middle = first;
+ mystl::advance(middle, half);
+ if (comp(*middle, value))
+ {
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ }
+ else
+ {
+ len = half;
+ }
+ }
+ return first;
+}
+
+// lbound_dispatch 的 random_access_iterator_tag 版本
+template
+RandomIter
+lbound_dispatch(RandomIter first, RandomIter last,
+ const T& value, random_access_iterator_tag, Compared comp)
+{
+ auto len = last - first;
+ auto half = len;
+ RandomIter middle;
+ while (len > 0)
+ {
+ half = len >> 1;
+ middle = first + half;
+ if (comp(*middle, value))
+ {
+ first = middle + 1;
+ len = len - half - 1;
+ }
+ else
+ {
+ len = half;
+ }
+ }
+ return first;
+}
+
+template
+ForwardIter
+lower_bound(ForwardIter first, ForwardIter last, const T& value, Compared comp)
+{
+ return mystl::lbound_dispatch(first, last, value, iterator_category(first), comp);
+}
+
+/*****************************************************************************************/
+// upper_bound
+// 在[first, last)中查找第一个大于value 的元素,并返回指向它的迭代器,若没有则返回 last
+/*****************************************************************************************/
+// ubound_dispatch 的 forward_iterator_tag 版本
+template
+ForwardIter
+ubound_dispatch(ForwardIter first, ForwardIter last,
+ const T& value, forward_iterator_tag)
+{
+ auto len = mystl::distance(first, last);
+ auto half = len;
+ ForwardIter middle;
+ while (len > 0)
+ {
+ half = len >> 1;
+ middle = first;
+ mystl::advance(middle, half);
+ if (value < *middle)
+ {
+ len = half;
+ }
+ else
+ {
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ }
+ }
+ return first;
+}
+
+// ubound_dispatch 的 random_access_iterator_tag 版本
+template
+RandomIter
+ubound_dispatch(RandomIter first, RandomIter last,
+ const T& value, random_access_iterator_tag)
+{
+ auto len = last - first;
+ auto half = len;
+ RandomIter middle;
+ while (len > 0)
+ {
+ half = len >> 1;
+ middle = first + half;
+ if (value < *middle)
+ {
+ len = half;
+ }
+ else
+ {
+ first = middle + 1;
+ len = len - half - 1;
+ }
+ }
+ return first;
+}
+
+template
+ForwardIter
+upper_bound(ForwardIter first, ForwardIter last, const T& value)
+{
+ return mystl::ubound_dispatch(first, last, value, iterator_category(first));
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+// ubound_dispatch 的 forward_iterator_tag 版本
+template
+ForwardIter
+ubound_dispatch(ForwardIter first, ForwardIter last,
+ const T& value, forward_iterator_tag, Compared comp)
+{
+ auto len = mystl::distance(first, last);
+ auto half = len;
+ ForwardIter middle;
+ while (len > 0)
+ {
+ half = len >> 1;
+ middle = first;
+ mystl::advance(middle, half);
+ if (comp(value, *middle))
+ {
+ len = half;
+ }
+ else
+ {
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ }
+ }
+ return first;
+}
+
+// ubound_dispatch 的 random_access_iterator_tag 版本
+template
+RandomIter
+ubound_dispatch(RandomIter first, RandomIter last,
+ const T& value, random_access_iterator_tag, Compared comp)
+{
+ auto len = last - first;
+ auto half = len;
+ RandomIter middle;
+ while (len > 0)
+ {
+ half = len >> 1;
+ middle = first + half;
+ if (comp(value, *middle))
+ {
+ len = half;
+ }
+ else
+ {
+ first = middle + 1;
+ len = len - half - 1;
+ }
+ }
+ return first;
+}
+
+template
+ForwardIter
+upper_bound(ForwardIter first, ForwardIter last, const T& value, Compared comp)
+{
+ return mystl::ubound_dispatch(first, last, value, iterator_category(first), comp);
+}
+
+/*****************************************************************************************/
+// binary_search
+// 二分查找,如果在[first, last)内有等同于 value 的元素,返回 true,否则返回 false
+/*****************************************************************************************/
+template
+bool binary_search(ForwardIter first, ForwardIter last, const T& value)
+{
+ auto i = mystl::lower_bound(first, last, value);
+ return i != last && !(value < *i);
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+bool binary_search(ForwardIter first, ForwardIter last, const T& value, Compared comp)
+{
+ auto i = mystl::lower_bound(first, last, value);
+ return i != last && !comp(value, *i);
+}
+
+/*****************************************************************************************/
+// equal_range
+// 查找[first,last)区间中与 value 相等的元素所形成的区间,返回一对迭代器指向区间首尾
+// 第一个迭代器指向第一个不小于 value 的元素,第二个迭代器指向第一个大于 value 的元素
+/*****************************************************************************************/
+// erange_dispatch 的 forward_iterator_tag 版本
+template
+mystl::pair
+erange_dispatch(ForwardIter first, ForwardIter last,
+ const T& value, forward_iterator_tag)
+{
+ auto len = mystl::distance(first, last);
+ auto half = len;
+ ForwardIter middle, left, right;
+ while (len > 0)
+ {
+ half = len >> 1;
+ middle = first;
+ mystl::advance(middle, half);
+ if (*middle < value)
+ {
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ }
+ else if (value < *middle)
+ {
+ len = half;
+ }
+ else
+ {
+ left = mystl::lower_bound(first, last, value);
+ mystl::advance(first, len);
+ right = mystl::upper_bound(++middle, first, value);
+ return mystl::pair(left, right);
+ }
+ }
+ return mystl::pair(last, last);
+}
+
+// erange_dispatch 的 random_access_iterator_tag 版本
+template
+mystl::pair
+erange_dispatch(RandomIter first, RandomIter last,
+ const T& value, random_access_iterator_tag)
+{
+ auto len = last - first;
+ auto half = len;
+ RandomIter middle, left, right;
+ while (len > 0)
+ {
+ half = len >> 1;
+ middle = first + half;
+ if (*middle < value)
+ {
+ first = middle + 1;
+ len = len - half - 1;
+ }
+ else if (value < *middle)
+ {
+ len = half;
+ }
+ else
+ {
+ left = mystl::lower_bound(first, middle, value);
+ right = mystl::upper_bound(++middle, first + len, value);
+ return mystl::pair(left, right);
+ }
+ }
+ return mystl::pair(last, last);
+}
+
+template
+mystl::pair
+equal_range(ForwardIter first, ForwardIter last, const T& value)
+{
+ return mystl::erange_dispatch(first, last, value, iterator_category(first));
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+// erange_dispatch 的 forward iterator 版本
+template
+mystl::pair
+erange_dispatch(ForwardIter first, ForwardIter last,
+ const T& value, forward_iterator_tag, Compared comp)
+{
+ auto len = mystl::distance(first, last);
+ auto half = len;
+ ForwardIter middle, left, right;
+ while (len > 0)
+ {
+ half = len >> 1;
+ middle = first;
+ mystl::advance(middle, half);
+ if (comp(*middle, value))
+ {
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ }
+ else if (comp(value, *middle))
+ {
+ len = half;
+ }
+ else
+ {
+ left = mystl::lower_bound(first, last, value, comp);
+ mystl::advance(first, len);
+ right = mystl::upper_bound(++middle, first, value, comp);
+ return mystl::pair(left, right);
+ }
+ }
+ return mystl::pair(last, last);
+}
+
+// erange_dispatch 的 random access iterator 版本
+template
+mystl::pair
+erange_dispatch(RandomIter first, RandomIter last,
+ const T& value, random_access_iterator_tag, Compared comp)
+{
+ auto len = last - first;
+ auto half = len;
+ RandomIter middle, left, right;
+ while (len > 0)
+ {
+ half = len >> 1;
+ middle = first + half;
+ if (comp(*middle, value))
+ {
+ first = middle + 1;
+ len = len - half - 1;
+ }
+ else if (comp(value, *middle))
+ {
+ len = half;
+ }
+ else
+ {
+ left = mystl::lower_bound(first, middle, value, comp);
+ right = mystl::upper_bound(++middle, first + len, value, comp);
+ return mystl::pair(left, right);
+ }
+ }
+ return mystl::pair(last, last);
+}
+
+template
+mystl::pair
+equal_range(ForwardIter first, ForwardIter last, const T& value, Compared comp)
+{
+ return mystl::erange_dispatch(first, last, value, iterator_category(first), comp);
+}
+
+/*****************************************************************************************/
+// generate
+// 将函数对象 gen 的运算结果对[first, last)内的每个元素赋值
+/*****************************************************************************************/
+template
+void generate(ForwardIter first, ForwardIter last, Generator gen)
+{
+ for (; first != last; ++first)
+ {
+ *first = gen();
+ }
+}
+
+/*****************************************************************************************/
+// generate_n
+// 用函数对象 gen 连续对 n 个元素赋值
+/*****************************************************************************************/
+template
+void generate_n(ForwardIter first, Size n, Generator gen)
+{
+ for (; n > 0; --n, ++first)
+ {
+ *first = gen();
+ }
+}
+
+/*****************************************************************************************/
+// includes
+// 判断序列一S1 是否包含序列二S2
+/*****************************************************************************************/
+template
+bool includes(InputIter1 first1, InputIter1 last1,
+ InputIter2 first2, InputIter2 last2)
+{
+ while (first1 != last1 && first2 != last2)
+ {
+ if (*first2 < *first1)
+ {
+ return false;
+ }
+ else if (*first1 < *first2)
+ {
+ ++first1;
+ }
+ else
+ {
+ ++first1, ++first2;
+ }
+ }
+ return first2 == last2;
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+bool includes(InputIter1 first1, InputIter1 last1,
+ InputIter2 first2, InputIter2 last2, Compared comp)
+{
+ while (first1 != last1 && first2 != last2)
+ {
+ if (comp(*first2, *first1))
+ {
+ return false;
+ }
+ else if (comp(*first1, *first2))
+ {
+ ++first1;
+ }
+ else
+ {
+ ++first1, ++first2;
+ }
+ }
+ return first2 == last2;
+}
+
+/*****************************************************************************************/
+// is_heap
+// 检查[first, last)内的元素是否为一个堆,如果是,则返回 true
+/*****************************************************************************************/
+template
+bool is_heap(RandomIter first, RandomIter last)
+{
+ auto n = mystl::distance(first, last);
+ auto parent = 0;
+ for (auto child = 1; child < n; ++child)
+ {
+ if (first[parent] < first[child])
+ return false;
+ if ((child & 1) == 0)
+ ++parent;
+ }
+ return true;
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+bool is_heap(RandomIter first, RandomIter last, Compared comp)
+{
+ auto n = mystl::distance(first, last);
+ auto parent = 0;
+ for (auto child = 1; child < n; ++child)
+ {
+ if (comp(first[parent], first[child]))
+ return false;
+ if ((child & 1) == 0)
+ ++parent;
+ }
+ return true;
+}
+
+/*****************************************************************************************/
+// is_sorted
+// 检查[first, last)内的元素是否升序,如果是升序,则返回 true
+/*****************************************************************************************/
+template
+bool is_sorted(ForwardIter first, ForwardIter last)
+{
+ if (first == last)
+ return true;
+ auto next = first;
+ ++next;
+ for (; next != last; first = next, ++next)
+ {
+ if (*next < *first)
+ return false;
+ }
+ return true;
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+bool is_sorted(ForwardIter first, ForwardIter last, Compared comp)
+{
+ if (first == last)
+ return true;
+ auto next = first;
+ ++next;
+ for (; next != last; first = next, ++next)
+ {
+ if (comp(*next, *first))
+ return false;
+ }
+ return true;
+}
+
+/*****************************************************************************************/
+// median
+// 找出三个值的中间值
+/*****************************************************************************************/
+template
+const T& median(const T& left, const T& mid, const T& right)
+{
+ if (left < mid)
+ if (mid < right) // left < mid < right
+ return mid;
+ else if (left < right) // left < right <= mid
+ return right;
+ else // right <= left < mid
+ return left;
+ else if (left < right) // mid <= left < right
+ return left;
+ else if (mid < right) // mid < right <= left
+ return right;
+ else // right <= mid <= left
+ return mid;
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+const T& median(const T& left, const T& mid, const T& right, Compared comp)
+{
+ if (comp(left, mid))
+ if (comp(mid, right))
+ return mid;
+ else if (comp(left, right))
+ return right;
+ else
+ return left;
+ else if (comp(left, right))
+ return left;
+ else if (comp(mid, right))
+ return right;
+ else
+ return mid;
+}
+
+/*****************************************************************************************/
+// max_element
+// 返回一个迭代器,指向序列中最大的元素
+/*****************************************************************************************/
+template
+ForwardIter max_element(ForwardIter first, ForwardIter last)
+{
+ if (first == last)
+ return first;
+ auto result = first;
+ while (++first != last)
+ {
+ if (*result < *first)
+ result = first;
+ }
+ return result;
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+ForwardIter max_element(ForwardIter first, ForwardIter last, Compared comp)
+{
+ if (first == last)
+ return first;
+ auto result = first;
+ while (++first != last)
+ {
+ if (comp(*result, *first))
+ result = first;
+ }
+ return result;
+}
+
+/*****************************************************************************************/
+// min_element
+// 返回一个迭代器,指向序列中最小的元素
+/*****************************************************************************************/
+template
+ForwardIter min_elememt(ForwardIter first, ForwardIter last)
+{
+ if (first == last)
+ return first;
+ auto result = first;
+ while (++first != last)
+ {
+ if (*first < *result)
+ result = first;
+ }
+ return result;
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+ForwardIter min_elememt(ForwardIter first, ForwardIter last, Compared comp)
+{
+ if (first == last)
+ return first;
+ auto result = first;
+ while (++first != last)
+ {
+ if (comp(*first, *result))
+ result = first;
+ }
+ return result;
+}
+
+/*****************************************************************************************/
+// swap_ranges
+// 将[first1, last1)从 first2 开始,交换相同个数元素
+// 交换的区间长度必须相同,两个序列不能互相重叠,返回一个迭代器指向序列二最后一个被交换元素的下一位置
+/*****************************************************************************************/
+template
+ForwardIter2
+swap_ranges(ForwardIter1 first1, ForwardIter1 last1,
+ ForwardIter2 first2)
+{
+ for (; first1 != last1; ++first1, ++first2)
+ {
+ mystl::iter_swap(first1, first2);
+ }
+ return first2;
+}
+
+/*****************************************************************************************/
+// transform
+// 第一个版本以函数对象 unary_op 作用于[first, last)中的每个元素并将结果保存至 result 中
+// 第二个版本以函数对象 binary_op 作用于两个序列[first1, last1)、[first2, last2)的相同位置
+/*****************************************************************************************/
+template
+OutputIter
+transform(InputIter first, InputIter last,
+ OutputIter result, UnaryOperation unary_op)
+{
+ for (; first != last; ++first, ++result)
+ {
+ *result = unary_op(*first);
+ }
+ return result;
+}
+
+template
+OutputIter
+transform(InputIter1 first1, InputIter1 last1,
+ InputIter2 first2, OutputIter result, BinaryOperation binary_op)
+{
+ for (; first1 != last1; ++first1, ++first2, ++result)
+ {
+ *result = binary_op(*first1, *first2);
+ }
+ return result;
+}
+
+/*****************************************************************************************/
+// remove_copy
+// 移除区间内与指定 value 相等的元素,并将结果复制到以 result 标示起始位置的容器上
+/*****************************************************************************************/
+template
+OutputIter
+remove_copy(InputIter first, InputIter last, OutputIter result, const T& value)
+{
+ for (; first != last; ++first)
+ {
+ if (*first != value)
+ {
+ *result++ = *first;
+ }
+ }
+ return result;
+}
+
+/*****************************************************************************************/
+// remove
+// 移除所有与指定 value 相等的元素
+// 并不从容器中删除这些元素,所以 remove 和 remove_if 不适用于 array
+/*****************************************************************************************/
+template
+ForwardIter remove(ForwardIter first, ForwardIter last, const T& value)
+{
+ first = mystl::find(first, last, value); // 利用 find 找出第一个匹配的地方
+ auto next = first;
+ return first == last ? first : mystl::remove_copy(++next, last, first, value);
+}
+
+/*****************************************************************************************/
+// remove_copy_if
+// 移除区间内所有令一元操作 unary_pred 为 true 的元素,并将结果复制到以 result 为起始位置的容器上
+/*****************************************************************************************/
+template
+OutputIter
+remove_copy_if(InputIter first, InputIter last,
+ OutputIter result, UnaryPredicate unary_pred)
+{
+ for (; first != last; ++first)
+ {
+ if (!unary_pred(*first))
+ {
+ *result = *first;
+ ++result;
+ }
+ }
+ return result;
+}
+
+/*****************************************************************************************/
+// remove_if
+// 移除区间内所有令一元操作 unary_pred 为 true 的元素
+/*****************************************************************************************/
+template
+ForwardIter
+remove_if(ForwardIter first, ForwardIter last, UnaryPredicate unary_pred)
+{
+ first = mystl::find_if(first, last, unary_pred); // 利用 find_if 找出第一个匹配的地方
+ auto next = first;
+ return first == last ? first : mystl::remove_copy_if(++next, last, first, unary_pred);
+}
+
+/*****************************************************************************************/
+// replace
+// 将区间内所有的 old_value 都以 new_value 替代
+/*****************************************************************************************/
+template
+void replace(ForwardIter first, ForwardIter last,
+ const T& old_value, const T& new_value)
+{
+ for (; first != last; ++first)
+ {
+ if (*first == old_value)
+ *first = new_value;
+ }
+}
+
+/*****************************************************************************************/
+// replace_copy
+// 行为与 replace 类似,不同的是将结果复制到 result 所指的容器中,原序列没有改变
+/*****************************************************************************************/
+template
+OutputIter
+replace_copy(InputIter first, InputIter last,
+ OutputIter result, const T& old_value, const T& new_value)
+{
+ for (; first != last; ++first, ++result)
+ {
+ *result = *first == old_value ? new_value : *first;
+ }
+ return result;
+}
+
+/*****************************************************************************************/
+// replace_copy_if
+// 行为与 replace_if 类似,不同的是将结果复制到 result 所指的容器中,原序列没有改变
+/*****************************************************************************************/
+template
+OutputIter
+replace_copy_if(InputIter first, InputIter last,
+ OutputIter result, UnaryPredicate unary_pred, const T& new_value)
+{
+ for (; first != last; ++first, ++result)
+ {
+ *result = unary_pred(*first) ? new_value : *first;
+ }
+ return result;
+}
+
+/*****************************************************************************************/
+// replace_if
+// 将区间内所有令一元操作 unary_pred 为 true 的元素都用 new_value 替代
+/*****************************************************************************************/
+template
+void replace_if(ForwardIter first, ForwardIter last,
+ UnaryPredicate unary_pred, const T& new_value)
+{
+ for (; first != last; ++first)
+ {
+ if (unary_pred(*first))
+ *first = new_value;
+ }
+}
+
+/*****************************************************************************************/
+// reverse
+// 将[first, last)区间内的元素反转
+/*****************************************************************************************/
+// reverse_dispatch 的 bidirectional_iterator_tag 版本
+template
+void reverse_dispatch(BidirectionalIter first, BidirectionalIter last,
+ bidirectional_iterator_tag)
+{
+ while (true)
+ {
+ if (first == last || first == --last)
+ return;
+ mystl::iter_swap(first++, last);
+ }
+}
+
+// reverse_dispatch 的 random_access_iterator_tag 版本
+template
+void reverse_dispatch(RandomIter first, RandomIter last,
+ random_access_iterator_tag)
+{
+ while (first < last)
+ mystl::iter_swap(first++, --last);
+}
+
+template
+void reverse(BidirectionalIter first, BidirectionalIter last)
+{
+ mystl::reverse_dispatch(first, last, iterator_category(first));
+}
+
+/*****************************************************************************************/
+// reverse_copy
+// 行为与 reverse 类似,不同的是将结果复制到 result 所指容器中
+/*****************************************************************************************/
+template
+OutputIter
+reverse_copy(BidirectionalIter first, BidirectionalIter last,
+ OutputIter result)
+{
+ while (first != last)
+ {
+ --last;
+ *result = *last;
+ ++result;
+ }
+ return result;
+}
+
+/*****************************************************************************************/
+// random_shuffle
+// 将[first, last)内的元素次序随机重排
+// 重载版本使用一个产生随机数的函数对象 rand
+/*****************************************************************************************/
+template
+void random_shuffle(RandomIter first, RandomIter last)
+{
+ if (first == last)
+ return;
+ srand((unsigned)time(0));
+ for (auto i = first + 1; i != last; ++i)
+ {
+ mystl::iter_swap(i, first + (rand() % (i - first + 1)));
+ }
+}
+
+// 重载版本使用一个产生随机数的函数对象 rand
+template
+void random_shuffle(RandomIter first, RandomIter last,
+ RandomNumberGenerator& rand)
+{
+ if (first == last)
+ return;
+ auto len = mystl::distance(first, last);
+ for (auto i = first + 1; i != last; ++i)
+ {
+ mystl::iter_swap(i, first + (rand(i - first + 1) % len));
+ }
+}
+
+/*****************************************************************************************/
+// rotate
+// 将[first, middle)内的元素和 [middle, last)内的元素互换,可以交换两个长度不同的区间
+// 返回交换后 middle 的位置
+/*****************************************************************************************/
+// rotate_dispatch 的 forward_iterator_tag 版本
+template
+ForwardIter
+rotate_dispatch(ForwardIter first, ForwardIter middle,
+ ForwardIter last, forward_iterator_tag)
+{
+ auto first2 = middle;
+ do
+ {
+ mystl::swap(*first++, *first2++);
+ if (first == middle)
+ middle = first2;
+ } while (first2 != last); // 后半段移到前面
+
+ auto new_middle = first; // 迭代器返回的位置
+ first2 = middle;
+ while (first2 != last)
+ { // 调整剩余元素
+ mystl::swap(*first++, *first2++);
+ if (first == middle)
+ {
+ middle = first2;
+ }
+ else if (first2 == last)
+ {
+ first2 = middle;
+ }
+ }
+ return new_middle;
+}
+
+// rotate_dispatch 的 bidirectional_iterator_tag 版本
+template
+BidirectionalIter
+rotate_dispatch(BidirectionalIter first, BidirectionalIter middle,
+ BidirectionalIter last, bidirectional_iterator_tag)
+{
+ mystl::reverse_dispatch(first, middle, bidirectional_iterator_tag());
+ mystl::reverse_dispatch(middle, last, bidirectional_iterator_tag());
+ while (first != middle && middle != last)
+ mystl::swap(*first++, *--last);
+ if (first == middle)
+ {
+ mystl::reverse_dispatch(middle, last, bidirectional_iterator_tag());
+ return last;
+ }
+ else
+ {
+ mystl::reverse_dispatch(first, middle, bidirectional_iterator_tag());
+ return first;
+ }
+}
+
+// 求最大公因子
+template
+EuclideanRingElement rgcd(EuclideanRingElement m, EuclideanRingElement n)
+{
+ while (n != 0)
+ {
+ auto t = m % n;
+ m = n;
+ n = t;
+ }
+ return m;
+}
+
+// rotate_dispatch 的 random_access_iterator_tag 版本
+template
+RandomIter
+rotate_dispatch(RandomIter first, RandomIter middle,
+ RandomIter last, random_access_iterator_tag)
+{
+ // 因为是 random access iterator,我们可以确定每个元素的位置
+ auto n = last - first;
+ auto l = middle - first;
+ auto r = n - l;
+ auto result = first + (last - middle);
+ if (l == r)
+ {
+ mystl::swap_ranges(first, middle, middle);
+ return result;
+ }
+ auto cycle_times = rgcd(n, l);
+ for (auto i = 0; i < cycle_times; ++i)
+ {
+ auto tmp = *first;
+ auto p = first;
+ if (l < r)
+ {
+ for (auto j = 0; j < r / cycle_times; ++j)
+ {
+ if (p > first + r)
+ {
+ *p = *(p - r);
+ p -= r;
+ }
+ *p = *(p + l);
+ p += l;
+ }
+ }
+ else
+ {
+ for (auto j = 0; j < l / cycle_times - 1; ++j)
+ {
+ if (p < last - l)
+ {
+ *p = *(p + l);
+ p += l;
+ }
+ *p = *(p - r);
+ p -= r;
+ }
+ }
+ *p = tmp;
+ ++first;
+ }
+ return result;
+}
+
+template
+ForwardIter
+rotate(ForwardIter first, ForwardIter middle, ForwardIter last)
+{
+ if (first == middle)
+ return last;
+ if (middle == last)
+ return first;
+ return mystl::rotate_dispatch(first, middle, last, iterator_category(first));
+}
+
+/*****************************************************************************************/
+// rotate_copy
+// 行为与 rotate 类似,不同的是将结果复制到 result 所指的容器中
+/*****************************************************************************************/
+template
+ForwardIter
+rotate_copy(ForwardIter first, ForwardIter middle,
+ ForwardIter last, OutputIter result)
+{
+ return mystl::copy(first, middle, mystl::copy(middle, last, result));
+}
+
+/*****************************************************************************************/
+// is_permutation
+// 判断[first1,last1)是否为[first2, last2)的排列组合
+/*****************************************************************************************/
+template
+bool is_permutation_aux(ForwardIter1 first1, ForwardIter1 last1,
+ ForwardIter2 first2, ForwardIter2 last2,
+ BinaryPred pred)
+{
+ constexpr bool is_ra_it = mystl::is_random_access_iterator::value
+ && mystl::is_random_access_iterator::value;
+ if (is_ra_it)
+ {
+ auto len1 = last1 - first1;
+ auto len2 = last2 - first2;
+ if (len1 != len2)
+ return false;
+ }
+
+ // 先找出相同的前缀段
+ for (; first1 != last1 && first2 != last2; ++first1, (void) ++first2)
+ {
+ if (!pred(*first1, *first2))
+ break;
+ }
+ if (is_ra_it)
+ {
+ if (first1 == last1)
+ return true;
+ }
+ else
+ {
+ auto len1 = mystl::distance(first1, last1);
+ auto len2 = mystl::distance(first2, last2);
+ if (len1 == 0 && len2 == 0)
+ return true;
+ if (len1 != len2)
+ return false;
+ }
+
+ // 判断剩余部分
+ for (auto i = first1; i != last1; ++i)
+ {
+ bool is_repeated = false;
+ for (auto j = first1; j != i; ++j)
+ {
+ if (pred(*j, *i))
+ {
+ is_repeated = true;
+ break;
+ }
+ }
+
+ if (!is_repeated)
+ {
+ // 计算 *i 在 [first2, last2) 的数目
+ auto c2 = 0;
+ for (auto j = first2; j != last2; ++j)
+ {
+ if (pred(*i, *j))
+ ++c2;
+ }
+ if (c2 == 0)
+ return false;
+
+ // 计算 *i 在 [first1, last1) 的数目
+ auto c1 = 1;
+ auto j = i;
+ for (++j; j != last1; ++j)
+ {
+ if (pred(*i, *j))
+ ++c1;
+ }
+ if (c1 != c2)
+ return false;
+ }
+ }
+ return true;
+}
+
+template
+bool is_permutation(ForwardIter1 first1, ForwardIter1 last1,
+ ForwardIter2 first2, ForwardIter2 last2,
+ BinaryPred pred)
+{
+ return is_permutation_aux(first1, last1, first2, last2, pred);
+}
+
+template
+bool is_permutation(ForwardIter1 first1, ForwardIter1 last1,
+ ForwardIter2 first2, ForwardIter2 last2)
+{
+ typedef typename iterator_traits::value_type v1;
+ typedef typename iterator_traits::value_type v2;
+ static_assert(std::is_same::value,
+ "the type should be same in mystl::is_permutation");
+ return is_permutation_aux(first1, last1, first2, last2,
+ mystl::equal_to());
+}
+
+/*****************************************************************************************/
+// next_permutation
+// 取得[first, last)所标示序列的下一个排列组合,如果没有下一个排序组合,返回 false,否则返回 true
+/*****************************************************************************************/
+template
+bool next_permutation(BidirectionalIter first, BidirectionalIter last)
+{
+ auto i = last;
+ if (first == last || first == --i)
+ return false;
+ for (;;)
+ {
+ auto ii = i;
+ if (*--i < *ii)
+ { // 找到第一对小于关系的元素
+ auto j = last;
+ while (!(*i < *--j)) {}
+ mystl::iter_swap(i, j); // 交换 i,j 所指元素
+ mystl::reverse(ii, last); // 将 ii 之后的所有元素反转
+ return true;
+ }
+ if (i == first)
+ {
+ mystl::reverse(first, last);
+ return false;
+ }
+ }
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+bool next_permutation(BidirectionalIter first, BidirectionalIter last, Compared comp)
+{
+ auto i = last;
+ if (first == last || first == --i)
+ return false;
+ for (;;)
+ {
+ auto ii = i;
+ if (comp(*--i, *ii))
+ {
+ auto j = last;
+ while (!comp(*i, *--j)) {}
+ mystl::iter_swap(i, j); // 交换 i,j 所指元素
+ mystl::reverse(ii, last); // 将 ii 之后的所有元素反转
+ return true;
+ }
+ if (i == first)
+ {
+ mystl::reverse(first, last);
+ return false;
+ }
+ }
+}
+
+/*****************************************************************************************/
+// prev_permutation
+// 取得[first, last)所标示序列的上一个排列组合,如果没有上一个排序组合,返回 false,否则返回 true
+/*****************************************************************************************/
+template
+bool prev_permutation(BidirectionalIter first, BidirectionalIter last)
+{
+ auto i = last;
+ if (first == last || first == --i)
+ return false;
+ for (;;)
+ {
+ auto ii = i;
+ if (*ii < *--i)
+ { // 找到第一对大于关系的元素
+ auto j = last;
+ while (!(*--j < *i)) {}
+ mystl::iter_swap(i, j); // 交换i,j
+ mystl::reverse(ii, last); // 将 ii 之后的所有元素反转
+ return true;
+ }
+ if (i == first)
+ {
+ mystl::reverse(first, last);
+ return false;
+ }
+ }
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+bool prev_permutation(BidirectionalIter first, BidirectionalIter last, Compared comp)
+{
+ auto i = last;
+ if (first == last || first == --i)
+ return false;
+ for (;;)
+ {
+ auto ii = i;
+ if (comp(*ii, *--i))
+ {
+ auto j = last;
+ while (!comp(*--j, *i)) {}
+ mystl::iter_swap(i, j); // 交换i,j
+ mystl::reverse(ii, last); // 将 ii 之后的所有元素反转
+ return true;
+ }
+ if (i == first)
+ {
+ mystl::reverse(first, last);
+ return false;
+ }
+ }
+}
+
+/*****************************************************************************************/
+// merge
+// 将两个经过排序的集合 S1 和 S2 合并起来置于另一段空间,返回一个迭代器指向最后一个元素的下一位置
+/*****************************************************************************************/
+template
+OutputIter
+merge(InputIter1 first1, InputIter1 last1,
+ InputIter2 first2, InputIter2 last2,
+ OutputIter result)
+{
+ while (first1 != last1 && first2 != last2)
+ {
+ if (*first2 < *first1)
+ {
+ *result = *first2;
+ ++first2;
+ }
+ else
+ {
+ *result = *first1;
+ ++first1;
+ }
+ ++result;
+ }
+ return mystl::copy(first2, last2, mystl::copy(first1, last1, result));
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+OutputIter
+merge(InputIter1 first1, InputIter1 last1,
+ InputIter2 first2, InputIter2 last2,
+ OutputIter result, Compared comp)
+{
+ while (first1 != last1 && first2 != last2)
+ {
+ if (comp(*first2, *first1))
+ {
+ *result = *first2;
+ ++first2;
+ }
+ else
+ {
+ *result = *first1;
+ ++first1;
+ }
+ ++result;
+ }
+ return mystl::copy(first2, last2, mystl::copy(first1, last1, result));
+}
+
+/*****************************************************************************************/
+// inplace_merge
+// 把连接在一起的两个有序序列结合成单一序列并保持有序
+/*****************************************************************************************/
+// 没有缓冲区的情况下合并
+template
+void merge_without_buffer(BidirectionalIter first, BidirectionalIter middle,
+ BidirectionalIter last, Distance len1, Distance len2)
+{
+ if (len1 == 0 || len2 == 0)
+ return;
+ if (len1 + len2 == 2)
+ {
+ if (*middle < *first)
+ mystl::iter_swap(first, middle);
+ return;
+ }
+ auto first_cut = first;
+ auto second_cut = middle;
+ Distance len11 = 0;
+ Distance len22 = 0;
+ if (len1 > len2)
+ { // 序列一较长,找到序列一的中点
+ len11 = len1 >> 1;
+ mystl::advance(first_cut, len11);
+ second_cut = mystl::lower_bound(middle, last, *first_cut);
+ len22 = mystl::distance(middle, second_cut);
+ }
+ else
+ { // 序列二较长,找到序列二的中点
+ len22 = len2 >> 1;
+ mystl::advance(second_cut, len22);
+ first_cut = mystl::upper_bound(first, middle, *second_cut);
+ len11 = mystl::distance(first, first_cut);
+ }
+ auto new_middle = mystl::rotate(first_cut, middle, second_cut);
+ mystl::merge_without_buffer(first, first_cut, new_middle, len11, len22);
+ mystl::merge_without_buffer(new_middle, second_cut, last, len1 - len11, len2 - len22);
+}
+
+template
+BidirectionalIter1
+merge_backward(BidirectionalIter1 first1, BidirectionalIter1 last1,
+ BidirectionalIter2 first2, BidirectionalIter2 last2,
+ BidirectionalIter1 result)
+{
+ if (first1 == last1)
+ return mystl::copy_backward(first2, last2, result);
+ if (first2 == last2)
+ return mystl::copy_backward(first1, last1, result);
+ --last1;
+ --last2;
+ while (true)
+ {
+ if (*last2 < *last1)
+ {
+ *--result = *last1;
+ if (first1 == last1)
+ return mystl::copy_backward(first2, ++last2, result);
+ --last1;
+ }
+ else
+ {
+ *--result = *last2;
+ if (first2 == last2)
+ return mystl::copy_backward(first1, ++last1, result);
+ --last2;
+ }
+ }
+}
+
+template
+BidirectionalIter1
+rotate_adaptive(BidirectionalIter1 first, BidirectionalIter1 middle,
+ BidirectionalIter1 last, Distance len1, Distance len2,
+ BidirectionalIter2 buffer, Distance buffer_size)
+{
+ BidirectionalIter2 buffer_end;
+ if (len1 > len2 && len2 <= buffer_size)
+ {
+ buffer_end = mystl::copy(middle, last, buffer);
+ mystl::copy_backward(first, middle, last);
+ return mystl::copy(buffer, buffer_end, first);
+ }
+ else if (len1 <= buffer_size)
+ {
+ buffer_end = mystl::copy(first, middle, buffer);
+ mystl::copy(middle, last, first);
+ return mystl::copy_backward(buffer, buffer_end, last);
+ }
+ else
+ {
+ return mystl::rotate(first, middle, last);
+ }
+}
+
+// 有缓冲区的情况下合并
+template
+void merge_adaptive(BidirectionalIter first, BidirectionalIter middle,
+ BidirectionalIter last, Distance len1, Distance len2,
+ Pointer buffer, Distance buffer_size)
+{
+ // 区间长度足够放进缓冲区
+ if (len1 <= len2 && len1 <= buffer_size)
+ {
+ Pointer buffer_end = mystl::copy(first, middle, buffer);
+ mystl::merge(buffer, buffer_end, middle, last, first);
+ }
+ else if (len2 <= buffer_size)
+ {
+ Pointer buffer_end = mystl::copy(middle, last, buffer);
+ mystl::merge_backward(first, middle, buffer, buffer_end, last);
+ }
+ else
+ { // 区间长度太长,分割递归处理
+ auto first_cut = first;
+ auto second_cut = middle;
+ Distance len11 = 0;
+ Distance len22 = 0;
+ if (len1 > len2)
+ {
+ len11 = len1 >> 1;
+ mystl::advance(first_cut, len11);
+ second_cut = mystl::lower_bound(middle, last, *first_cut);
+ len22 = mystl::distance(middle, second_cut);
+ }
+ else
+ {
+ len22 = len2 >> 1;
+ mystl::advance(second_cut, len22);
+ first_cut = mystl::upper_bound(first, middle, *second_cut);
+ len11 = mystl::distance(first, first_cut);
+ }
+ auto new_middle = mystl::rotate_adaptive(first_cut, middle, second_cut,
+ len1 - len11, len22, buffer, buffer_size);
+ mystl::merge_adaptive(first, first_cut, new_middle, len11, len22, buffer, buffer_size);
+ mystl::merge_adaptive(new_middle, second_cut, last, len1 - len11,
+ len2 - len22, buffer, buffer_size);
+ }
+}
+
+template
+void
+inplace_merge_aux(BidirectionalIter first, BidirectionalIter middle,
+ BidirectionalIter last, T*)
+{
+ auto len1 = mystl::distance(first, middle);
+ auto len2 = mystl::distance(middle, last);
+ temporary_buffer buf(first, last);
+ if (!buf.begin())
+ {
+ mystl::merge_without_buffer(first, middle, last, len1, len2);
+ }
+ else
+ {
+ mystl::merge_adaptive(first, middle, last, len1, len2, buf.begin(), buf.size());
+ }
+}
+
+template
+void
+inplace_merge(BidirectionalIter first, BidirectionalIter middle,
+ BidirectionalIter last)
+{
+ if (first == middle || middle == last)
+ return;
+ mystl::inplace_merge_aux(first, middle, last, value_type(first));
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+// 没有缓冲区的情况下合并
+template
+void merge_without_buffer(BidirectionalIter first, BidirectionalIter middle,
+ BidirectionalIter last, Distance len1, Distance len2,
+ Compared comp)
+{
+ if (len1 == 0 || len2 == 0)
+ return;
+ if (len1 + len2 == 2)
+ {
+ if (comp(*middle, *first))
+ mystl::iter_swap(first, middle);
+ return;
+ }
+ auto first_cut = first;
+ auto second_cut = middle;
+ Distance len11 = 0;
+ Distance len22 = 0;
+ if (len1 > len2)
+ {
+ len11 = len1 >> 1;
+ mystl::advance(first_cut, len11);
+ second_cut = mystl::lower_bound(middle, last, *first_cut, comp);
+ len22 = mystl::distance(middle, second_cut);
+ }
+ else
+ {
+ len22 = len2 >> 1;
+ mystl::advance(second_cut, len22);
+ first_cut = mystl::upper_bound(first, middle, *second_cut, comp);
+ len11 = mystl::distance(first, first_cut);
+ }
+ auto new_middle = mystl::rotate(first_cut, middle, second_cut);
+ mystl::merge_without_buffer(first, first_cut, new_middle, len11, len22, comp);
+ mystl::merge_without_buffer(new_middle, second_cut, last, len1 - len11, len2 - len22, comp);
+}
+
+template
+BidirectionalIter1
+merge_backward(BidirectionalIter1 first1, BidirectionalIter1 last1,
+ BidirectionalIter2 first2, BidirectionalIter2 last2,
+ BidirectionalIter1 result, Compared comp)
+{
+ if (first1 == last1)
+ return mystl::copy_backward(first2, last2, result);
+ if (first2 == last2)
+ return mystl::copy_backward(first1, last1, result);
+ --last1;
+ --last2;
+ while (true)
+ {
+ if (comp(*last2, *last1))
+ {
+ *--result = *last1;
+ if (first1 == last1)
+ return mystl::copy_backward(first2, ++last2, result);
+ --last1;
+ }
+ else
+ {
+ *--result = *last2;
+ if (first2 == last2)
+ return mystl::copy_backward(first1, ++last1, result);
+ --last2;
+ }
+ }
+}
+
+// 有缓冲区的情况下合并
+template
+void merge_adaptive(BidirectionalIter first, BidirectionalIter middle,
+ BidirectionalIter last, Distance len1, Distance len2,
+ Pointer buffer, Distance buffer_size, Compared comp)
+{
+ // 区间长度足够放进缓冲区
+ if (len1 <= len2 && len1 <= buffer_size)
+ {
+ Pointer buffer_end = mystl::copy(first, middle, buffer);
+ mystl::merge(buffer, buffer_end, middle, last, first, comp);
+ }
+ else if (len2 <= buffer_size)
+ {
+ Pointer buffer_end = mystl::copy(middle, last, buffer);
+ mystl::merge_backward(first, middle, buffer, buffer_end, last, comp);
+ }
+ else
+ { // 区间长度太长,分割递归处理
+ auto first_cut = first;
+ auto second_cut = middle;
+ Distance len11 = 0;
+ Distance len22 = 0;
+ if (len1 > len2)
+ {
+ len11 = len1 >> 1;
+ mystl::advance(first_cut, len11);
+ second_cut = mystl::lower_bound(middle, last, *first_cut, comp);
+ len22 = mystl::distance(middle, second_cut);
+ }
+ else
+ {
+ len22 = len2 >> 1;
+ mystl::advance(second_cut, len22);
+ first_cut = mystl::upper_bound(first, middle, *second_cut, comp);
+ len11 = mystl::distance(first, first_cut);
+ }
+ auto new_middle = mystl::rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
+ len22, buffer, buffer_size);
+ mystl::merge_adaptive(first, first_cut, new_middle, len11,
+ len22, buffer, buffer_size, comp);
+ mystl::merge_adaptive(new_middle, second_cut, last, len1 - len11,
+ len2 - len22, buffer, buffer_size, comp);
+ }
+}
+
+template
+void
+inplace_merge_aux(BidirectionalIter first, BidirectionalIter middle,
+ BidirectionalIter last, T*, Compared comp)
+{
+ auto len1 = mystl::distance(first, middle);
+ auto len2 = mystl::distance(middle, last);
+ temporary_buffer buf(first, last);
+ if (!buf.begin())
+ {
+ mystl::merge_without_buffer(first, middle, last, len1, len2, comp);
+ }
+ else
+ {
+ mystl::merge_adaptive(first, middle, last, len1, len2, buf.begin(), buf.size(), comp);
+ }
+}
+
+template
+void
+inplace_merge(BidirectionalIter first, BidirectionalIter middle,
+ BidirectionalIter last, Compared comp)
+{
+ if (first == middle || middle == last)
+ return;
+ mystl::inplace_merge_aux(first, middle, last, value_type(first), comp);
+}
+
+/*****************************************************************************************/
+// partial_sort
+// 对整个序列做部分排序,保证较小的 N 个元素以递增顺序置于[first, first + N)中
+/*****************************************************************************************/
+template
+void partial_sort(RandomIter first, RandomIter middle,
+ RandomIter last)
+{
+ mystl::make_heap(first, middle);
+ for (auto i = middle; i < last; ++i)
+ {
+ if (*i < *first)
+ {
+ mystl::pop_heap_aux(first, middle, i, *i, distance_type(first));
+ }
+ }
+ mystl::sort_heap(first, middle);
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+void partial_sort(RandomIter first, RandomIter middle,
+ RandomIter last, Compared comp)
+{
+ mystl::make_heap(first, middle, comp);
+ for (auto i = middle; i < last; ++i)
+ {
+ if (comp(*i, *first))
+ {
+ mystl::pop_heap_aux(first, middle, i, *i, distance_type(first), comp);
+ }
+ }
+ mystl::sort_heap(first, middle, comp);
+}
+
+/*****************************************************************************************/
+// partial_sort_copy
+// 行为与 partial_sort 类似,不同的是把排序结果复制到 result 容器中
+/*****************************************************************************************/
+template
+RandomIter
+psort_copy_aux(InputIter first, InputIter last,
+ RandomIter result_first, RandomIter result_last,
+ Distance*)
+{
+ if (result_first == result_last)
+ return result_last;
+ auto result_iter = result_first;
+ while (first != last && result_iter != result_last)
+ {
+ *result_iter = *first;
+ ++result_iter;
+ ++first;
+ }
+ mystl::make_heap(result_first, result_iter);
+ while (first != last)
+ {
+ if (*first < *result_first)
+ {
+ mystl::adjust_heap(result_first, static_cast(0),
+ result_iter - result_first, *first);
+ }
+ ++first;
+ }
+ mystl::sort_heap(result_first, result_iter);
+ return result_iter;
+}
+
+template
+RandomIter
+partial_sort_copy(InputIter first, InputIter last,
+ RandomIter result_first, RandomIter result_last)
+{
+ return mystl::psort_copy_aux(first, last, result_first, result_last,
+ distance_type(result_first));
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+RandomIter
+psort_copy_aux(InputIter first, InputIter last,
+ RandomIter result_first, RandomIter result_last,
+ Distance*, Compared comp)
+{
+ if (result_first == result_last)
+ return result_last;
+ auto result_iter = result_first;
+ while (first != last && result_iter != result_last)
+ {
+ *result_iter = *first;
+ ++result_iter;
+ ++first;
+ }
+ mystl::make_heap(result_first, result_iter, comp);
+ while (first != last)
+ {
+ if (comp(*first, *result_first))
+ {
+ mystl::adjust_heap(result_first, static_cast(0),
+ result_iter - result_first, *first, comp);
+ }
+ ++first;
+ }
+ mystl::sort_heap(result_first, result_iter, comp);
+ return result_iter;
+}
+
+template
+RandomIter
+partial_sort_copy(InputIter first, InputIter last,
+ RandomIter result_first, RandomIter result_last,
+ Compared comp)
+{
+ return mystl::psort_copy_aux(first, last, result_first, result_last,
+ distance_type(result_first), comp);
+}
+/*****************************************************************************************/
+// partition
+// 对区间内的元素重排,被一元条件运算判定为 true 的元素会放到区间的前段
+// 该函数不保证元素的原始相对位置
+/*****************************************************************************************/
+template
+BidirectionalIter
+partition(BidirectionalIter first, BidirectionalIter last,
+ UnaryPredicate unary_pred)
+{
+ while (true)
+ {
+ while (first != last && unary_pred(*first))
+ {
+ ++first;
+ }
+ if (first == last)
+ break;
+ --last;
+ while (first != last && !unary_pred(*last))
+ {
+ --last;
+ }
+ if (first == last)
+ break;
+ mystl::iter_swap(first, last);
+ ++first;
+ }
+ return first;
+}
+
+/*****************************************************************************************/
+// partition_copy
+// 行为与 partition 类似,不同的是,将被一元操作符判定为 true 的放到 result_true 的输出区间
+// 其余放到 result_false 的输出区间,并返回一个 mystl::pair 指向这两个区间的尾部
+/*****************************************************************************************/
+template
+mystl::pair
+partition_copy(InputIter first, InputIter last,
+ OutputIter1 result_true, OutputIter2 result_false,
+ UnaryPredicate unary_pred)
+{
+ for (; first != last; ++first)
+ {
+ if (unary_pred(*first))
+ {
+ *result_true++ = *first;
+ }
+ else
+ {
+ *result_false++ = *first;
+ }
+ }
+ return mystl::pair(result_true, result_false);
+}
+
+/*****************************************************************************************/
+// sort
+// 将[first, last)内的元素以递增的方式排序
+/*****************************************************************************************/
+constexpr static size_t kSmallSectionSize = 128; // 小型区间的大小,在这个大小内采用插入排序
+
+ // 用于控制分割恶化的情况
+template
+Size slg2(Size n)
+{ // 找出 lgk <= n 的 k 的最大值
+ Size k = 0;
+ for (; n > 1; n >>= 1)
+ ++k;
+ return k;
+}
+
+// 分割函数 unchecked_partition
+template
+RandomIter
+unchecked_partition(RandomIter first, RandomIter last, const T& pivot)
+{
+ while (true)
+ {
+ while (*first < pivot)
+ ++first;
+ --last;
+ while (pivot < *last)
+ --last;
+ if (!(first < last))
+ return first;
+ mystl::iter_swap(first, last);
+ ++first;
+ }
+}
+
+// 内省式排序,先进行 quick sort,当分割行为有恶化倾向时,改用 heap sort
+template
+void intro_sort(RandomIter first, RandomIter last, Size depth_limit)
+{
+ while (static_cast(last - first) > kSmallSectionSize)
+ {
+ if (depth_limit == 0)
+ { // 到达最大分割深度限制
+ mystl::partial_sort(first, last, last); // 改用 heap_sort
+ return;
+ }
+ --depth_limit;
+ auto mid = mystl::median(*(first), *(first + (last - first) / 2), *(last - 1));
+ auto cut = mystl::unchecked_partition(first, last, mid);
+ mystl::intro_sort(cut, last, depth_limit);
+ last = cut;
+ }
+}
+
+// 插入排序辅助函数 unchecked_linear_insert
+template
+void unchecked_linear_insert(RandomIter last, const T& value)
+{
+ auto next = last;
+ --next;
+ while (value < *next)
+ {
+ *last = *next;
+ last = next;
+ --next;
+ }
+ *last = value;
+}
+
+// 插入排序函数 unchecked_insertion_sort
+template
+void unchecked_insertion_sort(RandomIter first, RandomIter last)
+{
+ for (auto i = first; i != last; ++i)
+ {
+ mystl::unchecked_linear_insert(i, *i);
+ }
+}
+
+// 插入排序函数 insertion_sort
+template
+void insertion_sort(RandomIter first, RandomIter last)
+{
+ if (first == last)
+ return;
+ for (auto i = first + 1; i != last; ++i)
+ {
+ auto value = *i;
+ if (value < *first)
+ {
+ mystl::copy_backward(first, i, i + 1);
+ *first = value;
+ }
+ else
+ {
+ mystl::unchecked_linear_insert(i, value);
+ }
+ }
+}
+
+// 最终插入排序函数 final_insertion_sort
+template
+void final_insertion_sort(RandomIter first, RandomIter last)
+{
+ if (static_cast(last - first) > kSmallSectionSize)
+ {
+ mystl::insertion_sort(first, first + kSmallSectionSize);
+ mystl::unchecked_insertion_sort(first + kSmallSectionSize, last);
+ }
+ else
+ {
+ mystl::insertion_sort(first, last);
+ }
+}
+
+template
+void sort(RandomIter first, RandomIter last)
+{
+ if (first != last)
+ {
+ // 内省式排序,将区间分为一个个小区间,然后对整体进行插入排序
+ mystl::intro_sort(first, last, slg2(last - first) * 2);
+ mystl::final_insertion_sort(first, last);
+ }
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+// 分割函数 unchecked_partition
+template
+RandomIter
+unchecked_partition(RandomIter first, RandomIter last,
+ const T& pivot, Compared comp)
+{
+ while (true)
+ {
+ while (comp(*first, pivot))
+ ++first;
+ --last;
+ while (comp(pivot, *last))
+ --last;
+ if (!(first < last))
+ return first;
+ mystl::iter_swap(first, last);
+ ++first;
+ }
+}
+
+// 内省式排序,先进行 quick sort,当分割行为有恶化倾向时,改用 heap sort
+template
+void intro_sort(RandomIter first, RandomIter last,
+ Size depth_limit, Compared comp)
+{
+ while (static_cast(last - first) > kSmallSectionSize)
+ {
+ if (depth_limit == 0)
+ { // 到达最大分割深度限制
+ mystl::partial_sort(first, last, last, comp); // 改用 heap_sort
+ return;
+ }
+ --depth_limit;
+ auto mid = mystl::median(*(first), *(first + (last - first) / 2), *(last - 1));
+ auto cut = mystl::unchecked_partition(first, last, mid, comp);
+ mystl::intro_sort(cut, last, depth_limit, comp);
+ last = cut;
+ }
+}
+
+// 插入排序辅助函数 unchecked_linear_insert
+template
+void unchecked_linear_insert(RandomIter last, const T& value, Compared comp)
+{
+ auto next = last;
+ --next;
+ while (comp(value, *next))
+ { // 从尾部开始寻找第一个可插入位置
+ *last = *next;
+ last = next;
+ --next;
+ }
+ *last = value;
+}
+
+// 插入排序函数 unchecked_insertion_sort
+template
+void unchecked_insertion_sort(RandomIter first, RandomIter last,
+ Compared comp)
+{
+ for (auto i = first; i != last; ++i)
+ {
+ mystl::unchecked_linear_insert(i, *i, comp);
+ }
+}
+
+// 插入排序函数 insertion_sort
+template
+void insertion_sort(RandomIter first, RandomIter last, Compared comp)
+{
+ if (first == last)
+ return;
+ for (auto i = first + 1; i != last; ++i)
+ {
+ auto value = *i;
+ if (comp(value, *first))
+ {
+ mystl::copy_backward(first, i, i + 1);
+ *first = value;
+ }
+ else
+ {
+ mystl::unchecked_linear_insert(i, value, comp);
+ }
+ }
+}
+
+// 最终插入排序函数 final_insertion_sort
+template
+void final_insertion_sort(RandomIter first, RandomIter last, Compared comp)
+{
+ if (static_cast(last - first) > kSmallSectionSize)
+ {
+ mystl::insertion_sort(first, first + kSmallSectionSize, comp);
+ mystl::unchecked_insertion_sort(first + kSmallSectionSize, last, comp);
+ }
+ else
+ {
+ mystl::insertion_sort(first, last, comp);
+ }
+}
+
+template
+void sort(RandomIter first, RandomIter last, Compared comp)
+{
+ if (first != last)
+ {
+ // 内省式排序,将区间分为一个个小区间,然后对整体进行插入排序
+ mystl::intro_sort(first, last, slg2(last - first) * 2, comp);
+ mystl::final_insertion_sort(first, last, comp);
+ }
+}
+
+/*****************************************************************************************/
+// nth_element
+// 对序列重排,使得所有小于第 n 个元素的元素出现在它的前面,大于它的出现在它的后面
+/*****************************************************************************************/
+template
+void nth_element(RandomIter first, RandomIter nth,
+ RandomIter last)
+{
+ if (nth == last)
+ return;
+ while (last - first > 3)
+ {
+ auto cut = mystl::unchecked_partition(first, last, mystl::median(*first,
+ *(first + (last - first) / 2),
+ *(last - 1)));
+ if (cut <= nth) // 如果 nth 位于右段
+ first = cut; // 对右段进行分割
+ else
+ last = cut; // 对左段进行分割
+ }
+ mystl::insertion_sort(first, last);
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+void nth_element(RandomIter first, RandomIter nth,
+ RandomIter last, Compared comp)
+{
+ if (nth == last)
+ return;
+ while (last - first > 3)
+ {
+ auto cut = mystl::unchecked_partition(first, last, mystl::median(*first,
+ *(first + (last - first) / 2),
+ *(last - 1)), comp);
+ if (cut <= nth) // 如果 nth 位于右段
+ first = cut; // 对右段进行分割
+ else
+ last = cut; // 对左段进行分割
+ }
+ mystl::insertion_sort(first, last, comp);
+}
+
+/*****************************************************************************************/
+// unique_copy
+// 从[first, last)中将元素复制到 result 上,序列必须有序,如果有重复的元素,只会复制一次
+/*****************************************************************************************/
+// unique_copy_dispatch 的 forward_iterator_tag 版本
+template
+ForwardIter
+unique_copy_dispatch(InputIter first, InputIter last,
+ ForwardIter result, forward_iterator_tag)
+{
+ *result = *first;
+ while (++first != last)
+ {
+ if (*result != *first)
+ *++result = *first;
+ }
+ return ++result;
+}
+
+// unique_copy_dispatch 的 output_iterator_tag 版本
+// 由于 output iterator 只能进行只读操作,所以不能有 *result != *first 这样的判断
+template
+OutputIter
+unique_copy_dispatch(InputIter first, InputIter last,
+ OutputIter result, output_iterator_tag)
+{
+ auto value = *first;
+ *result = value;
+ while (++first != last)
+ {
+ if (value != *first)
+ {
+ value = *first;
+ *++result = value;
+ }
+ }
+ return ++result;
+}
+
+template
+OutputIter
+unique_copy(InputIter first, InputIter last, OutputIter result)
+{
+ if (first == last)
+ return result;
+ return mystl::unique_copy_dispatch(first, last, result, iterator_category(result));
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+// unique_copy_dispatch 的 forward_iterator_tag 版本
+template
+ForwardIter
+unique_copy_dispatch(InputIter first, InputIter last,
+ ForwardIter result, forward_iterator_tag, Compared comp)
+{
+ *result = *first;
+ while (++first != last)
+ {
+ if (!comp(*result, *first))
+ *++result = *first;
+ }
+ return ++result;
+}
+
+// unique_copy_dispatch 的 output_iterator_tag 版本
+// 由于 output iterator 只能进行只读操作,所以不能有 *result != *first 这样的判断
+template
+OutputIter
+unique_copy_dispatch(InputIter first, InputIter last,
+ OutputIter result, output_iterator_tag, Compared comp)
+{
+ auto value = *first;
+ *result = value;
+ while (++first != last)
+ {
+ if (!comp(value, *first))
+ {
+ value = *first;
+ *++result = value;
+ }
+ }
+ return ++result;
+}
+
+template
+OutputIter
+unique_copy(InputIter first, InputIter last, OutputIter result, Compared comp)
+{
+ if (first == last)
+ return result;
+ return mystl::unique_copy_dispatch(first, last, result, iterator_category(result), comp);
+}
+
+/*****************************************************************************************/
+// unique
+// 移除[first, last)内重复的元素,序列必须有序,和 remove 类似,它也不能真正的删除重复元素
+/*****************************************************************************************/
+template
+ForwardIter unique(ForwardIter first, ForwardIter last)
+{
+ first = mystl::adjacent_find(first, last);
+ return mystl::unique_copy(first, last, first);
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+ForwardIter unique(ForwardIter first, ForwardIter last, Compared comp)
+{
+ first = mystl::adjacent_find(first, last, comp);
+ return mystl::unique_copy(first, last, first, comp);
+}
+
+} // namespace mystl
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // !MYTINYSTL_ALGO_H_
+
diff --git a/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/algobase.h b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/algobase.h
new file mode 100644
index 0000000..f7342b5
--- /dev/null
+++ b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/algobase.h
@@ -0,0 +1,520 @@
+#ifndef MYTINYSTL_ALGOBASE_H_
+#define MYTINYSTL_ALGOBASE_H_
+
+// 这个头文件包含了 mystl 的基本算法
+
+#include
+
+#include "iterator.h"
+#include "util.h"
+
+namespace mystl
+{
+
+#ifdef max
+#pragma message("#undefing marco max")
+#undef max
+#endif // max
+
+#ifdef min
+#pragma message("#undefing marco min")
+#undef min
+#endif // min
+
+/*****************************************************************************************/
+// max
+// 取二者中的较大值,语义相等时保证返回第一个参数
+/*****************************************************************************************/
+template
+const T& max(const T& lhs, const T& rhs)
+{
+ return lhs < rhs ? rhs : lhs;
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+const T& max(const T& lhs, const T& rhs, Compare comp)
+{
+ return comp(lhs, rhs) ? rhs : lhs;
+}
+
+/*****************************************************************************************/
+// min
+// 取二者中的较小值,语义相等时保证返回第一个参数
+/*****************************************************************************************/
+template
+const T& min(const T& lhs, const T& rhs)
+{
+ return rhs < lhs ? rhs : lhs;
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+const T& min(const T& lhs, const T& rhs, Compare comp)
+{
+ return comp(rhs, lhs) ? rhs : lhs;
+}
+
+/*****************************************************************************************/
+// iter_swap
+// 将两个迭代器所指对象对调
+/*****************************************************************************************/
+template
+void iter_swap(FIter1 lhs, FIter2 rhs)
+{
+ mystl::swap(*lhs, *rhs);
+}
+
+/*****************************************************************************************/
+// copy
+// 把 [first, last)区间内的元素拷贝到 [result, result + (last - first))内
+/*****************************************************************************************/
+// input_iterator_tag 版本
+template
+OutputIter
+unchecked_copy_cat(InputIter first, InputIter last, OutputIter result,
+ mystl::input_iterator_tag)
+{
+ for (; first != last; ++first, ++result)
+ {
+ *result = *first;
+ }
+ return result;
+}
+
+// ramdom_access_iterator_tag 版本
+template
+OutputIter
+unchecked_copy_cat(RandomIter first, RandomIter last, OutputIter result,
+ mystl::random_access_iterator_tag)
+{
+ for (auto n = last - first; n > 0; --n, ++first, ++result)
+ {
+ *result = *first;
+ }
+ return result;
+}
+
+template
+OutputIter
+unchecked_copy(InputIter first, InputIter last, OutputIter result)
+{
+ return unchecked_copy_cat(first, last, result, iterator_category(first));
+}
+
+// 为 trivially_copy_assignable 类型提供特化版本
+template
+typename std::enable_if<
+ std::is_same::type, Up>::value &&
+ std::is_trivially_copy_assignable::value,
+ Up*>::type
+unchecked_copy(Tp* first, Tp* last, Up* result)
+{
+ const auto n = static_cast(last - first);
+ if (n != 0)
+ std::memmove(result, first, n * sizeof(Up));
+ return result + n;
+}
+
+template
+OutputIter copy(InputIter first, InputIter last, OutputIter result)
+{
+ return unchecked_copy(first, last, result);
+}
+
+/*****************************************************************************************/
+// copy_backward
+// 将 [first, last)区间内的元素拷贝到 [result - (last - first), result)内
+/*****************************************************************************************/
+// unchecked_copy_backward_cat 的 bidirectional_iterator_tag 版本
+template
+BidirectionalIter2
+unchecked_copy_backward_cat(BidirectionalIter1 first, BidirectionalIter1 last,
+ BidirectionalIter2 result, mystl::bidirectional_iterator_tag)
+{
+ while (first != last)
+ *--result = *--last;
+ return result;
+}
+
+// unchecked_copy_backward_cat 的 random_access_iterator_tag 版本
+template
+BidirectionalIter2
+unchecked_copy_backward_cat(RandomIter1 first, RandomIter1 last,
+ BidirectionalIter2 result, mystl::random_access_iterator_tag)
+{
+ for (auto n = last - first; n > 0; --n)
+ *--result = *--last;
+ return result;
+}
+
+template
+BidirectionalIter2
+unchecked_copy_backward(BidirectionalIter1 first, BidirectionalIter1 last,
+ BidirectionalIter2 result)
+{
+ return unchecked_copy_backward_cat(first, last, result,
+ iterator_category(first));
+}
+
+// 为 trivially_copy_assignable 类型提供特化版本
+template
+typename std::enable_if<
+ std::is_same::type, Up>::value &&
+ std::is_trivially_copy_assignable::value,
+ Up*>::type
+unchecked_copy_backward(Tp* first, Tp* last, Up* result)
+{
+ const auto n = static_cast(last - first);
+ if (n != 0)
+ {
+ result -= n;
+ std::memmove(result, first, n * sizeof(Up));
+ }
+ return result;
+}
+
+template
+BidirectionalIter2
+copy_backward(BidirectionalIter1 first, BidirectionalIter1 last, BidirectionalIter2 result)
+{
+ return unchecked_copy_backward(first, last, result);
+}
+
+/*****************************************************************************************/
+// copy_if
+// 把[first, last)内满足一元操作 unary_pred 的元素拷贝到以 result 为起始的位置上
+/*****************************************************************************************/
+template
+OutputIter
+copy_if(InputIter first, InputIter last, OutputIter result, UnaryPredicate unary_pred)
+{
+ for (; first != last; ++first)
+ {
+ if (unary_pred(*first))
+ *result++ = *first;
+ }
+ return result;
+}
+
+/*****************************************************************************************/
+// copy_n
+// 把 [first, first + n)区间上的元素拷贝到 [result, result + n)上
+// 返回一个 pair 分别指向拷贝结束的尾部
+/*****************************************************************************************/
+template
+mystl::pair
+unchecked_copy_n(InputIter first, Size n, OutputIter result, mystl::input_iterator_tag)
+{
+ for (; n > 0; --n, ++first, ++result)
+ {
+ *result = *first;
+ }
+ return mystl::pair(first, result);
+}
+
+template
+mystl::pair
+unchecked_copy_n(RandomIter first, Size n, OutputIter result,
+ mystl::random_access_iterator_tag)
+{
+ auto last = first + n;
+ return mystl::pair(last, mystl::copy(first, last, result));
+}
+
+template
+mystl::pair
+copy_n(InputIter first, Size n, OutputIter result)
+{
+ return unchecked_copy_n(first, n, result, iterator_category(first));
+}
+
+/*****************************************************************************************/
+// move
+// 把 [first, last)区间内的元素移动到 [result, result + (last - first))内
+/*****************************************************************************************/
+// input_iterator_tag 版本
+template
+OutputIter
+unchecked_move_cat(InputIter first, InputIter last, OutputIter result,
+ mystl::input_iterator_tag)
+{
+ for (; first != last; ++first, ++result)
+ {
+ *result = mystl::move(*first);
+ }
+ return result;
+}
+
+// ramdom_access_iterator_tag 版本
+template
+OutputIter
+unchecked_move_cat(RandomIter first, RandomIter last, OutputIter result,
+ mystl::random_access_iterator_tag)
+{
+ for (auto n = last - first; n > 0; --n, ++first, ++result)
+ {
+ *result = mystl::move(*first);
+ }
+ return result;
+}
+
+template
+OutputIter
+unchecked_move(InputIter first, InputIter last, OutputIter result)
+{
+ return unchecked_move_cat(first, last, result, iterator_category(first));
+}
+
+// 为 trivially_copy_assignable 类型提供特化版本
+template
+typename std::enable_if<
+ std::is_same::type, Up>::value &&
+ std::is_trivially_move_assignable::value,
+ Up*>::type
+unchecked_move(Tp* first, Tp* last, Up* result)
+{
+ const size_t n = static_cast(last - first);
+ if (n != 0)
+ std::memmove(result, first, n * sizeof(Up));
+ return result + n;
+}
+
+template
+OutputIter move(InputIter first, InputIter last, OutputIter result)
+{
+ return unchecked_move(first, last, result);
+}
+
+/*****************************************************************************************/
+// move_backward
+// 将 [first, last)区间内的元素移动到 [result - (last - first), result)内
+/*****************************************************************************************/
+// bidirectional_iterator_tag 版本
+template
+BidirectionalIter2
+unchecked_move_backward_cat(BidirectionalIter1 first, BidirectionalIter1 last,
+ BidirectionalIter2 result, mystl::bidirectional_iterator_tag)
+{
+ while (first != last)
+ *--result = mystl::move(*--last);
+ return result;
+}
+
+// random_access_iterator_tag 版本
+template
+RandomIter2
+unchecked_move_backward_cat(RandomIter1 first, RandomIter1 last,
+ RandomIter2 result, mystl::random_access_iterator_tag)
+{
+ for (auto n = last - first; n > 0; --n)
+ *--result = mystl::move(*--last);
+ return result;
+}
+
+template
+BidirectionalIter2
+unchecked_move_backward(BidirectionalIter1 first, BidirectionalIter1 last,
+ BidirectionalIter2 result)
+{
+ return unchecked_move_backward_cat(first, last, result,
+ iterator_category(first));
+}
+
+// 为 trivially_copy_assignable 类型提供特化版本
+template
+typename std::enable_if<
+ std::is_same::type, Up>::value &&
+ std::is_trivially_move_assignable::value,
+ Up*>::type
+unchecked_move_backward(Tp* first, Tp* last, Up* result)
+{
+ const size_t n = static_cast(last - first);
+ if (n != 0)
+ {
+ result -= n;
+ std::memmove(result, first, n * sizeof(Up));
+ }
+ return result;
+}
+
+template
+BidirectionalIter2
+move_backward(BidirectionalIter1 first, BidirectionalIter1 last, BidirectionalIter2 result)
+{
+ return unchecked_move_backward(first, last, result);
+}
+
+/*****************************************************************************************/
+// equal
+// 比较第一序列在 [first, last)区间上的元素值是否和第二序列相等
+/*****************************************************************************************/
+template
+bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2)
+{
+ for (; first1 != last1; ++first1, ++first2)
+ {
+ if (*first1 != *first2)
+ return false;
+ }
+ return true;
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2, Compared comp)
+{
+ for (; first1 != last1; ++first1, ++first2)
+ {
+ if (!comp(*first1, *first2))
+ return false;
+ }
+ return true;
+}
+
+/*****************************************************************************************/
+// fill_n
+// 从 first 位置开始填充 n 个值
+/*****************************************************************************************/
+template
+OutputIter unchecked_fill_n(OutputIter first, Size n, const T& value)
+{
+ for (; n > 0; --n, ++first)
+ {
+ *first = value;
+ }
+ return first;
+}
+
+// 为 one-byte 类型提供特化版本
+template
+typename std::enable_if<
+ std::is_integral::value && sizeof(Tp) == 1 &&
+ !std::is_same::value &&
+ std::is_integral::value && sizeof(Up) == 1,
+ Tp*>::type
+unchecked_fill_n(Tp* first, Size n, Up value)
+{
+ if (n > 0)
+ {
+ std::memset(first, (unsigned char)value, (size_t)(n));
+ }
+ return first + n;
+}
+
+template
+OutputIter fill_n(OutputIter first, Size n, const T& value)
+{
+ return unchecked_fill_n(first, n, value);
+}
+
+/*****************************************************************************************/
+// fill
+// 为 [first, last)区间内的所有元素填充新值
+/*****************************************************************************************/
+template
+void fill_cat(ForwardIter first, ForwardIter last, const T& value,
+ mystl::forward_iterator_tag)
+{
+ for (; first != last; ++first)
+ {
+ *first = value;
+ }
+}
+
+template
+void fill_cat(RandomIter first, RandomIter last, const T& value,
+ mystl::random_access_iterator_tag)
+{
+ fill_n(first, last - first, value);
+}
+
+template
+void fill(ForwardIter first, ForwardIter last, const T& value)
+{
+ fill_cat(first, last, value, iterator_category(first));
+}
+
+/*****************************************************************************************/
+// lexicographical_compare
+// 以字典序排列对两个序列进行比较,当在某个位置发现第一组不相等元素时,有下列几种情况:
+// (1)如果第一序列的元素较小,返回 true ,否则返回 false
+// (2)如果到达 last1 而尚未到达 last2 返回 true
+// (3)如果到达 last2 而尚未到达 last1 返回 false
+// (4)如果同时到达 last1 和 last2 返回 false
+/*****************************************************************************************/
+template
+bool lexicographical_compare(InputIter1 first1, InputIter1 last1,
+ InputIter2 first2, InputIter2 last2)
+{
+ for (; first1 != last1 && first2 != last2; ++first1, ++first2)
+ {
+ if (*first1 < *first2)
+ return true;
+ if (*first2 < *first1)
+ return false;
+ }
+ return first1 == last1 && first2 != last2;
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+bool lexicographical_compare(InputIter1 first1, InputIter1 last1,
+ InputIter2 first2, InputIter2 last2, Compred comp)
+{
+ for (; first1 != last1 && first2 != last2; ++first1, ++first2)
+ {
+ if (comp(*first1, *first2))
+ return true;
+ if (comp(*first2, *first1))
+ return false;
+ }
+ return first1 == last1 && first2 != last2;
+}
+
+// 针对 const unsigned char* 的特化版本
+bool lexicographical_compare(const unsigned char* first1,
+ const unsigned char* last1,
+ const unsigned char* first2,
+ const unsigned char* last2)
+{
+ const auto len1 = last1 - first1;
+ const auto len2 = last2 - first2;
+ // 先比较相同长度的部分
+ const auto result = std::memcmp(first1, first2, mystl::min(len1, len2));
+ // 若相等,长度较长的比较大
+ return result != 0 ? result < 0 : len1 < len2;
+}
+
+/*****************************************************************************************/
+// mismatch
+// 平行比较两个序列,找到第一处失配的元素,返回一对迭代器,分别指向两个序列中失配的元素
+/*****************************************************************************************/
+template
+mystl::pair
+mismatch(InputIter1 first1, InputIter1 last1, InputIter2 first2)
+{
+ while (first1 != last1 && *first1 == *first2)
+ {
+ ++first1;
+ ++first2;
+ }
+ return mystl::pair(first1, first2);
+}
+
+// 重载版本使用函数对象 comp 代替比较操作
+template
+mystl::pair
+mismatch(InputIter1 first1, InputIter1 last1, InputIter2 first2, Compred comp)
+{
+ while (first1 != last1 && comp(*first1, *first2))
+ {
+ ++first1;
+ ++first2;
+ }
+ return mystl::pair(first1, first2);
+}
+
+} // namespace mystl
+#endif // !MYTINYSTL_ALGOBASE_H_
+
diff --git a/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/algorithm.h b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/algorithm.h
new file mode 100644
index 0000000..ee99e4f
--- /dev/null
+++ b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/algorithm.h
@@ -0,0 +1,18 @@
+#ifndef MYTINYSTL_ALGORITHM_H_
+#define MYTINYSTL_ALGORITHM_H_
+
+// 这个头文件包含了 mystl 的所有算法,包括基本算法,数值算法,heap 算法,set 算法和其他算法
+
+#include "algobase.h"
+#include "algo.h"
+#include "set_algo.h"
+#include "heap_algo.h"
+#include "numeric.h"
+
+namespace mystl
+{
+
+} // namespace mystl
+
+#endif // !MYTINYSTL_ALGORITHM_H_
+
diff --git a/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/alloc.h b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/alloc.h
new file mode 100644
index 0000000..93d3bcf
--- /dev/null
+++ b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/alloc.h
@@ -0,0 +1,264 @@
+#ifndef MYTINYSTL_ALLOC_H_
+#define MYTINYSTL_ALLOC_H_
+
+// 这个头文件包含一个类 alloc,用于分配和回收内存,以内存池的方式实现
+//
+// 从 v2.0.0 版本开始,将不再使用内存池,这个文件将被弃用,但暂时保留
+//
+// 注意!!!
+// 我知道这个文件里很多实现是错的,这是很久很久前写的了,后面已经不用这个东西了,
+// 所以我也没再维护,有诸多问题,已经有人在issue中都提了,free_list的修改,
+// 指针作为参数时没实际修改到原指针,等等。相信会看这么仔细的,大部分都是
+// 初学C++的朋友,大佬都不会看这些玩具了,所以其中的错误,就留给对内存池实现
+// 感兴趣的朋友去修改啦!
+
+#include
+
+#include
+#include
+
+namespace mystl
+{
+
+// 共用体: FreeList
+// 采用链表的方式管理内存碎片,分配与回收小内存(<=4K)区块
+union FreeList
+{
+ union FreeList* next; // 指向下一个区块
+ char data[1]; // 储存本块内存的首地址
+};
+
+// 不同内存范围的上调大小
+enum
+{
+ EAlign128 = 8,
+ EAlign256 = 16,
+ EAlign512 = 32,
+ EAlign1024 = 64,
+ EAlign2048 = 128,
+ EAlign4096 = 256
+};
+
+// 小对象的内存大小
+enum { ESmallObjectBytes = 4096 };
+
+// free lists 个数
+enum { EFreeListsNumber = 56 };
+
+// 空间配置类 alloc
+// 如果内存较大,超过 4096 bytes,直接调用 std::malloc, std::free
+// 当内存较小时,以内存池管理,每次配置一大块内存,并维护对应的自由链表
+class alloc
+{
+private:
+ static char* start_free; // 内存池起始位置
+ static char* end_free; // 内存池结束位置
+ static size_t heap_size; // 申请 heap 空间附加值大小
+
+ static FreeList* free_list[EFreeListsNumber]; // 自由链表
+
+public:
+ static void* allocate(size_t n);
+ static void deallocate(void* p, size_t n);
+ static void* reallocate(void* p, size_t old_size, size_t new_size);
+
+private:
+ static size_t M_align(size_t bytes);
+ static size_t M_round_up(size_t bytes);
+ static size_t M_freelist_index(size_t bytes);
+ static void* M_refill(size_t n);
+ static char* M_chunk_alloc(size_t size, size_t &nobj);
+};
+
+// 静态成员变量初始化
+
+char* alloc::start_free = nullptr;
+char* alloc::end_free = nullptr;
+size_t alloc::heap_size = 0;
+
+FreeList* alloc::free_list[EFreeListsNumber] = {
+ nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,
+ nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,
+ nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,
+ nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,
+ nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,
+ nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,
+ nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr
+ };
+
+// 分配大小为 n 的空间, n > 0
+inline void* alloc::allocate(size_t n)
+{
+ FreeList* my_free_list;
+ FreeList* result;
+ if (n > static_cast(ESmallObjectBytes))
+ return std::malloc(n);
+ my_free_list = free_list[M_freelist_index(n)];
+ result = my_free_list;
+ if (result == nullptr)
+ {
+ void* r = M_refill(M_round_up(n));
+ return r;
+ }
+ my_free_list = result->next;
+ return result;
+}
+
+// 释放 p 指向的大小为 n 的空间, p 不能为 0
+inline void alloc::deallocate(void* p, size_t n)
+{
+ if (n > static_cast(ESmallObjectBytes))
+ {
+ std::free(p);
+ return;
+ }
+ FreeList* q = reinterpret_cast(p);
+ FreeList* my_free_list;
+ my_free_list = free_list[M_freelist_index(n)];
+ q->next = my_free_list;
+ my_free_list = q;
+}
+
+// 重新分配空间,接受三个参数,参数一为指向新空间的指针,参数二为原来空间的大小,参数三为申请空间的大小
+inline void* alloc::reallocate(void* p, size_t old_size, size_t new_size)
+{
+ deallocate(p, old_size);
+ p = allocate(new_size);
+ return p;
+}
+
+// bytes 对应上调大小
+inline size_t alloc::M_align(size_t bytes)
+{
+ if (bytes <= 512)
+ {
+ return bytes <= 256
+ ? bytes <= 128 ? EAlign128 : EAlign256
+ : EAlign512;
+ }
+ return bytes <= 2048
+ ? bytes <= 1024 ? EAlign1024 : EAlign2048
+ : EAlign4096;
+}
+
+// 将 bytes 上调至对应区间大小
+inline size_t alloc::M_round_up(size_t bytes)
+{
+ return ((bytes + M_align(bytes) - 1) & ~(M_align(bytes) - 1));
+}
+
+// 根据区块大小,选择第 n 个 free lists
+inline size_t alloc::M_freelist_index(size_t bytes)
+{
+ if (bytes <= 512)
+ {
+ return bytes <= 256
+ ? bytes <= 128
+ ? ((bytes + EAlign128 - 1) / EAlign128 - 1)
+ : (15 + (bytes + EAlign256 - 129) / EAlign256)
+ : (23 + (bytes + EAlign512 - 257) / EAlign512);
+ }
+ return bytes <= 2048
+ ? bytes <= 1024
+ ? (31 + (bytes + EAlign1024 - 513) / EAlign1024)
+ : (39 + (bytes + EAlign2048 - 1025) / EAlign2048)
+ : (47 + (bytes + EAlign4096 - 2049) / EAlign4096);
+}
+
+// 重新填充 free list
+void* alloc::M_refill(size_t n)
+{
+ size_t nblock = 10;
+ char* c = M_chunk_alloc(n, nblock);
+ FreeList* my_free_list;
+ FreeList* result, *cur, *next;
+ // 如果只有一个区块,就把这个区块返回给调用者,free list 没有增加新节点
+ if (nblock == 1)
+ return c;
+ // 否则把一个区块给调用者,剩下的纳入 free list 作为新节点
+ my_free_list = free_list[M_freelist_index(n)];
+ result = (FreeList*)c;
+ my_free_list = next = (FreeList*)(c + n);
+ for (size_t i = 1; ; ++i)
+ {
+ cur = next;
+ next = (FreeList*)((char*)next + n);
+ if (nblock - 1 == i)
+ {
+ cur->next = nullptr;
+ break;
+ }
+ else
+ {
+ cur->next = next;
+ }
+ }
+ return result;
+}
+
+// 从内存池中取空间给 free list 使用,条件不允许时,会调整 nblock
+char* alloc::M_chunk_alloc(size_t size, size_t& nblock)
+{
+ char* result;
+ size_t need_bytes = size * nblock;
+ size_t pool_bytes = end_free - start_free;
+
+ // 如果内存池剩余大小完全满足需求量,返回它
+ if (pool_bytes >= need_bytes)
+ {
+ result = start_free;
+ start_free += need_bytes;
+ return result;
+ }
+
+ // 如果内存池剩余大小不能完全满足需求量,但至少可以分配一个或一个以上的区块,就返回它
+ else if (pool_bytes >= size)
+ {
+ nblock = pool_bytes / size;
+ need_bytes = size * nblock;
+ result = start_free;
+ start_free += need_bytes;
+ return result;
+ }
+
+ // 如果内存池剩余大小连一个区块都无法满足
+ else
+ {
+ if (pool_bytes > 0)
+ { // 如果内存池还有剩余,把剩余的空间加入到 free list 中
+ FreeList* my_free_list = free_list[M_freelist_index(pool_bytes)];
+ ((FreeList*)start_free)->next = my_free_list;
+ my_free_list = (FreeList*)start_free;
+ }
+ // 申请 heap 空间
+ size_t bytes_to_get = (need_bytes << 1) + M_round_up(heap_size >> 4);
+ start_free = (char*)std::malloc(bytes_to_get);
+ if (!start_free)
+ { // heap 空间也不够
+ FreeList* my_free_list, *p;
+ // 试着查找有无未用区块,且区块足够大的 free list
+ for (size_t i = size; i <= ESmallObjectBytes; i += M_align(i))
+ {
+ my_free_list = free_list[M_freelist_index(i)];
+ p = my_free_list;
+ if (p)
+ {
+ my_free_list = p->next;
+ start_free = (char*)p;
+ end_free = start_free + i;
+ return M_chunk_alloc(size, nblock);
+ }
+ }
+ std::printf("out of memory");
+ end_free = nullptr;
+ throw std::bad_alloc();
+ }
+ end_free = start_free + bytes_to_get;
+ heap_size += bytes_to_get;
+ return M_chunk_alloc(size, nblock);
+ }
+}
+
+} // namespace mystl
+#endif // !MYTINYSTL_ALLOC_H_
+
diff --git a/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/allocator.h b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/allocator.h
new file mode 100644
index 0000000..a3a5d4e
--- /dev/null
+++ b/MyTinySTL/src/MyTinySTL-master/MyTinySTL-master/MyTinySTL/allocator.h
@@ -0,0 +1,113 @@
+#ifndef MYTINYSTL_ALLOCATOR_H_
+#define MYTINYSTL_ALLOCATOR_H_
+
+// 这个头文件包含一个模板类 allocator,用于管理内存的分配、释放,对象的构造、析构
+
+#include "construct.h"
+#include "util.h"
+
+namespace mystl
+{
+
+// 模板类:allocator
+// 模板函数代表数据类型
+template
+class allocator
+{
+public:
+ typedef T value_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+public:
+ static T* allocate();
+ static T* allocate(size_type n);
+
+ static void deallocate(T* ptr);
+ static void deallocate(T* ptr, size_type n);
+
+ static void construct(T* ptr);
+ static void construct(T* ptr, const T& value);
+ static void construct(T* ptr, T&& value);
+
+ template
+ static void construct(T* ptr, Args&& ...args);
+
+ static void destroy(T* ptr);
+ static void destroy(T* first, T* last);
+};
+
+template
+T* allocator::allocate()
+{
+ return static_cast(::operator new(sizeof(T)));
+}
+
+template
+T* allocator::allocate(size_type n)
+{
+ if (n == 0)
+ return nullptr;
+ return static_cast(::operator new(n * sizeof(T)));
+}
+
+template
+void allocator