~aritra1911/cylinder

11466e22b7556404fab082ac072eb5cdc5caffda — Aritra Sarkar 3 years ago da36a03 + aa46aa5
Merge pull request #2 from aritra1911/field_test

Add Field Types
4 files changed, 125 insertions(+), 0 deletions(-)

A field_test.cpp
A field_type.cpp
A field_type.hpp
A field_type.tpp
A field_test.cpp => field_test.cpp +69 -0
@@ 0,0 1,69 @@
#include <iostream>
#include <string>
#include <vector>
#include "field_type.hpp"

int main(void) {
    int n;
    std::cout << "How many fields? ";
    std::cin >> n;

    std::vector<AbstractField*> record;
    std::vector<std::string> field_names;

    std::cout << "\nEnter space separated field names: ";
    for (int i=0; i<n; i++) {
        std::string name;
        std::cin >> name;
        field_names.push_back(name);
    }

    std::cout << "\nNUMBER = 0\nVARCHAR = 1\nEnter space separated field types: ";

    FieldType type;
    for (int i=0; i<n; i++) {
        std::cin >> (int&)type;
        switch (type) {
            case NUMBER:
                record.push_back(new Field<int>(type, field_names[i]));
                break;

            default:
                record.push_back(new Field<std::string>(type, field_names[i]));
        }
    }

    std::cout << "Enter space separated values: ";
    for (int i = 0; i < n; i++) {
        switch (record[i]->type) {
            case NUMBER:
                std::cin >> static_cast<Field<int>*>(record[i])->value;
                break;

            default:
                std::cin >> static_cast<Field<std::string>*>(record[i])->value;
        }
    }

    std::cout << std::endl;

    for (int i=0; i<n; i++) {
        std::cout << record[i]->name << " : ";
        switch (record[i]->type) {
            case NUMBER:
                std::cout << static_cast<Field<int>*>(record[i])->value;
                break;

            default:
                std::cout << static_cast<Field<std::string>*>(record[i])->value;
        }
        std::cout << std::endl;
    }

    for (int i=0; i<n; i++)
        delete record[i];

    record.clear();

    return 0;
}

A field_type.cpp => field_type.cpp +8 -0
@@ 0,0 1,8 @@
#include <string>
#include "field_type.hpp"

AbstractField::AbstractField(const FieldType& type, const std::string& name) : type(type), name(name) { }

/* Since ~AbstractField() is declared as a pure virtual function, it needs a definition outside the `struct
 * AbstractField' anyway since there is no way to override a destructor. */
AbstractField::~AbstractField() { }

A field_type.hpp => field_type.hpp +39 -0
@@ 0,0 1,39 @@
#ifndef _FIELD_TYPE_HPP
# define _FIELD_TYPE_HPP

# include <string>

enum FieldType {
    NUMBER,  /* Int, TODO: Include Float */
    VARCHAR,  /* std::string, Don't think(TODO) too much right now */
};

/* AbstractField serves as a base for multiple fields of different types, i.e. a collection of AbstractField* in an
 * array can point to multiple Fields of different types. This is how a database record shall be maintained since we
 * don't know prior to user input, what type of Fields we'll be needing and how many of them. FieldType is helpful in
 * determining what type of Field we'll be casting the AbstractField* to.
 *
 * P.S. I'm new to this world of C++ casts and I don't quite know the difference between them. I've experimented with
 * dynamic_cast and static_cast and static_cast seems to be working fine.
 */

struct AbstractField {
    FieldType type;
    std::string name;

    AbstractField(const FieldType&, const std::string&);
    virtual ~AbstractField() = 0;
};

template<class T>
struct Field : AbstractField {
    T value;

    Field(const FieldType&, const std::string&);

    Field(const FieldType&, const std::string&, const T&);
};

# include "field_type.tpp"

#endif

A field_type.tpp => field_type.tpp +9 -0
@@ 0,0 1,9 @@
/* Context behind creating this file:
   https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file */

template <class T>
Field<T>::Field(const FieldType& type, const std::string& name) : AbstractField(type, name) { }

template <class T>
Field<T>::Field(const FieldType& type, const std::string& name, const T& value) :
    AbstractField(type, name), value(value) { }