C\C++ 0X - can i create a function using a class and overloading operators?
see my actual code:
Code:
#include <iostream.h>
#include <stdlib.h>
#include <string>
class Variant
{
char* data;
void* ptr;
Variant* elementos;
int arrSize;
void setString(const char* s)
{
if(!s) s = "";
data = (char*)malloc(strlen(s) + 1);
strcpy(data, s);
}
public:
enum Type { NONE, INT, STRING, DOUBLE, POINTER, LONG, ARRAY } type;
void clear()
{
if(data) { free(data); data = NULL; }
if(type == ARRAY && elementos)
{
delete[] elementos;
elementos = NULL;
arrSize = 0;
}
ptr = NULL;
type = NONE;
}
Variant()
{
data = NULL;
ptr = NULL;
elementos = NULL;
arrSize = 0;
type = NONE;
}
Variant(int i)
{
char buf[32];
ptr = NULL;
elementos = NULL;
arrSize = 0;
sprintf(buf, "%d", i);
setString(buf);
type = INT;
}
Variant(long l)
{
char buf[32];
ptr = NULL;
elementos = NULL;
arrSize = 0;
sprintf(buf, "%ld", l);
setString(buf);
type = LONG;
}
Variant(double d)
{
char buf[64];
ptr = NULL;
elementos = NULL;
arrSize = 0;
sprintf(buf, "%g", d);
setString(buf);
type = DOUBLE;
}
Variant(const char* s)
{
ptr = NULL;
elementos = NULL;
arrSize = 0;
setString(s);
type = STRING;
}
Variant(void* p)
{
data = NULL;
elementos = NULL;
arrSize = 0;
ptr = p;
type = POINTER;
}
// constructor array
Variant(int* size)
{
data = NULL;
ptr = NULL;
arrSize = *size;
elementos = new Variant[arrSize];
type = ARRAY;
}
// copy constructor
Variant(const Variant& other)
{
ptr = other.ptr;
type = other.type;
arrSize = other.arrSize;
elementos = NULL;
data = NULL;
if(other.data)
{
data = (char*)malloc(strlen(other.data) + 1);
strcpy(data, other.data);
}
if(type == ARRAY && other.elementos)
{
elementos = new Variant[arrSize];
for(int i = 0; i < arrSize; i++)
elementos[i] = other.elementos[i];
}
}
~Variant()
{
if(data) free(data);
if(type == ARRAY && elementos)
delete[] elementos;
}
// operator=
Variant& operator=(int i)
{
clear();
char buf[32];
sprintf(buf, "%d", i);
setString(buf);
type = INT;
return *this;
}
Variant& operator=(long l)
{
clear();
char buf[32];
sprintf(buf, "%ld", l);
setString(buf);
type = LONG;
return *this;
}
Variant& operator=(double d)
{
clear();
char buf[64];
sprintf(buf, "%g", d);
setString(buf);
type = DOUBLE;
return *this;
}
Variant& operator=(const char* s)
{
clear();
setString(s);
type = STRING;
return *this;
}
Variant& operator=(void* p)
{
clear();
ptr = p;
type = POINTER;
return *this;
}
Variant& operator=(const Variant& other)
{
if(this == &other) return *this;
clear();
ptr = other.ptr;
type = other.type;
arrSize = other.arrSize;
if(other.data)
{
data = (char*)malloc(strlen(other.data) + 1);
strcpy(data, other.data);
}
if(type == ARRAY && other.elementos)
{
elementos = new Variant[arrSize];
for(int i = 0; i < arrSize; i++)
elementos[i] = other.elementos[i];
}
return *this;
}
// operator[]
Variant& operator[](int i)
{
return elementos[i];
}
Variant& operator[](Variant index)
{
return elementos[index.ToInt()];
}
// conversões implícitas
operator const char*()const { return data ? data : ""; }
operator int() const { return data ? atoi(data) : 0; }
operator long() const { return data ? atol(data) : 0; }
operator double() const { return data ? atof(data) : 0.0; }
operator void*() const { return type == POINTER ? ptr : NULL; }
// métodos explícitos
const char* ToString() const { return data ? data : ""; }
int ToInt() const { return data ? atoi(data) : 0; }
long ToLong() const { return data ? atol(data) : 0; }
double ToDouble() const { return data ? atof(data) : 0.0; }
void* ToPtr() const { return type == POINTER ? ptr : NULL; }
int Size() const { return type == ARRAY ? arrSize : 0; }
Type getType() const { return type; }
#if defined(_MSC_VER) || defined(__BORLANDC__)
// TC++ e Visual C++ antigo - sem long long
#else
Variant(long long l)
{
char buf[64];
ptr = NULL;
elementos = NULL;
arrSize = 0;
sprintf(buf, "%lld", l);
setString(buf);
type = LONG;
}
Variant& operator=(long long l)
{
clear();
char buf[64];
sprintf(buf, "%lld", l);
setString(buf);
type = LONG;
return *this;
}
operator long long() { return data ? atoll(data) : 0; }
long long ToLongLong() { return data ? atoll(data) : 0; }
#endif
#if defined(__int32_t_defined) || defined(_STDINT_H)
Variant(int32_t i) { *this = (int)i; }
Variant(uint32_t i) { *this = (long)i; }
#endif
// para usar cout e cin.getline():
friend ostream& operator<<(ostream& os, Variant& v)
{
os << (const char*)v;
os.flush();
return os;
}
friend istream& operator>>(istream& is, Variant& v)
{
char buf[256];
is.getline(buf, sizeof(buf));
v = buf;
return is;
}
char* GetBuffer(int size = 256)
{
if(!data)
{
data = (char*)malloc(size);
data[0] = '\0';
type = STRING;
}
return data;
}
operator char*()
{
if(!data)
{
data = (char*)malloc(256);
data[0] = '\0';
type = STRING;
}
return data;
}
bool isNull()
{
return (type == NONE); // NONE = não inicializado = NULL! ?
}
bool operator==(void* p)
{
if(p == NULL)
return (type == NONE ||
(type == POINTER && ptr == NULL));
return ptr == p;
}
bool operator!=(void* p)
{
return !(*this == p);
}
};
template<class T>
class Vector
{
private:
T* m_data;
int m_size;
int m_capacity;
void grow()
{
m_capacity = m_capacity ? m_capacity * 2 : 1;
T* newdata = new T[m_capacity];
for(int i = 0; i < m_size; i++)
newdata[i] = m_data[i];
delete[] m_data;
m_data = newdata;
}
public:
// constructors
Vector() : m_data(0), m_size(0), m_capacity(0) {}
Vector(int size) : m_data(new T[size]), m_size(size), m_capacity(size)
{
for(int i = 0; i < size; i++)
m_data[i] = T();
}
Vector(const Vector& other) : m_data(0), m_size(0), m_capacity(0)
{
*this = other; // chama operator=(const Vector&)
}
~Vector() { delete[] m_data; }
// operator= cópia
Vector& operator=(const Vector& other)
{
if(this != &other)
{
delete[] m_data;
m_size = other.m_size;
m_capacity = other.m_capacity;
m_data = new T[m_capacity];
for(int i = 0; i < m_size; i++)
m_data[i] = other.m_data[i];
}
return *this;
}
// operator[]
T& operator[](int i) { return m_data[i]; }
const T& operator[](int i) const { return m_data[i]; }
// size / capacity
int size() const { return m_size; }
int capacity() const { return m_capacity; }
bool empty() const { return m_size == 0; }
// push / pop
void push_back(const T& v)
{
if(m_size == m_capacity) grow();
m_data[m_size++] = v;
}
void pop_back()
{
if(m_size > 0) m_size--;
}
// insert / remove
void insert(int pos, const T& v)
{
if(m_size == m_capacity) grow();
for(int i = m_size; i > pos; i--)
m_data[i] = m_data[i-1];
m_data[pos] = v;
m_size++;
}
void remove(int pos)
{
for(int i = pos; i < m_size-1; i++)
m_data[i] = m_data[i+1];
m_size--;
}
// clear / resize
void clear() { m_size = 0; }
void resize(int newsize)
{
if(newsize > m_capacity)
{
m_capacity = newsize;
T* newdata = new T[m_capacity];
for(int i = 0; i < m_size; i++)
newdata[i] = m_data[i];
delete[] m_data;
m_data = newdata;
}
m_size = newsize;
}
// front / back
T& front() { return m_data[0]; }
const T& front() const { return m_data[0]; }
T& back() { return m_data[m_size-1]; }
const T& back() const { return m_data[m_size-1]; }
// find
int find(const T& v) const
{
for(int i = 0; i < m_size; i++)
if(m_data[i] == v) return i;
return -1;
}
// operator, para encadear elementos
Vector& operator,(const T& v)
{
push_back(v);
return *this;
}
// operator<< para inicializar como cout
// cout compativel!
friend ostream& operator<<(ostream& os, const Vector& v)
{
for(int i = 0; i < v.m_size; i++)
os << v.m_data[i];
return os;
}
Vector& operator=(const T& v)
{
push_back(v);
return *this;
}
};
class Write : public Vector<Variant>
{
public:
Write() // constructor implícito!
{
}
Write(const Variant& v) // constructor implícito!
{
push_back(v);
}
Write& operator=(const Variant& v) // sem template!
{
clear();
push_back(v);
return *this;
}
Write& operator,(const Variant& v) // sem template!
{
push_back(v);
return *this;
}
~Write()
{
for(int i = 0; i < size(); i++)
cout << (*this)[i];
cout << endl;
}
};
#define write Write()=
int main()
{
write "olá mundo", 345, 35.78;
return 0;
}
(i'm using it on Visual C++ 6(VS98), but seems compatible with TC++)
using a Variant, is more easy instead using templates(TC++ don't have it)...
Write it's a class from Variant for create a funtion... with a macro i can use it like a function, but:
1 - can i change it for use the function parentheses?
2 - can i avoid 'Write()=' or 'Write(),' and use write(parameters)?(without macros)