]> git.mxchange.org Git - simgear.git/blob - simgear/structure/OSGUtils.hxx
restore some part of the code to prevent an untwanted segmentationf fault.
[simgear.git] / simgear / structure / OSGUtils.hxx
1 // OSGUtils.hxx - Useful templates for interfacing to Open Scene Graph
2 //
3 // Copyright (C) 2008  Tim Moore timoore@redhat.com
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Library General Public
7 // License as published by the Free Software Foundation; either
8 // version 2 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // Library General Public License for more details.
14 //
15 // You should have received a copy of the GNU Library General Public
16 // License along with this library; if not, write to the
17 // Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 // Boston, MA  02111-1307, USA.
19
20 #ifndef SIMGEAR_OSGUTILS_HXX
21 #define SIMGEAR_OSGUTILS_HXX 1
22
23 #include <boost/iterator/iterator_facade.hpp>
24 #include <osg/CopyOp>
25
26 namespace simgear
27 {
28 // RefPtrAdapter also appears in OpenSceneGraph's
29 // osgDB/DatabasePager.cpp. I wrote that code too. -- Tim Moore
30
31 // Convert function objects that take pointer args into functions that a
32 // reference to an osg::ref_ptr. This is quite useful for doing STL
33 // operations on lists of ref_ptr. This code assumes that a function
34 // with an argument const Foo* should be composed into a function of
35 // argument type ref_ptr<Foo>&, not ref_ptr<const Foo>&. Some support
36 // for that should be added to make this more general.
37 template <typename U>
38 struct PointerTraits
39 {
40     typedef class NullType {} PointeeType;
41 };
42
43 template <typename U>
44 struct PointerTraits<U*>
45 {
46     typedef U PointeeType;
47 };
48
49 template <typename U>
50 struct PointerTraits<const U*>
51 {
52     typedef U PointeeType;
53 };
54
55 template <typename FuncObj>
56 class RefPtrAdapter
57     : public std::unary_function<const osg::ref_ptr<typename PointerTraits<typename FuncObj::argument_type>::PointeeType>,
58                                  typename FuncObj::result_type>
59 {
60 public:
61     typedef typename PointerTraits<typename FuncObj::argument_type>::PointeeType PointeeType;
62     typedef osg::ref_ptr<PointeeType> RefPtrType;
63     explicit RefPtrAdapter(const FuncObj& funcObj) : _func(funcObj) {}
64     typename FuncObj::result_type operator()(const RefPtrType& refPtr) const
65     {
66         return _func(refPtr.get());
67     }
68 protected:
69         FuncObj _func;
70 };
71
72 template <typename FuncObj>
73 RefPtrAdapter<FuncObj> refPtrAdapt(const FuncObj& func)
74 {
75     return RefPtrAdapter<FuncObj>(func);
76 }
77 }
78 /** Typesafe wrapper around OSG's object clone function. Something
79  * very similar is in current OSG sources.
80  */
81 namespace osg
82 {
83 template <typename T> class ref_ptr;
84 class CopyOp;
85 }
86
87 namespace simgear
88 {
89 template <typename T>
90 T* clone(const T* object, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY)
91 {
92     return static_cast<T*>(object->clone(copyop));
93 }
94
95 template<typename T>
96 T* clone_ref(const osg::ref_ptr<T>& object,
97              const osg::CopyOp& copyop  = osg::CopyOp::SHALLOW_COPY)
98 {
99     return static_cast<T*>(object->clone(copyop));
100 }
101
102 template<typename Container>
103 class BackRefInsertIterator
104     : public boost::iterator_facade<BackRefInsertIterator<Container>,
105                                     BackRefInsertIterator<Container>,
106                                     boost::incrementable_traversal_tag
107                                     >
108 {
109 public:
110     typedef typename Container::value_type::element_type* PtrType;
111     BackRefInsertIterator() : _container(0) {}
112     explicit BackRefInsertIterator(Container& container)
113         : _container(&container)
114     {
115     }
116
117     BackRefInsertIterator&
118     operator=(const PtrType ptr)
119     {
120         _container->push_back(ptr);
121         return *this;
122     }
123     
124 private:
125     friend class boost::iterator_core_access;
126
127     void increment()
128     {
129     }
130     
131     BackRefInsertIterator& dereference()
132     {
133         return *this;
134     }
135
136     BackRefInsertIterator& dereference() const
137     {
138         return const_cast<BackRefInsertIterator&>(*this);
139     }
140
141     bool equal(const BackRefInsertIterator& rhs)
142     {
143         return _container == rhs._container;
144     }
145     
146     Container* _container;
147 };
148
149
150 template<typename Container>
151 inline BackRefInsertIterator<Container>
152 backRefInsertIterator(Container& container)
153 {
154     return BackRefInsertIterator<Container>(container);
155 }
156 }
157 #endif