# CPPTM Answers - Exercise 9-4

BOOST WIKI | RecentChanges | Preferences | Page List | Links List

No diff available--this is the first major revision. (no other diffs)
``` // (by Ariel Badichi)
#include <iostream>
#include <iterator>
#include <vector>
#include <list>
```

``` #include <boost/assign.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/eval_if.hpp>
```

``` namespace mpl = boost::mpl;
```

``` template<typename Iter>
typename boost::enable_if<
boost::is_arithmetic<
typename boost::iterator_value<Iter>::type
>,
typename boost::iterator_value<Iter>::type
>::type sum(Iter first, Iter last)
{
typename boost::iterator_value<Iter>::type x(0);
for (; first != last; ++first)
x += *first;
return x;
}
```

``` template<typename Cont>
struct inner_value_cont;
```

``` template<typename Iter>
struct inner_value
{
typedef typename boost::iterator_value<Iter>::type iv;
typedef typename mpl::eval_if<
boost::is_arithmetic<iv>,
mpl::identity<iv>,
inner_value_cont<iv>
>::type type;
};
```

``` template<typename Cont>
struct inner_value_cont : inner_value<typename Cont::iterator> {};
```

``` template<typename Iter>
typename boost::lazy_disable_if<
boost::is_arithmetic<
typename boost::iterator_value<Iter>::type
>,
inner_value<Iter>
>::type sum(Iter first, Iter last)
{
typename inner_value<Iter>::type x(0);
for (; first != last; ++first)
x += sum(first->begin(), first->end());
return x;
}
```

``` int main()
{
using namespace boost::assign;
```

```     std::vector<int> v;
v += 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
```

```     std::cout << sum(v.begin(), v.end()) << "\n";
```

```     std::vector<std::vector<float> > vv(2);
vv[0] += 1.2f, 3.14f, 5.0f;
vv[1] += 2.8f, 1.86f, 3.0f;
```

```     std::cout << sum(vv.begin(), vv.end()) << "\n";
```

```     std::list<std::list<std::vector<int> > > llv;
std::list<std::vector<int> > lv;
lv += v, v;
llv += lv, lv, lv;
```

```     std::cout << sum(llv.begin(), llv.end()) << "\n";
```

```     return 0;
}
```

BOOST WIKI | RecentChanges | Preferences | Page List | Links List