SlideShare a Scribd company logo
STD::VECTOR FROM SCRATCH
Alexey Kutumov
Senior software engineer at Kaspersky Lab
AGENDA
vector interface
vector_base
methods w/o size modifications
reserve
insert
erase
…
Profit!
VECTOR INTERFACE
INTERFACE
template <typename Type, typename Alloc = allocator<Type>>
class vector;
MINIMAL ALLOCATOR INTERFACE
template <typename Type>
struct allocator {
typedef Type value_type;
value_type* allocate(size_t n, const void* /* hint */ = nullptr) {
return (value_type*)(::operator new(n * sizeof(value_type)));
}
void deallocate(value_type* p, size_t n) {
::operator delete(p, n * sizeof(value_type));
}
};
VECTOR TYPES, PART 1
typedef ??? iterator;
typedef ??? const_iterator;
typedef ??? difference_type;
typedef ??? size_type;
VECTOR TYPES, PART 1
typedef Type* iterator;
typedef const Type* const_iterator;
typedef ptrdiff_t difference_type;
typedef size_t size_type;
VECTOR TYPES, PART 2
typedef value_type& reference;
typedef const value_type& const_reference;
typedef Type value_type;
typedef Alloc allocator_type;
typedef typename allocator_traits<Alloc>::pointer pointer;
typedef typename allocator_traits<Alloc>::const_pointer const_pointer;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
ALLOCATOR_TRAITS (TYPES, PART 1)
template <typename Allocator>
struct allocator_traits {
typedef Allocator allocator_type;
typedef typename Allocator::value_type value_type;
typedef ??? pointer;
typedef ??? const_pointer;
typedef ??? size_type;
(difference_type, void_pointer, const_void_pointer)
ALLOCATOR_TRAITS (TYPES, PART 1)
template <typename Allocator>
struct allocator_traits {
typedef Allocator allocator_type;
typedef typename Allocator::value_type value_type;
typedef typename detail::get_pointer<Allocator>::type pointer;
typedef typename detail::get_const_pointer<Allocator>::type const_pointer;
typedef typename detail::get_size_type<Allocator>::type size_type;
GET_POINTER
template <typename Allocator>
struct get_pointer {
template <typename Alloc2>
static auto select_type(int)->typename Alloc2::pointer;
template <typename Alloc2>
static auto select_type(wrap_int)->typename Allocator::value_type*;
typedef decltype(select_type<Allocator>(0)) type;
};
ALLOCATOR_TRAITS (TYPES, PART 2)
template <typename Allocator>
struct allocator_traits {
// ...
typedef ??? propagate_on_container_copy_assignment;
typedef ??? propagate_on_container_move_assignment;
typedef ??? propagate_on_container_swap;
ALLOCATOR_TRAITS (METHODS)
template <typename Alloc>
struct allocator_traits {
static pointer allocate(Alloc& a, size_type n, const void* hint = 0);
static void deallocate(Alloc& a, pointer p, size_type n);
template <typename Type, typename... Args>
static void construct(Alloc& alloc, Type* ptr, Args&&... args);
template <typename Type>
static void destroy(Alloc& alloc, Type* ptr);
static Alloc select_on_container_copy_construction(const Alloc& alloc);
};
STD
allocator<>
iterator_traits<>
ptrdiff_t
make_unsigned<>
declval<>()
allocator_traits<>
pointer_traits<>
false_type, true_type
integral_constant<>
forward<>()
remove_reference<>
reverse_iterator<>
iterator_traits<>
VECTOR_BASE
VECTOR_BASE
template <typename Type, typename Allocator>
struct vector_base: private Allocator {
iterator m_first;
iterator m_last;
iterator m_endOfCapacity;
vector_base();
vector_base(const Allocator& alloc);
vector_base(vector_base&& other);
vector_base(vector_base&& other, const Allocator& alloc);
vector_base& operator=(vector_base&& other);
vector_base& operator=(const vector_base& other);
~vector_base();
VECTOR_BASE
vector_base() : vector_base(Allocator()) {}
vector_base(const Allocator& alloc) : Allocator(alloc) {
tidy(*this);
}
vector_base(vector_base&& other)
: Allocator(std::move(static_cast<Allocator&&>(other))) {
swap_base(*this, static_cast<vector_base&>(other));
tidy(other);
}
vector_base(vector_base&& other, const Allocator& alloc) : Allocator(alloc) {
swap_base(*this, static_cast<vector_base&>(other));
tidy(other);
}
VECTOR_BASE
vector_base& operator=(vector_base&& other) {
destroy_and_free(m_first, m_last, m_endOfCapacity, allocator_from(*this));
propagate_on_move_assignment(static_cast<Allocator&&>(other));
swap_base(*this, static_cast<vector_base&>(other));
tidy(other);
return *this;
}
vector_base& operator=(const vector_base& other) {
propagate_on_copy_assignment(static_cast<const Allocator&>(other));
return *this;
}
VECTOR_BASE
void propagate_on_move_assignment(Allocator&& other) {
typedef vector_allocator_traits::propagate_on_container_move_assignment tag;
propagate_on_move_assignment(forward<Allocator>(other), tag());
}
void propagate_on_move_assignment(Allocator&& other, true_type) {
static_cast<Allocator&>(*this) = std::move(other);
}
void propagate_on_move_assignment(Allocator&& /* other */, false_type) {
// does nothing
}
UNINITIALIZED_*
template<typename FwdIt, typename Alloc, typename ... Args>
void uninitialized_construct_a(FwdIt f, FwdIt l, Alloc& a, Args&&... args);
template<typename InputIt, typename FwdIt, typename Alloc>
FwdIt uninitialized_copy_a(InputIt first, InputIt last, FwdIt dest, Alloc& a);
template<typename Type, typename Size, typename FwdIt, typename Alloc>
FwdIt uninitialized_fill_n_a(FwdIt dest, Size n, const Type& v, Alloc& a);
UNINITIALIZED_CONSTRUCT
template<typename FwdIt, typename Alloc, typename ... Args>
void uninitialized_construct_a(FwdIt f, FwdIt l, Alloc& a, Args&&... args) {
FwdIt c = f;
try {
for (; c != l; ++c) {
allocator_traits<Alloc>::construct(a, addressof(*c), forward<Args>(args)...);
}
}
catch (...) {
destroy_range(first, c, alloc);
throw;
}
}
STD
move()
swap()
addressof()
enable_if<>
is_function<>
uninitialized_fill_n()
uninitialized_copy()
METHODS WITHOUT SIZE MODIFICATIONS
METHODS WITHOUT SIZE MODIFICATIONS
allocator_type get_allocator() const;
*reference at(size_type pos) *;
*reference operator[](size_type pos) *;
*reference front() *;
*reference back() *;
*pointer data() *;
*iterator *begin() *;
*iterator *end() *;
size_type size() const;
size_type capacity() const;
size_type max_size() const;
bool empty() const;
RESERVE
RESERVE
void reserve(size_type newCapacity) {
if (newCapacity > max_size()) {
throw std::length_error("");
}
if (newCapacity > capacity()) {
iterator newFirst = alloc(allocator_from(*this), newCapacity);
try {
relocate(newFirst, newCapacity);
} catch (...) {
dealloc(allocator_from(*this), newFirst, newCapacity);
throw;
}
}
}
RELOCATE
void relocate(iterator newFirst, size_type newCapacity) {
iterator newLast = detail::uninitialized_copy_a(
make_move_iterator(m_first),
make_move_iterator(m_last),
newFirst,
allocator_from(*this));
destroy_and_free(m_first, m_last, m_endOfCapacity, allocator_from(*this));
m_first = newFirst;
m_last = newLast;
m_endOfCapacity = m_first + newCapacity;
}
MOVE_ITERATOR
template <typename Iterator>
class move_iterator {
Iterator m_current;
public:
typedef value_type&& reference;
reference operator*() const {
return std::move(*m_current);
}
STD
length_error
logic_error
basic_string<>
logic_error
basic_string<>
...
exception
make_move_iterator()
move_iterator<>
INSERT
INSERT
iterator insert(const_iterator pos, const Type& value);
iterator insert(const_iterator pos, Type&& value);
iterator insert(const_iterator pos, size_type count, const Type& value);
template <typename InputIterator>
typename enable_if<is_iterator<InputIterator>::value, iterator>::type
insert(const_iterator pos, InputIterator first, InputIterator last);
iterator insert(const_iterator pos, std::initializer_list<Type> ilist);
INSERT
iterator insert(const_iterator pos, const Type& value) {
return insert_with_perfect_fwd(pos, value);
}
iterator insert(const_iterator pos, Type&& value) {
return insert_with_perfect_fwd(pos, std::forward<Type>(value));
}
iterator insert(const_iterator pos, std::initializer_list<Type> ilist) {
return insert_range(pos, ilist.begin(), ilist.end());
}
iterator insert(const_iterator pos, size_type count, const Type& value) {
return insert_range(pos, make_iterator(count, value), make_iterator());
}
COUNTING_ITERATOR
template <typename Type>
struct counting_iterator {
size_t m_count;
Type* m_value;
counting_iterator& operator++() {
--m_count;
return *this;
}
reference operator*() {
return *m_value;
}
};
INSERT_WITH_PERFECT_FWD
template <typename... Args>
iterator insert_with_perfect_fwd(const_iterator pos, Args&&... a) {
difference_type offset = pos - cbegin();
grow(size() + 1);
uninitialized_construct_a(m_last, m_last + 1, alloc(*this), forward<Args>(a)...);
m_last += 1;
rotate(m_first + offset, m_last - 1, m_last);
return m_first + offset;
}
ROTATE
first new_first last
INSERT_RANGE
template <typename InputIterator>
insert_range(const_iterator pos, InputIterator first, InputIterator last) {
difference_type offset = pos - cbegin();
difference_type count = std::distance(first, last);
grow(size() + count);
detail::uninitialized_copy_a(first, last, m_last, allocator_from(*this));
m_last += count;
rotate(m_first + offset, m_last - count, m_last);
return m_first + offset;
}
STD
rotate()
iter_swap()
distance()
is_base_of<>
ERASE
ERASE
iterator erase(const_iterator pos) {
return erase(pos, pos + 1);
}
iterator erase(const_iterator first, const_iterator last) {
iterator newLast = rotate(cast_from_const(first), cast_from_const(last), m_last);
detail::destroy_range(newLast, m_last, allocator_from(*this));
m_last = newLast;
return cast_from_const(first);
}
OTHER METHODS
OTHER METHODS
void assign(size_type count, const Type& value) {
erase(m_first, m_last);
resize(count, value);
}
template <typename... Args>
iterator emplace(const_iterator pos, Args&&... args) {
return insert_with_perfect_fwd(pos, std::forward<Args>(args)...);
}
void push_back(const value_type& value) {
insert_with_perfect_fwd(end(), value);
}
CLOC
---------------------------------------------------------------------------
Language files blank comment code
---------------------------------------------------------------------------
C/C++ Header 20 428 33 1449
C++ 3 271 8 995
---------------------------------------------------------------------------
SUM: 23 699 41 2444
---------------------------------------------------------------------------
LET'S TALK?
alexey.kutumov@gmail.com
https://github.com/prograholic/simple_vector

More Related Content

What's hot

Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The Landing
Haci Murat Yaman
 
Welcome to Modern C++
Welcome to Modern C++Welcome to Modern C++
Welcome to Modern C++
Seok-joon Yun
 
Joel Falcou, Boost.SIMD
Joel Falcou, Boost.SIMDJoel Falcou, Boost.SIMD
Joel Falcou, Boost.SIMD
Sergey Platonov
 
Apache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheelApache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheel
tcurdt
 
Pro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptPro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScript
Seok-joon Yun
 
Qt Rest Server
Qt Rest ServerQt Rest Server
Qt Rest Server
Vasiliy Sorokin
 
Smart pointers
Smart pointersSmart pointers
Smart pointers
Vishal Mahajan
 
C++ L08-Classes Part1
C++ L08-Classes Part1C++ L08-Classes Part1
C++ L08-Classes Part1
Mohammad Shaker
 
Антон Бикинеев, Reflection in C++Next
Антон Бикинеев,  Reflection in C++NextАнтон Бикинеев,  Reflection in C++Next
Антон Бикинеев, Reflection in C++Next
Sergey Platonov
 
Vulkan 1.1 Reference Guide
Vulkan 1.1 Reference GuideVulkan 1.1 Reference Guide
Vulkan 1.1 Reference Guide
The Khronos Group Inc.
 
OpenGL SC 2.0 Quick Reference
OpenGL SC 2.0 Quick ReferenceOpenGL SC 2.0 Quick Reference
OpenGL SC 2.0 Quick Reference
The Khronos Group Inc.
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Sergey Platonov
 
Дмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репортДмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репорт
Sergey Platonov
 
Dynamic C++ ACCU 2013
Dynamic C++ ACCU 2013Dynamic C++ ACCU 2013
Dynamic C++ ACCU 2013
aleks-f
 
C++20 the small things - Timur Doumler
C++20 the small things - Timur DoumlerC++20 the small things - Timur Doumler
C++20 the small things - Timur Doumler
corehard_by
 
OpenXR 1.0 Reference Guide
OpenXR 1.0 Reference GuideOpenXR 1.0 Reference Guide
OpenXR 1.0 Reference Guide
The Khronos Group Inc.
 
Vulkan 1.0 Quick Reference
Vulkan 1.0 Quick ReferenceVulkan 1.0 Quick Reference
Vulkan 1.0 Quick Reference
The Khronos Group Inc.
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
Andrey Karpov
 

What's hot (20)

Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The Landing
 
Welcome to Modern C++
Welcome to Modern C++Welcome to Modern C++
Welcome to Modern C++
 
Joel Falcou, Boost.SIMD
Joel Falcou, Boost.SIMDJoel Falcou, Boost.SIMD
Joel Falcou, Boost.SIMD
 
Apache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheelApache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheel
 
Pro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptPro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScript
 
Qt Rest Server
Qt Rest ServerQt Rest Server
Qt Rest Server
 
Smart pointers
Smart pointersSmart pointers
Smart pointers
 
C++ L08-Classes Part1
C++ L08-Classes Part1C++ L08-Classes Part1
C++ L08-Classes Part1
 
C++ aptitude
C++ aptitudeC++ aptitude
C++ aptitude
 
Антон Бикинеев, Reflection in C++Next
Антон Бикинеев,  Reflection in C++NextАнтон Бикинеев,  Reflection in C++Next
Антон Бикинеев, Reflection in C++Next
 
Vulkan 1.1 Reference Guide
Vulkan 1.1 Reference GuideVulkan 1.1 Reference Guide
Vulkan 1.1 Reference Guide
 
Constructor,destructors cpp
Constructor,destructors cppConstructor,destructors cpp
Constructor,destructors cpp
 
OpenGL SC 2.0 Quick Reference
OpenGL SC 2.0 Quick ReferenceOpenGL SC 2.0 Quick Reference
OpenGL SC 2.0 Quick Reference
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
 
Дмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репортДмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репорт
 
Dynamic C++ ACCU 2013
Dynamic C++ ACCU 2013Dynamic C++ ACCU 2013
Dynamic C++ ACCU 2013
 
C++20 the small things - Timur Doumler
C++20 the small things - Timur DoumlerC++20 the small things - Timur Doumler
C++20 the small things - Timur Doumler
 
OpenXR 1.0 Reference Guide
OpenXR 1.0 Reference GuideOpenXR 1.0 Reference Guide
OpenXR 1.0 Reference Guide
 
Vulkan 1.0 Quick Reference
Vulkan 1.0 Quick ReferenceVulkan 1.0 Quick Reference
Vulkan 1.0 Quick Reference
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 

Viewers also liked

Дмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеДмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Sergey Platonov
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
Sergey Platonov
 
Pointers & References in C++
Pointers & References in C++Pointers & References in C++
Pointers & References in C++
Ilio Catallo
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
Sergey Platonov
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
victor-yastrebov
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Sergey Platonov
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Platonov Sergey
 
Parallel STL
Parallel STLParallel STL
Parallel STL
Evgeny Krutko
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Sergey Platonov
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
Roman Orlov
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3
Platonov Sergey
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Yauheni Akhotnikau
 
Фитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в формеФитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в форме
Ilia Shishkov
 
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines
Sergey Zubkov
 
Quality assurance of large c++ projects
Quality assurance of large c++ projectsQuality assurance of large c++ projects
Quality assurance of large c++ projects
corehard_by
 
HexRaysCodeXplorer: object oriented RE for fun and profit
HexRaysCodeXplorer: object oriented RE for fun and profitHexRaysCodeXplorer: object oriented RE for fun and profit
HexRaysCodeXplorer: object oriented RE for fun and profit
Alex Matrosov
 
C++: inheritance, composition, polymorphism
C++: inheritance, composition, polymorphismC++: inheritance, composition, polymorphism
C++: inheritance, composition, polymorphismJussi Pohjolainen
 
Fuzzing: The New Unit Testing
Fuzzing: The New Unit TestingFuzzing: The New Unit Testing
Fuzzing: The New Unit Testing
Dmitry Vyukov
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Mikhail Matrosov
 
Василий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексиейВасилий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексией
Sergey Platonov
 

Viewers also liked (20)

Дмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеДмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI веке
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
Pointers & References in C++
Pointers & References in C++Pointers & References in C++
Pointers & References in C++
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
 
Фитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в формеФитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в форме
 
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines
 
Quality assurance of large c++ projects
Quality assurance of large c++ projectsQuality assurance of large c++ projects
Quality assurance of large c++ projects
 
HexRaysCodeXplorer: object oriented RE for fun and profit
HexRaysCodeXplorer: object oriented RE for fun and profitHexRaysCodeXplorer: object oriented RE for fun and profit
HexRaysCodeXplorer: object oriented RE for fun and profit
 
C++: inheritance, composition, polymorphism
C++: inheritance, composition, polymorphismC++: inheritance, composition, polymorphism
C++: inheritance, composition, polymorphism
 
Fuzzing: The New Unit Testing
Fuzzing: The New Unit TestingFuzzing: The New Unit Testing
Fuzzing: The New Unit Testing
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
 
Василий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексиейВасилий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексией
 

Similar to Алексей Кутумов, Вектор с нуля

include ltfunctionalgt include ltiteratorgt inclu.pdf
include ltfunctionalgt include ltiteratorgt inclu.pdfinclude ltfunctionalgt include ltiteratorgt inclu.pdf
include ltfunctionalgt include ltiteratorgt inclu.pdf
naslin841216
 
C++ extension methods
C++ extension methodsC++ extension methods
C++ extension methods
phil_nash
 
Javascripting.pptx
Javascripting.pptxJavascripting.pptx
Javascripting.pptx
Vinod Srivastava
 
include ltfunctionalgt include ltiteratorgt inclu.pdf
include ltfunctionalgt include ltiteratorgt inclu.pdfinclude ltfunctionalgt include ltiteratorgt inclu.pdf
include ltfunctionalgt include ltiteratorgt inclu.pdf
aathmiboutique
 
C++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptxC++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptx
ShashiShash2
 
C++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptxC++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptx
Abubakar524802
 
Need help with the TODO's (DONE IN C++) #pragma once #include -funct.pdf
Need help with the TODO's (DONE IN C++) #pragma once   #include -funct.pdfNeed help with the TODO's (DONE IN C++) #pragma once   #include -funct.pdf
Need help with the TODO's (DONE IN C++) #pragma once #include -funct.pdf
actexerode
 
C++ code, please help! RESPOND W COMPLETED CODE PLEASE, am using V.pdf
C++ code, please help! RESPOND W COMPLETED CODE PLEASE,  am using V.pdfC++ code, please help! RESPOND W COMPLETED CODE PLEASE,  am using V.pdf
C++ code, please help! RESPOND W COMPLETED CODE PLEASE, am using V.pdf
rahulfancycorner21
 
Generic Types in Java (for ArtClub @ArtBrains Software)
Generic Types in Java (for ArtClub @ArtBrains Software)Generic Types in Java (for ArtClub @ArtBrains Software)
Generic Types in Java (for ArtClub @ArtBrains Software)
Andrew Petryk
 
C++ code, please help! Troubleshooting and cannot for the life of me.pdf
C++ code, please help! Troubleshooting and cannot for the life of me.pdfC++ code, please help! Troubleshooting and cannot for the life of me.pdf
C++ code, please help! Troubleshooting and cannot for the life of me.pdf
rahulfancycorner21
 
Domänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit XtextDomänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit Xtext
Dr. Jan Köhnlein
 
Intro to C# - part 2.pptx emerging technology
Intro to C# - part 2.pptx emerging technologyIntro to C# - part 2.pptx emerging technology
Intro to C# - part 2.pptx emerging technology
worldchannel
 
Please code in C++ and do only the �TO DO�s and all of them. There a.pdf
Please code in C++ and do only the �TO DO�s and all of them. There a.pdfPlease code in C++ and do only the �TO DO�s and all of them. There a.pdf
Please code in C++ and do only the �TO DO�s and all of them. There a.pdf
farankureshi
 
The STL
The STLThe STL
The STL
adil raja
 
c++ pointers by Amir Hamza Khan (SZABISTIAN)
c++ pointers by Amir Hamza Khan (SZABISTIAN)c++ pointers by Amir Hamza Khan (SZABISTIAN)
c++ pointers by Amir Hamza Khan (SZABISTIAN)
Ameer Hamxa
 
Introduction to Client-Side Javascript
Introduction to Client-Side JavascriptIntroduction to Client-Side Javascript
Introduction to Client-Side Javascript
Julie Iskander
 
李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义yiditushe
 
Please complete ALL of the �TO DO�s in this code. I am really strugg.pdf
Please complete ALL of the �TO DO�s in this code. I am really strugg.pdfPlease complete ALL of the �TO DO�s in this code. I am really strugg.pdf
Please complete ALL of the �TO DO�s in this code. I am really strugg.pdf
support58
 
C++11 - STL Additions
C++11 - STL AdditionsC++11 - STL Additions
C++11 - STL Additions
GlobalLogic Ukraine
 
2.overview of c++ ________lecture2
2.overview of c++  ________lecture22.overview of c++  ________lecture2
2.overview of c++ ________lecture2
Warui Maina
 

Similar to Алексей Кутумов, Вектор с нуля (20)

include ltfunctionalgt include ltiteratorgt inclu.pdf
include ltfunctionalgt include ltiteratorgt inclu.pdfinclude ltfunctionalgt include ltiteratorgt inclu.pdf
include ltfunctionalgt include ltiteratorgt inclu.pdf
 
C++ extension methods
C++ extension methodsC++ extension methods
C++ extension methods
 
Javascripting.pptx
Javascripting.pptxJavascripting.pptx
Javascripting.pptx
 
include ltfunctionalgt include ltiteratorgt inclu.pdf
include ltfunctionalgt include ltiteratorgt inclu.pdfinclude ltfunctionalgt include ltiteratorgt inclu.pdf
include ltfunctionalgt include ltiteratorgt inclu.pdf
 
C++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptxC++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptx
 
C++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptxC++ FUNCTIONS-1.pptx
C++ FUNCTIONS-1.pptx
 
Need help with the TODO's (DONE IN C++) #pragma once #include -funct.pdf
Need help with the TODO's (DONE IN C++) #pragma once   #include -funct.pdfNeed help with the TODO's (DONE IN C++) #pragma once   #include -funct.pdf
Need help with the TODO's (DONE IN C++) #pragma once #include -funct.pdf
 
C++ code, please help! RESPOND W COMPLETED CODE PLEASE, am using V.pdf
C++ code, please help! RESPOND W COMPLETED CODE PLEASE,  am using V.pdfC++ code, please help! RESPOND W COMPLETED CODE PLEASE,  am using V.pdf
C++ code, please help! RESPOND W COMPLETED CODE PLEASE, am using V.pdf
 
Generic Types in Java (for ArtClub @ArtBrains Software)
Generic Types in Java (for ArtClub @ArtBrains Software)Generic Types in Java (for ArtClub @ArtBrains Software)
Generic Types in Java (for ArtClub @ArtBrains Software)
 
C++ code, please help! Troubleshooting and cannot for the life of me.pdf
C++ code, please help! Troubleshooting and cannot for the life of me.pdfC++ code, please help! Troubleshooting and cannot for the life of me.pdf
C++ code, please help! Troubleshooting and cannot for the life of me.pdf
 
Domänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit XtextDomänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit Xtext
 
Intro to C# - part 2.pptx emerging technology
Intro to C# - part 2.pptx emerging technologyIntro to C# - part 2.pptx emerging technology
Intro to C# - part 2.pptx emerging technology
 
Please code in C++ and do only the �TO DO�s and all of them. There a.pdf
Please code in C++ and do only the �TO DO�s and all of them. There a.pdfPlease code in C++ and do only the �TO DO�s and all of them. There a.pdf
Please code in C++ and do only the �TO DO�s and all of them. There a.pdf
 
The STL
The STLThe STL
The STL
 
c++ pointers by Amir Hamza Khan (SZABISTIAN)
c++ pointers by Amir Hamza Khan (SZABISTIAN)c++ pointers by Amir Hamza Khan (SZABISTIAN)
c++ pointers by Amir Hamza Khan (SZABISTIAN)
 
Introduction to Client-Side Javascript
Introduction to Client-Side JavascriptIntroduction to Client-Side Javascript
Introduction to Client-Side Javascript
 
李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义
 
Please complete ALL of the �TO DO�s in this code. I am really strugg.pdf
Please complete ALL of the �TO DO�s in this code. I am really strugg.pdfPlease complete ALL of the �TO DO�s in this code. I am really strugg.pdf
Please complete ALL of the �TO DO�s in this code. I am really strugg.pdf
 
C++11 - STL Additions
C++11 - STL AdditionsC++11 - STL Additions
C++11 - STL Additions
 
2.overview of c++ ________lecture2
2.overview of c++  ________lecture22.overview of c++  ________lecture2
2.overview of c++ ________lecture2
 

More from Sergey Platonov

Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного багаЛев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
Sergey Platonov
 
Павел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.ioПавел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.io
Sergey Platonov
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Sergey Platonov
 
Антон Полухин. C++17
Антон Полухин. C++17Антон Полухин. C++17
Антон Полухин. C++17
Sergey Platonov
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
Sergey Platonov
 
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на QtДенис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Sergey Platonov
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Sergey Platonov
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладка
Sergey Platonov
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Sergey Platonov
 
Dori Exterman, Considerations for choosing the parallel computing strategy th...
Dori Exterman, Considerations for choosing the parallel computing strategy th...Dori Exterman, Considerations for choosing the parallel computing strategy th...
Dori Exterman, Considerations for choosing the parallel computing strategy th...
Sergey Platonov
 
Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++
Sergey Platonov
 
Михаил Матросов, Повседневный С++: boost и STL
Михаил Матросов, Повседневный С++: boost и STLМихаил Матросов, Повседневный С++: boost и STL
Михаил Матросов, Повседневный С++: boost и STL
Sergey Platonov
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
Sergey Platonov
 
Илья Шишков, Принципы создания тестируемого кода
Илья Шишков, Принципы создания тестируемого кодаИлья Шишков, Принципы создания тестируемого кода
Илья Шишков, Принципы создания тестируемого кода
Sergey Platonov
 
Антон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствамиАнтон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствами
Sergey Platonov
 
Андрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кодаАндрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кода
Sergey Platonov
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Sergey Platonov
 

More from Sergey Platonov (17)

Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного багаЛев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
 
Павел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.ioПавел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.io
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
 
Антон Полухин. C++17
Антон Полухин. C++17Антон Полухин. C++17
Антон Полухин. C++17
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
 
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на QtДенис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладка
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
 
Dori Exterman, Considerations for choosing the parallel computing strategy th...
Dori Exterman, Considerations for choosing the parallel computing strategy th...Dori Exterman, Considerations for choosing the parallel computing strategy th...
Dori Exterman, Considerations for choosing the parallel computing strategy th...
 
Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++
 
Михаил Матросов, Повседневный С++: boost и STL
Михаил Матросов, Повседневный С++: boost и STLМихаил Матросов, Повседневный С++: boost и STL
Михаил Матросов, Повседневный С++: boost и STL
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
 
Илья Шишков, Принципы создания тестируемого кода
Илья Шишков, Принципы создания тестируемого кодаИлья Шишков, Принципы создания тестируемого кода
Илья Шишков, Принципы создания тестируемого кода
 
Антон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствамиАнтон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствами
 
Андрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кодаАндрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кода
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 

Recently uploaded

Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
Roshan Dwivedi
 

Recently uploaded (20)

Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
 

Алексей Кутумов, Вектор с нуля

  • 1. STD::VECTOR FROM SCRATCH Alexey Kutumov Senior software engineer at Kaspersky Lab
  • 2. AGENDA vector interface vector_base methods w/o size modifications reserve insert erase … Profit!
  • 4. INTERFACE template <typename Type, typename Alloc = allocator<Type>> class vector;
  • 5. MINIMAL ALLOCATOR INTERFACE template <typename Type> struct allocator { typedef Type value_type; value_type* allocate(size_t n, const void* /* hint */ = nullptr) { return (value_type*)(::operator new(n * sizeof(value_type))); } void deallocate(value_type* p, size_t n) { ::operator delete(p, n * sizeof(value_type)); } };
  • 6. VECTOR TYPES, PART 1 typedef ??? iterator; typedef ??? const_iterator; typedef ??? difference_type; typedef ??? size_type;
  • 7. VECTOR TYPES, PART 1 typedef Type* iterator; typedef const Type* const_iterator; typedef ptrdiff_t difference_type; typedef size_t size_type;
  • 8. VECTOR TYPES, PART 2 typedef value_type& reference; typedef const value_type& const_reference; typedef Type value_type; typedef Alloc allocator_type; typedef typename allocator_traits<Alloc>::pointer pointer; typedef typename allocator_traits<Alloc>::const_pointer const_pointer; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  • 9. ALLOCATOR_TRAITS (TYPES, PART 1) template <typename Allocator> struct allocator_traits { typedef Allocator allocator_type; typedef typename Allocator::value_type value_type; typedef ??? pointer; typedef ??? const_pointer; typedef ??? size_type; (difference_type, void_pointer, const_void_pointer)
  • 10. ALLOCATOR_TRAITS (TYPES, PART 1) template <typename Allocator> struct allocator_traits { typedef Allocator allocator_type; typedef typename Allocator::value_type value_type; typedef typename detail::get_pointer<Allocator>::type pointer; typedef typename detail::get_const_pointer<Allocator>::type const_pointer; typedef typename detail::get_size_type<Allocator>::type size_type;
  • 11. GET_POINTER template <typename Allocator> struct get_pointer { template <typename Alloc2> static auto select_type(int)->typename Alloc2::pointer; template <typename Alloc2> static auto select_type(wrap_int)->typename Allocator::value_type*; typedef decltype(select_type<Allocator>(0)) type; };
  • 12. ALLOCATOR_TRAITS (TYPES, PART 2) template <typename Allocator> struct allocator_traits { // ... typedef ??? propagate_on_container_copy_assignment; typedef ??? propagate_on_container_move_assignment; typedef ??? propagate_on_container_swap;
  • 13. ALLOCATOR_TRAITS (METHODS) template <typename Alloc> struct allocator_traits { static pointer allocate(Alloc& a, size_type n, const void* hint = 0); static void deallocate(Alloc& a, pointer p, size_type n); template <typename Type, typename... Args> static void construct(Alloc& alloc, Type* ptr, Args&&... args); template <typename Type> static void destroy(Alloc& alloc, Type* ptr); static Alloc select_on_container_copy_construction(const Alloc& alloc); };
  • 16. VECTOR_BASE template <typename Type, typename Allocator> struct vector_base: private Allocator { iterator m_first; iterator m_last; iterator m_endOfCapacity; vector_base(); vector_base(const Allocator& alloc); vector_base(vector_base&& other); vector_base(vector_base&& other, const Allocator& alloc); vector_base& operator=(vector_base&& other); vector_base& operator=(const vector_base& other); ~vector_base();
  • 17. VECTOR_BASE vector_base() : vector_base(Allocator()) {} vector_base(const Allocator& alloc) : Allocator(alloc) { tidy(*this); } vector_base(vector_base&& other) : Allocator(std::move(static_cast<Allocator&&>(other))) { swap_base(*this, static_cast<vector_base&>(other)); tidy(other); } vector_base(vector_base&& other, const Allocator& alloc) : Allocator(alloc) { swap_base(*this, static_cast<vector_base&>(other)); tidy(other); }
  • 18. VECTOR_BASE vector_base& operator=(vector_base&& other) { destroy_and_free(m_first, m_last, m_endOfCapacity, allocator_from(*this)); propagate_on_move_assignment(static_cast<Allocator&&>(other)); swap_base(*this, static_cast<vector_base&>(other)); tidy(other); return *this; } vector_base& operator=(const vector_base& other) { propagate_on_copy_assignment(static_cast<const Allocator&>(other)); return *this; }
  • 19. VECTOR_BASE void propagate_on_move_assignment(Allocator&& other) { typedef vector_allocator_traits::propagate_on_container_move_assignment tag; propagate_on_move_assignment(forward<Allocator>(other), tag()); } void propagate_on_move_assignment(Allocator&& other, true_type) { static_cast<Allocator&>(*this) = std::move(other); } void propagate_on_move_assignment(Allocator&& /* other */, false_type) { // does nothing }
  • 20. UNINITIALIZED_* template<typename FwdIt, typename Alloc, typename ... Args> void uninitialized_construct_a(FwdIt f, FwdIt l, Alloc& a, Args&&... args); template<typename InputIt, typename FwdIt, typename Alloc> FwdIt uninitialized_copy_a(InputIt first, InputIt last, FwdIt dest, Alloc& a); template<typename Type, typename Size, typename FwdIt, typename Alloc> FwdIt uninitialized_fill_n_a(FwdIt dest, Size n, const Type& v, Alloc& a);
  • 21. UNINITIALIZED_CONSTRUCT template<typename FwdIt, typename Alloc, typename ... Args> void uninitialized_construct_a(FwdIt f, FwdIt l, Alloc& a, Args&&... args) { FwdIt c = f; try { for (; c != l; ++c) { allocator_traits<Alloc>::construct(a, addressof(*c), forward<Args>(args)...); } } catch (...) { destroy_range(first, c, alloc); throw; } }
  • 23. METHODS WITHOUT SIZE MODIFICATIONS
  • 24. METHODS WITHOUT SIZE MODIFICATIONS allocator_type get_allocator() const; *reference at(size_type pos) *; *reference operator[](size_type pos) *; *reference front() *; *reference back() *; *pointer data() *; *iterator *begin() *; *iterator *end() *; size_type size() const; size_type capacity() const; size_type max_size() const; bool empty() const;
  • 26. RESERVE void reserve(size_type newCapacity) { if (newCapacity > max_size()) { throw std::length_error(""); } if (newCapacity > capacity()) { iterator newFirst = alloc(allocator_from(*this), newCapacity); try { relocate(newFirst, newCapacity); } catch (...) { dealloc(allocator_from(*this), newFirst, newCapacity); throw; } } }
  • 27. RELOCATE void relocate(iterator newFirst, size_type newCapacity) { iterator newLast = detail::uninitialized_copy_a( make_move_iterator(m_first), make_move_iterator(m_last), newFirst, allocator_from(*this)); destroy_and_free(m_first, m_last, m_endOfCapacity, allocator_from(*this)); m_first = newFirst; m_last = newLast; m_endOfCapacity = m_first + newCapacity; }
  • 28. MOVE_ITERATOR template <typename Iterator> class move_iterator { Iterator m_current; public: typedef value_type&& reference; reference operator*() const { return std::move(*m_current); }
  • 31. INSERT iterator insert(const_iterator pos, const Type& value); iterator insert(const_iterator pos, Type&& value); iterator insert(const_iterator pos, size_type count, const Type& value); template <typename InputIterator> typename enable_if<is_iterator<InputIterator>::value, iterator>::type insert(const_iterator pos, InputIterator first, InputIterator last); iterator insert(const_iterator pos, std::initializer_list<Type> ilist);
  • 32. INSERT iterator insert(const_iterator pos, const Type& value) { return insert_with_perfect_fwd(pos, value); } iterator insert(const_iterator pos, Type&& value) { return insert_with_perfect_fwd(pos, std::forward<Type>(value)); } iterator insert(const_iterator pos, std::initializer_list<Type> ilist) { return insert_range(pos, ilist.begin(), ilist.end()); } iterator insert(const_iterator pos, size_type count, const Type& value) { return insert_range(pos, make_iterator(count, value), make_iterator()); }
  • 33. COUNTING_ITERATOR template <typename Type> struct counting_iterator { size_t m_count; Type* m_value; counting_iterator& operator++() { --m_count; return *this; } reference operator*() { return *m_value; } };
  • 34. INSERT_WITH_PERFECT_FWD template <typename... Args> iterator insert_with_perfect_fwd(const_iterator pos, Args&&... a) { difference_type offset = pos - cbegin(); grow(size() + 1); uninitialized_construct_a(m_last, m_last + 1, alloc(*this), forward<Args>(a)...); m_last += 1; rotate(m_first + offset, m_last - 1, m_last); return m_first + offset; }
  • 36. INSERT_RANGE template <typename InputIterator> insert_range(const_iterator pos, InputIterator first, InputIterator last) { difference_type offset = pos - cbegin(); difference_type count = std::distance(first, last); grow(size() + count); detail::uninitialized_copy_a(first, last, m_last, allocator_from(*this)); m_last += count; rotate(m_first + offset, m_last - count, m_last); return m_first + offset; }
  • 38. ERASE
  • 39. ERASE iterator erase(const_iterator pos) { return erase(pos, pos + 1); } iterator erase(const_iterator first, const_iterator last) { iterator newLast = rotate(cast_from_const(first), cast_from_const(last), m_last); detail::destroy_range(newLast, m_last, allocator_from(*this)); m_last = newLast; return cast_from_const(first); }
  • 41. OTHER METHODS void assign(size_type count, const Type& value) { erase(m_first, m_last); resize(count, value); } template <typename... Args> iterator emplace(const_iterator pos, Args&&... args) { return insert_with_perfect_fwd(pos, std::forward<Args>(args)...); } void push_back(const value_type& value) { insert_with_perfect_fwd(end(), value); }
  • 42. CLOC --------------------------------------------------------------------------- Language files blank comment code --------------------------------------------------------------------------- C/C++ Header 20 428 33 1449 C++ 3 271 8 995 --------------------------------------------------------------------------- SUM: 23 699 41 2444 ---------------------------------------------------------------------------

Editor's Notes

  1. Добрый день, меня зовут Алексей Кутумов, я являюсь старшим разработчиком в ЛК
  2. План: Что я хочу показать: Представим, что мы разработчики стандартной библиотеки C++, что нам нужно от стандартной библиотеки, чтобы мы смогли реализовать std::vector. В этом докладе мы возьмем только компилятор (я делал с помощью компилятора из MSVS 2015 – cl.exe версии 19). Он довольно хорошо умеет C++11 и, возможно, что-то из C++14. И сами построим свою стандартную библиотеку. Вообще, изначально, я хотел сделать основной целью доклада мысль, что реализовать std::vector – это просто. Но потом я подумал, и понял, что это неинтересно. Ну, во-первых, это действительно просто сделать (как мне кажется), ну а во-вторых, это не совсем интересно. Понятно, что упрощение реализации неизменно ведет к сужению кейсов использования, или ухудшении производительности, ухудшении гарантий и т.д. В конце концов, int* x = new int[10], чем не вектор? Итак, какой у нас план: Сначала мы осмотрим интерфейс нашего вектора – только декларацию, и посмотрим, что-же из стандартной библиотеки нам нужно, чтобы задекларировать интерфейс вектора. Затем, мы будем реализовывать вектор. Придумаем такую штуку как vector_base, поймем, для чего она нужна. После этого, мы пойдем реализовывать вектор потихоньку. Начнем сначала с методов, которые не изменяют размер вектора. Потом реализуем метод reserve, поговорим подробнее о гарантиях, которые он дает, и как мы их достигаем. Потом реализуем метод insert, который вставляет один элемент, поговорим о его гарантиях. Затем реализуем insert с парой итераторов. Затем реализуем insert с n элементами. После этого, реализуем erase с парой итераторов. А после этого, внезапно, реализуем весь остальной функционал вектора.
  3. Вот так выглядит декларация вектора, наверняка все знают, даже наверное наизусть эту декларацию. Итак, давайте я еще раз поясню, я буду показывать какие-то куски кода, потом мы будем разбирать все конструкции, которые в этом куске кода есть, при этом, будут появляться новые куски кода, в общем, вот такая рекурсия. Да, и еще, если не сказано обратное, то по умолчаию считаем, что мы находимся внутри пространства std Итак, тут нам все понятно – два параметра шаблона. Первый параметр – это тип объектов, которые будут храниться в векторе Второй параметр – это аллокатор, он имеет значение по умолчанию – стандартный аллокатор. Итак, мы плавно переходим к обсуждению аллокаторов.
  4. Здесь представлен интерфейс аллокатора, как видно, здесь тоже нет никаких сложностей. От аллокатора требуется совсем немного, суметь выделить и удалить память, ну и кроме этого, объявить тип value_type. Кто нибудь смотрел доклад Александреску про аллокаторы? Поднимите руки. Отлично, тогда следующий вопрос вы пропускаете. Итак, вопрос, кто нибудь знает, зачем изначально были придуманы аллокаторы? Изначально аллокаторы были придуманы Александром Степановым для того чтобы контейнеры не зависели от модели памяти (если кто знает, то в 16-битном режиме есть разные типы указателей, near pointer, far pointer). Как раз аллокаторы абстрагировали это знание предоставлением нужного типа указателей и механизма аллокации и деаллокации памяти. В С++11 ввели понятие minimal allocator interface, теперь от аллокатора требуется совсем немного обязательных вещей: Объявить value_type – тип объектов, которые аллоцируются этим аллокатором. Объявить функции allocate и deallocate для управления памятью. Итак, с аллокатором тоже все понятно. В принципе, мы можем даже предоставить реализацию этого аллокатора
  5. Снова возвращаемся к вектору. Итак, давайте поговорим про типы, которые вектор предоставляет клиентам. Я опустил заголовок класса и разбил декларации типов на два слайда. Итак, на этом слайде представлены типы, которые отдаются на откуп реализации. Давайте вспомним, какие требования стандарт предъявляет к этим типам? Давайте сначала поговорим про difference_type и size_type Какие требования стандарт предъявляет к двум следующим типам? difference_type – это должен быть тем же самым типом что и тип, значение которого возвращается при вычислении разницы двух итераторов. size_type – это тип, который может представить любое неотрицательное число типа difference_type Кто знает, какие требования к типу итератора предъявляет стандарт? Итератор должен удовлетворять модели (или концепту) RandomAccessIterator. Что самое простое подходит – обычный указатель, его и возьмем.
  6. Итого, для этих типов, мы выбираем самую простую реализацию, которая удовлетворяет всем требованиям. В принципе, нас эта полностью устраивает.
  7. Теперь, что касается остальных типов. С одной стороны все проще, в стандарте явно прописано, что эти типы должны быть такими, как указано на этом слайде. Я уверен, многие из вас знакомы с std::reverse_iterator, поднимите руки, кто знает что такое reverse_iterator? Отлично, тогда, я думаю, нет смысла подробно объяснять что это такое – это адаптер, который сам является итератором – он определяет операции инкремента, декремента, сравнения и т.д. Но при этом, операции инкремента и декремента работают противоположным образом по сравнению с базовым итератором – в обратную сторону.
  8. Мы же подробно поговорим про allocator_traits. allocator_traits – относительно новая сущность, которая появилась в стандарте C++11. Что она из себя представляет, как и любые traits она позволяет получать и использовать различные свойства аллокаторов – определяемые типы, вызывать методы аллокатора и пр. единым способом. Давайте посмотрим на интерфейс, сначала типы, причем типы мы тоже разделим на несколько частей. Сюда же относятся и типы difference_type, void_pointer и const_void_pointer, но я не стал их указывать, так как места на слайдах не очень много, но мы про них помним. Итак, что нам говорит стандарт – первые два типа – тут все понятно, откуда взять остальные типы? У кого есть какие идеи? На самом деле стандарт говорит следующее – если тип Allocator предоставляет нужный тип, то нужно взять его, иначе нужно взять другой тип, причем для каждого типа стандарт говорит что нужно брать. Вот давайте разберем pointer – про него стандарт говорит следующее. Если Allocator предоставляет такой тип, то взять его. Если нет, то нужно взять указатель на Allocator::value_type. Ну вот, давайте разберем, как это можно реализовать на примере pointer
  9. Вообще, что касается работы с типами на этапе компиляции, то 90% случаев – это SFINAE, остальные 10% это полный перебор типов, перегрузка и пр. Собственно, в приведенном примере я так и реализовал с помощью detail::get_pointer. Давайте на него посмотрим
  10. Вот так реализован шаблон get_pointer, который выбирает нужный тип в зависимости от наличия типа pointer. Здесь приведены декларации двух шаблонных статических методов deduce_type. Первый метод принимает на вход int и возвращает Alloc2::pointer. Второй метод принимает на вход нечто по имени wrap_int и возвращает другой тип – указатель на value_type. Ну и в самом низу мы декларируем тип type на основе типа возвращаемого фукнцией select_type Итак, осталась пара вопросов, почему вторая функция select_type принимает на вход аргумент типа wrap_int и что это за аргумент? Ну здесь на самом деле все просто, wrap_int – это структура, у которой объявлен один единственный конструктор, принимающий на вход int. Для чего это сделано – для того чтобы управлять процессом выбора перегруженной функции, в случае если обе функции подходят. Смотрите, если наш Allocator предоставляет тип pointer, то первая функция будет определена, точно также будет определена и вторая функция. Более того, вторая функция всегда будет определена, потому что тип value_type* всегда определен – стандарт требует наличие value_type. Таким образом компилятор встает перед нелегким выбором, ему нужно выбрать одну из функций, вот он и выбирает ту, у которой входной аргумент получается явно, без неявных конверсий (и вызовов конструкторов). Кстати, может кто нибудь сказать, как еще можно управлять процессом выбора перегруженной функции? Ну можно вместо wrap_int воткнуть … - эллипсис. Но мы использовали wrap_int, потому что он нам пригодится в еще одном месте, там где эллипсис использовать нельзя.
  11. Но это еще не все типы, которые нам интересны, стандарт C++11 привносит еще три типа. propagate_on_container_*. Кто нибудь знает, для чего эти типы нужны? Эти три типа определяют поведение контейнеров при вызове оператора копирующего присваивания, при вызове оператора перемещающего присваивания, и при вызове метода swap. Собственно, механизм определения этих типов точно такой же как и остальных типов allocator_traits, SFINAE магия решает. Этиы типы могут принимать значения либо true_type либо false_type Теперь, давайте разберем. Допустим propagate == true_type, тогда аллокатор участвует в операции. Это может быть нужно, если аллокатор имеет состояние (например, держит какую-то арену), тогда при копировании он может сделать новую арену, или же расшарить существующую и т.д. Если propagate == false_type, то аллокатор не участвует в операции, это может быть полезно, если аллокатор не имеет состояния, например, зовет malloc и free. Такому аллокатору нечего копировать.
  12. Вот методы, которые предоставляются allocator_traits, с ними ситуация аналогичная Первые два метода обязаны предоставляться аллокатором, поэтом реализация просто их зовет. С остальные методами ситуация следующая: если аллокатор предоставляет такие методы, то позвать их, иначе позвать стандартные реализации. Если с первыми 4 методами все более или менее поняно, то последний метод стоит обговорить отдельно. Итак вопрос, кто нибудь знает для чего нужен этот метод? Этот метод используется в контейнерах при реализации копирующего конструктора. Он определяет, каким образом нам копировать аллокатор. В принципе, мы опять, можем не копировать аллокатор, а создать новый и его вернуть. Или же сделать что-то еще. Идея реализации абсолютно аналогична выбору типов. Точно также SFINAE магия и приоритет перегруженных методово позволяет нам выбрать нужный.
  13. Итак, с чего мы все начали, мы определяли интерфейс вектора. И уже только для того чтобы задекларировать часть публичного интерфейса вектора нам пришлось реализовать следующее подмножество std. Я намеренно не обсуждал многие вещи, иначе мы бы до конца презентации обсуждали их, а нам надо еще реализацию вектора сделать. Если кому интересно, я могу после доклада, в кулуарах рассказать, как реализуются те или иные сущности в стандартной библиотеке. Мы еще не рассматривали методы вектора и пр, при рассмотрении методов еще добавится парочка сущностей.
  14. Итак, давайте теперь перейдем к реализации нашего вектора. Что такое vector_base, зачем я выделил его? На самом деле все просто. Для того чтобы реализовывать вектор нужно определиться с его представлением. Как мы будем хранить начало вектора, как будем хранить размер, как будем хранить диапазон выделенной памяти? Кроме этого в этом классе мы соберем утилитарные функции по управлению вектором.
  15. Опять, мы рассмотрим интерфейс нашего вектора по частям. Сначала конструкторы, операторы присваивания и деструктор. Здесь мы, кроме всего прочего определяем и внутреннее представление вектора, мы берем три итератора – итератор на начало, на конец данных и на конец выделенной области. Кстати, кто нибудь может сказать, зачем я здесь использую приватное наследование от аллокатора? Это для оптимизации. Есть такая оптимизация Empty base class optimization, если базовый класс пустой, то реализация вправе не выделять под него память при наследовании. Таким образом, sizeof(vector_base) будет равен 3* sizeof(pointer) в случае, если аллокатор пустой. Заметьте, что такого нельзя добиться если аллокатор объявить членом. Так как стандарт требует чтобы объект (даже пустой) всегда имел уникальный адрес.
  16. Вот реализация конструкторов. Как видите она довольно простая. Первый конструктор делегирует второму. Второй конструктор копирует аллокатор и выставляет m_first, m_last и m_endOfCapacity в значения по умолчанию (0). Третий конструктор – забирает у other его указатели и аллокатор. Четвертый конструктор забирает у other указатели, и ставит новый аллокатор. Реализация статических методов swap_base и tidy тривиальна. В первом случае мы свопаем указатели, во втором случае мы их зануляем. Здесь нет ничего сложного
  17. Теперь давайте рассмотрим операторы move и copy assignment. В принципе, они тоже довольно тривиальны. В первом случае мы освобождаем this если он чем то владел Затем обрабатываем аллокатор. Помните, мы обсуждали, что в allocator_traits задается стратегия как использовать аллокатор при move присваивании, вот здесь мы это обрабатываем. Ну а дальше просто – мы свопаем this и other, а потом обнуляем other. Оператор копирующего присваивания еще проще, в нем мы обрабатываем только аллокатор, все остальные действия будет производиться в другом месте.
  18. Вот так реализована функция propagate_on_move_assignment Мы диспетчеризуем вызов двум другим функциям. И в зависимости от типа мы либо муваем аллокатор, либо вообще ничего не делаем! Точно также реализован и propagate_on_copy_assignment.
  19. Теперь давайте опять ненадолго отвлечемся от вектора и поговорим про семейство unitialized_ функций. На самом деле, 2 из 3-х функций вам должны быть знакомы. Они практически полностью повторяют функции std::uninitialized_copy и std::unititalized_fill_n. Две остальные функции –unitialized_construct_a – дополнительная вспомогательная функция, котора тоже нам понадобится.
  20. Эта функция тоже довольно проста. Мы получаем на вход итератор с неинициализированной памятью, и вызываем construct с переданными аргументами. Как мы уже видели ранее, в реализации construct, там вызывается placement new. Все остальные функции реализуются аналогичным образом. Один вопрос, для чего здесь используется функция addressof? Все очень просто – тип, по которым итерируется итератор FwdIt может иметь перегруженный оператор &, и поэтому записать &*c будет некорректно. Функция addressof как раз предназначена для получения адреса из ссылки. Важный вопрос, какую гарантию относительно возникновения исключений дает эта функция? Эта функция дает сильную гарантию. Если возникнет исключение, то функция оставит входной диапазон неизменным относительно начала выполнения этой функции. То есть никакого эффекта не будет. Кстати, это касается и других функций, это очень важно, так как эти функции являются строительными кирпичиками для нашего вектора.
  21. Итак, к чему мы пришли, у нас есть реализация базовой части вектора, которая прячет особенности реализации и предоставляет удобные обертки для дальнейшей реализации. Что касается стандартной библиотеки, то вот несколько новых сущностей, которые мы добавили в библиотеку. Что касается последних двух функций, то их легко получить из _a версий, просто предоставив стандартный аллокатор в качестве аргумента. И это будет удовлетворять стандарту.
  22. Вот список константных методов – их реализация довольно проста, поэтому я не буду здесь ее приводить. Практически все функции однострочные. Звездочками я обозначил либо const, либо cr префиксы для функций begin и end.
  23. Итак, нам осталось реализовать три метода вектора. Начнем с reserve
  24. Вот реализация функции reserve. В принципе, реализация ее довольно проста: Проверили входные аргументы, потом выделили память для нового хранилища. И потом позвали функцию relocate, которая переместит правильным образом наш вектор в новый регион памяти. Кстати, теперь нас интересуют гарантии исключений для этой функции. Кто помнит, какие требования в стандарте? Сильная гарантия – если возникнет исключение в конструкторе копирования объектов, или при выделении памяти то функция не имеет эффекта. Если же возникнет исключение в move конструкторе, то поведение не определено. Ну это и понятно, если конструктор копирования не изменяет исходный объект, то move конструктор изменяет, и нет гарантии, что мы сможем вернуть объект в изначальное состояние. Текущая реализация не ухудшает сильной гарантии. Остается только посмотреть на реализацию relocate.
  25. Вот реализация функции relocate. Как мы помним, функция uninitialized_copy предъявляет сильную гарантию, но здесь мы делаем финт. Мы делаем move_iterator из обычного итератора, таким образом, вместо копирования будет производиться перемещение, если оно доступно. Таким образом, мы вполне легально можем переместить все объекты без копирования, что обычно дешевле. Ну и в конце остается рутина – очистить и удалить старый регион и переназначить указатели на новое хранилище.
  26. Вот самая интересная часть move_iterator – оператор разыменования возвращает rvalue ссылку, а не lvalue ссылку. Таким образом, если у типа есть move конструктор или move оператор присваивания, то именно он и вызовется.
  27. Итак, после реализации метода resever наша стандартная библиотека расширилась еще немного, и обрела реализацию иерархии исключений и реализацию basic_string!!! Что удивительно, реализация basic_string тоже использует length_error для реализации метода reserve, а конструктор length_error принимает на вход std::string, получается этакая рекурсия!! На самом деле, я не реализовывал basic_string, вместо этого я реализовал шаблонный конструктор у length_error, который принимает любой аргумент, в том числе и строку.
  28. Второй метод – вставка элемента или нескольких в заданную позицию
  29. Вот я перечислил методы insert, которые должны быть реализованы. Давайте вспомним какие требования к безопасности к ним предъявляет стандарт. Стандарт говорит, что если вставляем один элемент в конец и он CopyInsertable или move конструктор не кидает исключений, то в случае исключения функция не имеет эффекта - строгая гарантия. Во всех остальных случаях – базовая гарантия, инварианты вектора не нарушены, состояние не определено, но валидно. Кто может сказать, для чего в 4-й декларации используется enable_if? Чтобы различить 3 и 4 метод, например, позвали insert(pos, 0, 0). Какую функцию выбрать? Компилятор не сможет. И вот в этом случае нужен наш enable_if. Итак, давайте посмотрим на интерфейс и подумаем, может мы сможем выразить некоторые методы через другие.
  30. В принципе, мы 5 методов можем свести к двум. Благодаря тому, что у нас есть perfect forwarding, то мы можем одинаково передавать любые типы ссылок. Чем мы и воспользовались здесь. То есть две реализации свелись к одной. Вторая часть insert – вставляет диапазон. Я здесь не стал указывать пятую реализацию, которая принимает пару итераторов. Ее реализация не менее тривиальна чем представленные здесь. Отдельно стоит сказать про последнюю реализацию. Изначально казалось, что она ближе к первым двум, но на самом деле нет, и я сейчас объясню. Мы можем сделать специальный итератор, который просто считает свою позицию, и при разыменовании всегда возвращает один и тот же элемент. Таким образом, мы можем сделать такой итератор и передать его в insert_range.
  31. А вот и реализация этого counting iterator – у нас есть счетчик, текущее положение итератора, и оператор разыменования, который возвращает всегда одно и тоже значение. Ну и операции инкремента и декремента оператора сответственно, уменьшают или увеличивают значение счетчика. Таким образом мы получаем хитрый итератор, который всегда возвращает одно и тоже значение Кстати, какая категория итератора может быть у этого итератора – random access iterator?
  32. Итак, давайте рассмотрим реализацию метода Итак, что мы делаем: Вызываем метод grow, запрашиваем новый размер. Потом конструируем один элемент в КОНЦЕ вектора, увеличиваем размер вектора. Затем вызываем функцию из стандартной библиотеки rotate, которая меняет местами элементы в последовательности так, что нужный элемент оказывается на своем месте. Ну вот и все! Давайте посмотрим более детально. grow – это очень простой метод, он по сути реализует стратегию роста capacity вектора. По сути он вычисляет новое значение capacity, так чтобы оно было не меньше запрашиваемого и текущего capacity, и потом зовет reserve. Reserve как мы помним, дает строгую гарантию. unitialized_construct_a – мы уже разбирали, он конструирует объект в памяти. После этого мы увеличиваем размер вектора на 1. А потом, происходит самая магия, мы вращаем элементы в векторе так, чтобы последний элемент встал на место first + offset (то есть на место нашего pos), а все последующие элементы встанут за ним в том же порядке, в котором они и были. Вспоминаем про наши требования – вставка в конец одного элемента должна иметь строгую гарантию. Вставка в конец элемента – это значит, что pos == end(), мы помним, что вставляем всегда перед позицией. А это значит, что элемент уже на своем месте, и ничего вращать не надо! Получается, что все условия соблюдены!
  33. Единственный слайд с картинкой. Итак, реализация алгоритма rotate довольно простая: rotate на вход принимает 3 итератора, начало и конец, и еще один параметр – новое начало, элементы от new_firtst до end будут идти перед элементами [first, new_first). Вот я здесь привел картинку, которая, как мне кажется поясняет работу алгоритма. Я не буду приводить реализацию этого алгоритма, она довольно простая. Вообще говоря, функция rotate имеет базовую гарантию, но в случае, когда ничего делать не надо – эта функция как раз ничего не делает.
  34. Как видите, реализация метода insert_range очень похожа на реализацию предыдущего метода. Гарантии здесь те же самые. Кстати, кто может сказать, какое здесь сделано допущение? Мы используем std::distance, вообще говоря, distance определена для InputIterator. Но InputIterator вообще говоря только однопроходные, то есть повторно итерироваться нельзя. Поэтому здесь надо диспетчеризировать по категории итератора.
  35. Итак, для реализации insert нам понадобились следующие новые сущности из стандартной библиотеки. std::rotate, которая в свою очередь зовет iter_swap distance, для реализации метода insert_range – для подсчета расстояния между итераторами. is_base_of, для определения категории итератора
  36. Вот и реализация всех методов erase. Стандарт требует только базовой гарантии для методов. Мы опять используем фокус с rotate, чтобы ненужные элементы переместить в конец. После того как мы переместили в конец, мы зовем у них деструкторы и обновляем m_last, заметьте, capacity мы не трогали.
  37. Итого, реализация вектора с нуля заняла у меня полторы тыщи строк. При этом я реализовал подмножество type_traits, algorithm, utility, memory, iterator. В общем всех подсистем понемногу. Также почти 1000 строк кода у меня заняли тесты на вектор.
  38. Дискас!