#include <cstdint>
#include <iostream>

extern "C" {
  void trn1( int32_t const * in0,
             int32_t const * in1,
             int32_t       * out );
  void trn2( int32_t const * in0,
             int32_t const * in1,
             int32_t       * out );
  void zip1( int32_t const * in0,
             int32_t const * in1,
             int32_t       * out );
  void zip2( int32_t const * in0,
             int32_t const * in1,
             int32_t       * out );
};

int main( int    argc,
          char * argv[] ) {

  int32_t l_in0[4] = { 0, 1, 2, 3 };
  int32_t l_in1[4] = { 4, 5, 6, 7 };
  int32_t l_out[4] = { 0 };

  std::cout << "in0:  ";
  for( int i = 0; i < 4; ++i ) {
    std::cout << l_in0[i] << " ";
  }
  std::cout << std::endl;

  std::cout << "in1:  ";
  for( int i = 0; i < 4; ++i ) {
    std::cout << l_in1[i] << " ";
  }
  std::cout << std::endl;


  // TRN1: interleaves odd elements from both vectors
  trn1( l_in0,
        l_in1,
        l_out );
  std::cout << "TRN1: ";
  for( int i = 0; i < 4; ++i ) {
    std::cout << l_out[i] << " ";
  }
  std::cout << std::endl;

  // TRN2: interleaves even elements from both vectors
  trn2( l_in0,
        l_in1,
        l_out );
  std::cout << "TRN2: ";
  for( int i = 0; i < 4; ++i ) {
    std::cout << l_out[i] << " ";
  }
  std::cout << std::endl;

  // ZIP1: interleaves first half of elements
  zip1( l_in0,
        l_in1,
        l_out );
  std::cout << "ZIP1: ";
  for( int i = 0; i < 4; ++i ) {
    std::cout << l_out[i] << " ";
  }
  std::cout << std::endl;

  // ZIP2: interleaves second half of elements
  zip2( l_in0,
        l_in1,
        l_out );
  std::cout << "ZIP2: ";
  for( int i = 0; i < 4; ++i ) {
    std::cout << l_out[i] << " ";
  }
  std::cout << std::endl;

  return EXIT_SUCCESS;
}
