{"id":44999750,"url":"https://github.com/gharveymn/small_vector","last_synced_at":"2026-02-18T22:10:57.946Z","repository":{"id":84505412,"uuid":"326632751","full_name":"gharveymn/small_vector","owner":"gharveymn","description":"A fully featured single header library implementing a vector container with a small buffer optimization.","archived":false,"fork":false,"pushed_at":"2025-04-27T01:40:45.000Z","size":600,"stargazers_count":59,"open_issues_count":8,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-27T02:28:36.782Z","etag":null,"topics":["concepts","cpp","single-header-library","small-vector"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gharveymn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-01-04T09:30:48.000Z","updated_at":"2025-04-27T01:40:48.000Z","dependencies_parsed_at":"2024-02-08T05:27:56.457Z","dependency_job_id":"28056d77-2a50-4328-bc9a-f9117823f70d","html_url":"https://github.com/gharveymn/small_vector","commit_stats":null,"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/gharveymn/small_vector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gharveymn%2Fsmall_vector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gharveymn%2Fsmall_vector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gharveymn%2Fsmall_vector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gharveymn%2Fsmall_vector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gharveymn","download_url":"https://codeload.github.com/gharveymn/small_vector/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gharveymn%2Fsmall_vector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29596530,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T20:59:56.587Z","status":"ssl_error","status_checked_at":"2026-02-18T20:58:41.434Z","response_time":162,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["concepts","cpp","single-header-library","small-vector"],"created_at":"2026-02-18T22:10:57.286Z","updated_at":"2026-02-18T22:10:57.939Z","avatar_url":"https://github.com/gharveymn.png","language":"C++","readme":"# gch::small_vector\n\nThis is a vector container implementation with a small buffer optimization. It doesn't have any\ndependencies unlike the `boost::container::small_vector` and `llvm::SmallVector` implementations\nand may be used as a drop-in header (along with the license).\n\nPerformance is about on par with the [other implementations](#Other-Implementations), but with\nstricter conformance to the named requirements as specified in the standard. Consequently, this\nimplementation is close to API compatible with `std::vector`, and in many cases can be used as a\ndrop-in replacement.\n\nThis library is compatible with C++11 and up, with `constexpr` and `concept` support for C++20.\n\n## Technical Overview\n\n```c++\ntemplate \u003ctypename T, \n          unsigned InlineCapacity = default_buffer_size\u003cstd::allocator\u003cT\u003e\u003e::value, \n          typename Allocator      = std::allocator\u003cT\u003e\u003e\nclass small_vector;\n```\n\nA `small_vector` is a contiguous sequence container with a certain amount of dedicated storage on\nthe stack.  When this storage is filled up, it switches to allocating on the heap.\n\nA `small_vector` supports insertion and erasure operations in 𝓞(1) the end, and 𝓞(n) in the middle.\nIt also meets the requirements of *Container*, *AllocatorAwareContainer*, *SequenceContainer*,\n*ContiguousContainer*, and *ReversibleContainer*.\n\nTemplate arguments may be used to define the type of stored elements, the number of elements to be\nstored on the stack, and the type of allocator to be used.\n\nWhen compiling with C++20 support, `small_vector` may be used in `constexpr` expressions.\n\nA `small_vector` may be instantiated with an incomplete type `T`, but only if `InlineCapacity` is\nequal to `0`.\n\nWhen compiling with support for `concept`s with complete type `T`, instantiation of a `small_vector`\nrequires that `Allocator` meet the *Allocator* named requirements. Member functions are also\nconstrained by various `concept`s when `T` is complete.\n\nThe default argument for `InlineCapacity` is computed to be the number of elements needed to size\nthe object at 64 bytes. If the size of `T` makes this impossible to do with a non-zero number of\nelements, the value of `InlineCapacity` is set to `1`.\n\n## Usage\n\nYou have a few options to import this library into your project. It is a single-header library,\nso you should be able to use it without too much fuss.\n\n### As a Drop-In Header\n\nJust to drop `source/include/gch/small_vector.hpp` and `docs/LICENSE` into your project.\n\n### As a Git Submodule\n\nYou can add the project as a submodule with\n\n```commandline\ngit submodule add -b main git@github.com:gharveymn/small_vector.git external/small_vector\n```\n\nand then add it as a subdirectory to your project by adding something like\n\n```cmake\nadd_subdirectory (external/small_vector)\ntarget_link_libraries (\u003ctarget\u003e PRIVATE gch::small_vector)\n```\n\nto `CMakeLists.txt`.\n\n### As a System Library\n\nYou can install the library with (Unix-specific, remove `sudo` on Windows)\n\n```commandline\ngit clone git@github.com:gharveymn/small_vector.git\ncmake -D GCH_SMALL_VECTOR_ENABLE_TESTS=OFF -B small_vector/build -S small_vector\nsudo cmake --install small_vector/build\n```\n\nand then link it to your project by adding\n\n```cmake\nfind_package (small_vector REQUIRED)\ntarget_link_libraries (\u003ctarget\u003e PRIVATE gch::small_vector)\n```\n\nto `CMakeLists.txt`.\n\n## Q\u0026A\n\n### Can I specify the `size_type` like with `folly::small_vector`?\n\nNot directly no, but `gch::small_vector::size_type` is derived from `std::allocator_traits`,\nso you can just write a wrapper around whatever allocator you're using to modify it. This can be\ndone with something like\n\n```c++\ntemplate \u003ctypename T\u003e \nstruct tiny_allocator \n  : std::allocator\u003cT\u003e \n{ \n  using size_type = std::uint16_t;\n\n  using std::allocator\u003cT\u003e::allocator;\n\n  // You don't need either of the following when compiling for C++20.\n  template \u003ctypename U\u003e\n  struct rebind { using other = tiny_allocator\u003cU\u003e; };\n\n  void\n  max_size (void) = delete;\n};\n\nint\nmain (void)\n{\n  small_vector\u003cint\u003e vs;\n  std::cout \u003c\u003c \"std::allocator\u003cint\u003e:\"                         \u003c\u003c '\\n'\n            \u003c\u003c \"  sizeof (vs):     \" \u003c\u003c sizeof (vs)           \u003c\u003c '\\n'\n            \u003c\u003c \"  Inline capacity: \" \u003c\u003c vs.inline_capacity () \u003c\u003c '\\n'\n            \u003c\u003c \"  Maximum size:    \" \u003c\u003c vs.max_size ()        \u003c\u003c \"\\n\\n\";\n\n  small_vector\u003cint, default_buffer_size_v\u003ctiny_allocator\u003cint\u003e\u003e, tiny_allocator\u003cint\u003e\u003e vt;\n  std::cout \u003c\u003c \"tiny_allocator\u003cint\u003e:\"                         \u003c\u003c '\\n'\n            \u003c\u003c \"  sizeof (vt):     \" \u003c\u003c sizeof (vt)           \u003c\u003c '\\n'\n            \u003c\u003c \"  Inline capacity: \" \u003c\u003c vt.inline_capacity () \u003c\u003c '\\n'\n            \u003c\u003c \"  Maximum size:    \" \u003c\u003c vt.max_size ()        \u003c\u003c std::endl;\n}\n```\n\nOutput:\n\n```text\nstd::allocator\u003cint\u003e:\n  sizeof (vs):     64\n  Inline capacity: 10\n  Maximum size:    4611686018427387903\n\ntiny_allocator\u003cint\u003e:\n  sizeof (vt):     64\n  Inline capacity: 12\n  Maximum size:    16383\n```\n\n### How can I use this with my STL container template templates?\n\nYou can create a homogeneous template wrapper with something like\n\n```c++\ntemplate \u003ctypename T, typename Allocator = std::allocator\u003cT\u003e,\n          typename InlineCapacityType =\n            std::integral_constant\u003cunsigned, default_buffer_size\u003cAllocator\u003e::value\u003e\u003e\nusing small_vector_ht = small_vector\u003cT, InlineCapacityType::value, Allocator\u003e;\n\ntemplate \u003ctemplate \u003ctypename ...\u003e class VectorT\u003e\nvoid\nf (void)\n{\n  VectorT\u003cint\u003e x;\n  VectorT\u003cstd::string\u003e y;\n  /* ... */\n}\n\nvoid\ng (void)\n{\n  f\u003cstd::vector\u003e ();\n  f\u003csmall_vector_ht\u003e ();\n}\n```\n\nI don't include this in the header because too much choice can often cause confusion about how\nthings are supposed to be used.\n\n### How do I use this in a `constexpr`?\n\nIn C++20, just as with `std::vector`, you cannot create a `constexpr` object of type\n`small_vector`. However, you can use it *inside* a `constexpr`. That is,\n\n```c++\n// Allowed.\nconstexpr \nint \nf (void)\n{\n  small_vector\u003cint\u003e v { 1, 2, 3 };\n  return std::accumulate (v.begin (), v.end (), 0);\n}\n\n// Not allowed.\n// constexpr small_vector\u003cint\u003e w { };\n```\n\n### How do I disable the `concept`s?\n\nYou can define the preprocessor directive `GCH_DISABLE_CONCEPTS` with your compiler. In CMake:\n\n```cmake\ntarget_compile_definitions (\u003ctarget_name\u003e PRIVATE GCH_DISABLE_CONCEPTS)\n```\n\nThese are a bit experimental at the moment, so if something is indeed incorrect please feel free to send\nme a note to fix it.\n\n### How can I enable the pretty-printer for GDB?\n\nAssuming you have installed the library, you can add the following to either `$HOME/.gdbinit` or\n`$(pwd)/.gdbinit`.\n\n```gdb\npython\nimport sys\nsys.path.append(\"/usr/local/share/gch/python\")\nfrom gch.gdb.prettyprinters import small_vector\nend\n```\n\nIf you installed the library to another location, simply adjust the path as needed.\n\nAs a side-note, I haven't found a way to automatically install pretty printers for GDB, so if someone knows how to\ndo so, please let me know.\n\n### Why do I get bad performance compared to other implementations when using this with a throwing move constructor?\n\nThis implementation provides the same strong exception guarantees as the STL vector. So, in some\ncases copies will be made instead of moves when relocating elements if the move constructor of the\nvalue type may throw.\n\nYou can disable the strong exception guarantees by defining\n`GCH_NO_STRONG_EXCEPTION_GUARANTEES` before including the header.\n\n### Why isn't my `small_vector` empty after moving it?\n\nIn cases where the `small_vector` is inlined, we leverage the language of the standard which states that objects which \nhave been moved from are placed in a \"valid but unspecified state\". So, while the data inside the objects of the \n`small_vector` will have been moved, they will not necessarily have been destroyed. This makes it so we can get a bit \nbetter performance if we are immediately moving new data into the `small_vector` which had been moved from.\n\nThe following shows the expected behavior.\n\n```c++\ngch::small_vector\u003cstd::string, 4\u003e v1 { \"hi\", \"howdy\", \"hello\" };\nauto v2 = std::move (v1);\nassert (v2.size () == 3);\nassert (v1.size () == 3);\nfor (auto\u0026 s : v1)\n  assert (s.empty());\n```\n\n## Brief\n\nIn the interest of succinctness, this brief is prepared with declaration decorations compatible\nwith C++20. The `constexpr` and `concept` features will not be available for other versions of the\nstandard.\n\nAlso note that I've omitted the namespacing and template arguments in the `concept`s  used in\nmost of the `requires` statements. Those arguments involve `value_type`, `small_vector`, and `allocator_type`, in the\nobvious fashion.\n\n```c++\nnamespace gch\n{\n  namespace concepts\n  {\n    template \u003ctypename T\u003e concept MoveAssignable;\n    template \u003ctypename T\u003e concept CopyAssignable;\n    template \u003ctypename T\u003e concept Swappable;\n\n    template \u003ctypename T, typename X, typename A, typename ...Args\u003e\n    concept EmplaceConstructible;\n\n    template \u003ctypename T, typename X, typename A\u003e concept DefaultInsertable;\n    template \u003ctypename T, typename X, typename A\u003e concept MoveInsertable;\n    template \u003ctypename T, typename X, typename A\u003e concept CopyInsertable;\n    template \u003ctypename T, typename X, typename A\u003e concept Erasable;\n\n    template \u003ctypename A, typename T\u003e concept AllocatorFor;\n    template \u003ctypename A\u003e concept Allocator;\n  }\n\n  // A class used to calculate the default number of elements in inline storage using a heuristic.\n  template \u003ctypename Allocator\u003e\n  requires concepts::Allocator\u003cAllocator\u003e\n  struct default_buffer_size;\n\n  template \u003ctypename Allocator\u003e\n  inline constexpr\n  unsigned\n  default_buffer_size_v = default_buffer_size\u003cAllocator\u003e::value;\n\n  // A contiguous iterator (just a pointer wrapper).\n  template \u003ctypename Pointer, typename DifferenceType\u003e\n  class small_vector_iterator;\n\n  template \u003ctypename T,\n            unsigned InlineCapacity = default_buffer_size_v\u003cstd::allocator\u003cT\u003e\u003e,\n            typename Allocator      = std::allocator\u003cT\u003e\u003e\n  requires concepts::AllocatorFor\u003cAllocator, T\u003e\n  class small_vector\n  {\n  public:\n    using value_type             = T;\n    using allocator_type         = Allocator;\n    using size_type              = typename std::allocator_traits\u003cAllocator\u003e::size_type;\n    using difference_type        = /* min { signed size_type, alloc_traits::difference_type } */;\n    using reference              =       value_type\u0026;\n    using const_reference        = const value_type\u0026;\n    using pointer                = typename std::allocator_traits\u003callocator_type\u003e::pointer;\n    using const_pointer          = typename std::allocator_traits\u003callocator_type\u003e::const_pointer;\n\n    using iterator               = small_vector_iterator\u003cpointer, difference_type\u003e;\n    using const_iterator         = small_vector_iterator\u003cconst_pointer, difference_type\u003e;\n    using reverse_iterator       = std::reverse_iterator\u003citerator\u003e;\n    using const_reverse_iterator = std::reverse_iterator\u003cconst_iterator\u003e;\n\n    /* construction */\n    constexpr\n    small_vector (void)\n      noexcept (noexcept (allocator_type ()))\n      requires concepts::DefaultConstructible\u003callocator_type\u003e;\n\n    constexpr\n    small_vector (const small_vector\u0026 other)\n      requires CopyInsertable \u0026\u0026 CopyAssignable;\n\n    constexpr\n    small_vector (small_vector\u0026\u0026 other) \n      noexcept (std::is_nothrow_move_constructible\u003cvalue_type\u003e::value || 0 == InlineCapacity)\n      requires MoveInsertable;\n\n    constexpr explicit\n    small_vector (const allocator_type\u0026 alloc) noexcept;\n\n    constexpr\n    small_vector (const small_vector\u0026 other, const allocator_type\u0026 alloc)\n      requires CopyInsertable;\n\n    constexpr\n    small_vector (small_vector\u0026\u0026 other, const allocator_type\u0026 alloc)\n      requires MoveInsertable;\n\n    constexpr explicit\n    small_vector (size_type count, const allocator_type\u0026 alloc = allocator_type ())\n      requires DefaultInsertable;\n\n    constexpr\n    small_vector (size_type count, const_reference value,\n                  const allocator_type\u0026 alloc = allocator_type ())\n      requires CopyInsertable;\n\n    template \u003cstd::copy_constructible Generator\u003e\n    requires std::invocable\u003cGenerator\u0026\u003e\n         \u0026\u0026  EmplaceConstructible\u003cstd::invoke_result_t\u003cGenerator\u0026\u003e\u003e\n    GCH_CPP20_CONSTEXPR\n    small_vector (size_type count, Generator g, const allocator_type\u0026 alloc = allocator_type ());\n\n    template \u003cstd::input_iterator InputIt\u003e\n    requires EmplaceConstructible\u003cstd::iter_reference_t\u003cInputIt\u003e\u003e\n         \u0026\u0026  (std::forward_iterator\u003cInputIt\u003e || MoveInsertable)\n    constexpr\n    small_vector (InputIt first, InputIt last, const allocator_type\u0026 alloc = allocator_type ());\n\n    constexpr\n    small_vector (std::initializer_list\u003cvalue_type\u003e init,\n                  const allocator_type\u0026 alloc = allocator_type ())\n      requires EmplaceConstructible\u003cconst_reference\u003e;\n\n    template \u003cunsigned I\u003e\n    requires CopyInsertable \u0026\u0026 CopyAssignable\n    constexpr explicit\n    small_vector (const small_vector\u003cT, I, Allocator\u003e\u0026 other);\n\n    template \u003cunsigned LessI\u003e\n    requires (LessI \u003c InlineCapacity) \u0026\u0026 MoveInsertable\n    constexpr explicit\n    small_vector (small_vector\u003cT, LessI, Allocator\u003e\u0026\u0026 other)\n      noexcept (std::is_nothrow_move_constructible\u003cvalue_type\u003e::value);\n\n    template \u003cunsigned GreaterI\u003e\n    requires (InlineCapacity \u003c GreaterI) \u0026\u0026 MoveInsertable\n    constexpr explicit\n    small_vector (small_vector\u003cT, GreaterI, Allocator\u003e\u0026\u0026 other);\n\n    template \u003cunsigned I\u003e\n    requires CopyInsertable\n    constexpr\n    small_vector (const small_vector\u003cT, I, Allocator\u003e\u0026 other, const allocator_type\u0026 alloc);\n\n    template \u003cunsigned I\u003e\n    requires MoveInsertable\n    constexpr\n    small_vector (small_vector\u003cT, I, Allocator\u003e\u0026\u0026 other, const allocator_type\u0026 alloc);\n\n    /* destruction */\n    constexpr\n    ~small_vector (void)\n      requires Erasable;\n\n    /* assignment */\n    constexpr\n    small_vector\u0026\n    operator= (const small_vector\u0026 other)\n      requires CopyInsertable \u0026\u0026 CopyAssignable;\n\n    constexpr\n    small_vector\u0026\n    operator= (small_vector\u0026\u0026 other) \n      noexcept (  (  std::is_same\u003cstd::allocator\u003cvalue_type\u003e, Allocator\u003e::value\n                 ||  std::allocator_traits\u003cAllocator\u003e::propagate_on_container_move_assignment::value\n                 ||  std::allocator_traits\u003cAllocator\u003e::is_always_equal::value\n                  )\n              \u0026\u0026  (  (  std::is_nothrow_move_assignable\u003cvalue_type\u003e::value\n                    \u0026\u0026  std::is_nothrow_move_constructible\u003cvalue_type\u003e::value\n                     )\n                 ||  InlineCapacity == 0\n                  )\n               )\n      requires MoveInsertable \u0026\u0026 MoveAssignable;\n\n    constexpr\n    small_vector\u0026\n    operator= (std::initializer_list\u003cvalue_type\u003e ilist)\n      requires CopyInsertable \u0026\u0026 CopyAssignable;\n\n    constexpr\n    void\n    assign (size_type count, const_reference value)\n      requires CopyInsertable \u0026\u0026 CopyAssignable;\n\n    template \u003cstd::input_iterator InputIt\u003e\n    requires EmplaceConstructible\u003cstd::iter_reference_t\u003cInputIt\u003e\u003e\n         \u0026\u0026  (std::forward_iterator\u003cInputIt\u003e || MoveInsertable)\n    constexpr\n    void\n    assign (InputIt first, InputIt last);\n\n    constexpr\n    void\n    assign (std::initializer_list\u003cvalue_type\u003e ilist)\n      requires EmplaceConstructible\u003cconst_reference\u003e;\n\n    template \u003cunsigned I\u003e\n    requires CopyInsertable \u0026\u0026 CopyAssignable\n    constexpr\n    void\n    assign (const small_vector\u003cT, I, Allocator\u003e\u0026 other);\n\n    constexpr\n    void\n    assign (small_vector\u0026\u0026 other)\n      noexcept (  (  std::is_same\u003cstd::allocator\u003cvalue_type\u003e, Allocator\u003e::value\n                 ||  std::allocator_traits\u003cAllocator\u003e::propagate_on_container_move_assignment::value\n                 ||  std::allocator_traits\u003cAllocator\u003e::is_always_equal::value\n                  )\n              \u0026\u0026  (  (  std::is_nothrow_move_assignable\u003cvalue_type\u003e::value\n                    \u0026\u0026  std::is_nothrow_move_constructible\u003cvalue_type\u003e::value\n                     )\n                 ||  InlineCapacity == 0\n                  )\n               )\n      requires MoveInsertable \u0026\u0026 MoveAssignable;\n\n    template \u003cunsigned LessI\u003e\n    requires (LessI \u003c InlineCapacity) \u0026\u0026 MoveInsertable \u0026\u0026 MoveAssignable\n    constexpr\n    void\n    assign (small_vector\u003cT, LessI, Allocator\u003e\u0026\u0026 other)\n      noexcept (  (  std::is_same\u003cstd::allocator\u003cvalue_type\u003e, Allocator\u003e::value\n                 ||  std::allocator_traits\u003cAllocator\u003e::propagate_on_container_move_assignment::value\n                 ||  std::allocator_traits\u003cAllocator\u003e::is_always_equal::value\n                  )\n              \u0026\u0026  std::is_nothrow_move_assignable\u003cvalue_type\u003e::value\n              \u0026\u0026  std::is_nothrow_move_constructible\u003cvalue_type\u003e::value\n               );\n\n    template \u003cunsigned GreaterI\u003e\n    requires (InlineCapacity \u003c GreaterI) \u0026\u0026 MoveInsertable \u0026\u0026 MoveAssignable\n    constexpr\n    void\n    assign (small_vector\u003cT, GreaterI, Allocator\u003e\u0026\u0026 other);\n\n    constexpr\n    void\n    swap (small_vector\u0026 other)\n      noexcept (  (  std::is_same\u003cstd::allocator\u003cvalue_type\u003e, Allocator\u003e::value\n                 ||  std::allocator_traits\u003cAllocator\u003e::propagate_on_container_swap::value\n                 ||  std::allocator_traits\u003cAllocator\u003e::is_always_equal::value\n                  )\n              \u0026\u0026  (  (  std::is_nothrow_move_constructible\u003cvalue_type\u003e::value\n                    \u0026\u0026  std::is_nothrow_move_assignable\u003cvalue_type\u003e::value\n                    \u0026\u0026  std::is_nothrow_swappable\u003cvalue_type\u003e::value\n                     )\n                 ||  InlineCapacity == 0\n                  )\n               )\n      requires (MoveInsertable \u0026\u0026 MoveAssignable \u0026\u0026 Swappable)\n           ||  (  (  std::is_same\u003cstd::allocator\u003cvalue_type\u003e, Allocator\u003e::value\n                 ||  std::allocator_traits\u003cAllocator\u003e::propagate_on_container_swap::value\n                 ||  std::allocator_traits\u003cAllocator\u003e::is_always_equal::value\n                  )\n              \u0026\u0026  InlineCapacity == 0\n               )\n           \n    template \u003cunsigned I\u003e\n    constexpr\n    void\n    swap (small_vector\u0026 other)\n      requires (MoveInsertable \u0026\u0026 MoveAssignable \u0026\u0026 Swappable)\n           ||  (  (  std::is_same\u003cstd::allocator\u003cvalue_type\u003e, Allocator\u003e::value\n                 ||  std::allocator_traits\u003cAllocator\u003e::propagate_on_container_swap::value\n                 ||  std::allocator_traits\u003cAllocator\u003e::is_always_equal::value\n                  )\n               )\n\n    /* iteration */\n    constexpr iterator               begin   (void)       noexcept;\n    constexpr const_iterator         begin   (void) const noexcept;\n    constexpr const_iterator         cbegin  (void) const noexcept;\n\n    constexpr iterator               end     (void)       noexcept;\n    constexpr const_iterator         end     (void) const noexcept;\n    constexpr const_iterator         cend    (void) const noexcept;\n\n    constexpr reverse_iterator       rbegin  (void)       noexcept;\n    constexpr const_reverse_iterator rbegin  (void) const noexcept;\n    constexpr const_reverse_iterator crbegin (void) const noexcept;\n\n    constexpr reverse_iterator       rend    (void)       noexcept;\n    constexpr const_reverse_iterator rend    (void) const noexcept;\n    constexpr const_reverse_iterator crend   (void) const noexcept;\n\n    /* access */\n    constexpr reference       at (size_type pos);\n    constexpr const_reference at (size_type pos) const;\n\n    constexpr reference       operator[] (size_type pos);\n    constexpr const_reference operator[] (size_type pos) const;\n\n    constexpr reference       front (void);\n    constexpr const_reference front (void) const;\n\n    constexpr reference       back  (void);\n    constexpr const_reference back  (void) const;\n\n    constexpr pointer         data  (void)       noexcept;\n    constexpr const_pointer   data  (void) const noexcept;\n\n    /* state information */\n    [[nodiscard]]\n    constexpr bool empty (void) const noexcept;\n\n    constexpr size_type      size          (void) const noexcept;\n    constexpr size_type      max_size      (void) const noexcept;\n    constexpr size_type      capacity      (void) const noexcept;\n    constexpr allocator_type get_allocator (void) const noexcept;\n\n    /* insertion */\n    constexpr\n    iterator\n    insert (const_iterator pos, const_reference value)\n      requires CopyInsertable \u0026\u0026 CopyAssignable;\n\n    constexpr\n    iterator\n    insert (const_iterator pos, value_type\u0026\u0026 value)\n      requires MoveInsertable \u0026\u0026 MoveAssignable;\n\n    constexpr\n    iterator\n    insert (const_iterator pos, size_type count, const_reference value)\n      requires CopyInsertable \u0026\u0026 CopyAssignable;\n\n    template \u003cstd::input_iterator InputIt\u003e\n    requires EmplaceConstructible\u003cstd::iter_reference_t\u003cInputIt\u003e\u003e\n         \u0026\u0026  MoveInsertable\n         \u0026\u0026  MoveAssignable\n    constexpr\n    iterator\n    insert (const_iterator pos, InputIt first, InputIt last);\n\n    constexpr\n    iterator\n    insert (const_iterator pos, std::initializer_list\u003cvalue_type\u003e ilist)\n      requires EmplaceConstructible\u003cconst_reference\u003e\n           \u0026\u0026  MoveInsertable\n           \u0026\u0026  MoveAssignable;\n\n    template \u003ctypename ...Args\u003e\n      requires EmplaceConstructible\u003cArgs...\u003e\n           \u0026\u0026  MoveInsertable\n           \u0026\u0026  MoveAssignable\n    constexpr\n    iterator\n    emplace (const_iterator pos, Args\u0026\u0026... args);\n\n    constexpr\n    iterator\n    erase (const_iterator pos)\n      requires MoveAssignable \u0026\u0026 Erasable;\n\n    constexpr\n    iterator\n    erase (const_iterator first, const_iterator last)\n      requires MoveAssignable \u0026\u0026 Erasable;\n\n    constexpr\n    void\n    push_back (const_reference value)\n      requires CopyInsertable;\n\n    constexpr\n    void\n    push_back (value_type\u0026\u0026 value)\n      requires MoveInsertable;\n\n    template \u003ctypename ...Args\u003e\n    requires EmplaceConstructible\u003cArgs...\u003e \u0026\u0026 MoveInsertable\n    constexpr\n    reference\n    emplace_back (Args\u0026\u0026... args);\n\n    constexpr\n    void\n    pop_back (void)\n      requires Erasable;\n\n    /* global state modification */\n    constexpr\n    void\n    reserve (size_type new_cap)\n      requires MoveInsertable;\n\n    constexpr\n    void\n    shrink_to_fit (void)\n      requires MoveInsertable;\n\n    constexpr\n    void\n    clear (void) noexcept\n      requires Erasable;\n\n    constexpr\n    void\n    resize (size_type count)\n      requires MoveInsertable \u0026\u0026 DefaultInsertable;\n\n    constexpr\n    void\n    resize (size_type count, const_reference value)\n      requires CopyInsertable;\n\n    /* non-standard */\n    [[nodiscard]] constexpr bool      inlined         (void) const noexcept;\n    [[nodiscard]] constexpr bool      inlinable       (void) const noexcept;\n    [[nodiscard]] constexpr size_type inline_capacity (void) const noexcept;\n\n    template \u003cstd::input_iterator InputIt\u003e\n    requires EmplaceConstructible\u003cstd::iter_reference_t\u003cInputIt\u003e\u003e\n         \u0026\u0026  MoveInsertable\n    constexpr\n    small_vector\u0026\n    append (InputIt first, InputIt last);\n\n    constexpr\n    small_vector\u0026\n    append (std::initializer_list\u003cvalue_type\u003e ilist)\n      requires EmplaceConstructible\u003cconst_reference\u003e\n           \u0026\u0026  MoveInsertable;\n\n    template \u003cunsigned I\u003e\n    constexpr\n    small_vector\u0026\n    append (const small_vector\u003cT, I, Allocator\u003e\u0026 other)\n      requires CopyInsertable;\n\n    template \u003cunsigned I\u003e\n    constexpr\n    small_vector\u0026\n    append (small_vector\u003cT, I, Allocator\u003e\u0026\u0026 other)\n      requires MoveInsertable;\n  };\n\n  /* non-member functions */\n\n  template \u003ctypename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator\u003e\n  constexpr\n  bool\n  operator== (const small_vector\u003cT, InlineCapacityLHS, Allocator\u003e\u0026 lhs,\n              const small_vector\u003cT, InlineCapacityRHS, Allocator\u003e\u0026 rhs);\n\n  template \u003ctypename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator\u003e\n  constexpr\n  auto\n  operator\u003c=\u003e (const small_vector\u003cT, InlineCapacityLHS, Allocator\u003e\u0026 lhs,\n               const small_vector\u003cT, InlineCapacityRHS, Allocator\u003e\u0026 rhs);\n\n  /* insert other comparison boilerplate here if not using C++20 */\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  void\n  swap (small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 lhs,\n        small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 rhs)\n    noexcept (noexcept (lhs.swap (rhs)))\n    requires MoveInsertable \u0026\u0026 Swappable;\n  \n  template \u003ctypename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator\u003e\n  constexpr\n  void\n  swap (small_vector\u003cT, InlineCapacityLHS, Allocator\u003e\u0026 lhs,\n        small_vector\u003cT, InlineCapacityRHS, Allocator\u003e\u0026 rhs)\n    requires MoveInsertable \u0026\u0026 Swappable;\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator, typename U\u003e\n  constexpr\n  typename small_vector\u003cT, InlineCapacity, Allocator\u003e::size_type\n  erase (small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 c, const U\u0026 value);\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator, typename Pred\u003e\n  constexpr\n  typename small_vector\u003cT, InlineCapacity, Allocator\u003e::size_type\n  erase_if (small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 c, Pred pred);\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  begin (small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (v.begin ());\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  begin (const small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (v.begin ());\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  cbegin (const small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (begin (v));\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  end (small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (v.end ());\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  end (const small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (v.end ());\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  cend (const small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (end (v));\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  rbegin (small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (rbegin (v));\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  rbegin (const small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (rbegin (v));\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  crbegin (const small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (rbegin (v));\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  rend (small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (v.rend ());\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  rend (const small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (v.rend ());\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  crend (const small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (rend (v));\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  size (const small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (v.size ());\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  ssize (const small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e std::common_type_t\u003cstd::ptrdiff_t, std::make_signed_t\u003cdecltype (v.size ())\u003e\u003e;\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  [[nodiscard]] constexpr\n  auto\n  empty (const small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (v.empty ())\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  data (small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (v.data ())\n\n  template \u003ctypename T, unsigned InlineCapacity, typename Allocator\u003e\n  constexpr\n  auto\n  data (const small_vector\u003cT, InlineCapacity, Allocator\u003e\u0026 v) noexcept\n    -\u003e decltype (v.data ())\n\n  template \u003ctypename InputIt,\n            unsigned InlineCapacity = default_buffer_size_v\u003c\n              std::allocator\u003ctypename std::iterator_traits\u003cInputIt\u003e::value_type\u003e\u003e,\n            typename Allocator = std::allocator\u003ctypename std::iterator_traits\u003cInputIt\u003e::value_type\u003e\u003e\n  small_vector (InputIt, InputIt, Allocator = Allocator ())\n    -\u003e small_vector\u003ctypename std::iterator_traits\u003cInputIt\u003e::value_type, InlineCapacity, Allocator\u003e;\n}\n```\n\n## Other Implementations\n\n- [boost::container::small_vector](https://www.boost.org/doc/libs/1_60_0/doc/html/boost/container/small_vector.html)\n- [llvm::SmallVector](https://llvm.org/doxygen/classllvm_1_1SmallVector.html)\n- [folly::small_vector](https://github.com/facebook/folly/blob/main/folly/docs/small_vector.md)\n\n## License\n\nThis project may be modified and distributed under the terms of the MIT license. See the [LICENSE](LICENSE)\nfile for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgharveymn%2Fsmall_vector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgharveymn%2Fsmall_vector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgharveymn%2Fsmall_vector/lists"}