Created
January 21, 2026 11:07
-
-
Save kerrytazi/198d82056e1b7e2608145802f1264563 to your computer and use it in GitHub Desktop.
Implementation of vector with size of 64 bits
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <cstddef> | |
| #include <cstdint> | |
| #include <bit> | |
| #include <stdexcept> | |
| #include <memory> | |
| template <typename T> | |
| struct micro_vector | |
| { | |
| using size_type = size_t; | |
| using value_type = T; | |
| using pointer = T*; | |
| using const_pointer = const T*; | |
| using reference = T&; | |
| using const_reference = const T&; | |
| using move_reference = T&&; | |
| micro_vector() = default; | |
| micro_vector(const micro_vector& other) | |
| { | |
| _copy_from(other); | |
| } | |
| micro_vector& operator=(const micro_vector& other) | |
| { | |
| _destroy(); | |
| _copy_from(other); | |
| return *this; | |
| } | |
| micro_vector(micro_vector&& other) | |
| { | |
| swap(other); | |
| } | |
| micro_vector& operator=(micro_vector&& other) | |
| { | |
| swap(other); | |
| return *this; | |
| } | |
| ~micro_vector() | |
| { | |
| _destroy(); | |
| } | |
| size_type capacity() const | |
| { | |
| return 1 << 16; | |
| } | |
| size_type size() const | |
| { | |
| return _get_size(); | |
| } | |
| pointer data() | |
| { | |
| return std::bit_cast<pointer>(_get_data()); | |
| } | |
| const_pointer data() const | |
| { | |
| return std::bit_cast<const_pointer>(_get_data()); | |
| } | |
| bool empty() const { return size() == 0; } | |
| pointer begin() { return data(); } | |
| pointer end() { return data() + size(); } | |
| const const_pointer begin() const { return data(); } | |
| const const_pointer end() const { return data() + size(); } | |
| const const_pointer cbegin() const { return data(); } | |
| const const_pointer cend() const { return data() + size(); } | |
| template <typename... TArgs> | |
| reference emplace_back(TArgs&&... args) | |
| { | |
| _alloc_inner(); | |
| auto s = size(); | |
| auto p = data(); | |
| if (s + 1 >= capacity()) | |
| throw std::bad_alloc(); | |
| std::construct_at(&p[s], std::forward<TArgs>(args)...); | |
| _set_size(s + 1); | |
| return p[s]; | |
| } | |
| reference emplace_back(move_reference val) | |
| { | |
| _alloc_inner(); | |
| auto s = size(); | |
| auto p = data(); | |
| if (s + 1 >= capacity()) | |
| throw std::bad_alloc(); | |
| std::construct_at<value_type>(&p[s], std::move(val)); | |
| _set_size(s + 1); | |
| return p[s]; | |
| } | |
| void push_back(const_reference val) | |
| { | |
| emplace_back(val); | |
| } | |
| void push_back(move_reference val) | |
| { | |
| emplace_back(std::move(val)); | |
| } | |
| void swap(micro_vector& other) | |
| { | |
| std::swap(_val, other._val); | |
| } | |
| void _copy_from(const micro_vector& other) | |
| { | |
| if (!other._val) | |
| return; | |
| for (const_reference val : other) | |
| push_back(val); | |
| } | |
| void _alloc_inner() | |
| { | |
| if (data()) | |
| return; | |
| _val = std::bit_cast<size_type>(std::allocator<value_type>{}.allocate(capacity())); | |
| } | |
| void _destroy() | |
| { | |
| if (_val == 0) | |
| return; | |
| for (auto it = begin(); it != end(); ++it) | |
| std::destroy_at(it); | |
| std::allocator<value_type>{}.deallocate(data(), capacity()); | |
| _val = 0; | |
| } | |
| size_type _get_size() const { return _val >> 48; } | |
| size_type _get_data() const { return _val & 0x0000'ffff'ffff'ffff; } | |
| void _set_size(size_type new_size) | |
| { | |
| _val = (new_size << 48) | _get_data(); | |
| } | |
| size_type _val = 0; | |
| }; | |
| static_assert(sizeof(void*) == 8, "Only 64 bit systems supported"); | |
| static_assert(sizeof(micro_vector<int>) == 8, "How?"); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "micro_vector.hpp" | |
| #include <iostream> | |
| int main() | |
| { | |
| micro_vector<int> vec1; | |
| vec1.push_back(123); | |
| vec1.push_back(456); | |
| vec1.push_back(789); | |
| auto vec2 = vec1; | |
| vec2.emplace_back(654); | |
| std::cout << "vec1:\n"; | |
| for (auto val : vec1) | |
| std::cout << val << "\n"; | |
| std::cout << "vec2:\n"; | |
| for (auto val : vec2) | |
| std::cout << val << "\n"; | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment