Merge branch 'master' of github.com:vishap/test

This commit is contained in:
2021-11-20 13:23:35 +00:00
67 changed files with 4233 additions and 9 deletions

View File

@@ -0,0 +1,102 @@
/*
VIM: let b:lcppflags="-std=c++14 -O2 -pthread -I."
VIM: let b:wcppflags="/O2 /EHsc /DWIN32"
VIM-: let b:cppflags=g:Iboost.g:Itbb
VIM-: let b:ldflags=g:Lboost.g:Ltbb
VIM-: let b:ldlibpath=g:Bboost.g:Btbb
VIM-: let b:argv=""
*/
#include <iostream>
#include <exception>
class A
{
public:
int i;
A() {
std::cout << "default ctr" << std::endl;
}
A(const A&) {
std::cout << "copy ctr" << std::endl;
}
A(A&&) {
std::cout << "move ctr" << std::endl;
}
void operator = (const A&) {
std::cout << "copy" << std::endl;
}
void operator = (A&&) {
std::cout << "move" << std::endl;
}
};
void test3( A a ){
std::cout << "by value" << std::endl;
}
void test3( A&& a ){
std::cout << "rvalue" << std::endl;
}
void test3( const A& a ){
std::cout << "const lvalue&" << std::endl;
}
void test3( A& a ){
std::cout << "lvalue &" << std::endl;
}
template <typename T>
void test2( T&& t ){
test3(std::forward<T>(t));
}
template <typename T>
void test( T t ){
//test2(std::forward<T>(t));
test3(t);
}
A rvalue()
{
return A();
}
A& lvalue()
{
static A a;
return a;
}
const A& clvalue()
{
static A a;
return a;
}
int main ( void )
{try{
test(rvalue());
test(lvalue());
test(clvalue());
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}

View File

@@ -0,0 +1,72 @@
/*
VIM: let b:lcppflags="-std=c++14 -O2 -pthread"
VIM: let b:wcppflags="/O2 /EHsc /DWIN32"
VIM: let b:argv=""
*/
#include <iostream>
#include <exception>
#include <vector>
//#include <initializer_list>
template <typename CONT>
void print( CONT&& cont )
{
std::cout << "template ";
for( auto n : cont ){
std::cout << n << ' ';
}
std::cout << std::endl;
}
#if 1
void print( const std::initializer_list<auto>& cont )
{
std::cout << "initializer_list<auto> ";
for( auto n : cont ){
std::cout << n << ' ';
}
std::cout << std::endl;
}
#if 1
void print( const std::initializer_list<int>& cont )
{
std::cout << "initializer_list<int> ";
for( auto n : cont ){
std::cout << n << ' ';
}
std::cout << std::endl;
}
#endif
#endif
int main ( void )
{try{
std::vector<int> v = {1,2,3};
print(v);
print({3,4,5});
print({3LL,4LL,5LL});
print({3LL,4,5});
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}

42
cpp/cpp11/overload.cpp Normal file
View File

@@ -0,0 +1,42 @@
/*
VIM: let b:lcppflags="-std=c++11 -O2 -pthread"
VIM: let b:wcppflags="/O2 /EHsc /DWIN32"
VIM: let b:argv=""
*/
#include <iostream>
#include <exception>
#include <string>
void a( std::string&& s )
{
std::cout << " by value " << std::endl;
}
void a( const std::string& s )
{
std::cout << " const ref " << std::endl;
}
int main ( void )
{try{
std::string s = "bbbbbb";
a(s);
a(std::string("aaaa"));
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}

93
cpp/cpp11/test1.cpp Normal file
View File

@@ -0,0 +1,93 @@
/*
VIM: let b:lcppflags="-std=c++14 -O2 -pthread -I."
VIM: let b:wcppflags="/O2 /EHsc /DWIN32"
VIM: let b:argv=""
*/
#include <iostream>
#include <exception>
#include <trnx_vector.h>
namespace trnx {
struct A{
int a1;
};
void test()
{
trnx::vector<A> v;
v.push_back(A{0});
v.push_back(A{1});
v.push_back(A{2});
for(const auto& x : v)
{
std::cout << x.a1 << ' ';
}
std::cout << std::endl;
}
#if 1
struct MoveOnly
{
int d_datum;
// Allow moves
MoveOnly(MoveOnly&&) = default;
MoveOnly& operator=(MoveOnly&&) = default;
// Prevent copies
MoveOnly(const MoveOnly&) = delete;
MoveOnly& operator=(const MoveOnly&) = delete;
};
void lab1()
{
trnx::vector<MoveOnly> v;
v.push_back(MoveOnly{0});
v.push_back(MoveOnly{1});
v.push_back(MoveOnly{2});
for(const auto& x : v)
{
std::cout << x.d_datum << ' ';
}
std::cout << std::endl;
}
#endif
void main()
{
test();
lab1();
}
} // close namespace trnx
int main ( void )
{try{
trnx::main();
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}

75
cpp/cpp11/trnx_order.h Normal file
View File

@@ -0,0 +1,75 @@
#ifndef INCLUDED_TRNX_ORDER
#define INCLUDED_TRNX_ORDER
#include <bsl_iostream.h>
#include <bsl_string.h>
#include <bael_log.h>
namespace BloombergLP {
namespace trnx {
class Order
{
public:
Order()
{
BAEL_LOG_SET_CATEGORY("ORDER");
BAEL_LOG_INFO << "Order::Order()" << BAEL_LOG_END;
};
Order(const bsl::string& symbol, double price, int amount,
char side)
: d_symbol(symbol), d_price(price), d_amount(amount),
d_side(side)
{
BAEL_LOG_SET_CATEGORY("ORDER");
BAEL_LOG_INFO << "Order::Order(string, double, int, char)"
<< BAEL_LOG_END;
}
Order(const Order& other)
: d_symbol(other.d_symbol), d_price(other.d_price),
d_amount(other.d_amount), d_side(other.d_side)
{
BAEL_LOG_SET_CATEGORY("ORDER");
BAEL_LOG_INFO << "Order::Order(const Order&)" << BAEL_LOG_END;
}
~Order()
{
BAEL_LOG_SET_CATEGORY("ORDER");
BAEL_LOG_INFO << "Order::~Order()" << BAEL_LOG_END;
}
bool operator==(const Order& other) const
{
return (d_symbol == other.d_symbol &&
d_price == other.d_price &&
d_amount == other.d_amount && d_side == other.d_side);
}
const bsl::string& symbol() const { return d_symbol; }
double price() const { return d_price; }
int amount() const { return d_amount; }
char side() const { return d_side; }
private:
bsl::string d_symbol;
double d_price;
int d_amount;
char d_side;
friend bsl::ostream& operator<<(bsl::ostream& os, const Order& o);
};
inline bsl::ostream& operator<<(bsl::ostream& os, const Order& o)
{
os << "[" << o.d_symbol << ',' << o.d_price << ',' << o.d_amount
<< ',' << o.d_side << "]";
return os;
}
} // close namespace trnx
} // close namespace BloombergLP
#endif

224
cpp/cpp11/trnx_vector.h Normal file
View File

@@ -0,0 +1,224 @@
#ifndef INCLUDED_TRNX_VECTOR
#define INCLUDED_TRNX_VECTOR
#include <cstddef>
#include <exception>
#include <iterator>
#include <type_traits>
#include <memory>
#include <trnx_vector_impl.h>
namespace trnx {
template <typename T>
class vector
{
public:
typedef T value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
private:
size_type d_size;
size_type d_capacity;
typedef detail::uninitialized<T> buff_type[];
std::unique_ptr<buff_type> d_buff;
// `uninitialized<T>` represents enough uninitialized storage for an
// instance of `T`. The lifetime of the `T` instance is controlled
// manually via the `.construct` and `.destroy` member functions.
// An initialized instance can be accessed through `.get`.
public:
typedef detail::iter_impl<detail::uninitialized<T> > iterator; //CHG
typedef detail::iter_impl<const detail::uninitialized<T> > const_iterator; //CHG
// `iter_impl` is an iterator type that automatically transforms
// `uninitialized<T>*` into `T*` when dereferencing.
vector() : d_size(0), d_capacity(0), d_buff(nullptr)
{
// A default-constructed vector is empty and has no allocated buffer.
}
vector(const vector& rhs)
: d_size(rhs.d_size),
d_capacity(rhs.d_capacity),
// Allocate enough space for `rhs.d_size` items.
d_buff(std::make_unique<buff_type>(rhs.d_size))
{
// Copy-construct all of `rhs`'s elements into the current buffer.
for(size_type i = 0; i < d_size; ++i)
{
d_buff[i].construct(rhs.d_buff[i].get());
}
}
~vector()
{
// Destroy all elements in the vector. In the Standard, the order of
// destruction is unspecified.
for(size_type i = 0; i < d_size; ++i)
{
d_buff[i].destroy();
}
}
vector<T>& operator=(const vector<T>& rhs);
// The copy-constructor allocates enough memory to store `rhs`'s
// elements in a new buffer, copies over the current elements to the
// new buffer, and finally sets `d_buff` to point to the new buffer.
size_type size() const { return d_size; }
size_type capacity() const { return d_capacity; }
bool empty() const { return d_size == 0; }
iterator begin() { return iterator(d_buff.get()); }
iterator begin() const { return iterator(d_buff.get()); }
iterator end() { return iterator(d_buff.get() + d_size); }
iterator end() const { return iterator(d_buff.get() + d_size); }
const_iterator cbegin() const { return const_iterator(d_buff.get()); }
const_iterator cend() const { return const_iterator(d_buff.get() + d_size); }
reference front() { return d_buff[0].get(); }
const_reference front() const { return d_buff[0].get(); }
reference back() { return d_buff[d_size - 1].get(); }
const_reference back() const { return d_buff[d_size - 1].get(); }
reference operator[](size_type i) { return d_buff[i].get(); }
const_reference operator[](size_type i) const { return d_buff[i].get(); }
reference at(size_type i)
{
if(i >= d_size)
{
throw std::out_of_range("Index out of range");
}
else
{
return d_buff[i].get();
}
}
const_reference at(size_type i) const
{
// The following use of `const_cast` is legal and simply prevents code
// repetition with the non-`const` version of `at`.
return const_cast<vector<T>&>(*this).at(i);
}
void push_back(const T& item);
void push_back(T&& item);
void pop_back();
void clear();
void reserve(size_type new_capacity);
};
template <typename T>
void vector<T>::push_back(const T& item)
{
if(d_size >= d_capacity)
{
const size_type new_capacity = (d_capacity == 0) ? 1
: d_capacity * 2;
reserve(new_capacity);
}
d_buff[d_size++].construct(item);
}
template <typename T>
void vector<T>::push_back(T&& item)
{
if(d_size >= d_capacity)
{
const size_type new_capacity = (d_capacity == 0) ? 1
: d_capacity * 2;
reserve(new_capacity);
}
d_buff[d_size++].construct(std::move(item));
}
template <typename T>
void vector<T>::pop_back()
{
BSLS_ASSERT(!empty());
d_buff[d_size - 1].destroy();
--d_size;
}
template <typename T>
void vector<T>::clear()
{
// Destroy all existing elements
for(size_type i = 0; i < d_size; ++i)
{
d_buff[i].destroy();
}
// Set size to zero, but leave capacity unchanged
d_size = 0;
}
template <typename T>
vector<T>& vector<T>::operator=(const vector& rhs)
{
// Prevent self-assignment
if(&rhs != this)
{
// Destroy all existing elements and set size to zero
clear();
// Reserve if necessary
reserve(rhs.d_size);
// Copy elements from `rhs`
for(size_type i = 0; i < rhs.d_size; ++i)
{
d_buff[i].construct(rhs.d_buff[i].get());
}
// Update size
d_size = rhs.d_size;
}
return *this;
}
template <typename T>
void vector<T>::reserve(size_type new_capacity)
{
// Exit early if there's no need to reserve more memory
if(new_capacity <= d_capacity) { return; }
// Allocate a new buffer
auto buff = std::make_unique<buff_type>(new_capacity);
// Copy-construct existing elements into the new buffer and destroy them
// in the old one
for(size_type i = 0; i < d_size; ++i)
{
buff[i].construct(std::move(d_buff[i].get()));
d_buff[i].destroy();
}
// Deallocate old buffer, set the owned buffer to `buff`
d_buff = std::move(buff);
// Update capacity
d_capacity = new_capacity;
}
} // close namespace trnx
#endif

View File

@@ -0,0 +1,106 @@
#ifndef INCLUDED_TRNX_VECTOR_IMPL
#define INCLUDED_TRNX_VECTOR_IMPL
#include <cstddef>
#include <exception>
#include <iterator>
#include <type_traits>
namespace trnx {
namespace detail {
// This union is not meant to be shown/completely understood from the students.
//
// They should know that `uninitialized<T>` means "enough storage for a `T`
// instance, and that they can manually control the lifetime of that instance
// through the `.construct` and `.destroy` member functions.
//
// It is undefined behavior to:
// * Call `construct` on an already-initialized instance.
// * Call `destroy` on a non-initialized instance.
// * Access the reference returned by `get` on a non-initialized instance.
//
template <typename T>
union uninitialized
{
private:
T d_datum;
public:
using inner_type = T;
uninitialized() { }
~uninitialized() { }
template <typename... Ts>
void construct(Ts&&... xs)
{
new (&d_datum) T(std::forward<Ts>(xs)...);
}
void destroy()
{
d_datum.~T();
}
T& get() { return d_datum; }
const T& get() const { return d_datum; }
};
// This class is not meant to be shown/completely understood from the students.
//
// It basically unwraps `uninitialized<T>` upon dereference, behaving as any
// other normal random access iterator, transparently to the user.
//
template <typename T>
class iter_impl
{
private:
T* d_ptr;
using inner_type = typename T::inner_type;
public:
using difference_type = std::ptrdiff_t;
using value_type = inner_type;
using pointer = inner_type*;
using reference = inner_type&;
using iterator_category = std::random_access_iterator_tag;
iter_impl() : d_ptr(nullptr) { }
iter_impl(T* rhs) : d_ptr(rhs) { }
iter_impl(const iter_impl& rhs) : d_ptr(rhs.d_ptr) { }
iter_impl& operator=(const iter_impl &rhs) { d_ptr = rhs.d_ptr; return *this; }
iter_impl& operator+=(difference_type rhs) { d_ptr += rhs; return *this; }
iter_impl& operator-=(difference_type rhs) { d_ptr -= rhs; return *this; }
inner_type& operator*() const { return d_ptr->get(); }
inner_type* operator->() const { return &d_ptr->get(); }
inner_type& operator[](difference_type rhs) const { return d_ptr[rhs]; }
iter_impl& operator++() { ++d_ptr; return *this; }
iter_impl& operator--() { --d_ptr; return *this; }
iter_impl operator++(int) { iter_impl tmp(*this); ++d_ptr; return tmp; }
iter_impl operator--(int) { iter_impl tmp(*this); --d_ptr; return tmp; }
difference_type operator-(const iter_impl& rhs) const { return iter_impl(d_ptr - rhs.ptr); }
iter_impl operator+(difference_type rhs) const { return iter_impl(d_ptr + rhs); }
iter_impl operator-(difference_type rhs) const { return iter_impl(d_ptr - rhs); }
friend iter_impl operator+(difference_type lhs, const iter_impl& rhs) { return iter_impl(lhs + rhs.d_ptr); }
friend iter_impl operator-(difference_type lhs, const iter_impl& rhs) { return iter_impl(lhs - rhs.d_ptr); }
bool operator==(const iter_impl& rhs) const { return d_ptr == rhs.d_ptr; }
bool operator!=(const iter_impl& rhs) const { return d_ptr != rhs.d_ptr; }
bool operator>(const iter_impl& rhs) const { return d_ptr > rhs.d_ptr; }
bool operator<(const iter_impl& rhs) const { return d_ptr < rhs.d_ptr; }
bool operator>=(const iter_impl& rhs) const { return d_ptr >= rhs.d_ptr; }
bool operator<=(const iter_impl& rhs) const { return d_ptr <= rhs.d_ptr; }
};
} // close namespace detail
} // close namespace trnx
#endif