open_toontown_panda3d/panda/src/express/dcast.h

93 lines
3.4 KiB
C++

// Filename: dcast.h
// Created by: drose (06Aug01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef DCAST_H
#define DCAST_H
#include "pandabase.h"
#include "typeHandle.h"
#include "typedObject.h"
// The DCAST (downcast) macro is defined as a convenience for
// downcasting from some TypedObject pointer (or a PointerTo). It's
// just a normal C++-style downcast, except it first checks get_type()
// to make sure the downcasting is safe. If you compile with NDEBUG,
// or set verify-dcast to #f, this check is removed.
// DCAST will return NULL if the downcasting is unsafe. If you'd
// rather it abort out of the function (a la nassertv/nassertr), then
// see DCAST_INTO_V and DCAST_INTO_R, below.
template<class WantType>
INLINE WantType *_dcast(WantType *, TypedObject *ptr);
template<class WantType>
INLINE const WantType *_dcast(WantType *, const TypedObject *ptr);
// Note: it is important that DCAST not repeat the pointer parameter,
// since many users of DCAST may want to use the result of a function
// as the pointer parameter, and it could be terribly confusing and
// difficult to trace if the function were inadvertently executed
// twice. This happened!
#define DCAST(want_type, pointer) _dcast((want_type*)0, pointer)
// DCAST_INTO_V and DCAST_INTO_R are similar in purpose to DCAST,
// except they: (a) automatically assign a variable instead of
// returning the downcasted pointer, and (b) they immediately return
// out of the function if the downcasting fails. DCAST_INTO_V is for
// use in a void function and returns nothing; DCAST_INTO_R is for use
// in a non-void function and returns the indicated value.
// Both DCAST_INTO_V and DCAST_INTO_R accept as the first parameter a
// variable of type (want_type *) or (const want_type *), instead of
// the name of the type. This variable will be filled with the new
// pointer.
// _dcast_ref is used to implement DCAST_INTO_V and DCAST_INTO_R. Its
// difference from _dcast is that it takes a reference to a pointer as
// a first parameter. The main point of this is to shut up the
// compiler about pointers used before their value is assigned.
template<class WantType>
INLINE WantType *_dcast_ref(WantType *&, TypedObject *ptr);
template<class WantType>
INLINE const WantType *_dcast_ref(WantType *&, const TypedObject *ptr);
#ifndef NDEBUG
// _dcast_verify performs the actual verification.
EXPCL_PANDAEXPRESS bool
_dcast_verify(TypeHandle want_handle, size_t want_size,
const TypedObject *ptr);
#endif // NDEBUG
#define DCAST_INTO_V(to_pointer, from_pointer) \
{ \
(to_pointer) = _dcast_ref(to_pointer, from_pointer); \
nassertv((void *)(to_pointer) != (void *)NULL); \
}
#define DCAST_INTO_R(to_pointer, from_pointer, return_value) \
{ \
(to_pointer) = _dcast_ref(to_pointer, from_pointer); \
nassertr((void *)(to_pointer) != (void *)NULL, return_value); \
}
#include "dcast.T"
#endif