| 
					
				 | 
			
			
				@@ -0,0 +1,483 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifndef __GBLIBCPP_VECTOR__ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define __GBLIBCPP_VECTOR__ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <functional> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <memory> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <initializer_list> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <cstddef> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+namespace std { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template <typename T, typename Allocator = std::allocator<T>> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class vector { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    using value_type = T; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    using allocator_type = Allocator; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    using size_type = std::size_t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    using difference_type = std::ptrdiff_t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    using reference = T&; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    using const_reference = const T&; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template <bool Const> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    class _iterator { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // using iterator_category = std::random_access_iterator_tag; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        using value_type = std::conditional_t<Const, const T, T>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        using difference_type = std::ptrdiff_t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        using pointer = std::add_pointer_t<value_type>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        using reference = std::add_lvalue_reference_t<value_type>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        T* m_ptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr _iterator(void) noexcept : m_ptr() {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr explicit _iterator(const T* ptr) noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            : m_ptr(const_cast<T*>(ptr)) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr _iterator(const _iterator& other) noexcept = default; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr _iterator(_iterator&& other) noexcept = default; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr _iterator& operator=(const _iterator& other) noexcept = default; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr _iterator& operator=(_iterator&& other) noexcept = default; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr bool operator==(const _iterator& other) const noexcept = default; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr reference operator*() const noexcept { return *m_ptr; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr pointer operator&() const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { return std::addressof(this->operator*()); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr pointer operator->() const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { return this->operator&(); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr _iterator& operator++() noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { ++m_ptr; return *this; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr _iterator operator++(int) noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { _iterator ret(m_ptr); (void)this->operator++(); return ret; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr _iterator& operator--(void) noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { --m_ptr; return *this; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr _iterator operator--(int) noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { _iterator ret(m_ptr); (void)this->operator--(); return ret; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr operator bool() { return m_ptr; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr operator _iterator<true>() { return _iterator<true> { m_ptr }; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr operator _iterator<false>() { return _iterator<false> { m_ptr }; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constexpr operator const T*() { return m_ptr; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+private: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    using alloc_traits = std::allocator_traits<Allocator>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    using pointer = typename alloc_traits::pointer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    using const_pointer = typename alloc_traits::const_pointer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    using iterator = _iterator<false>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    using const_iterator = _iterator<true>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+private: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    T* m_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    size_type m_size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    size_type m_capacity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    allocator_type m_alloc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+private: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // assert(n >= m_size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void _reallocate_safe(size_type n) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        auto* newptr = alloc_traits::allocate(m_alloc, n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (size_t i = 0; i < m_size; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alloc_traits::construct(m_alloc, newptr + i, std::move(m_data[i])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alloc_traits::destroy(m_alloc, m_data + i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        alloc_traits::deallocate(m_alloc, m_data, m_capacity); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m_data = newptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m_capacity = n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // make m_capacity >= n >= m_size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void _pre_resize(size_type n) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (n < m_size) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            while (n < m_size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                pop_back(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else if (n > m_size) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            reserve(n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr vector(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        noexcept(noexcept(Allocator())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        : m_data(), m_size(), m_capacity(), m_alloc() {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr explicit vector(const Allocator& alloc) noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        : m_data(), m_size(), m_capacity(), m_alloc(alloc) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr vector(size_type n, const T& val, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const Allocator& alloc = Allocator()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        : vector(alloc) { resize(n, val); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr explicit vector(size_type n, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const Allocator& alloc = Allocator()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        : vector(alloc) { resize(n); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // TODO: check whether InputIter satisfies LegacyInputIterator 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template <typename InputIter> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr vector(InputIter first, InputIter last, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const Allocator& alloc = Allocator()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        : vector(alloc) { insert(cbegin(), first, last); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr vector(const vector& other) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        : vector(std::allocator_traits<allocator_type>:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            select_on_container_copy_construction(other.m_alloc)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { insert(cbegin(), other.begin(), other.end()); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr vector(const vector& other, const Allocator& alloc) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        : vector(alloc) { insert(cbegin(), other.begin(), other.end()); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr vector(vector&& other) noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        : m_data(std::exchange(other.m_data, nullptr)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        , m_size(std::exchange(other.m_size, 0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        , m_capacity(std::exchange(other.m_capacity, 0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        , m_alloc(std::move(other.m_alloc)) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr vector(vector&& other, const Allocator& alloc) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        : vector(alloc) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (alloc == other.get_allocator()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            m_data = std::exchange(other.m_data, nullptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            m_size = std::exchange(other.m_size, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            m_capacity = std::exchange(other.m_capacity, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // TODO: std::move_iterator 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // insert(cbegin(), std::make_move_iterator(other.begin()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //     std::make_move_iterator(other.end())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (auto& item : other) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                emplace_back(std::move(item)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr vector(std::initializer_list<T> init, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const Allocator& alloc = Allocator()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        : vector(alloc) { insert(cbegin(), init.begin(), init.end()); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr ~vector() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        resize(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        shrink_to_fit(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    vector& operator=(const vector& other) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if constexpr (alloc_traits:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            propagate_on_container_copy_assignment::value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (m_alloc != other.m_alloc) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                shrink_to_fit(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            m_alloc = other.m_alloc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        insert(cbegin(), other.begin(), other.end()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return *this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    vector& operator=(vector&& other) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if constexpr (alloc_traits:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            propagate_on_container_move_assignment::value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            shrink_to_fit(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            m_alloc = std::move(other.m_alloc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (m_alloc != other.m_alloc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // TODO: std::move_iterator 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                for (auto& item : other) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    emplace_back(std::move(item)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return *this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            shrink_to_fit(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m_data = std::exchange(other.m_data, nullptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m_size = std::exchange(other.m_size, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m_capacity = std::exchange(other.m_capacity, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return *this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    vector& operator=(std::initializer_list<T> init) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assign(init.begin(), init.end()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return *this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void assign(size_type n, const T& val) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        resize(n, val); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // TODO: check whether InputIter satisfies LegacyInputIterator 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template <typename InputIter> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void assign(InputIter first, InputIter last) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        insert(cbegin(), first, last); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void assign(std::initializer_list<T> init) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        insert(cbegin(), init.begin(), init.end()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr allocator_type get_allocator(void) const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return m_alloc; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr reference at(size_type pos) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO: exceptions 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // if (pos >= sz) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     throw std::out_of_range("vector::at"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return m_data[pos]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr const_reference at(size_type pos) const 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO: exceptions 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // if (pos >= sz) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     throw std::out_of_range("vector::at"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return m_data[pos]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr reference operator[](size_type pos) noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return m_data[pos]; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr const_reference operator[](size_type pos) const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return m_data[pos]; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr reference front() noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return m_data[0]; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr const_reference front() const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return m_data[0]; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr reference back() noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return m_data[m_size - 1]; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr const_reference back() const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return m_data[m_size - 1]; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr T* data(void) noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return m_data; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr const T* data(void) const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return m_data; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // TODO: std::reverse_iterator 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr iterator begin() noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return iterator { m_data }; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr const_iterator begin() const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return const_iterator { m_data }; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr const_iterator cbegin() const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return const_iterator { m_data }; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr iterator end() noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return iterator { m_data + m_size }; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr const_iterator end() const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return const_iterator { m_data + m_size }; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr const_iterator cend() const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return const_iterator { m_data + m_size }; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    [[nodiscard]] constexpr bool empty() const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return m_size == 0; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr size_type size() const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return m_size; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr size_type capacity() const noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return m_capacity; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void reserve(size_type new_cap) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (new_cap > m_capacity) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _reallocate_safe(new_cap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void resize(size_type n) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        _pre_resize(n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        while (n > m_size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            emplace_back(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void resize(size_type n, const value_type& value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        _pre_resize(n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        while (n > m_size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            emplace_back(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void shrink_to_fit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (m_size != m_capacity) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _reallocate_safe(m_size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void clear() noexcept 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { resize(0); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template <typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr iterator emplace(const_iterator pos, Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        size_type idx = pos - m_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!pos) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            reserve(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (m_size == m_capacity) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            reserve(m_capacity * 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (size_type i = m_size; i > idx; --i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alloc_traits::construct(m_alloc, m_data + i, std::move(m_data[i-1])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        alloc_traits::construct(m_alloc, m_data + idx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ++m_size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return iterator { m_data + idx }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr iterator insert(const_iterator pos, T&& val) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return emplace(pos, std::move(val)); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr iterator insert(const_iterator pos, const T& val) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return emplace(pos, val); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr iterator insert(const_iterator pos, size_type n, const T& val) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!n) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return pos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        size_type idx = pos - m_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!pos) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            reserve(n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (m_size + n > m_capacity) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            reserve(m_capacity * 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (size_type i = m_size + n - 1; i >= idx + n; --i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alloc_traits::construct(m_alloc, m_data + i, std::move(m_data[i-n])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (size_type i = idx; i < idx + n; ++i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alloc_traits::construct(m_alloc, m_data + i, val); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m_size += n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return iterator { m_data + idx }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // TODO: LegacyInputIterator version of this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template <typename ForwardIter> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr iterator insert(const_iterator pos, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ForwardIter first, ForwardIter last) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        size_type idx = pos - m_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        size_type n = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ForwardIter tmp = first; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        while (tmp != last) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ++n, ++tmp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!n) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return pos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!pos) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            reserve(n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (m_size + n > m_capacity) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            reserve(m_capacity * 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (size_type i = m_size + n - 1; i >= idx + n; --i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alloc_traits::construct(m_alloc, m_data + i, std::move(m_data[i-n])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (size_type i = idx; i < idx + n; ++i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alloc_traits::construct(m_alloc, m_data + i, *first++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m_size += n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return iterator { m_data + idx }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr iterator insert(const_iterator pos, std::initializer_list<T> init) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { return insert(pos, init.begin(), init.end()); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr iterator erase(const_iterator pos) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        size_type idx = pos - m_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        alloc_traits::destroy(m_alloc, m_data + idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (size_type i = idx; i < m_size - 1; ++i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alloc_traits::construct(m_alloc, m_data + i, std::move(m_data[i+1])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        --m_size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return iterator { m_data + idx }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr iterator erase(const_iterator first, const_iterator last) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        size_type n = last - first; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!n) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return last; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        size_type idx = first - m_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (size_type i = idx; i < idx + n; ++i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alloc_traits::destroy(m_alloc, m_data + i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (size_type i = idx; i < m_size - n; ++i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            m_alloc.construct(m_data + i, std::move(m_data[i+n])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m_size -= n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return iterator { m_data + idx }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void push_back(const T& val) { insert(cend(), val); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void push_back(T&& val) { insert(cend(), std::move(val)); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template <typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void emplace_back(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { emplace(cend(), std::forward<Args>(args)...); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void pop_back() { erase(--cend()); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constexpr void swap(vector& other) noexcept( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        alloc_traits::propagate_on_container_swap::value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        || alloc_traits::is_always_equal::value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (alloc_traits::propagate_on_container_swap::value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            std::swap(m_alloc, other.m_alloc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        std::swap(m_data, other.m_data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        std::swap(m_size, other.m_size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        std::swap(m_capacity, other.m_capacity); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template <typename T, typename Allocator> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+constexpr void swap( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    std::vector<T, Allocator>& lhs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    std::vector<T, Allocator>& rhs) noexcept(noexcept(lhs.swap(rhs))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ lhs.swap(rhs); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template <typename T, typename Allocator, typename U> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+constexpr typename std::vector<T, Allocator>::size_type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+erase(std::vector<T, Allocator>& vec, const U& value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    typename std::vector<T, Allocator>::size_type n = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (auto iter = vec.begin(); iter != vec.end(); ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (*iter == value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            iter = vec.erase(iter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ++n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ++iter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template <typename T, typename Allocator, typename Pred> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+constexpr typename std::vector<T, Allocator>::size_type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+erase_if(std::vector<T, Allocator>& vec, Pred pred) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    typename std::vector<T, Allocator>::size_type n = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (auto iter = vec.begin(); iter != vec.end(); ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (pred(*iter)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            iter = vec.erase(iter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ++n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ++iter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} // namespace std 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 |