Bertini 2 - C++ Core
Software for Numerical Algebraic Geometry
Loading...
Searching...
No Matches
visitable.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//visitable.hpp is free software: you can redistribute it and/or modify
4//it under the terms of the GNU General Public License as published by
5//the Free Software Foundation, either version 3 of the License, or
6//(at your option) any later version.
7//
8//visitable.hpp is distributed in the hope that it will be useful,
9//but WITHOUT ANY WARRANTY; without even the implied warranty of
10//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11//GNU General Public License for more details.
12//
13//You should have received a copy of the GNU General Public License
14//along with visitable.hpp. If not, see <http://www.gnu.org/licenses/>.
15//
16// Copyright(C) 2015 - 2021 by Bertini2 Development Team
17//
18// See <http://www.gnu.org/licenses/> for a copy of the license,
19// as well as COPYING. Bertini2 is provided with permitted
20// additional terms in the b2/licenses/ directory.
21
22// individual authors of this file include:
23// silviana amethyst, university of wisconsin-eau claire
24//
25
31
32#ifndef BERTINI_DETAIL_VISITABLE_HPP
33#define BERTINI_DETAIL_VISITABLE_HPP
34
37
38namespace bertini{
39
40 namespace policy{
41
49 template<class VisitedT, typename RetT>
51 {
52 static RetT OnUnknownVisitor(VisitedT&a, VisitorBase&) // VisitorBase is inherited from using CRTP -- it's not a template parameter to this function, so its typeid name is useless.
53 {
54 std::cout << "unknown visitor: " << a << " of type " << typeid(VisitedT).name() << ". Make sure you've added it in all three places! two in the class definition (type inheritance listing as visiting, and virtual function declaration), and one in cpp source (function definition)." << std::endl;
55 return VisitedT();
56 }
57 };
58
59 template<class VisitedT, typename RetT>
60 struct RaiseExceptionWithTypeNamesInMessage
61 {
62 static RetT OnUnknownVisitor(VisitedT&a, VisitorBase&)
63 {
64 std::stringstream err_msg;
65 err_msg << "unknown visitor: " << a << " of type " << typeid(VisitedT).name() << ". Make sure you've added it in all three places! two in the class definition (type inheritance listing as visiting, and virtual function declaration), and one in cpp source (function definition)." << std::endl;
66 throw std::runtime_error(err_msg.str());
67 }
68 };
72 template<class VisitedT, typename RetT>
73 using DefaultCatchAll = RaiseExceptionWithTypeNamesInMessage<VisitedT, RetT>;
74 } // namespace policy
75
76
77
78
86 template< typename RetT = void, template<class,class> class CatchAll = policy::DefaultCatchAll>
88 {
89 public:
90 typedef RetT VisitReturnType;
91 virtual ~VisitableBase() = default;
92 virtual VisitReturnType Accept(VisitorBase&) = 0; // the implementation will either be provided by a macro, or by hand, for each class which is visitable.
93
94 protected:
95
106 template<typename T>
107 static
108 VisitReturnType AcceptBase(T& visited, VisitorBase& guest)
109 {
110 if (auto p = dynamic_cast<Visitor<T>*>(&guest))
111 return p->Visit(visited);
112 else
113 return CatchAll<T,RetT>::OnUnknownVisitor(visited, guest);
114 }
115 };
116
117
121 #define BERTINI_DEFAULT_VISITABLE() \
122 virtual VisitReturnType Accept(VisitorBase& guest) override \
123 { return AcceptBase(*this, guest); }
124
125} // namespace bertini
126
127
128#endif
129
The base class for visitable types.
Definition visitable.hpp:88
static VisitReturnType AcceptBase(T &visited, VisitorBase &guest)
Abstract method for how to accept a visitor.
Definition visitable.hpp:108
A strawman class for implementing the visitor pattern.
Definition visitor.hpp:46
The first non-trivial visitor class.
Definition visitor.hpp:62
Contains the detail/events base types.
A policy for what to do when a visited type is encoutered by a visitor it doesn't know.
Definition visitable.hpp:51
RaiseExceptionWithTypeNamesInMessage< VisitedT, RetT > DefaultCatchAll
Definition visitable.hpp:73
Contains the visitor base types.