1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
#include <iostream>
#include <list>
#include <vector>

#include "concatenate.hpp"

template <typename A, typename B>
struct IsSame
{
    static constexpr bool value = false;
};

template <typename A>
struct IsSame<A, A>
{
    static constexpr bool value = true;
};

template <bool cond, typename ret>
struct RestrictTo
{
};

template <typename ret>
struct RestrictTo<true,ret>
{
    typedef ret     type;
};


// SFINAE
template <typename A, typename B>
typename RestrictTo<IsSame<A,B>::value, void>::type
foo(A i, B j)
{
    std::cout << "A and B are the same" << std::endl;
}

template <typename A, typename B>
typename RestrictTo<! IsSame<A,B>::val(), void>::type
foo(A i, B j)
{
    std::cout << "A and B are *not* the same" << std::endl;
}

int
main()
{
    std::vector<int> a = {123};
    std::list<int>   b = {456};

    // auto of type:
    // typename ConcatenatedContainerView<std::vector<int>,
    //                                    list<int> >::iterator

    /*
    for (auto it = concatenate(a,b).begin(); it != concatenate(a,b).end(); ++it)
    {
        std::cout << *it << std::endl;
    }
    */
    for (int i : concatenate(concatenate(a,a),a)) {
        std::cout << i << std::endl;
    }

    /*
    std::cout << IsSame<int,int>::value << std::endl;
    std::cout << IsSame<float,int>::value << std::endl;


    foo(1,   3);  // foo(int,int)
    foo(1.3, 5);  // foo(double,int)
    */

    /*
    for (int i : a & b) {
        std::cout << i << std::endl;
    }
    */
}