Skip to content

Instantly share code, notes, and snippets.

@haxpor
Created July 15, 2019 01:54
Show Gist options
  • Save haxpor/aa00ecec82a84d578f523247c76c0856 to your computer and use it in GitHub Desktop.
Save haxpor/aa00ecec82a84d578f523247c76c0856 to your computer and use it in GitHub Desktop.
Test code following and adapting from https://stackoverflow.com/a/35008842/571227 to check if such STL container store its elements in contiguous way or not. Compile it will `g++ -std=c++11 Contiguous.cpp`
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <deque>
#include <array>
#include <string>
#include <vector>
template<typename I>
bool IsContiguous(I iteratorFirst, I iteratorEnd) {
bool testResult = true;
const int n = std::distance(iteratorFirst, iteratorEnd);
for (int i = 0; i<n && testResult; ++i) {
testResult &= *(std::next(iteratorFirst, i)) == *(std::next(std::addressof(*iteratorFirst), i));
}
return testResult;
}
int main() {
auto l = std::list<int>({1, 2, 3});
auto m = std::map<int, int>({{1,1}, {2,2}, {3,3}});
auto u = std::unordered_map<int, int>({{1,1}, {2,2}, {3,3}});
auto s = std::set<int>({1, 2, 3, 4, 5});
auto us = std::unordered_set<int>({1,2,3,4,5});
auto d = std::deque<int>(5);
auto d_l = std::deque<int>(4000);
int arr[] = {1,2,3,4,5};
auto a = std::array<int, 5>( {1,2,3,4,5} );
auto st = std::string( "test" );
auto st_l = std::string( "testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest" ); // "test" repeated for 200 times
auto v = std::vector<int>( {1,2,3,4,5,6} );
auto v_l = std::vector<int>( 5000 );
// std::queue has no iterator interface, but it should has the same effect as of std::deque provided
// we don't specify custom underlying container in constructor
// std::stack has no iterator interface, but it should has the same effect as of std::deque provided
// we don't specify custom underlying container in constructor
// output: false
// the following from inspection and use reasoning
// std::list usually allocates a large memory block and expand when need later (normally behavior of std::allocator)
// but internally can link nodes together scattering around inside the allocated memory block itself
std::cout << std::boolalpha << "std::list - " << IsContiguous(l.begin(), l.end()) << std::endl;
// output: false
// std::map is BST, thus no requirement for elements to be in contiguous
std::cout << std::boolalpha << "std::map - " << IsContiguous(m.begin(), m.end()) << std::endl;
// output: false
// std::unordered_map is hashmap which has hash table and will be rehashed everytime it need to expand its memory block
// thus elements can be scattering around
std::cout << std::boolalpha << "std::unordered_map - " << IsContiguous(u.begin(), u.end()) << std::endl;
// output: false
// std::set is sorted asssociated value of key objects, it's usually implemented as BST.
std::cout << std::boolalpha << "std::set - " << IsContiguous(s.begin(), s.end()) << std::endl;
// output: false
// std::unordered_set is un-sorted associated value of key objects, implemented in hashmap.
std::cout << std::boolalpha << "std::unordered_set - " << IsContiguous(us.begin(), us.end()) << std::endl;
// output: true
// if number of elements is not large, then it's still contiguous
std::cout << std::boolalpha << "std::deque - " << IsContiguous(d.begin(), d.end()) << std::endl;
// output: false
// if number of elements went large, then it's not contigous anymore
std::cout << std::boolalpha << "std::deque (large) - " << IsContiguous(d_l.begin(), d_l.end()) << std::endl;
// output: true
// normal array is contiguous
std::cout << std::boolalpha << "arr[] - " << IsContiguous(std::begin(arr), std::end(arr)) << std::endl;
// output: true
// std::array also has contiguous memory
std::cout << std::boolalpha << "std::array - " << IsContiguous(a.begin(), a.end()) << std::endl;
// output: true
// std::string with short string still has contiguous memory
std::cout << std::boolalpha << "std::string - " << IsContiguous(st.begin(), st.end()) << std::endl;
// output: true
// std::string with very long string still has elements stored in contiguous memory although before that
// it expanded memory block and copy old elements to a new one
std::cout << std::boolalpha << "std::string (long) - " << IsContiguous(st_l.begin(), st_l.end()) << std::endl;
// output: true
// std::vector has contigous memory storage
std::cout << std::boolalpha << "std::vector - " << IsContiguous(v.begin(), v.end()) << std::endl;
// output: true
// std::vector with large number of elements still has contigous memory storage
std::cout << std::boolalpha << "std::vector (large) - " << IsContiguous(v_l.begin(), v_l.end()) << std::endl;
// output: true
// std::queue has the same effect as of std::deque, for this case of small number of elements
std::cout << std::boolalpha << "std::queue - " << IsContiguous(q.begin(), q.end()) << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment