1 Star 0 Fork 6

C-Band / MLTool

forked from Yang9527 / MLTool 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
vector.h 15.77 KB
一键复制 编辑 原始数据 按行查看 历史
Yang9527 提交于 2013-09-01 18:45 . add numeric differential
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
#ifndef MLTOOL_VECTOR_H
#define MLTOOL_VECTOR_H
#include<iostream>
#include<memory>
#include<iterator>
#include<type_traits>
#include<algorithm>
#include"tags.h"
namespace math{
template<class T, class ALLOC = std::allocator<T> >
class vector
{
public:
typedef ALLOC allocator_type;
typedef typename ALLOC::size_type size_type;
typedef typename ALLOC::difference_type difference_type;
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef pointer iterator;
typedef const_pointer const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef vector_tag category;
//constructors
//default constructor
explicit vector(const allocator_type &a = allocator_type())
:alloc_(a), size_(0), data_(nullptr){
std::cout << "default constructor called!" << std::endl;
}
//non-init fill constructor
explicit vector(size_type sz, const allocator_type &a = allocator_type())
:alloc_(a), size_(sz), data_(nullptr)
{
std::cout << "non-init fill constructor called!" << std::endl;
if(size_)
{
data_ = alloc_.allocate(size_);
if(!std::has_trivial_default_constructor<T>::value)
for(pointer p = data_; p!= data_ + size_; ++p)
alloc_.construct(p);
}
}
//init fill constructor
vector(size_type sz, const value_type &init, const allocator_type &a = allocator_type())
:alloc_(a), size_(sz), data_(nullptr)
{
std::cout << "init fill constructor called!" << std::endl;
if(size_)
{
data_ = alloc_.allocate(size_);
std::uninitialized_fill_n(data_, size_, init);
}
}
//range constructor
template<class Iter>
vector(const Iter& first, const Iter& last,
const allocator_type &a = allocator_type(),
typename std::enable_if<!std::is_integral<Iter>::value, void>::type ** = 0)
:size_(last - first), data_(nullptr)
{
std::cout << "range constructor called!" << std::endl;
if(size_)
{
data_ = alloc_.allocate(size_);
std::uninitialized_copy(first, last, data_);
}
}
//copy constructor
vector(const vector &c)
:alloc_(c.alloc_), size_(c.size_), data_(nullptr)
{
std::cout << "copy constructor called!" << std::endl;
if(size_)
{
data_ = alloc_.allocate(size_);
std::uninitialized_copy(c.begin(), c.end(), begin());
}
}
//conversion
template<class U>
vector(const vector<U> &c)
:alloc_(), size_(c.size()), data_(nullptr)
{
std::cout << "conversion called!" << std::endl;
if(size_)
{
data_ = alloc_.allocate(size_);
std::uninitialized_copy(c.begin(), c.end(), begin());
}
}
//move constructor
vector(vector &&c)
:alloc_(c.alloc_), size_(0), data_(nullptr)
{
std::cout << "move constructor called!" << std::endl;
std::swap(size_, c.size_);
std::swap(data_, c.data_);
}
//assignment
vector& operator=(const vector &rhs)
{
std::cout << "assignment called!" << std::endl;
if(this != &rhs)
{
if(size_ == rhs.size_)
std::copy(rhs.begin(),rhs.end(),begin());
else
{
destroy_impl();
if(rhs.size_)
{
data_ = alloc_.allocate(rhs.size_);
std::uninitialized_copy(rhs.begin(), rhs.end(), data_);
}
size_ = rhs.size_;
}
}
return *this;
}
//move assignment
vector& operator=(vector &&rhs) noexcept
{
std::cout << "move assignment called!" << std::endl;
if(this != &rhs)
{
destroy_impl();
data_ = rhs.data_;
size_ = rhs.size_;
rhs.data_ = nullptr;
rhs.size_ = 0;
}
return *this;
}
//destructor
~vector()
{
std::cout << "destructor called!" << std::endl;
destroy_impl();
}
// +=, -=, *=, /=
template<class U>
vector& operator +=(const vector<U>& v)
{
for(size_type i = 0; i < size_; ++i)
data_[i] += v[i];
return *this;
}
template<class U>
vector& operator -=(const vector<U>& v)
{
for(size_type i = 0; i < size_; ++i)
data_[i] -= v[i];
return *this;
}
template<class U>
vector& operator *=(const vector<U>& v)
{
for(size_type i = 0; i < size_; ++i)
data_[i] *= v[i];
return *this;
}
template<class U>
vector& operator /=(const vector<U>& v)
{
for(size_type i = 0; i < size_; ++i)
data_[i] /= v[i];
return *this;
}
vector& operator +=(const value_type &t)
{
for(size_type i = 0; i < size_; ++i)
data_[i] += t;
return *this;
}
vector& operator -=(const value_type &t)
{
for(size_type i = 0; i < size_; ++i)
data_[i] -= t;
return *this;
}
vector& operator *=(const value_type &t)
{
for(size_type i = 0; i < size_; ++i)
data_[i] *= t;
return *this;
}
vector& operator /=(const value_type &t)
{
value_type tmp = 1.0/t;
this -> operator *=(tmp);
return *this;
}
//operator - (negative)
friend inline vector operator -(const vector &v1)
{
vector ans(v1.size());
for(size_type i = 0; i < v1.size_; ++i)
ans.data_[i] = -v1.data_[i];
return ans;
}
friend inline vector&& operator -(vector &&v)
{
v *= -1;
return std::move(v);
}
// operator +
friend inline vector operator +(const vector &v1, const vector &v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
std::cout << "1st called!" << std::endl;
vector ans(v1.size());
std::transform(v1.begin(), v1.end(), v2.begin(), ans.begin(), std::plus<value_type>());
return ans;
}
friend inline vector&& operator +(vector &&v1, const vector &v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
std::cout << "2nd called!" << std::endl;
return std::move(v1 += v2);
}
friend inline vector&& operator +(const vector &v1, vector &&v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
std::cout << "3rd called!" << std::endl;
return std::move(v2 += v1);
}
friend inline vector&& operator +(vector &&v1, vector &&v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
std::cout << "4th called!" << std::endl;
return std::move(v1 += v2);
}
// operator -
friend inline vector operator -(const vector &v1, const vector &v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
vector ans(v1.size());
std::transform(v1.begin(), v1.end(), v2.begin(), ans.begin(), std::minus<value_type>());
return ans;
}
friend inline vector&& operator -(vector &&v1, const vector &v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
return std::move(v1 -= v2);
}
friend inline vector&& operator -(const vector &v1, vector &&v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
std::transform(v1.begin(), v1.end(), v2.begin(), v2.begin(), std::minus<value_type>());
return std::move(v2);
}
friend inline vector&& operator -(vector &&v1, vector &&v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
return std::move(v1 -= v2);
}
// operator *
friend inline vector operator*(const vector &v1, const vector &v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
std::cout << "1st called!" << std::endl;
vector ans(v1.size());
std::transform(v1.begin(), v1.end(), v2.begin(), ans.begin(), std::multiplies<value_type>());
return ans;
}
friend inline vector&& operator*(vector &&v1, const vector &v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
std::cout << "2nd called!" << std::endl;
return std::move(v1*= v2);
}
friend inline vector&& operator*(const vector &v1, vector &&v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
std::cout << "3rd called!" << std::endl;
return std::move(v2*= v1);
}
friend inline vector&& operator*(vector &&v1, vector &&v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
std::cout << "4th called!" << std::endl;
return std::move(v1*= v2);
}
// operator /
friend inline vector operator /(const vector &v1, const vector &v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
vector ans(v1.size());
std::transform(v1.begin(), v1.end(), v2.begin(), ans.begin(), std::divides<value_type>());
return ans;
}
friend inline vector&& operator /(vector &&v1, const vector &v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
return std::move(v1 /= v2);
}
friend inline vector&& operator /(const vector &v1, vector &&v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
std::transform(v1.begin(), v1.end(), v2.begin(), v2.begin(), std::divides<value_type>());
return std::move(v2);
}
friend inline vector&& operator /(vector &&v1, vector &&v2)
{
#ifdef CHECK_DIMENSION_MATCH
assert(v1.size() == v2.size());
#endif
return std::move(v1 /= v2);
}
// +, -, * , / scalar
friend inline vector operator + (const vector &v, value_type t)
{
vector ans(v.size());
for(int i = 0; i < v.size(); ++i)
ans.data_[i] = t + v.data_[i];
return ans;
}
friend inline vector operator + (value_type t, const vector &v)
{
return v + t;
}
friend inline vector&& operator +(vector &&v, value_type t)
{
v += t;
return std::move(v);
}
friend inline vector&& operator +(value_type t, vector &&v)
{
v += t;
return std::move(v);
}
// *
friend inline vector operator * (const vector &v, value_type t)
{
vector ans(v.size());
for(int i = 0; i < v.size(); ++i)
ans.data_[i] = v.data_[i] * t;
return ans;
}
friend inline vector operator * (value_type t, const vector &v)
{
return v * t;
}
friend inline vector&& operator *(vector &&v, value_type t)
{
v *= t;
return std::move(v);
}
friend inline vector&& operator *(value_type t, vector &&v)
{
v *= t;
return std::move(v);
}
// -
friend inline vector operator - (const vector &v, value_type t)
{
vector ans(v.size());
for(int i = 0; i < v.size(); ++i)
ans.data_[i] = v.data_[i] - t;
return ans;
}
friend inline vector operator - (value_type t, const vector &v)
{
vector ans(v.size());
for(int i = 0; i < v.size(); ++i)
ans.data_[i] = t - v.data_[i];
return ans;
}
friend inline vector&& operator -(vector &&v, value_type t)
{
v -= t;
return std::move(v);
}
friend inline vector&& operator -(value_type t, vector &&v)
{
for(size_type i = 0; i < v.size(); ++i)
v.data_[i] = t - v.data_[i];
return std::move(v);
}
// /
friend inline vector operator / (const vector &v, value_type t)
{
vector ans(v.size());
for(int i = 0; i < v.size(); ++i)
ans.data_[i] = v.data_[i] / t;
return ans;
}
friend inline vector operator / (value_type t, const vector &v)
{
vector ans(v.size());
for(int i = 0; i < v.size(); ++i)
ans.data_[i] = t / v.data_[i];
return ans;
}
friend inline vector&& operator /(vector &&v, value_type t)
{
v /= t;
return std::move(v);
}
friend inline vector&& operator /(value_type t, vector &&v)
{
for(size_type i = 0; i < v.size(); ++i)
v.data_[i] = t / v.data_[i];
return std::move(v);
}
size_type size() const
{
return size_;
}
size_type max_size() const
{
return alloc_.max_size();
}
bool empty() const
{
return !data_;
}
reference operator[](size_type i)
{
return data_[i];
}
const_reference operator[](size_type i) const
{
return data_[i];
}
iterator begin()
{
return data_;
}
const_iterator begin() const
{
return data_;
}
pointer data()
{
return data_;
}
const_pointer data() const
{
return data_;
}
iterator end()
{
return data_ + size_;
}
const_iterator end() const
{
return data_ + size_;
}
reverse_iterator rbegin()
{
return reverse_iterator(end());
}
const_reverse_iterator rbegin() const
{
return const_reverse_iterator(end());
}
reverse_iterator rend()
{
return reverse_iterator(begin());
}
const_reverse_iterator rend() const
{
return const_reverse_iterator(begin());
}
//swap
void swap(vector &tmp)
{
std::cout << "swap called!" << std::endl;
if(this != &tmp)
{
std::swap(size_, tmp.size_);
std::swap(data_, tmp.data_);
}
}
friend void swap(vector &a1, vector &a2)
{
a1.swap(a2);
}
//resize
void resize(size_type sz, bool preserve = false)
{
resize_impl(sz,preserve);
}
protected:
ALLOC alloc_;
pointer data_;
size_type size_;
inline void destroy_impl()
{
if(size_)
{
if(!std::is_trivially_destructible<T>::value)
for(pointer p = data_; p != data_ + size_; ++p)
alloc_.destroy(p);
alloc_.deallocate(data_, size_);
}
}
void resize_impl(size_type sz_new, bool preserve)
{
if(size_ != sz_new)
{
pointer data_old = data_;
data_ = nullptr;
size_type sz_old = size_;
size_ = sz_new;
if(sz_new)
{
data_ = alloc_.allocate(sz_new);
if(preserve)
{
pointer si = data_old; //source
pointer di = data_; //destination
if(sz_new < sz_old)
{
for(; di != data_ + sz_new; ++di)
{
alloc_.construct(di, *si);
++si;
}
}
else //sz_new > sz_old
{
for(; di != data_ + sz_old; ++di)
{
alloc_.construct(di, *si);
++si;
}
value_type init = value_type();
for(; di != data_ + sz_new; ++di)
alloc_.construct(di, init);
}
}
else //preserve == false
if(!std::has_trivial_default_constructor<T>::value)
for(pointer di = data_; di != data_ + sz_new; ++di)
alloc_.construct(di);
}
if(sz_old)
{
if(!std::is_trivially_destructible<T>::value)
for(pointer p = data_old; p != data_old + sz_old; ++p)
alloc_.destroy(p);
alloc_.deallocate(data_old, sz_old);
}
}
}
};
} //namespace math
#endif
C++
1
https://gitee.com/C-BAND/mltool.git
git@gitee.com:C-BAND/mltool.git
C-BAND
mltool
MLTool
master

搜索帮助