Giter VIP home page Giter VIP logo

tuple_utility's Introduction

tuple_utility

Utilities for C++ tuples.

tuple_map:

#include "tuple_utility.hpp"

int main()
{
  auto t = std::make_tuple(0, 1, 2, 3);

  auto negative_t = tuple_map([](int x)
  {
    return -x;
  }, t);

  std::cout << "negative_t: ";
  tuple_print(negative_t);
  std::cout << std::endl;

  // prints 0, -1, -2, -3

  return 0;
}

std::arrays are tuples too:

#include "tuple_utility.hpp"
#include <array>

int main()
{
  std::array<int> t = {0, 1, 2, 3};

  auto negative_t = tuple_map([](int x)
  {
    return -x;
  }, t);

  std::cout << "negative_t: ";
  tuple_print(negative_t);
  std::cout << std::endl;

  // prints 0, -1, -2, -3

  return 0;
}

As is any type which specializes tuple_traits:

#include "tuple_utility.hpp"
#include <utility>

struct my_float3
{
  float x, y, z;
};

template<>
struct tuple_traits<my_float3>
{
  using tuple_type = my_float3;
  
  static const size_t size = 3;
  
  template<size_t i>
  using element_type = float;
  
  template<size_t i>
  static float& get(tuple_type& t)
  {
    static_assert(i < size, "i must be < size");
    return &t.x + i;
  }
  
  template<size_t i>
  static const float& get(const tuple_type& t)
  {
    static_assert(i < size, "i must be < size");
    return &t.x + i;
  }
  
  template<size_t i>
  static float&& get(tuple_type&& t)
  {
    static_assert(i < size, "i must be < size");
    return std::move(&t.x + i);
  }
};

int main()
{
  my_float3 t = {0.f, 1.f, 2.f};

  auto negative_t = tuple_map([](float x)
  {
    return -x;
  }, t);

  std::cout << "negative_t: ";
  tuple_print(negative_t);
  std::cout << std::endl;

  // prints 0, -1, -2

  return 0;
}

tuple_map is variadic:

#include "tuple_utility.hpp"

int main()
{
  auto t = std::make_tuple(0, 1, 2, 3);

  auto negative_t = tuple_map([](int x)
  {
    return -x;
  }, t);

  auto zero_t = tuple_map([](int x, int y)
  {
    return x + y;
  }, t, negative_t);

  std::cout << "zero_t: ";
  tuple_print(zero_t);
  std::cout << std::endl;

  // prints 0, 0, 0, 0

  return 0;
}

tuple_head & tuple_tail:

#include "tuple_utility.hpp"

int main()
{
  auto t = std::make_tuple(0, 1, 2, 3);

  std::cout << "t's head is " << tuple_head(t) << std::endl;
  
  // prints 0

  auto t_tail = tuple_tail(t);
  std::cout << "t's tail is ";
  tuple_print(t_tail);
  std::cout << std::endl;

  // prints 1, 2, 3

  return 0;
}

tuple_take & tuple_drop:

#include "tuple_utility.hpp"

int main()
{
  auto t = std::make_tuple(0, 1, 2, 3);

  auto t_take_2 = tuple_take<2>(t);

  std::cout << "t_take_2 is ";
  tuple_print(t_take_2);
  std::cout << std::endl;

  // prints 0, 1

  auto t_drop_2 = tuple_drop<2>(t);

  std::cout << "t_drop_2 is ";
  tuple_drop<2>(t);
  std::cout << std::endl;

  // prints 2, 3

  return 0;
}

tuple_append:

#include "tuple_utility.hpp"

int main()
{
  auto t = std::make_tuple(0, 1, 2, 3);

  auto t_append_4 = tuple_append(t, 4);

  std::cout << "t_append_4 is ";
  tuple_print(t_append_4);
  std::cout << std::endl;

  // prints 0, 1, 2, 3, 4

  return 0;
}

tuple_prepend:

#include "tuple_utility.hpp"

int main()
{
  auto t = std::make_tuple(0, 1, 2, 3);

  auto t_prepend_neg_1 = tuple_prepend(t, -1);

  std::cout << "t_prepend_neg_1 is ";
  tuple_print(t_prepend_neg_1);
  std::cout << std::endl;

  // prints -1, 0, 1, 2, 3

  return 0;
}

make_from_tuple:

#include "tuple_utility.hpp"
#include <vector>

int main()
{
  auto t = std::make_tuple(13, 13);

  auto vector_of_13s = make_from_tuple<std::vector<int>>(t);

  // vector_of_13s is a std::vector<int> containing 13
  // elements which are all equal to 13

  return 0;
}

tuple_reduce:

#include "tuple_utility.hpp"

int main()
{
  auto t = std::make_tuple(0, 1, 2, 3);

  auto sum = tuple_reduce(t, 0, [](int x, int y){return x + y;});

  std::cout << "sum of t's elements is " << sum << std::endl;
  // prints 6

  return 0;
}

tuple_for_each:

#include "tuple_utility.hpp"

int main()
{
  auto t = std::make_tuple(0, 1, 2, 3);

  auto sum = tuple_for_each([](int& x){ ++x; }, t);

  tuple_print(t);
  // prints 1, 2, 3, 4

  return 0;
}

tuple_filter:

#include "tuple_utility.hpp"
#include <type_traits>
#include <string>

int main()
{
  auto t1 = std::make_tuple(13, 3.14159, std::string("hi there"));

  auto t2 = tuple_filter<std::is_arithmetic>(t1);

  tuple_print(t2);
  std::cout << std::endl;
  // prints 13, 3.14159

  return 0;
}

tuple_lexicographical_compare:

#include "tuple_utility.hpp"

int main()
{
  auto t1 = std::make_tuple(0, 1, 2);
  auto t2 = std::make_tuple(3, 4);

  std::cout << "t1 is less than t2: " << tuple_lexicographical_compare(t1, t2) << std::endl;
  // prints 1

  auto t3 = std::make_tuple(5, 6, 7);
  auto t4 = std::make_tuple(0, 1, 2, 3, 4);

  std::cout << "t3 is less than t4: " << tuple_lexicographical_compare(t3, t4) << std::endl;
  // prints 0

  return 0;
}

tuple_repeat:

#include "tuple_utility.hpp"

int main()
{
  auto t1 = tuple_repeat<3>(13.0);

  tuple_print(t1);
  std::cout << std::endl;
  // prints 13, 13, 13

  return 0;
}

tuple_gather:

#include "tuple_utility.hpp"

int main()
{
  auto t1 = std::make_tuple('a', 'b', 'c', 'd', 'e');
  auto t2 = tuple_gather<0,2,4>(t1);

  tuple_print(t2);
  std::cout << std::endl;
  // prints a, c, e

  return 0;
}

tuple_utility's People

Contributors

jaredhoberock avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tuple_utility's Issues

nested tuple support

I'd really like to make use of this library, but would need support for nested tuples:

  auto one_t = std::make_tuple(std::make_tuple(1),std::make_tuple(1,1));
  auto two_t = std::make_tuple(std::make_tuple(2),std::make_tuple(2,2));

  auto three_t = nested_tuple_map([](int x, int y){return x + y ;}, one_t, two_t);

  assert(three_t == std::make_tuple(std::make_tuple(3),std::make_tuple(3,3)));

tuple_sort

Would it be possible to implement tuple_sort or even tuple_sort_by_key? I would find these useful.

__tuple_cat_get_result should static_assert its parameter is a reference

We're computing the result of functions like __get() incorrectly, and its causing results to get silently cast to a value.

To get this right, we need to make sure __tuple_cat_get_result propagates its reference type correctly, and to do that, we need to make sure to always pass it a reference type.

tuple_get

What do you think of tuple_get, a generalized form of get? In general:

    tuple_get<I...>(tuple) == make_tuple(get<I>(tuple)...)

An example:

   auto a = make_tuple(1,2,3);
   assert(tuple_get<2,1>(a) == make_tuple(3,2));
   assert(tuple_get<0,0,1,1,2,2>(a) == make_tuple(1,1,2,2,3,3));

I could describe the specific application to illustrate how this would be extraordinarily useful, but suffice it to say, this would simplify a ton of code I have. Would you be interested in such a contribution to your tuple_utility library?

vectorization of tuple_map, tuple_reduce

Do you have any thoughts on achieving vectorization via tuple_map, tuple_reduce, or any other operations in this library?

Over the years, I have experimented with implementing my own for_each_n using OpenMP/TBB and various versions of Intel's vectorization directives -- as would be allowed by a call to for_each_n with parallel_vector_execution_policy. This was unsuccessful for the case of non-trivial loops. I definitely could investigate that approach further, and it probably was just a result of limitations of older versions of icpc and my own lack of knowledge about vectorization. I could also just wait to try out implementations of parallel_vector_execution_policy...

However, your library got me thinking that perhaps vectorization could be achieved in a more explicit fashion: instead of vectorizing entire loops, perhaps instead vectorization could be achieved inside of each iteration of these loops, by vectorizing each individual tuple operation (implementable by calls to tuple_map, tuple_reduce, etc.). Typical tuple sizes are currently O(10).

The general pattern (in pseudocode) I deal with is:

for(auto cell : grid)    // <--- parallelize here, no luck at requesting vectorization here (pragma ivdep, simd, etc.)
{
   // read tuple data in from memory  -- tuple_size is O(10)

   // tuple_map  <--- vectorize here
   // tuple_reduce <-- vectorize here
   // tuple_map <-- vectorize here
   // etc.

   // store tuple data to memory
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.