summaryrefslogtreecommitdiff
path: root/boost/statechart/detail/constructor.hpp
blob: 0cc317af2dd0a3a9a5a478414ca36d71cd8e3302 (plain)
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#ifndef BOOST_STATECHART_DETAIL_CONSTRUCTOR_HPP_INCLUDED
#define BOOST_STATECHART_DETAIL_CONSTRUCTOR_HPP_INCLUDED
//////////////////////////////////////////////////////////////////////////////
// Copyright 2002-2006 Andreas Huber Doenni
// Distributed under the Boost Software License, Version 1.0. (See accompany-
// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//////////////////////////////////////////////////////////////////////////////



#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/advance.hpp>
#include <boost/mpl/find.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/erase.hpp>
#include <boost/mpl/reverse.hpp>
#include <boost/mpl/long.hpp>



namespace boost
{
namespace statechart
{
namespace detail
{



template< class ContextList, class OutermostContextBase >
struct constructor;

//////////////////////////////////////////////////////////////////////////////
template< class ContextList, class OutermostContextBase >
struct outer_constructor
{
  typedef typename mpl::front< ContextList >::type to_construct;
  typedef typename to_construct::context_ptr_type context_ptr_type;
  typedef typename to_construct::inner_context_ptr_type
    inner_context_ptr_type;

  typedef typename to_construct::inner_initial_list inner_initial_list;
  typedef typename mpl::pop_front< ContextList >::type inner_context_list;
  typedef typename mpl::front< inner_context_list >::type::orthogonal_position
    inner_orthogonal_position;
  typedef typename mpl::advance<
    typename mpl::begin< inner_initial_list >::type,
    inner_orthogonal_position >::type to_construct_iter;

  typedef typename mpl::erase<
    inner_initial_list,
    to_construct_iter,
    typename mpl::end< inner_initial_list >::type
  >::type first_inner_initial_list;

  typedef typename mpl::erase<
    inner_initial_list,
    typename mpl::begin< inner_initial_list >::type,
    typename mpl::next< to_construct_iter >::type
  >::type last_inner_initial_list;

  static void construct(
    const context_ptr_type & pContext,
    OutermostContextBase & outermostContextBase )
  {
    const inner_context_ptr_type pInnerContext =
      to_construct::shallow_construct( pContext, outermostContextBase );
    to_construct::template deep_construct_inner<
      first_inner_initial_list >( pInnerContext, outermostContextBase );
    constructor< inner_context_list, OutermostContextBase >::construct(
      pInnerContext, outermostContextBase );
    to_construct::template deep_construct_inner<
      last_inner_initial_list >( pInnerContext, outermostContextBase );
  }
};

//////////////////////////////////////////////////////////////////////////////
template< class ContextList, class OutermostContextBase >
struct inner_constructor
{
  typedef typename mpl::front< ContextList >::type to_construct;
  typedef typename to_construct::context_ptr_type context_ptr_type;

  static void construct(
    const context_ptr_type & pContext,
    OutermostContextBase & outermostContextBase )
  {
    to_construct::deep_construct( pContext, outermostContextBase );
  }
};

//////////////////////////////////////////////////////////////////////////////
template< class ContextList, class OutermostContextBase >
struct constructor_impl : public mpl::eval_if<
  mpl::equal_to< mpl::size< ContextList >, mpl::long_< 1 > >,
  mpl::identity< inner_constructor< ContextList, OutermostContextBase > >,
  mpl::identity< outer_constructor< ContextList, OutermostContextBase > > >
{
};


//////////////////////////////////////////////////////////////////////////////
template< class ContextList, class OutermostContextBase >
struct constructor :
  constructor_impl< ContextList, OutermostContextBase >::type {};

//////////////////////////////////////////////////////////////////////////////
template< class CommonContext, class DestinationState >
struct make_context_list
{
  typedef typename mpl::reverse< typename mpl::push_front<
    typename mpl::erase<
      typename DestinationState::context_type_list,
      typename mpl::find<
        typename DestinationState::context_type_list,
        CommonContext
      >::type,
      typename mpl::end<
        typename DestinationState::context_type_list
      >::type
    >::type,
    DestinationState
  >::type >::type type;
};



} // namespace detail
} // namespace statechart
} // namespace boost



#endif