summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2016-07-19 14:29:40 +0200
committerDennis Brentjes <d.brentjes@gmail.com>2016-07-19 14:29:40 +0200
commitb43c009f77a2964882c9d8d88df195ef906338bc (patch)
tree672e5787012292ac39939229b6b31bc51f6081ad
parent06336eaddcc6a8f9cc578d8f059117c3aa535c9f (diff)
downloadopenwar-b43c009f77a2964882c9d8d88df195ef906338bc.tar.gz
openwar-b43c009f77a2964882c9d8d88df195ef906338bc.tar.bz2
openwar-b43c009f77a2964882c9d8d88df195ef906338bc.zip
No longer uses exceptions for control flow.
-rw-r--r--binparse/output.hpp70
1 files changed, 48 insertions, 22 deletions
diff --git a/binparse/output.hpp b/binparse/output.hpp
index d942fca..4d17175 100644
--- a/binparse/output.hpp
+++ b/binparse/output.hpp
@@ -49,14 +49,23 @@ template <typename ValueType>
std::ostream& operator<<(std::ostream& os, std::vector<ValueType> const& vec);
template <typename Key, typename Value>
-std::ostream& operator<<(std::ostream& os, std::map<Key, Value> const& map) {
- try {
- indent scoped(os);
- os << std::endl;
- for(auto&& entry : map) {
- os << entry.first << ": " << entry.second << std::endl;
- }
- } catch(std::bad_cast&) {
+std::ostream& operator<<(otreestream& os, std::map<Key, Value> const& map) {
+ indent scoped(os);
+ os << std::endl;
+ for(auto&& entry : map) {
+ os << entry.first << ": " << entry.second << std::endl;
+ }
+
+ return os;
+}
+
+template <typename Key, typename Value>
+std::ostream& operator<<(std::ostream& os, std::map<Key, Value> const& map) {
+ auto* tree_os = dynamic_cast<otreestream*>(&os);
+
+ if(tree_os) {
+ *tree_os << map;
+ } else {
os << std::endl;
for(auto&& entry : map) {
os << entry.first << ": " << entry.second << std::endl;
@@ -67,24 +76,31 @@ std::ostream& operator<<(std::ostream& os, std::map<Key, Value> const& map) {
}
template <typename ValueType>
+std::ostream& operator<<(otreestream& os, std::vector<ValueType> const& vec) {
+ indent scoped(os);
+ os << std::endl;
+ for(auto&& entry : vec) {
+ os << entry << std::endl;
+ }
+
+ return os;
+}
+
+template <typename ValueType>
std::ostream& operator<<(std::ostream& os, std::vector<ValueType> const& vec) {
- try {
- indent scoped(os);
- os << std::endl;
- for(auto&& entry : vec) {
- os << entry << std::endl;
- }
- } catch(std::bad_cast&) {
+ auto* tree_os = dynamic_cast<otreestream*>(&os);
+ if(tree_os) {
+ *tree_os << vec;
+ } else {
os << std::endl;
for(auto&& entry : vec) {
os << entry << std::endl;
}
}
+
return os;
}
-
-
template<typename T>
std::ostream& output_impl(std::ostream& os, T const&, indices<>) {
return os;
@@ -99,14 +115,24 @@ std::ostream& output_impl(std::ostream& os, T const& t, indices<I, Indices...>)
}
template <typename T, typename std::enable_if<boost::fusion::traits::is_sequence<T>::value>::type*>
+std::ostream& operator<<(otreestream& os, T const& t) {
+ typedef typename build_indices<boost::fusion::result_of::size<T>::value>::type indices;
+
+ indent scoped(os);
+ os << std::endl;
+ output_impl<T>(os, t, indices{});
+
+ return os;
+}
+
+template <typename T, typename std::enable_if<boost::fusion::traits::is_sequence<T>::value>::type*>
std::ostream& operator<<(std::ostream& os, T const& t) {
typedef typename build_indices<boost::fusion::result_of::size<T>::value>::type indices;
- try {
- indent scoped(os);
- os << std::endl;
- output_impl<T>(os, t, indices{});
- } catch(std::bad_cast&) {
+ auto* tree_os = dynamic_cast<otreestream*>(&os);
+ if(tree_os) {
+ *tree_os << t;
+ } else {
os << std::endl;
output_impl<T>(os, t, indices{});
}