mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	
						commit
						b5399a7aa0
					
				
							
								
								
									
										128
									
								
								libdevcore/Visitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								libdevcore/Visitor.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,128 @@ | ||||
| /*
 | ||||
| 	This file is part of solidity. | ||||
| 
 | ||||
| 	solidity is free software: you can redistribute it and/or modify | ||||
| 	it under the terms of the GNU General Public License as published by | ||||
| 	the Free Software Foundation, either version 3 of the License, or | ||||
| 	(at your option) any later version. | ||||
| 
 | ||||
| 	solidity is distributed in the hope that it will be useful, | ||||
| 	but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| 	GNU General Public License for more details. | ||||
| 
 | ||||
| 	You should have received a copy of the GNU General Public License | ||||
| 	along with solidity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| */ | ||||
| /**
 | ||||
|  * Visitor templates. | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <functional> | ||||
| #include <boost/variant/static_visitor.hpp> | ||||
| 
 | ||||
| namespace dev | ||||
| { | ||||
| 
 | ||||
| /// Generic visitor used as follows:
 | ||||
| /// boost::apply_visitor(GenericVisitor<Class1, Class2>(
 | ||||
| ///     [](Class1& _c) { _c.f(); },
 | ||||
| ///     [](Class2& _c) { _c.g(); }
 | ||||
| /// ), variant);
 | ||||
| /// This one does not have a fallback and will fail at
 | ||||
| /// compile-time if you do not specify all variants.
 | ||||
| 
 | ||||
| template <class...> | ||||
| struct GenericVisitor{}; | ||||
| 
 | ||||
| template <class Visitable, class... Others> | ||||
| struct GenericVisitor<Visitable, Others...>: public GenericVisitor<Others...> | ||||
| { | ||||
| 	using GenericVisitor<Others...>::operator (); | ||||
| 	explicit GenericVisitor( | ||||
| 		std::function<void(Visitable&)> _visitor, | ||||
| 		std::function<void(Others&)>... _otherVisitors | ||||
| 	): | ||||
| 		GenericVisitor<Others...>(std::move(_otherVisitors)...), | ||||
| 		m_visitor(std::move(_visitor)) | ||||
| 	{} | ||||
| 
 | ||||
| 	void operator()(Visitable& _v) const { m_visitor(_v); } | ||||
| 
 | ||||
| 	std::function<void(Visitable&)> m_visitor; | ||||
| }; | ||||
| template <> | ||||
| struct GenericVisitor<>: public boost::static_visitor<> { | ||||
| 	void operator()() const {} | ||||
| }; | ||||
| 
 | ||||
| /// Generic visitor with fallback:
 | ||||
| /// boost::apply_visitor(GenericFallbackVisitor<Class1, Class2>(
 | ||||
| ///     [](Class1& _c) { _c.f(); },
 | ||||
| ///     [](Class2& _c) { _c.g(); }
 | ||||
| /// ), variant);
 | ||||
| /// This one DOES have a fallback and will NOT fail at
 | ||||
| /// compile-time if you do not specify all variants.
 | ||||
| 
 | ||||
| template <class...> | ||||
| struct GenericFallbackVisitor{}; | ||||
| 
 | ||||
| template <class Visitable, class... Others> | ||||
| struct GenericFallbackVisitor<Visitable, Others...>: public GenericFallbackVisitor<Others...> | ||||
| { | ||||
| 	explicit GenericFallbackVisitor( | ||||
| 		std::function<void(Visitable&)> _visitor, | ||||
| 		std::function<void(Others&)>... _otherVisitors | ||||
| 	): | ||||
| 		GenericFallbackVisitor<Others...>(std::move(_otherVisitors)...), | ||||
| 		m_visitor(std::move(_visitor)) | ||||
| 	{} | ||||
| 
 | ||||
| 	using GenericFallbackVisitor<Others...>::operator (); | ||||
| 	void operator()(Visitable& _v) const { m_visitor(_v); } | ||||
| 
 | ||||
| 	std::function<void(Visitable&)> m_visitor; | ||||
| }; | ||||
| template <> | ||||
| struct GenericFallbackVisitor<>: public boost::static_visitor<> { | ||||
| 	template <class T> | ||||
| 	void operator()(T&) const { } | ||||
| }; | ||||
| 
 | ||||
| /// Generic visitor with fallback that can return a value:
 | ||||
| /// boost::apply_visitor(GenericFallbackReturnsVisitor<ReturnType, Class1, Class2>(
 | ||||
| ///     [](Class1& _c) { return _c.f(); },
 | ||||
| ///     [](Class2& _c) { return _c.g(); }
 | ||||
| /// ), variant);
 | ||||
| /// This one DOES have a fallback and will NOT fail at
 | ||||
| /// compile-time if you do not specify all variants.
 | ||||
| /// The fallback {}-constructs the return value.
 | ||||
| 
 | ||||
| template <class R, class...> | ||||
| struct GenericFallbackReturnsVisitor{}; | ||||
| 
 | ||||
| template <class R, class Visitable, class... Others> | ||||
| struct GenericFallbackReturnsVisitor<R, Visitable, Others...>: public GenericFallbackReturnsVisitor<R, Others...> | ||||
| { | ||||
| 	explicit GenericFallbackReturnsVisitor( | ||||
| 		std::function<R(Visitable&)> _visitor, | ||||
| 		std::function<R(Others&)>... _otherVisitors | ||||
| 	): | ||||
| 		GenericFallbackReturnsVisitor<R, Others...>(std::move(_otherVisitors)...), | ||||
| 		m_visitor(std::move(_visitor)) | ||||
| 	{} | ||||
| 
 | ||||
| 	using GenericFallbackReturnsVisitor<R, Others...>::operator (); | ||||
| 	R operator()(Visitable& _v) const { return m_visitor(_v); } | ||||
| 
 | ||||
| 	std::function<R(Visitable&)> m_visitor; | ||||
| }; | ||||
| template <class R> | ||||
| struct GenericFallbackReturnsVisitor<R>: public boost::static_visitor<R> { | ||||
| 	template <class T> | ||||
| 	R operator()(T&) const { return {}; } | ||||
| }; | ||||
| 
 | ||||
| } | ||||
| @ -22,6 +22,8 @@ | ||||
| 
 | ||||
| #include <libsolidity/interface/Exceptions.h> | ||||
| 
 | ||||
| #include <libdevcore/Visitor.h> | ||||
| 
 | ||||
| #include <boost/variant.hpp> | ||||
| #include <boost/optional.hpp> | ||||
| 
 | ||||
| @ -35,31 +37,6 @@ namespace solidity | ||||
| namespace assembly | ||||
| { | ||||
| 
 | ||||
| template <class...> | ||||
| struct GenericVisitor{}; | ||||
| 
 | ||||
| template <class Visitable, class... Others> | ||||
| struct GenericVisitor<Visitable, Others...>: public GenericVisitor<Others...> | ||||
| { | ||||
| 	using GenericVisitor<Others...>::operator (); | ||||
| 	explicit GenericVisitor( | ||||
| 		std::function<void(Visitable&)> _visitor, | ||||
| 		std::function<void(Others&)>... _otherVisitors | ||||
| 	): | ||||
| 		GenericVisitor<Others...>(_otherVisitors...), | ||||
| 		m_visitor(_visitor) | ||||
| 	{} | ||||
| 
 | ||||
| 	void operator()(Visitable& _v) const { m_visitor(_v); } | ||||
| 
 | ||||
| 	std::function<void(Visitable&)> m_visitor; | ||||
| }; | ||||
| template <> | ||||
| struct GenericVisitor<>: public boost::static_visitor<> { | ||||
| 	void operator()() const {} | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| struct Scope | ||||
| { | ||||
| 	using YulType = std::string; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user