#ifndef __UTILITIES_VARIOUS_H
#define __UTILITIES_VARIOUS_H

#include <vector>
#include <map>
#include <unordered_map>

template<typename TK, typename TV>
std::vector<TK> map_keys(std::map<TK, TV> const& input_map) {
  std::vector<TK> retval;
  for (auto const& element : input_map) {
    retval.push_back(element.first);
  }
  return retval;
}

template<typename TK, typename TV>
std::vector<TV> map_values(std::map<TK, TV> const& input_map) {
  std::vector<TV> retval;
  for (auto const& element : input_map) {
    retval.push_back(element.second);
  }
  return retval;
}

template<typename TK, typename TV>
std::vector<TK> map_keys(std::unordered_map<TK, TV> const& input_map) {
  std::vector<TK> retval;
  for (auto const& element : input_map) {
    retval.push_back(element.first);
  }
  return retval;
}

template<typename TK, typename TV>
std::vector<TV> map_values(std::unordered_map<TK, TV> const& input_map) {
  std::vector<TV> retval;
  for (auto const& element : input_map) {
    retval.push_back(element.second);
  }
  return retval;
}

inline std::string join(const std::vector<std::string>& v, std::string separator) {
	std::string result;
	for (size_t i = 0, i_end = v.size(); i < i_end; ++i) {
		if(i) { result += separator; }
		result += v[i];
	}
	return result;
}

#endif // __UTILITIES_VARIOUS_H
