Finding the position of the first occurrence of a value in an std::integer_sequence

Viewed 288

I want to find the position of the first occurrence of a value in an std::integer_sequence.

  1. Is there an algorithm in the standard library for this task?
  2. If not, what would be a good way to do it?

--

Below is my attempt. It works, but I don't find it very elegant; also it fails to produce a clean error ("value not found") when the value is not present (code commented out due to compilation). (Also, having to specify the integer type in Find_in_integer_sequence feels redundant, but I suppose there is no way around it.)

The code is there just for your amusement, it is not supposed to be a starting point for a proposed solution.

# include <iostream>
# include <utility>
# include <type_traits>

namespace detail
{
  template < int Idx, typename T, T Match, T ...Values >
  struct Find;

  template < int Idx, bool B, typename T, T Match, T ...Values >
  struct Find_impl;

  template < int Idx, typename T, T Match, T ...Values >
  struct Find_impl<Idx, true, T, Match, Values...>
  {
    static const int value = Idx;
  };

  template < int Idx, typename T, T Match, T Value, T ...Other_values >
  struct Find_impl<Idx, false, T, Match, Value, Other_values...>
    : public Find<(Idx + 1), T, Match, Other_values...>
  {
  };

  template < int Idx, typename T, T Match, T Value, T ...Other_values >
  struct Find<Idx, T, Match, Value, Other_values...>
    : public Find_impl<Idx, (Match == Value), T, Match, Value, Other_values...>
  {
  };

  //template < int Idx, typename T, T Match >
  //struct Find<Idx, T, Match>
  //{
  //  static_assert(false, "value not found");
  //};
}

template < typename T, T Match, T ...Values >
struct Find
  : public detail::Find<0, T, Match, Values...>
{
};

template < typename T, T Match, typename TIS >
struct Find_in_integer_sequence;

template < typename T, T Match, T ...Values>
struct Find_in_integer_sequence<T, Match, std::integer_sequence<T, Values...>>
  : public Find<T, Match, Values...>
{
};

int main()
{
  using i1 = std::integer_sequence<int, 2, 3, 3, 2, 3, 2, 0>;
  auto k = Find_in_integer_sequence<int, 0, i1>::value;
  std::cout << k << std::endl; # prints "6"
  return 0;
}
2 Answers
Related