Yeah, though it is a little less [...] of say Boost.Lamdba and such.
You could also go the other direction.
Still a lot of work. (NNR)
Soma
Code:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
// a sortof `meta-function' to provide a default delmiter value
// based on the types used in the operation and
// the specializations needed for the standard streams
template
<
typename T
>
struct delimiter
{
static T get();
};
template <> struct delimiter<char>
{
static char get()
{
return(',');
}
};
template <> struct delimiter<wchar_t>
{
static wchar_t get()
{
return(L',');
}
};
// a `meta-function' to work around a few broken compilers
// and a few problematic `iterator_traits' implementation
// issues so we can properly determine the type to be
// stored
// works because the nested `value_type' of
// unspecialized `std::iterator_traits' should
// always be `void'
template
<
typename itT,
typename typeT
>
struct discover_nested_type2
{
typedef typeT type;
};
template
<
typename itT
>
struct discover_nested_type2<itT, void>
{
typedef typename itT::container_type::value_type type;
};
// the interface to the above `meta-function'
template
<
typename itT
>
struct discover_nested_type
{
typedef typename std::iterator_traits<itT>::value_type maybe_value_type;
typedef typename discover_nested_type2<itT, maybe_value_type>::type type;
};
// a function to "parse" delimted strings
// ignores quoted values and quoted value pairs
template
<
typename inputT,
typename outputT
>
void process
(
inputT begin, // expects a `char *',
inputT end, // `wchar_t *', or compatible
outputT out, // expects an "input iterator" of some kind (including trivial pointer types)
typename std::iterator_traits<inputT>::value_type delim = delimiter<typename std::iterator_traits<inputT>::value_type>::get()
)
{
using namespace std;
typedef typename iterator_traits<inputT>::value_type char_type;
typedef typename discover_nested_type<outputT>::type value_type;
basic_string<char_type> temp(begin, end);
basic_istringstream<char_type> input(temp);
while(getline(input, temp, delim))
{
value_type data;
basic_istringstream<char_type> tin(temp);
if(tin >> data)
{
*out++ = data;
}
else
{
throw("something");
}
}
}
int main()
{
using namespace std;
string test1("1.1,2.2,3.3,4.4");
vector<double> data1;
process(test1.begin(), test1.end(), back_inserter(data1));
cout << "number of elements (1): " << data1.size() << '\n';
copy(data1.begin(), data1.end(), ostream_iterator<double>(cout, "\n"));
char test2[] = "-5&6&-7&8&9";
int sizeof_test2(sizeof(test2)/sizeof(test2[0]));
int data2[5];
int sizeof_data2(sizeof(data2)/sizeof(data2[0]));
process(test2, test2 + sizeof_test2, data2, '&');
cout << "\nnumber of elements (2): " << 5 << '\n';
copy(data2, data2 + sizeof_data2, ostream_iterator<int>(cout, "\n"));
return(0);
}