Signature Description
enum class sort_spec : unsigned char {
 ascen = 1,
 desce = 2,
};
Enumerated type to specify the direction of sort; ascending vs. descending.

Signature Description Parameters

template<typename T, typename ... Ts>
void
sort(const char *name, sort_spec dir);
Sort the DataFrame by the named column. If name equals DF_INDEX_COL_NAME, it sorts by index. Otherwise it sorts by the named column. Sort first calls make_consistent() that may add nan values to data columns.
nan values make sorting nondeterministic.
T: Type of the by_name column. You always of the specify this type, even if it is being sorted to the default index
Ts: The list of types for all columns. A type should be specified only once.
name: The name of a column or string DF_INDEX_COL_NAME.
dir: Direction of sorting, ascending or descending

template<typename T1, typename T2, typename ... Ts>
void
sort(const char *name1, sort_spec dir1,
     const char *name2, sort_spec dir2);
This sort function sorts DataFrame based on two columns, also specified by the two directions. name[n] could be DF_INDEX_COL_NAME in whcih case the index column is taken as the sorting column.
NOTE: The order of T[n] type specifications must match the order of name[n] column names. In addition, all column types must be specified separately. Otherwise, the behavior is undefined.
NOTE: Sort first calls make_consistent() that may add nan values to data columns. nan values make sorting nondeterministic.
T1: Type of the first named column. You always must specify this type, even if it is being sorted by the index.
T2: Type of the second named column. You always must specify this type, even if it is being sorted by the index.
Ts: List all the types of all data columns. A type should be specified in the list only once.
name1: Name of the first column or string DF_INDEX_COL_NAME
name2: Name of the second column or string DF_INDEX_COL_NAME
dir1: Direction of sorting for the first column
dir2: Direction of sorting for the second column

template<typename T1, typename T2, typename T3,
         typename ... Ts>
void
sort(const char *name1, sort_spec dir1,
     const char *name2, sort_spec dir2,
     const char *name3, sort_spec dir3);
This sort function is similar to above, but it uses 3 columns T1: Type of the first named column. You always must specify this type, even if it is being sorted by the index.
T2: Type of the second named column. You always must specify this type, even if it is being sorted by the index.
T3: Type of the third named column. You always must specify this type, even if it is being sorted by the index.
Ts: List all the types of all data columns. A type should be specified in the list only once.
name1: Name of the first column or string DF_INDEX_COL_NAME
name2: Name of the second column or string DF_INDEX_COL_NAME
name3: Name of the third column or string DF_INDEX_COL_NAME
dir1: Direction of sorting for the first column
dir2: Direction of sorting for the second column
dir3: Direction of sorting for the third column

template<typename T1, typename T2, typename T3,
         typename T4, typename ... Ts>
void
sort(const char *name1, sort_spec dir1,
     const char *name2, sort_spec dir2,
     const char *name3, sort_spec dir3,
     const char *name4, sort_spec dir4);
This sort function is similar to above, but it uses 4 columns T1: Type of the first named column. You always must specify this type, even if it is being sorted by the index.
T2: Type of the second named column. You always must specify this type, even if it is being sorted by the index.
T3: Type of the third named column. You always must specify this type, even if it is being sorted by the index.
T4: Type of the fourth named column. You always must specify this type, even if it is being sorted by the index.
Ts: List all the types of all data columns. A type should be specified in the list only once.
name1: Name of the first column or string DF_INDEX_COL_NAME
name2: Name of the second column or string DF_INDEX_COL_NAME
name3: Name of the third column or string DF_INDEX_COL_NAME
name4: Name of the fourth column or string DF_INDEX_COL_NAME
dir1: Direction of sorting for the first column
dir2: Direction of sorting for the second column
dir3: Direction of sorting for the third column
dir4: Direction of sorting for the fourth column

template<typename T1, typename T2, typename T3,
         typename T4, typename T5, typename ... Ts>
void
sort(const char *name1, sort_spec dir1,
     const char *name2, sort_spec dir2,
     const char *name3, sort_spec dir3,
     const char *name4, sort_spec dir4,
     const char *name5, sort_spec dir5);
This sort function is similar to above, but it uses 5 columns T1: Type of the first named column. You always must specify this type, even if it is being sorted by the index.
T2: Type of the second named column. You always must specify this type, even if it is being sorted by the index.
T3: Type of the third named column. You always must specify this type, even if it is being sorted by the index.
T4: Type of the fourth named column. You always must specify this type, even if it is being sorted by the index.
T5: Type of the fifth named column. You always must specify this type, even if it is being sorted by the index.
Ts: List all the types of all data columns. A type should be specified in the list only once.
name1: Name of the first column or string DF_INDEX_COL_NAME
name2: Name of the second column or string DF_INDEX_COL_NAME
name3: Name of the third column or string DF_INDEX_COL_NAME
name4: Name of the fourth column or string DF_INDEX_COL_NAME
name5: Name of the fifth column or string DF_INDEX_COL_NAME
dir1: Direction of sorting for the first column
dir2: Direction of sorting for the second column
dir3: Direction of sorting for the third column
dir4: Direction of sorting for the fourth column
dir5: Direction of sorting for the fifth column

template<typename T, typename ... Ts>
std::future<void>
sort_async(const char *name, sort_spec dir);
This is the asynchronous version that returns a std::future. Please see above for details

template<typename T1, typename T2, typename ... Ts>
std::future<void>
sort_async(const char *name1, sort_spec dir1,
           const char *name2, sort_spec dir2);
This is the asynchronous version that returns a std::future. Please see above for details

template<typename T1, typename T2, typename T3,
         typename ... Ts>
std::future<void>
sort_async(const char *name1, sort_spec dir1,
           const char *name2, sort_spec dir2,
           const char *name3, sort_spec dir3);
This is the asynchronous version that returns a std::future. Please see above for details

template<typename T1, typename T2, typename T3,
         typename T4, typename ... Ts>
std::future<void>
sort_async(const char *name1, sort_spec dir1,
           const char *name2, sort_spec dir2,
           const char *name3, sort_spec dir3,
           const char *name4, sort_spec dir4);
This is the asynchronous version that returns a std::future. Please see above for details

template<typename T1, typename T2, typename T3,
         typename T4, typename T5, typename ... Ts>
std::future<void>
sort_async(const char *name1, sort_spec dir1,
           const char *name2, sort_spec dir2,
           const char *name3, sort_spec dir3,
           const char *name4, sort_spec dir4,
           const char *name5, sort_spec dir5);
This is the asynchronous version that returns a std::future. Please see above for details
static void test_multi_col_sort()  {

    std::cout << "\nTesting multi-column sort ..." << std::endl;

    MyDataFrame df;

    std::vector<unsigned long>  idxvec = { 1UL, 2UL, 3UL, 10UL, 5UL, 7UL, 8UL, 12UL, 9UL, 12UL, 10UL, 13UL, 10UL, 15UL, 14UL };
    std::vector<double>         dblvec = { 0.0, 15.0, 14.0, 2.0, 1.0, 12.0, 11.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 9.0, 10.0};
    std::vector<double>         dblvec2 = { 100.0, 101.0, 102.0, 103.0, 104.0, 105.0, 106.55, 107.34, 1.8, 111.0, 112.0, 113.0, 114.0, 115.0, 116.0};
    std::vector<int>            intvec = { 1, 2, 3, 4, 5, 8, 6, 7, 11, 14, 9, 10, 15, 12, 13 };
    std::vector<std::string>    strvec = { "zz", "bb", "cc", "ww", "ee", "ff", "gg", "hh", "ii", "jj", "kk", "ll", "mm", "nn", "oo" };

    df.load_data(std::move(idxvec),
                 std::make_pair("dbl_col", dblvec),
                 std::make_pair("dbl_col_2", dblvec2),
                 std::make_pair("int_col", intvec),
                 std::make_pair("str_col", strvec));

    auto    sf = df.sort_async<MyDataFrame::IndexType, int, std::string, int, double, std::string>
                     (DF_INDEX_COL_NAME, sort_spec::ascen, "int_col", sort_spec::desce, "str_col", sort_spec::desce);

    sf.get();
    assert(df.get_index()[0] == 1);
    assert(df.get_index()[5] == 8);
    assert(df.get_index()[8] == 10);
    assert(df.get_index()[13] == 14);
    assert(df.get_index()[14] == 15);

    assert(df.get_column<int>("int_col")[0] == 1);
    assert(df.get_column<int>("int_col")[5] == 6);
    assert(df.get_column<int>("int_col")[8] == 9);
    assert(df.get_column<int>("int_col")[13] == 13);
    assert(df.get_column<int>("int_col")[14] == 12);

    assert(df.get_column<std::string>("str_col")[0] == "zz");
    assert(df.get_column<std::string>("str_col")[5] == "gg");
    assert(df.get_column<std::string>("str_col")[8] == "kk");
    assert(df.get_column<std::string>("str_col")[13] == "oo");
    assert(df.get_column<std::string>("str_col")[14] == "nn");

    assert(df.get_column<double>("dbl_col")[0] == 0.0);
    assert(df.get_column<double>("dbl_col")[5] == 11.0);
    assert(df.get_column<double>("dbl_col")[8] == 5.0);
    assert(df.get_column<double>("dbl_col")[13] == 10.0);
    assert(df.get_column<double>("dbl_col")[14] == 9.0);

    assert(df.get_column<double>("dbl_col_2")[0] == 100.0);
    assert(df.get_column<double>("dbl_col_2")[5] == 106.55);
    assert(df.get_column<double>("dbl_col_2")[8] == 112.0);
    assert(df.get_column<double>("dbl_col_2")[13] == 116.0);
    assert(df.get_column<double>("dbl_col_2")[14] == 115.0);
}
C++ DataFrame