From 8e9878f3725557ca1444080f829b5d611fbc8355 Mon Sep 17 00:00:00 2001
From: Adam Wardynski <award@.(win7-laptop)>
Date: Thu, 28 Apr 2011 21:50:56 +0200
Subject: [PATCH] Helper class for (un)typed sections of ops in wccl files.

---
 libwccl/wcclfileopsections.h | 222 +++++++++++++++++++++++++++++++++++
 1 file changed, 222 insertions(+)
 create mode 100644 libwccl/wcclfileopsections.h

diff --git a/libwccl/wcclfileopsections.h b/libwccl/wcclfileopsections.h
new file mode 100644
index 0000000..409efca
--- /dev/null
+++ b/libwccl/wcclfileopsections.h
@@ -0,0 +1,222 @@
+#ifndef LIBWCCL_WCCLFILEOPSECTIONS_H
+#define LIBWCCL_WCCLFILEOPSECTIONS_H
+
+#include <libwccl/ops/opsequence.h>
+#include <boost/unordered_map.hpp>
+#include <libpwrutils/foreach.h>
+
+namespace Wccl {
+
+template<class T>
+class WcclFileOpSections : boost::noncopyable
+{
+	BOOST_MPL_ASSERT( (boost::is_base_of<FunctionalOpSequence, T>) );
+	BOOST_MPL_ASSERT_NOT( (boost::is_same<FunctionalOpSequence, T>) );
+public:
+	typedef typename T::op_t op_t;
+	typedef typename boost::shared_ptr<op_t> op_ptr_t;
+	typedef typename boost::shared_ptr<const op_t> op_ptr_c_t;
+	typedef typename boost::shared_ptr<T> ptr_t;
+	typedef typename boost::shared_ptr<const T> ptr_c_t;
+	typedef typename std::vector<ptr_t> ptr_v_t;
+	typedef typename boost::unordered_map<std::string, ptr_t> map_t;
+	typedef typename T::name_op_v_t name_op_v_t;
+	typedef typename T::name_op_v_c_t name_op_v_c_t;
+
+protected:	
+	
+	bool has_section(const std::string& name) const;
+
+	const ptr_v_t& sections();
+	
+	size_t size() const;
+	bool empty() const;
+
+	std::vector<std::string> section_names() const;
+
+	T& get_section(const std::string& name);
+	const T& get_section(const std::string& name) const;
+
+	ptr_t get_section_ptr(const std::string& name);
+	ptr_c_t get_section_ptr(const std::string& name) const;
+
+	op_t& get_op(const std::string& name, size_t idx = 0);
+	const op_t& get_op(const std::string& name, size_t idx = 0) const;
+
+	op_ptr_t get_op_ptr(const std::string& name, size_t idx = 0);
+	op_ptr_c_t get_op_ptr(const std::string& name, size_t idx = 0) const;
+
+	name_op_v_t& add_name_op_pairs(name_op_v_t& pairs);
+	name_op_v_c_t& add_name_op_pairs(name_op_v_c_t& pairs) const;
+
+	name_op_v_t gen_name_op_pairs();
+	name_op_v_c_t gen_name_op_pairs() const;
+	
+	WcclFileOpSections()
+		: sections_(),
+		  name_section_map_()
+	{
+	}
+
+	void append(const ptr_t& section);
+
+	ptr_v_t sections_;
+	map_t name_section_map_;
+};
+
+} /* end ns Wccl */
+
+
+//
+// Implementation details
+//
+namespace Wccl {
+
+template<class T> inline
+bool WcclFileOpSections<T>::has_section(const std::string& name) const
+{
+	return name_section_map_.find(name) != name_section_map_.end();
+}
+
+template<class T> inline
+typename const WcclFileOpSections<T>::ptr_v_t& WcclFileOpSections<T>::sections()
+{
+	return sections_;
+}
+
+template<class T> inline
+bool WcclFileOpSections<T>::empty() const
+{
+	return sections_.empty();
+}
+
+template<class T> inline
+size_t WcclFileOpSections<T>::size() const
+{
+	return sections_.size();
+}
+
+template<class T> inline
+std::vector<std::string> WcclFileOpSections<T>::section_names() const
+{
+	std::vector<std::string> v(size());
+	foreach(const ptr_t& section, sections_) {
+		v.push_back(section->name());
+	}
+	return v;
+}
+
+template<class T> inline
+typename WcclFileOpSections<T>::ptr_t WcclFileOpSections<T>::get_section_ptr(const std::string& name)
+{
+	map_t::iterator i = name_section_map_.find(name);
+	if (i == name_section_map_.end()) {
+		throw InvalidArgument("name", "Section named \"" + name + "\" does not exist.");
+	}
+	return i->second;
+}
+
+template<class T> inline
+typename WcclFileOpSections<T>::ptr_c_t WcclFileOpSections<T>::get_section_ptr(const std::string& name) const
+{
+	map_t::const_iterator i = name_section_map_.find(name);
+	if (i == name_section_map_.end()) {
+		throw InvalidArgument("name", "Section named \"" + name + "\" does not exist.");
+	}
+	return i->second;
+}
+
+template<class T> inline
+T& WcclFileOpSections<T>::get_section(const std::string& name)
+{
+	return *get_section_ptr(name);
+}
+
+template<class T> inline
+const T& WcclFileOpSections<T>::get_section(const std::string& name) const
+{
+	return *get_section_ptr(name);
+}
+
+template<class T> inline
+typename T::name_op_v_t& WcclFileOpSections<T>::add_name_op_pairs(name_op_v_t& pairs)
+{
+	foreach(const ptr_t& section, sections_) {
+		section->add_name_op_pairs(pairs);
+	}
+	return pairs;
+}
+
+template<class T> inline
+typename T::name_op_v_c_t& WcclFileOpSections<T>::add_name_op_pairs(name_op_v_c_t& pairs) const
+{
+	foreach(const ptr_t& section, sections_) {
+		section->add_name_op_pairs(pairs);
+	}
+	return pairs;
+}
+
+template<class T> inline
+typename T::name_op_v_t WcclFileOpSections<T>::gen_name_op_pairs()
+{
+	name_op_v_t pairs;
+	foreach(const ptr_t& section, sections_) {
+		section->add_name_op_pairs(pairs);
+	}
+	return pairs;
+}
+
+template<class T> inline
+typename T::name_op_v_c_t WcclFileOpSections<T>::gen_name_op_pairs() const
+{
+	name_op_v_c_t pairs;
+	foreach(const ptr_t& section, sections_) {
+		section->add_name_op_pairs(pairs);
+	}
+	return pairs;
+}
+
+template<class T> inline
+void WcclFileOpSections<T>::append(const ptr_t& section)
+{
+	if (has_section(section->name())) {
+		throw InvalidArgument("section", "Section named \"" + section->name() + "\" already added.");
+	}
+	sections_.push_back(section);
+	name_section_map_[section->name()] = section;
+}
+
+template<class T> inline
+typename T::op_t& WcclFileOpSections<T>::get_op(
+	const std::string& name,
+	size_t idx = 0)
+{
+	return get_section(name).get(idx);
+}
+
+template<class T> inline
+typename const T::op_t& WcclFileOpSections<T>::get_op(
+	const std::string& name,
+	size_t idx = 0) const
+{
+	return get_section(name).get(idx);
+}
+
+template<class T> inline
+typename WcclFileOpSections<T>::op_ptr_t WcclFileOpSections<T>::get_op_ptr(
+	const std::string& name,
+	size_t idx = 0)
+{
+	return get_section(name).get_ptr(idx);
+}
+
+template<class T> inline
+typename WcclFileOpSections<T>::op_ptr_c_t WcclFileOpSections<T>::get_op_ptr(
+	const std::string& name,
+	size_t idx = 0) const
+{
+	return get_section(name).get_ptr(idx);
+}
+
+} /* end ns Wccl */
+#endif // LIBWCCL_WCCLFILEOPSECTIONS_H
-- 
GitLab