Skip to content

Commit

Permalink
cpp: a bunch of random stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
cirosantilli committed Oct 26, 2018
1 parent b6346e1 commit ff59462
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 82 deletions.
82 changes: 73 additions & 9 deletions cpp/algorithm.cpp
Expand Up @@ -37,28 +37,93 @@ int main() {
* Particularly important because of the copy and swap idiom.
*/

// # randomize
// # random_shuffle
{
std::vector<int> v{2, 0, 1};
std::random_shuffle(v.begin(), v.end());
}

// # copy
#if __cplusplus >= 201703L
/* # sample
*
* https://stackoverflow.com/questions/6942273/how-to-get-a-random-element-from-a-c-container/42484107#42484107
*/
{
std::vector<int> v{2, 0, 1};
std::vector<int> v2(5, 3);
std::copy(v.begin(), v.end(), v2.begin() + 1);
assert(v2 == std::vector<int>({3, 2, 0, 1, 3}));
const std::vector<int> in{1, 2, 3, 5, 7};
std::vector<int> out;
size_t nelems = 3;
std::sample(in.begin(), in.end(), std::back_inserter(out),
nelems, std::mt19937{std::random_device{}()});
std::set in_set(std::begin(in), std::end(in));
std::set out_set(std::begin(out), std::end(out));

// The sample elements are distinct.
assert(out_set.size() == nelems);

// The sample elements came from the input.
std::set<int> intersect;
std::set_intersection(
in.begin(), in.end(), out.begin(), out.end(),
std::inserter(intersect, intersect.begin())
);
assert(intersect.size() == nelems);

//for (auto i : out)
// std::cout << i << std::endl;
}
#endif

/* # equal
*
* Compares ranges of two containers.
*
* Vs memcmp:
* https://stackoverflow.com/questions/39262496/why-is-stdequal-much-slower-than-a-hand-rolled-loop-for-two-small-stdarray
*/
{
std::vector<int> v {0, 1, 2 };
std::vector<int> v1{0, 1, 2 };
std::vector<int> v2{ 1, 2, 3};
assert(std::equal(v.begin() + 1, v.end(), v2.begin()));
assert(std::equal(v1.begin() + 1, v1.end(), v2.begin()));
}

/* # copy
*
* Vs memcpy: can compile down to an assembly optimized memcpy for arrays apparently, so just always use this:
* https://stackoverflow.com/questions/4707012/is-it-better-to-use-stdmemcpy-or-stdcopy-in-terms-to-performance
*/
{
/* Newbie basic class usage. */
{
std::vector<int> v{0, 1, 2, 3, 4};
std::vector<int> v2(v.size(), v.size());
std::copy(v.begin() + 1, v.end() - 1, v2.begin() + 2);
assert(v2 == std::vector<int>({5, 5, 1, 2, 3}));
}

/* # std::begin
*
* # std::end
*
* Array usage.
*
* https://stackoverflow.com/questions/7593086/why-use-non-member-begin-and-end-functions-in-c11
*/
{
int v1[]{0, 1, 2, 3, 4};
int v2[]{5, 5, 5, 5, 5};
int v3[]{5, 5, 1, 2, 3};
std::copy(std::begin(v1) + 1, std::end(v1) - 1, std::begin(v2) + 2);
assert(std::equal(std::begin(v2), std::end(v2), std::begin(v3)));
}

/* Therefore, a more elegant class approach that uses exact same syntax as arrays. */
{
std::vector<int> v1{0, 1, 2, 3, 4};
std::vector<int> v2{5, 5, 5, 5, 5};
std::vector<int> v3{5, 5, 1, 2, 3};
std::copy(std::begin(v1) + 1, std::end(v1) - 1, std::begin(v2) + 2);
assert(std::equal(std::begin(v2), std::end(v2), std::begin(v3)));
}
}

/* # accumulate
Expand Down Expand Up @@ -125,7 +190,6 @@ int main() {
* If you want to get the position of those items, use `equal_range`, `lower_bound` or `upper_bound`.
*/
{

std::vector<int> v{0, 1, 2};
assert(std::binary_search(v.begin(), v.end(), 1) == true);
assert(std::binary_search(v.begin(), v.end(), 3) == false);
Expand Down
23 changes: 22 additions & 1 deletion cpp/array.cpp
@@ -1,10 +1,31 @@
/* https://stackoverflow.com/questions/4424579/stdvector-versus-stdarray-in-c */
/* # std::array
*
* https://stackoverflow.com/questions/4424579/stdvector-versus-stdarray-in-c
*
* Basically: never use raw arrays in C++, use this instead.
* It is better in every sense.
*/

#include "common.hpp"

int main() {
std::array<int, 3> a{{0, 1, 2}};

assert(a.size() == 3);

// No implicit bounds checks.
//std::cout << a[4] << std::endl;

// But does have some goodies, since it knows the array size,
// e.g. operator== comparison.
assert((std::array<int, 3>{1, 2, 3} == std::array<int, 3>{1, 2, 3}));

// Nah, can't deduce size from initializer:
// https://stackoverflow.com/questions/6114067/how-to-emulate-c-array-initialization-int-arr-e1-e2-e3-behaviou
// std::array<int>{1, 2, 3}

// But does not have any constructor goodies, e.g. fill constructor:
//std::array<int, 3>(24);
// Maybe this is to make it POD?
static_assert(std::is_pod<std::array<int, 1>>());
}
12 changes: 5 additions & 7 deletions cpp/iterator.cpp
Expand Up @@ -55,17 +55,15 @@ int main() {
// After C++11; the range based syntax is the best way to use them.
{
/*
# forward iteration
# begin
Can be done on all containers.
Returns an iterator to the first element.
# begin
# end
Returns an iterator to the first element.
Returns an iterator to the first element *after* the last.
# end
Returns an iterator to the first element *after* the last.
https://stackoverflow.com/questions/7593086/why-use-non-member-begin-and-end-functions-in-c11
*/
{
std::vector<int> v{1, 2, 0};
Expand Down
4 changes: 4 additions & 0 deletions cpp/pod.cpp
Expand Up @@ -9,6 +9,7 @@
*/

#include <type_traits>
#include <array>
#include <vector>

int main() {
Expand Down Expand Up @@ -227,6 +228,9 @@ int main() {
{
static_assert(!std::is_pod<std::vector<int>>());
static_assert(!std::is_trivially_copyable<std::vector<int>>());
// Some might be though:
// https://stackoverflow.com/questions/3674247/is-stdarrayt-s-guaranteed-to-be-pod-if-t-is-pod
static_assert(std::is_pod<std::array<int, 1>>());
}

/* Array of POD is POD. */
Expand Down
6 changes: 4 additions & 2 deletions cpp/unique_ptr.cpp
Expand Up @@ -140,7 +140,7 @@ int main() {

// # reset
{
/* With no argumetns, explicit destruction of pointer. Equivalent to `delete`.
/* With no arguments, explicitly destroy the pointer. Equivalent to `delete`.
*
* http://stackoverflow.com/questions/25609457/unique-ptr-explicit-delete
*/
Expand All @@ -152,13 +152,15 @@ int main() {
}

// Reset with an argument
// does what you would expect: release and replace.
// does what you would expect: release and replace,
// just like assignment.
{
std::unique_ptr<Base> p(new Base(1));
assert(p->i == 1);
assert(Base::count == 1);

/* Nope. TODO why?
*
* - https://stackoverflow.com/questions/48104034/why-cant-i-assign-to-unique-ptr-of-type-uint-8
* - https://stackoverflow.com/questions/34882140/why-cant-a-pointer-be-automatically-converted-into-a-unique-ptr-when-returning
*/
Expand Down
112 changes: 49 additions & 63 deletions cpp/vector.cpp
@@ -1,16 +1,7 @@
/*
# vector
Array backed conatiner that grows / shrinks as necessary.
$O(1)$ random access.
$O(n)$ element removal from interior
$O(1)$ element append to end (amortized, $O(n)$ worst case)
All methods that work for several SLT containers shall only be cheated here once.
*/
/* # vector
*
* Dynamic array: https://en.wikipedia.org/wiki/Dynamic_array
*/

#include "common.hpp"

Expand All @@ -31,11 +22,10 @@ int main() {
assert(v.size() == 3);
}

/*
Fill constructor.
Make a `std::vector` with n copies of a single value.
*/
/* Fill constructor.
*
* Make a `std::vector` with n copies of a single value.
*/
{
// Copies of given object.
{
Expand Down Expand Up @@ -71,22 +61,21 @@ int main() {
assert(v != v1);
}

/*
# Contigous storage
# Data
Storage is required to be contiguous by TR1:
http://stackoverflow.com/questions/849168/are-stdvector-elements-guaranteed-to-be-contiguous
C++11 introduces the `data()` method which returns a pointer to the first element.
It works even if the vector is empty.
http://stackoverflow.com/questions/6485496/how-to-get-stdvector-pointer-to-the-raw-data
Before C++11, `&v[0]` works for non-empty vectors.
`vector<bool>` as usual is an exception.
*/
/* # Contiguous storage
*
* # Data
*
* Storage is required to be contiguous by TR1:
* http://stackoverflow.com/questions/849168/are-stdvector-elements-guaranteed-to-be-contiguous
*
* C++11 introduces the `data()` method which returns a pointer to the first element.
* It works even if the vector is empty.
* http://stackoverflow.com/questions/6485496/how-to-get-stdvector-pointer-to-the-raw-data
*
* Before C++11, `&v[0]` works for non-empty vectors.
*
* `vector<bool>` as usual is an exception.
*/
{
std::vector<int> v{0, 1, 2};
assert(&v[0] == v.data());
Expand All @@ -96,31 +85,29 @@ int main() {

// size methods
{
/*
# size
# length of vector
# size_type
Number of elements in std::vector.
This has type std::vector<X>::size_type
*/
/* # size
*
* # length of vector
*
* # size_type
*
* Number of elements in std::vector.
*
* This has type std::vector<X>::size_type
*/
{
std::vector<int> v;
assert(v.size() == 0);
v.push_back(0);
assert(v.size() == 1);
}

/*
# resize
If larger than current size, append given element at end.
If smaller than current size, remove elements from end.
*/
/* # resize
*
* If larger than current size, append given element at end.
*
* If smaller than current size, remove elements from end.
*/
{
// Reduce size
{
Expand Down Expand Up @@ -150,17 +137,16 @@ int main() {

// Capacity methods.
{
/*
# capacity
Get currently allocated size.
Different from size, which is the number of elements in the std::vector!
At least as large as size.
Likely to be a power of 2 on most implementations.
*/
/* # capacity
*
* Get currently allocated size.
*
* Different from size, which is the number of elements in the std::vector!
*
* At least as large as size.
*
* Likely to be a power of 2 on most implementations.
*/
{
std::vector<int> v;
v.push_back(0);
Expand Down

0 comments on commit ff59462

Please sign in to comment.