Skip to content

Instantly share code, notes, and snippets.

@mpapierski
Created August 10, 2013 15:57
Show Gist options
  • Save mpapierski/6200965 to your computer and use it in GitHub Desktop.
Save mpapierski/6200965 to your computer and use it in GitHub Desktop.
sql-like syntax for standard library containers
#include <iostream>
#include <string>
#include <boost/tuple/tuple.hpp>
#include <boost/utility.hpp>
#include <vector>
#include <boost/typeof/typeof.hpp>
#include <boost/foreach.hpp>
struct person
{
int id_;
std::string first_name_;
std::string last_name_;
person(int id, std::string first_name, std::string last_name)
: id_(id)
, first_name_(first_name)
, last_name_(last_name)
{
}
};
/**
* Convert pointer to member variable to its type.
* Example:
* std::string Class::* returns T.
* We don't need implementation because we only use it in expression
* which is OK to calculate result type.
*/
template <typename T, typename Cls>
T process_member_variable(T Cls::*input);
/**
* Wrapper around our type process function.
* Calculates result of expression that yields actual type of pointer to
* member variable.
* type_from_member<T Cls::*>::type is T
*/
template <typename T>
struct type_from_member
{
typedef BOOST_TYPEOF(process_member_variable(T())) type;
};
template <typename FromT, typename T1>
struct select_impl
{
FromT from_obj_;
T1 t1_;
typedef typename type_from_member<T1>::type arg1_type;
select_impl(FromT from_obj, T1 t1)
: from_obj_(from_obj)
, t1_(t1)
{}
std::vector<boost::tuple<arg1_type> > to_vector()
{
typedef typename FromT::value_type::iterator iter_type;
std::vector<boost::tuple<arg1_type> > results;
for (iter_type it = from_obj_.input_.begin(); it != from_obj_.input_.end(); ++it)
{
const arg1_type & arg1 = (*it).*t1_;
results.push_back(boost::make_tuple(arg1));
}
return results;
}
};
template <typename T>
struct from_impl
{
typedef from_impl<T> this_type;
typedef T value_type;
T & input_;
from_impl(T & input)
: input_(input)
{
}
template <typename F1>
select_impl<this_type, F1> select(F1 f1)
{
return select_impl<this_type, F1>(*this, f1);
}
};
template <typename T>
from_impl<T> from(T & input) { return from_impl<T>(input); }
int
main()
{
std::vector<person> vec;
vec.push_back(person(1, "first name 1", "last name 1"));
vec.push_back(person(2, "first name 2", "last name 2"));
// make query
std::vector<boost::tuple<std::string> > out =
from(vec).
select(&person::first_name_).
to_vector();
// Iterate over result set
BOOST_FOREACH(boost::tuple<std::string> & result, out)
{
std::cout << boost::get<0>(result) << std::endl;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment