 // Using Google Tests "Type Parameterized Tests"
 // Every test defined as TYPED_TEST(JoinTest, *) will be run once for every instance of
 // TestParameters defined below
+// The kind of join is determined by the first template argument to TestParameters
+// The number and types of columns used in both the left and right sets of columns are 
+// determined by the number and types of vectors in the std::tuple<...> that is the second
+// template argument to TestParameters
 typedef ::testing::Types< 
                           // Single column inner join tests for all types
                           TestParameters< join_kind::INNER, std::tuple<std::vector<int32_t>> >,


TYPED_TEST(JoinTest, ExampleTest)
{
  this->create_input(100,10,
                     100,10);

  std::vector<result_type> reference_result = this->compute_reference_solution();

  std::vector<result_type> gdf_result{};
  this->compute_gdf_result(gdf_result);

  ASSERT_EQ(reference_result.size(), gdf_result.size()) << "Size of gdf result does not match reference result\n";


            //                                             right_gdf_columns, 
            //                                             &gdf_join_result);
            std::cout << "Multi column *inner* joins not supported yet\n";
            EXPECT_TRUE(false);
            break;
          }
        default:
          std::cout << "Invalid join method" << std::endl;
          EXPECT_TRUE(false);
      }
    }
    EXPECT_EQ(GDF_SUCCESS, result_error) << "The gdf join function did not complete successfully";

    // The output is an array of size `n` where the first n/2 elements are the 
    // left_indices and the last n/2 elements are the right indices
    size_t output_size = gdf_join_result_size(gdf_join_result);
    size_t total_pairs = output_size/2;

    int * join_output = static_cast<int*>(gdf_join_result_data(gdf_join_result));

    // Host vector to hold gdf join output
    std::vector<int> host_result(output_size);

    // Copy result of gdf join to the host
    cudaMemcpy(host_result.data(), join_output, output_size * sizeof(int), cudaMemcpyDeviceToHost);

    // Free the original join result
    gdf_join_result_free(gdf_join_result);
    join_output = nullptr;

    // Host vector of result_type pairs to hold final result for comparison to reference solution
    std::vector<result_type> host_pair_result(total_pairs);

    // Copy raw output into corresponding result_type pair
    for(size_t i = 0; i < total_pairs; ++i){
      host_pair_result[i].first = host_result[i];
      host_pair_result[i].second = host_result[i + total_pairs];
    }

    // Sort the output for comparison to reference solution
    if(sort){
      std::sort(host_pair_result.begin(), host_pair_result.end());
    }

    if(print){
      std::cout << "GDF result size: " << host_pair_result.size() << std::endl;
      std::cout << "left index, right index" << std::endl;
      std::copy(host_pair_result.begin(), host_pair_result.end(), std::ostream_iterator<result_type>(std::cout, ""));
      std::cout << "\n";
    }

    return host_pair_result;
  }
};

