| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 | #ifndef OPENCV_FLANN_ANY_H_#define OPENCV_FLANN_ANY_H_/* * (C) Copyright Christopher Diggins 2005-2011 * (C) Copyright Pablo Aguilar 2005 * (C) Copyright Kevlin Henney 2001 * * Distributed under the Boost Software License, Version 1.0. (See * accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt * * Adapted for FLANN by Marius Muja */#include "defines.h"#include <stdexcept>#include <ostream>#include <typeinfo>namespace cvflann{namespace anyimpl{struct bad_any_cast{};struct empty_any{};inline std::ostream& operator <<(std::ostream& out, const empty_any&){    out << "[empty_any]";    return out;}struct base_any_policy{    virtual void static_delete(void** x) = 0;    virtual void copy_from_value(void const* src, void** dest) = 0;    virtual void clone(void* const* src, void** dest) = 0;    virtual void move(void* const* src, void** dest) = 0;    virtual void* get_value(void** src) = 0;    virtual const void* get_value(void* const * src) = 0;    virtual ::size_t get_size() = 0;    virtual const std::type_info& type() = 0;    virtual void print(std::ostream& out, void* const* src) = 0;    virtual ~base_any_policy() {}};template<typename T>struct typed_base_any_policy : base_any_policy{    virtual ::size_t get_size() { return sizeof(T); }    virtual const std::type_info& type() { return typeid(T); }};template<typename T>struct small_any_policy : typed_base_any_policy<T>{    virtual void static_delete(void**) { }    virtual void copy_from_value(void const* src, void** dest)    {        new (dest) T(* reinterpret_cast<T const*>(src));    }    virtual void clone(void* const* src, void** dest) { *dest = *src; }    virtual void move(void* const* src, void** dest) { *dest = *src; }    virtual void* get_value(void** src) { return reinterpret_cast<void*>(src); }    virtual const void* get_value(void* const * src) { return reinterpret_cast<const void*>(src); }    virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(src); }};template<typename T>struct big_any_policy : typed_base_any_policy<T>{    virtual void static_delete(void** x)    {        if (* x) delete (* reinterpret_cast<T**>(x));        *x = NULL;    }    virtual void copy_from_value(void const* src, void** dest)    {        *dest = new T(*reinterpret_cast<T const*>(src));    }    virtual void clone(void* const* src, void** dest)    {        *dest = new T(**reinterpret_cast<T* const*>(src));    }    virtual void move(void* const* src, void** dest)    {        (*reinterpret_cast<T**>(dest))->~T();        **reinterpret_cast<T**>(dest) = **reinterpret_cast<T* const*>(src);    }    virtual void* get_value(void** src) { return *src; }    virtual const void* get_value(void* const * src) { return *src; }    virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast<T const*>(*src); }};template<> inline void big_any_policy<flann_centers_init_t>::print(std::ostream& out, void* const* src){    out << int(*reinterpret_cast<flann_centers_init_t const*>(*src));}template<> inline void big_any_policy<flann_algorithm_t>::print(std::ostream& out, void* const* src){    out << int(*reinterpret_cast<flann_algorithm_t const*>(*src));}template<> inline void big_any_policy<cv::String>::print(std::ostream& out, void* const* src){    out << (*reinterpret_cast<cv::String const*>(*src)).c_str();}template<typename T>struct choose_policy{    typedef big_any_policy<T> type;};template<typename T>struct choose_policy<T*>{    typedef small_any_policy<T*> type;};struct any;/// Choosing the policy for an any type is illegal, but should never happen./// This is designed to throw a compiler error.template<>struct choose_policy<any>{    typedef void type;};/// Specializations for small types.#define SMALL_POLICY(TYPE) \    template<> \    struct choose_policy<TYPE> { typedef small_any_policy<TYPE> type; \    }SMALL_POLICY(signed char);SMALL_POLICY(unsigned char);SMALL_POLICY(signed short);SMALL_POLICY(unsigned short);SMALL_POLICY(signed int);SMALL_POLICY(unsigned int);SMALL_POLICY(signed long);SMALL_POLICY(unsigned long);SMALL_POLICY(float);SMALL_POLICY(bool);#undef SMALL_POLICYtemplate <typename T>class SinglePolicy{    SinglePolicy();    SinglePolicy(const SinglePolicy& other);    SinglePolicy& operator=(const SinglePolicy& other);public:    static base_any_policy* get_policy();private:    static typename choose_policy<T>::type policy;};template <typename T>typename choose_policy<T>::type SinglePolicy<T>::policy;/// This function will return a different policy for each type.template <typename T>inline base_any_policy* SinglePolicy<T>::get_policy() { return &policy; }} // namespace anyimplstruct any{private:    // fields    anyimpl::base_any_policy* policy;    void* object;public:    /// Initializing constructor.    template <typename T>    any(const T& x)        : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)    {        assign(x);    }    /// Empty constructor.    any()        : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)    { }    /// Special initializing constructor for string literals.    any(const char* x)        : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)    {        assign(x);    }    /// Copy constructor.    any(const any& x)        : policy(anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy()), object(NULL)    {        assign(x);    }    /// Destructor.    ~any()    {        policy->static_delete(&object);    }    /// Assignment function from another any.    any& assign(const any& x)    {        reset();        policy = x.policy;        policy->clone(&x.object, &object);        return *this;    }    /// Assignment function.    template <typename T>    any& assign(const T& x)    {        reset();        policy = anyimpl::SinglePolicy<T>::get_policy();        policy->copy_from_value(&x, &object);        return *this;    }    /// Assignment operator.    template<typename T>    any& operator=(const T& x)    {        return assign(x);    }    /// Assignment operator. Template-based version above doesn't work as expected. We need regular assignment operator here.    any& operator=(const any& x)    {        return assign(x);    }    /// Assignment operator, specialed for literal strings.    /// They have types like const char [6] which don't work as expected.    any& operator=(const char* x)    {        return assign(x);    }    /// Utility functions    any& swap(any& x)    {        std::swap(policy, x.policy);        std::swap(object, x.object);        return *this;    }    /// Cast operator. You can only cast to the original type.    template<typename T>    T& cast()    {        if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();        T* r = reinterpret_cast<T*>(policy->get_value(&object));        return *r;    }    /// Cast operator. You can only cast to the original type.    template<typename T>    const T& cast() const    {        if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();        const T* r = reinterpret_cast<const T*>(policy->get_value(&object));        return *r;    }    /// Returns true if the any contains no value.    bool empty() const    {        return policy->type() == typeid(anyimpl::empty_any);    }    /// Frees any allocated memory, and sets the value to NULL.    void reset()    {        policy->static_delete(&object);        policy = anyimpl::SinglePolicy<anyimpl::empty_any>::get_policy();    }    /// Returns true if the two types are the same.    bool compatible(const any& x) const    {        return policy->type() == x.policy->type();    }    /// Returns if the type is compatible with the policy    template<typename T>    bool has_type()    {        return policy->type() == typeid(T);    }    const std::type_info& type() const    {        return policy->type();    }    friend std::ostream& operator <<(std::ostream& out, const any& any_val);};inline std::ostream& operator <<(std::ostream& out, const any& any_val){    any_val.policy->print(out,&any_val.object);    return out;}}#endif // OPENCV_FLANN_ANY_H_
 |