Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / utility / messagestringcollector.h
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \libinternal \file
32  * \brief
33  * Declares ::gmx::MessageStringCollector.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \inlibraryapi
37  * \ingroup module_utility
38  */
39 #ifndef GMX_UTILITY_MESSAGESTRINGCOLLECTOR_H
40 #define GMX_UTILITY_MESSAGESTRINGCOLLECTOR_H
41
42 #include <string>
43
44 #include "../utility/common.h"
45
46 namespace gmx
47 {
48
49 /*! \libinternal \brief
50  * Helper class for collecting message strings, optionally with context.
51  *
52  * After strings have been collected, they can be formatted into one long
53  * string for, e.g., printing out or for including in an exception.
54  *
55  * \inlibraryapi
56  * \ingroup module_utility
57  */
58 class MessageStringCollector
59 {
60     public:
61         MessageStringCollector();
62         ~MessageStringCollector();
63
64         /*! \brief
65          * Starts a context for messages.
66          *
67          * \param[in] name  Short description of the context.
68          *
69          * \see finishContext()
70          * \see MessageStringContext
71          */
72         void startContext(const char *name);
73         /*! \brief
74          * Convenience wrapper for startContext(const char *).
75          */
76         void startContext(const std::string &name)
77         { startContext(name.c_str()); }
78         /*! \brief
79          * Adds a new message.
80          */
81         void append(const char *message)
82         { append(std::string(message)); }
83         /*! \brief
84          * Adds a new message.
85          */
86         void append(const std::string &message);
87         /*! \brief
88          * Ends a context started with startContext().
89          *
90          * \see MessageStringContext
91          */
92         void finishContext();
93         /*! \brief
94          * Clears all collected messages.
95          */
96         void clear();
97
98         /*! \brief
99          * Returns true if any messages have been added.
100          *
101          * \returns true if append() has been called at least once.
102          *
103          * The return value is identical to \c toString().empty().
104          * Calls to startContext()/finishContext() only do not cause this
105          * function to return true.
106          */
107         bool isEmpty() const;
108         /*! \brief
109          * Returns all collected messages as one string.
110          */
111         std::string toString() const;
112
113     private:
114         class Impl;
115
116         PrivateImplPointer<Impl> impl_;
117 };
118
119 /*! \libinternal \brief
120  * Convenience class for creating a message context.
121  *
122  * This class provides a RAII-style interface to the
123  * MessageStringCollector::startContext() and
124  * MessageStringCollector::finishContext() methods: finishContext() is called
125  * upon destruction of the object.  This avoids the need to call
126  * MessageStringCollector::finishContext() on every possible exit point.
127  *
128  * Example usage:
129  * \code
130 bool function(::gmx::MessageStringCollector *errors)
131 {
132     ::gmx::MessageStringContext errcontext(errors, "In function()");
133     bool bOk = function2(errors);
134     bOk = function3(errors) && bOk;
135     // <more processing>
136     return bOk;
137 }
138  * \endcode
139  *
140  * \see MessageStringCollector
141  * \inlibraryapi
142  * \ingroup module_utility
143  */
144 class MessageStringContext
145 {
146     public:
147         /*! \brief
148          * Adds a context for the given object.
149          */
150         MessageStringContext(MessageStringCollector *collector, const char *name)
151             : collector_(*collector)
152         {
153             collector_.startContext(name);
154         }
155         /*! \brief
156          * Adds a context for the given object.
157          */
158         MessageStringContext(MessageStringCollector *collector,
159                              const std::string &name)
160             : collector_(*collector)
161         {
162             collector_.startContext(name);
163         }
164         /*! \brief
165          * Calls MessageStringCollector::finishContext() on the wrapped object.
166          */
167         ~MessageStringContext()
168         {
169             collector_.finishContext();
170         }
171
172     private:
173         //! The wrapped object.
174         MessageStringCollector &collector_;
175
176         GMX_DISALLOW_COPY_AND_ASSIGN(MessageStringContext);
177 };
178
179 } // namespace gmx
180
181 #endif