source: rrlib_util/tDoubleDispatcher.h @ 43:0b04f7b6406e

Last change on this file since 43:0b04f7b6406e was 43:0b04f7b6406e, checked in by Tobias Föhst <foehst@…>, 8 years ago

Reformatted with astyle 2.02.1

File size: 5.2 KB
Line 
1//
2// You received this file as part of RRLib
3// Robotics Research Library
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License
9// as published by the Free Software Foundation; either version 2
10// of the License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20//
21//----------------------------------------------------------------------
22/*!\file    tDoubleDispatcher.h
23 *
24 * \author  Tobias Foehst
25 *
26 * \date    2011-03-26
27 *
28 * \brief Contains tDoubleDispatcher
29 *
30 * \b tDoubleDispatcher
31 *
32 */
33//----------------------------------------------------------------------
34#ifndef __rrlib__util__tDoubleDispatcher_h__
35#define __rrlib__util__tDoubleDispatcher_h__
36
37//----------------------------------------------------------------------
38// External includes (system with <>, local with "")
39//----------------------------------------------------------------------
40#include <boost/type.hpp>
41
42//----------------------------------------------------------------------
43// Internal includes with ""
44//----------------------------------------------------------------------
45#include "rrlib/util/tTypeList.h"
46
47//----------------------------------------------------------------------
48// Debugging
49//----------------------------------------------------------------------
50#include <cassert>
51
52//----------------------------------------------------------------------
53// Namespace declaration
54//----------------------------------------------------------------------
55namespace rrlib
56{
57namespace util
58{
59
60//----------------------------------------------------------------------
61// Forward declarations / typedefs / enums
62//----------------------------------------------------------------------
63
64//----------------------------------------------------------------------
65// Class declaration
66//----------------------------------------------------------------------
67//!
68/*!
69 *
70 */
71template <
72typename TExecutor,
73         typename TLeftBase,
74         typename TLeftTypes,
75         bool Tsymmetric = true,
76         typename TRightBase = TLeftBase,
77         typename TRightTypes = TLeftTypes,
78         typename TReturn = void
79         >
80class tDoubleDispatcher
81{
82
83//----------------------------------------------------------------------
84// Public typedefs and methods
85//----------------------------------------------------------------------
86public:
87
88  static TReturn Execute(TLeftBase &left, TRightBase &right)
89  {
90    DispatchLeft(left, right, boost::type<typename TLeftTypes::tUnique::tResult::tDerivedToFront::tResult>());
91  }
92
93//----------------------------------------------------------------------
94// Private fields and methods
95//----------------------------------------------------------------------
96private:
97
98  template <bool Tswap_arguments, typename TLeft, typename TRight>
99  struct tCallTrait
100  {
101    static TReturn Execute(TLeft &left, TRight &right)
102    {
103      return TExecutor::Execute(left, right);
104    }
105  };
106  template <typename TLeft, typename TRight>
107  struct tCallTrait<true, TLeft, TRight>
108  {
109    static TReturn Execute(TLeft &left, TRight &right)
110    {
111      return TExecutor::Execute(right, left);
112    }
113  };
114
115  static TReturn DispatchLeft(TLeftBase &left, TRightBase &right, boost::type<type_list::tEmptyList>)
116  {
117    TExecutor::OnError(left, right);
118  }
119  template <typename TTypes>
120  static TReturn DispatchLeft(TLeftBase &left, TRightBase &right, boost::type<TTypes>)
121  {
122    typedef typename TTypes::tHead tHead;
123    typedef typename TTypes::tTail tTail;
124    if (tHead *left_dispatched = dynamic_cast<tHead *>(&left))
125    {
126      return DispatchRight(*left_dispatched, right, boost::type<typename TRightTypes::tUnique::tResult::tDerivedToFront::tResult>());
127    }
128    DispatchLeft(left, right, boost::type<tTail>());
129  }
130
131  template <typename TLeft>
132  static TReturn DispatchRight(TLeft &left_dispatched, TRightBase &right, boost::type<type_list::tEmptyList>)
133  {
134    TExecutor::OnError(left_dispatched, right);
135  }
136  template <typename TLeft, typename TTypes>
137  static TReturn DispatchRight(TLeft &left_dispatched, TRightBase &right, boost::type<TTypes>)
138  {
139    typedef typename TTypes::tHead tHead;
140    typedef typename TTypes::tTail tTail;
141    if (tHead *right_dispatched = dynamic_cast<tHead *>(&right))
142    {
143      const bool cSWAP_ARGUMENTS = Tsymmetric && type_list::tFind<TRightTypes, tHead>::cINDEX < type_list::tFind<TLeftTypes, TLeft>::cINDEX;
144      return tCallTrait<cSWAP_ARGUMENTS, TLeft, tHead>::Execute(left_dispatched, *right_dispatched);
145    }
146    return DispatchRight(left_dispatched, right, boost::type<tTail>());
147  }
148
149};
150
151//----------------------------------------------------------------------
152// End of namespace declaration
153//----------------------------------------------------------------------
154}
155}
156
157#endif
Note: See TracBrowser for help on using the repository browser.