93 lines
3.4 KiB
C++
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
|