Newer
Older
Import / research / framework / source / CsvParser.hpp
/************************************************
*
*  CSV file parser
*  Copyright (C) 2020
*  John Ryland
*  All rights reserved
*
************************************************/
#pragma once
#ifndef CSV_PARSER_HPP
#define CSV_PARSER_HPP

#include <vector>
#include <set>
#include <string>
#include <type_traits>

//template <typename T>
//T from_string_cast(std::string aString);

template<typename T, typename type>
using templated_by_return_type = std::enable_if_t< std::is_same< T, type >::value, T >;

template<typename T>
templated_by_return_type<T, int> from_string(std::string aString)
{
    return std::atoi(aString.c_str());
}

template<typename T>
templated_by_return_type<T, float> from_string(std::string aString)
{
    return std::atof(aString.c_str());
}

class CsvParser
{
public:
    using Row = std::vector<std::string>;
    using Table = std::vector<Row>;
    using Indexes = std::vector<size_t>;
    using IndexSet = std::set<size_t>;

    CsvParser();

    void SetFieldNames(const Row& aExpectedOrderedFieldNames);
    bool Parse(const std::string& aCsvResourceLocator);

    // types constructible from strings
    // field mappings - filters table to rows of interest and presents them in the correct order
    // something to initialize a struct from the converted types

    const Row& GetHeaderRow() const { return mHeader; }
    const Table& GetRows() const    { return mTable;  }

    template <typename T>
    T GetFieldValue(size_t aFieldIndex, const Row& aRow) const
    {
        std::string str = aRow.at(aFieldIndex);
        return from_string<T>(str);
    }

private:
    Row   mExpectedFields;
    Row   mHeader;
    Table mTable;
};

#endif // CSV_PARSER_HPP