source: trunk/legacy/any.hh @ 496

Last change on this file since 496 was 440, checked in by epyon, 10 years ago
  • massive std::string removal
  • no header depends on std::string anymore (or any other STL header)
  • still some code files do (WIP)
  • massive refactoring where std::string was used
  • lua still messy (grep for string128 - used everywhere)
  • string_twine added
File size: 2.9 KB
Line 
1// Copyright (C) 2014-2015 ChaosForge Ltd
2// http://chaosforge.org/
3//
4// This file is part of Nova libraries.
5// For conditions of distribution and use, see copying.txt file in root folder.
6
7/**
8 * @file any.hh
9 * @author Kornel Kisielewicz
10 * @brief any type
11 *
12 * based on http://www.two-sdg.demon.co.uk/curbralan/papers/ValuedConversions.pdf
13 */
14
15#ifndef NV_STL_ANY_HH
16#define NV_STL_ANY_HH
17
18#include <nv/common.hh>
19#include <nv/stl/utility.hh>
20#include <nv/stl/type_traits.hh>
21#include <nv/stl/type_info.hh>
22
23#error "any type is currently unsupported!"
24
25namespace nv
26{
27       
28        class any
29        {
30        public:
31                any() : m_content( nullptr ) {}
32               
33                any( const any& other )
34                        : m_content( other.m_content ? other.m_content->clone() : nullptr )
35                {}
36
37                template< typename T >
38                any( const T& value )
39                        : m_content( new holder<T>( value ) )
40                {}
41
42                any( any&& other )
43                        : m_content( other.m_content )
44                {}
45
46                template< typename T >
47                any( T&& value )
48                        : m_content( new holder<T>( forward<T>(value) ) )
49                {}
50
51                ~any()
52                {
53                        delete m_content;
54                }
55
56                any& swap( any& rhs )
57                {
58                        nv::swap( m_content, rhs.m_content );
59                        return *this;
60                }
61
62                any& operator=( const any& rhs )
63                {
64                        return swap( any( rhs ) );
65                }
66
67                any& operator=( any&& rhs )
68                {
69                        swap( rhs );
70                        any().swap( rhs );
71                        return *this;
72                }
73
74                template < typename T >
75                any& operator= ( T&& rhs )
76                {
77                        any( forward<T>(rhs) ).swap(*this);
78                        return *this;
79                }
80
81                operator const void* () const
82                {
83                        return m_content;
84                }
85
86                template< typename T >
87                bool copy_to( T& value ) const
88                {
89                        const T* copyable = to_ptr<T>();
90                        if ( copyable ) value = *copyable;
91                        return copyable;
92                }
93                template< typename T >
94                const T* to_ptr() const
95                {
96                        return type_info() == typeid(T) ? &static_cast< holder<T> *>(m_content)->held                           : nullptr;
97                }
98
99                bool empty() const
100                {
101                        return !m_content;
102                }
103
104                void clear()
105                {
106                        any().swap(*this);
107                }
108
109                const std::type_info &type_info() const
110                {
111                        return m_content ? m_content->type_info() : typeid(void);
112                }
113        private:
114                class placeholder
115                {
116                public:
117                        virtual const std::type_info& type_info() const = 0;
118                        virtual placeholder *clone() const = 0;
119                        virtual ~placeholder() {}
120                };
121
122                template< typename T >
123                class holder : public placeholder
124                {
125                public:
126                        holder( const T& value ) : held(value)
127                        {
128                        }
129                        holder( T&& value ) : held(forward<T>(value))
130                        {
131                        }
132                        virtual const std::type_info &type_info() const
133                        {
134                                return typeid(T);
135                        }
136                        virtual placeholder *clone() const
137                        {
138                                return new holder(held);
139                        }
140                        const T held;
141                };
142                placeholder *m_content;
143        };
144
145        inline void swap( any& lhs, any& rhs )
146        {
147                lhs.swap(rhs);
148        }
149
150        template< typename T >
151        T any_cast( const any& operand )
152        {
153                const T* result = operand.to_ptr<T>();
154                return result ? *result : throw std::bad_cast();
155        }
156}
157
158#endif // NV_STL_ANY_HH
Note: See TracBrowser for help on using the repository browser.