File: VarVisitor.h

package info (click to toggle)
poco 1.14.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 56,460 kB
  • sloc: cpp: 340,542; ansic: 245,601; makefile: 1,742; yacc: 1,005; sh: 698; sql: 312; lex: 282; xml: 128; perl: 29; python: 24
file content (116 lines) | stat: -rw-r--r-- 2,464 bytes parent folder | download
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
//
// VarVisitor.h
//
// Library: Foundation
// Package: Dynamic
// Module:  VarVisitor
//
// Definition of the VarVisitor class.
//
// Copyright (c) 2023, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier:	BSL-1.0
//


#ifndef Foundation_VarVisitor_INCLUDED
#define Foundation_VarVisitor_INCLUDED


#include "Poco/Dynamic/Var.h"
#include <unordered_map>
#include <functional>


namespace Poco {
namespace Details {


#ifndef POCO_DOC


struct TypeInfoHash
{
	inline std::size_t operator()(std::type_info const& t) const { return t.hash_code(); }
};


struct EqualRef
{
	template <typename T>
	bool operator()(std::reference_wrapper<T> a, std::reference_wrapper<T> b) const
	{
		return a.get() == b.get();
	}
};


using TypeInfoRef = std::reference_wrapper<std::type_info const>;
using HandlerCaller = std::function<void(const Poco::Dynamic::Var&)>;


template <typename T>
using HandlerPointer = void (*)(const T&);


template <typename T>
using Handler = std::function<void(const T&)>;


#endif // POCO_DOC


} // Details


namespace Dynamic {


class Foundation_API Visitor
	/// VarVisitor class.
{
	std::unordered_map<Details::TypeInfoRef,
			Details::HandlerCaller,
			Details::TypeInfoHash,
			Details::EqualRef> _handlers;
	
public:
	template <typename T>
	bool addHandler(const Details::Handler<T>& f)
		/// Add handler for specific type T which holds in Var.
		/// This method is more safe, because it saves copy of handler : lambda or std::function.
		/// Returns true if handler was added.
	{
		auto result = _handlers.emplace(std::ref(typeid(T)),
			Details::HandlerCaller([handler = f](const Poco::Dynamic::Var& x)
			{
				handler(x.extract<T>());
			}));
		return result.second;
	}
	
	template <typename T>
	bool addHandler(Details::HandlerPointer<T> f)
		/// Add handler for specific type T which holds in Var.
		/// This method is less safe, because it saves only copy of function pointer.
		/// Returns true if handler was added.
	{
		auto result = _handlers.emplace(std::ref(typeid(T)),
			Details::HandlerCaller([handlerPointer = f](const Poco::Dynamic::Var& x)
			{
				handlerPointer(x.extract<T>());
			}));
		return result.second;
	}
	
	bool visit(const Poco::Dynamic::Var& x) const;
		/// Find handler for held type and if it exists call handler.
		/// Returns true if hanlder was found othrewise returns false.
};


} } // namespace Poco::Dynamic


#endif // Foundation_VarVisitor_INCLUDED