Repository files navigation

steady::vector

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

"Persistent" means that all vectors are immutable and when you "modify" the vector you get a copy of it with your changes integrated. Internally, the different generations of the vector object shares most state so this is very fast and uses little memory. This is done using atomic reference counting.

Since vectors never change, there is no need for thread synchronization like mutexes!

Documentation: https://github.com/marcusz/steady/blob/master/steady/steady_vector.md

Basic example:

//	Make a vector of ints. Add a few numbers.
//	Notice that push_back() returns a new vector each time - you need to save the return value.
//	There are no side effects. This makes code very simple and solid.
//	It also makes it simple to design pure functions.
void example1(){
steady::vector<int> a;
a.push_back(3);
a.push_back(8);
a.push_back(11);
//	Notice! a is still the empty vector! It has not changed!
assert(a.size() == 0);
//	Reuse variable b to keep the latest generation of the vector.
steady::vector<int> b;
b = b.push_back(3);
b = b.push_back(8);
b = b.push_back(11);
assert(b.size() == 3);
assert(b[2] == 11);
}

Writing to a vector:

//	Replace values in the vector. This also leaves original vector unchanged.
void example3(){
const steady::vector<int> a{ 10, 20, 30 };
const auto b = a.store(0, 2010);
const auto c = b.store(2, 2030);
assert(a == (steady::vector<int>{ 10, 20, 30 }));
assert(b == (steady::vector<int>{ 2010, 20, 30 }));
assert(c == (steady::vector<int>{ 2010, 20, 2030 }));
}
  • Apache License, Version 2.0

  • Based on Clojure's magical persistent vector class and Phil Bagwells work. Does not yet use Clojure's tail-optimization.

  • Strong exception-safety guarantee, just like C++ standard library and boost.

  • Robust and heavily unit-tested implementation.

Comparison to C++ std::vector<>

PRO:s

  1. More robust, easy-to-understand and side-effect free code since you know vectors never change.

  2. Since the vector never changes, it is safe to use it from many threads = thread safe.

  3. Easier to implement pure function - functions that have no side-effects - and still have good performance. Pure functions are central to making reliable, testable and multithreaded code.

  4. Faster than std::vector<> when growing big vectors.

CON:s

  1. Somewhat slower reading and writing. (There are techniques - like batching - to avoid some of this overhead.)

  2. Not complete set of std C++ features, like iterators.

  3. Not a 100% drop-in replacement for std::vector<>.

About

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

Resources

Stars

18 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

steady::vector

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

"Persistent" means that all vectors are immutable and when you "modify" the vector you get a copy of it with your changes integrated. Internally, the different generations of the vector object shares most state so this is very fast and uses little memory. This is done using atomic reference counting.

Since vectors never change, there is no need for thread synchronization like mutexes!

Documentation: https://github.com/marcusz/steady/blob/master/steady/steady_vector.md

Basic example:

//	Make a vector of ints. Add a few numbers.
//	Notice that push_back() returns a new vector each time - you need to save the return value.
//	There are no side effects. This makes code very simple and solid.
//	It also makes it simple to design pure functions.
void example1(){
steady::vector<int> a;
a.push_back(3);
a.push_back(8);
a.push_back(11);
//	Notice! a is still the empty vector! It has not changed!
assert(a.size() == 0);
//	Reuse variable b to keep the latest generation of the vector.
steady::vector<int> b;
b = b.push_back(3);
b = b.push_back(8);
b = b.push_back(11);
assert(b.size() == 3);
assert(b[2] == 11);
}

Writing to a vector:

//	Replace values in the vector. This also leaves original vector unchanged.
void example3(){
const steady::vector<int> a{ 10, 20, 30 };
const auto b = a.store(0, 2010);
const auto c = b.store(2, 2030);
assert(a == (steady::vector<int>{ 10, 20, 30 }));
assert(b == (steady::vector<int>{ 2010, 20, 30 }));
assert(c == (steady::vector<int>{ 2010, 20, 2030 }));
}
  • Apache License, Version 2.0

  • Based on Clojure's magical persistent vector class and Phil Bagwells work. Does not yet use Clojure's tail-optimization.

  • Strong exception-safety guarantee, just like C++ standard library and boost.

  • Robust and heavily unit-tested implementation.

Comparison to C++ std::vector<>

PRO:s

  1. More robust, easy-to-understand and side-effect free code since you know vectors never change.

  2. Since the vector never changes, it is safe to use it from many threads = thread safe.

  3. Easier to implement pure function - functions that have no side-effects - and still have good performance. Pure functions are central to making reliable, testable and multithreaded code.

  4. Faster than std::vector<> when growing big vectors.

CON:s

  1. Somewhat slower reading and writing. (There are techniques - like batching - to avoid some of this overhead.)

  2. Not complete set of std C++ features, like iterators.

  3. Not a 100% drop-in replacement for std::vector<>.

About

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

Resources

Stars

18 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

steady::vector

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

"Persistent" means that all vectors are immutable and when you "modify" the vector you get a copy of it with your changes integrated. Internally, the different generations of the vector object shares most state so this is very fast and uses little memory. This is done using atomic reference counting.

Since vectors never change, there is no need for thread synchronization like mutexes!

Documentation: https://github.com/marcusz/steady/blob/master/steady/steady_vector.md

Basic example:

//	Make a vector of ints. Add a few numbers.
//	Notice that push_back() returns a new vector each time - you need to save the return value.
//	There are no side effects. This makes code very simple and solid.
//	It also makes it simple to design pure functions.
void example1(){
steady::vector<int> a;
a.push_back(3);
a.push_back(8);
a.push_back(11);
//	Notice! a is still the empty vector! It has not changed!
assert(a.size() == 0);
//	Reuse variable b to keep the latest generation of the vector.
steady::vector<int> b;
b = b.push_back(3);
b = b.push_back(8);
b = b.push_back(11);
assert(b.size() == 3);
assert(b[2] == 11);
}

Writing to a vector:

//	Replace values in the vector. This also leaves original vector unchanged.
void example3(){
const steady::vector<int> a{ 10, 20, 30 };
const auto b = a.store(0, 2010);
const auto c = b.store(2, 2030);
assert(a == (steady::vector<int>{ 10, 20, 30 }));
assert(b == (steady::vector<int>{ 2010, 20, 30 }));
assert(c == (steady::vector<int>{ 2010, 20, 2030 }));
}
  • Apache License, Version 2.0

  • Based on Clojure's magical persistent vector class and Phil Bagwells work. Does not yet use Clojure's tail-optimization.

  • Strong exception-safety guarantee, just like C++ standard library and boost.

  • Robust and heavily unit-tested implementation.

Comparison to C++ std::vector<>

PRO:s

  1. More robust, easy-to-understand and side-effect free code since you know vectors never change.

  2. Since the vector never changes, it is safe to use it from many threads = thread safe.

  3. Easier to implement pure function - functions that have no side-effects - and still have good performance. Pure functions are central to making reliable, testable and multithreaded code.

  4. Faster than std::vector<> when growing big vectors.

CON:s

  1. Somewhat slower reading and writing. (There are techniques - like batching - to avoid some of this overhead.)

  2. Not complete set of std C++ features, like iterators.

  3. Not a 100% drop-in replacement for std::vector<>.

About

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

Resources

Stars

18 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

steady::vector

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

"Persistent" means that all vectors are immutable and when you "modify" the vector you get a copy of it with your changes integrated. Internally, the different generations of the vector object shares most state so this is very fast and uses little memory. This is done using atomic reference counting.

Since vectors never change, there is no need for thread synchronization like mutexes!

Documentation: https://github.com/marcusz/steady/blob/master/steady/steady_vector.md

Basic example:

//	Make a vector of ints. Add a few numbers.
//	Notice that push_back() returns a new vector each time - you need to save the return value.
//	There are no side effects. This makes code very simple and solid.
//	It also makes it simple to design pure functions.
void example1(){
steady::vector<int> a;
a.push_back(3);
a.push_back(8);
a.push_back(11);
//	Notice! a is still the empty vector! It has not changed!
assert(a.size() == 0);
//	Reuse variable b to keep the latest generation of the vector.
steady::vector<int> b;
b = b.push_back(3);
b = b.push_back(8);
b = b.push_back(11);
assert(b.size() == 3);
assert(b[2] == 11);
}

Writing to a vector:

//	Replace values in the vector. This also leaves original vector unchanged.
void example3(){
const steady::vector<int> a{ 10, 20, 30 };
const auto b = a.store(0, 2010);
const auto c = b.store(2, 2030);
assert(a == (steady::vector<int>{ 10, 20, 30 }));
assert(b == (steady::vector<int>{ 2010, 20, 30 }));
assert(c == (steady::vector<int>{ 2010, 20, 2030 }));
}
  • Apache License, Version 2.0

  • Based on Clojure's magical persistent vector class and Phil Bagwells work. Does not yet use Clojure's tail-optimization.

  • Strong exception-safety guarantee, just like C++ standard library and boost.

  • Robust and heavily unit-tested implementation.

Comparison to C++ std::vector<>

PRO:s

  1. More robust, easy-to-understand and side-effect free code since you know vectors never change.

  2. Since the vector never changes, it is safe to use it from many threads = thread safe.

  3. Easier to implement pure function - functions that have no side-effects - and still have good performance. Pure functions are central to making reliable, testable and multithreaded code.

  4. Faster than std::vector<> when growing big vectors.

CON:s

  1. Somewhat slower reading and writing. (There are techniques - like batching - to avoid some of this overhead.)

  2. Not complete set of std C++ features, like iterators.

  3. Not a 100% drop-in replacement for std::vector<>.

About

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

Resources

Stars

18 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

steady::vector

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

"Persistent" means that all vectors are immutable and when you "modify" the vector you get a copy of it with your changes integrated. Internally, the different generations of the vector object shares most state so this is very fast and uses little memory. This is done using atomic reference counting.

Since vectors never change, there is no need for thread synchronization like mutexes!

Documentation: https://github.com/marcusz/steady/blob/master/steady/steady_vector.md

Basic example:

//	Make a vector of ints. Add a few numbers.
//	Notice that push_back() returns a new vector each time - you need to save the return value.
//	There are no side effects. This makes code very simple and solid.
//	It also makes it simple to design pure functions.
void example1(){
steady::vector<int> a;
a.push_back(3);
a.push_back(8);
a.push_back(11);
//	Notice! a is still the empty vector! It has not changed!
assert(a.size() == 0);
//	Reuse variable b to keep the latest generation of the vector.
steady::vector<int> b;
b = b.push_back(3);
b = b.push_back(8);
b = b.push_back(11);
assert(b.size() == 3);
assert(b[2] == 11);
}

Writing to a vector:

//	Replace values in the vector. This also leaves original vector unchanged.
void example3(){
const steady::vector<int> a{ 10, 20, 30 };
const auto b = a.store(0, 2010);
const auto c = b.store(2, 2030);
assert(a == (steady::vector<int>{ 10, 20, 30 }));
assert(b == (steady::vector<int>{ 2010, 20, 30 }));
assert(c == (steady::vector<int>{ 2010, 20, 2030 }));
}
  • Apache License, Version 2.0

  • Based on Clojure's magical persistent vector class and Phil Bagwells work. Does not yet use Clojure's tail-optimization.

  • Strong exception-safety guarantee, just like C++ standard library and boost.

  • Robust and heavily unit-tested implementation.

Comparison to C++ std::vector<>

PRO:s

  1. More robust, easy-to-understand and side-effect free code since you know vectors never change.

  2. Since the vector never changes, it is safe to use it from many threads = thread safe.

  3. Easier to implement pure function - functions that have no side-effects - and still have good performance. Pure functions are central to making reliable, testable and multithreaded code.

  4. Faster than std::vector<> when growing big vectors.

CON:s

  1. Somewhat slower reading and writing. (There are techniques - like batching - to avoid some of this overhead.)

  2. Not complete set of std C++ features, like iterators.

  3. Not a 100% drop-in replacement for std::vector<>.

About

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

Resources

Stars

18 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

steady::vector

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

"Persistent" means that all vectors are immutable and when you "modify" the vector you get a copy of it with your changes integrated. Internally, the different generations of the vector object shares most state so this is very fast and uses little memory. This is done using atomic reference counting.

Since vectors never change, there is no need for thread synchronization like mutexes!

Documentation: https://github.com/marcusz/steady/blob/master/steady/steady_vector.md

Basic example:

//	Make a vector of ints. Add a few numbers.
//	Notice that push_back() returns a new vector each time - you need to save the return value.
//	There are no side effects. This makes code very simple and solid.
//	It also makes it simple to design pure functions.
void example1(){
steady::vector<int> a;
a.push_back(3);
a.push_back(8);
a.push_back(11);
//	Notice! a is still the empty vector! It has not changed!
assert(a.size() == 0);
//	Reuse variable b to keep the latest generation of the vector.
steady::vector<int> b;
b = b.push_back(3);
b = b.push_back(8);
b = b.push_back(11);
assert(b.size() == 3);
assert(b[2] == 11);
}

Writing to a vector:

//	Replace values in the vector. This also leaves original vector unchanged.
void example3(){
const steady::vector<int> a{ 10, 20, 30 };
const auto b = a.store(0, 2010);
const auto c = b.store(2, 2030);
assert(a == (steady::vector<int>{ 10, 20, 30 }));
assert(b == (steady::vector<int>{ 2010, 20, 30 }));
assert(c == (steady::vector<int>{ 2010, 20, 2030 }));
}
  • Apache License, Version 2.0

  • Based on Clojure's magical persistent vector class and Phil Bagwells work. Does not yet use Clojure's tail-optimization.

  • Strong exception-safety guarantee, just like C++ standard library and boost.

  • Robust and heavily unit-tested implementation.

Comparison to C++ std::vector<>

PRO:s

  1. More robust, easy-to-understand and side-effect free code since you know vectors never change.

  2. Since the vector never changes, it is safe to use it from many threads = thread safe.

  3. Easier to implement pure function - functions that have no side-effects - and still have good performance. Pure functions are central to making reliable, testable and multithreaded code.

  4. Faster than std::vector<> when growing big vectors.

CON:s

  1. Somewhat slower reading and writing. (There are techniques - like batching - to avoid some of this overhead.)

  2. Not complete set of std C++ features, like iterators.

  3. Not a 100% drop-in replacement for std::vector<>.

About

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

Resources

Stars

18 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

steady::vector

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

"Persistent" means that all vectors are immutable and when you "modify" the vector you get a copy of it with your changes integrated. Internally, the different generations of the vector object shares most state so this is very fast and uses little memory. This is done using atomic reference counting.

Since vectors never change, there is no need for thread synchronization like mutexes!

Documentation: https://github.com/marcusz/steady/blob/master/steady/steady_vector.md

Basic example:

//	Make a vector of ints. Add a few numbers.
//	Notice that push_back() returns a new vector each time - you need to save the return value.
//	There are no side effects. This makes code very simple and solid.
//	It also makes it simple to design pure functions.
void example1(){
steady::vector<int> a;
a.push_back(3);
a.push_back(8);
a.push_back(11);
//	Notice! a is still the empty vector! It has not changed!
assert(a.size() == 0);
//	Reuse variable b to keep the latest generation of the vector.
steady::vector<int> b;
b = b.push_back(3);
b = b.push_back(8);
b = b.push_back(11);
assert(b.size() == 3);
assert(b[2] == 11);
}

Writing to a vector:

//	Replace values in the vector. This also leaves original vector unchanged.
void example3(){
const steady::vector<int> a{ 10, 20, 30 };
const auto b = a.store(0, 2010);
const auto c = b.store(2, 2030);
assert(a == (steady::vector<int>{ 10, 20, 30 }));
assert(b == (steady::vector<int>{ 2010, 20, 30 }));
assert(c == (steady::vector<int>{ 2010, 20, 2030 }));
}
  • Apache License, Version 2.0

  • Based on Clojure's magical persistent vector class and Phil Bagwells work. Does not yet use Clojure's tail-optimization.

  • Strong exception-safety guarantee, just like C++ standard library and boost.

  • Robust and heavily unit-tested implementation.

Comparison to C++ std::vector<>

PRO:s

  1. More robust, easy-to-understand and side-effect free code since you know vectors never change.

  2. Since the vector never changes, it is safe to use it from many threads = thread safe.

  3. Easier to implement pure function - functions that have no side-effects - and still have good performance. Pure functions are central to making reliable, testable and multithreaded code.

  4. Faster than std::vector<> when growing big vectors.

CON:s

  1. Somewhat slower reading and writing. (There are techniques - like batching - to avoid some of this overhead.)

  2. Not complete set of std C++ features, like iterators.

  3. Not a 100% drop-in replacement for std::vector<>.

About

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

Resources

Stars

18 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

steady::vector

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

"Persistent" means that all vectors are immutable and when you "modify" the vector you get a copy of it with your changes integrated. Internally, the different generations of the vector object shares most state so this is very fast and uses little memory. This is done using atomic reference counting.

Since vectors never change, there is no need for thread synchronization like mutexes!

Documentation: https://github.com/marcusz/steady/blob/master/steady/steady_vector.md

Basic example:

//	Make a vector of ints. Add a few numbers.
//	Notice that push_back() returns a new vector each time - you need to save the return value.
//	There are no side effects. This makes code very simple and solid.
//	It also makes it simple to design pure functions.
void example1(){
steady::vector<int> a;
a.push_back(3);
a.push_back(8);
a.push_back(11);
//	Notice! a is still the empty vector! It has not changed!
assert(a.size() == 0);
//	Reuse variable b to keep the latest generation of the vector.
steady::vector<int> b;
b = b.push_back(3);
b = b.push_back(8);
b = b.push_back(11);
assert(b.size() == 3);
assert(b[2] == 11);
}

Writing to a vector:

//	Replace values in the vector. This also leaves original vector unchanged.
void example3(){
const steady::vector<int> a{ 10, 20, 30 };
const auto b = a.store(0, 2010);
const auto c = b.store(2, 2030);
assert(a == (steady::vector<int>{ 10, 20, 30 }));
assert(b == (steady::vector<int>{ 2010, 20, 30 }));
assert(c == (steady::vector<int>{ 2010, 20, 2030 }));
}
  • Apache License, Version 2.0

  • Based on Clojure's magical persistent vector class and Phil Bagwells work. Does not yet use Clojure's tail-optimization.

  • Strong exception-safety guarantee, just like C++ standard library and boost.

  • Robust and heavily unit-tested implementation.

Comparison to C++ std::vector<>

PRO:s

  1. More robust, easy-to-understand and side-effect free code since you know vectors never change.

  2. Since the vector never changes, it is safe to use it from many threads = thread safe.

  3. Easier to implement pure function - functions that have no side-effects - and still have good performance. Pure functions are central to making reliable, testable and multithreaded code.

  4. Faster than std::vector<> when growing big vectors.

CON:s

  1. Somewhat slower reading and writing. (There are techniques - like batching - to avoid some of this overhead.)

  2. Not complete set of std C++ features, like iterators.

  3. Not a 100% drop-in replacement for std::vector<>.

About

This is a fast and reliable persistent (immutable) vector class for C++. You can safely share these vectors between threads in multi-threaded programs.

Resources

Stars

18 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages