|
|
#pragma once
|
|
|
|
|
|
#include <map>
|
|
|
#include <string>
|
|
|
#include <variant>
|
|
|
#include <vector>
|
|
|
#include <cassert>
|
|
|
|
|
|
// 表格中的数据类型
|
|
|
using DataTableValue = std::variant<int, double, std::string>;
|
|
|
|
|
|
/**
|
|
|
* 表格中的列
|
|
|
*/
|
|
|
class DataColumn
|
|
|
{
|
|
|
public:
|
|
|
enum class DataType
|
|
|
{
|
|
|
Int,
|
|
|
Double,
|
|
|
String,
|
|
|
};
|
|
|
|
|
|
DataColumn(const std::string& m_name, DataType m_dataType)
|
|
|
: m_name(m_name), m_dataType(m_dataType)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
const std::string& getName() const
|
|
|
{
|
|
|
return m_name;
|
|
|
}
|
|
|
|
|
|
void setName(const std::string& name)
|
|
|
{
|
|
|
m_name = name;
|
|
|
}
|
|
|
|
|
|
DataType getDataType() const
|
|
|
{
|
|
|
return m_dataType;
|
|
|
}
|
|
|
|
|
|
void setDataType(DataType dataType)
|
|
|
{
|
|
|
m_dataType = dataType;
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
std::string m_name;
|
|
|
DataType m_dataType;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 表格中的行
|
|
|
*/
|
|
|
class DataRow
|
|
|
{
|
|
|
public:
|
|
|
/**
|
|
|
* 通过列名设置值
|
|
|
*
|
|
|
* \param columnName 列名
|
|
|
* \param value 值
|
|
|
*/
|
|
|
void setValue(const std::string& columnName, const DataTableValue& value)
|
|
|
{
|
|
|
m_values[columnName] = value;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取指定列的值
|
|
|
*
|
|
|
* \param columnName 列名
|
|
|
* \return
|
|
|
*/
|
|
|
const DataTableValue &value(const std::string& columnName) const
|
|
|
{
|
|
|
return m_values.at(columnName);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取指定列的值
|
|
|
*
|
|
|
* \param columnName 列名
|
|
|
* \return
|
|
|
*/
|
|
|
DataTableValue& operator[](const std::string& columnName)
|
|
|
{
|
|
|
return m_values[columnName];
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
std::map<std::string, DataTableValue> m_values;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 表格
|
|
|
* \note
|
|
|
* 这个表格类还很不完善,主要有以下几点
|
|
|
* 1、设置值时没有根据列头做类型校验
|
|
|
* 2、添加列时,没有去所有行里面添加值
|
|
|
* 3、没有移除列等操作
|
|
|
* 4、没有对下标有效性进行校验
|
|
|
* 5、其它暂时没细想
|
|
|
* 虽然不够完善,但是不妨碍使用,主要用在统计一类功能上面
|
|
|
*/
|
|
|
class DataTable
|
|
|
{
|
|
|
public:
|
|
|
/**
|
|
|
* 添加列
|
|
|
*
|
|
|
* \param column 列
|
|
|
*/
|
|
|
void addColumn(const DataColumn& column)
|
|
|
{
|
|
|
m_columns.push_back(column);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取列数
|
|
|
*
|
|
|
* \return 表的列数
|
|
|
*/
|
|
|
size_t columnCount() const
|
|
|
{
|
|
|
return m_columns.size();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 添加一行数据
|
|
|
*
|
|
|
* \param row 行
|
|
|
*/
|
|
|
void addRow(const DataRow& row)
|
|
|
{
|
|
|
m_rows.push_back(row);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取表总行数
|
|
|
*
|
|
|
* \return
|
|
|
*/
|
|
|
size_t rowCount() const
|
|
|
{
|
|
|
return m_rows.size();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据行列下标获取值
|
|
|
*
|
|
|
* \param rowIndex 行下标,从0开始
|
|
|
* \param columnIndex 列下标,从0开始
|
|
|
* \return 对应的值
|
|
|
*/
|
|
|
const DataTableValue& getValue(int rowIndex, int columnIndex) const
|
|
|
{
|
|
|
assert(rowIndex >= 0);
|
|
|
assert(columnIndex >= 0);
|
|
|
|
|
|
return m_rows[rowIndex].value(m_columns[columnIndex].getName());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据行列下标设置值
|
|
|
*
|
|
|
* \param rowIndex 行下标,从0开始
|
|
|
* \param columnIndex 列下标,从0开始
|
|
|
* \param value 值
|
|
|
*/
|
|
|
void setValue(int rowIndex, int columnIndex, const DataTableValue& value)
|
|
|
{
|
|
|
assert(rowIndex >= 0);
|
|
|
assert(columnIndex >= 0);
|
|
|
|
|
|
m_rows[rowIndex].setValue(m_columns[columnIndex].getName(), value);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取列头
|
|
|
*
|
|
|
* \return 所有列组成的头
|
|
|
*/
|
|
|
std::vector<std::string> getColumnHeaders() const
|
|
|
{
|
|
|
std::vector<std::string> headers;
|
|
|
for (const auto& column : m_columns) {
|
|
|
headers.push_back(column.getName());
|
|
|
}
|
|
|
return headers;
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
std::vector<DataColumn> m_columns;
|
|
|
std::vector<DataRow> m_rows;
|
|
|
};
|
|
|
|