#include <cassert>
#include <iostream>
#include <type_traits>
#include <utility>
#include <chrono>
#include <set>
#include <map>
#include <vector>
#include <iterator>
#define LOOPS 100
#define MAXEL 100000
template<typename Type>
class Range{
public:
typedef std::pair<Type,Type> Pair;
typedef std::set<Type> Set;
Range(const Pair & pair){
m_ptr = static_cast<void * >( new Pair(pair) );
m_which = 0;
}
Range(Pair && pair){
m_ptr = static_cast<void * >( new Pair( std::move(pair) ) );
m_which = 0;
}
Range(const Set & set){
m_which = 1;
m_ptr = static_cast<void * >( new Set(set) );
}
Range(Set && set){
m_which = 1;
m_ptr = static_cast<void * >( new Set( std::move(set) ) );
}
Range(const Range & r){
*this = r;
}
// Move Constructor
Range(Range && r){
*this = std::move(r);
}
// Move Assigment
Range & operator=(Range && r){
assert(r.m_ptr);
if(m_ptr != r.m_ptr && this != &r ){ // Prevent self-assignment
~Range(); // delete resources
m_ptr = std::move(r.m_ptr);
m_which = std::move(r.m_which);
r.m_ptr = nullptr;
r.m_which = 0;
}
}
// Assigment
Range & operator=(Range & r){
if(m_ptr != r.m_ptr && this != &r ){ // Prevent self-assignment
if(r.m_which == 0){
if(m_which == 0 && m_ptr){
*static_cast<Pair*>(m_ptr) = *static_cast<Pair*>(r.m_ptr); // Copy
}
m_ptr = static_cast<void * >( new Pair(*static_cast<Pair*>(r.m_ptr))); // Make new and Copy
}else if(r.m_which==1){
if(m_which == 1 && m_ptr){
*static_cast<Set*>(m_ptr) = *static_cast<Set*>(r.m_ptr); // Copy
}
m_ptr = static_cast<void * >( new Set(*static_cast<Set*>(r.m_ptr))); // Make new and Copy
}
m_which = r.m_which;
}
}
~Range(){
if(m_ptr){
if(m_which == 0){
auto p = static_cast<Pair * >(m_ptr); delete p;
}else if(m_which==1){
auto p = static_cast<Set * >(m_ptr); delete p;
}
m_which = 0;
}
}
class iterator {
public:
iterator():m_r(nullptr),m_cur(0){};
iterator(Range * r, bool atEnd = false):m_r(r) {
if(!m_r->m_ptr){
m_cur=0;
return;
}
if(m_r->m_which == 0){
auto p = static_cast<Pair * >(m_r->m_ptr);
if(atEnd){
m_cur = p->second;
}else{
m_cur = p->first;
}
}else{
auto p = static_cast<Set * >(m_r->m_ptr);
if(atEnd){
m_it = p->end();
}else{
m_it = p->begin();
}
}
};
//Delete assignment operator
iterator & operator=(const iterator&) = delete;
iterator & operator=(iterator&) = delete;
~iterator() {
}
iterator( const iterator & it ): m_r(it.m_r), m_cur(it.m_cur) {
}
/** pre-increment ++it
* Allow to iterate over the end of the sequence
*/
iterator & operator++() {
if(m_r->m_which == 0){
++m_cur;
}else {
++m_it;
}
return *this;
}
/** post-increment it++
*
*/
iterator operator++(int) {
iterator it(*this);
operator++();
return it;
}
bool operator==(const iterator &rhs) {
if(m_r->m_which == 0){
return m_cur == rhs.m_cur; // Two iterators for differente ranges, might compare equal!
}else {
return m_it == rhs.m_it;
}
}
// Return false if the same!
bool operator!=(const iterator &rhs) {
return !(*this==rhs);
}
Type operator*() {
if(m_r->m_which == 0){
return m_cur ;
}else {
return *m_it;
}
}
private:
Range * m_r;
typename Set::iterator m_it;
Type m_cur;
};
iterator begin(){
return iterator(this);
}
iterator end(){
return iterator(this,true);
}
private:
unsigned int m_which = 0;
void * m_ptr = nullptr;
};
#define INIT_TIMER auto start = std::chrono::high_resolution_clock::now();
#define START_TIMER start = std::chrono::high_resolution_clock::now();
#define STOP_TIMER(name) \
double count = std::chrono::duration<double,std::milli>(std::chrono::high_resolution_clock::now()-start ).count(); \
std::cout << "RUNTIME of " << name << ": " << count << " ms " << std::endl;
int main(){
std::cout << "Speed Test ============================" << std::endl;
typedef unsigned int Type;
std::set<Type> s;
unsigned int max = 100000;
// Filling vector and set
std::vector<Type> vec(max);
for(int j = 0; j< vec.size(); j++) {
vec[j] = j*j;
}
while(s.size()<max){
s.insert(rand());
}
// Making Pair
std::pair<Type, Type> a(0,max);
int loops = LOOPS;
int n = 0;
{
Range<Type> range(a);
INIT_TIMER
START_TIMER
auto itEnd = range.end();
for(int i=1; i<loops; i++) {
for(auto it=range.begin(); it != itEnd; ++it) {
n += *it*i;
//std::cout << *it << std::endl;
}
}
STOP_TIMER("Range: [Pair] ")
}
{
Range<Type> range(s);
INIT_TIMER
START_TIMER
auto itEnd = range.end();
for(int i=1; i<loops; i++) {
for(auto it=range.begin(); it != itEnd; ++it) {
n += *it*i;
//std::cout << *it << std::endl;
}
}
STOP_TIMER("Range: [Set]")
}
{
INIT_TIMER
START_TIMER
auto s2 = s;
auto itEnd = s2.end();
for(int i=1; i<loops; i++) {
for(auto it=s2.begin(); it != itEnd; ++it) {
n += *it*i;
//std::cout << *it << std::endl;
}
}
STOP_TIMER("std::set")
}
{
INIT_TIMER
START_TIMER
for(unsigned int i=1; i<loops; ++i) {
for(unsigned int j = 0; j<max; ++j){
n+=i*j;
}
}
STOP_TIMER("Range: Normal For Loop")
}
}