/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield 
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * OpenSceneGraph Public License for more details.
*/
//osgIntrospection - Copyright (C) 2005 Marco Jez

#ifndef OSGINTROSPECTION_INSTANCECREATOR_
#define OSGINTROSPECTION_INSTANCECREATOR_

#include <osgIntrospection/Value>
#include <osgIntrospection/variant_cast>

namespace osgIntrospection
{

    /// The ObjectInstanceCreator struct template is a collection of 
    /// static methods that provide the means for creating instances
    /// of object types dynamically. Such methods are usually called
    /// from within TypedConstructorInfo{n}::createInstance().    
    template<typename T>
    struct ObjectInstanceCreator
    {
        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12, typename P13, typename P14, typename P15>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9, Value& a10, Value& a11, Value& a12, Value& a13, Value& a14, Value& a15)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9), variant_cast<P10>(a10), variant_cast<P11>(a11), variant_cast<P12>(a12), variant_cast<P13>(a13), variant_cast<P14>(a14), variant_cast<P15>(a15));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12, typename P13, typename P14>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9, Value& a10, Value& a11, Value& a12, Value& a13, Value& a14)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9), variant_cast<P10>(a10), variant_cast<P11>(a11), variant_cast<P12>(a12), variant_cast<P13>(a13), variant_cast<P14>(a14));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12, typename P13>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9, Value& a10, Value& a11, Value& a12, Value& a13)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9), variant_cast<P10>(a10), variant_cast<P11>(a11), variant_cast<P12>(a12), variant_cast<P13>(a13));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9, Value& a10, Value& a11, Value& a12)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9), variant_cast<P10>(a10), variant_cast<P11>(a11), variant_cast<P12>(a12));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9, Value& a10, Value& a11)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9), variant_cast<P10>(a10), variant_cast<P11>(a11));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9, Value& a10)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9), variant_cast<P10>(a10));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4));
        }

        template<typename P0, typename P1, typename P2, typename P3>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3));
        }

        template<typename P0, typename P1, typename P2>
        static Value create(Value& a0, Value& a1, Value& a2)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2));
        }

        template<typename P0, typename P1>
        static Value create(Value& a0, Value& a1)
        {
            return new T(variant_cast<P0>(a0), variant_cast<P1>(a1));
        }

        template<typename P0>
        static Value create(Value& a0)
        {
            return new T(variant_cast<P0>(a0));
        }

        static Value create()
        {
            return new T();
        }

    };

    template<typename T>
    struct ValueInstanceCreator
    {
        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12, typename P13, typename P14, typename P15>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9, Value& a10, Value& a11, Value& a12, Value& a13, Value& a14, Value& a15)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9), variant_cast<P10>(a10), variant_cast<P11>(a11), variant_cast<P12>(a12), variant_cast<P13>(a13), variant_cast<P14>(a14), variant_cast<P15>(a15));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12, typename P13, typename P14>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9, Value& a10, Value& a11, Value& a12, Value& a13, Value& a14)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9), variant_cast<P10>(a10), variant_cast<P11>(a11), variant_cast<P12>(a12), variant_cast<P13>(a13), variant_cast<P14>(a14));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12, typename P13>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9, Value& a10, Value& a11, Value& a12, Value& a13)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9), variant_cast<P10>(a10), variant_cast<P11>(a11), variant_cast<P12>(a12), variant_cast<P13>(a13));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9, Value& a10, Value& a11, Value& a12)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9), variant_cast<P10>(a10), variant_cast<P11>(a11), variant_cast<P12>(a12));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9, Value& a10, Value& a11)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9), variant_cast<P10>(a10), variant_cast<P11>(a11));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9, Value& a10)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9), variant_cast<P10>(a10));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8, Value& a9)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8), variant_cast<P9>(a9));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7, Value& a8)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7), variant_cast<P8>(a8));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6, Value& a7)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6), variant_cast<P7>(a7));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5, Value& a6)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5), variant_cast<P6>(a6));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4, Value& a5)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4), variant_cast<P5>(a5));
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3, Value& a4)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3), variant_cast<P4>(a4));
        }

        template<typename P0, typename P1, typename P2, typename P3>
        static Value create(Value& a0, Value& a1, Value& a2, Value& a3)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2), variant_cast<P3>(a3));
        }

        template<typename P0, typename P1, typename P2>
        static Value create(Value& a0, Value& a1, Value& a2)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1), variant_cast<P2>(a2));
        }

        template<typename P0, typename P1>
        static Value create(Value& a0, Value& a1)
        {
            return T(variant_cast<P0>(a0), variant_cast<P1>(a1));
        }

        template<typename P0>
        static Value create(Value& a0)
        {
            return T(variant_cast<P0>(a0));
        }

        static Value create()
        {
            return T();
        }

    };

    template<typename T>
    struct DummyInstanceCreator
    {
        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12, typename P13, typename P14, typename P15>
        static Value create(Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12, typename P13, typename P14>
        static Value create(Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12, typename P13>
        static Value create(Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12>
        static Value create(Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11>
        static Value create(Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
        static Value create(Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
        static Value create(Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
        static Value create(Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
        static Value create(Value& , Value& , Value& , Value& , Value& , Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
        static Value create(Value& , Value& , Value& , Value& , Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
        static Value create(Value& , Value& , Value& , Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1, typename P2, typename P3, typename P4>
        static Value create(Value& , Value& , Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1, typename P2, typename P3>
        static Value create(Value& , Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1, typename P2>
        static Value create(Value& , Value& , Value& )
        {
            return Value();
        }

        template<typename P0, typename P1>
        static Value create(Value& , Value& )
        {
            return Value();
        }

        template<typename P0>
        static Value create(Value& )
        {
            return Value();
        }

        static Value create()
        {
            return Value();
        }

    };


}

#endif
