/*!
 * Checks whether a variable has one of many possible values.
 *
 * Example: if(Utils::isOneOf(var, {val1, val2, val3})) doSomething();
 *
 * \param candidate the variable to be checked
 * \param list      vector containing possible values
 *
 * \returns true if there is a match.
 */
template<typename T>
static inline bool isOneOf(const T& candidate, const std::vector<T>& list)
{
  for(auto& element : list)
  {
    if(candidate == element)
    {
      return true;
    }
  }
  return false;
}


/*!
 * Checks whether a variable has one of many possible values.
 *
 * Example: if(Utils::isNoneOf(var, {val1, val2, val3})) doSomething();
 *
 * \param candidate the variable to be checked
 * \param list      vector containing possible values
 *
 * \returns true if there is no match.
 */
template<typename T>
static inline bool isNoneOf(const T& candidate, const std::vector<T>& list)
{
  for(auto& element : list)
  {
    if(candidate == element)
    {
      return false;
    }
  }
  return true;
}


/*!
 * Returns a vector of strings that correspond to the string
 * representations of the elements in list.
 *
 * The type of the elements in list must provide the function
 * std::string toString().
 *
 */
template<class C>
static inline std::vector<std::string> allToString(const std::vector<C>& list)
{
  std::vector<std::string> answer;

  for(auto& element : list)
  {
    answer.push_back(element.toString());
  }

  return answer;
}


/*!
 * Returns a string that is the concatenation of the strings in the
 * standard container list, using the separator sep.
 */
template<class C>
static inline std::string joinStrings(const std::string& sep, const C& list)
{
  if(list.empty())
  {
    return "";
  }

  std::stringstream ans;

  for(auto& element : list)
  {
    ans << sep << element;
  }

  return ans.str().substr(sep.length());
}