This file is indexed.

/usr/include/trilinos/Teuchos_OpaqueWrapper.hpp is in libtrilinos-teuchos-dev 12.4.2-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
// @HEADER
// ***********************************************************************
//
//                    Teuchos: Common Tools Package
//                 Copyright (2004) Sandia Corporation
//
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
// license for use of this work by or on behalf of the U.S. Government.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
//
// ***********************************************************************
// @HEADER

#ifndef TEUCHOS_OPAQUE_WRAPPER_HPP
#define TEUCHOS_OPAQUE_WRAPPER_HPP


#include "Teuchos_RCP.hpp"


//#define TEUCHOS_OPAQUE_WRAPPER_ANNOUNCE_FREE

#ifdef TEUCHOS_OPAQUE_WRAPPER_ANNOUNCE_FREE
#  include "Teuchos_VerboseObject.hpp"
#endif // TEUCHOS_OPAQUE_WRAPPER_ANNOUNCE_FREE


namespace Teuchos {


/** \class OpaqueWrapper
 * \brief Base class for wrapped opaque objects.
 * \tparam Opaque Type of the opaque object (a.k.a. handle).
 * \ingroup teuchos_mem_mng_grp
 *
 * \section Teuchos_OpaqueWrapper_Summary Summary
 *
 * If you want to create an RCP to an opaque handle (an instance of a
 * type like MPI_Comm), use the opaqueWrapper() nonmember template
 * function.  If that opaque handle needs to be freed after all
 * references to it go away, then supply a "free" function to
 * opaqueWrapper().  The type returned by opaqueWrapper() is
 * <tt>RCP<OpaqueWrapper<T> ></tt>, an RCP (reference-counted "smart"
 * pointer) to a wrapper of the opaque handle type T.  Users are not
 * allowed to construct an OpaqueWrapper object explicitly.  You must
 * use the opaqueWrapper() nonmember function to do so.
 *
 * \section Teuchos_OpaqueWrapper_Prereq Prerequisites
 *
 * In order to understand this documentation, you must first have
 * learned how to use RCP (Teuchos' reference-counted "smart" pointer
 * class) to manage dynamically allocated memory and other resources.
 * It also helps to be familiar with MPI (the Message Passing
 * Interface for distributed-memory parallel programming), but this is
 * not required.
 *
 * \section Teuchos_OpaqueWrapper_Handles What are opaque handles?
 *
 * Many different software libraries use the <i>opaque handle</i>
 * (a.k.a. opaque object) idiom to hide the internals of a data
 * structure from users.  This standard technique allows users to
 * treat an instance of a data structure as a handle.  Users may pass
 * the handle around as if it were a simple value type (like int), and
 * must call nonmember functions in order to create, operate on, use,
 * or destroy instances of the data structure.  The MPI (Message
 * Passing Interface) standard is full of examples of the opaque
 * handle idiom, including MPI_Comm (for communicators), MPI_Datatype
 * (for standard and custom data types), and MPI_Op (for standard and
 * custom reduction operations).
 *
 * In general, opaque handles (corresponding to the Opaque template
 * parameter) must be <i>assignable</i>.  This means that copy
 * construction and assignment (operator=) must be syntactically
 * correct for instances of Opaque.  This is certainly true of MPI's
 * opaque handle types.
 *
 * Opaque handles are a useful technique, but they interfere with
 * correct use of reference-counted "smart" pointer types such as
 * Teuchos' RCP or std::shared_ptr.  We will explain below why this is
 * the case.  The OpaqueWrapper base class allows opaque handles to be
 * wrapped by a real object, whose address you can take.  This is
 * needed in order to wrap an opaque object in a RCP, for example.
 *
 * \section Teuchos_OpaqueWrapper_Special Why do opaque handles need special treatment?
 *
 * The OpaqueWrapper class was motivated by MPI's common use of the
 * opaque handle idiom.  For MPI, passing MPI_Comm, MPI_Datatype, and
 * MPI_Op objects around by handles hides implementation details from
 * the user.  Handles also make it easier to access MPI functionality
 * from Fortran, so that C, C++, and Fortran can all share the same
 * handle mechanism.  In fact, some MPI implementations (such as
 * MPICH, at least historically if not currently) simply implement
 * these handles all as integers.  (As the MPI standard's advice to
 * implementers suggests, such an implementation would likely maintain
 * a table for each MPI process that maps the integer value to a
 * pointer to the corresponding object.)  For example, MPI_Comm might
 * be a typedef to int, and MPI_COMM_WORLD might be a C preprocessor
 * macro for a literal integer value:
 *
 \code
 typedef int MPI_Comm;
 #define MPI_COMM_WORLD 42
 \endcode

 * In this case, the expression <tt>rcp(&MPI_COMM_WORLD)</tt> would
 * not even compile, since one cannot take the address of an integer
 * literal such as 42.  (Remember that preprocessor macros get
 * replaced with their values before the C++ compiler does its work.)
 * To make this expression compile, one might try the following:

 \code
 // THIS FUNCTION IS WRONG.  IT MAY SEGFAULT.
 Teuchos::RCP<MPI_Comm> getMpiCommPtr()
 {
   MPI_Comm comm = MPI_COMM_WORLD;
   // WRONG!!!  comm is a stack variable!
   return Teuchos::rcp (&comm, false);
 }
 \endcode

 * Using the returned communicator would result in undefined behavior,
 * which in practice might be a segfault, memory corruption, or MPI
 * getting severely confused.  This is because the stack variable
 * <tt>comm</tt>, which may be just an integer, disappears at the end
 * of the function.  Its address would no longer point to valid memory
 * after the function returns.
 *
 * The following code is syntactically correct, but may leak memory:

 \code
 // THIS CODE LEAKS MEMORY FOR GENERAL MPI_Comm OBJECTS.
 Teuchos::RCP<MPI_Comm> getMpiCommPtr (MPI_Comm comm)
 {
   MPI_Comm *pComm = new MPI_Comm (comm);
   // Works for comm==MPI_COMM_WORLD or MPI_COMM_SELF;
   // leaks memory for user-created MPI_Comm objects.
   return Teuchos::rcp (pComm);
 }
 \endcode

 * The above implementation of getMpiCommPtr() is correct only for the
 * standard MPI_Comm objects provided by MPI, like MPI_COMM_WORLD and
 * MPI_COMM_SELF.  It is <i>not</i> correct, and in fact may leak
 * memory, for custom MPI_Comm objects that the user creates by
 * calling functions like MPI_Comm_split().  This is because
 * user-created MPI_Comm objects must be freed by MPI_Comm_free().
 * Other kinds of opaque objects, like MPI_Datatype and MPI_Op, have
 * their own free functions.  Thus, even if opaque handles have the
 * type integer, they really behave like pointers or references.  Some
 * of them can and should be freed at the end of their useful lives;
 * others must not.  (Compare std::ostream; std::cout should never be
 * closed by typical user code, but an output file should be closed.)
 *
 * \section Teuchos_OpaqueWrapper_How How to use OpaqueWrapper
 *
 * We fix this problem by providing the OpaqueWrapper template base
 * class and the opaqueWrapper() nonmember template function.  Use
 * this function to wrap an opaque handle (like an MPI_Comm) in an
 * RCP.  This ensures that the RCP does the right thing in case the
 * handle must be freed.  For example, to wrap MPI_COMM_WORLD in a
 * RCP, just do this:

 \code
 RCP<OpaqueWrapper<MPI_Comm> > comm = opaqueWrapper (MPI_COMM_WORLD);
 \endcode

 * If you instead want to create a custom MPI_Comm using a function
 * like MPI_Comm_split(), then you may wrap it in an RCP as follows
 * (please see discussion later about MPI_Comm_free()):

 \code
 MPI_Comm rawComm;
 // We omit all arguments but the last of MPI_Comm_split, for clarity.
 int errCode = MPI_Comm_split (..., &rawComm);
 if (errCode != MPI_SUCCESS) {
   // ... Handle the error ...
 }
 RCP<OpaqueWrapper<MPI_Comm> > comm = opaqueWrapper (rawComm, MPI_Comm_free);
 \endcode

 * The optional second argument to opaqueWrapper() is a "free"
 * function.  It has type OpaqueFree which is a template parameter.
 * If the free function is provided, then when the RCP's reference
 * count goes to zero, that function is called to "free" the handle.
 * If opaqueFree is a free function, then the following must be
 * syntactically valid, where <tt>opaque</tt> has type <tt>Opaque</tt>:

 \code
 opaqueFree (&opaque);
 \endcode

 * The function's return value, if any, is ignored.  Furthermore, the
 * OpaqueFree type must be copy constructible.  (A function pointer is
 * trivally copy constructible.)
 *
 * Users are responsible for knowing whether to provide a free
 * function to opaqueWrapper().  In this case, because we created an
 * MPI_Comm dynamically using a communicator "constructor" function,
 * the MPI_Comm must be "freed" after use.  RCP will automatically
 * call the "free" function once the reference count of \c comm
 * reaches zero.
 *
 * \note The above example is only correct if the reference count of
 * \c comm will go to zero before MPI_Finalize is called.  This is
 * because it's not valid to call MPI_Comm_free after MPI_Finalize has
 * been called.  The details::safeCommFree function checks whether
 * MPI_Finalize has been called (via MPI_Finalized) before calling
 * MPI_Comm_free; you may use this function as the free function if
 * you are concerned about this.
 */
template <class Opaque>
class OpaqueWrapper {
public:
  /// \brief Constructor that accepts and wraps a raw handle.
  ///
  /// Users typically never have to invoke the constructor explicitly.
  /// The opaqueWrapper() nonmember template function does this for them.
  OpaqueWrapper( Opaque opaque )
    : opaque_(opaque)
    {}
  /// \brief Implicit type conversion from wrapper to raw handle.
  ///
  /// Users typically never have to convert directly from an
  /// OpaqueWrapper to the raw handle that it wraps.  For example, if
  /// you have an <tt>RCP<OpaqueHandle<T> ></tt>, just deferencing the
  /// RCP will return the raw handle via this implicit type conversion
  /// operator:
  /// \code
  /// // We omit the right-hand side of this assignment, for simplicity.
  /// RCP<OpaqueWrapper<T> > wrapped = ...;
  /// // RCP's operator* returns OpaqueWrapper<T>&.
  /// // In turn, the operator below automatically converts to T.
  /// T raw = *wrapped;
  /// \endcode
  operator Opaque () const
    { return opaque_; }
  /// \brief Explicit type conversion from wrapper to raw handle.
  ///
  /// Users typically never have to convert directly from an
  /// OpaqueWrapper to the raw handle that it wraps.  However,
  /// in case they do, we provide this operator.
  Opaque operator()() const
    { return opaque_; }
protected:
  /// \brief The actual handle.
  ///
  /// This is protected and not private so that OpaqueWrapperWithFree
  /// can access it.  In general, one should avoid using protected
  /// data, but it would be silly to add member functions just for
  /// this simple use case.
  Opaque  opaque_;
private:
  OpaqueWrapper(); // Not defined
  OpaqueWrapper(const OpaqueWrapper&); // Not defined
  OpaqueWrapper& operator=(const OpaqueWrapper&); // Not defined
};

/** \class OpaqueWrapperWithFree
 * \brief Subclass for wrapped opaque objects with a free function.
 * \tparam Opaque Type of the opaque object (a.k.a. handle).
 * \tparam OpaqueFree Type of the function for freeing the handle.
 *
 * \note Teuchos users do not normally need to use or refer to this
 *   class.  The opaqueWrapper() nonmember template function suffices
 *   for nearly all use cases.  Please see the documentation of the
 *   base class OpaqueWrapper.
 *
 * This subclass allows a client to easily wrap any opaque object that
 * needs a function to free it.  This function (or function object)
 * must be callable as:

 \code
 opaqueFree(&opaque);
 \endcode

 * It must also be copy constructible.  (A function pointer is
 * trivially copy constructible.)  Please refer to the documentation
 * of OpaqueWrapper for examples of how to supply a function for
 * freeing an opaque handle.
 *
 * \relates OpaqueWrapper
 */
template <class Opaque, class OpaqueFree>
class OpaqueWrapperWithFree : public OpaqueWrapper<Opaque> {
public:
  //! Constructor: takes the opaque handle, and its free function.
  OpaqueWrapperWithFree( Opaque opaque, OpaqueFree opaqueFree )
    : OpaqueWrapper<Opaque>(opaque), opaqueFree_(opaqueFree)
  {}
  //! Destructor: invokes the free function.
  ~OpaqueWrapperWithFree()
  {
    // FIXME (mfh 10 Sep 2012) This only works if the free function is
    // a raw function pointer, not if it is a general "function object"
    // (i.e., something callable via operator()).
    if(opaqueFree_) {
#ifdef TEUCHOS_OPAQUE_WRAPPER_ANNOUNCE_FREE
      Teuchos::RCP<Teuchos::FancyOStream>
	out = Teuchos::VerboseObjectBase::getDefaultOStream();
      Teuchos::OSTab tab(out);
      *out << "\nOpaqueWrapperWithFree::~OpaqueWrapperWithFree(): Freeing opaque object"
	   << " of type " << TypeNameTraits<Opaque>::name() << "!\n";
#endif // TEUCHOS_OPAQUE_WRAPPER_ANNOUNCE_FREE
      opaqueFree_(&this->opaque_);
    }
  }
private:
  //! Function (or function object) for freeing the handle.
  OpaqueFree opaqueFree_;
  OpaqueWrapperWithFree(); // Not defined
  OpaqueWrapperWithFree(const OpaqueWrapperWithFree&); // Not defined
  OpaqueWrapperWithFree& operator=(const OpaqueWrapperWithFree&); // Not defined
};


/** \brief Create a new <tt>OpaqueWrapper</tt> object without a free function.
 *
 * See the documentation of OpaqueWrapper for a detailed explanation
 * of why and how to use this function.
 *
 * \relates OpaqueWrapper
 */
template <class Opaque>
inline
RCP<OpaqueWrapper<Opaque> >
opaqueWrapper( Opaque opaque)
{
  return rcp(new OpaqueWrapper<Opaque>(opaque));
}


/** \brief Create a new <tt>OpaqueWrapper</tt> object with a free function.
 *
 * See the documentation of OpaqueWrapper for a detailed explanation
 * of why and how to use this function.
 *
 * \relates OpaqueWrapper
 */
template <class Opaque, class OpaqueFree>
inline
RCP<OpaqueWrapper<Opaque> >
opaqueWrapper( Opaque opaque, OpaqueFree opaqueFree)
{
  return rcp(new OpaqueWrapperWithFree<Opaque,OpaqueFree>(opaque,opaqueFree));
}


} // namespace Teuchos


#endif  // TEUCHOS_OPAQUE_WRAPPER_HPP