#ifndef __JTOOLS__JTUPLE__ #define __JTOOLS__JTUPLE__ #include #include #include "JLang/JTypeList.hh" #include "JLang/JNullType.hh" #include "JLang/JClass.hh" #include "JLang/JComparable.hh" #include "JLang/JType.hh" #include "JLang/JNumber.hh" #include "JMath/JMath.hh" #include "JIO/JSerialisable.hh" /** * \file * Data structure based on type list. * \author mdejong */ namespace JTOOLS {} namespace JPP { using namespace JTOOLS; } namespace JTOOLS { using JLANG::JTypeList; using JLANG::JTYPELIST; using JLANG::JNullType; using JLANG::JClass; using JLANG::JType; using JLANG::JNumber; using JLANG::for_each; using JMATH::JMath; using JLANG::JComparable; using JIO::JReader; using JIO::JWriter; /** * Template data structure. */ template struct JTuple : public JMath < JTuple >, public JComparable< JTuple > { typedef JTypeList typelist; /** * Default constructor. */ JTuple() {} /** * Constructor. * * \param __first first */ JTuple(typename JClass::argument_type __first) : first(__first) {} /** * Negate tuple. * * \return this tuple */ JTuple& negate() { first = -first; return *this; } /** * Add tuple. * * \param tuple tuple * \return this tuple */ JTuple& add(const JTuple& tuple) { first += tuple.first; return *this; } /** * Subtract tuple. * * \param tuple tuple * \return this tuple */ JTuple& sub(const JTuple& tuple) { first -= tuple.first; return *this; } /** * Scale tuple. * * \param factor multiplication factor * \return this tuple */ JTuple& mul(const double factor) { first *= factor; return *this; } /** * Scale tuple. * * \param factor division factor * \return this tuple */ JTuple& div(const double factor) { first /= factor; return *this; } /** * Compare tuple. * * \param tuple tuple * \return true if this tuple less than given tuple; else false */ bool less(const JTuple& tuple) const { return first < tuple.first; } /** * Read tuple from input. * * \param in input stream * \param tuple tuple * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JTuple& tuple) { return in >> tuple.first; } /** * Write tuple to output. * * \param out output stream * \param tuple tuple * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JTuple& tuple) { return out << tuple.first; } /** * Read tuple from input. * * \param in reader * \param tuple tuple * \return reader */ friend inline JReader& operator>>(JReader& in, JTuple& tuple) { return in >> tuple.first; } /** * Write tuple to output. * * \param out writer * \param tuple tuple * \return writer */ friend inline JWriter& operator<<(JWriter& out, const JTuple& tuple) { return out << tuple.first; } T first; }; /** * Template specialisation of JTuple for multiple data types. */ template struct JTuple< JTypeList > : public JMath < JTuple< JTypeList > >, public JComparable< JTuple< JTypeList > > { typedef JTypeList typelist; /** * Default constructor. */ JTuple() {} /** * Constructor. * * \param __first first * \param __second second */ JTuple(typename JClass::argument_type __first, const JTuple& __second) : first (__first), second(__second) {} /** * Initialise constructor. * * \param value first value * \param args remaining values */ template JTuple(typename JClass::argument_type value, const Args& ...args) : first (value), second(args...) {} /** * Negate tuple. * * \return this tuple */ JTuple& negate() { first = -first; second.negate(); return *this; } /** * Add tuple. * * \param tuple tuple * \return this tuple */ JTuple& add(const JTuple& tuple) { first += tuple.first; second.add(tuple.second); return *this; } /** * Subtract tuple. * * \param tuple tuple * \return this tuple */ JTuple& sub(const JTuple& tuple) { first -= tuple.first; second.sub(tuple.second); return *this; } /** * Scale tuple. * * \param factor multiplication factor * \return this tuple */ JTuple& mul(const double factor) { first *= factor; second.mul(factor); return *this; } /** * Scale tuple. * * \param factor division factor * \return this tuple */ JTuple& div(const double factor) { first /= factor; second.div(factor); return *this; } /** * Compare tuple. * * \param tuple tuple * \return true if this tuple less than given tuple; else false */ bool less(const JTuple& tuple) const { if (first == tuple.first) return second < tuple.second; else return first < tuple.first; } /** * Read tuple from input. * * \param in input stream * \param tuple tuple * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JTuple& tuple) { in >> tuple.first; in >> tuple.second; return in; } /** * Write tuple to output. * * \param out output stream * \param tuple tuple * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JTuple& tuple) { out << tuple.first; out << ' '; out << tuple.second; return out; } /** * Read tuple from input. * * \param in reader * \param tuple tuple * \return reader */ friend inline JReader& operator>>(JReader& in, JTuple& tuple) { in >> tuple.first; in >> tuple.second; return in; } /** * Write tuple to output. * * \param out writer * \param tuple tuple * \return writer */ friend inline JWriter& operator<<(JWriter& out, const JTuple& tuple) { out << tuple.first; out << tuple.second; return out; } JHead_t first; JTuple second; }; /** * Template specialisation of JTuple for two data types. */ template struct JTuple< JTypeList > > : public JMath < JTuple > > >, public JComparable< JTuple > > > { typedef JTypeList typelist; /** * Default constructor. */ JTuple() {} /** * Constructor. * * \param __first first * \param __second second */ JTuple(typename JClass::argument_type __first, typename JClass::argument_type __second) : first (__first), second(__second) {} /** * Constructor. * * \param __first first * \param __second second */ JTuple(typename JClass::argument_type __first, const JTuple& __second) : first (__first), second(__second.first) {} /** * Negate tuple. * * \return this tuple */ JTuple& negate() { first = -first; second = -second; return *this; } /** * Add tuple. * * \param tuple tuple * \return this tuple */ JTuple& add(const JTuple& tuple) { first += tuple.first; second += tuple.second; return *this; } /** * Subtract tuple. * * \param tuple tuple * \return this tuple */ JTuple& sub(const JTuple& tuple) { first -= tuple.first; second -= tuple.second; return *this; } /** * Scale tuple. * * \param factor multiplication factor * \return this tuple */ JTuple& mul(const double factor) { first *= factor; second *= factor; return *this; } /** * Scale tuple. * * \param factor division factor * \return this tuple */ JTuple& div(const double factor) { first /= factor; second /= factor; return *this; } /** * Compare tuple. * * \param tuple tuple * \return true if this tuple less than given tuple; else false */ bool less(const JTuple& tuple) const { if (first == tuple.first) return second < tuple.second; else return first < tuple.first; } /** * Read tuple from input. * * \param in input stream * \param tuple tuple * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JTuple& tuple) { in >> tuple.first; in >> tuple.second; return in; } /** * Write tuple to output. * * \param out output stream * \param tuple tuple * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JTuple& tuple) { out << tuple.first; out << ' '; out << tuple.second; return out; } /** * Read tuple from input. * * \param in reader * \param tuple tuple * \return reader */ friend inline JReader& operator>>(JReader& in, JTuple& tuple) { in >> tuple.first; in >> tuple.second; return in; } /** * Write tuple to output. * * \param out writer * \param tuple tuple * \return writer */ friend inline JWriter& operator<<(JWriter& out, const JTuple& tuple) { out << tuple.first; out << tuple.second; return out; } JHead_t first; JTail_t second; }; /** * Terminator class of recursive JTuple class. */ template struct JTuple< JTypeList > : public JTuple { typedef JTypeList typelist; /** * Default constructor. */ JTuple() {} /** * Constructor. * * \param __first first */ JTuple(typename JClass::argument_type __first) : JTuple(__first) {} /** * Constructor. * * \param __first first * \param __second second */ JTuple(typename JClass::argument_type __first, const JTuple& __second) : JTuple(__first) {} }; /** * For each data type method. * * The given object should provide for the function object operator *
   *    template
   *    void object()(JType type, tuple);
   * 
* * \param object object * \param typelist type list * \param tuple tuple * \return object */ template JObject_t& for_each(JObject_t& object, JType< JTypeList > typelist, const JTuple& tuple) { for_each(object, JType(), tuple); for_each(object, JType(), tuple); return object; } /** * For each data type method. * * The given object should provide for the function object operator *
   *    template
   *    void object()(JType type, tuple);
   * 
* * \param object object * \param type type * \param tuple tuple * \return object */ template JObject_t& for_each(JObject_t& object, JType type, const JTuple& tuple) { object(type, tuple); return object; } /** * Helper method for tuple. * * \param args values * \return tuple */ template inline JTuple::typelist> make_tuple(const Args& ...args) { return JTuple::typelist>(args...); } /** * Termination method of for each data type method. * * \param object object * \param type null type * \param tuple tuple * \return object */ template JObject_t& for_each(JObject_t& object, JType type, const JTuple& tuple) { return object; } } #endif