Commit 7c5fb975 authored by Jason Rhinelander's avatar Jason Rhinelander

Add output stream support for members

This outputs something like `Member[n]` or `Firm[n]`, and can be
overridden on a per-subclass basis.  It also works for shared members
and weak members.
parent 708abdc0
......@@ -4,4 +4,6 @@ namespace eris {
SharedMember<Member> Agent::sharedSelf() const { return simAgent(id()); }
Agent::operator std::string() const { return "Agent[" + std::to_string(id()) + "]"; }
}
......@@ -20,6 +20,10 @@ public:
* at the beginning of each period.
*/
Bundle assets;
/// Returns `Agent[n]`
explicit operator std::string() const override;
protected:
/// Returns a SharedMember<Member> wrapped around the current object
SharedMember<Member> sharedSelf() const override;
......
......@@ -264,4 +264,8 @@ Firm::Reservation::~Reservation() {
release();
}
Firm::operator std::string() const {
return "Firm[" + std::to_string(id()) + "]";
}
}
......@@ -237,6 +237,9 @@ public:
*/
double epsilon = 1e-10;
/// Converts to string `Firm[n]`.
operator std::string() const override;
protected:
// The following are internal methods that subclasses should provide, but should only be called
// externally indirectly through a call to the analogous supply...() function.
......
#include <eris/Good.hpp>
namespace eris {
SharedMember<Member> Good::sharedSelf() const { return simGood(id()); }
Good::operator std::string() const {
return "Good[" + name + (name.empty() ? "" : ", id=") + std::to_string(id()) + "]";
}
}
......@@ -33,8 +33,12 @@ public:
*/
virtual double atom() { return 0.0; }
/// Converts to string (primarily for debugging). String will be: `Good[n]` for an unnamed
/// good, and `Good[NAME, id=n]` for a named good with name string "NAME".
operator std::string() const override;
protected:
SharedMember<Member> sharedSelf() const override { return simGood(id()); }
SharedMember<Member> sharedSelf() const override;
};
}
#include <eris/Market.hpp>
#include <vector>
#include <sstream>
namespace eris {
......@@ -108,4 +109,12 @@ const char* Market::output_infeasible::what() const noexcept { return "Requested
const char* Market::low_price::what() const noexcept { return "Requested output not available for given price"; }
const char* Market::insufficient_assets::what() const noexcept { return "Assets insufficient for purchasing requested output"; }
Market::operator std::string() const {
if (price_unit.empty() && output_unit.empty())
return "Market[" + std::to_string(id()) + "]";
std::ostringstream ss;
ss << "Market[" << id() << ": " << price_unit << " -> " << output_unit << "]";
return ss.str();
}
}
......@@ -327,6 +327,10 @@ public:
*/
const Bundle price_unit;
/// Converts to string `Market[n: In -> Out]`, where `n` is the `id()`, `In` is the input
/// bundle, and `Out` is the output bundle. If both are empty, yields just `Market[n]`.
operator std::string() const override;
protected:
/// Firms participating in this market
std::unordered_set<id_t> suppliers_;
......
......@@ -240,4 +240,12 @@ Member::Lock::Supplemental Member::Lock::supplement(const SharedMember<Member> &
return Supplemental(*this, member);
}
Member::operator std::string() const {
return "Member[" + std::to_string(id()) + "]";
}
std::ostream& operator << (std::ostream &os, const Member &m) {
return os << static_cast<std::string>(m);
}
}
......@@ -10,6 +10,7 @@
#include <type_traits>
#include <algorithm>
#include <string>
#include <ostream>
namespace eris {
......@@ -611,6 +612,13 @@ protected:
*/
unsigned long maxThreads() const { return simulation()->maxThreads(); }
/// Obtains a string representation of this member, primarily for debugging. The default is
/// `Member[n]` where `n` is the id() of the agent, but subclasses may override.
virtual explicit operator std::string() const;
/// Converts the object to a std::string when sent to an output stream
friend std::ostream& operator << (std::ostream &os, const Member &m);
private:
// The global id counter
static std::atomic<id_t> next_id_;
......
......@@ -5,6 +5,7 @@
#include <typeinfo>
#include <functional>
#include <type_traits>
#include <ostream>
namespace eris {
......@@ -145,6 +146,12 @@ public:
/// Default move assignment
SharedMember& operator=(SharedMember &&) = default;
/// Output support; outputs '<null member>' for an empty reference, otherwise forwards to
/// underlying T's `operator <<`.
friend std::ostream& operator << (std::ostream &os, const SharedMember &s) {
return s.ptr_ ? os << *s : os << "<null member>";
}
private:
std::shared_ptr<T> ptr_;
......@@ -210,6 +217,9 @@ public:
/// between the boolean conversion and the subsequent operation.
operator bool() { return !ptr_.expired(); }
/// Output support; equivalent to `os << w.lock()`.
friend std::ostream& operator << (std::ostream &os, const WeakMember &w) { return os << w.lock(); }
private:
std::weak_ptr<T> ptr_;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment