Boost - 해당되는 글 25건

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




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


#include <iostream>

#include <boost/msm/back/state_machine.hpp>

#include <boost/msm/front/state_machine_def.hpp>

#include <boost/msm/front/functor_row.hpp>


namespace msm = boost::msm;

namespace mpl = boost::mpl;

using namespace boost::msm::front;





// 이벤트들

struct play {};

struct end_pause{};

struct stop{};

struct pause {};

struct open_close {};

struct NextSong {};

struct PreviousSong {};

struct error_found {};

struct end_error {};

struct end_error2 {};


// 플래그, 현재 상태의 property에 관한 정보를 허용한다.

struct PlayingPaused {};

struct CDLoaded {};

struct FirstSongPlaying {};


// 약간의 데이터를 전달하는 완료된 이벤트 타입 

struct cd_detected

{

cd_detected( std::string _name ) : name( _name )

{}


std::string name;

};


// front-end 로 정의돈 FSM 구조체

struct player_ : public msm::front::state_machine_def< player_ >

{

typedef int activate_deferred_events;


//

// FSM 상태들.

struct Empty : public msm::front::state<>

{

// 플레이 이벤트가 이 상태를 떠나면, 그 플레이 상태가 처리 되거나 또는 거부 될때까지 지연된다 

//typedef mpl::vector<play> deferred_events;


// 모든(선택적인) entry/exit 함수는 전달된 이벤트를 갖는다.

template< class Event, class FSM >

void on_entry(Event const&, FSM&) { std::cout << "입장: 빈 상태" << std::endl; }

template< class Event, class FSM >

void on_exit( Event const& , FSM& ) { std::cout << "퇴장: 빈 상태" << std::endl; }

};


struct Open : public msm::front::state<>

{

// 플레이 이벤트가 이 상태를 떠나면, 그 플레이 상태가 처리 되거나 또는 거부 될때까지 지연된다 

//typedef mpl::vector<play> deferred_events;

typedef mpl::vector1<CDLoaded> flag_list;


template< class Event, class FSM >

void on_entry(Event const&, FSM&) { std::cout << "입장: 열린 상태" << std::endl; }

template< class Event, class FSM >

void on_exit( Event const& , FSM& ) { std::cout << "퇴장: 열린 상태" << std::endl; }

};


struct Stopped : public msm::front::state<>

{

// 플레이 이벤트가 이 상태를 떠나면, 그 플레이 상태가 처리 되거나 또는 거부 될때까지 지연된다

typedef mpl::vector1<CDLoaded> flag_list;


template< class Event, class FSM >

void on_entry(Event const&, FSM&) { std::cout << "입장: 정지된 상태" << std::endl; }

template< class Event, class FSM >

void on_exit( Event const& , FSM& ) { std::cout << "퇴장: 정지된 상태" << std::endl; }

};


// 플레이어 상태 머신에 포함된 상태는 스스로 그러한 상태 머신이 된다.

// 당신이 보는것처럼, 플레잉은 따로 선언이 필요 없이 

// 어디에서든  다른팀의 다른 모듈로 따로따로 개발되어질수 있다. 

// 이것은 내가 간단히 plyaer 내부에 정의했다.

struct Playing_ : public msm::front::state_machine_def<Playing_>

{

// 플레이 중일때, cd 는 로딩완료되었고, 우리는 일시정지 또는 플레잉안에 있다.

typedef mpl::vector2< PlayingPaused, CDLoaded > flag_list;


template< class Event, class FSM >

void on_entry(Event const&, FSM&) { std::cout << "입장: 플레이중 상태" << std::endl; }

template< class Event, class FSM >

void on_exit( Event const& , FSM& ) { std::cout << "퇴장: 플레이중 상태" << std::endl; }


// FSM 상태 리스트들

struct Song1 : public msm::front::state<>

{

typedef mpl::vector1< FirstSongPlaying > flag_list;


template< class Event, class FSM >

void on_entry(Event const&, FSM&) { std::cout << "입장: 첫번째 노래 상태" << std::endl; }

template< class Event, class FSM >

void on_exit( Event const& , FSM& ) { std::cout << "퇴장: 첫번째 노래 상태" << std::endl; }

};


struct Song2 : public msm::front::state<>

{

template< class Event, class FSM >

void on_entry(Event const&, FSM&) { std::cout << "입장: 두번째 노래 상태" << std::endl; }

template< class Event, class FSM >

void on_exit( Event const& , FSM& ) { std::cout << "퇴장: 두번째 노래 상태" << std::endl; }

};


struct Song3 : public msm::front::state<>

{

template< class Event, class FSM >

void on_entry(Event const&, FSM&) { std::cout << "입장: 세번째 노래 상태" << std::endl; }

template< class Event, class FSM >

void on_exit( Event const& , FSM& ) { std::cout << "퇴장: 세번째 노래 상태" << std::endl; }

};


// 초기화 상태는 반드시 정의되야 함

typedef Song1 initial_state;


//

// 전이 행동들

void start_next_song( NextSong const& ) { std::cout << "재생중:다음곡 재생 시작" << std::endl; }

void start_prev_song( PreviousSong const& ) { std::cout << "재생중:이전곡 재생 시작" << std::endl; }


//

// 방어 조건들


//

// 전이 테이블을 쉽게 만들기 위해 typedef

typedef Playing_ pl;


// Playing_을 위한 전이 테이블

struct transition_table : mpl::vector4

<

// 시작, 이벤트, 다음, 전이 행동, 방어행동

// +-------------------+-------------------+-------------------+--------------------------+----------------+

a_row< Song1 , NextSong , Song2 , &pl::start_next_song >,

a_row< Song2 , PreviousSong , Song1 , &pl::start_prev_song >,

a_row< Song2 , NextSong , Song3 , &pl::start_next_song >,

a_row< Song3 , PreviousSong , Song2 , &pl::start_prev_song >

> {};


// 기본 no-transition 응답을 재정의

template< class FSM, class Event >

void no_transition( Event const& e, FSM&, int state )

{

std::cout << "no_transition from state " << state << " on evert" << typeid(e).name() << std::endl;

}

};


// back-end( 실질적인 인스턴스를 생성하는 것 )

typedef msm::back::state_machine< Playing_ > Playing;


// entry/exit 를 정의하지 않는 상태

struct Paused : public msm::front::state<>

{

typedef mpl::vector2< PlayingPaused, CDLoaded > flag_list;

};


// all ok

struct AllOK : public msm::front::state<>

{

template< class Event, class FSM >

void on_entry(Event const&, FSM&) { std::cout << "입장: All OK 상태" << std::endl; }

template< class Event, class FSM >

void on_exit( Event const& , FSM& ) { std::cout << "퇴장: All OK 상태" << std::endl; }

};


// 이 상태는 모든 이벤트가 막혔을 때 가게되는 만들어진 종점 상태이다.

struct ErrorMode : public msm::front::interrupt_state< end_error > // 에러모드는 중단 뿐이 없다. 되돌리려면 end_error 이벤트를 발생시킨다.

{

template< class Event, class FSM >

void on_entry(Event const&, FSM&) { std::cout << "입장: ErrorMode 상태" << std::endl; }

template< class Event, class FSM >

void on_exit( Event const& , FSM& ) { std::cout << "퇴장: ErrorMode 상태" << std::endl; }

};


// player 상태 머신의 초기화 상태

typedef mpl::vector< Empty, AllOK > initial_state;


// 전이 행돌들

void start_playback( play const& ) { std::cout << "CD 플레이어: 재생 시작" << std::endl; }

void open_drawer( open_close const& ) { std::cout << "CD 플레이어: CD drawer 열기" << std::endl; }

void close_drawer( open_close const& ) { std::cout << "CD 플레이어: CD drawer 닫기" << std::endl; }

void store_cd_info( cd_detected const& ) { std::cout << "CD 플레이어: CD 정보 읽기" << std::endl; }

void stop_playback( stop const& ) { std::cout << "CD 플레이어: 재생 중지" << std::endl; }

void pause_playback( pause const& ) { std::cout << "CD 플레이어: 재생 일시 정지" << std::endl; }

void resume_playback( end_pause const& ) { std::cout << "CD 플레이어: 다시 재생" << std::endl; }

void stop_and_open( open_close const& ) { std::cout << "CD 플레이어: 정지 후 CD drawer 열기" << std::endl; }

void stopped_again( stop const& ) { std::cout << "CD 플레이어: 다시 정지" << std::endl; }


void report_error( error_found const& ) { std::cout << "CD 플레이어: 문제 발생 알림" << std::endl; }

void report_end_error( end_error const& ) { std::cout << "CD 플레이어: 문제 종료 알림" << std::endl; }


// 전이 테이플 편하게 할라꼬

typedef player_ p;


struct transition_table : mpl::vector< 

// Start Event Next Action Guard

// +--------------+------------------+----------------+------------------------+------------------------+

// 정지 상태

a_row < Stopped, play, Playing, &p::start_playback >,

a_row < Stopped, open_close, Open, &p::open_drawer >,

a_row < Stopped, stop, Stopped, &p::stopped_again >,


// +--------------+------------------+----------------+------------------------+------------------------+

// 열림 상태

a_row < Open, open_close, Empty, &p::close_drawer >,

Row < Open, play, none, Defer, none >,


// +--------------+------------------+----------------+------------------------+------------------------+

// 빈 상태

a_row < Empty, open_close, Open, &p::open_drawer >,

a_row < Empty, cd_detected, Stopped, &p::store_cd_info >,

Row < Empty, play, none, Defer, none >,


// +--------------+------------------+----------------+------------------------+------------------------+

// 재생 상태

a_row < Playing, stop, Stopped, &p::stop_playback >,

a_row < Playing, pause, Paused, &p::pause_playback >,

a_row < Playing, open_close, Open, &p::stop_and_open >,


// +--------------+------------------+----------------+------------------------+------------------------+

// 일지 정시 상태

a_row < Paused, end_pause, Playing, &p::resume_playback >,

a_row < Paused, stop, Stopped, &p::stop_playback >,

a_row < Paused, open_close, Open, &p::stop_and_open >,


// +--------------+------------------+----------------+------------------------+------------------------+

// 일지 정시 상태

a_row < AllOK, error_found, ErrorMode, &p::report_error >,

a_row < ErrorMode, end_error, AllOK, &p::report_end_error >


>{};


// 기본 no-transition 응답을 재정의

template< class FSM, class Event >

void no_transition( Event const& e, FSM&, int state )

{

std::cout << "no_transition from state " << state << " on evert" << typeid(e).name() << std::endl;

}

};


// back-end 를 뽑아내자

typedef msm::back::state_machine< player_ > player_state_machine;


static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused", "AllOK", "ErrorMode" };

void pstate(player_state_machine const& p)

{

for( unsigned int i = 0; i < player_state_machine::nr_regions::value; ++i )

{

std::cout << " -> " << state_names[ p.current_state()[i] ] << std::endl;

}

}


void msm_test()

{

player_state_machine psm;


// 고수준 상태 머신은 시작이 필요하단다. 이것은 on_entry와 상태 머신의 시작의 mark를 호출 할것이다.

psm.start();


std::cout << std::endl;


// 지연된 이벤트 테스트

// 무조건 cd_detected 이후에 처리되야 하는 empty 와 open안에서 지연됨

psm.process_event( play() );


// 플래그 테스트

std::cout << "CDLoaded active:" << std::boolalpha << psm.is_flag_active< CDLoaded >() << std::endl; // -> 실패 ( 여전히 CD가 없다. )

// 열기로 가자, empty의 on_exit 가 호출되고, 그리고 행동, 그리고 open의 on_entry가 호출된다.

psm.process_event( open_close() ); pstate( psm );

psm.process_event( open_close() ); pstate( psm );

psm.process_event( cd_detected( "louie, louie" ) );


//psm.process_event( cd_detected( "louie, louie" ) );

//psm.process_event( play() );


// 이 시점에, play는 active( 지연되었던 )??

std::cout << "PlayingPaused active:" << std::boolalpha << psm.is_flag_active< PlayingPaused >() << std::endl;

std::cout << "FirstSong active:" << std::boolalpha << psm.is_flag_active< FirstSongPlaying >() << std::endl;


psm.process_event( NextSong() ); pstate( psm );



std::cout << std::endl;


psm.stop();


printf( "end msm test... (press enter)\n" );

getchar();

}




'Boost' 카테고리의 다른 글

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




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


#include <iostream>

// back

#include <boost/msm/back/state_machine.hpp>

// front

#include <boost/msm/front/state_machine_def.hpp>


namespace msm = boost::msm;

namespace mpl = boost::mpl;


namespace

{

// 이벤트들

struct play {};

struct end_pause {};

struct stop {};

struct pause {};

struct open_close {};

struct NextSong {};

struct PreviousSong {};


// 디스크 타입

// 약간의 데이터를 전송하는 복잡한 이벤트 타입

enum DiskTypeEnum

{

DISK_CD = 0,

DISK_DVD = 1,

}; 


struct cd_detected

{

cd_detected( std::string _name, DiskTypeEnum _diskType )

: name_( _name )

, diskType_ ( _diskType )

{


}


std::string name_;

DiskTypeEnum diskType_;

};


// front-end : FSM 구조체를 정의

struct player_ : public msm::front::state_machine_def< player_ >

{

// 입장

template< class Event, class FSM >

void on_entry( Event const&, FSM& ) { std::cout << "entering: Player" << std::endl; }

// 퇴장

template< class Event, class FSM >

void on_exit( Event const&, FSM& ) { std::cout << "leaving: Player" << std::endl; }


// the list of fsm states

struct Empty : public msm::front::state<>

{

template < class Event, class FSM >

void on_entry( Event const&, FSM& ) { std::cout << "entering: Empty" << std::endl; }


template< class Event, class FSM >

void on_exit( Event const&, FSM& ) { std::cout << "leaving: Empty" << std::endl; }

};

struct Open : public msm::front::state<>

{

template < class Event, class FSM >

void on_entry( Event const&, FSM& ) { std::cout << "entering: Open" << std::endl; }


template< class Event, class FSM >

void on_exit( Event const&, FSM& ) { std::cout << "leaving: Open" << std::endl; }

};

struct Stopped : public msm::front::state<msm::front::default_base_state,msm::front::sm_ptr>

{

template < class Event, class FSM >

void on_entry( Event const&, FSM& ) { std::cout << "entering: Stopped" << std::endl; }


template< class Event, class FSM >

void on_exit( Event const&, FSM& ) { std::cout << "leaving: Stopped" << std::endl; }


void set_sm_ptr( player_* pl )

{

m_player = pl;

}

player_* m_player;

};

struct Paused : public msm::front::state<>

{

template < class Event, class FSM >

void on_entry( Event const&, FSM& ) { std::cout << "entering: Paused" << std::endl; }


template< class Event, class FSM >

void on_exit( Event const&, FSM& ) { std::cout << "leaving: Paused" << std::endl; }

};


struct Playing_ : public msm::front::state_machine_def<Playing_>

{

template < class Event, class FSM >

void on_entry( Event const&, FSM& ) { std::cout << "entering: Playing" << std::endl; }

template< class Event, class FSM >

void on_exit( Event const&, FSM& ) { std::cout << "leaving: Playing" << std::endl; }


struct Song1 : public msm::front::state<>

{

template< class Event, class FSM >

void on_entry( Event const&, FSM& ) { std::cout << "starting: First Song" << std::endl; }

template< class Event, class FSM >

void on_exit( Event const&, FSM& ) { std::cout << "finishing: First Song" << std::endl; }

};

struct Song2 : public msm::front::state<>

{

template< class Event, class FSM >

void on_entry( Event const&, FSM& ) { std::cout << "starting: Second Song" << std::endl; }

template< class Event, class FSM >

void on_exit( Event const&, FSM& ) { std::cout << "finishing: Second Song" << std::endl; }

};

struct Song3 : public msm::front::state<>

{

template< class Event, class FSM >

void on_entry( Event const&, FSM& ) { std::cout << "starting: Third Song" << std::endl; }

template< class Event, class FSM >

void on_exit( Event const&, FSM& ) { std::cout << "finishing: Third Song" << std::endl; }

};


typedef Song1 initial_state;




// 전이 함수들

void start_next_song( NextSong const& ) { std::cout << "Playing::start_next_song" << std::endl; }

void start_prev_song( PreviousSong const& ) { std::cout << "Playing::start_prev_song" << std::endl; }


// 가드 조건

typedef Playing_ pl;

// 플레잉의 전이 테이블

struct transition_table : mpl::vector4

<

a_row < Song1, NextSong, Song2, &pl::start_next_song >,

a_row < Song2, PreviousSong, Song1, &pl::start_prev_song >,

a_row < Song2, NextSong, Song3, &pl::start_next_song >,

a_row < Song3, PreviousSong, Song2, &pl::start_prev_song >

>{};


// 없는 전이 상태

template< class FSM, class Event >

void no_transition( Event const& e, FSM&, int state)

{

std::cout << "no transition state" << state << " on event" << typeid(e).name() << std::endl;

}

};


// back-end

typedef msm::back::state_machine<Playing_> Playing;


// 플레이어 스테이트 머신의 초기 상태, 반드시 정의되어야 한다.

typedef Empty initial_state;


// 전의되는 행동들.

void start_playback( play const& ) { std::cout << "player::start_playback" << std::endl; }

void open_drawer( open_close const& ) { std::cout << "player::open_drawer" << std::endl; }

void close_drawer( open_close const& ) { std::cout << "player::close_drawer" << std::endl; }

void store_cd_info( cd_detected const& ) { std::cout << "player::store_cd_info" << std::endl; }

void stop_playback( stop const& ) { std::cout << "player::stop_playback" << std::endl; }

void pause_playback( pause const& ) { std::cout << "player::pause_playback" << std::endl; }

void resume_playback( end_pause const& ) { std::cout << "player::resume_playback" << std::endl; }

void stop_and_open( open_close const& ) { std::cout << "player::stop_and_open" << std::endl; }

void stopped_again( stop const& ) { std::cout << "player::stopped_again" << std::endl; }


// 가드 조건? 실행 불가 조건을 얘기하는듯

bool good_disk_format( cd_detected const& evt )

{

// 방어 조건 테스트, cd만 가능, dvd 안됨

if( evt.diskType_ != DISK_CD )

{

std::cout << "wrong disk, sorry" << std::endl;

return false;

}

return true;

}


bool auto_start(cd_detected const& )

{

return false;

}


typedef player_ p; // 전의 테이블을 깔끔하게 만들기 위해서

struct transition_table : mpl::vector< 

// Start Event Next Action Guard

// +--------------+------------------+----------------+------------------------+------------------------+

// 정지 상태

a_row < Stopped, play, Playing, &p::start_playback >,

a_row < Stopped, open_close, Open, &p::open_drawer >,

_row < Stopped, stop, Stopped >,

// 열림 상태

a_row < Open, open_close, Empty, &p::close_drawer >,

// 빈 상태

a_row < Empty, open_close, Open, &p::open_drawer >,

 row < Empty, cd_detected, Stopped, &p::store_cd_info, &p::good_disk_format >,

 row < Empty, cd_detected, Playing, &p::store_cd_info, &p::auto_start >,

// 재생 상태

a_row < Playing, stop, Stopped, &p::stop_playback >,

a_row < Playing, pause, Paused, &p::pause_playback >,

a_row < Playing, open_close, Open, &p::stop_and_open >,

// 일지 정시 상태

a_row < Paused, end_pause, Playing, &p::resume_playback >,

a_row < Paused, stop, Stopped, &p::stop_playback >,

a_row < Paused, open_close, Open, &p::stop_and_open >


>{};

// 없는 전이 상태

template< class FSM, class Event >

void no_transition( Event const& e, FSM& , int state)

{

std::cout << "no transition state" << state << " on event" << typeid(e).name() << std::endl;

}


// row   : 5개의 매개변수를 가진다. 시작 상태, 이벤트, 목표 상태, 행동( 상태 전의가 성공했을때 호출 함수) 그리고 방어( 상태 전의가 가능한지 확인 함수)

// a_row : a는 행동을 뜻하며, 방어를 빼고 액션만 허용

// g_row : g는 방어를 뜻하며, 액션을 빼고 방어만 허용

// _row  : 행동과 방어를 빼고 정의

};


// pick a back-end

typedef msm::back::state_machine<player_> player;


static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };

void pstate(player const& p)

{

std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;

}


void MSM_TEST()

{

player p;


p.start();


p.process_event( open_close() ); pstate(p);

p.process_event( open_close() ); pstate(p);


p.process_event(cd_detected("louie, louie",DISK_DVD)); pstate(p);

p.process_event(cd_detected("louie, louie",DISK_CD)); pstate(p);

p.process_event(play()); pstate(p);


p.process_event(NextSong()); pstate(p);

p.process_event(NextSong()); pstate(p);

p.process_event(PreviousSong()); pstate(p);


p.process_event(pause()); pstate(p);


p.process_event(end_pause()); pstate(p);

p.process_event(pause()); pstate(p);

p.process_event(stop()); pstate(p);

p.process_event(stop()); pstate(p);


p.process_event(play()); pstate(p);


std::cout<< "stop fsm" << std::endl;

p.stop();


std::cout<< "restart fsm" << std::endl;

p.start();


getchar();


}


}

'Boost' 카테고리의 다른 글

Boost MPL 샘플  (0) 2016.01.29
Boost Meta State Machine 테스트 2  (0) 2016.01.29
Boost lock-free Queue 성능 테스트  (0) 2016.01.29
Boost Fusion 샘플  (0) 2016.01.29
Boost Function 샘플  (0) 2016.01.29
      Boost  |  2016. 1. 29. 17:57




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


#pragma once


#include <Windows.h>

#include <boost/lockfree/queue.hpp>

#include <boost/lockfree/spsc_queue.hpp>

#include <boost/pool/pool_alloc.hpp>

#include <boost/pool/object_pool.hpp>

#include <boost/lockfree/policies.hpp>

#include <boost/thread.hpp>

#include <boost/timer.hpp>

#include <boost/progress.hpp>


#pragma pack(push,4)


#define PACKET_TOTAL_SIZE 2048

#define PACKET_EOL_LENGTH 10

#define PACKET_MAX_BUFFER 2010

#define PACKET_HDR_SIZE 28//sizeof( UINT64 )


class CPacket

{


public:


union

{

// Restrict: ACK (Server to Client)

struct

{

UCHAR m_ucOwner;

UCHAR m_ucErr;

};

// Restrict: REQ (Client to Server)

USHORT m_usSerial; // Security: Record & Replay

};


USHORT m_usCmd; // internal command protocol

USHORT m_usPacketID; // packet id

USHORT m_usSize; // Stream data size (+PACKETHDR)


INT m_nHostID; //  Host ID

DWORD64 m_dw64DBID; // DB ID


DWORD m_dwPacketOption; // packet option

DWORD m_dwDataCRC; // data crc


// EOL 사이즈를 포함한 크기

BYTE m_lpData [ 2020 ];


public:

CPacket()

{

setEmpty();

}


CPacket( const CPacket& _Right )

{

this->m_nHostID = _Right.m_nHostID;

//memcpy( this, _Right.segment(), _Right.size() );

memcpy( this->m_lpData, _Right.m_lpData, sizeof( BYTE ) * 2020 );

}


//// 튜플 대입 연산자 선언

//CPacket& operator=( const CPacket& _Right ) _THROW0()

//{

// memcpy( this->m_lpData, _Right.m_lpData, sizeof( BYTE ) * 2020 );


// return (*this);

//}


/*inline

VOID copy_of ( CPacket& _Right )

{ memcpy( this, _Right, _Right.size() ); }*/


/*~CPacket()

{


}*/

//BYTE* segment () const { return reinterpret_cast<BYTE*>(this); }


VOID CPacket::setEmpty()

{

ZeroMemory( this, PACKET_TOTAL_SIZE );


m_usSize = PACKET_TOTAL_SIZE;

}


// 스트림 총 크기

//USHORT& size () const { return m_usSize; }


};


#define CAPACITY_MAX 50000



//

// que 1

// 

typedef boost::fast_pool_allocator< CPacket, boost::default_user_allocator_new_delete, boost::details::pool::null_mutex, 32, 0 > fast_pool_alloc_null_mutex;

fast_pool_alloc_null_mutex alloc1;

boost::lockfree::queue< CPacket, boost::lockfree::capacity<10000>, boost::lockfree::allocator< fast_pool_alloc_null_mutex > > que1( alloc1 );


//

// que 2

// 

typedef boost::fast_pool_allocator< CPacket > fast_pool_alloc;

fast_pool_alloc alloc2;

boost::lockfree::queue< CPacket, boost::lockfree::capacity<10000>, boost::lockfree::allocator< fast_pool_alloc > > que2( alloc2 );


//

// que 3

// 

boost::lockfree::spsc_queue< CPacket, boost::lockfree::capacity<10000> > que3;


//

// que 4

// 

//boost::lockfree::queue< CPacket > que4;



int sum1 = 0;

int sum2 = 0;

int sum3 = 0;


void produce()

{

int i = 0;

for( ; i <= CAPACITY_MAX; ++i )

{

CPacket p;

p.m_nHostID = i;

//que1.bounded_push( p );

while( !que1.bounded_push( p ) );

}

}


void consume()

{

int i = 0;

for( ; i <= CAPACITY_MAX; )

{

CPacket p;

while( que1.pop(p))

{

++i;

sum1 += p.m_nHostID;

}

}

}


void produce2()

{

int i = 0;

for( ; i <= CAPACITY_MAX; ++i )

{

CPacket p;

p.m_nHostID = i;

while( !que2.bounded_push( p ) );

}

}


void consume2()

{

int i = 0;

for( ; i <= CAPACITY_MAX; )

{

CPacket p;

while( que2.pop(p))

{

++i;

sum2 += p.m_nHostID;

}

}

}


void produce3()

{

int i = 0;

for( ; i <= CAPACITY_MAX; ++i )

{

CPacket p;

p.m_nHostID = i;

while( !que3.push( p ) );

}

}


void consume3()

{

int i = 0;

for( ; i <= CAPACITY_MAX; )

{

CPacket p;

while( que3.pop(p))

{

++i;

sum3 += p.m_nHostID;

}

}

}


void lock_free_queue_test()

{

{

// 프로그레스 타이머

boost::progress_timer progress_t;


sum1 = 0;


boost::thread t1(produce);

boost::thread t2(consume);


t1.join();

t2.join();


//consume();


std::cout << "boost::lockfree::queue< CPacket, boost::lockfree::capacity<60000>, boost::lockfree::allocator< fast_pool_alloc_null_mutex > >" << std::endl;


std::cout << sum1 << "\n";

}


Sleep(10);


{

// 프로그레스 타이머

boost::progress_timer progress_t;


sum1 = 0;


boost::thread t1(produce2);

boost::thread t2(consume2);


t1.join();

t2.join();


//consume2();


std::cout << "boost::lockfree::queue< CPacket, boost::lockfree::capacity<60000>, boost::lockfree::allocator< fast_pool_alloc > >" << std::endl;


std::cout << sum2 << "\n";

}


Sleep(10);


{

// 프로그레스 타이머

boost::progress_timer progress_t;


sum1 = 0;


boost::thread t1(produce3);

boost::thread t2(consume3);


t1.join();

t2.join();


//consume3();


std::cout << "boost::lockfree::queue< CPacket, boost::lockfree::capacity<60000> >" << std::endl;


std::cout << sum3 << "\n";

}




//typedef boost::lockfree::spsc_queue< ENK::CPacket, boost::lockfree::capacity<65535>, boost::lockfree::allocator >

}



'Boost' 카테고리의 다른 글

Boost Meta State Machine 테스트 2  (0) 2016.01.29
Boost Meta State Machine 테스트  (0) 2016.01.29
Boost Fusion 샘플  (0) 2016.01.29
Boost Function 샘플  (0) 2016.01.29
Boost Format 샘플  (0) 2016.01.29
      Boost  |  2016. 1. 29. 17:55




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


#include <boost/fusion/container.hpp>

#include <boost/fusion/sequence.hpp>

#include <boost/mpl/int.hpp>

#include <string>

#include <iostream>


namespace fusion = boost::fusion;

namespace mpl = boost::mpl;


void fusion_test()

{

typedef fusion::vector< int, std::string, bool ,double > vector_type;

vector_type v(10, "boost", true, 3.14 );



std::cout << fusion::at< mpl::int_<1>>(v) << std::endl;

}

'Boost' 카테고리의 다른 글

Boost Meta State Machine 테스트  (0) 2016.01.29
Boost lock-free Queue 성능 테스트  (0) 2016.01.29
Boost Function 샘플  (0) 2016.01.29
Boost Format 샘플  (0) 2016.01.29
Boost Foreach 샘플  (0) 2016.01.29
      Boost  |  2016. 1. 29. 17:53




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


#include <iostream>

#include <boost/function.hpp>

#include <vector>

#include <algorithm>


#include <boost/assign.hpp>

#include <boost/bind.hpp>


//

// 부스트 function 테스트

//

// assign도 같이 사용합니다.



// 

// 같은 매개 변수를 같는 함수 2

int someFunction1(  const char* )

{

return 1;

}


std::size_t someFunction2( const char* )

{

return 2;

}


//

// 일반 함수 일때 Function 테스트

void Function_With_Func_Test()

{

boost::function< int ( const char* ) > fp = someFunction1;

std::cout << fp("1234") << std::endl;


fp = someFunction2;

std::cout << fp("1234") << std::endl;

}


//

// 함수 객체 2

struct someFunctionObj1

{

int operator()( const char* ) const { return 1; }

};


struct someFunctionObj2

{

int operator()( const char* ) const { return 2; }

};


//

// 함수 객체 operator 일때 테스트

void Function_With_Operator_Test()

{

someFunctionObj1 func1;

someFunctionObj2 func2;


boost::function< int( const char*  ) > fp = func1;

std::cout << fp("1234") << std::endl;


fp = func2;

std::cout << fp("1234") << std::endl;


fp = someFunction2;

std::cout << fp("1234") << std::endl;


// 기존 설정된 함수를 해제할떄는 0을 대입한다.

// 이후 function을 사용하면 boost::bad_function_call 발생

fp = 0;


try

{

std::cout << fp("1234") << std::endl;

}

catch (boost::bad_function_call& e)

{

std::cout << e.what() << std::endl;

}

}


struct world

{

int hello( const char* name )

{

std::cout<< "hello " << name << std::endl;


return 1;

}

};




//

// 멤버 함수를 설정하였을 경우 테스트

void Function_With_Member_Func_Test()

{

world w;

boost::function< int ( world*, const char* ) > fp = &world::hello;


fp( &w, "hong sung ki" );

}


//

//

struct Man

{

std::string name;

int say( const char* text )

{

std::cout<< "my name is " << name << std::endl;

std::cout<< "i need " << text << std::endl;


return 1;

}

};


struct Woman

{

std::string name;

int say( const char* text )

{

std::cout<< "my name is " << name << std::endl;

std::cout<< "i want " << text << std::endl;


return 2;

}

};


//

// function, bind 를 모두 배웠을 경우 컴비네이션으로 사용 가능한 방법

// 사실 이걸 사용하기위해 위의 예제들을 공부함

void Function_With_Bind_Test()

{

Man m1, m2;

m1.name = "skhong";

m2.name = "okidoki";


Woman w1, w2;

w1.name = "taehee";


// function 에 멤버 함수를 bind 해서 대입

boost::function<  int ( const char* ) > fp = boost::bind( &Man::say, &m1, _1 );

std::cout<< fp("car") << std::endl;


// 같은 클래스의 다른 인스턴스를 대입 해도 가능

fp = boost::bind( &Man::say, &m2, _1 );

std::cout<< fp("girl") << std::endl;


// 다른 클래스의 멤버 함수지만 같은 시그니쳐를 가지고 있으므로

// bind를 통해서 한번 wrap 후 function에 대입 가능하다.

fp = boost::bind( &Woman::say, &w1, _1 );

std::cout<< fp("beuty") << std::endl;

}

'Boost' 카테고리의 다른 글

Boost lock-free Queue 성능 테스트  (0) 2016.01.29
Boost Fusion 샘플  (0) 2016.01.29
Boost Format 샘플  (0) 2016.01.29
Boost Foreach 샘플  (0) 2016.01.29
Boost Bind 샘플  (0) 2016.01.29
      Boost  |  2016. 1. 29. 17:52




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


#include <iostream>

#include <boost/format.hpp>


//

// iostream 형태의 파일 포맷을 극뽁!

// 형식, 인자의 개수에 관해서 안전

// 형식이 안전한 c++ 스타일의 printf와 비슷하다고 한다.


void Format_Test()

{

// 순서대로 표기

std::cout << boost::format("%1% %2%" ) % "hello" % 100 << std::endl;

// 역순으로 표기

std::cout << boost::format("%2% %1%" ) % "hello" % 100 << std::endl;


// %05d : 0포함 5자리수의 정수

// %x : 16진수 표기

// %f : float 형

// %% : % 표기

std::cout << boost::format("%05d %x %f %%") % 200 % 255 % 3.33f << std::endl;


// 변수에 받는것은 어떻게 하는것인지 찾아봐야 한다.

// %1% 과 %05d 는 섞어쓸수  없나보다.

// 에러가 남

// 정확하게 쓰려면 %1$05d 로 사용해야한다.

std::string txt = boost::io::str( boost::format("%1$05d %2$x %3$f") % 200 % 255 % 3.33f );

std::cout << " 변수 저장 : " << txt <<std::endl;

}



'Boost' 카테고리의 다른 글

Boost Fusion 샘플  (0) 2016.01.29
Boost Function 샘플  (0) 2016.01.29
Boost Foreach 샘플  (0) 2016.01.29
Boost Bind 샘플  (0) 2016.01.29
Boost Assign 샘플  (0) 2016.01.29
      Boost  |  2016. 1. 29. 16:58




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


#include <iostream>

#include <algorithm>

#include <wtypes.h>

#include <string>

#include <vector>

#include <map>

#include <stack>


// 벡터에 boost assign 을 사용한다.

// 더이상 자세한 설명은 생략한다.

#include <boost/assign/std/vector.hpp>


#include <boost/assign/list_inserter.hpp>


#include <boost/tuple/tuple.hpp>

#include <boost/tuple/tuple_io.hpp>

#include <boost/foreach.hpp>


///

// boost_foreach 를 통해서 컨테이너 루프를 돌려보자.

// std::foreach 를 통해서 컨테이너 루프를 할경우 functor를 만들어야 하는데

// 귀찮음을 덜어줌


// assign 사용하기 위해서

using namespace boost::assign;



// Vector, boost_foreach 테스트

void Foreach_with_vector_test()

{

std::vector< int > v1;

v1.push_back( 100 );

v1.push_back( 200 );

v1.push_back( 300 );

v1.push_back( 400 );

v1.push_back( 500 );


BOOST_FOREACH( int& iter, v1 )

{

std::cout << "벡터 값 : " << iter << std::endl;

}


// boost assign 추가

std::vector< int > v2;// = { 100, 200, 300 };


// assign을 이용해서 대입

v2 += 1,2,3,4,5,6,7,8,9;

BOOST_FOREACH( int& iter, v2 )

{

std::cout << "벡터 값 : " << iter << std::endl;

}

}


void Foreach_with_map_test()

{

std::map< std::string, int > m1;


// 인서트

insert( m1 )

( "1월", 31 )( "2월", 28 )

( "3월", 31 )( "4월", 31 )

( "5월", 31 )( "6월", 31 )

( "7월", 31 )( "8월", 31 )

( "9월", 31 )( "10월", 31 )

( "11월", 31 )( "12월", 31 );


std::string key;

int value;

BOOST_FOREACH( boost::tie( key, value ), m1 )

{

std::cout << "Key : " << key << "Value : " << value << std::endl;

}


// 2번째 방법

typedef std::pair< std::string, int > pair_t;

BOOST_FOREACH( pair_t p, m1 )

{

std::cout << "Key : " << p.first << "Value : " << p.second << std::endl;

}


// 이건 안됨 에러임 매크로라서 , 를 인식해서 에러남

/*BOOST_FOREACH( std::pair< std::string, int > p, m1 )

{

std::cout << "Key : " << p.first << "Value : " << p.second << std::endl;

}*/

}


'Boost' 카테고리의 다른 글

Boost Function 샘플  (0) 2016.01.29
Boost Format 샘플  (0) 2016.01.29
Boost Bind 샘플  (0) 2016.01.29
Boost Assign 샘플  (0) 2016.01.29
Boost Array 샘플  (0) 2016.01.29
      Boost  |  2016. 1. 29. 16:58




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


#include <iostream>

#include <boost/function.hpp>

#include <vector>

#include <algorithm>


#include <boost/assign.hpp>

#include <boost/bind.hpp>


//

// boost::bind

//

// assign도 같이 사용합니다.

// 기존 bind1st, bind2st 등 stl 에서 지원해주던것을

// 좀더 간편하게 확장 버젼으로 사용 가능함

// 멤버 함수들도 손쉽게 바인드 가능

// 함수 매개변수 형식만 맞춰주면

// 어떤 클래스의 어떠한 멤버 함수들이라도 바인드 가능하다는

// 장점이 있어요!


using namespace boost::assign;


void print( int i )

{

std::cout<< i << std::endl;

}


void add( int i, int j )

{

std::cout<<i+j<<std::endl;

}


bool compare( int i , int j )

{

return i > j;

}


void Bind_Test()

{

// assign을 이용한 초기화

vector< int > v = list_of(1)(2)(3)(4).to_container( v );

std::for_each( v.begin(), v.end(), print );


// assign을 이용한 초기화2

vector< int > v2;

v2 += 1,2,3,4,5,6,7,8,9,10;


// foreach 를 통해서 이항 함수를 호출하고 싶을때

// 기존에는 functor를 생성하고 

// std::binary_function<int,int,void> 형태로 만들어야 한다.

// 하지만 boost 를 이용하면 간단하게 아래와 같은 형식으로 사용 가능하다.

std::for_each( v2.begin(), v2.end(), boost::bind( add, 10, _1 ) );

}


void Bind_Test2()

{

std::vector< int > v;

v += 4,1,5,3,7,2,8;


// 내림 차순 정렬

std::cout << "내림차순 정렬" << std::endl;

std::sort( v.begin(), v.end(), boost::bind( compare, _1, _2 ) );

std::for_each( v.begin(), v.end(), print );


// 오름 차순 정렬

std::cout << "오름차순 정렬" << std::endl;


// 내림 차순 정렬에서 플레이스홀더 _1, _2 만 역으로 변경해주면

// 정렬 순서가 바뀌게 된다.

std::sort( v.begin(), v.end(), boost::bind( compare, _2, _1 ) );

std::for_each( v.begin(), v.end(), print );

}


// 멤버 함수 바인딩


class CMyTest

{

private:


std::vector< int > m_v;


public:

CMyTest()

{

m_v += 4,1,5,3,7,2,8;

}


void print( int i )

{

std::cout << i << std::endl;

}


bool compaire( int i, int j )

{

return i < j;

}

};


void Bind_Call_MemberFunc_Test()

{

CMyTest myTest;


boost::shared_ptr< CMyTest > spMyTest( new CMyTest() );

boost::bind( &CMyTest::print, boost::ref( myTest ), _1 )( 1 ); // myTest.print( 1 )

boost::bind( &CMyTest::print, &myTest, _1 )( 1 ); // (&myTest)->print( 1 )

boost::bind( &CMyTest::print, myTest, _1 )( 1 ); // (myTest의 복사본).print( 1 )

boost::bind( &CMyTest::print, spMyTest, _1 )( 1 ); // (spMyTest의 복사본)->print( 1 )



//std::sort(  )

}


class CButton

{

private:


boost::function<void()> m_onClick;


public:


CButton( boost::function<void()> onClick )

{

m_onClick =  onClick;

}


void doClick()

{

m_onClick();

}

};


class CPlayer

{

public:


void play()

{

std::cout<<"Do Play"<<std::endl;

}

void stop()

{

std::cout<<"Do Stop"<<std::endl;

}

};



// function 과 함께 bind를 사용하는 방법

// 같이 사용할 경우 멤버의 함수를 변수처럼 저장한 후 사용 가능하다.

void Bind_With_Function_Test()

{

CPlayer thePlayer;

CButton playBtn( boost::bind( &CPlayer::play, &thePlayer ) );

CButton stopBtn( boost::bind( &CPlayer::stop, &thePlayer ) );


playBtn.doClick();

stopBtn.doClick();

}

'Boost' 카테고리의 다른 글

Boost Format 샘플  (0) 2016.01.29
Boost Foreach 샘플  (0) 2016.01.29
Boost Assign 샘플  (0) 2016.01.29
Boost Array 샘플  (0) 2016.01.29
Boost Any 샘플  (0) 2016.01.29
      Boost  |  2016. 1. 29. 16:55




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


#include <iostream>

#include <algorithm>

#include <wtypes.h>

#include <string>

#include <vector>

#include <map>

#include <stack>

#include <set>

#include <queue>


#include <boost/array.hpp>


// 벡터에 boost::assign 을 사용한다.

// 더이상 자세한 설명은 생략한다.

#include <boost/assign.hpp>


#include <boost/tuple/tuple.hpp>

#include <boost/tuple/tuple_io.hpp>

#include <boost/foreach.hpp>


using namespace std;

using namespace boost;

using namespace boost::assign;


//

// stl container 초기화 또는 값을 대입하였을 경우

// 아주 아주 편리하게 도와주는 녀석


void Assign_Test()

{


vector< int > v = list_of(1)(2)(3)(4).to_container( v );

list< int > l = list_of(1)(2)(3)(4).to_container( l );

set< int > s = list_of(1)(2)(3)(4).to_container( s );

map< int,int > m = map_list_of(1,2)(2,3)(3,4)(4,5).to_container( m );


stack< int > st = list_of(1)(2)(3)(4).to_adapter( st );

queue< int > q = list_of(1)(2)(3)(4).to_adapter( q );


array< int, 4 > a = list_of(1)(2)(3)(4).to_array( a );


// v 출력

BOOST_FOREACH( int& iter, v )

{

std::cout << "벡터 값 : " << iter << std::endl;

}


// v 출력

BOOST_FOREACH( int& iter, l )

{

std::cout << "리스트 값 : " << iter << std::endl;

}


// v 출력

BOOST_FOREACH( int& iter, s )

{

std::cout << "Set 값 : " << iter << std::endl;

}


int key;

int value;

BOOST_FOREACH( boost::tie( key, value ), m )

{

std::cout << "Key : " << key << "Value : " << value << std::endl;

}


// v 출력

/*BOOST_FOREACH( int& iter, st )

{

std::cout << "Stack 값 : " << iter << std::endl;

}


// v 출력

BOOST_FOREACH( int& iter, q )

{

std::cout << "Queue 값 : " << iter << std::endl;

}*/


// v 출력

BOOST_FOREACH( int& iter, a )

{

std::cout << "Array 값 : " << iter << std::endl;

}

}

'Boost' 카테고리의 다른 글

Boost Foreach 샘플  (0) 2016.01.29
Boost Bind 샘플  (0) 2016.01.29
Boost Array 샘플  (0) 2016.01.29
Boost Any 샘플  (0) 2016.01.29
boost::mpl 라이브러리를 이용한 Packet의 자동 생성 및 처리 방법  (0) 2014.05.26
      Boost  |  2016. 1. 29. 16:54



홍쿤사마's Blog is powered by Daum