/* ---------------------------------------------------------------------------- * GTSAM Copyright 2010, Georgia Tech Research Corporation, * Atlanta, Georgia 30332-0415 * All Rights Reserved * Authors: Frank Dellaert, et al. (see THANKS for the full author list) * See LICENSE for the license information * -------------------------------------------------------------------------- */ /** * @file Key.h * @brief * @author Richard Roberts * @date Feb 20, 2012 */ #pragma once #include #include #include #include #include #include #include #include #include namespace gtsam { /// Typedef for a function to format a key, i.e. to convert it to a string using KeyFormatter = std::function; // Helper function for DefaultKeyFormatter GTSAM_EXPORT std::string _defaultKeyFormatter(Key key); /** * The default KeyFormatter, which is used if no KeyFormatter is passed * to a 'print' function. * * Automatically detects plain integer keys and Symbol keys. * * Marked as `extern` so that it can be updated by external libraries. * */ extern GTSAM_EXPORT KeyFormatter DefaultKeyFormatter; // Helper function for Multi-robot Key Formatter GTSAM_EXPORT std::string _multirobotKeyFormatter(gtsam::Key key); /// /// A KeyFormatter that will check for LabeledSymbol keys, as well as Symbol and plain /// integer keys. This keyformatter will need to be passed in to override the default /// formatter in print functions. /// /// Checks for LabeledSymbol, Symbol and then plain keys, in order. static const gtsam::KeyFormatter MultiRobotKeyFormatter = &_multirobotKeyFormatter; /// To use the key_formatter on Keys, they must be wrapped in a StreamedKey. struct StreamedKey { const Key &key_; explicit StreamedKey(const Key &key) : key_(key) {} GTSAM_EXPORT friend std::ostream &operator<<(std::ostream &, const StreamedKey &); }; /** * Output stream manipulator that will format gtsam::Keys according to the given * KeyFormatter, as long as Key values are wrapped in a gtsam::StreamedKey. * LabeledSymbol and Symbol values do not have to be wrapped. * usage: * Key key = LabeledSymbol('x', 'A', 5); // cast to key type * cout << key_formatter(MultiRobotKeyFormatter) << StreamedKey(key); */ class key_formatter { public: explicit key_formatter(KeyFormatter v) : formatter_(v) {} GTSAM_EXPORT friend std::ostream &operator<<(std::ostream &, const key_formatter &); GTSAM_EXPORT friend std::ostream &operator<<(std::ostream &, const StreamedKey &); private: KeyFormatter formatter_; static void *&property(std::ios_base &s); static void set_property(std::ios_base &s, const KeyFormatter &f); static KeyFormatter *get_property(std::ios_base &s); }; /// Define collection type once and for all - also used in wrappers using KeyVector = FastVector; // TODO(frank): Nothing fast about these :-( using KeyList = FastList; using KeySet = FastSet; using KeyGroupMap = FastMap; /// Utility function to print one key with optional prefix GTSAM_EXPORT void PrintKey( Key key, const std::string &s = "", const KeyFormatter &keyFormatter = DefaultKeyFormatter); /// Utility function to print sets of keys with optional prefix GTSAM_EXPORT void PrintKeyList( const KeyList &keys, const std::string &s = "", const KeyFormatter &keyFormatter = DefaultKeyFormatter); /// Utility function to print sets of keys with optional prefix GTSAM_EXPORT void PrintKeyVector( const KeyVector &keys, const std::string &s = "", const KeyFormatter &keyFormatter = DefaultKeyFormatter); /// Utility function to print sets of keys with optional prefix GTSAM_EXPORT void PrintKeySet( const KeySet &keys, const std::string &s = "", const KeyFormatter &keyFormatter = DefaultKeyFormatter); // Define Key to be Testable by specializing gtsam::traits template struct traits; template <> struct traits { static void Print(const Key& val, const std::string& str = "") { PrintKey(val, str); } static bool Equals(const Key& val1, const Key& val2, double tol = 1e-8) { return val1 == val2; } }; } // namespace gtsam