ss928_framework/thridpart/ncnn/include/simplestl.h

566 lines
11 KiB
C
Raw Normal View History

2024-12-16 13:31:45 +08:00
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef NCNN_SIMPLESTL_H
#define NCNN_SIMPLESTL_H
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#if !NCNN_SIMPLESTL
#include <new>
#else
// allocation functions
NCNN_EXPORT void* operator new(size_t size);
NCNN_EXPORT void* operator new[](size_t size);
// placement allocation functions
NCNN_EXPORT void* operator new(size_t size, void* ptr);
NCNN_EXPORT void* operator new[](size_t size, void* ptr);
// deallocation functions
NCNN_EXPORT void operator delete(void* ptr);
NCNN_EXPORT void operator delete[](void* ptr);
// deallocation functions since c++14
#if __cplusplus >= 201402L
NCNN_EXPORT void operator delete(void* ptr, size_t sz);
NCNN_EXPORT void operator delete[](void* ptr, size_t sz);
#endif
// placement deallocation functions
NCNN_EXPORT void operator delete(void* ptr, void* voidptr2);
NCNN_EXPORT void operator delete[](void* ptr, void* voidptr2);
#endif
// minimal stl data structure implementation
namespace std {
template<typename T>
const T& max(const T& a, const T& b)
{
return (a < b) ? b : a;
}
template<typename T>
const T& min(const T& a, const T& b)
{
return (a > b) ? b : a;
}
template<typename T>
void swap(T& a, T& b)
{
T temp(a);
a = b;
b = temp;
}
template<typename T1, typename T2>
struct pair
{
pair()
: first(), second()
{
}
pair(const T1& t1, const T2& t2)
: first(t1), second(t2)
{
}
T1 first;
T2 second;
};
template<typename T1, typename T2>
bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y)
{
return (x.first == y.first && x.second == y.second);
}
template<typename T1, typename T2>
bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y)
{
return x.first < y.first || (!(y.first < x.first) && x.second < y.second);
}
template<typename T1, typename T2>
bool operator!=(const pair<T1, T2>& x, const pair<T1, T2>& y)
{
return !(x == y);
}
template<typename T1, typename T2>
bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y)
{
return y < x;
}
template<typename T1, typename T2>
bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y)
{
return !(y < x);
}
template<typename T1, typename T2>
bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y)
{
return !(x < y);
}
template<typename T1, typename T2>
pair<T1, T2> make_pair(const T1& t1, const T2& t2)
{
return pair<T1, T2>(t1, t2);
}
template<typename T>
struct node
{
node* prev_;
node* next_;
T data_;
node()
: prev_(0), next_(0), data_()
{
}
node(const T& t)
: prev_(0), next_(0), data_(t)
{
}
};
template<typename T>
struct iter_list
{
iter_list()
: curr_(0)
{
}
iter_list(node<T>* n)
: curr_(n)
{
}
iter_list(const iter_list& i)
: curr_(i.curr_)
{
}
~iter_list()
{
}
iter_list& operator=(const iter_list& i)
{
curr_ = i.curr_;
return *this;
}
T& operator*()
{
return curr_->data_;
}
T* operator->()
{
return &(curr_->data_);
}
bool operator==(const iter_list& i)
{
return curr_ == i.curr_;
}
bool operator!=(const iter_list& i)
{
return curr_ != i.curr_;
}
iter_list& operator++()
{
curr_ = curr_->next_;
return *this;
}
iter_list& operator--()
{
curr_ = curr_->prev_;
return *this;
}
node<T>* curr_;
};
template<typename T>
struct list
{
typedef iter_list<T> iterator;
list()
{
head_ = new node<T>();
tail_ = head_;
count_ = 0;
}
~list()
{
clear();
delete head_;
}
list(const list& l)
{
head_ = new node<T>();
tail_ = head_;
count_ = 0;
for (iter_list<T> i = l.begin(); i != l.end(); ++i)
{
push_back(*i);
}
}
list& operator=(const list& l)
{
if (this == &l)
{
return *this;
}
clear();
for (iter_list<T> i = l.begin(); i != l.end(); ++i)
{
push_back(*i);
}
return *this;
}
void clear()
{
while (count_ > 0)
{
pop_front();
}
}
void pop_front()
{
if (count_ > 0)
{
head_ = head_->next_;
delete head_->prev_;
head_->prev_ = 0;
--count_;
}
}
size_t size() const
{
return count_;
}
iter_list<T> begin() const
{
return iter_list<T>(head_);
}
iter_list<T> end() const
{
return iter_list<T>(tail_);
}
bool empty() const
{
return count_ == 0;
}
void push_back(const T& t)
{
if (count_ == 0)
{
head_ = new node<T>(t);
head_->prev_ = 0;
head_->next_ = tail_;
tail_->prev_ = head_;
count_ = 1;
}
else
{
node<T>* temp = new node<T>(t);
temp->prev_ = tail_->prev_;
temp->next_ = tail_;
tail_->prev_->next_ = temp;
tail_->prev_ = temp;
++count_;
}
}
iter_list<T> erase(iter_list<T> pos)
{
if (pos != end())
{
node<T>* temp = pos.curr_;
if (temp == head_)
{
++pos;
temp->next_->prev_ = 0;
head_ = temp->next_;
}
else
{
--pos;
temp->next_->prev_ = temp->prev_;
temp->prev_->next_ = temp->next_;
++pos;
}
delete temp;
--count_;
}
return pos;
}
protected:
node<T>* head_;
node<T>* tail_;
size_t count_;
};
template<typename T>
struct greater
{
bool operator()(const T& x, const T& y) const
{
return (x > y);
}
};
template<typename T>
struct less
{
bool operator()(const T& x, const T& y) const
{
return (x < y);
}
};
template<typename RandomAccessIter, typename Compare>
void partial_sort(RandomAccessIter first, RandomAccessIter middle, RandomAccessIter last, Compare comp)
{
// [TODO] heap sort should be used here, but we simply use bubble sort now
for (RandomAccessIter i = first; i < middle; ++i)
{
// bubble sort
for (RandomAccessIter j = last - 1; j > first; --j)
{
if (comp(*j, *(j - 1)))
{
swap(*j, *(j - 1));
}
}
}
}
template<typename T>
struct vector
{
vector()
: data_(0), size_(0), capacity_(0)
{
}
vector(const size_t new_size, const T& value = T())
: data_(0), size_(0), capacity_(0)
{
resize(new_size, value);
}
~vector()
{
clear();
}
vector(const vector& v)
: data_(0), size_(0), capacity_(0)
{
resize(v.size());
for (size_t i = 0; i < size_; i++)
{
data_[i] = v.data_[i];
}
}
vector& operator=(const vector& v)
{
if (this == &v)
{
return *this;
}
resize(0);
resize(v.size());
for (size_t i = 0; i < size_; i++)
{
data_[i] = v.data_[i];
}
return *this;
}
void resize(const size_t new_size, const T& value = T())
{
try_alloc(new_size);
if (new_size > size_)
{
for (size_t i = size_; i < new_size; i++)
{
new (&data_[i]) T(value);
}
}
else if (new_size < size_)
{
for (size_t i = new_size; i < size_; i++)
{
data_[i].~T();
}
}
size_ = new_size;
}
void clear()
{
for (size_t i = 0; i < size_; i++)
{
data_[i].~T();
}
delete[](char*) data_;
data_ = 0;
size_ = 0;
capacity_ = 0;
}
T* data() const
{
return data_;
}
size_t size() const
{
return size_;
}
T& operator[](size_t i) const
{
return data_[i];
}
T* begin() const
{
return &data_[0];
}
T* end() const
{
return &data_[size_];
}
bool empty() const
{
return size_ == 0;
}
void push_back(const T& t)
{
try_alloc(size_ + 1);
new (&data_[size_]) T(t);
size_++;
}
void insert(T* pos, T* b, T* e)
{
vector* v = 0;
if (b >= begin() && b < end())
{
//the same vector
v = new vector(*this);
b = v->begin() + (b - begin());
e = v->begin() + (e - begin());
}
size_t diff = pos - begin();
try_alloc(size_ + (e - b));
pos = begin() + diff;
memmove(pos + (e - b), pos, (end() - pos) * sizeof(T));
size_t len = e - b;
size_ += len;
for (size_t i = 0; i < len; i++)
{
*pos = *b;
pos++;
b++;
}
delete v;
}
T* erase(T* pos)
{
pos->~T();
memmove(pos, pos + 1, (end() - pos - 1) * sizeof(T));
size_--;
return pos;
}
protected:
T* data_;
size_t size_;
size_t capacity_;
void try_alloc(size_t new_size)
{
if (new_size * 3 / 2 > capacity_ / 2)
{
capacity_ = new_size * 2;
T* new_data = (T*)new char[capacity_ * sizeof(T)];
memset(static_cast<void*>(new_data), 0, capacity_ * sizeof(T));
if (data_)
{
memmove(new_data, data_, sizeof(T) * size_);
delete[](char*) data_;
}
data_ = new_data;
}
}
};
struct NCNN_EXPORT string : public vector<char>
{
string()
{
}
string(const char* str)
{
size_t len = strlen(str);
resize(len);
memcpy(data_, str, len);
}
const char* c_str() const
{
return (const char*)data_;
}
bool operator==(const string& str2) const
{
return strcmp(data_, str2.data_) == 0;
}
bool operator==(const char* str2) const
{
return strcmp(data_, str2) == 0;
}
bool operator!=(const char* str2) const
{
return strcmp(data_, str2) != 0;
}
string& operator+=(const string& str1)
{
insert(end(), str1.begin(), str1.end());
return *this;
}
};
inline string operator+(const string& str1, const string& str2)
{
string str(str1);
str.insert(str.end(), str2.begin(), str2.end());
return str;
}
} // namespace std
#endif // NCNN_SIMPLESTL_H