Source

mana-core-rootutils / RootUtils / PyROOTConstFix.h

// This file's extension implies that it's C, but it's really -*- C++ -*-.
// $Id: PyROOTConstFix.h,v 1.1 2007-10-11 21:49:02 ssnyder Exp $

/**
 * @file RootUtils/PyROOTConstFix.h
 * @author scott snyder
 * @date Oct 2007
 * @brief Work around pyroot const bug.
 */


#ifndef ROOTUTILS_PYROOTCONSTFIX_H
#define ROOTUTILS_PYROOTCONSTFIX_H


#include <string>


namespace RootUtils {


/**
 * @brief Work around pyroot const bug.
 *
 * In root 5.14.00, pyroot has a problem with how const vs. non-const
 * overloads are handled.  Given two overloads that match with the exception
 * of the const qualifier, pyroot will call the non-const version.
 * But when it converts the returned value to python form, the type
 * it uses is that of the first overload.  If the return types of the
 * two overloads are not layout-compatible, then this can cause crashes.
 *
 * This is a problem in particular for DataVector.  There, for the element
 * access methods, the const method returns a pointer directly, while
 * the non-const method returns a proxy object.  PyROOT was calling
 * the non-const version but then converting the result as if it were
 * a pointer.
 *
 * As a workaround, the code here will overwrite the name of the
 * const overload with trash, effectively hiding it from pyroot.
 */
class PyROOTConstFix
{
public:
  /**
   * @brief Fix one method.
   * @param classname The name of the class containing the method to fix.
   * @param funcname The name of the method to fix.
   *
   * Any const overload of the named method will have its name
   * overwritten in the cint dictionary, effectively hiding it from pyroot.
   */
  static void fix_one (const char* classname, const char* funcname);


  /**
   * @brief Fix all DataVector methods of a given class.
   * @param classname The name of the class to fix.
   *
   * This will apply @c fix_one to all of the DataVector methods
   * affected by this problem.
   */
  static void fix_all (const char* classname);


  /*
   * @brief Test for a DataVector class and apply fix if needed.
   * @param classname The name of the class to test.
   * @returns True if the class or one of its bases was fixed, false otherwise.
   *
   * This function will test @c classname and any base classes
   * to see if they are DataVector classes.  If so, @c fix_all
   * will be applied to the class, and the function will return true.
   */
  static bool test_dv (const char* classname);
};


} // namespace RootUtils


#endif // not ROOTUTILS_PYROOTCONSTFIX_H