simplestl.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. // Tencent is pleased to support the open source community by making ncnn available.
  2. //
  3. // Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
  4. //
  5. // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // https://opensource.org/licenses/BSD-3-Clause
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed
  11. // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  12. // CONDITIONS OF ANY KIND, either express or implied. See the License for the
  13. // specific language governing permissions and limitations under the License.
  14. #ifndef NCNN_SIMPLESTL_H
  15. #define NCNN_SIMPLESTL_H
  16. #include <stddef.h>
  17. #include <stdint.h>
  18. #include <string.h>
  19. #if !NCNN_SIMPLESTL
  20. #include <new>
  21. #else
  22. // allocation functions
  23. NCNN_EXPORT void* operator new(size_t size);
  24. NCNN_EXPORT void* operator new[](size_t size);
  25. // placement allocation functions
  26. NCNN_EXPORT void* operator new(size_t size, void* ptr);
  27. NCNN_EXPORT void* operator new[](size_t size, void* ptr);
  28. // deallocation functions
  29. NCNN_EXPORT void operator delete(void* ptr);
  30. NCNN_EXPORT void operator delete[](void* ptr);
  31. // deallocation functions since c++14
  32. #if __cplusplus >= 201402L
  33. NCNN_EXPORT void operator delete(void* ptr, size_t sz);
  34. NCNN_EXPORT void operator delete[](void* ptr, size_t sz);
  35. #endif
  36. // placement deallocation functions
  37. NCNN_EXPORT void operator delete(void* ptr, void* voidptr2);
  38. NCNN_EXPORT void operator delete[](void* ptr, void* voidptr2);
  39. #endif
  40. // minimal stl data structure implementation
  41. namespace std {
  42. template<typename T>
  43. const T& max(const T& a, const T& b)
  44. {
  45. return (a < b) ? b : a;
  46. }
  47. template<typename T>
  48. const T& min(const T& a, const T& b)
  49. {
  50. return (a > b) ? b : a;
  51. }
  52. template<typename T>
  53. void swap(T& a, T& b)
  54. {
  55. T temp(a);
  56. a = b;
  57. b = temp;
  58. }
  59. template<typename T1, typename T2>
  60. struct pair
  61. {
  62. pair()
  63. : first(), second()
  64. {
  65. }
  66. pair(const T1& t1, const T2& t2)
  67. : first(t1), second(t2)
  68. {
  69. }
  70. T1 first;
  71. T2 second;
  72. };
  73. template<typename T1, typename T2>
  74. bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y)
  75. {
  76. return (x.first == y.first && x.second == y.second);
  77. }
  78. template<typename T1, typename T2>
  79. bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y)
  80. {
  81. return x.first < y.first || (!(y.first < x.first) && x.second < y.second);
  82. }
  83. template<typename T1, typename T2>
  84. bool operator!=(const pair<T1, T2>& x, const pair<T1, T2>& y)
  85. {
  86. return !(x == y);
  87. }
  88. template<typename T1, typename T2>
  89. bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y)
  90. {
  91. return y < x;
  92. }
  93. template<typename T1, typename T2>
  94. bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y)
  95. {
  96. return !(y < x);
  97. }
  98. template<typename T1, typename T2>
  99. bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y)
  100. {
  101. return !(x < y);
  102. }
  103. template<typename T1, typename T2>
  104. pair<T1, T2> make_pair(const T1& t1, const T2& t2)
  105. {
  106. return pair<T1, T2>(t1, t2);
  107. }
  108. template<typename T>
  109. struct node
  110. {
  111. node* prev_;
  112. node* next_;
  113. T data_;
  114. node()
  115. : prev_(0), next_(0), data_()
  116. {
  117. }
  118. node(const T& t)
  119. : prev_(0), next_(0), data_(t)
  120. {
  121. }
  122. };
  123. template<typename T>
  124. struct iter_list
  125. {
  126. iter_list()
  127. : curr_(0)
  128. {
  129. }
  130. iter_list(node<T>* n)
  131. : curr_(n)
  132. {
  133. }
  134. iter_list(const iter_list& i)
  135. : curr_(i.curr_)
  136. {
  137. }
  138. ~iter_list()
  139. {
  140. }
  141. iter_list& operator=(const iter_list& i)
  142. {
  143. curr_ = i.curr_;
  144. return *this;
  145. }
  146. T& operator*()
  147. {
  148. return curr_->data_;
  149. }
  150. T* operator->()
  151. {
  152. return &(curr_->data_);
  153. }
  154. bool operator==(const iter_list& i)
  155. {
  156. return curr_ == i.curr_;
  157. }
  158. bool operator!=(const iter_list& i)
  159. {
  160. return curr_ != i.curr_;
  161. }
  162. iter_list& operator++()
  163. {
  164. curr_ = curr_->next_;
  165. return *this;
  166. }
  167. iter_list& operator--()
  168. {
  169. curr_ = curr_->prev_;
  170. return *this;
  171. }
  172. node<T>* curr_;
  173. };
  174. template<typename T>
  175. struct list
  176. {
  177. typedef iter_list<T> iterator;
  178. list()
  179. {
  180. head_ = new node<T>();
  181. tail_ = head_;
  182. count_ = 0;
  183. }
  184. ~list()
  185. {
  186. clear();
  187. delete head_;
  188. }
  189. list(const list& l)
  190. {
  191. head_ = new node<T>();
  192. tail_ = head_;
  193. count_ = 0;
  194. for (iter_list<T> i = l.begin(); i != l.end(); ++i)
  195. {
  196. push_back(*i);
  197. }
  198. }
  199. list& operator=(const list& l)
  200. {
  201. if (this == &l)
  202. {
  203. return *this;
  204. }
  205. clear();
  206. for (iter_list<T> i = l.begin(); i != l.end(); ++i)
  207. {
  208. push_back(*i);
  209. }
  210. return *this;
  211. }
  212. void clear()
  213. {
  214. while (count_ > 0)
  215. {
  216. pop_front();
  217. }
  218. }
  219. void pop_front()
  220. {
  221. if (count_ > 0)
  222. {
  223. head_ = head_->next_;
  224. delete head_->prev_;
  225. head_->prev_ = 0;
  226. --count_;
  227. }
  228. }
  229. size_t size() const
  230. {
  231. return count_;
  232. }
  233. iter_list<T> begin() const
  234. {
  235. return iter_list<T>(head_);
  236. }
  237. iter_list<T> end() const
  238. {
  239. return iter_list<T>(tail_);
  240. }
  241. bool empty() const
  242. {
  243. return count_ == 0;
  244. }
  245. void push_back(const T& t)
  246. {
  247. if (count_ == 0)
  248. {
  249. head_ = new node<T>(t);
  250. head_->prev_ = 0;
  251. head_->next_ = tail_;
  252. tail_->prev_ = head_;
  253. count_ = 1;
  254. }
  255. else
  256. {
  257. node<T>* temp = new node<T>(t);
  258. temp->prev_ = tail_->prev_;
  259. temp->next_ = tail_;
  260. tail_->prev_->next_ = temp;
  261. tail_->prev_ = temp;
  262. ++count_;
  263. }
  264. }
  265. iter_list<T> erase(iter_list<T> pos)
  266. {
  267. if (pos != end())
  268. {
  269. node<T>* temp = pos.curr_;
  270. if (temp == head_)
  271. {
  272. ++pos;
  273. temp->next_->prev_ = 0;
  274. head_ = temp->next_;
  275. }
  276. else
  277. {
  278. --pos;
  279. temp->next_->prev_ = temp->prev_;
  280. temp->prev_->next_ = temp->next_;
  281. ++pos;
  282. }
  283. delete temp;
  284. --count_;
  285. }
  286. return pos;
  287. }
  288. protected:
  289. node<T>* head_;
  290. node<T>* tail_;
  291. size_t count_;
  292. };
  293. template<typename T>
  294. struct greater
  295. {
  296. bool operator()(const T& x, const T& y) const
  297. {
  298. return (x > y);
  299. }
  300. };
  301. template<typename T>
  302. struct less
  303. {
  304. bool operator()(const T& x, const T& y) const
  305. {
  306. return (x < y);
  307. }
  308. };
  309. template<typename RandomAccessIter, typename Compare>
  310. void partial_sort(RandomAccessIter first, RandomAccessIter middle, RandomAccessIter last, Compare comp)
  311. {
  312. // [TODO] heap sort should be used here, but we simply use bubble sort now
  313. for (RandomAccessIter i = first; i < middle; ++i)
  314. {
  315. // bubble sort
  316. for (RandomAccessIter j = last - 1; j > first; --j)
  317. {
  318. if (comp(*j, *(j - 1)))
  319. {
  320. swap(*j, *(j - 1));
  321. }
  322. }
  323. }
  324. }
  325. template<typename T>
  326. struct vector
  327. {
  328. vector()
  329. : data_(0), size_(0), capacity_(0)
  330. {
  331. }
  332. vector(const size_t new_size, const T& value = T())
  333. : data_(0), size_(0), capacity_(0)
  334. {
  335. resize(new_size, value);
  336. }
  337. ~vector()
  338. {
  339. clear();
  340. }
  341. vector(const vector& v)
  342. : data_(0), size_(0), capacity_(0)
  343. {
  344. resize(v.size());
  345. for (size_t i = 0; i < size_; i++)
  346. {
  347. data_[i] = v.data_[i];
  348. }
  349. }
  350. vector& operator=(const vector& v)
  351. {
  352. if (this == &v)
  353. {
  354. return *this;
  355. }
  356. resize(0);
  357. resize(v.size());
  358. for (size_t i = 0; i < size_; i++)
  359. {
  360. data_[i] = v.data_[i];
  361. }
  362. return *this;
  363. }
  364. void resize(const size_t new_size, const T& value = T())
  365. {
  366. try_alloc(new_size);
  367. if (new_size > size_)
  368. {
  369. for (size_t i = size_; i < new_size; i++)
  370. {
  371. new (&data_[i]) T(value);
  372. }
  373. }
  374. else if (new_size < size_)
  375. {
  376. for (size_t i = new_size; i < size_; i++)
  377. {
  378. data_[i].~T();
  379. }
  380. }
  381. size_ = new_size;
  382. }
  383. void clear()
  384. {
  385. for (size_t i = 0; i < size_; i++)
  386. {
  387. data_[i].~T();
  388. }
  389. delete[](char*) data_;
  390. data_ = 0;
  391. size_ = 0;
  392. capacity_ = 0;
  393. }
  394. T* data() const
  395. {
  396. return data_;
  397. }
  398. size_t size() const
  399. {
  400. return size_;
  401. }
  402. T& operator[](size_t i) const
  403. {
  404. return data_[i];
  405. }
  406. T* begin() const
  407. {
  408. return &data_[0];
  409. }
  410. T* end() const
  411. {
  412. return &data_[size_];
  413. }
  414. bool empty() const
  415. {
  416. return size_ == 0;
  417. }
  418. void push_back(const T& t)
  419. {
  420. try_alloc(size_ + 1);
  421. new (&data_[size_]) T(t);
  422. size_++;
  423. }
  424. void insert(T* pos, T* b, T* e)
  425. {
  426. vector* v = 0;
  427. if (b >= begin() && b < end())
  428. {
  429. //the same vector
  430. v = new vector(*this);
  431. b = v->begin() + (b - begin());
  432. e = v->begin() + (e - begin());
  433. }
  434. size_t diff = pos - begin();
  435. try_alloc(size_ + (e - b));
  436. pos = begin() + diff;
  437. memmove(pos + (e - b), pos, (end() - pos) * sizeof(T));
  438. size_t len = e - b;
  439. size_ += len;
  440. for (size_t i = 0; i < len; i++)
  441. {
  442. *pos = *b;
  443. pos++;
  444. b++;
  445. }
  446. delete v;
  447. }
  448. T* erase(T* pos)
  449. {
  450. pos->~T();
  451. memmove(pos, pos + 1, (end() - pos - 1) * sizeof(T));
  452. size_--;
  453. return pos;
  454. }
  455. protected:
  456. T* data_;
  457. size_t size_;
  458. size_t capacity_;
  459. void try_alloc(size_t new_size)
  460. {
  461. if (new_size * 3 / 2 > capacity_ / 2)
  462. {
  463. capacity_ = new_size * 2;
  464. T* new_data = (T*)new char[capacity_ * sizeof(T)];
  465. memset(static_cast<void*>(new_data), 0, capacity_ * sizeof(T));
  466. if (data_)
  467. {
  468. memmove(new_data, data_, sizeof(T) * size_);
  469. delete[](char*) data_;
  470. }
  471. data_ = new_data;
  472. }
  473. }
  474. };
  475. struct NCNN_EXPORT string : public vector<char>
  476. {
  477. string()
  478. {
  479. }
  480. string(const char* str)
  481. {
  482. size_t len = strlen(str);
  483. resize(len);
  484. memcpy(data_, str, len);
  485. }
  486. const char* c_str() const
  487. {
  488. return (const char*)data_;
  489. }
  490. bool operator==(const string& str2) const
  491. {
  492. return strcmp(data_, str2.data_) == 0;
  493. }
  494. bool operator==(const char* str2) const
  495. {
  496. return strcmp(data_, str2) == 0;
  497. }
  498. bool operator!=(const char* str2) const
  499. {
  500. return strcmp(data_, str2) != 0;
  501. }
  502. string& operator+=(const string& str1)
  503. {
  504. insert(end(), str1.begin(), str1.end());
  505. return *this;
  506. }
  507. };
  508. inline string operator+(const string& str1, const string& str2)
  509. {
  510. string str(str1);
  511. str.insert(str.end(), str2.begin(), str2.end());
  512. return str;
  513. }
  514. } // namespace std
  515. #endif // NCNN_SIMPLESTL_H