Boost 1.55 버전 기준으로 작성했습니다.


#pragma once


//#include <boost/mpl/aux_/test.hpp>

#include <vector>

#include <boost/mpl/assert.hpp>

#include <boost/type_traits/is_same.hpp>

#include <iostream>

#include <boost/mpl/vector_c.hpp>

#include <boost/mpl/list_c.hpp>


#include <boost/mpl/vector.hpp>

#include <boost/mpl/list.hpp>

#include <boost/mpl/map.hpp>


#include <boost/mpl/at.hpp>


#include <boost/mpl/push_front.hpp>

#include <boost/mpl/push_back.hpp>


#include <boost/mpl/integral_c.hpp>

#include <boost/mpl/size.hpp>

#include <boost/mpl/front.hpp>

#include <boost/mpl/back.hpp>


#include <boost/mpl/begin.hpp>

#include <boost/mpl/next.hpp>

#include <boost/mpl/deref.hpp>


#include <boost/mpl/prior.hpp>


#include <boost/mpl/empty.hpp>


#include <boost/type_traits.hpp>


#include <boost/mpl/equal.hpp>

#include <boost/mpl/remove.hpp>


#include <boost/mpl/apply.hpp>

#include <boost/mpl/minus.hpp>

#include <boost/mpl/plus.hpp>

#include <boost/mpl/int.hpp>


#include <boost/mpl/transform.hpp>

#include <boost/mpl/for_each.hpp>

#include <boost/mpl/equal_to.hpp>


namespace mpl = boost::mpl;


using namespace std;


//MPL_TEST_CASE()

//{

// MPL_ASSERT( (boost::is_same<char, char> ) );

//}


template< typename T, typename U >

struct is_same_another : boost::integral_constant< bool, false >

{

typedef ::boost::integral_constant< bool, false > base_;

using base_::value;

};


template< typename T >

struct is_same_another< T, T > : boost::integral_constant< bool, true >

{

typedef ::boost::integral_constant< bool, true > base_;

using base_::value;

};


void mpl_test()

{

// is same

{

std::cout << "is_same_another<bool,bool>::value; " << is_same_another< bool, bool >::value << std::endl;

std::cout << "is_same_another<bool,int>::value; " << is_same_another< bool, int >::value << std::endl;

}


//typedef mpl::push_back< int, mpl::integral_c< 100 > >::type push_back_test;


// vector c 테스트

// at_c 에서 뽑아온다.

{

typedef mpl::vector_c< int, 0, 2, 4, 6, 8 > container1;


cout << "----------------------------------------------" << endl;

cout << "mpl::vector_c, mpl::at_c 테스트" << endl;

cout << "----------------------------------------------" << endl;

cout << mpl::at_c< container1, 0 >::type::value << endl;

cout << mpl::at_c< container1, 1 >::type::value << endl;

cout << mpl::at_c< container1, 2 >::type::value << endl;

cout << mpl::at_c< container1, 3 >::type::value << endl;

cout << mpl::at_c< container1, 4 >::type::value << endl;

}


// 사이즈를 구하는 함수 mpl::size

// vector_c size

{

cout << "----------------------------------------------" << endl;

cout << "mpl::size 테스트" << endl;

cout << "----------------------------------------------" << endl;


typedef mpl::vector_c< int, 0, 2 > container1;

typedef mpl::vector_c< int, 0, 2, 4 > container2;

typedef mpl::vector_c< int, 0, 2, 4, 8 > container3;

typedef mpl::vector_c< int, 0, 2, 4, 8, 10 > container4;


cout << mpl::size< container1 >::value << endl;

cout << mpl::size< container2 >::type::value << endl;

cout << mpl::size< container3 >::value << endl;

cout << mpl::size< container4 >::value << endl;

}


// mpl::front - 첫번째 요소의 값을 구한다. mpl::back은 mpl::list 에서 적용 불가

{

cout << "----------------------------------------------" << endl;

cout << "mpl::list_c, mpl::front 테스트" << endl;

cout << "----------------------------------------------" << endl;


typedef mpl::list_c< int, 0, 1 > container1;

typedef mpl::list_c< int, 1, 2 > container2;

typedef mpl::list_c< int, 2, 3 > container3;

typedef mpl::list_c< int, 3, 4 > container4;


cout << mpl::front< container1 >::type::value << endl;

cout << mpl::front< container2 >::type::value << endl;

cout << mpl::front< container3 >::type::value << endl;

cout << mpl::front< container4 >::type::value << endl;

}


{

cout << "----------------------------------------------" << endl;

cout << "mpl::begin, mpl::next, mpl::deref, mpl::end 테스트" << endl;

cout << "----------------------------------------------" << endl;


typedef mpl::vector_c< int, 2, 4, 6, 8 > container1;


typedef mpl::begin< container1 >::type it1;

typedef mpl::next< it1 >::type it2;

typedef mpl::next< it2 >::type it3;

typedef mpl::next< it3 >::type it4;


cout << mpl::deref< it1 >::type::value << endl;

cout << mpl::deref< it2 >::type::value << endl;

cout << mpl::deref< it3 >::type::value << endl;

cout << mpl::deref< it4 >::type::value << endl;


typedef mpl::end< container1 >::type ie;

cout << "end ? - " << boost::is_same< ie, it4 >::value << endl;

typedef mpl::next< it4 >::type it5;

cout << "end ? - " << boost::is_same< ie, it5 >::value << endl;

}


{

cout << "----------------------------------------------" << endl;

cout << "mpl::prior 테스트, vector_c에서만 사용 가능" << endl;

cout << "----------------------------------------------" << endl;


typedef mpl::vector_c< int, 2, 4, 6, 8 > container1;


typedef mpl::end< container1 >::type itE;

typedef mpl::begin< container1 >::type itB;


typedef mpl::prior< itE >::type it4;

typedef mpl::prior< it4 >::type it3;

typedef mpl::prior< it3 >::type it2;

typedef mpl::prior< it2 >::type it1;


cout << mpl::deref<it1>::type::value << endl;

cout << mpl::deref<it2>::type::value << endl;

cout << mpl::deref<it3>::type::value << endl;

cout << mpl::deref<it4>::type::value << endl;

}


{

cout << "----------------------------------------------" << endl;

cout << "mpl::empty 테스트" << endl;

cout << "----------------------------------------------" << endl;


typedef mpl::vector_c< int, 2, 4, 6, 8 > container1;

typedef mpl::vector_c< int, 1 > container2;

typedef mpl::vector_c< int > container3;


cout << mpl::empty<container1>::type::value << endl;

cout << mpl::empty<container2>::type::value << endl;

cout << mpl::empty<container3>::type::value << endl;

}


// mpl::push_front, push_back - mpl::list 는 mpl::push_back 을 사용하지 못한다.

{

cout << "----------------------------------------------" << endl;

cout << "mpl::push_front 테스트" << endl;

cout << "----------------------------------------------" << endl;


typedef mpl::vector_c< int > container1_0;

typedef mpl::vector_c< int, 8, 6, 4, 2 > container3;


typedef mpl::push_front< container1_0, mpl::int_<2> >::type container1_1;

typedef mpl::push_front< container1_1, mpl::int_<4> >::type container1_2;

typedef mpl::push_front< container1_2, mpl::int_<6> >::type container1_3;

typedef mpl::push_front< container1_3, mpl::int_<8> >::type container1_4;


cout << mpl::at_c<container1_4, 0>::type::value << endl;

cout << mpl::at_c<container1_4, 1>::type::value << endl;

cout << mpl::at_c<container1_4, 2>::type::value << endl;

cout << mpl::at_c<container1_4, 3>::type::value << endl;


// 같은값은 아니다.

cout << "is same ? - " << boost::is_same< container1_4, container3 >::value << endl;


// mpl::equal 로 비교하면 같은값이 아니자나

cout << "is equal ? - " << mpl::equal< container1_4, container3 >::value << endl;

}


// mpl::push_front, push_back - mpl::list 는 mpl::push_back 을 사용하지 못한다.

{

cout << "----------------------------------------------" << endl;

cout << "mpl::remove 테스트" << endl;

cout << "----------------------------------------------" << endl;


// vector_c에서는 mpl::remove 가 적용되지 않는다.

typedef mpl::vector_c< int, 2, 2, 6, 8 > container1;

typedef mpl::remove< container1, mpl::int_<2> >::type container1_68;


cout << mpl::at_c<container1_68, 0>::type::value << endl;

cout << mpl::at_c<container1_68, 1>::type::value << endl;

cout << mpl::at_c<container1_68, 2>::type::value << endl;

cout << mpl::at_c<container1_68, 3>::type::value << endl;


// vector 에서는 mpl::remove 가 적용된다.

typedef mpl::vector< int, float, float, int > container2;

typedef mpl::vector< int, int > container3;


typedef mpl::remove< container2, float >::type container2_int;


cout << "equal? - " << mpl::equal< container2_int, container3 >::type::value << endl;


cout << typeid( mpl::at_c< container2_int, 0 >::type ).name() << endl;

cout << typeid( mpl::at_c< container2_int, 1 >::type ).name() << endl;

cout << typeid( mpl::at_c< container2_int, 2 >::type ).name() << endl;


// 컴파일 에러!

//cout << typeid( mpl::at_c< container2_int, 3 >::type ).name() << endl;

}


{

cout << "----------------------------------------------" << endl;

cout << "mpl:: 테스트" << endl;

cout << "----------------------------------------------" << endl;


// 자리값을 이용해 -3, 3 의 결과물이 나온다.

cout << mpl::apply< mpl::minus< mpl::_1, mpl::_2 >, mpl::int_<1>, mpl::int_<4> >::type::value << std::endl;

cout << mpl::apply< mpl::minus< mpl::_2, mpl::_1 >, mpl::int_<1>, mpl::int_<4> >::type::value << std::endl;


// unnamed placeholder( mpl::_ = 이름없는 자리표 ) 는 "순서대로 알아서 인수를 맵핑시켜달라" 라는 의미로 해석

cout << mpl::apply< mpl::plus< mpl::_, mpl::_ >, mpl::int_<1>, mpl::int_<4> >::type::value << std::endl;

cout << mpl::apply< mpl::plus< mpl::_, mpl::_ >, mpl::int_<4>, mpl::int_<1> >::type::value << std::endl;


// unnamed placeholder 가 2개라면 인수도 2개여야 한다. 그래서 이것은 에러!

// cout << mpl::apply< mpl::plus< mpl::_, mpl::_ >, mpl::int_<4> >::type::value << std::endl;


// 인수는 하나이지만 placeholder를 이용해서 컴파일이 가능하다.

cout << mpl::apply< mpl::plus< mpl::_1, mpl::_1 >, mpl::int_<4> >::type::value << std::endl;


}

}


 // Meta Function class

// 공개적으로 접근 가능한 apply 라는 메타 함수를 내포한 클래스


// 1. apply 의 내부에 기능을 직접 구현한 메타함수 클래스

struct MetaFuncClass_Plus

{

// apply 라는 메타 함수가 즉 표현식이 된다

template< typename T1, typename T2 >

struct apply

{

typedef typename mpl::plus< T1, T2 >::type type;

};

};


// 2. 상속을 통한 메타함수 클래스

struct MetaFuncForwarding_Plus

{

template< typename T1, typename T2 >

struct apply : mpl::plus< T1, T2 >

{


};

};


// mpl::apply 함수

// mpl 에서는 자리표 표현식과 메타함수 클래스를 Lambda Expression ( 람다 표현식 ) 이라고 합니다.

// 이는 둘다 apply 를 통하여 재평가 될 수 있다는 것을 위의 두 예제에서 보셨을 겁니다.

// mpl::apply< 첫번째 인수, 두번째, 세번째 >

// 위의 mpl::apply 함수는 첫번째 인수를 호출하는 메타함수이며, 첫번째 인수는 lambda Expression 이어야 합니다.

// 이를 적절히 호출하기 위해서는 람다표현식에 적용할 인수들( 두번째, 세번째 , ... )과 함꼐 호출되어져야 합니다.

void meta_test2()

{

cout << mpl::apply< MetaFuncClass_Plus, mpl::int_<2>, mpl::int_<3> >::type::value << std::endl;

cout << mpl::apply< MetaFuncForwarding_Plus, mpl::int_<2>, mpl::int_<3> >::type::value << std::endl;

}


// mpl::lambda 함수


template< typename N1, typename N2 >

struct my_plus

{

typedef mpl::integral_c< long, N1::value + N2::value > type;

};


struct print_list

{

template< class T >

void operator()( T a ) const

{

cout << a << "-";

}

};


#define TEST7


void meta_test3()

{

typedef mpl::list_c< long, 0, 2, 4, 6, 8, 10 > evens;

typedef mpl::list_c< long, 2, 3, 5, 7, 11, 13 > primes;

typedef mpl::list_c< long, 2, 5, 9, 13, 19, 23 > sums;


#ifdef TEST1

typedef mpl::transform< evens, primes, mpl::plus<> >::type result;

#endif


#ifdef TEST2

typedef mpl::transform< evens, primes, MetaFuncClass_Plus >::type result;

#endif


#ifdef TEST3

typedef mpl::transform< evens, primes, MetaFuncForwarding_Plus >::type result;

#endif


#ifdef TEST4

typedef mpl::transform< evens, primes, mpl::plus< mpl::_1, mpl::_2 > >::type result;

#endif


#ifdef TEST5

typedef mpl::transform< evens, primes, mpl::plus< mpl::_, mpl::_ > >::type result;

#endif


#ifdef TEST6

typedef mpl::transform< evens, primes, my_plus< mpl::_1, mpl::_2 > >::type result;

#endif


#ifdef TEST7

typedef mpl::transform< evens, primes, mpl::lambda< my_plus< mpl::_, mpl::_ > > >::type result;

#endif


mpl::for_each< result >( print_list() );

cout << endl;

mpl::for_each< sums >( print_list() );

cout << endl;


// 타입과 값 모두 체크

cout << "Equal? - " << mpl::equal< result, sums >::type::value << endl;


// 값들만 체크

cout << "Equal To? - " << mpl::equal< result, sums, mpl::equal_to< mpl::_1, mpl::_2 > >::type::value << std::endl;

}


template< class T >

struct foo_one

{

typedef T type;

};


template< class T >

struct foo_two

{

typedef typename foo_one<T>::type type;

};


template< class T >

struct foo_three

{

typedef typename foo_two<T>::type type;

};


void mpl_test4()

{

typedef foo_three<long>::type foo_three_of_type;


cout << typeid( foo_three_of_type ).name() << endl;

}


#define STD_OUT( a ) std_out(#a, typeid( a ).name() )


void std_out( const char* type_data, const char* type_name )

{

cout << "* TYPE_DATA - " << type_data << endl;

cout << "* TYPE_NAME - " << type_name << endl;

cout<< endl << endl;

}


// 적절한 방법으로 지연평가를 수행함

void test_one()

{

typedef std::vector< mpl::_ > vec_lambda;

STD_OUT( vec_lambda );


typedef mpl::lambda< vec_lambda >::type vec_mata_func;

STD_OUT( vec_mata_func );


typedef mpl::apply< vec_lambda, int >::type::iterator vec_int_iterator;

STD_OUT( vec_int_iterator );

}


// 템플릿 인스턴스화가 되고 나서 지연평가 apply 를 수행함

void test_two()

{

typedef std::vector< mpl::_ >::iterator vec_it_lambda;

STD_OUT( vec_it_lambda );


typedef mpl::lambda< vec_it_lambda >::type vec_it_meta_func;

STD_OUT( vec_it_meta_func );

}


void mpl_test5()

{

test_one();

test_two();

}


'Boost' 카테고리의 다른 글

Boost Optional 샘플  (0) 2016.01.31
Multi Index 샘플  (0) 2016.01.31
Boost Meta State Machine 테스트 2  (0) 2016.01.29
Boost Meta State Machine 테스트  (0) 2016.01.29
Boost lock-free Queue 성능 테스트  (0) 2016.01.29
      Boost  |  2016. 1. 29. 17:59



홍쿤사마's Blog is powered by Daum