cpptables
Tabular data for C++ using types for tables and columns.
Overview
Table schemas are defined at compile time allowing operations such as joins and grouping to be checked for type correctness.
Columns support column-oriented operations.
Examples
#include <cpptables/table.hh>
#include <cpptables/where.hh>
#include <iostream>
using namespace tables;
using namespace std;
struct col0 { constexpr static char const * const name = "col0"; };
struct col1 { constexpr static char const * const name = "col1"; };
struct col2 { constexpr static char const * const name = "col2"; };
struct col3 { constexpr static char const * const name = "col3"; };
int main()
{
using table_t = table<
pair<col0,std::string_view>,
pair<col1,unsigned>,
pair<col2,double>
>;
const table_t t(
{"A", "B", "C", "A", "B", "C", "A", "B", "C"},
{1,10,100,2,20,200,3,30,300},
{100.0,200.0,300.0,400.0,500.0,600.0,700.0,800.0,900.0}
);
// Filter rows
{
// Select rows whose col0 is A
const table_t t0 = t.at( where( t.col<col0>() == std::string_view("A")));
cout << "select where col0 == A:\n" << t0 << "\n";
// Same query, different syntax
const table_t t1 = t.at( t.col<col0>().eq(std::string_view("A")).where() );
// Select rows whose col0 > A
const table_t t2 = t.at( t.col<col0>().gt(std::string_view("A")).where() );
cout << "select where col0 > A:\n" << t2 << "\n";
}
// ================ Grouping with group_by ================
using gtable_t = table_t::group_by_t<std::tuple<col0>>;
const gtable_t gt = t.group_by<col0>();
// Sum col1,col2 grouped by col0
{
const table_t t_sum = t.group_by<col0>().sum();
cout << "sum col1,col2 by col0:\n" << t_sum << "\n";
}
// ================ apply aggregators or transformation to groups: fby ================
// Sum col1,avg col2 by col0
{
const auto fsum = [](const column<auto>& xs) { return xs.sum(); };
const auto favg = [](const column<auto>& xs) { return xs.avg(); };
const table_t t1 = t.fby<col0>().agg<col1,col2>(fsum,favg);
cout << "sum col1,avg col2 by col0:\n" << t1 << "\n";
}
// Reverse col1 by col0
{
const auto freverse = [](const column<auto>& xs) { return xs.reverse(); };
const table_t t1 = t.fby<col0>().fupdate<col1>(freverse);
cout << "reverse col1 by col0:\n" << t1 << "\n";
}
// ================ Joins ================
using table1_t = table<
pair<col0,std::string_view>,
std::pair<col3,std::string_view>
>;
const table1_t t1(
{"A", "B"},
{"alfa","beta"}
);
// Left join t with t1 on col0
{
const auto t_lj = t.lj( t1.key_by<col0>() );
cout << "left join t with t1:\n" << t_lj << "\n";
}
// Inner join t with t1 on col0
{
const auto t_ij = t.ij( t1.key_by<col0>() );
cout << "inner join t with t1:\n" << t_ij << "\n";
}
return 0;
}
Output:
select where col0 == A: col0 col1 col2 -------------- A 1 100 A 2 400 A 3 700 select where col0 > A: col0 col1 col2 -------------- B 10 200 C 100 300 B 20 500 C 200 600 B 30 800 C 300 900 sum col1,col2 by col0: col0 col1 col2 -------------- A 6 1200 B 60 1500 C 600 1800 sum col1,avg col2 by col0: col0 col1 col2 -------------- A 6 400 B 60 500 C 600 600 reverse col1 by col0: col0 col1 col2 -------------- A 3 100 B 30 200 C 300 300 A 2 400 B 20 500 C 200 600 A 1 700 B 10 800 C 100 900 left join t with t1: col0 col1 col2 col3 ------------------- A 1 100 alfa B 10 200 beta C 100 300 none A 2 400 alfa B 20 500 beta C 200 600 none A 3 700 alfa B 30 800 beta C 300 900 none inner join t with t1: col0 col1 col2 col3 ------------------- A 1 100 alfa B 10 200 beta A 2 400 alfa B 20 500 beta A 3 700 alfa B 30 800 beta