-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit c77a3a3
Showing
8 changed files
with
944 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# bcc3.1_stl | ||
|
||
STL Implementation for Borland C++ compiler from 1992 written as a utility library for an OS project at School of Electrical Engineering, University of Belgrade in 2016. | ||
|
||
BCC 3.1 is very old, but it provides a simple way of tempering with interrupt routines on DOS which makes it a suitable tool for teaching OS courses. | ||
|
||
Feel free to contribute tests and comments and expand the library for the future generations which will be doing similar projects using BCC 3.1 at University of Belgrade or other universities. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
// File: algo.h | ||
// Author: Viktor Slavkovic | ||
// Date: May 2016 | ||
|
||
#ifndef ALGORITHM_H_INCLUDED | ||
#define ALGORITHM_H_INCLUDED | ||
|
||
//////////////////////////////////////////////////////////////////////////////// | ||
// Modifying sequence operations: | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
template <class T> | ||
void swap(T& a, T& b) { | ||
T temp(a); | ||
a = b; | ||
b = temp; | ||
} | ||
|
||
//////////////////////////////////////////////////////////////////////////////// | ||
// Min / max: | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
template <class T> | ||
const T& min(const T& a, const T& b) { | ||
return b < a ? b : a; | ||
} | ||
|
||
template <class T> | ||
const T& max(const T& a, const T& b) { | ||
return a < b ? b : a; | ||
} | ||
|
||
//////////////////////////////////////////////////////////////////////////////// | ||
// Heap: | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
template <class RandomAccessIterator> | ||
void push_heap(RandomAccessIterator first, RandomAccessIterator last) { | ||
_heap_percolate_up(first, last - first - 1); | ||
} | ||
|
||
template <class RandomAccessIterator, class Compare> | ||
void push_heap(RandomAccessIterator first, RandomAccessIterator last, | ||
Compare comp) { | ||
_heap_percolate_up(first, last - first - 1, comp); | ||
} | ||
|
||
template <class RandomAccessIterator> | ||
void pop_heap(RandomAccessIterator first, RandomAccessIterator last) { | ||
int n = last - first; | ||
swap(first[0], first[n - 1]); | ||
_heap_percolate_down(first, n - 1, 0); | ||
} | ||
|
||
template <class RandomAccessIterator, class Compare> | ||
void pop_heap(RandomAccessIterator first, RandomAccessIterator last, | ||
Compare comp) { | ||
int n = last - first; | ||
swap(first[0], first[n - 1]); | ||
_heap_percolate_down(first, n - 1, 0, comp); | ||
} | ||
|
||
template <class RandomAccessIterator> | ||
void make_heap(RandomAccessIterator first, RandomAccessIterator last) { | ||
int n = last - first; | ||
for (int i = n / 2; i >= 0; i--) _heap_percolate_down(first, n, i); | ||
} | ||
|
||
template <class RandomAccessIterator, class Compare> | ||
void make_heap(RandomAccessIterator first, RandomAccessIterator last, | ||
Compare comp) { | ||
int n = last - first; | ||
for (int i = n / 2; i >= 0; i--) _heap_percolate_down(first, n, i, comp); | ||
} | ||
|
||
//////////////////////////////////////////////////////////////////////////////// | ||
// Helper functions | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
template <class RandomAccessIterator> | ||
int _heap_min_child_idx(RandomAccessIterator first, int n, int idx) { | ||
int l = idx * 2 + 1; | ||
int r = (idx + 1) * 2; | ||
if (l >= n && r >= n) return -1; | ||
if (l >= n) return r; | ||
if (r >= n) return l; | ||
return (first[r] < first[l]) ? r : l; | ||
} | ||
|
||
template <class RandomAccessIterator, class Compare> | ||
int _heap_min_child_idx(RandomAccessIterator first, int n, int idx, | ||
Compare comp) { | ||
int l = idx * 2 + 1; | ||
int r = (idx + 1) * 2; | ||
if (l >= n && r >= n) return -1; | ||
if (l >= n) return r; | ||
if (r >= n) return l; | ||
return (comp(first[r], first[l])) ? r : l; | ||
} | ||
|
||
template <class RandomAccessIterator> | ||
void _heap_percolate_up(RandomAccessIterator first, int idx) { | ||
int p = (idx - 1) / 2; | ||
while (idx && first[idx] < first[p]) { | ||
swap(first[p], first[idx]); | ||
idx = p; | ||
p = (idx - 1) / 2; | ||
} | ||
} | ||
|
||
template <class RandomAccessIterator, class Compare> | ||
void _heap_percolate_up(RandomAccessIterator first, int idx, Compare comp) { | ||
int p = (idx - 1) / 2; | ||
while (idx && comp(first[idx], first[p])) { | ||
swap(first[p], first[idx]); | ||
idx = p; | ||
p = (idx - 1) / 2; | ||
} | ||
} | ||
|
||
template <class RandomAccessIterator> | ||
void _heap_percolate_down(RandomAccessIterator first, int n, int idx) { | ||
int c = _heap_min_child_idx(first, n, idx); | ||
while (c != -1 && first[c] < first[idx]) { | ||
swap(first[c], first[idx]); | ||
idx = c; | ||
c = _heap_min_child_idx(first, n, idx); | ||
} | ||
} | ||
|
||
template <class RandomAccessIterator, class Compare> | ||
void _heap_percolate_down(RandomAccessIterator first, int n, int idx, | ||
Compare comp) { | ||
int c = _heap_min_child_idx(first, n, idx, comp); | ||
while (c != -1 && comp(first[c], first[idx])) { | ||
swap(first[c], first[idx]); | ||
idx = c; | ||
c = _heap_min_child_idx(first, n, idx, comp); | ||
} | ||
} | ||
|
||
#endif // ALGORITHM_H_INCLUDED |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
// File: list.h | ||
// Author: Viktor Slavkovic | ||
// Date: May 2016 | ||
|
||
#ifndef _STL_LIST_H_ | ||
#define _STL_LIST_H_ | ||
|
||
#include <assert.h> | ||
|
||
template <class T> | ||
class list { | ||
public: | ||
typedef T value_type; | ||
typedef unsigned size_type; | ||
|
||
list() : head_(0), tail_(0), size_(0u) {} | ||
~list() { clear(); } | ||
|
||
value_type& front() { | ||
assert(size_); | ||
return head_->val; | ||
} | ||
|
||
const value_type& front() const { | ||
assert(size_); | ||
return head_->val; | ||
} | ||
|
||
value_type& back() { | ||
assert(size_); | ||
return tail_->val; | ||
} | ||
|
||
const value_type& back() const { | ||
assert(size_); | ||
return tail_->val; | ||
} | ||
|
||
size_type size() const { return size_; } | ||
|
||
int empty() const { return !size_; } | ||
|
||
void clear() { | ||
while (head_) { | ||
pnode temp = head_; | ||
head_ = head_->next; | ||
delete temp; | ||
} | ||
tail_ = 0; | ||
size_ = 0; | ||
} | ||
|
||
void push_back(const value_type& val) { | ||
pnode temp = new node(val); | ||
if (!size_++) | ||
head_ = tail_ = temp; | ||
else { | ||
tail_->next = temp; | ||
tail_ = temp; | ||
} | ||
} | ||
|
||
void push_front(const value_type& val) { | ||
head_ = new node(val, head_); | ||
if (!size_++) tail_ = head_; | ||
} | ||
|
||
// O(size) | ||
void pop_back() { | ||
if (!size_) return; | ||
pnode* p = &head_; | ||
while ((*p)->next) p = &((*p)->next); | ||
delete (*p); | ||
*p = 0; | ||
if (!--size_) head_ = tail_ = 0; | ||
} | ||
|
||
void pop_front() { | ||
if (!size_) return; | ||
pnode temp = head_; | ||
head_ = head_->next; | ||
delete temp; | ||
if (!--size_) head_ = tail_ = 0; | ||
} | ||
|
||
int operator==(const list& rhs) const { | ||
if (size_ != rhs.size_) return 0; | ||
for (pnode p1 = head_, p2 = rhs.head_; p1; p1 = p1->next, p2 = p2->next) | ||
if (p1->val != p2->val) return 0; | ||
return 1; | ||
} | ||
|
||
int operator!=(const list& rhs) const { return !(*this == rhs); } | ||
|
||
private: | ||
struct node { | ||
node(const value_type& val, node* next = 0) : val(val), next(next) {} | ||
value_type val; | ||
node* next; | ||
}; | ||
typedef node* pnode; | ||
|
||
pnode head_, tail_; | ||
unsigned size_; | ||
|
||
public: | ||
class iterator { | ||
public: | ||
iterator() : owner(0), p(0) {} | ||
|
||
void operator++() { | ||
if (p) p = p->next; | ||
} | ||
|
||
void operator++(int k) { | ||
if (p) p = p->next; | ||
} | ||
|
||
value_type& operator*() { | ||
assert(p); | ||
return p->val; | ||
} | ||
|
||
int operator==(const iterator& rhs) const { | ||
if (!owner) return 0; | ||
if (owner != rhs.owner) return 0; | ||
return (p == rhs.p); | ||
} | ||
|
||
int operator!=(const iterator& rhs) const { return !(*this == rhs); } | ||
|
||
private: | ||
typedef list<value_type>::node* pnode; | ||
pnode p; | ||
|
||
list<value_type>* owner; | ||
iterator(list<value_type>* owner, const pnode& p) : owner(owner), p(p) {} | ||
|
||
friend class list<value_type>; | ||
}; | ||
|
||
iterator begin() { return iterator(this, head_); } | ||
|
||
iterator end() { return iterator(this, (pnode)0); } | ||
}; | ||
|
||
#endif // _STL_LIST_H_ |
Oops, something went wrong.