Showing preview only (644K chars total). Download the full file or copy to clipboard to get everything.
Repository: Alinshans/MyTinySTL
Branch: master
Commit: f86437ecffe8
Files: 59
Total size: 620.5 KB
Directory structure:
gitextract_bjpk8nmi/
├── .gitattributes
├── .gitignore
├── .travis.yml
├── CMakeLists.txt
├── License.txt
├── MSVC/
│ ├── MyTinySTL_VS2015.sln
│ ├── MyTinySTL_VS2015.vcxproj
│ └── MyTinySTL_VS2015.vcxproj.filters
├── MyTinySTL/
│ ├── algo.h
│ ├── algobase.h
│ ├── algorithm.h
│ ├── alloc.h
│ ├── allocator.h
│ ├── astring.h
│ ├── basic_string.h
│ ├── construct.h
│ ├── deque.h
│ ├── exceptdef.h
│ ├── functional.h
│ ├── hashtable.h
│ ├── heap_algo.h
│ ├── iterator.h
│ ├── list.h
│ ├── map.h
│ ├── memory.h
│ ├── numeric.h
│ ├── queue.h
│ ├── rb_tree.h
│ ├── set.h
│ ├── set_algo.h
│ ├── stack.h
│ ├── stream_iterator.h
│ ├── type_traits.h
│ ├── uninitialized.h
│ ├── unordered_map.h
│ ├── unordered_set.h
│ ├── util.h
│ └── vector.h
├── README.md
├── Test/
│ ├── CMakeLists.txt
│ ├── Lib/
│ │ └── redbud/
│ │ ├── io/
│ │ │ └── color.h
│ │ └── platform.h
│ ├── README.md
│ ├── algorithm_performance_test.h
│ ├── algorithm_test.h
│ ├── deque_test.h
│ ├── iterator_test.h
│ ├── list_test.h
│ ├── map_test.h
│ ├── queue_test.h
│ ├── set_test.h
│ ├── stack_test.h
│ ├── string_test.h
│ ├── test.cpp
│ ├── test.h
│ ├── unordered_map_test.h
│ ├── unordered_set_test.h
│ └── vector_test.h
└── appveyor.yml
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
###############################################################################
# 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
================================================
FILE: .gitignore
================================================
## 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/
================================================
FILE: .travis.yml
================================================
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
================================================
FILE: CMakeLists.txt
================================================
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)
================================================
FILE: License.txt
================================================
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.
================================================
FILE: MSVC/MyTinySTL_VS2015.sln
================================================
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
================================================
FILE: MSVC/MyTinySTL_VS2015.vcxproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{E88807F6-B07C-4371-BD38-FB1569F894E4}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>MyTinySTL</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<ProjectName>MyTinySTL</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\Test\algorithm_performance_test.h" />
<ClInclude Include="..\Test\algorithm_test.h" />
<ClInclude Include="..\Test\deque_test.h" />
<ClInclude Include="..\Test\Lib\redbud\io\color.h" />
<ClInclude Include="..\Test\Lib\redbud\platform.h" />
<ClInclude Include="..\Test\list_test.h" />
<ClInclude Include="..\Test\map_test.h" />
<ClInclude Include="..\Test\queue_test.h" />
<ClInclude Include="..\Test\set_test.h" />
<ClInclude Include="..\Test\stack_test.h" />
<ClInclude Include="..\Test\string_test.h" />
<ClInclude Include="..\Test\test.h" />
<ClInclude Include="..\Test\unordered_map_test.h" />
<ClInclude Include="..\Test\unordered_set_test.h" />
<ClInclude Include="..\Test\vector_test.h" />
<ClInclude Include="..\MyTinySTL\algo.h" />
<ClInclude Include="..\MyTinySTL\algobase.h" />
<ClInclude Include="..\MyTinySTL\algorithm.h" />
<ClInclude Include="..\MyTinySTL\alloc.h" />
<ClInclude Include="..\MyTinySTL\allocator.h" />
<ClInclude Include="..\MyTinySTL\basic_string.h" />
<ClInclude Include="..\MyTinySTL\construct.h" />
<ClInclude Include="..\MyTinySTL\deque.h" />
<ClInclude Include="..\MyTinySTL\exceptdef.h" />
<ClInclude Include="..\MyTinySTL\functional.h" />
<ClInclude Include="..\MyTinySTL\hashtable.h" />
<ClInclude Include="..\MyTinySTL\unordered_map.h" />
<ClInclude Include="..\MyTinySTL\unordered_set.h" />
<ClInclude Include="..\MyTinySTL\heap_algo.h" />
<ClInclude Include="..\MyTinySTL\iterator.h" />
<ClInclude Include="..\MyTinySTL\list.h" />
<ClInclude Include="..\MyTinySTL\map.h" />
<ClInclude Include="..\MyTinySTL\memory.h" />
<ClInclude Include="..\MyTinySTL\numeric.h" />
<ClInclude Include="..\MyTinySTL\queue.h" />
<ClInclude Include="..\MyTinySTL\rb_tree.h" />
<ClInclude Include="..\MyTinySTL\set.h" />
<ClInclude Include="..\MyTinySTL\set_algo.h" />
<ClInclude Include="..\MyTinySTL\stack.h" />
<ClInclude Include="..\MyTinySTL\astring.h" />
<ClInclude Include="..\MyTinySTL\type_traits.h" />
<ClInclude Include="..\MyTinySTL\uninitialized.h" />
<ClInclude Include="..\MyTinySTL\util.h" />
<ClInclude Include="..\MyTinySTL\vector.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\Test\test.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
================================================
FILE: MSVC/MyTinySTL_VS2015.vcxproj.filters
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="资源文件">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="include">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="source">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="test">
<UniqueIdentifier>{ec314ff3-dcde-4cac-a63a-4f6827750d0a}</UniqueIdentifier>
</Filter>
<Filter Include="test\Lib">
<UniqueIdentifier>{c6f24d77-e6f0-439e-954a-c0ca577689d5}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\MyTinySTL\type_traits.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\construct.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\alloc.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\allocator.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\uninitialized.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\iterator.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\numeric.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\algobase.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\heap_algo.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\set_algo.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\algo.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\algorithm.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\vector.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\memory.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\list.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\deque.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\stack.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\queue.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\functional.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\rb_tree.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\set.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\map.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\hashtable.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\basic_string.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\unordered_set.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\unordered_map.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\Test\algorithm_performance_test.h">
<Filter>test</Filter>
</ClInclude>
<ClInclude Include="..\Test\algorithm_test.h">
<Filter>test</Filter>
</ClInclude>
<ClInclude Include="..\Test\deque_test.h">
<Filter>test</Filter>
</ClInclude>
<ClInclude Include="..\Test\list_test.h">
<Filter>test</Filter>
</ClInclude>
<ClInclude Include="..\Test\map_test.h">
<Filter>test</Filter>
</ClInclude>
<ClInclude Include="..\Test\queue_test.h">
<Filter>test</Filter>
</ClInclude>
<ClInclude Include="..\Test\set_test.h">
<Filter>test</Filter>
</ClInclude>
<ClInclude Include="..\Test\stack_test.h">
<Filter>test</Filter>
</ClInclude>
<ClInclude Include="..\Test\string_test.h">
<Filter>test</Filter>
</ClInclude>
<ClInclude Include="..\Test\test.h">
<Filter>test</Filter>
</ClInclude>
<ClInclude Include="..\Test\unordered_map_test.h">
<Filter>test</Filter>
</ClInclude>
<ClInclude Include="..\Test\unordered_set_test.h">
<Filter>test</Filter>
</ClInclude>
<ClInclude Include="..\Test\vector_test.h">
<Filter>test</Filter>
</ClInclude>
<ClInclude Include="..\Test\Lib\redbud\platform.h">
<Filter>test\Lib</Filter>
</ClInclude>
<ClInclude Include="..\Test\Lib\redbud\io\color.h">
<Filter>test\Lib</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\astring.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\util.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\MyTinySTL\exceptdef.h">
<Filter>include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\Test\test.cpp">
<Filter>test</Filter>
</ClCompile>
</ItemGroup>
</Project>
================================================
FILE: MyTinySTL/algo.h
================================================
#ifndef MYTINYSTL_ALGO_H_
#define MYTINYSTL_ALGO_H_
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4244)
#endif
// 这个头文件包含了 mystl 的一系列算法
#include <cstddef>
#include <ctime>
#include "algobase.h"
#include "memory.h"
#include "heap_algo.h"
#include "functional.h"
namespace mystl
{
/*****************************************************************************************/
// all_of
// 检查[first, last)内是否全部元素都满足一元操作 unary_pred 为 true 的情况,满足则返回 true
/*****************************************************************************************/
template <class InputIter, class UnaryPredicate>
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 <class InputIter, class UnaryPredicate>
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 <class InputIter, class UnaryPredicate>
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 <class InputIter, class T>
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 <class InputIter, class UnaryPredicate>
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 <class InputIter, class T>
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 <class InputIter, class UnaryPredicate>
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 <class InputIter, class UnaryPredicate>
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 <class ForwardIter1, class ForwardIter2>
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 <class ForwardIter1, class ForwardIter2, class Compared>
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 <class ForwardIter, class Size, class T>
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 <class ForwardIter, class Size, class T, class Compared>
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 <class ForwardIter1, class ForwardIter2>
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 <class BidirectionalIter1, class BidirectionalIter2>
BidirectionalIter1
find_end_dispatch(BidirectionalIter1 first1, BidirectionalIter1 last1,
BidirectionalIter2 first2, BidirectionalIter2 last2,
bidirectional_iterator_tag, bidirectional_iterator_tag)
{
typedef reverse_iterator<BidirectionalIter1> reviter1;
typedef reverse_iterator<BidirectionalIter2> 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 <class ForwardIter1, class ForwardIter2>
ForwardIter1
find_end(ForwardIter1 first1, ForwardIter1 last1,
ForwardIter2 first2, ForwardIter2 last2)
{
typedef typename iterator_traits<ForwardIter1>::iterator_category Category1;
typedef typename iterator_traits<ForwardIter2>::iterator_category Category2;
return mystl::find_end_dispatch(first1, last1, first2, last2, Category1(), Category2());
}
// 重载版本使用函数对象 comp 代替比较操作
// find_end_dispatch 的 forward_iterator_tag 版本
template <class ForwardIter1, class ForwardIter2, class Compared>
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 <class BidirectionalIter1, class BidirectionalIter2, class Compared>
BidirectionalIter1
find_end_dispatch(BidirectionalIter1 first1, BidirectionalIter1 last1,
BidirectionalIter2 first2, BidirectionalIter2 last2,
bidirectional_iterator_tag, bidirectional_iterator_tag, Compared comp)
{
typedef reverse_iterator<BidirectionalIter1> reviter1;
typedef reverse_iterator<BidirectionalIter2> 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 <class ForwardIter1, class ForwardIter2, class Compared>
ForwardIter1
find_end(ForwardIter1 first1, ForwardIter1 last1,
ForwardIter2 first2, ForwardIter2 last2, Compared comp)
{
typedef typename iterator_traits<ForwardIter1>::iterator_category Category1;
typedef typename iterator_traits<ForwardIter2>::iterator_category Category2;
return mystl::find_end_dispatch(first1, last1, first2, last2, Category1(), Category2(), comp);
}
/*****************************************************************************************/
// find_first_of
// 在[first1, last1)中查找[first2, last2)中的某些元素,返回指向第一次出现的元素的迭代器
/*****************************************************************************************/
template <class InputIter, class ForwardIter>
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 <class InputIter, class ForwardIter, class Compared>
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 <class InputIter, class Function>
Function for_each(InputIter first, InputIter last, Function f)
{
for (; first != last; ++first)
{
f(*first);
}
return f;
}
/*****************************************************************************************/
// adjacent_find
// 找出第一对匹配的相邻元素,缺省使用 operator== 比较,如果找到返回一个迭代器,指向这对元素的第一个元素
/*****************************************************************************************/
template <class ForwardIter>
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 <class ForwardIter, class Compared>
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 <class ForwardIter, class T>
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 <class RandomIter, class T>
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 <class ForwardIter, class T>
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 <class ForwardIter, class T, class Compared>
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 <class RandomIter, class T, class Compared>
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 <class ForwardIter, class T, class Compared>
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 <class ForwardIter, class T>
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 <class RandomIter, class T>
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 <class ForwardIter, class T>
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 <class ForwardIter, class T, class Compared>
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 <class RandomIter, class T, class Compared>
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 <class ForwardIter, class T, class Compared>
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 <class ForwardIter, class T>
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 <class ForwardIter, class T, class Compared>
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 <class ForwardIter, class T>
mystl::pair<ForwardIter, ForwardIter>
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<ForwardIter, ForwardIter>(left, right);
}
}
return mystl::pair<ForwardIter, ForwardIter>(last, last);
}
// erange_dispatch 的 random_access_iterator_tag 版本
template <class RandomIter, class T>
mystl::pair<RandomIter, RandomIter>
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<RandomIter, RandomIter>(left, right);
}
}
return mystl::pair<RandomIter, RandomIter>(last, last);
}
template <class ForwardIter, class T>
mystl::pair<ForwardIter, ForwardIter>
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 <class ForwardIter, class T, class Compared>
mystl::pair<ForwardIter, ForwardIter>
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<ForwardIter, ForwardIter>(left, right);
}
}
return mystl::pair<ForwardIter, ForwardIter>(last, last);
}
// erange_dispatch 的 random access iterator 版本
template <class RandomIter, class T, class Compared>
mystl::pair<RandomIter, RandomIter>
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<RandomIter, RandomIter>(left, right);
}
}
return mystl::pair<RandomIter, RandomIter>(last, last);
}
template <class ForwardIter, class T, class Compared>
mystl::pair<ForwardIter, ForwardIter>
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 <class ForwardIter, class Generator>
void generate(ForwardIter first, ForwardIter last, Generator gen)
{
for (; first != last; ++first)
{
*first = gen();
}
}
/*****************************************************************************************/
// generate_n
// 用函数对象 gen 连续对 n 个元素赋值
/*****************************************************************************************/
template <class ForwardIter, class Size, class Generator>
void generate_n(ForwardIter first, Size n, Generator gen)
{
for (; n > 0; --n, ++first)
{
*first = gen();
}
}
/*****************************************************************************************/
// includes
// 判断序列一S1 是否包含序列二S2
/*****************************************************************************************/
template <class InputIter1, class InputIter2>
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 <class InputIter1, class InputIter2, class Compared>
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 <class RandomIter>
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 <class RandomIter, class Compared>
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 <class ForwardIter>
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 <class ForwardIter, class Compared>
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 <class T>
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 <class T, class Compared>
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 <class ForwardIter>
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 <class ForwardIter, class Compared>
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 <class ForwardIter>
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 <class ForwardIter, class Compared>
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 <class ForwardIter1, class ForwardIter2>
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 <class InputIter, class OutputIter, class UnaryOperation>
OutputIter
transform(InputIter first, InputIter last,
OutputIter result, UnaryOperation unary_op)
{
for (; first != last; ++first, ++result)
{
*result = unary_op(*first);
}
return result;
}
template <class InputIter1, class InputIter2, class OutputIter, class BinaryOperation>
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 <class InputIter, class OutputIter, class T>
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 <class ForwardIter, class T>
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 <class InputIter, class OutputIter, class UnaryPredicate>
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 <class ForwardIter, class UnaryPredicate>
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 <class ForwardIter, class T>
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 <class InputIter, class OutputIter, class T>
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 <class InputIter, class OutputIter, class UnaryPredicate, class T>
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 <class ForwardIter, class UnaryPredicate, class T>
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 <class BidirectionalIter>
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 <class RandomIter>
void reverse_dispatch(RandomIter first, RandomIter last,
random_access_iterator_tag)
{
while (first < last)
mystl::iter_swap(first++, --last);
}
template <class BidirectionalIter>
void reverse(BidirectionalIter first, BidirectionalIter last)
{
mystl::reverse_dispatch(first, last, iterator_category(first));
}
/*****************************************************************************************/
// reverse_copy
// 行为与 reverse 类似,不同的是将结果复制到 result 所指容器中
/*****************************************************************************************/
template <class BidirectionalIter, class OutputIter>
OutputIter
reverse_copy(BidirectionalIter first, BidirectionalIter last,
OutputIter result)
{
while (first != last)
{
--last;
*result = *last;
++result;
}
return result;
}
/*****************************************************************************************/
// random_shuffle
// 将[first, last)内的元素次序随机重排
// 重载版本使用一个产生随机数的函数对象 rand
/*****************************************************************************************/
template <class RandomIter>
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 <class RandomIter, class RandomNumberGenerator>
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 <class ForwardIter>
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 <class BidirectionalIter>
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 <class EuclideanRingElement>
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 <class RandomIter>
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 <class ForwardIter>
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 <class ForwardIter, class OutputIter>
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 <class ForwardIter1, class ForwardIter2, class BinaryPred>
bool is_permutation_aux(ForwardIter1 first1, ForwardIter1 last1,
ForwardIter2 first2, ForwardIter2 last2,
BinaryPred pred)
{
constexpr bool is_ra_it = mystl::is_random_access_iterator<ForwardIter1>::value
&& mystl::is_random_access_iterator<ForwardIter2>::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 <class ForwardIter1, class ForwardIter2, class BinaryPred>
bool is_permutation(ForwardIter1 first1, ForwardIter1 last1,
ForwardIter2 first2, ForwardIter2 last2,
BinaryPred pred)
{
return is_permutation_aux(first1, last1, first2, last2, pred);
}
template <class ForwardIter1, class ForwardIter2>
bool is_permutation(ForwardIter1 first1, ForwardIter1 last1,
ForwardIter2 first2, ForwardIter2 last2)
{
typedef typename iterator_traits<ForwardIter1>::value_type v1;
typedef typename iterator_traits<ForwardIter2>::value_type v2;
static_assert(std::is_same<v1, v2>::value,
"the type should be same in mystl::is_permutation");
return is_permutation_aux(first1, last1, first2, last2,
mystl::equal_to<v1>());
}
/*****************************************************************************************/
// next_permutation
// 取得[first, last)所标示序列的下一个排列组合,如果没有下一个排序组合,返回 false,否则返回 true
/*****************************************************************************************/
template <class BidirectionalIter>
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 <class BidirectionalIter, class Compared>
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 <class BidirectionalIter>
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 <class BidirectionalIter, class Compared>
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 <class InputIter1, class InputIter2, class OutputIter>
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 <class InputIter1, class InputIter2, class OutputIter, class Compared>
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 <class BidirectionalIter, class Distance>
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 <class BidirectionalIter1, class BidirectionalIter2>
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 <class BidirectionalIter1, class BidirectionalIter2, class Distance>
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 <class BidirectionalIter, class Distance, class Pointer>
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 <class BidirectionalIter, class T>
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<BidirectionalIter, T> 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 <class BidirectionalIter>
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 <class BidirectionalIter, class Distance, class Compared>
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 <class BidirectionalIter1, class BidirectionalIter2, class Compared>
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 <class BidirectionalIter, class Distance, class Pointer, class Compared>
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 <class BidirectionalIter, class T, class Compared>
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<BidirectionalIter, T> 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 <class BidirectionalIter, class Compared>
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 <class RandomIter>
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 <class RandomIter, class Compared>
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 <class InputIter, class RandomIter, class Distance>
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<Distance>(0),
result_iter - result_first, *first);
}
++first;
}
mystl::sort_heap(result_first, result_iter);
return result_iter;
}
template <class InputIter, class RandomIter>
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 <class InputIter, class RandomIter, class Distance, class Compared>
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<Distance>(0),
result_iter - result_first, *first, comp);
}
++first;
}
mystl::sort_heap(result_first, result_iter, comp);
return result_iter;
}
template <class InputIter, class RandomIter, class Compared>
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 <class BidirectionalIter, class UnaryPredicate>
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 <class InputIter, class OutputIter1, class OutputIter2, class UnaryPredicate>
mystl::pair<OutputIter1, OutputIter2>
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<OutputIter1, OutputIter2>(result_true, result_false);
}
/*****************************************************************************************/
// sort
// 将[first, last)内的元素以递增的方式排序
/*****************************************************************************************/
constexpr static size_t kSmallSectionSize = 128; // 小型区间的大小,在这个大小内采用插入排序
// 用于控制分割恶化的情况
template <class Size>
Size slg2(Size n)
{ // 找出 lgk <= n 的 k 的最大值
Size k = 0;
for (; n > 1; n >>= 1)
++k;
return k;
}
// 分割函数 unchecked_partition
template <class RandomIter, class T>
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 <class RandomIter, class Size>
void intro_sort(RandomIter first, RandomIter last, Size depth_limit)
{
while (static_cast<size_t>(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 <class RandomIter, class T>
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 <class RandomIter>
void unchecked_insertion_sort(RandomIter first, RandomIter last)
{
for (auto i = first; i != last; ++i)
{
mystl::unchecked_linear_insert(i, *i);
}
}
// 插入排序函数 insertion_sort
template <class RandomIter>
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 <class RandomIter>
void final_insertion_sort(RandomIter first, RandomIter last)
{
if (static_cast<size_t>(last - first) > kSmallSectionSize)
{
mystl::insertion_sort(first, first + kSmallSectionSize);
mystl::unchecked_insertion_sort(first + kSmallSectionSize, last);
}
else
{
mystl::insertion_sort(first, last);
}
}
template <class RandomIter>
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 <class RandomIter, class T, class Compared>
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 <class RandomIter, class Size, class Compared>
void intro_sort(RandomIter first, RandomIter last,
Size depth_limit, Compared comp)
{
while (static_cast<size_t>(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 <class RandomIter, class T, class Compared>
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 <class RandomIter, class Compared>
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 <class RandomIter, class Compared>
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 <class RandomIter, class Compared>
void final_insertion_sort(RandomIter first, RandomIter last, Compared comp)
{
if (static_cast<size_t>(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 <class RandomIter, class Compared>
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 <class RandomIter>
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 <class RandomIter, class Compared>
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 <class InputIter, class ForwardIter>
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 <class InputIter, class OutputIter>
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 <class InputIter, class OutputIter>
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 <class InputIter, class ForwardIter, class Compared>
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 <class InputIter, class OutputIter, class Compared>
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 <class InputIter, class OutputIter, class Compared>
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 <class ForwardIter>
ForwardIter unique(ForwardIter first, ForwardIter last)
{
first = mystl::adjacent_find(first, last);
return mystl::unique_copy(first, last, first);
}
// 重载版本使用函数对象 comp 代替比较操作
template <class ForwardIter, class Compared>
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_
================================================
FILE: MyTinySTL/algobase.h
================================================
#ifndef MYTINYSTL_ALGOBASE_H_
#define MYTINYSTL_ALGOBASE_H_
// 这个头文件包含了 mystl 的基本算法
#include <cstring>
#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 <class T>
const T& max(const T& lhs, const T& rhs)
{
return lhs < rhs ? rhs : lhs;
}
// 重载版本使用函数对象 comp 代替比较操作
template <class T, class Compare>
const T& max(const T& lhs, const T& rhs, Compare comp)
{
return comp(lhs, rhs) ? rhs : lhs;
}
/*****************************************************************************************/
// min
// 取二者中的较小值,语义相等时保证返回第一个参数
/*****************************************************************************************/
template <class T>
const T& min(const T& lhs, const T& rhs)
{
return rhs < lhs ? rhs : lhs;
}
// 重载版本使用函数对象 comp 代替比较操作
template <class T, class Compare>
const T& min(const T& lhs, const T& rhs, Compare comp)
{
return comp(rhs, lhs) ? rhs : lhs;
}
/*****************************************************************************************/
// iter_swap
// 将两个迭代器所指对象对调
/*****************************************************************************************/
template <class FIter1, class FIter2>
void iter_swap(FIter1 lhs, FIter2 rhs)
{
mystl::swap(*lhs, *rhs);
}
/*****************************************************************************************/
// copy
// 把 [first, last)区间内的元素拷贝到 [result, result + (last - first))内
/*****************************************************************************************/
// input_iterator_tag 版本
template <class InputIter, class OutputIter>
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 <class RandomIter, class OutputIter>
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 <class InputIter, class OutputIter>
OutputIter
unchecked_copy(InputIter first, InputIter last, OutputIter result)
{
return unchecked_copy_cat(first, last, result, iterator_category(first));
}
// 为 trivially_copy_assignable 类型提供特化版本
template <class Tp, class Up>
typename std::enable_if<
std::is_same<typename std::remove_const<Tp>::type, Up>::value &&
std::is_trivially_copy_assignable<Up>::value,
Up*>::type
unchecked_copy(Tp* first, Tp* last, Up* result)
{
const auto n = static_cast<size_t>(last - first);
if (n != 0)
std::memmove(result, first, n * sizeof(Up));
return result + n;
}
template <class InputIter, class OutputIter>
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 <class BidirectionalIter1, class BidirectionalIter2>
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 <class RandomIter1, class BidirectionalIter2>
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 <class BidirectionalIter1, class BidirectionalIter2>
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 <class Tp, class Up>
typename std::enable_if<
std::is_same<typename std::remove_const<Tp>::type, Up>::value &&
std::is_trivially_copy_assignable<Up>::value,
Up*>::type
unchecked_copy_backward(Tp* first, Tp* last, Up* result)
{
const auto n = static_cast<size_t>(last - first);
if (n != 0)
{
result -= n;
std::memmove(result, first, n * sizeof(Up));
}
return result;
}
template <class BidirectionalIter1, class BidirectionalIter2>
BidirectionalIter2
copy_backward(BidirectionalIter1 first, BidirectionalIter1 last, BidirectionalIter2 result)
{
return unchecked_copy_backward(first, last, result);
}
/*****************************************************************************************/
// copy_if
// 把[first, last)内满足一元操作 unary_pred 的元素拷贝到以 result 为起始的位置上
/*****************************************************************************************/
template <class InputIter, class OutputIter, class UnaryPredicate>
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 <class InputIter, class Size, class OutputIter>
mystl::pair<InputIter, OutputIter>
unchecked_copy_n(InputIter first, Size n, OutputIter result, mystl::input_iterator_tag)
{
for (; n > 0; --n, ++first, ++result)
{
*result = *first;
}
return mystl::pair<InputIter, OutputIter>(first, result);
}
template <class RandomIter, class Size, class OutputIter>
mystl::pair<RandomIter, OutputIter>
unchecked_copy_n(RandomIter first, Size n, OutputIter result,
mystl::random_access_iterator_tag)
{
auto last = first + n;
return mystl::pair<RandomIter, OutputIter>(last, mystl::copy(first, last, result));
}
template <class InputIter, class Size, class OutputIter>
mystl::pair<InputIter, OutputIter>
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 <class InputIter, class OutputIter>
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 <class RandomIter, class OutputIter>
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 <class InputIter, class OutputIter>
OutputIter
unchecked_move(InputIter first, InputIter last, OutputIter result)
{
return unchecked_move_cat(first, last, result, iterator_category(first));
}
// 为 trivially_copy_assignable 类型提供特化版本
template <class Tp, class Up>
typename std::enable_if<
std::is_same<typename std::remove_const<Tp>::type, Up>::value &&
std::is_trivially_move_assignable<Up>::value,
Up*>::type
unchecked_move(Tp* first, Tp* last, Up* result)
{
const size_t n = static_cast<size_t>(last - first);
if (n != 0)
std::memmove(result, first, n * sizeof(Up));
return result + n;
}
template <class InputIter, class OutputIter>
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 <class BidirectionalIter1, class BidirectionalIter2>
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 <class RandomIter1, class RandomIter2>
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 <class BidirectionalIter1, class BidirectionalIter2>
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 <class Tp, class Up>
typename std::enable_if<
std::is_same<typename std::remove_const<Tp>::type, Up>::value &&
std::is_trivially_move_assignable<Up>::value,
Up*>::type
unchecked_move_backward(Tp* first, Tp* last, Up* result)
{
const size_t n = static_cast<size_t>(last - first);
if (n != 0)
{
result -= n;
std::memmove(result, first, n * sizeof(Up));
}
return result;
}
template <class BidirectionalIter1, class BidirectionalIter2>
BidirectionalIter2
move_backward(BidirectionalIter1 first, BidirectionalIter1 last, BidirectionalIter2 result)
{
return unchecked_move_backward(first, last, result);
}
/*****************************************************************************************/
// equal
// 比较第一序列在 [first, last)区间上的元素值是否和第二序列相等
/*****************************************************************************************/
template <class InputIter1, class InputIter2>
bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2)
{
for (; first1 != last1; ++first1, ++first2)
{
if (*first1 != *first2)
return false;
}
return true;
}
// 重载版本使用函数对象 comp 代替比较操作
template <class InputIter1, class InputIter2, class Compared>
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 <class OutputIter, class Size, class T>
OutputIter unchecked_fill_n(OutputIter first, Size n, const T& value)
{
for (; n > 0; --n, ++first)
{
*first = value;
}
return first;
}
// 为 one-byte 类型提供特化版本
template <class Tp, class Size, class Up>
typename std::enable_if<
std::is_integral<Tp>::value && sizeof(Tp) == 1 &&
!std::is_same<Tp, bool>::value &&
std::is_integral<Up>::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 <class OutputIter, class Size, class T>
OutputIter fill_n(OutputIter first, Size n, const T& value)
{
return unchecked_fill_n(first, n, value);
}
/*****************************************************************************************/
// fill
// 为 [first, last)区间内的所有元素填充新值
/*****************************************************************************************/
template <class ForwardIter, class T>
void fill_cat(ForwardIter first, ForwardIter last, const T& value,
mystl::forward_iterator_tag)
{
for (; first != last; ++first)
{
*first = value;
}
}
template <class RandomIter, class T>
void fill_cat(RandomIter first, RandomIter last, const T& value,
mystl::random_access_iterator_tag)
{
fill_n(first, last - first, value);
}
template <class ForwardIter, class T>
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 <class InputIter1, class InputIter2>
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 <class InputIter1, class InputIter2, class Compred>
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 <class InputIter1, class InputIter2>
mystl::pair<InputIter1, InputIter2>
mismatch(InputIter1 first1, InputIter1 last1, InputIter2 first2)
{
while (first1 != last1 && *first1 == *first2)
{
++first1;
++first2;
}
return mystl::pair<InputIter1, InputIter2>(first1, first2);
}
// 重载版本使用函数对象 comp 代替比较操作
template <class InputIter1, class InputIter2, class Compred>
mystl::pair<InputIter1, InputIter2>
mismatch(InputIter1 first1, InputIter1 last1, InputIter2 first2, Compred comp)
{
while (first1 != last1 && comp(*first1, *first2))
{
++first1;
++first2;
}
return mystl::pair<InputIter1, InputIter2>(first1, first2);
}
} // namespace mystl
#endif // !MYTINYSTL_ALGOBASE_H_
================================================
FILE: MyTinySTL/algorithm.h
================================================
#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_
================================================
FILE: MyTinySTL/alloc.h
================================================
#ifndef MYTINYSTL_ALLOC_H_
#define MYTINYSTL_ALLOC_H_
// 这个头文件包含一个类 alloc,用于分配和回收内存,以内存池的方式实现
//
// 从 v2.0.0 版本开始,将不再使用内存池,这个文件将被弃用,但暂时保留
//
// 注意!!!
// 我知道这个文件里很多实现是错的,这是很久很久前写的了,后面已经不用这个东西了,
// 所以我也没再维护,有诸多问题,已经有人在issue中都提了,free_list的修改,
// 指针作为参数时没实际修改到原指针,等等。相信会看这么仔细的,大部分都是
// 初学C++的朋友,大佬都不会看这些玩具了,所以其中的错误,就留给对内存池实现
// 感兴趣的朋友去修改啦!
#include <new>
#include <cstddef>
#include <cstdio>
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<size_t>(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<size_t>(ESmallObjectBytes))
{
std::free(p);
return;
}
FreeList* q = reinterpret_cast<FreeList*>(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_
================================================
FILE: MyTinySTL/allocator.h
================================================
#ifndef MYTINYSTL_ALLOCATOR_H_
#define MYTINYSTL_ALLOCATOR_H_
// 这个头文件包含一个模板类 allocator,用于管理内存的分配、释放,对象的构造、析构
#include "construct.h"
#include "util.h"
namespace mystl
{
// 模板类:allocator
// 模板函数代表数据类型
template <class T>
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 <class... Args>
static void construct(T* ptr, Args&& ...args);
static void destroy(T* ptr);
static void destroy(T* first, T* last);
};
template <class T>
T* allocator<T>::allocate()
{
return static_cast<T*>(::operator new(sizeof(T)));
}
template <class T>
T* allocator<T>::allocate(size_type n)
{
if (n == 0)
return nullptr;
return static_cast<T*>(::operator new(n * sizeof(T)));
}
template <class T>
void allocator<T>::deallocate(T* ptr)
{
if (ptr == nullptr)
return;
::operator delete(ptr);
}
template <class T>
void allocator<T>::deallocate(T* ptr, size_type /*size*/)
{
if (ptr == nullptr)
return;
::operator delete(ptr);
}
template <class T>
void allocator<T>::construct(T* ptr)
{
mystl::construct(ptr);
}
template <class T>
void allocator<T>::construct(T* ptr, const T& value)
{
mystl::construct(ptr, value);
}
template <class T>
void allocator<T>::construct(T* ptr, T&& value)
{
mystl::construct(ptr, mystl::move(value));
}
template <class T>
template <class ...Args>
void allocator<T>::construct(T* ptr, Args&& ...args)
{
mystl::construct(ptr, mystl::forward<Args>(args)...);
}
template <class T>
void allocator<T>::destroy(T* ptr)
{
mystl::destroy(ptr);
}
template <class T>
void allocator<T>::destroy(T* first, T* last)
{
mystl::destroy(first, last);
}
} // namespace mystl
#endif // !MYTINYSTL_ALLOCATOR_H_
================================================
FILE: MyTinySTL/astring.h
================================================
#ifndef MYTINYSTL_ASTRING_H_
#define MYTINYSTL_ASTRING_H_
// 定义了 string, wstring, u16string, u32string 类型
#include "basic_string.h"
namespace mystl
{
using string = mystl::basic_string<char>;
using wstring = mystl::basic_string<wchar_t>;
using u16string = mystl::basic_string<char16_t>;
using u32string = mystl::basic_string<char32_t>;
}
#endif // !MYTINYSTL_ASTRING_H_
================================================
FILE: MyTinySTL/basic_string.h
================================================
#ifndef MYTINYSTL_BASIC_STRING_H_
#define MYTINYSTL_BASIC_STRING_H_
// 这个头文件包含一个模板类 basic_string
// 用于表示字符串类型
#include <iostream>
#include "iterator.h"
#include "memory.h"
#include "functional.h"
#include "exceptdef.h"
namespace mystl
{
// char_traits
template <class CharType>
struct char_traits
{
typedef CharType char_type;
static size_t length(const char_type* str)
{
size_t len = 0;
for (; *str != char_type(0); ++str)
++len;
return len;
}
static int compare(const char_type* s1, const char_type* s2, size_t n)
{
for (; n != 0; --n, ++s1, ++s2)
{
if (*s1 < *s2)
return -1;
if (*s2 < *s1)
return 1;
}
return 0;
}
static char_type* copy(char_type* dst, const char_type* src, size_t n)
{
MYSTL_DEBUG(src + n <= dst || dst + n <= src);
char_type* r = dst;
for (; n != 0; --n, ++dst, ++src)
*dst = *src;
return r;
}
static char_type* move(char_type* dst, const char_type* src, size_t n)
{
char_type* r = dst;
if (dst < src)
{
for (; n != 0; --n, ++dst, ++src)
*dst = *src;
}
else if (src < dst)
{
dst += n;
src += n;
for (; n != 0; --n)
*--dst = *--src;
}
return r;
}
static char_type* fill(char_type* dst, char_type ch, size_t count)
{
char_type* r = dst;
for (; count > 0; --count, ++dst)
*dst = ch;
return r;
}
};
// Partialized. char_traits<char>
template <>
struct char_traits<char>
{
typedef char char_type;
static size_t length(const char_type* str) noexcept
{ return std::strlen(str); }
static int compare(const char_type* s1, const char_type* s2, size_t n) noexcept
{ return std::memcmp(s1, s2, n); }
static char_type* copy(char_type* dst, const char_type* src, size_t n) noexcept
{
MYSTL_DEBUG(src + n <= dst || dst + n <= src);
return static_cast<char_type*>(std::memcpy(dst, src, n));
}
static char_type* move(char_type* dst, const char_type* src, size_t n) noexcept
{
return static_cast<char_type*>(std::memmove(dst, src, n));
}
static char_type* fill(char_type* dst, char_type ch, size_t count) noexcept
{
return static_cast<char_type*>(std::memset(dst, ch, count));
}
};
// Partialized. char_traits<wchar_t>
template <>
struct char_traits<wchar_t>
{
typedef wchar_t char_type;
static size_t length(const char_type* str) noexcept
{
return std::wcslen(str);
}
static int compare(const char_type* s1, const char_type* s2, size_t n) noexcept
{
return std::wmemcmp(s1, s2, n);
}
static char_type* copy(char_type* dst, const char_type* src, size_t n) noexcept
{
MYSTL_DEBUG(src + n <= dst || dst + n <= src);
return static_cast<char_type*>(std::wmemcpy(dst, src, n));
}
static char_type* move(char_type* dst, const char_type* src, size_t n) noexcept
{
return static_cast<char_type*>(std::wmemmove(dst, src, n));
}
static char_type* fill(char_type* dst, char_type ch, size_t count) noexcept
{
return static_cast<char_type*>(std::wmemset(dst, ch, count));
}
};
// Partialized. char_traits<char16_t>
template <>
struct char_traits<char16_t>
{
typedef char16_t char_type;
static size_t length(const char_type* str) noexcept
{
size_t len = 0;
for (; *str != char_type(0); ++str)
++len;
return len;
}
static int compare(const char_type* s1, const char_type* s2, size_t n) noexcept
{
for (; n != 0; --n, ++s1, ++s2)
{
if (*s1 < *s2)
return -1;
if (*s2 < *s1)
return 1;
}
return 0;
}
static char_type* copy(char_type* dst, const char_type* src, size_t n) noexcept
{
MYSTL_DEBUG(src + n <= dst || dst + n <= src);
char_type* r = dst;
for (; n != 0; --n, ++dst, ++src)
*dst = *src;
return r;
}
static char_type* move(char_type* dst, const char_type* src, size_t n) noexcept
{
char_type* r = dst;
if (dst < src)
{
for (; n != 0; --n, ++dst, ++src)
*dst = *src;
}
else if (src < dst)
{
dst += n;
src += n;
for (; n != 0; --n)
*--dst = *--src;
}
return r;
}
static char_type* fill(char_type* dst, char_type ch, size_t count) noexcept
{
char_type* r = dst;
for (; count > 0; --count, ++dst)
*dst = ch;
return r;
}
};
// Partialized. char_traits<char32_t>
template <>
struct char_traits<char32_t>
{
typedef char32_t char_type;
static size_t length(const char_type* str) noexcept
{
size_t len = 0;
for (; *str != char_type(0); ++str)
++len;
return len;
}
static int compare(const char_type* s1, const char_type* s2, size_t n) noexcept
{
for (; n != 0; --n, ++s1, ++s2)
{
if (*s1 < *s2)
return -1;
if (*s2 < *s1)
return 1;
}
return 0;
}
static char_type* copy(char_type* dst, const char_type* src, size_t n) noexcept
{
MYSTL_DEBUG(src + n <= dst || dst + n <= src);
char_type* r = dst;
for (; n != 0; --n, ++dst, ++src)
*dst = *src;
return r;
}
static char_type* move(char_type* dst, const char_type* src, size_t n) noexcept
{
char_type* r = dst;
if (dst < src)
{
for (; n != 0; --n, ++dst, ++src)
*dst = *src;
}
else if (src < dst)
{
dst += n;
src += n;
for (; n != 0; --n)
*--dst = *--src;
}
return r;
}
static char_type* fill(char_type* dst, char_type ch, size_t count) noexcept
{
char_type* r = dst;
for (; count > 0; --count, ++dst)
*dst = ch;
return r;
}
};
// 初始化 basic_string 尝试分配的最小 buffer 大小,可能被忽略
#define STRING_INIT_SIZE 32
// 模板类 basic_string
// 参数一代表字符类型,参数二代表萃取字符类型的方式,缺省使用 mystl::char_traits
template <class CharType, class CharTraits = mystl::char_traits<CharType>>
class basic_string
{
public:
typedef CharTraits traits_type;
typedef CharTraits char_traits;
typedef mystl::allocator<CharType> allocator_type;
typedef mystl::allocator<CharType> data_allocator;
typedef typename allocator_type::value_type value_type;
typedef typename allocator_type::pointer pointer;
typedef typename allocator_type::const_pointer const_pointer;
typedef typename allocator_type::reference reference;
typedef typename allocator_type::const_reference const_reference;
typedef typename allocator_type::size_type size_type;
typedef typename allocator_type::difference_type difference_type;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef mystl::reverse_iterator<iterator> reverse_iterator;
typedef mystl::reverse_iterator<const_iterator> const_reverse_iterator;
allocator_type get_allocator() { return allocator_type(); }
static_assert(std::is_pod<CharType>::value, "Character type of basic_string must be a POD");
static_assert(std::is_same<CharType, typename traits_type::char_type>::value,
"CharType must be same as traits_type::char_type");
public:
// 末尾位置的值,例:
// if (str.find('a') != string::npos) { /* do something */ }
static constexpr size_type npos = static_cast<size_type>(-1);
private:
iterator buffer_; // 储存字符串的起始位置
size_type size_; // 大小
size_type cap_; // 容量
public:
// 构造、复制、移动、析构函数
basic_string() noexcept
{ try_init(); }
basic_string(size_type n, value_type ch)
:buffer_(nullptr), size_(0), cap_(0)
{
fill_init(n, ch);
}
basic_string(const basic_string& other, size_type pos)
:buffer_(nullptr), size_(0), cap_(0)
{
init_from(other.buffer_, pos, other.size_ - pos);
}
basic_string(const basic_string& other, size_type pos, size_type count)
:buffer_(nullptr), size_(0), cap_(0)
{
init_from(other.buffer_, pos, count);
}
basic_string(const_pointer str)
:buffer_(nullptr), size_(0), cap_(0)
{
init_from(str, 0, char_traits::length(str));
}
basic_string(const_pointer str, size_type count)
:buffer_(nullptr), size_(0), cap_(0)
{
init_from(str, 0, count);
}
template <class Iter, typename std::enable_if<
mystl::is_input_iterator<Iter>::value, int>::type = 0>
basic_string(Iter first, Iter last)
{ copy_init(first, last, iterator_category(first)); }
basic_string(const basic_string& rhs)
:buffer_(nullptr), size_(0), cap_(0)
{
init_from(rhs.buffer_, 0, rhs.size_);
}
basic_string(basic_string&& rhs) noexcept
:buffer_(rhs.buffer_), size_(rhs.size_), cap_(rhs.cap_)
{
rhs.buffer_ = nullptr;
rhs.size_ = 0;
rhs.cap_ = 0;
}
basic_string& operator=(const basic_string& rhs);
basic_string& operator=(basic_string&& rhs) noexcept;
basic_string& operator=(const_pointer str);
basic_string& operator=(value_type ch);
~basic_string() { destroy_buffer(); }
public:
// 迭代器相关操作
iterator begin() noexcept
{ return buffer_; }
const_iterator begin() const noexcept
{ return buffer_; }
iterator end() noexcept
{ return buffer_ + size_; }
const_iterator end() const noexcept
{ return buffer_ + size_; }
reverse_iterator rbegin() noexcept
{ return reverse_iterator(end()); }
const_reverse_iterator rbegin() const noexcept
{ return const_reverse_iterator(end()); }
reverse_iterator rend() noexcept
{ return reverse_iterator(begin()); }
const_reverse_iterator rend() const noexcept
{ return const_reverse_iterator(begin()); }
const_iterator cbegin() const noexcept
{ return begin(); }
const_iterator cend() const noexcept
{ return end(); }
const_reverse_iterator crbegin() const noexcept
{ return rbegin(); }
const_reverse_iterator crend() const noexcept
{ return rend(); }
// 容量相关操作
bool empty() const noexcept
{ return size_ == 0; }
size_type size() const noexcept
{ return size_; }
size_type length() const noexcept
{ return size_; }
size_type capacity() const noexcept
{ return cap_; }
size_type max_size() const noexcept
{ return static_cast<size_type>(-1); }
void reserve(size_type n);
void shrink_to_fit();
// 访问元素相关操作
reference operator[](size_type n)
{
MYSTL_DEBUG(n <= size_);
if (n == size_)
*(buffer_ + n) = value_type();
return *(buffer_ + n);
}
const_reference operator[](size_type n) const
{
MYSTL_DEBUG(n <= size_);
if (n == size_)
*(buffer_ + n) = value_type();
return *(buffer_ + n);
}
reference at(size_type n)
{
THROW_OUT_OF_RANGE_IF(n >= size_, "basic_string<Char, Traits>::at()"
"subscript out of range");
return (*this)[n];
}
const_reference at(size_type n) const
{
THROW_OUT_OF_RANGE_IF(n >= size_, "basic_string<Char, Traits>::at()"
"subscript out of range");
return (*this)[n];
}
reference front()
{
MYSTL_DEBUG(!empty());
return *begin();
}
const_reference front() const
{
MYSTL_DEBUG(!empty());
return *begin();
}
reference back()
{
MYSTL_DEBUG(!empty());
return *(end() - 1);
}
const_reference back() const
{
MYSTL_DEBUG(!empty());
return *(end() - 1);
}
const_pointer data() const noexcept
{ return to_raw_pointer(); }
const_pointer c_str() const noexcept
{ return to_raw_pointer(); }
// 添加删除相关操作
// insert
iterator insert(const_iterator pos, value_type ch);
iterator insert(const_iterator pos, size_type count, value_type ch);
template <class Iter>
iterator insert(const_iterator pos, Iter first, Iter last);
// push_back / pop_back
void push_back(value_type ch)
{ append(1, ch); }
void pop_back()
{
MYSTL_DEBUG(!empty());
--size_;
}
// append
basic_string& append(size_type count, value_type ch);
basic_string& append(const basic_string& str)
{ return append(str, 0, str.size_); }
basic_string& append(const basic_string& str, size_type pos)
{ return append(str, pos, str.size_ - pos); }
basic_string& append(const basic_string& str, size_type pos, size_type count);
basic_string& append(const_pointer s)
{ return append(s, char_traits::length(s)); }
basic_string& append(const_pointer s, size_type count);
template <class Iter, typename std::enable_if<
mystl::is_input_iterator<Iter>::value, int>::type = 0>
basic_string& append(Iter first, Iter last)
{ return append_range(first, last); }
// erase /clear
iterator erase(const_iterator pos);
iterator erase(const_iterator first, const_iterator last);
// resize
void resize(size_type count)
{ resize(count, value_type()); }
void resize(size_type count, value_type ch);
void clear() noexcept
{ size_ = 0; }
// basic_string 相关操作
// compare
int compare(const basic_string& other) const;
int compare(size_type pos1, size_type count1, const basic_string& other) const;
int compare(size_type pos1, size_type count1, const basic_string& other,
size_type pos2, size_type count2 = npos) const;
int compare(const_pointer s) const;
int compare(size_type pos1, size_type count1, const_pointer s) const;
int compare(size_type pos1, size_type count1, const_pointer s, size_type count2) const;
// substr
basic_string substr(size_type index, size_type count = npos)
{
count = mystl::min(count, size_ - index);
return basic_string(buffer_ + index, buffer_ + index + count);
}
// replace
basic_string& replace(size_type pos, size_type count, const basic_string& str)
{
THROW_OUT_OF_RANGE_IF(pos > size_, "basic_string<Char, Traits>::replace's pos out of range");
return replace_cstr(buffer_ + pos, count, str.buffer_, str.size_);
}
basic_string& replace(const_iterator first, const_iterator last, const basic_string& str)
{
MYSTL_DEBUG(begin() <= first && last <= end() && first <= last);
return replace_cstr(first, static_cast<size_type>(last - first), str.buffer_, str.size_);
}
basic_string& replace(size_type pos, size_type count, const_pointer str)
{
THROW_OUT_OF_RANGE_IF(pos > size_, "basic_string<Char, Traits>::replace's pos out of range");
return replace_cstr(buffer_ + pos, count, str, char_traits::length(str));
}
basic_string& replace(const_iterator first, const_iterator last, const_pointer str)
{
MYSTL_DEBUG(begin() <= first && last <= end() && first <= last);
return replace_cstr(first, static_cast<size_type>(last - first), str, char_traits::length(str));
}
basic_string& replace(size_type pos, size_type count, const_pointer str, size_type count2)
{
THROW_OUT_OF_RANGE_IF(pos > size_, "basic_string<Char, Traits>::replace's pos out of range");
return replace_cstr(buffer_ + pos, count, str, count2);
}
basic_string& replace(const_iterator first, const_iterator last, const_pointer str, size_type count)
{
MYSTL_DEBUG(begin() <= first && last <= end() && first <= last);
return replace_cstr(first, static_cast<size_type>(last - first), str, count);
}
basic_string& replace(size_type pos, size_type count, size_type count2, value_type ch)
{
THROW_OUT_OF_RANGE_IF(pos > size_, "basic_string<Char, Traits>::replace's pos out of range");
return replace_fill(buffer_ + pos, count, count2, ch);
}
basic_string& replace(const_iterator first, const_iterator last, size_type count, value_type ch)
{
MYSTL_DEBUG(begin() <= first && last <= end() && first <= last);
return replace_fill(first, static_cast<size_type>(last - first), count, ch);
}
basic_string& replace(size_type pos1, size_type count1, const basic_string& str,
size_type pos2, size_type count2 = npos)
{
THROW_OUT_OF_RANGE_IF(pos1 > size_ || pos2 > str.size_,
"basic_string<Char, Traits>::replace's pos out of range");
return replace_cstr(buffer_ + pos1, count1, str.buffer_ + pos2, count2);
}
template <class Iter, typename std::enable_if<
mystl::is_input_iterator<Iter>::value, int>::type = 0>
basic_string& replace(const_iterator first, const_iterator last, Iter first2, Iter last2)
{
MYSTL_DEBUG(begin() <= first && last <= end() && first <= last);
return replace_copy(first, last, first2, last2);
}
// reverse
void reverse() noexcept;
// swap
void swap(basic_string& rhs) noexcept;
// 查找相关操作
// find
size_type find(value_type ch, size_type pos = 0) const noexcept;
size_type find(const_pointer str, size_type pos = 0) const noexcept;
size_type find(const_pointer str, size_type pos, size_type count) const noexcept;
size_type find(const basic_string& str, size_type pos = 0) const noexcept;
// rfind
size_type rfind(value_type ch, size_type pos = npos) const noexcept;
size_type rfind(const_pointer str, size_type pos = npos) const noexcept;
size_type rfind(const_pointer str, size_type pos, size_type count) const noexcept;
size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
// find_first_of
size_type find_first_of(value_type ch, size_type pos = 0) const noexcept;
size_type find_first_of(const_pointer s, size_type pos = 0) const noexcept;
size_type find_first_of(const_pointer s, size_type pos, size_type count) const noexcept;
size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
// find_first_not_of
size_type find_first_not_of(value_type ch, size_type pos = 0) const noexcept;
size_type find_first_not_of(const_pointer s, size_type pos = 0) const noexcept;
size_type find_first_not_of(const_pointer s, size_type pos, size_type count) const noexcept;
size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
// find_last_of
size_type find_last_of(value_type ch, size_type pos = 0) const noexcept;
size_type find_last_of(const_pointer s, size_type pos = 0) const noexcept;
size_type find_last_of(const_pointer s, size_type pos, size_type count) const noexcept;
size_type find_last_of(const basic_string& str, size_type pos = 0) const noexcept;
// find_last_not_of
size_type find_last_not_of(value_type ch, size_type pos = 0) const noexcept;
size_type find_last_not_of(const_pointer s, size_type pos = 0) const noexcept;
size_type find_last_not_of(const_pointer s, size_type pos, size_type count) const noexcept;
size_type find_last_not_of(const basic_string& str, size_type pos = 0) const noexcept;
// count
size_type count(value_type ch, size_type pos = 0) const noexcept;
public:
// 重载 operator+=
basic_string& operator+=(const basic_string& str)
{ return append(str); }
basic_string& operator+=(value_type ch)
{ return append(1, ch); }
basic_string& operator+=(const_pointer str)
{ return append(str, str + char_traits::length(str)); }
// 重载 operator >> / operatror <<
friend std::istream& operator >> (std::istream& is, basic_string& str)
{
value_type* buf = new value_type[4096];
is >> buf;
basic_string tmp(buf);
str = std::move(tmp);
delete[]buf;
return is;
}
friend std::ostream& operator << (std::ostream& os, const basic_string& str)
{
for (size_type i = 0; i < str.size_; ++i)
os << *(str.buffer_ + i);
return os;
}
private:
// helper functions
// init / destroy
void try_init() noexcept;
void fill_init(size_type n, value_type ch);
template <class Iter>
void copy_init(Iter first, Iter last, mystl::input_iterator_tag);
template <class Iter>
void copy_init(Iter first, Iter last, mystl::forward_iterator_tag);
void init_from(const_pointer src, size_type pos, size_type n);
void destroy_buffer();
// get raw pointer
const_pointer to_raw_pointer() const;
// shrink_to_fit
void reinsert(size_type size);
// append
template <class Iter>
basic_string& append_range(Iter first, Iter last);
// compare
int compare_cstr(const_pointer s1, size_type n1, const_pointer s2, size_type n2) const;
// replace
basic_string& replace_cstr(const_iterator first, size_type count1, const_pointer str, size_type count2);
basic_string& replace_fill(const_iterator first, size_type count1, size_type count2, value_type ch);
template <class Iter>
basic_string& replace_copy(const_iterator first, const_iterator last, Iter first2, Iter last2);
// reallocate
void reallocate(size_type need);
iterator reallocate_and_fill(iterator pos, size_type n, value_type ch);
iterator reallocate_and_copy(iterator pos, const_iterator first, const_iterator last);
};
/*****************************************************************************************/
// 复制赋值操作符
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>&
basic_string<CharType, CharTraits>::
operator=(const basic_string& rhs)
{
if (this != &rhs)
{
basic_string tmp(rhs);
swap(tmp);
}
return *this;
}
// 移动赋值操作符
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>&
basic_string<CharType, CharTraits>::
operator=(basic_string&& rhs) noexcept
{
destroy_buffer();
buffer_ = rhs.buffer_;
size_ = rhs.size_;
cap_ = rhs.cap_;
rhs.buffer_ = nullptr;
rhs.size_ = 0;
rhs.cap_ = 0;
return *this;
}
// 用一个字符串赋值
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>&
basic_string<CharType, CharTraits>::
operator=(const_pointer str)
{
const size_type len = char_traits::length(str);
if (cap_ < len)
{
auto new_buffer = data_allocator::allocate(len + 1);
data_allocator::deallocate(buffer_);
buffer_ = new_buffer;
cap_ = len + 1;
}
char_traits::copy(buffer_, str, len);
size_ = len;
return *this;
}
// 用一个字符赋值
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>&
basic_string<CharType, CharTraits>::
operator=(value_type ch)
{
if (cap_ < 1)
{
auto new_buffer = data_allocator::allocate(2);
data_allocator::deallocate(buffer_);
buffer_ = new_buffer;
cap_ = 2;
}
*buffer_ = ch;
size_ = 1;
return *this;
}
// 预留储存空间
template <class CharType, class CharTraits>
void basic_string<CharType, CharTraits>::
reserve(size_type n)
{
if (cap_ < n)
{
THROW_LENGTH_ERROR_IF(n > max_size(), "n can not larger than max_size()"
"in basic_string<Char,Traits>::reserve(n)");
auto new_buffer = data_allocator::allocate(n);
char_traits::move(new_buffer, buffer_, size_);
buffer_ = new_buffer;
cap_ = n;
}
}
// 减少不用的空间
template <class CharType, class CharTraits>
void basic_string<CharType, CharTraits>::
shrink_to_fit()
{
if (size_ != cap_)
{
reinsert(size_);
}
}
// 在 pos 处插入一个元素
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::iterator
basic_string<CharType, CharTraits>::
insert(const_iterator pos, value_type ch)
{
iterator r = const_cast<iterator>(pos);
if (size_ == cap_)
{
return reallocate_and_fill(r, 1, ch);
}
char_traits::move(r + 1, r, end() - r);
++size_;
*r = ch;
return r;
}
// 在 pos 处插入 n 个元素
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::iterator
basic_string<CharType, CharTraits>::
insert(const_iterator pos, size_type count, value_type ch)
{
iterator r = const_cast<iterator>(pos);
if (count == 0)
return r;
if (cap_ - size_ < count)
{
return reallocate_and_fill(r, count, ch);
}
if (pos == end())
{
char_traits::fill(end(), ch, count);
size_ += count;
return r;
}
char_traits::move(r + count, r, count);
char_traits::fill(r, ch, count);
size_ += count;
return r;
}
// 在 pos 处插入 [first, last) 内的元素
template <class CharType, class CharTraits>
template <class Iter>
typename basic_string<CharType, CharTraits>::iterator
basic_string<CharType, CharTraits>::
insert(const_iterator pos, Iter first, Iter last)
{
iterator r = const_cast<iterator>(pos);
const size_type len = mystl::distance(first, last);
if (len == 0)
return r;
if (cap_ - size_ < len)
{
return reallocate_and_copy(r, first, last);
}
if (pos == end())
{
mystl::uninitialized_copy(first, last, end());
size_ += len;
return r;
}
char_traits::move(r + len, r, len);
mystl::uninitialized_copy(first, last, r);
size_ += len;
return r;
}
// 在末尾添加 count 个 ch
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>&
basic_string<CharType, CharTraits>::
append(size_type count, value_type ch)
{
THROW_LENGTH_ERROR_IF(size_ > max_size() - count,
"basic_string<Char, Tratis>'s size too big");
if (cap_ - size_ < count)
{
reallocate(count);
}
char_traits::fill(buffer_ + size_, ch, count);
size_ += count;
return *this;
}
// 在末尾添加 [str[pos] str[pos+count]) 一段
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>&
basic_string<CharType, CharTraits>::
append(const basic_string& str, size_type pos, size_type count)
{
THROW_LENGTH_ERROR_IF(size_ > max_size() - count,
"basic_string<Char, Tratis>'s size too big");
if (count == 0)
return *this;
if (cap_ - size_ < count)
{
reallocate(count);
}
char_traits::copy(buffer_ + size_, str.buffer_ + pos, count);
size_ += count;
return *this;
}
// 在末尾添加 [s, s+count) 一段
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>&
basic_string<CharType, CharTraits>::
append(const_pointer s, size_type count)
{
THROW_LENGTH_ERROR_IF(size_ > max_size() - count,
"basic_string<Char, Tratis>'s size too big");
if (cap_ - size_ < count)
{
reallocate(count);
}
char_traits::copy(buffer_ + size_, s, count);
size_ += count;
return *this;
}
// 删除 pos 处的元素
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::iterator
basic_string<CharType, CharTraits>::
erase(const_iterator pos)
{
MYSTL_DEBUG(pos != end());
iterator r = const_cast<iterator>(pos);
char_traits::move(r, pos + 1, end() - pos - 1);
--size_;
return r;
}
// 删除 [first, last) 的元素
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::iterator
basic_string<CharType, CharTraits>::
erase(const_iterator first, const_iterator last)
{
if (first == begin() && last == end())
{
clear();
return end();
}
const size_type n = end() - last;
iterator r = const_cast<iterator>(first);
char_traits::move(r, last, n);
size_ -= (last - first);
return r;
}
// 重置容器大小
template <class CharType, class CharTraits>
void basic_string<CharType, CharTraits>::
resize(size_type count, value_type ch)
{
if (count < size_)
{
erase(buffer_ + count, buffer_ + size_);
}
else
{
append(count - size_, ch);
}
}
// 比较两个 basic_string,小于返回 -1,大于返回 1,等于返回 0
template <class CharType, class CharTraits>
int basic_string<CharType, CharTraits>::
compare(const basic_string& other) const
{
return compare_cstr(buffer_, size_, other.buffer_, other.size_);
}
// 从 pos1 下标开始的 count1 个字符跟另一个 basic_string 比较
template <class CharType, class CharTraits>
int basic_string<CharType, CharTraits>::
compare(size_type pos1, size_type count1, const basic_string& other) const
{
auto n1 = mystl::min(count1, size_ - pos1);
return compare_cstr(buffer_ + pos1, n1, other.buffer_, other.size_);
}
// 从 pos1 下标开始的 count1 个字符跟另一个 basic_string 下标 pos2 开始的 count2 个字符比较
template <class CharType, class CharTraits>
int basic_string<CharType, CharTraits>::
compare(size_type pos1, size_type count1, const basic_string& other,
size_type pos2, size_type count2) const
{
auto n1 = mystl::min(count1, size_ - pos1);
auto n2 = mystl::min(count2, other.size_ - pos2);
return compare_cstr(buffer_, n1, other.buffer_, n2);
}
// 跟一个字符串比较
template <class CharType, class CharTraits>
int basic_string<CharType, CharTraits>::
compare(const_pointer s) const
{
auto n2 = char_traits::length(s);
return compare_cstr(buffer_, size_, s, n2);
}
// 从下标 pos1 开始的 count1 个字符跟另一个字符串比较
template <class CharType, class CharTraits>
int basic_string<CharType, CharTraits>::
compare(size_type pos1, size_type count1, const_pointer s) const
{
auto n1 = mystl::min(count1, size_ - pos1);
auto n2 = char_traits::length(s);
return compare_cstr(buffer_, n1, s, n2);
}
// 从下标 pos1 开始的 count1 个字符跟另一个字符串的前 count2 个字符比较
template <class CharType, class CharTraits>
int basic_string<CharType, CharTraits>::
compare(size_type pos1, size_type count1, const_pointer s, size_type count2) const
{
auto n1 = mystl::min(count1, size_ - pos1);
return compare_cstr(buffer_, n1, s, count2);
}
// 反转 basic_string
template <class CharType, class CharTraits>
void basic_string<CharType, CharTraits>::
reverse() noexcept
{
for (auto i = begin(), j = end(); i < j;)
{
mystl::iter_swap(i++, --j);
}
}
// 交换两个 basic_string
template <class CharType, class CharTraits>
void basic_string<CharType, CharTraits>::
swap(basic_string& rhs) noexcept
{
if (this != &rhs)
{
mystl::swap(buffer_, rhs.buffer_);
mystl::swap(size_, rhs.size_);
mystl::swap(cap_, rhs.cap_);
}
}
// 从下标 pos 开始查找字符为 ch 的元素,若找到返回其下标,否则返回 npos
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find(value_type ch, size_type pos) const noexcept
{
for (auto i = pos; i < size_; ++i)
{
if (*(buffer_ + i) == ch)
return i;
}
return npos;
}
// 从下标 pos 开始查找字符串 str,若找到返回起始位置的下标,否则返回 npos
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find(const_pointer str, size_type pos) const noexcept
{
const auto len = char_traits::length(str);
if (len == 0)
return pos;
if (size_ - pos < len)
return npos;
const auto left = size_ - len;
for (auto i = pos; i <= left; ++i)
{
if (*(buffer_ + i) == *str)
{
size_type j = 1;
for (; j < len; ++j)
{
if (*(buffer_ + i + j) != *(str + j))
break;
}
if (j == len)
return i;
}
}
return npos;
}
// 从下标 pos 开始查找字符串 str 的前 count 个字符,若找到返回起始位置的下标,否则返回 npos
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find(const_pointer str, size_type pos, size_type count) const noexcept
{
if (count == 0)
return pos;
if (size_ - pos < count)
return npos;
const auto left = size_ - count;
for (auto i = pos; i <= left; ++i)
{
if (*(buffer_ + i) == *str)
{
size_type j = 1;
for (; j < count; ++j)
{
if (*(buffer_ + i + j) != *(str + j))
break;
}
if (j == count)
return i;
}
}
return npos;
}
// 从下标 pos 开始查找字符串 str,若找到返回起始位置的下标,否则返回 npos
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find(const basic_string& str, size_type pos) const noexcept
{
const size_type count = str.size_;
if (count == 0)
return pos;
if (size_ - pos < count)
return npos;
const auto left = size_ - count;
for (auto i = pos; i <= left; ++i)
{
if (*(buffer_ + i) == str.front())
{
size_type j = 1;
for (; j < count; ++j)
{
if (*(buffer_ + i + j) != str[j])
break;
}
if (j == count)
return i;
}
}
return npos;
}
// 从下标 pos 开始反向查找值为 ch 的元素,与 find 类似
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
rfind(value_type ch, size_type pos) const noexcept
{
if (pos >= size_)
pos = size_ - 1;
for (auto i = pos; i != 0; --i)
{
if (*(buffer_ + i) == ch)
return i;
}
return front() == ch ? 0 : npos;
}
// 从下标 pos 开始反向查找字符串 str,与 find 类似
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
rfind(const_pointer str, size_type pos) const noexcept
{
if (pos >= size_)
pos = size_ - 1;
const size_type len = char_traits::length(str);
switch (len)
{
case 0:
return pos;
case 1:
{
for (auto i = pos; i != 0; --i)
{
if (*(buffer_ + i) == *str)
return i;
}
return front() == *str ? 0 : npos;
}
default:
{ // len >= 2
for (auto i = pos; i >= len - 1; --i)
{
if (*(buffer_ + i) == *(str + len - 1))
{
size_type j = 1;
for (; j < len; ++j)
{
if (*(buffer_ + i - j) != *(str + len - j - 1))
break;
}
if (j == len)
return i - len + 1;
}
}
break;
}
}
return npos;
}
// 从下标 pos 开始反向查找字符串 str 前 count 个字符,与 find 类似
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
rfind(const_pointer str, size_type pos, size_type count) const noexcept
{
if (count == 0)
return pos;
if (pos >= size_)
pos = size_ - 1;
if (pos < count - 1)
return npos;
for (auto i = pos; i >= count - 1; --i)
{
if (*(buffer_ + i) == *(str + count - 1))
{
size_type j = 1;
for (; j < count; ++j)
{
if (*(buffer_ + i - j) != *(str + count - j - 1))
break;
}
if (j == count)
return i - count + 1;
}
}
return npos;
}
// 从下标 pos 开始反向查找字符串 str,与 find 类似
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
rfind(const basic_string& str, size_type pos) const noexcept
{
const size_type count = str.size_;
if (pos >= size_)
pos = size_ - 1;
if (count == 0)
return pos;
if (pos < count - 1)
return npos;
for (auto i = pos; i >= count - 1; --i)
{
if (*(buffer_ + i) == str[count - 1])
{
size_type j = 1;
for (; j < count; ++j)
{
if (*(buffer_ + i - j) != str[count - j - 1])
break;
}
if (j == count)
return i - count + 1;
}
}
return npos;
}
// 从下标 pos 开始查找 ch 出现的第一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_first_of(value_type ch, size_type pos) const noexcept
{
for (auto i = pos; i < size_; ++i)
{
if (*(buffer_ + i) == ch)
return i;
}
return npos;
}
// 从下标 pos 开始查找字符串 s 其中的一个字符出现的第一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_first_of(const_pointer s, size_type pos) const noexcept
{
const size_type len = char_traits::length(s);
for (auto i = pos; i < size_; ++i)
{
value_type ch = *(buffer_ + i);
for (size_type j = 0; j < len; ++j)
{
if (ch == *(s + j))
return i;
}
}
return npos;
}
// 从下标 pos 开始查找字符串 s
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_first_of(const_pointer s, size_type pos, size_type count) const noexcept
{
for (auto i = pos; i < size_; ++i)
{
value_type ch = *(buffer_ + i);
for (size_type j = 0; j < count; ++j)
{
if (ch == *(s + j))
return i;
}
}
return npos;
}
// 从下标 pos 开始查找字符串 str 其中一个字符出现的第一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_first_of(const basic_string& str, size_type pos) const noexcept
{
for (auto i = pos; i < size_; ++i)
{
value_type ch = *(buffer_ + i);
for (size_type j = 0; j < str.size_; ++j)
{
if (ch == str[j])
return i;
}
}
return npos;
}
// 从下标 pos 开始查找与 ch 不相等的第一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_first_not_of(value_type ch, size_type pos) const noexcept
{
for (auto i = pos; i < size_; ++i)
{
if (*(buffer_ + i) != ch)
return i;
}
return npos;
}
// 从下标 pos 开始查找与字符串 s 其中一个字符不相等的第一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_first_not_of(const_pointer s, size_type pos) const noexcept
{
const size_type len = char_traits::length(s);
for (auto i = pos; i < size_; ++i)
{
value_type ch = *(buffer_ + i);
for (size_type j = 0; j < len; ++j)
{
if (ch != *(s + j))
return i;
}
}
return npos;
}
// 从下标 pos 开始查找与字符串 s 前 count 个字符中不相等的第一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_first_not_of(const_pointer s, size_type pos, size_type count) const noexcept
{
for (auto i = pos; i < size_; ++i)
{
value_type ch = *(buffer_ + i);
for (size_type j = 0; j < count; ++j)
{
if (ch != *(s + j))
return i;
}
}
return npos;
}
// 从下标 pos 开始查找与字符串 str 的字符中不相等的第一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_first_not_of(const basic_string& str, size_type pos) const noexcept
{
for (auto i = pos; i < size_; ++i)
{
value_type ch = *(buffer_ + i);
for (size_type j = 0; j < str.size_; ++j)
{
if (ch != str[j])
return i;
}
}
return npos;
}
// 从下标 pos 开始查找与 ch 相等的最后一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_last_of(value_type ch, size_type pos) const noexcept
{
for (auto i = size_ - 1; i >= pos; --i)
{
if (*(buffer_ + i) == ch)
return i;
}
return npos;
}
// 从下标 pos 开始查找与字符串 s 其中一个字符相等的最后一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_last_of(const_pointer s, size_type pos) const noexcept
{
const size_type len = char_traits::length(s);
for (auto i = size_ - 1; i >= pos; --i)
{
value_type ch = *(buffer_ + i);
for (size_type j = 0; j < len; ++j)
{
if (ch == *(s + j))
return i;
}
}
return npos;
}
// 从下标 pos 开始查找与字符串 s 前 count 个字符中相等的最后一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_last_of(const_pointer s, size_type pos, size_type count) const noexcept
{
for (auto i = size_ - 1; i >= pos; --i)
{
value_type ch = *(buffer_ + i);
for (size_type j = 0; j < count; ++j)
{
if (ch == *(s + j))
return i;
}
}
return npos;
}
// 从下标 pos 开始查找与字符串 str 字符中相等的最后一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_last_of(const basic_string& str, size_type pos) const noexcept
{
for (auto i = size_ - 1; i >= pos; --i)
{
value_type ch = *(buffer_ + i);
for (size_type j = 0; j < str.size_; ++j)
{
if (ch == str[j])
return i;
}
}
return npos;
}
// 从下标 pos 开始查找与 ch 字符不相等的最后一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_last_not_of(value_type ch, size_type pos) const noexcept
{
for (auto i = size_ - 1; i >= pos; --i)
{
if (*(buffer_ + i) != ch)
return i;
}
return npos;
}
// 从下标 pos 开始查找与字符串 s 的字符中不相等的最后一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_last_not_of(const_pointer s, size_type pos) const noexcept
{
const size_type len = char_traits::length(s);
for (auto i = size_ - 1; i >= pos; --i)
{
value_type ch = *(buffer_ + i);
for (size_type j = 0; j < len; ++j)
{
if (ch != *(s + j))
return i;
}
}
return npos;
}
// 从下标 pos 开始查找与字符串 s 前 count 个字符中不相等的最后一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_last_not_of(const_pointer s, size_type pos, size_type count) const noexcept
{
for (auto i = size_ - 1; i >= pos; --i)
{
value_type ch = *(buffer_ + i);
for (size_type j = 0; j < count; ++j)
{
if (ch != *(s + j))
return i;
}
}
return npos;
}
// 从下标 pos 开始查找与字符串 str 字符中不相等的最后一个位置
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
find_last_not_of(const basic_string& str, size_type pos) const noexcept
{
for (auto i = size_ - 1; i >= pos; --i)
{
value_type ch = *(buffer_ + i);
for (size_type j = 0; j < str.size_; ++j)
{
if (ch != str[j])
return i;
}
}
return npos;
}
// 返回从下标 pos 开始字符为 ch 的元素出现的次数
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::size_type
basic_string<CharType, CharTraits>::
count(value_type ch, size_type pos) const noexcept
{
size_type n = 0;
for (auto i = pos; i < size_; ++i)
{
if (*(buffer_ + i) == ch)
++n;
}
return n;
}
/*****************************************************************************************/
// helper function
// 尝试初始化一段 buffer,若分配失败则忽略,不会抛出异常
template <class CharType, class CharTraits>
void basic_string<CharType, CharTraits>::
try_init() noexcept
{
try
{
buffer_ = data_allocator::allocate(static_cast<size_type>(STRING_INIT_SIZE));
size_ = 0;
cap_ = 0;
}
catch (...)
{
buffer_ = nullptr;
size_ = 0;
cap_ = 0;
// no throw
}
}
// fill_init 函数
template <class CharType, class CharTraits>
void basic_string<CharType, CharTraits>::
fill_init(size_type n, value_type ch)
{
const auto init_size = mystl::max(static_cast<size_type>(STRING_INIT_SIZE), n + 1);
buffer_ = data_allocator::allocate(init_size);
char_traits::fill(buffer_, ch, n);
size_ = n;
cap_ = init_size;
}
// copy_init 函数
template <class CharType, class CharTraits>
template <class Iter>
void basic_string<CharType, CharTraits>::
copy_init(Iter first, Iter last, mystl::input_iterator_tag)
{
size_type n = mystl::distance(first, last);
const auto init_size = mystl::max(static_cast<size_type>(STRING_INIT_SIZE), n + 1);
try
{
buffer_ = data_allocator::allocate(init_size);
size_ = n;
cap_ = init_size;
}
catch (...)
{
buffer_ = nullptr;
size_ = 0;
cap_ = 0;
throw;
}
for (; n > 0; --n, ++first)
append(*first);
}
template <class CharType, class CharTraits>
template <class Iter>
void basic_string<CharType, CharTraits>::
copy_init(Iter first, Iter last, mystl::forward_iterator_tag)
{
const size_type n = mystl::distance(first, last);
const auto init_size = mystl::max(static_cast<size_type>(STRING_INIT_SIZE), n + 1);
try
{
buffer_ = data_allocator::allocate(init_size);
size_ = n;
cap_ = init_size;
mystl::uninitialized_copy(first, last, buffer_);
}
catch (...)
{
buffer_ = nullptr;
size_ = 0;
cap_ = 0;
throw;
}
}
// init_from 函数
template <class CharType, class CharTraits>
void basic_string<CharType, CharTraits>::
init_from(const_pointer src, size_type pos, size_type count)
{
const auto init_size = mystl::max(static_cast<size_type>(STRING_INIT_SIZE), count + 1);
buffer_ = data_allocator::allocate(init_size);
char_traits::copy(buffer_, src + pos, count);
size_ = count;
cap_ = init_size;
}
// destroy_buffer 函数
template <class CharType, class CharTraits>
void basic_string<CharType, CharTraits>::
destroy_buffer()
{
if (buffer_ != nullptr)
{
data_allocator::deallocate(buffer_, cap_);
buffer_ = nullptr;
size_ = 0;
cap_ = 0;
}
}
// to_raw_pointer 函数
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::const_pointer
basic_string<CharType, CharTraits>::
to_raw_pointer() const
{
*(buffer_ + size_) = value_type();
return buffer_;
}
// reinsert 函数
template <class CharType, class CharTraits>
void basic_string<CharType, CharTraits>::
reinsert(size_type size)
{
auto new_buffer = data_allocator::allocate(size);
try
{
char_traits::move(new_buffer, buffer_, size);
}
catch (...)
{
data_allocator::deallocate(new_buffer);
}
buffer_ = new_buffer;
size_ = size;
cap_ = size;
}
// append_range,末尾追加一段 [first, last) 内的字符
template <class CharType, class CharTraits>
template <class Iter>
basic_string<CharType, CharTraits>&
basic_string<CharType, CharTraits>::
append_range(Iter first, Iter last)
{
const size_type n = mystl::distance(first, last);
THROW_LENGTH_ERROR_IF(size_ > max_size() - n,
"basic_string<Char, Tratis>'s size too big");
if (cap_ - size_ < n)
{
reallocate(n);
}
mystl::uninitialized_copy_n(first, n, buffer_ + size_);
size_ += n;
return *this;
}
template <class CharType, class CharTraits>
int basic_string<CharType, CharTraits>::
compare_cstr(const_pointer s1, size_type n1, const_pointer s2, size_type n2) const
{
auto rlen = mystl::min(n1, n2);
auto res = char_traits::compare(s1, s2, rlen);
if (res != 0) return res;
if (n1 < n2) return -1;
if (n1 > n2) return 1;
return 0;
}
// 把 first 开始的 count1 个字符替换成 str 开始的 count2 个字符
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>&
basic_string<CharType, CharTraits>::
replace_cstr(const_iterator first, size_type count1, const_pointer str, size_type count2)
{
if (static_cast<size_type>(cend() - first) < count1)
{
count1 = cend() - first;
}
if (count1 < count2)
{
const size_type add = count2 - count1;
THROW_LENGTH_ERROR_IF(size_ > max_size() - add,
"basic_string<Char, Traits>'s size too big");
if (size_ > cap_ - add)
{
reallocate(add);
}
pointer r = const_cast<pointer>(first);
char_traits::move(r + count2, first + count1, end() - (first + count1));
char_traits::copy(r, str, count2);
size_ += add;
}
else
{
pointer r = const_cast<pointer>(first);
char_traits::move(r + count2, first + count1, end() - (first + count1));
char_traits::copy(r, str, count2);
size_ -= (count1 - count2);
}
return *this;
}
// 把 first 开始的 count1 个字符替换成 count2 个 ch 字符
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>&
basic_string<CharType, CharTraits>::
replace_fill(const_iterator first, size_type count1, size_type count2, value_type ch)
{
if (static_cast<size_type>(cend() - first) < count1)
{
count1 = cend() - first;
}
if (count1 < count2)
{
const size_type add = count2 - count1;
THROW_LENGTH_ERROR_IF(size_ > max_size() - add,
"basic_string<Char, Traits>'s size too big");
if (size_ > cap_ - add)
{
reallocate(add);
}
pointer r = const_cast<pointer>(first);
char_traits::move(r + count2, first + count1, end() - (first + count1));
char_traits::fill(r, ch, count2);
size_ += add;
}
else
{
pointer r = const_cast<pointer>(first);
char_traits::move(r + count2, first + count1, end() - (first + count1));
char_traits::fill(r, ch, count2);
size_ -= (count1 - count2);
}
return *this;
}
// 把 [first, last) 的字符替换成 [first2, last2)
template <class CharType, class CharTraits>
template <class Iter>
basic_string<CharType, CharTraits>&
basic_string<CharType, CharTraits>::
replace_copy(const_iterator first, const_iterator last, Iter first2, Iter last2)
{
size_type len1 = last - first;
size_type len2 = last2 - first2;
if (len1 < len2)
{
const size_type add = len2 - len1;
THROW_LENGTH_ERROR_IF(size_ > max_size() - add,
"basic_string<Char, Traits>'s size too big");
if (size_ > cap_ - add)
{
reallocate(add);
}
pointer r = const_cast<pointer>(first);
char_traits::move(r + len2, first + len1, end() - (first + len1));
char_traits::copy(r, first2, len2);
size_ += add;
}
else
{
pointer r = const_cast<pointer>(first);
char_traits::move(r + len2, first + len1, end() - (first + len1));
char_traits::copy(r, first2, len2);
size_ -= (len1 - len2);
}
return *this;
}
// reallocate 函数
template <class CharType, class CharTraits>
void basic_string<CharType, CharTraits>::
reallocate(size_type need)
{
const auto new_cap = mystl::max(cap_ + need, cap_ + (cap_ >> 1));
auto new_buffer = data_allocator::allocate(new_cap);
char_traits::move(new_buffer, buffer_, size_);
data_allocator::deallocate(buffer_);
buffer_ = new_buffer;
cap_ = new_cap;
}
// reallocate_and_fill 函数
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::iterator
basic_string<CharType, CharTraits>::
reallocate_and_fill(iterator pos, size_type n, value_type ch)
{
const auto r = pos - buffer_;
const auto old_cap = cap_;
const auto new_cap = mystl::max(old_cap + n, old_cap + (old_cap >> 1));
auto new_buffer = data_allocator::allocate(new_cap);
auto e1 = char_traits::move(new_buffer, buffer_, r) + r;
auto e2 = char_traits::fill(e1, ch, n) + n;
char_traits::move(e2, buffer_ + r, size_ - r);
data_allocator::deallocate(buffer_, old_cap);
buffer_ = new_buffer;
size_ += n;
cap_ = new_cap;
return buffer_ + r;
}
// reallocate_and_copy 函数
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::iterator
basic_string<CharType, CharTraits>::
reallocate_and_copy(iterator pos, const_iterator first, const_iterator last)
{
const auto r = pos - buffer_;
const auto old_cap = cap_;
const size_type n = mystl::distance(first, last);
const auto new_cap = mystl::max(old_cap + n, old_cap + (old_cap >> 1));
auto new_buffer = data_allocator::allocate(new_cap);
auto e1 = char_traits::move(new_buffer, buffer_, r) + r;
auto e2 = mystl::uninitialized_copy_n(first, n, e1) + n;
char_traits::move(e2, buffer_ + r, size_ - r);
data_allocator::deallocate(buffer_, old_cap);
buffer_ = new_buffer;
size_ += n;
cap_ = new_cap;
return buffer_ + r;
}
/*****************************************************************************************/
// 重载全局操作符
// 重载 operator+
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>
operator+(const basic_string<CharType, CharTraits>& lhs,
const basic_string<CharType, CharTraits>& rhs)
{
basic_string<CharType, CharTraits> tmp(lhs);
tmp.append(rhs);
return tmp;
}
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>
operator+(const CharType* lhs, const basic_string<CharType, CharTraits>& rhs)
{
basic_string<CharType, CharTraits> tmp(lhs);
tmp.append(rhs);
return tmp;
}
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>
operator+(CharType ch, const basic_string<CharType, CharTraits>& rhs)
{
basic_string<CharType, CharTraits> tmp(1, ch);
tmp.append(rhs);
return tmp;
}
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>
operator+(const basic_string<CharType, CharTraits>& lhs, const CharType* rhs)
{
basic_string<CharType, CharTraits> tmp(lhs);
tmp.append(rhs);
return tmp;
}
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>
operator+(const basic_string<CharType, CharTraits>& lhs, CharType ch)
{
basic_string<CharType, CharTraits> tmp(lhs);
tmp.append(1, ch);
return tmp;
}
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>
operator+(basic_string<CharType, CharTraits>&& lhs,
const basic_string<CharType, CharTraits>& rhs)
{
basic_string<CharType, CharTraits> tmp(mystl::move(lhs));
tmp.append(rhs);
return tmp;
}
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>
operator+(const basic_string<CharType, CharTraits>& lhs,
basic_string<CharType, CharTraits>&& rhs)
{
basic_string<CharType, CharTraits> tmp(mystl::move(rhs));
tmp.insert(tmp.begin(), lhs.begin(), lhs.end());
return tmp;
}
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>
operator+(basic_string<CharType, CharTraits>&& lhs,
basic_string<CharType, CharTraits>&& rhs)
{
basic_string<CharType, CharTraits> tmp(mystl::move(lhs));
tmp.append(rhs);
return tmp;
}
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>
operator+(const CharType* lhs, basic_string<CharType, CharTraits>&& rhs)
{
basic_string<CharType, CharTraits> tmp(mystl::move(rhs));
tmp.insert(tmp.begin(), lhs, lhs + char_traits<CharType>::length(lhs));
return tmp;
}
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>
operator+(CharType ch, basic_string<CharType, CharTraits>&& rhs)
{
basic_string<CharType, CharTraits> tmp(mystl::move(rhs));
tmp.insert(tmp.begin(), ch);
return tmp;
}
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>
operator+(basic_string<CharType, CharTraits>&& lhs, const CharType* rhs)
{
basic_string<CharType, CharTraits> tmp(mystl::move(lhs));
tmp.append(rhs);
return tmp;
}
template <class CharType, class CharTraits>
basic_string<CharType, CharTraits>
operator+(basic_string<CharType, CharTraits>&& lhs, CharType ch)
{
basic_string<CharType, CharTraits> tmp(mystl::move(lhs));
tmp.append(1, ch);
return tmp;
}
// 重载比较操作符
template <class CharType, class CharTraits>
bool operator==(const basic_string<CharType, CharTraits>& lhs,
const basic_string<CharType, CharTraits>& rhs)
{
return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
}
template <class CharType, class CharTraits>
bool operator!=(const basic_string<CharType, CharTraits>& lhs,
const basic_string<CharType, CharTraits>& rhs)
{
return lhs.size() != rhs.size() || lhs.compare(rhs) != 0;
}
template <class CharType, class CharTraits>
bool operator<(const basic_string<CharType, CharTraits>& lhs,
const basic_string<CharType, CharTraits>& rhs)
{
return lhs.compare(rhs) < 0;
}
template <class CharType, class CharTraits>
bool operator<=(const basic_string<CharType, CharTraits>& lhs,
const basic_string<CharType, CharTraits>& rhs)
{
return lhs.compare(rhs) <= 0;
}
template <class CharType, class CharTraits>
bool operator>(const basic_string<CharType, CharTraits>& lhs,
const basic_string<CharType, CharTraits>& rhs)
{
return lhs.compare(rhs) > 0;
}
template <class CharType, class CharTraits>
bool operator>=(const basic_string<CharType, CharTraits>& lhs,
const basic_string<CharType, CharTraits>& rhs)
{
return lhs.compare(rhs) >= 0;
}
// 重载 mystl 的 swap
template <class CharType, class CharTraits>
void swap(basic_string<CharType, CharTraits>& lhs,
basic_string<CharType, CharTraits>& rhs) noexcept
{
lhs.swap(rhs);
}
// 特化 mystl::hash
template <class CharType, class CharTraits>
struct hash<basic_string<CharType, CharTraits>>
{
size_t operator()(const basic_string<CharType, CharTraits>& str)
{
return bitwise_hash((const unsigned char*)str.c_str(),
str.size() * sizeof(CharType));
}
};
} // namespace mystl
#endif // !MYTINYSTL_BASIC_STRING_H_
================================================
FILE: MyTinySTL/construct.h
================================================
#ifndef MYTINYSTL_CONSTRUCT_H_
#define MYTINYSTL_CONSTRUCT_H_
// 这个头文件包含两个函数 construct,destroy
// construct : 负责对象的构造
// destroy : 负责对象的析构
#include <new>
#include "type_traits.h"
#include "iterator.h"
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4100) // unused parameter
#endif // _MSC_VER
namespace mystl
{
// construct 构造对象
template <class Ty>
void construct(Ty* ptr)
{
::new ((void*)ptr) Ty();
}
template <class Ty1, class Ty2>
void construct(Ty1* ptr, const Ty2& value)
{
::new ((void*)ptr) Ty1(value);
}
template <class Ty, class... Args>
void construct(Ty* ptr, Args&&... args)
{
::new ((void*)ptr) Ty(mystl::forward<Args>(args)...);
}
// destroy 将对象析构
template <class Ty>
void destroy_one(Ty*, std::true_type) {}
template <class Ty>
void destroy_one(Ty* pointer, std::false_type)
{
if (pointer != nullptr)
{
pointer->~Ty();
}
}
template <class ForwardIter>
void destroy_cat(ForwardIter , ForwardIter , std::true_type) {}
template <class ForwardIter>
void destroy_cat(ForwardIter first, ForwardIter last, std::false_type)
{
for (; first != last; ++first)
destroy(&*first);
}
template <class Ty>
void destroy(Ty* pointer)
{
destroy_one(pointer, std::is_trivially_destructible<Ty>{});
}
template <class ForwardIter>
void destroy(ForwardIter first, ForwardIter last)
{
destroy_cat(first, last, std::is_trivially_destructible<
typename iterator_traits<ForwardIter>::value_type>{});
}
} // namespace mystl
#ifdef _MSC_VER
#pragma warning(pop)
#endif // _MSC_VER
#endif // !MYTINYSTL_CONSTRUCT_H_
================================================
FILE: MyTinySTL/deque.h
================================================
#ifndef MYTINYSTL_DEQUE_H_
#define MYTINYSTL_DEQUE_H_
// 这个头文件包含了一个模板类 deque
// deque: 双端队列
// notes:
//
// 异常保证:
// mystl::deque<T> 满足基本异常保证,部分函数无异常保证,并对以下等函数做强异常安全保证:
// * emplace_front
// * emplace_back
// * emplace
// * push_front
// * push_back
// * insert
#include <initializer_list>
#include "iterator.h"
#include "memory.h"
#include "util.h"
#include "exceptdef.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
// deque map 初始化的大小
#ifndef DEQUE_MAP_INIT_SIZE
#define DEQUE_MAP_INIT_SIZE 8
#endif
template <class T>
struct deque_buf_size
{
static constexpr size_t value = sizeof(T) < 256 ? 4096 / sizeof(T) : 16;
};
// deque 的迭代器设计
template <class T, class Ref, class Ptr>
struct deque_iterator : public iterator<random_access_iterator_tag, T>
{
typedef deque_iterator<T, T&, T*> iterator;
typedef deque_iterator<T, const T&, const T*> const_iterator;
typedef deque_iterator self;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* value_pointer;
typedef T** map_pointer;
static const size_type buffer_size = deque_buf_size<T>::value;
// 迭代器所含成员数据
value_pointer cur; // 指向所在缓冲区的当前元素
value_pointer first; // 指向所在缓冲区的头部
value_pointer last; // 指向所在缓冲区的尾部
map_pointer node; // 缓冲区所在节点
// 构造、复制、移动函数
deque_iterator() noexcept
:cur(nullptr), first(nullptr), last(nullptr), node(nullptr) {}
deque_iterator(value_pointer v, map_pointer n)
:cur(v), first(*n), last(*n + buffer_size), node(n) {}
deque_iterator(const iterator& rhs)
:cur(rhs.cur), first(rhs.first), last(rhs.last), node(rhs.node)
{
}
deque_iterator(iterator&& rhs) noexcept
:cur(rhs.cur), first(rhs.first), last(rhs.last), node(rhs.node)
{
rhs.cur = nullptr;
rhs.first = nullptr;
rhs.last = nullptr;
rhs.node = nullptr;
}
deque_iterator(const const_iterator& rhs)
:cur(rhs.cur), first(rhs.first), last(rhs.last), node(rhs.node)
{
}
self& operator=(const iterator& rhs)
{
if (this != &rhs)
{
cur = rhs.cur;
first = rhs.first;
last = rhs.last;
node = rhs.node;
}
return *this;
}
// 转到另一个缓冲区
void set_node(map_pointer new_node)
{
node = new_node;
first = *new_node;
last = first + buffer_size;
}
// 重载运算符
reference operator*() const { return *cur; }
pointer operator->() const { return cur; }
difference_type operator-(const self& x) const
{
return static_cast<difference_type>(buffer_size) * (node - x.node)
+ (cur - first) - (x.cur - x.first);
}
self& operator++()
{
++cur;
if (cur == last)
{ // 如果到达缓冲区的尾
set_node(node + 1);
cur = first;
}
return *this;
}
self operator++(int)
{
self tmp = *this;
++*this;
return tmp;
}
self& operator--()
{
if (cur == first)
{ // 如果到达缓冲区的头
set_node(node - 1);
cur = last;
}
--cur;
return *this;
}
self operator--(int)
{
self tmp = *this;
--*this;
return tmp;
}
self& operator+=(difference_type n)
{
const auto offset = n + (cur - first);
if (offset >= 0 && offset < static_cast<difference_type>(buffer_size))
{ // 仍在当前缓冲区
cur += n;
}
else
{ // 要跳到其他的缓冲区
const auto node_offset = offset > 0
? offset / static_cast<difference_type>(buffer_size)
: -static_cast<difference_type>((-offset - 1) / buffer_size) - 1;
set_node(node + node_offset);
cur = first + (offset - node_offset * static_cast<difference_type>(buffer_size));
}
return *this;
}
self operator+(difference_type n) const
{
self tmp = *this;
return tmp += n;
}
self& operator-=(difference_type n)
{
return *this += -n;
}
self operator-(difference_type n) const
{
self tmp = *this;
return tmp -= n;
}
reference operator[](difference_type n) const { return *(*this + n); }
// 重载比较操作符
bool operator==(const self& rhs) const { return cur == rhs.cur; }
bool operator< (const self& rhs) const
{ return node == rhs.node ? (cur < rhs.cur) : (node < rhs.node); }
bool operator!=(const self& rhs) const { return !(*this == rhs); }
bool operator> (const self& rhs) const { return rhs < *this; }
bool operator<=(const self& rhs) const { return !(rhs < *this); }
bool operator>=(const self& rhs) const { return !(*this < rhs); }
};
// 模板类 deque
// 模板参数代表数据类型
template <class T>
class deque
{
public:
// deque 的型别定义
typedef mystl::allocator<T> allocator_type;
typedef mystl::allocator<T> data_allocator;
typedef mystl::allocator<T*> map_allocator;
typedef typename allocator_type::value_type value_type;
typedef typename allocator_type::pointer pointer;
typedef typename allocator_type::const_pointer const_pointer;
typedef typename allocator_type::reference reference;
typedef typename allocator_type::const_reference const_reference;
typedef typename allocator_type::size_type size_type;
typedef typename allocator_type::difference_type difference_type;
typedef pointer* map_pointer;
typedef const_pointer* const_map_pointer;
typedef deque_iterator<T, T&, T*> iterator;
typedef deque_iterator<T, const T&, const T*> const_iterator;
typedef mystl::reverse_iterator<iterator> reverse_iterator;
typedef mystl::reverse_iterator<const_iterator> const_reverse_iterator;
allocator_type get_allocator() { return allocator_type(); }
static const size_type buffer_size = deque_buf_size<T>::value;
private:
// 用以下四个数据来表现一个 deque
iterator begin_; // 指向第一个节点
iterator end_; // 指向最后一个结点
map_pointer map_; // 指向一块 map,map 中的每个元素都是一个指针,指向一个缓冲区
size_type map_size_; // map 内指针的数目
public:
// 构造、复制、移动、析构函数
deque()
{ fill_init(0, value_type()); }
explicit deque(size_type n)
{ fill_init(n, value_type()); }
deque(size_type n, const value_type& value)
{ fill_init(n, value); }
template <class IIter, typename std::enable_if<
mystl::is_input_iterator<IIter>::value, int>::type = 0>
deque(IIter first, IIter last)
{ copy_init(first, last, iterator_category(first)); }
deque(std::initializer_list<value_type> ilist)
{
copy_init(ilist.begin(), ilist.end(), mystl::forward_iterator_tag());
}
deque(const deque& rhs)
{
copy_init(rhs.begin(), rhs.end(), mystl::forward_iterator_tag());
}
deque(deque&& rhs) noexcept
:begin_(mystl::move(rhs.begin_)),
end_(mystl::move(rhs.end_)),
map_(rhs.map_),
map_size_(rhs.map_size_)
{
rhs.map_ = nullptr;
rhs.map_size_ = 0;
}
deque& operator=(const deque& rhs);
deque& operator=(deque&& rhs);
deque& operator=(std::initializer_list<value_type> ilist)
{
deque tmp(ilist);
swap(tmp);
return *this;
}
~deque()
{
if (map_ != nullptr)
{
clear();
data_allocator::deallocate(*begin_.node, buffer_size);
*begin_.node = nullptr;
map_allocator::deallocate(map_, map_size_);
map_ = nullptr;
}
}
public:
// 迭代器相关操作
iterator begin() noexcept
{ return begin_; }
const_iterator begin() const noexcept
{ return begin_; }
iterator end() noexcept
{ return end_; }
const_iterator end() const noexcept
{ return end_; }
reverse_iterator rbegin() noexcept
{ return reverse_iterator(end()); }
const_reverse_iterator rbegin() const noexcept
{ return reverse_iterator(end()); }
reverse_iterator rend() noexcept
{ return reverse_iterator(begin()); }
const_reverse_iterator rend() const noexcept
{ return reverse_iterator(begin()); }
const_iterator cbegin() const noexcept
{ return begin(); }
const_iterator cend() const noexcept
{ return end(); }
const_reverse_iterator crbegin() const noexcept
{ return rbegin(); }
const_reverse_iterator crend() const noexcept
{ return rend(); }
// 容量相关操作
bool empty() const noexcept { return begin() == end(); }
size_type size() const noexcept { return end_ - begin_; }
size_type max_size() const noexcept { return static_cast<size_type>(-1); }
void resize(size_type new_size) { resize(new_size, value_type()); }
void resize(size_type new_size, const value_type& value);
void shrink_to_fit() noexcept;
// 访问元素相关操作
reference operator[](size_type n)
{
MYSTL_DEBUG(n < size());
return begin_[n];
}
const_reference operator[](size_type n) const
{
MYSTL_DEBUG(n < size());
return begin_[n];
}
reference at(size_type n)
{
THROW_OUT_OF_RANGE_IF(!(n < size()), "deque<T>::at() subscript out of range");
return (*this)[n];
}
const_reference at(size_type n) const
{
THROW_OUT_OF_RANGE_IF(!(n < size()), "deque<T>::at() subscript out of range");
return (*this)[n];
}
reference front()
{
MYSTL_DEBUG(!empty());
return *begin();
}
const_reference front() const
{
MYSTL_DEBUG(!empty());
return *begin();
}
reference back()
{
MYSTL_DEBUG(!empty());
return *(end() - 1);
}
const_reference back() const
{
MYSTL_DEBUG(!empty());
return *(end() - 1);
}
// 修改容器相关操作
// assign
void assign(size_type n, const value_type& value)
{ fill_assign(n, value); }
template <class IIter, typename std::enable_if<
mystl::is_input_iterator<IIter>::value, int>::type = 0>
void assign(IIter first, IIter last)
{ copy_assign(first, last, iterator_category(first)); }
void assign(std::initializer_list<value_type> ilist)
{ copy_assign(ilist.begin(), ilist.end(), mystl::forward_iterator_tag{}); }
// emplace_front / emplace_back / emplace
template <class ...Args>
void emplace_front(Args&& ...args);
template <class ...Args>
void emplace_back(Args&& ...args);
template <class ...Args>
iterator emplace(iterator pos, Args&& ...args);
// push_front / push_back
void push_front(const value_type& value);
void push_back(const value_type& value);
void push_front(value_type&& value) { emplace_front(mystl::move(value)); }
void push_back(value_type&& value) { emplace_back(mystl::move(value)); }
// pop_back / pop_front
void pop_front();
void pop_back();
// insert
iterator insert(iterator position, const value_type& value);
iterator insert(iterator position, value_type&& value);
void insert(iterator position, size_type n, const value_type& value);
template <class IIter, typename std::enable_if<
mystl::is_input_iterator<IIter>::value, int>::type = 0>
void insert(iterator position, IIter first, IIter last)
{ insert_dispatch(position, first, last, iterator_category(first)); }
// erase /clear
iterator erase(iterator position);
iterator erase(iterator first, iterator last);
void clear();
// swap
void swap(deque& rhs) noexcept;
private:
// helper functions
// create node / destroy node
map_pointer create_map(size_type size);
void create_buffer(map_pointer nstart, map_pointer nfinish);
void destroy_buffer(map_pointer nstart, map_pointer nfinish);
// initialize
void map_init(size_type nelem);
void fill_init(size_type n, const value_type& value);
template <class IIter>
void copy_init(IIter, IIter, input_iterator_tag);
template <class FIter>
void copy_init(FIter, FIter, forward_iterator_tag);
// assign
void fill_assign(size_type n, const value_type& value);
template <class IIter>
void copy_assign(IIter first, IIter last, input_iterator_tag);
template <class FIter>
void copy_assign(FIter first, FIter last, forward_iterator_tag);
// insert
template <class... Args>
iterator insert_aux(iterator position, Args&& ...args);
void fill_insert(iterator position, size_type n, const value_type& x);
template <class FIter>
void copy_insert(iterator, FIter, FIter, size_type);
template <class IIter>
void insert_dispatch(iterator, IIter, IIter, input_iterator_tag);
template <class FIter>
void insert_dispatch(iterator, FIter, FIter, forward_iterator_tag);
// reallocate
void require_capacity(size_type n, bool front);
void reallocate_map_at_front(size_type need);
void reallocate_map_at_back(size_type need);
};
/*****************************************************************************************/
// 复制赋值运算符
template <class T>
deque<T>& deque<T>::operator=(const deque& rhs)
{
if (this != &rhs)
{
const auto len = size();
if (len >= rhs.size())
{
erase(mystl::copy(rhs.begin_, rhs.end_, begin_), end_);
}
else
{
iterator mid = rhs.begin() + static_cast<difference_type>(len)
gitextract_bjpk8nmi/ ├── .gitattributes ├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── License.txt ├── MSVC/ │ ├── MyTinySTL_VS2015.sln │ ├── MyTinySTL_VS2015.vcxproj │ └── MyTinySTL_VS2015.vcxproj.filters ├── MyTinySTL/ │ ├── algo.h │ ├── algobase.h │ ├── algorithm.h │ ├── alloc.h │ ├── allocator.h │ ├── astring.h │ ├── basic_string.h │ ├── construct.h │ ├── deque.h │ ├── exceptdef.h │ ├── functional.h │ ├── hashtable.h │ ├── heap_algo.h │ ├── iterator.h │ ├── list.h │ ├── map.h │ ├── memory.h │ ├── numeric.h │ ├── queue.h │ ├── rb_tree.h │ ├── set.h │ ├── set_algo.h │ ├── stack.h │ ├── stream_iterator.h │ ├── type_traits.h │ ├── uninitialized.h │ ├── unordered_map.h │ ├── unordered_set.h │ ├── util.h │ └── vector.h ├── README.md ├── Test/ │ ├── CMakeLists.txt │ ├── Lib/ │ │ └── redbud/ │ │ ├── io/ │ │ │ └── color.h │ │ └── platform.h │ ├── README.md │ ├── algorithm_performance_test.h │ ├── algorithm_test.h │ ├── deque_test.h │ ├── iterator_test.h │ ├── list_test.h │ ├── map_test.h │ ├── queue_test.h │ ├── set_test.h │ ├── stack_test.h │ ├── string_test.h │ ├── test.cpp │ ├── test.h │ ├── unordered_map_test.h │ ├── unordered_set_test.h │ └── vector_test.h └── appveyor.yml
SYMBOL INDEX (757 symbols across 47 files)
FILE: MyTinySTL/algo.h
function namespace (line 19) | namespace mystl
type reverse_iterator (line 342) | typedef reverse_iterator<BidirectionalIter2> reviter2;
type typename (line 364) | typedef typename iterator_traits<ForwardIter2>::iterator_category Catego...
type reverse_iterator (line 409) | typedef reverse_iterator<BidirectionalIter2> reviter2;
type typename (line 431) | typedef typename iterator_traits<ForwardIter2>::iterator_category Catego...
type typename (line 1689) | typedef typename iterator_traits<ForwardIter1>::value_type v1;
type typename (line 1690) | typedef typename iterator_traits<ForwardIter2>::value_type v2;
function else (line 2108) | else if (len2 <= buffer_size)
FILE: MyTinySTL/algobase.h
function namespace (line 11) | namespace mystl
function lexicographical_compare (line 476) | bool lexicographical_compare(const unsigned char* first1,
FILE: MyTinySTL/algorithm.h
function namespace (line 12) | namespace mystl
FILE: MyTinySTL/alloc.h
function namespace (line 20) | namespace mystl
FILE: MyTinySTL/allocator.h
function namespace (line 9) | namespace mystl
FILE: MyTinySTL/astring.h
function namespace (line 8) | namespace mystl
FILE: MyTinySTL/basic_string.h
function namespace (line 14) | namespace mystl
function iterator (line 376) | iterator end() noexcept
function reverse_iterator (line 381) | reverse_iterator rbegin() noexcept
function const_reverse_iterator (line 383) | const_reverse_iterator rbegin() const noexcept
function const_reverse_iterator (line 387) | const_reverse_iterator rend() const noexcept
function const_iterator (line 392) | const_iterator cend() const noexcept
function const_reverse_iterator (line 396) | const_reverse_iterator crend() const noexcept
function reference (line 416) | reference operator[](size_type n)
function const_reference (line 423) | const_reference operator[](size_type n) const
function reference (line 431) | reference at(size_type n)
function const_reference (line 437) | const_reference at(size_type n) const
function reference (line 444) | reference front()
function reference (line 455) | reference back()
function const_pointer (line 466) | const_pointer data() const noexcept
function push_back (line 482) | void push_back(value_type ch)
function pop_back (line 484) | void pop_back()
function resize (line 513) | void resize(size_type count)
function clear (line 517) | void clear() noexcept
function basic_string (line 532) | basic_string substr(size_type index, size_type count = npos)
function reverse (line 601) | void reverse() noexcept;
function const_pointer (line 693) | const_pointer to_raw_pointer() const;
FILE: MyTinySTL/construct.h
function namespace (line 18) | namespace mystl
FILE: MyTinySTL/deque.h
function namespace (line 25) | namespace mystl
function set_node (line 111) | void set_node(map_pointer new_node)
function reference (line 119) | reference operator*() const { return *cur; }
function pointer (line 120) | pointer operator->() const { return cur; }
function reference (line 194) | reference operator[](difference_type n) const { return *(*this + n); }
function operator (line 197) | bool operator==(const self& rhs) const { return cur == rhs.cur; }
function operator (line 198) | bool operator< (const self& rhs) const
function operator (line 200) | bool operator!=(const self& rhs) const { return !(*this == rhs); }
function operator (line 201) | bool operator> (const self& rhs) const { return rhs < *this; }
function operator (line 202) | bool operator<=(const self& rhs) const { return !(rhs < *this); }
function operator (line 203) | bool operator>=(const self& rhs) const { return !(*this < rhs); }
type mystl (line 214) | typedef mystl::allocator<T> data_allocator;
type mystl (line 215) | typedef mystl::allocator<T*> map_allocator;
type typename (line 217) | typedef typename allocator_type::value_type value_type;
type typename (line 218) | typedef typename allocator_type::pointer pointer;
type typename (line 219) | typedef typename allocator_type::const_pointer const_pointer;
type typename (line 220) | typedef typename allocator_type::reference reference;
type typename (line 221) | typedef typename allocator_type::const_reference const_reference;
type typename (line 222) | typedef typename allocator_type::size_type size_type;
type typename (line 223) | typedef typename allocator_type::difference_type difference_type;
type pointer (line 224) | typedef pointer* map_pointer;
type const_pointer (line 225) | typedef const_pointer* const_map_pointer;
type deque_iterator (line 227) | typedef deque_iterator<T, T&, T*> iterator;
type deque_iterator (line 228) | typedef deque_iterator<T, const
type mystl (line 229) | typedef mystl::reverse_iterator<iterator> reverse_iterator;
type mystl (line 230) | typedef mystl::reverse_iterator<const_iterator> const_reverse_iterator;
function allocator_type (line 232) | allocator_type get_allocator() { return allocator_type(); }
function explicit (line 249) | explicit deque(size_type n)
function iterator (line 308) | iterator end() noexcept
function reverse_iterator (line 313) | reverse_iterator rbegin() noexcept
function const_reverse_iterator (line 315) | const_reverse_iterator rbegin() const noexcept
function const_reverse_iterator (line 319) | const_reverse_iterator rend() const noexcept
function const_iterator (line 324) | const_iterator cend() const noexcept
function const_reverse_iterator (line 328) | const_reverse_iterator crend() const noexcept
function resize (line 336) | void resize(size_type new_size) { resize(new_size, value_type()); }
function shrink_to_fit (line 338) | void shrink_to_fit() noexcept;
function const_reference (line 346) | const_reference operator[](size_type n) const
function reference (line 352) | reference at(size_type n)
function const_reference (line 357) | const_reference at(size_type n) const
function reference (line 363) | reference front()
function reference (line 373) | reference back()
function assign (line 388) | void assign(size_type n, const value_type& value)
function assign (line 396) | void assign(std::initializer_list<value_type> ilist)
function push_front (line 413) | void push_front(value_type&& value) { emplace_front(mystl::move(valu...
function push_back (line 414) | void push_back(value_type&& value) { emplace_back(mystl::move(value...
FILE: MyTinySTL/exceptdef.h
function namespace (line 8) | namespace mystl
FILE: MyTinySTL/functional.h
function namespace (line 8) | namespace mystl
function T (line 67) | T operator()(const T& x) const { return -x; }
function const (line 82) | bool operator()(const T& x, const T& y) const { return x == y; }
function const (line 89) | bool operator()(const T& x, const T& y) const { return x != y; }
function const (line 96) | bool operator()(const T& x, const T& y) const { return x > y; }
function const (line 103) | bool operator()(const T& x, const T& y) const { return x < y; }
function const (line 110) | bool operator()(const T& x, const T& y) const { return x >= y; }
function const (line 117) | bool operator()(const T& x, const T& y) const { return x <= y; }
function const (line 124) | bool operator()(const T& x, const T& y) const { return x && y; }
function const (line 131) | bool operator()(const T& x, const T& y) const { return x || y; }
function const (line 138) | bool operator()(const T& x) const { return !x; }
function T (line 145) | const T& operator()(const T& x) const { return x; }
function typename (line 152) | const typename Pair::first_type& operator()(const Pair& x) const
function typename (line 162) | const typename Pair::second_type& operator()(const Pair& x) const
function Arg1 (line 172) | Arg1 operator()(const Arg1& x, const Arg2&) const { return x; }
function Arg2 (line 179) | Arg2 operator()(const Arg1&, const Arg2& y) const { return y; }
function bitwise_hash (line 238) | inline size_t bitwise_hash(const unsigned char* first, size_t count)
function float (line 257) | struct hash<float>
function double (line 266) | struct hash<double>
type hash (line 275) | struct hash
FILE: MyTinySTL/hashtable.h
function namespace (line 16) | namespace mystl
type T (line 40) | typedef T key_type;
type T (line 41) | typedef T mapped_type;
type T (line 42) | typedef T value_type;
type typename (line 60) | typedef typename std::remove_cv<typename
type typename (line 61) | typedef typename T::second_type mapped_type;
type T (line 62) | typedef T value_type;
type ht_value_traits_imp (line 82) | typedef ht_value_traits_imp<T, is_map> value_traits_type;
type typename (line 84) | typedef typename value_traits_type::key_type key_type;
type typename (line 85) | typedef typename value_traits_type::mapped_type mapped_type;
type typename (line 86) | typedef typename value_traits_type::value_type value_type;
type ht_iterator_base (line 125) | typedef ht_iterator_base<T, Hash, KeyEqual> base;
type mystl (line 126) | typedef mystl::ht_iterator<T, Hash, KeyEqual> iterator;
type mystl (line 127) | typedef mystl::ht_const_iterator<T, Hash, KeyEqual> const_iterator;
type hashtable_node (line 128) | typedef hashtable_node<T>* node_ptr;
type hashtable (line 129) | typedef hashtable* contain_ptr;
type node_ptr (line 130) | typedef const node_ptr const_node_ptr;
type contain_ptr (line 131) | typedef const contain_ptr const_contain_ptr;
type size_type (line 133) | typedef size_t size_type;
type difference_type (line 134) | typedef ptrdiff_t difference_type;
function operator (line 141) | bool operator==(const base& rhs) const { return node == rhs.node; }
function operator (line 142) | bool operator!=(const base& rhs) const { return node != rhs.node; }
type typename (line 149) | typedef typename base::hashtable hashtable;
type typename (line 150) | typedef typename base::iterator iterator;
type typename (line 151) | typedef typename base::const_iterator const_iterator;
type typename (line 152) | typedef typename base::node_ptr node_ptr;
type typename (line 153) | typedef typename base::contain_ptr contain_ptr;
type ht_value_traits (line 155) | typedef ht_value_traits<T> value_traits;
type T (line 156) | typedef T value_type;
type value_type (line 157) | typedef value_type* pointer;
type value_type (line 158) | typedef value_type& reference;
function reference (line 199) | reference operator*() const { return node->value; }
function pointer (line 200) | pointer operator->() const { return &(operator*()); }
type typename (line 227) | typedef typename base::hashtable hashtable;
type typename (line 228) | typedef typename base::iterator iterator;
type typename (line 229) | typedef typename base::const_iterator const_iterator;
type typename (line 230) | typedef typename base::const_node_ptr node_ptr;
type typename (line 231) | typedef typename base::const_contain_ptr contain_ptr;
type ht_value_traits (line 233) | typedef ht_value_traits<T> value_traits;
type T (line 234) | typedef T value_type;
type value_type (line 235) | typedef const value_type* pointer;
type value_type (line 236) | typedef const value_type& reference;
function reference (line 277) | reference operator*() const { return node->value; }
function pointer (line 278) | pointer operator->() const { return &(operator*()); }
type T (line 307) | typedef T value_type;
type value_type (line 308) | typedef value_type* pointer;
type value_type (line 309) | typedef value_type& reference;
type size_type (line 310) | typedef size_t size_type;
type difference_type (line 311) | typedef ptrdiff_t difference_type;
type hashtable_node (line 312) | typedef hashtable_node<T>* node_ptr;
type ht_local_iterator (line 314) | typedef ht_local_iterator<T> self;
type ht_local_iterator (line 315) | typedef ht_local_iterator<T> local_iterator;
type ht_const_local_iterator (line 316) | typedef ht_const_local_iterator<T> const_local_iterator;
function node (line 319) | ht_local_iterator(node_ptr n)
function node (line 323) | ht_local_iterator(const local_iterator& rhs)
function node (line 327) | ht_local_iterator(const const_local_iterator& rhs)
function reference (line 332) | reference operator*() const { return node->value; }
function pointer (line 333) | pointer operator->() const { return &(operator*()); }
function operator (line 349) | bool operator==(const self& other) const { return node == other.node; }
function operator (line 350) | bool operator!=(const self& other) const { return node != other.node; }
type T (line 356) | typedef T value_type;
type value_type (line 357) | typedef const value_type* pointer;
type value_type (line 358) | typedef const value_type& reference;
type size_type (line 359) | typedef size_t size_type;
type difference_type (line 360) | typedef ptrdiff_t difference_type;
type hashtable_node (line 361) | typedef const hashtable_node<T>* node_ptr;
type ht_const_local_iterator (line 363) | typedef ht_const_local_iterator<T> self;
type ht_local_iterator (line 364) | typedef ht_local_iterator<T> local_iterator;
type ht_const_local_iterator (line 365) | typedef ht_const_local_iterator<T> const_local_iterator;
function node (line 369) | ht_const_local_iterator(node_ptr n)
function node (line 373) | ht_const_local_iterator(const local_iterator& rhs)
function node (line 377) | ht_const_local_iterator(const const_local_iterator& rhs)
function reference (line 382) | reference operator*() const { return node->value; }
function pointer (line 383) | pointer operator->() const { return &(operator*()); }
function operator (line 399) | bool operator==(const self& other) const { return node == other.node; }
function operator (line 400) | bool operator!=(const self& other) const { return node != other.node; }
function ht_next_prime (line 462) | inline size_t ht_next_prime(size_t n)
type typename (line 482) | typedef typename value_traits::key_type key_type;
type typename (line 483) | typedef typename value_traits::mapped_type mapped_type;
type typename (line 484) | typedef typename value_traits::value_type value_type;
type Hash (line 485) | typedef Hash hasher;
type KeyEqual (line 486) | typedef KeyEqual key_equal;
type hashtable_node (line 488) | typedef hashtable_node<T> node_type;
type node_type (line 489) | typedef node_type* node_ptr;
type mystl (line 490) | typedef mystl::vector<node_ptr> bucket_type;
type mystl (line 492) | typedef mystl::allocator<T> allocator_type;
type mystl (line 493) | typedef mystl::allocator<T> data_allocator;
type mystl (line 494) | typedef mystl::allocator<node_type> node_allocator;
type typename (line 496) | typedef typename allocator_type::pointer pointer;
type typename (line 497) | typedef typename allocator_type::const_pointer const_pointer;
type typename (line 498) | typedef typename allocator_type::reference reference;
type typename (line 499) | typedef typename allocator_type::const_reference const_reference;
type typename (line 500) | typedef typename allocator_type::size_type size_type;
type typename (line 501) | typedef typename allocator_type::difference_type difference_type;
type mystl (line 503) | typedef mystl::ht_iterator<T, Hash, KeyEqual> iterator;
type mystl (line 504) | typedef mystl::ht_const_iterator<T, Hash, KeyEqual> const_iterator;
type mystl (line 505) | typedef mystl::ht_local_iterator<T> local_iterator;
type mystl (line 506) | typedef mystl::ht_const_local_iterator<T> const_local_iterator;
function is_equal (line 525) | bool is_equal(const key_type& key1, const key_type& key2) const
function const_iterator (line 530) | const_iterator M_cit(node_ptr node) const noexcept
function iterator (line 535) | iterator M_begin() noexcept
function iterator (line 600) | iterator begin() noexcept
function const_iterator (line 602) | const_iterator begin() const noexcept
function const_iterator (line 606) | const_iterator end() const noexcept
function const_iterator (line 611) | const_iterator cend() const noexcept
function iterator (line 644) | iterator insert_multi(const value_type& value)
function iterator (line 649) | iterator insert_multi(value_type&& value)
function iterator (line 662) | iterator insert_multi_use_hint(const_iterator /*hint*/, const value_type...
function iterator (line 664) | iterator insert_multi_use_hint(const_iterator /*hint*/, value_type&& value)
function iterator (line 667) | iterator insert_unique_use_hint(const_iterator /*hint*/, const value_typ...
function iterator (line 669) | iterator insert_unique_use_hint(const_iterator /*hint*/, value_type&& va...
function local_iterator (line 707) | local_iterator begin(size_type n) noexcept
function const_local_iterator (line 712) | const_local_iterator begin(size_type n) const noexcept
function const_local_iterator (line 717) | const_local_iterator cbegin(size_type n) const noexcept
function local_iterator (line 723) | local_iterator end(size_type n) noexcept
function const_local_iterator (line 728) | const_local_iterator end(size_type n) const noexcept
function const_local_iterator (line 733) | const_local_iterator cend(size_type n) const noexcept
function size_type (line 741) | size_type max_bucket_count() const noexcept
function max_load_factor (line 755) | void max_load_factor(float ml)
function reserve (line 763) | void reserve(size_type count)
FILE: MyTinySTL/heap_algo.h
function namespace (line 8) | namespace mystl
FILE: MyTinySTL/iterator.h
function namespace (line 10) | namespace mystl
function reference (line 309) | reference operator[](difference_type n) const
FILE: MyTinySTL/list.h
function namespace (line 26) | namespace mystl
type T (line 100) | typedef T value_type;
type T (line 101) | typedef T* pointer;
type T (line 102) | typedef T& reference;
type typename (line 103) | typedef typename node_traits<T>::base_ptr base_ptr;
type typename (line 104) | typedef typename node_traits<T>::node_ptr node_ptr;
type list_iterator (line 105) | typedef list_iterator<T> self;
function node_ (line 111) | list_iterator(base_ptr x)
function node_ (line 113) | list_iterator(node_ptr x)
function node_ (line 115) | list_iterator(const list_iterator& rhs)
function reference (line 119) | reference operator*() const { return node_->as_node()->value; }
function pointer (line 120) | pointer operator->() const { return &(operator*()); }
function operator (line 148) | bool operator==(const self& rhs) const { return node_ == rhs.node_; }
function operator (line 149) | bool operator!=(const self& rhs) const { return node_ != rhs.node_; }
type T (line 155) | typedef T value_type;
type T (line 156) | typedef const T* pointer;
type T (line 157) | typedef const T& reference;
type typename (line 158) | typedef typename node_traits<T>::base_ptr base_ptr;
type typename (line 159) | typedef typename node_traits<T>::node_ptr node_ptr;
type list_const_iterator (line 160) | typedef list_const_iterator<T> self;
function node_ (line 165) | list_const_iterator(base_ptr x)
function node_ (line 167) | list_const_iterator(node_ptr x)
function node_ (line 171) | list_const_iterator(const list_const_iterator& rhs)
function reference (line 174) | reference operator*() const { return node_->as_node()->value; }
function pointer (line 175) | pointer operator->() const { return &(operator*()); }
function operator (line 203) | bool operator==(const self& rhs) const { return node_ == rhs.node_; }
function operator (line 204) | bool operator!=(const self& rhs) const { return node_ != rhs.node_; }
type mystl (line 215) | typedef mystl::allocator<T> data_allocator;
type mystl (line 216) | typedef mystl::allocator<list_node_base<T>> base_allocator;
type mystl (line 217) | typedef mystl::allocator<list_node<T>> node_allocator;
type typename (line 219) | typedef typename allocator_type::value_type value_type;
type typename (line 220) | typedef typename allocator_type::pointer pointer;
type typename (line 221) | typedef typename allocator_type::const_pointer const_pointer;
type typename (line 222) | typedef typename allocator_type::reference reference;
type typename (line 223) | typedef typename allocator_type::const_reference const_reference;
type typename (line 224) | typedef typename allocator_type::size_type size_type;
type typename (line 225) | typedef typename allocator_type::difference_type difference_type;
type list_iterator (line 227) | typedef list_iterator<T> iterator;
type list_const_iterator (line 228) | typedef list_const_iterator<T> const_iterator;
type mystl (line 229) | typedef mystl::reverse_iterator<iterator> reverse_iterator;
type mystl (line 230) | typedef mystl::reverse_iterator<const_iterator> const_reverse_iterator;
type typename (line 232) | typedef typename node_traits<T>::base_ptr base_ptr;
type typename (line 233) | typedef typename node_traits<T>::node_ptr node_ptr;
function allocator_type (line 235) | allocator_type get_allocator() { return node_allocator(); }
function explicit (line 246) | explicit list(size_type n)
function iterator (line 310) | iterator end() noexcept
function reverse_iterator (line 315) | reverse_iterator rbegin() noexcept
function const_reverse_iterator (line 317) | const_reverse_iterator rbegin() const noexcept
function const_reverse_iterator (line 321) | const_reverse_iterator rend() const noexcept
function const_iterator (line 326) | const_iterator cend() const noexcept
function const_reverse_iterator (line 330) | const_reverse_iterator crend() const noexcept
function reference (line 344) | reference front()
function reference (line 356) | reference back()
function assign (line 372) | void assign(size_type n, const value_type& value)
function assign (line 380) | void assign(std::initializer_list<T> ilist)
function iterator (line 415) | iterator insert(const_iterator pos, const value_type& value)
function iterator (line 423) | iterator insert(const_iterator pos, value_type&& value)
function iterator (line 431) | iterator insert(const_iterator pos, size_type n, const value_type& value)
function push_front (line 448) | void push_front(const value_type& value)
function push_front (line 456) | void push_front(value_type&& value)
function push_back (line 461) | void push_back(const value_type& value)
function push_back (line 469) | void push_back(value_type&& value)
function pop_front (line 476) | void pop_front()
function pop_back (line 485) | void pop_back()
function resize (line 503) | void resize(size_type new_size) { resize(new_size, value_type()); }
function swap (line 506) | void swap(list& rhs) noexcept
function remove (line 518) | void remove(const value_type& value)
function unique (line 523) | void unique()
function merge (line 528) | void merge(list& x)
function sort (line 533) | void sort()
FILE: MyTinySTL/map.h
function namespace (line 18) | namespace mystl
function tree_ (line 81) | map(const map& rhs)
function iterator (line 116) | iterator begin() noexcept
function iterator (line 120) | iterator end() noexcept
function reverse_iterator (line 125) | reverse_iterator rbegin() noexcept
function const_reverse_iterator (line 127) | const_reverse_iterator rbegin() const noexcept
function const_reverse_iterator (line 131) | const_reverse_iterator rend() const noexcept
function const_iterator (line 136) | const_iterator cend() const noexcept
function const_reverse_iterator (line 140) | const_reverse_iterator crend() const noexcept
function mapped_type (line 159) | const mapped_type& at(const key_type& key) const
function iterator (line 208) | iterator insert(iterator hint, const value_type& value)
function iterator (line 212) | iterator insert(iterator hint, value_type&& value)
function erase (line 223) | void erase(iterator position) { tree_.erase(position); }
function size_type (line 224) | size_type erase(const key_type& key) { return tree_.erase_uniq...
function erase (line 225) | void erase(iterator first, iterator last) { tree_.erase(first, last...
function clear (line 227) | void clear() { tree_.clear(); }
function iterator (line 231) | iterator find(const key_type& key) { return tree_.fin...
function const_iterator (line 232) | const_iterator find(const key_type& key) const { return tree_.fin...
function size_type (line 234) | size_type count(const key_type& key) const { return tree_.cou...
function iterator (line 236) | iterator lower_bound(const key_type& key) { return tree_.low...
function const_iterator (line 237) | const_iterator lower_bound(const key_type& key) const { return tree_.low...
function iterator (line 239) | iterator upper_bound(const key_type& key) { return tree_.upp...
function const_iterator (line 240) | const_iterator upper_bound(const key_type& key) const { return tree_.upp...
function swap (line 250) | void swap(map& rhs) noexcept
type T (line 312) | typedef T mapped_type;
type mystl (line 313) | typedef mystl::pair<const Key, T> value_type;
type Compare (line 314) | typedef Compare key_compare;
function comp (line 322) | value_compare(Compare c) : comp(c) {}
type typename (line 338) | typedef typename base_type::pointer pointer;
type typename (line 339) | typedef typename base_type::const_pointer const_pointer;
type typename (line 340) | typedef typename base_type::reference reference;
type typename (line 341) | typedef typename base_type::const_reference const_reference;
type typename (line 342) | typedef typename base_type::iterator iterator;
type typename (line 343) | typedef typename base_type::const_iterator const_iterator;
type typename (line 344) | typedef typename base_type::reverse_iterator reverse_iterator;
type typename (line 345) | typedef typename base_type::const_reverse_iterator const_reverse_iterator;
type typename (line 346) | typedef typename base_type::size_type size_type;
type typename (line 347) | typedef typename base_type::difference_type difference_type;
type typename (line 348) | typedef typename base_type::allocator_type allocator_type;
function tree_ (line 363) | multimap(const multimap& rhs)
function iterator (line 398) | iterator begin() noexcept
function iterator (line 402) | iterator end() noexcept
function reverse_iterator (line 407) | reverse_iterator rbegin() noexcept
function const_reverse_iterator (line 409) | const_reverse_iterator rbegin() const noexcept
function const_reverse_iterator (line 413) | const_reverse_iterator rend() const noexcept
function const_iterator (line 418) | const_iterator cend() const noexcept
function const_reverse_iterator (line 422) | const_reverse_iterator crend() const noexcept
function iterator (line 444) | iterator insert(const value_type& value)
function iterator (line 448) | iterator insert(value_type&& value)
function iterator (line 453) | iterator insert(iterator hint, const value_type& value)
function iterator (line 457) | iterator insert(iterator hint, value_type&& value)
function erase (line 468) | void erase(iterator position) { tree_.erase(positi...
function size_type (line 469) | size_type erase(const key_type& key) { return tree_.erase...
function erase (line 470) | void erase(iterator first, iterator last) { tree_.erase(first,...
function clear (line 472) | void clear() { tree_.clear(); }
function iterator (line 476) | iterator find(const key_type& key) { return tree_.fin...
function const_iterator (line 477) | const_iterator find(const key_type& key) const { return tree_.fin...
function size_type (line 479) | size_type count(const key_type& key) const { return tree_.cou...
function iterator (line 481) | iterator lower_bound(const key_type& key) { return tree_.low...
function const_iterator (line 482) | const_iterator lower_bound(const key_type& key) const { return tree_.low...
function iterator (line 484) | iterator upper_bound(const key_type& key) { return tree_.upp...
function const_iterator (line 485) | const_iterator upper_bound(const key_type& key) const { return tree_.upp...
function swap (line 495) | void swap(multimap& rhs) noexcept
FILE: MyTinySTL/memory.h
function namespace (line 16) | namespace mystl
FILE: MyTinySTL/numeric.h
function namespace (line 8) | namespace mystl
FILE: MyTinySTL/queue.h
function namespace (line 13) | namespace mystl
function push (line 111) | void push(const value_type& value)
function push (line 113) | void push(value_type&& value)
function pop (line 116) | void pop()
function clear (line 119) | void clear()
function swap (line 125) | void swap(queue& rhs) noexcept(noexcept(mystl::swap(c_, rhs.c_)))
type Compare (line 188) | typedef Compare value_compare;
type typename (line 190) | typedef typename Container::value_type value_type;
type typename (line 191) | typedef typename Container::size_type size_type;
type typename (line 192) | typedef typename Container::reference reference;
type typename (line 193) | typedef typename Container::const_reference const_reference;
function explicit (line 211) | explicit priority_queue(size_type n)
function c_ (line 235) | priority_queue(const Container& s)
function push (line 298) | void push(const value_type& value)
function push (line 303) | void push(value_type&& value)
function pop (line 309) | void pop()
function clear (line 315) | void clear()
function swap (line 321) | void swap(priority_queue& rhs) noexcept(noexcept(mystl::swap(c_, rhs.c_)...
FILE: MyTinySTL/rb_tree.h
function namespace (line 17) | namespace mystl
type rb_tree_value_traits (line 171) | typedef rb_tree_value_traits<T> value_traits;
type typename (line 173) | typedef typename value_traits::key_type key_type;
type typename (line 174) | typedef typename value_traits::mapped_type mapped_type;
type typename (line 175) | typedef typename value_traits::value_type value_type;
type value_type (line 177) | typedef value_type* pointer;
type value_type (line 178) | typedef value_type& reference;
type value_type (line 179) | typedef const value_type* const_pointer;
type value_type (line 180) | typedef const value_type& const_reference;
type rb_tree_node_base (line 182) | typedef rb_tree_node_base<T> base_type;
type rb_tree_node (line 183) | typedef rb_tree_node<T> node_type;
type base_type (line 185) | typedef base_type* base_ptr;
type node_type (line 186) | typedef node_type* node_ptr;
function node (line 198) | node(nullptr) {}
function inc (line 201) | void inc()
function dec (line 221) | void dec()
type typename (line 252) | typedef typename tree_traits::value_type value_type;
type typename (line 253) | typedef typename tree_traits::pointer pointer;
type typename (line 254) | typedef typename tree_traits::reference reference;
type typename (line 255) | typedef typename tree_traits::base_ptr base_ptr;
type typename (line 256) | typedef typename tree_traits::node_ptr node_ptr;
type rb_tree_iterator (line 258) | typedef rb_tree_iterator<T> iterator;
type rb_tree_const_iterator (line 259) | typedef rb_tree_const_iterator<T> const_iterator;
type iterator (line 260) | typedef iterator self;
function reference (line 272) | reference operator*() const { return node->get_node_ptr()->value; }
function pointer (line 273) | pointer operator->() const { return &(operator*()); }
type typename (line 304) | typedef typename tree_traits::value_type value_type;
type typename (line 305) | typedef typename tree_traits::const_pointer pointer;
type typename (line 306) | typedef typename tree_traits::const_reference reference;
type typename (line 307) | typedef typename tree_traits::base_ptr base_ptr;
type typename (line 308) | typedef typename tree_traits::node_ptr node_ptr;
type rb_tree_iterator (line 310) | typedef rb_tree_iterator<T> iterator;
type rb_tree_const_iterator (line 311) | typedef rb_tree_const_iterator<T> const_iterator;
type const_iterator (line 312) | typedef const_iterator self;
function reference (line 324) | reference operator*() const { return node->get_node_ptr()->value; }
function pointer (line 325) | pointer operator->() const { return &(operator*()); }
type rb_tree_value_traits (line 718) | typedef rb_tree_value_traits<T> value_traits;
type typename (line 720) | typedef typename tree_traits::base_type base_type;
type typename (line 721) | typedef typename tree_traits::base_ptr base_ptr;
type typename (line 722) | typedef typename tree_traits::node_type node_type;
type typename (line 723) | typedef typename tree_traits::node_ptr node_ptr;
type typename (line 724) | typedef typename tree_traits::key_type key_type;
type typename (line 725) | typedef typename tree_traits::mapped_type mapped_type;
type typename (line 726) | typedef typename tree_traits::value_type value_type;
type Compare (line 727) | typedef Compare key_compare;
type mystl (line 729) | typedef mystl::allocator<T> allocator_type;
type mystl (line 730) | typedef mystl::allocator<T> data_allocator;
type mystl (line 731) | typedef mystl::allocator<base_type> base_allocator;
type mystl (line 732) | typedef mystl::allocator<node_type> node_allocator;
type typename (line 734) | typedef typename allocator_type::pointer pointer;
type typename (line 735) | typedef typename allocator_type::const_pointer const_pointer;
type typename (line 736) | typedef typename allocator_type::reference reference;
type typename (line 737) | typedef typename allocator_type::const_reference const_reference;
type typename (line 738) | typedef typename allocator_type::size_type size_type;
type typename (line 739) | typedef typename allocator_type::difference_type difference_type;
type rb_tree_iterator (line 741) | typedef rb_tree_iterator<T> iterator;
type rb_tree_const_iterator (line 742) | typedef rb_tree_const_iterator<T> const_iterator;
type mystl (line 743) | typedef mystl::reverse_iterator<iterator> reverse_iterator;
type mystl (line 744) | typedef mystl::reverse_iterator<const_iterator> const_reverse_iterator;
function const_iterator (line 778) | const_iterator begin() const noexcept
function reverse_iterator (line 785) | reverse_iterator rbegin() noexcept
function const_reverse_iterator (line 787) | const_reverse_iterator rbegin() const noexcept
function const_reverse_iterator (line 791) | const_reverse_iterator rend() const noexcept
function const_iterator (line 796) | const_iterator cend() const noexcept
function const_reverse_iterator (line 800) | const_reverse_iterator crend() const noexcept
function iterator (line 828) | iterator insert_multi(value_type&& value)
function iterator (line 833) | iterator insert_multi(iterator hint, const value_type& value)
function iterator (line 837) | iterator insert_multi(iterator hint, value_type&& value)
function iterator (line 857) | iterator insert_unique(iterator hint, const value_type& value)
function iterator (line 861) | iterator insert_unique(iterator hint, value_type&& value)
function size_type (line 891) | size_type count_multi(const key_type& key) const
function size_type (line 896) | size_type count_unique(const key_type& key) const
FILE: MyTinySTL/set.h
function namespace (line 18) | namespace mystl
function erase (line 168) | void erase(iterator position) { tree_.erase(position); }
function size_type (line 169) | size_type erase(const key_type& key) { return tree_.erase_uniq...
function erase (line 170) | void erase(iterator first, iterator last) { tree_.erase(first, last...
function clear (line 172) | void clear() { tree_.clear(); }
function iterator (line 176) | iterator find(const key_type& key) { return tree_.fin...
function const_iterator (line 177) | const_iterator find(const key_type& key) const { return tree_.fin...
function size_type (line 179) | size_type count(const key_type& key) const { return tree_.cou...
function iterator (line 181) | iterator lower_bound(const key_type& key) { return tree_.low...
function const_iterator (line 182) | const_iterator lower_bound(const key_type& key) const { return tree_.low...
function iterator (line 184) | iterator upper_bound(const key_type& key) { return tree_.upp...
function const_iterator (line 185) | const_iterator upper_bound(const key_type& key) const { return tree_.upp...
function swap (line 195) | void swap(set& rhs) noexcept
type Key (line 256) | typedef Key value_type;
type Compare (line 257) | typedef Compare key_compare;
type Compare (line 258) | typedef Compare value_compare;
type typename (line 268) | typedef typename base_type::const_pointer pointer;
type typename (line 269) | typedef typename base_type::const_pointer const_pointer;
type typename (line 270) | typedef typename base_type::const_reference reference;
type typename (line 271) | typedef typename base_type::const_reference const_reference;
type typename (line 272) | typedef typename base_type::const_iterator iterator;
type typename (line 273) | typedef typename base_type::const_iterator const_iterator;
type typename (line 274) | typedef typename base_type::const_reverse_iterator reverse_iterator;
type typename (line 275) | typedef typename base_type::const_reverse_iterator const_reverse_iterator;
type typename (line 276) | typedef typename base_type::size_type size_type;
type typename (line 277) | typedef typename base_type::difference_type difference_type;
type typename (line 278) | typedef typename base_type::allocator_type allocator_type;
function tree_ (line 292) | multiset(const multiset& rhs)
function iterator (line 326) | iterator begin() noexcept
function iterator (line 330) | iterator end() noexcept
function reverse_iterator (line 335) | reverse_iterator rbegin() noexcept
function const_reverse_iterator (line 337) | const_reverse_iterator rbegin() const noexcept
function const_reverse_iterator (line 341) | const_reverse_iterator rend() const noexcept
function const_iterator (line 346) | const_iterator cend() const noexcept
function const_reverse_iterator (line 350) | const_reverse_iterator crend() const noexcept
function iterator (line 372) | iterator insert(const value_type& value)
function iterator (line 376) | iterator insert(value_type&& value)
function iterator (line 381) | iterator insert(iterator hint, const value_type& value)
function iterator (line 385) | iterator insert(iterator hint, value_type&& value)
function erase (line 396) | void erase(iterator position) { tree_.erase(positi...
function size_type (line 397) | size_type erase(const key_type& key) { return tree_.erase...
function erase (line 398) | void erase(iterator first, iterator last) { tree_.erase(first,...
function clear (line 400) | void clear() { tree_.clear(); }
function iterator (line 404) | iterator find(const key_type& key) { return tree_.fin...
function const_iterator (line 405) | const_iterator find(const key_type& key) const { return tree_.fin...
function size_type (line 407) | size_type count(const key_type& key) const { return tree_.cou...
function iterator (line 409) | iterator lower_bound(const key_type& key) { return tree_.low...
function const_iterator (line 410) | const_iterator lower_bound(const key_type& key) const { return tree_.low...
function iterator (line 412) | iterator upper_bound(const key_type& key) { return tree_.upp...
function const_iterator (line 413) | const_iterator upper_bound(const key_type& key) const { return tree_.upp...
function swap (line 423) | void swap(multiset& rhs) noexcept
FILE: MyTinySTL/set_algo.h
function namespace (line 10) | namespace mystl
function else (line 29) | else if (*first2 < *first1)
FILE: MyTinySTL/stack.h
function namespace (line 9) | namespace mystl
function push (line 105) | void push(const value_type& value)
function push (line 107) | void push(value_type&& value)
function pop (line 110) | void pop()
function clear (line 113) | void clear()
function swap (line 119) | void swap(stack& rhs) noexcept(noexcept(mystl::swap(c_, rhs.c_)))
FILE: MyTinySTL/stream_iterator.h
function namespace (line 6) | namespace mystl
FILE: MyTinySTL/type_traits.h
function namespace (line 9) | namespace mystl
FILE: MyTinySTL/uninitialized.h
function namespace (line 12) | namespace mystl
FILE: MyTinySTL/unordered_map.h
function namespace (line 17) | namespace mystl
function ht_ (line 91) | unordered_map(const unordered_map& rhs)
function iterator (line 124) | iterator begin() noexcept
function iterator (line 128) | iterator end() noexcept
function iterator (line 163) | iterator insert(const_iterator hint, const value_type& value)
function iterator (line 165) | iterator insert(const_iterator hint, value_type&& value)
function erase (line 174) | void erase(iterator it)
function erase (line 176) | void erase(iterator first, iterator last)
function size_type (line 179) | size_type erase(const key_type& key)
function clear (line 182) | void clear()
function swap (line 185) | void swap(unordered_map& other) noexcept
function mapped_type (line 196) | const mapped_type& at(const key_type& key) const
function size_type (line 218) | size_type count(const key_type& key) const
function iterator (line 221) | iterator find(const key_type& key)
function const_iterator (line 223) | const_iterator find(const key_type& key) const
function local_iterator (line 233) | local_iterator begin(size_type n) noexcept
function const_local_iterator (line 235) | const_local_iterator begin(size_type n) const noexcept
function const_local_iterator (line 237) | const_local_iterator cbegin(size_type n) const noexcept
function local_iterator (line 240) | local_iterator end(size_type n) noexcept
function const_local_iterator (line 242) | const_local_iterator end(size_type n) const noexcept
function const_local_iterator (line 244) | const_local_iterator cend(size_type n) const noexcept
function size_type (line 252) | size_type bucket_size(size_type n) const noexcept
function size_type (line 254) | size_type bucket(const key_type& key) const
function max_load_factor (line 262) | void max_load_factor(float ml) { ht_.max_load_factor(...
function rehash (line 264) | void rehash(size_type count) { ht_.rehash(count); }
function reserve (line 265) | void reserve(size_type count) { ht_.reserve(count); }
type typename (line 320) | typedef typename base_type::key_type key_type;
type typename (line 321) | typedef typename base_type::mapped_type mapped_type;
type typename (line 322) | typedef typename base_type::value_type value_type;
type typename (line 323) | typedef typename base_type::hasher hasher;
type typename (line 324) | typedef typename base_type::key_equal key_equal;
type typename (line 326) | typedef typename base_type::size_type size_type;
type typename (line 327) | typedef typename base_type::difference_type difference_type;
type typename (line 328) | typedef typename base_type::pointer pointer;
type typename (line 329) | typedef typename base_type::const_pointer const_pointer;
type typename (line 330) | typedef typename base_type::reference reference;
type typename (line 331) | typedef typename base_type::const_reference const_reference;
type typename (line 333) | typedef typename base_type::iterator iterator;
type typename (line 334) | typedef typename base_type::const_iterator const_iterator;
type typename (line 335) | typedef typename base_type::local_iterator local_iterator;
type typename (line 336) | typedef typename base_type::const_local_iterator const_local_iterator;
function explicit (line 348) | explicit unordered_multimap(size_type bucket_count,
function ht_ (line 376) | unordered_multimap(const unordered_multimap& rhs)
function iterator (line 409) | iterator begin() noexcept
function iterator (line 413) | iterator end() noexcept
function iterator (line 443) | iterator insert(const value_type& value)
function iterator (line 445) | iterator insert(value_type&& value)
function iterator (line 448) | iterator insert(const_iterator hint, const value_type& value)
function iterator (line 450) | iterator insert(const_iterator hint, value_type&& value)
function erase (line 459) | void erase(iterator it)
function erase (line 461) | void erase(iterator first, iterator last)
function size_type (line 464) | size_type erase(const key_type& key)
function clear (line 467) | void clear()
function swap (line 470) | void swap(unordered_multimap& other) noexcept
function size_type (line 475) | size_type count(const key_type& key) const
function iterator (line 478) | iterator find(const key_type& key)
function const_iterator (line 480) | const_iterator find(const key_type& key) const
function local_iterator (line 490) | local_iterator begin(size_type n) noexcept
function const_local_iterator (line 492) | const_local_iterator begin(size_type n) const noexcept
function const_local_iterator (line 494) | const_local_iterator cbegin(size_type n) const noexcept
function local_iterator (line 497) | local_iterator end(size_type n) noexcept
function const_local_iterator (line 499) | const_local_iterator end(size_type n) const noexcept
function const_local_iterator (line 501) | const_local_iterator cend(size_type n) const noexcept
function size_type (line 509) | size_type bucket_size(size_type n) const noexcept
function size_type (line 511) | size_type bucket(const key_type& key) const
function max_load_factor (line 519) | void max_load_factor(float ml) { ht_.max_load_factor(...
function rehash (line 521) | void rehash(size_type count) { ht_.rehash(count); }
function reserve (line 522) | void reserve(size_type count) { ht_.reserve(count); }
FILE: MyTinySTL/unordered_set.h
function namespace (line 17) | namespace mystl
function ht_ (line 89) | unordered_set(const unordered_set& rhs)
function iterator (line 122) | iterator begin() noexcept
function iterator (line 126) | iterator end() noexcept
function iterator (line 161) | iterator insert(const_iterator hint, const value_type& value)
function iterator (line 163) | iterator insert(const_iterator hint, value_type&& value)
function erase (line 172) | void erase(iterator it)
function erase (line 174) | void erase(iterator first, iterator last)
function size_type (line 177) | size_type erase(const key_type& key)
function clear (line 180) | void clear()
function swap (line 183) | void swap(unordered_set& other) noexcept
function size_type (line 188) | size_type count(const key_type& key) const
function iterator (line 191) | iterator find(const key_type& key)
function const_iterator (line 193) | const_iterator find(const key_type& key) const
function local_iterator (line 203) | local_iterator begin(size_type n) noexcept
function const_local_iterator (line 205) | const_local_iterator begin(size_type n) const noexcept
function const_local_iterator (line 207) | const_local_iterator cbegin(size_type n) const noexcept
function local_iterator (line 210) | local_iterator end(size_type n) noexcept
function const_local_iterator (line 212) | const_local_iterator end(size_type n) const noexcept
function const_local_iterator (line 214) | const_local_iterator cend(size_type n) const noexcept
function size_type (line 222) | size_type bucket_size(size_type n) const noexcept
function size_type (line 224) | size_type bucket(const key_type& key) const
function max_load_factor (line 232) | void max_load_factor(float ml) { ht_.max_load_factor(...
function rehash (line 234) | void rehash(size_type count) { ht_.rehash(count); }
function reserve (line 235) | void reserve(size_type count) { ht_.reserve(count); }
type typename (line 291) | typedef typename base_type::key_type key_type;
type typename (line 292) | typedef typename base_type::value_type value_type;
type typename (line 293) | typedef typename base_type::hasher hasher;
type typename (line 294) | typedef typename base_type::key_equal key_equal;
type typename (line 296) | typedef typename base_type::size_type size_type;
type typename (line 297) | typedef typename base_type::difference_type difference_type;
type typename (line 298) | typedef typename base_type::pointer pointer;
type typename (line 299) | typedef typename base_type::const_pointer const_pointer;
type typename (line 300) | typedef typename base_type::reference reference;
type typename (line 301) | typedef typename base_type::const_reference const_reference;
type typename (line 303) | typedef typename base_type::const_iterator iterator;
type typename (line 304) | typedef typename base_type::const_iterator const_iterator;
type typename (line 305) | typedef typename base_type::const_local_iterator local_iterator;
type typename (line 306) | typedef typename base_type::const_local_iterator const_local_iterator;
function explicit (line 318) | explicit unordered_multiset(size_type bucket_count,
function ht_ (line 346) | unordered_multiset(const unordered_multiset& rhs)
function iterator (line 380) | iterator begin() noexcept
function iterator (line 384) | iterator end() noexcept
function iterator (line 414) | iterator insert(const value_type& value)
function iterator (line 416) | iterator insert(value_type&& value)
function iterator (line 419) | iterator insert(const_iterator hint, const value_type& value)
function iterator (line 421) | iterator insert(const_iterator hint, value_type&& value)
function erase (line 430) | void erase(iterator it)
function erase (line 432) | void erase(iterator first, iterator last)
function size_type (line 435) | size_type erase(const key_type& key)
function clear (line 438) | void clear()
function swap (line 441) | void swap(unordered_multiset& other) noexcept
function size_type (line 446) | size_type count(const key_type& key) const
function iterator (line 449) | iterator find(const key_type& key)
function const_iterator (line 451) | const_iterator find(const key_type& key) const
function local_iterator (line 461) | local_iterator begin(size_type n) noexcept
function const_local_iterator (line 463) | const_local_iterator begin(size_type n) const noexcept
function const_local_iterator (line 465) | const_local_iterator cbegin(size_type n) const noexcept
function local_iterator (line 468) | local_iterator end(size_type n) noexcept
function const_local_iterator (line 470) | const_local_iterator end(size_type n) const noexcept
function const_local_iterator (line 472) | const_local_iterator cend(size_type n) const noexcept
function size_type (line 480) | size_type bucket_size(size_type n) const noexcept
function size_type (line 482) | size_type bucket(const key_type& key) const
function max_load_factor (line 490) | void max_load_factor(float ml) { ht_.max_load_factor(...
function rehash (line 492) | void rehash(size_type count) { ht_.rehash(count); }
function reserve (line 493) | void reserve(size_type count) { ht_.reserve(count); }
FILE: MyTinySTL/util.h
function namespace (line 10) | namespace mystl
type Ty1 (line 69) | typedef Ty1 first_type;
type Ty2 (line 70) | typedef Ty2 second_type;
function swap (line 232) | void swap(pair& other)
FILE: MyTinySTL/vector.h
function namespace (line 27) | namespace mystl
function iterator (line 133) | iterator end() noexcept
function reverse_iterator (line 138) | reverse_iterator rbegin() noexcept
function const_reverse_iterator (line 140) | const_reverse_iterator rbegin() const noexcept
function const_reverse_iterator (line 144) | const_reverse_iterator rend() const noexcept
function const_iterator (line 149) | const_iterator cend() const noexcept
function const_reverse_iterator (line 153) | const_reverse_iterator crend() const noexcept
function reference (line 169) | reference operator[](size_type n)
function const_reference (line 174) | const_reference operator[](size_type n) const
function reference (line 179) | reference at(size_type n)
function const_reference (line 184) | const_reference at(size_type n) const
function reference (line 190) | reference front()
function reference (line 200) | reference back()
function pointer (line 211) | pointer data() noexcept { return begin_; }
function assign (line 218) | void assign(size_type n, const value_type& value)
function assign (line 229) | void assign(std::initializer_list<value_type> il)
function push_back (line 243) | void push_back(value_type&& value)
function iterator (line 251) | iterator insert(const_iterator pos, value_type&& value)
function iterator (line 254) | iterator insert(const_iterator pos, size_type n, const value_type& value)
function clear (line 271) | void clear() { erase(begin(), end()); }
function resize (line 274) | void resize(size_type new_size) { return resize(new_size, value_type...
function reverse (line 277) | void reverse() { mystl::reverse(begin(), end()); }
FILE: Test/Lib/redbud/io/color.h
type class (line 44) | enum class
type class (line 59) | enum class
type class (line 74) | enum class
type class (line 89) | enum class
function hbg (line 102) | enum class hbg
FILE: Test/Lib/redbud/platform.h
function namespace (line 99) | namespace redbud
FILE: Test/algorithm_performance_test.h
function namespace (line 11) | namespace mystl
FILE: Test/algorithm_test.h
function gen (line 40) | int gen() { return 5; }
function r (line 41) | int r(int i) { return (i * 5 + 1) % 9; }
function is_odd (line 42) | bool is_odd(int i) { return i & 1; }
function is_even (line 43) | bool is_even(int i) { return !(i & 1); }
function arr_sum (line 44) | void arr_sum(int i) { for_each_sum += i; }
function cmp (line 45) | bool cmp(const int& a, const int& b) { return b < a; }
function unary_op (line 46) | int unary_op(const int& x) { return x + 1; }
function binary_op (line 47) | int binary_op(const int& x, const int& y) { return x + y; }
function TEST (line 52) | TEST(copy_test)
function TEST (line 77) | TEST(copy_if_test)
function TEST (line 89) | TEST(copy_n_test)
function TEST (line 101) | TEST(move_test)
function TEST (line 112) | TEST(move_backward_test)
function TEST (line 139) | TEST(fill_test)
function TEST (line 152) | TEST(fill_n_test)
function TEST (line 164) | TEST(iter_swap_test)
function TEST (line 180) | TEST(lexicographical_compare_test)
function TEST (line 197) | TEST(max_test)
function TEST (line 207) | TEST(min_test)
function p1 (line 223) | auto p1 = std::mismatch(arr1, arr1 + 7, arr2);
function TEST (line 257) | TEST(pop_heap_test)
function TEST (line 278) | TEST(push_heap_test)
function TEST (line 299) | TEST(sort_heap_test)
function TEST (line 318) | TEST(set_difference_test)
function TEST (line 335) | TEST(set_intersection_test)
function TEST (line 352) | TEST(set_symmetric_difference_test)
function TEST (line 369) | TEST(set_union_test)
function TEST (line 387) | TEST(accumulate_test)
function TEST (line 398) | TEST(adjacent_difference_test)
function TEST (line 411) | TEST(inner_product_test)
function TEST (line 422) | TEST(iota_test)
function TEST (line 434) | TEST(partial_sum_test)
function TEST (line 451) | TEST(adjacent_find_test)
function TEST (line 463) | TEST(all_of_test)
function TEST (line 473) | TEST(any_of_test)
function TEST (line 483) | TEST(binary_search_test)
function TEST (line 492) | TEST(count_test)
function TEST (line 503) | TEST(count_if_test)
function p1 (line 515) | auto p1 = mystl::equal_range(arr1, arr1 + 7, 3);
function TEST (line 532) | TEST(find_end_test)
function TEST (line 547) | TEST(find_first_of_test)
function TEST (line 558) | TEST(find_if_test)
function TEST (line 567) | TEST(find_if_not_test)
function TEST (line 585) | TEST(generate_test)
function TEST (line 594) | TEST(generate_n_test)
function TEST (line 620) | TEST(inplace_merge_test)
function TEST (line 634) | TEST(is_heap_test)
function TEST (line 648) | TEST(is_sorted_test)
function TEST (line 662) | TEST(lower_bound_test)
function TEST (line 675) | TEST(max_elememt_test)
function TEST (line 685) | TEST(median_test)
function TEST (line 693) | TEST(merge_test)
function TEST (line 708) | TEST(min_elememt_test)
function TEST (line 718) | TEST(is_permutation_test)
function TEST (line 734) | TEST(next_permutation_test)
function TEST (line 753) | TEST(none_of_test)
function TEST (line 766) | TEST(nth_element_test)
function TEST (line 809) | TEST(partial_sort_test)
function TEST (line 823) | TEST(partial_sort_copy_test)
function TEST (line 840) | TEST(partition_test)
function TEST (line 852) | TEST(partition_copy_test)
function TEST (line 863) | TEST(prev_permutation_test)
function TEST (line 882) | TEST(random_shuffle_test)
function TEST (line 897) | TEST(remove_test)
FILE: Test/deque_test.h
function namespace (line 13) | namespace test
FILE: Test/iterator_test.h
function namespace (line 12) | namespace iterator_test
FILE: Test/list_test.h
function namespace (line 15) | namespace list_test
FILE: Test/map_test.h
function namespace (line 16) | namespace map_test
FILE: Test/queue_test.h
function namespace (line 15) | namespace queue_test
FILE: Test/set_test.h
function namespace (line 15) | namespace set_test
FILE: Test/stack_test.h
function namespace (line 13) | namespace test
FILE: Test/string_test.h
function namespace (line 11) | namespace mystl
FILE: Test/test.cpp
function main (line 25) | int main()
FILE: Test/test.h
function namespace (line 17) | namespace mystl
function Run (line 87) | void UnitTest::Run()
FILE: Test/unordered_map_test.h
function namespace (line 16) | namespace unordered_map_test
FILE: Test/unordered_set_test.h
function namespace (line 16) | namespace unordered_set_test
FILE: Test/vector_test.h
function namespace (line 13) | namespace test
Condensed preview — 59 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (664K chars).
[
{
"path": ".gitattributes",
"chars": 2518,
"preview": "###############################################################################\n# Set default behavior to automatically "
},
{
"path": ".gitignore",
"chars": 3901,
"preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# Loca"
},
{
"path": ".travis.yml",
"chars": 1336,
"preview": "language: cpp\n\n# ubuntu 14.04 version\nsudo: required\ndist: trusty\n\nmatrix:\n include:\n - os: linux\n compiler: gc"
},
{
"path": "CMakeLists.txt",
"chars": 1348,
"preview": "cmake_minimum_required(VERSION 2.8)\n\nproject(MyTinySTL)\n\n# version\nset(MyTinySTL_VERSION_MAJOR 2)\nset(MyTinySTL_VERSION_"
},
{
"path": "License.txt",
"chars": 1224,
"preview": "Copyright (c) 2016-2017 Alinshans. All rights reserved.\r\n\r\nFirst published on github, see https://github.com/Alinshans/M"
},
{
"path": "MSVC/MyTinySTL_VS2015.sln",
"chars": 1275,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.25420.1\nMinim"
},
{
"path": "MSVC/MyTinySTL_VS2015.vcxproj",
"chars": 9579,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.micros"
},
{
"path": "MSVC/MyTinySTL_VS2015.vcxproj.filters",
"chars": 5457,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
},
{
"path": "MyTinySTL/algo.h",
"chars": 75112,
"preview": "#ifndef MYTINYSTL_ALGO_H_\n#define MYTINYSTL_ALGO_H_\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable : 42"
},
{
"path": "MyTinySTL/algobase.h",
"chars": 15877,
"preview": "#ifndef MYTINYSTL_ALGOBASE_H_\n#define MYTINYSTL_ALGOBASE_H_\n\n// 这个头文件包含了 mystl 的基本算法\n\n#include <cstring>\n\n#include \"ite"
},
{
"path": "MyTinySTL/algorithm.h",
"chars": 304,
"preview": "#ifndef MYTINYSTL_ALGORITHM_H_\n#define MYTINYSTL_ALGORITHM_H_\n\n// 这个头文件包含了 mystl 的所有算法,包括基本算法,数值算法,heap 算法,set 算法和其他算法\n"
},
{
"path": "MyTinySTL/alloc.h",
"chars": 6438,
"preview": "#ifndef MYTINYSTL_ALLOC_H_\n#define MYTINYSTL_ALLOC_H_\n\n// 这个头文件包含一个类 alloc,用于分配和回收内存,以内存池的方式实现\n//\n// 从 v2.0.0 版本开始,将不再使用"
},
{
"path": "MyTinySTL/allocator.h",
"chars": 2173,
"preview": "#ifndef MYTINYSTL_ALLOCATOR_H_\n#define MYTINYSTL_ALLOCATOR_H_\n\n// 这个头文件包含一个模板类 allocator,用于管理内存的分配、释放,对象的构造、析构\n\n#includ"
},
{
"path": "MyTinySTL/astring.h",
"chars": 382,
"preview": "#ifndef MYTINYSTL_ASTRING_H_\n#define MYTINYSTL_ASTRING_H_\n\n// 定义了 string, wstring, u16string, u32string 类型\n\n#include \"b"
},
{
"path": "MyTinySTL/basic_string.h",
"chars": 56086,
"preview": "#ifndef MYTINYSTL_BASIC_STRING_H_\n#define MYTINYSTL_BASIC_STRING_H_\n\n// 这个头文件包含一个模板类 basic_string\n// 用于表示字符串类型\n\n#includ"
},
{
"path": "MyTinySTL/construct.h",
"chars": 1581,
"preview": "#ifndef MYTINYSTL_CONSTRUCT_H_\n#define MYTINYSTL_CONSTRUCT_H_\n\n// 这个头文件包含两个函数 construct,destroy\n// construct : 负责对象的构造\n"
},
{
"path": "MyTinySTL/deque.h",
"chars": 34021,
"preview": "#ifndef MYTINYSTL_DEQUE_H_\n#define MYTINYSTL_DEQUE_H_\n\n// 这个头文件包含了一个模板类 deque\n// deque: 双端队列\n\n// notes:\n//\n// 异常保证:\n// "
},
{
"path": "MyTinySTL/exceptdef.h",
"chars": 496,
"preview": "#ifndef MYTINYSTL_EXCEPTDEF_H_\n#define MYTINYSTL_EXCEPTDEF_H_\n\n#include <stdexcept>\n\n#include <cassert>\n\nnamespace mystl"
},
{
"path": "MyTinySTL/functional.h",
"chars": 6093,
"preview": "#ifndef MYTINYSTL_FUNCTIONAL_H_\n#define MYTINYSTL_FUNCTIONAL_H_\n\n// 这个头文件包含了 mystl 的函数对象与哈希函数\n\n#include <cstddef>\n\nname"
},
{
"path": "MyTinySTL/hashtable.h",
"chars": 43523,
"preview": "#ifndef MYTINYSTL_HASHTABLE_H_\n#define MYTINYSTL_HASHTABLE_H_\n\n// 这个头文件包含了一个模板类 hashtable\n// hashtable : 哈希表,使用开链法处理冲突\n"
},
{
"path": "MyTinySTL/heap_algo.h",
"chars": 6873,
"preview": "#ifndef MYTINYSTL_HEAP_ALGO_H_\n#define MYTINYSTL_HEAP_ALGO_H_\n\n// 这个头文件包含 heap 的四个算法 : push_heap, pop_heap, sort_heap, "
},
{
"path": "MyTinySTL/iterator.h",
"chars": 9659,
"preview": "#ifndef MYTINYSTL_ITERATOR_H_\n#define MYTINYSTL_ITERATOR_H_\n\n// 这个头文件用于迭代器设计,包含了一些模板结构体与全局函数,\n\n#include <cstddef>\n\n#inc"
},
{
"path": "MyTinySTL/list.h",
"chars": 26204,
"preview": "#ifndef MYTINYSTL_LIST_H_\n#define MYTINYSTL_LIST_H_\n\n// 这个头文件包含了一个模板类 list\n// list : 双向链表\n\n// notes:\n//\n// 异常保证:\n// mys"
},
{
"path": "MyTinySTL/map.h",
"chars": 16446,
"preview": "#ifndef MYTINYSTL_MAP_H_\n#define MYTINYSTL_MAP_H_\n\n// 这个头文件包含了两个模板类 map 和 multimap\n// map : 映射,元素具有键值和实值,会根据键值大小自动"
},
{
"path": "MyTinySTL/memory.h",
"chars": 4271,
"preview": "#ifndef MYTINYSTL_MEMORY_H_\n#define MYTINYSTL_MEMORY_H_\n\n// 这个头文件负责更高级的动态内存管理\n// 包含一些基本函数、空间配置器、未初始化的储存空间管理,以及一个模板类 aut"
},
{
"path": "MyTinySTL/numeric.h",
"chars": 4149,
"preview": "#ifndef MYTINYSTL_NUMERIC_H_\n#define MYTINYSTL_NUMERIC_H_\n\n// 这个头文件包含了 mystl 的数值算法\n\n#include \"iterator.h\"\n\nnamespace my"
},
{
"path": "MyTinySTL/queue.h",
"chars": 8633,
"preview": "#ifndef MYTINYSTL_QUEUE_H_\n#define MYTINYSTL_QUEUE_H_\n\n// 这个头文件包含了两个模板类 queue 和 priority_queue\n// queue : 队列\n/"
},
{
"path": "MyTinySTL/rb_tree.h",
"chars": 43896,
"preview": "#ifndef MYTINYSTL_RB_TREE_H_\n#define MYTINYSTL_RB_TREE_H_\n\n// 这个头文件包含一个模板类 rb_tree\n// rb_tree : 红黑树\n\n#include <initiali"
},
{
"path": "MyTinySTL/set.h",
"chars": 14144,
"preview": "#ifndef MYTINYSTL_SET_H_\n#define MYTINYSTL_SET_H_\n\n// 这个头文件包含两个模板类 set 和 multiset\n// set : 集合,键值即实值,集合内元素会自动排序,键值不"
},
{
"path": "MyTinySTL/set_algo.h",
"chars": 6249,
"preview": "#ifndef MYTINYSTL_SET_ALGO_H_\n#define MYTINYSTL_SET_ALGO_H_\n\n// 这个头文件包含 set 的四种算法: union, intersection, difference, sym"
},
{
"path": "MyTinySTL/stack.h",
"chars": 3791,
"preview": "#ifndef MYTINYSTL_STACK_H_\n#define MYTINYSTL_STACK_H_\n\n// 这个头文件包含了一个模板类 stack\n// stack : 栈\n\n#include \"deque.h\" \n\nnam"
},
{
"path": "MyTinySTL/stream_iterator.h",
"chars": 2113,
"preview": "#ifndef MYTINYSTL_STREAM_ITERATOR_H_\n#define MYTINYSTL_STREAM_ITERATOR_H_\n\n#include \"basic_string.h\"\n\nnamespace mystl\n{\n"
},
{
"path": "MyTinySTL/type_traits.h",
"chars": 878,
"preview": "#ifndef MYTINYSTL_TYPE_TRAITS_H_\n#define MYTINYSTL_TYPE_TRAITS_H_\n\n// 这个头文件用于提取类型信息\n\n// use standard header for type_tr"
},
{
"path": "MyTinySTL/uninitialized.h",
"chars": 7619,
"preview": "#ifndef MYTINYSTL_UNINITIALIZED_H_\n#define MYTINYSTL_UNINITIALIZED_H_\n\n// 这个头文件用于对未初始化空间构造元素\n\n#include \"algobase.h\"\n#in"
},
{
"path": "MyTinySTL/unordered_map.h",
"chars": 17599,
"preview": "#ifndef MYTINYSTL_UNORDERED_MAP_H_\n#define MYTINYSTL_UNORDERED_MAP_H_\n\n// 这个头文件包含两个模板类 unordered_map 和 unordered_multim"
},
{
"path": "MyTinySTL/unordered_set.h",
"chars": 16552,
"preview": "#ifndef MYTINYSTL_UNORDERED_SET_H_\n#define MYTINYSTL_UNORDERED_SET_H_\n\n// 这个头文件包含两个模板类 unordered_set 和 unordered_multis"
},
{
"path": "MyTinySTL/util.h",
"chars": 7747,
"preview": "#ifndef MYTINYSTL_UTIL_H_\n#define MYTINYSTL_UTIL_H_\n\n// 这个文件包含一些通用工具,包括 move, forward, swap 等函数,以及 pair 等 \n\n#include <c"
},
{
"path": "MyTinySTL/vector.h",
"chars": 22565,
"preview": "#ifndef MYTINYSTL_VECTOR_H_\n#define MYTINYSTL_VECTOR_H_\n\n// 这个头文件包含一个模板类 vector\n// vector : 向量\n\n// notes:\n//\n// 异常保证:\n/"
},
{
"path": "README.md",
"chars": 3480,
"preview": "MyTinySTL\n=====\n[](https://travis-ci.org/Ali"
},
{
"path": "Test/CMakeLists.txt",
"chars": 163,
"preview": "include_directories(${PROJECT_SOURCE_DIR}/MyTinySTL)\nset(APP_SRC test.cpp)\nset(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_D"
},
{
"path": "Test/Lib/redbud/io/color.h",
"chars": 8241,
"preview": "// ============================================================================\n// Copyright (c) 2017 Alinshans. All rig"
},
{
"path": "Test/Lib/redbud/platform.h",
"chars": 2984,
"preview": "// ============================================================================\n// Copyright (c) 2017 Alinshans. All rig"
},
{
"path": "Test/README.md",
"chars": 3181,
"preview": "单元测试 (Unit test)\n=====\n## 测试环境 (Test environment)\n 测试直接在 `Travis CI` 和 `AppVeyor` 上构建并运行,已在以下环境中做过测试:\n \n Tests were b"
},
{
"path": "Test/algorithm_performance_test.h",
"chars": 4328,
"preview": "#ifndef MYTINYSTL_ALGORITHM_PERFORMANCE_TEST_H_\n#define MYTINYSTL_ALGORITHM_PERFORMANCE_TEST_H_\n\n// 仅仅针对 sort, binary_s"
},
{
"path": "Test/algorithm_test.h",
"chars": 37347,
"preview": "#ifndef MYTINYSTL_ALGORITHM_TEST_H_\n#define MYTINYSTL_ALGORITHM_TEST_H_\n\n// 算法测试: 包含了 mystl 的 81 个算法测试\n\n#include <algori"
},
{
"path": "Test/deque_test.h",
"chars": 3365,
"preview": "#ifndef MYTINYSTL_DEQUE_TEST_H_\n#define MYTINYSTL_DEQUE_TEST_H_\n\n// deque test : 测试 deque 的接口和 push_front/push_back 的性能"
},
{
"path": "Test/iterator_test.h",
"chars": 1136,
"preview": "#ifndef MYTINYSTL_ITERATOR_TEST_H_\n#define MYTINYSTL_ITERATOR_TEST_H_\n\n#include \"test.h\"\n#include \"../MyTinySTL/iterator"
},
{
"path": "Test/list_test.h",
"chars": 3868,
"preview": "#ifndef MYTINYSTL_LIST_TEST_H_\n#define MYTINYSTL_LIST_TEST_H_\n\n// list test : 测试 list 的接口与 insert, sort 的性能\n\n#include <"
},
{
"path": "Test/map_test.h",
"chars": 6843,
"preview": "#ifndef MYTINYSTL_MAP_TEST_H_\n#define MYTINYSTL_MAP_TEST_H_\n\n// map test : 测试 map, multimap 的接口与它们 insert 的性能\n\n#include"
},
{
"path": "Test/queue_test.h",
"chars": 5860,
"preview": "#ifndef MYTINYSTL_QUEUE_TEST_H_\n#define MYTINYSTL_QUEUE_TEST_H_\n\n// queue test : 测试 queue, priority_queue 的接口和它们 push 的"
},
{
"path": "Test/set_test.h",
"chars": 5438,
"preview": "#ifndef MYTINYSTL_SET_TEST_H_\n#define MYTINYSTL_SET_TEST_H_\n\n// set test : 测试 set, multiset 的接口与它们 insert 的性能\n\n#include"
},
{
"path": "Test/stack_test.h",
"chars": 2972,
"preview": "#ifndef MYTINYSTL_STACK_TEST_H_\n#define MYTINYSTL_STACK_TEST_H_\n\n// stack test : 测试 stack 的接口 和 push 的性能\n\n#include <sta"
},
{
"path": "Test/string_test.h",
"chars": 7372,
"preview": "#ifndef MYTINYSTL_STRING_TEST_H_\n#define MYTINYSTL_STRING_TEST_H_\n\n// string test : 测试 string 的接口和 insert 的性能\n\n#include"
},
{
"path": "Test/test.cpp",
"chars": 1338,
"preview": "#ifdef _MSC_VER\n#define _SCL_SECURE_NO_WARNINGS\n#endif\n\n#if defined(_MSC_VER) && defined(_DEBUG)\n#define _CRTDBG_MAP_AL"
},
{
"path": "Test/test.h",
"chars": 30255,
"preview": "#ifndef MYTINYSTL_TEST_H_\n#define MYTINYSTL_TEST_H_\n\n// 一个简单的单元测试框架,定义了两个类 TestCase 和 UnitTest,以及一系列用于测试的宏\n\n#include <c"
},
{
"path": "Test/unordered_map_test.h",
"chars": 8183,
"preview": "#ifndef MYTINYSTL_UNORDERED_MAP_TEST_H_\n#define MYTINYSTL_UNORDERED_MAP_TEST_H_\n\n// unordered_map test : 测试 unordered_m"
},
{
"path": "Test/unordered_set_test.h",
"chars": 7314,
"preview": "#ifndef MYTINYSTL_UNORDERED_SET_TEST_H_\n#define MYTINYSTL_UNORDERED_SET_TEST_H_\n\n// unordered_set test : 测试 unordered_s"
},
{
"path": "Test/vector_test.h",
"chars": 3377,
"preview": "#ifndef MYTINYSTL_VECTOR_TEST_H_\n#define MYTINYSTL_VECTOR_TEST_H_\n\n// vector test : 测试 vector 的接口与 push_back 的性能\n\n#incl"
},
{
"path": "appveyor.yml",
"chars": 276,
"preview": "version: 2.0.1{build}\n\nbranches:\n only:\n - master\n \nimage: \n - Visual Studio 2015\n - Visual Studio 2017\n \nconfig"
}
]
About this extraction
This page contains the full source code of the Alinshans/MyTinySTL GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 59 files (620.5 KB), approximately 182.5k tokens, and a symbol index with 757 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.