Angus Leeming <[EMAIL PROTECTED]> writes:

| Attached is a simple sample showing how I could use boost::any to implement 
| the transformation stuff in InsetExternal.

I do not agree with how you use operatesOn. 

|       template<typename Factory, typename Data>
|       TransformCommand::ptr_type
|       getTransformer(Data const & data) const {
|               TransformCommand::ptr_type ptr;
|
|               if (operatesOn(data)) {
|                       Factory factory = boost::any_cast<Factory>(value);
|                       ptr = factory(data);
|               }
|
|               return ptr;
|       }

IMHO you should do the try/catch right there in getTransformer, no
 need to do the any_cast twice.

        template<typename Factory, typename Data>
        TransformCommand::ptr_type
        getTransformer(Data const & data) const {
                TransformCommand::ptr_type ptr;

                try {
                    Factory factor = boost::any_cast<Factory>(value);
                    ptr = factory(data);
                }
                catch (boost::bad_any_cast const &) {
                }
                return ptr;
        }

Of course this functions really should just throw if wrong factory is
 used, and not return a empty ptr in that case:

        template<typename Factory, typename Data>
        TransformCommand::ptr_type
        getTransformer(Data const & data) const {
                TransformCommand::ptr_type ptr;
                Factory factor = boost::any_cast<Factory>(value);
                return factory(data);
        }

And the caller should handle the try and catch.
(getTransformer could catch the exception, but should rethrow it (as
another type perhaps).

| I think it results in very elegant code, but the killer is the try,catch 
| block. The block is needed, so I guess that this means I cannot use the 
| appropach within lyx?

If we all agree that we want to use exceptions, I am all for it.
But that is up to the rest of you.

| // This loop is all that needs go in insetexternal.C
| int main()
| {
|       std::vector<TransformStore> factories;
|       build(factories);
>
|       RotationData rotationdata(30);
|       ResizeData resizedata(2);
>
|       string command = "\\input{foo}";
>
|       std::vector<TransformStore>::const_iterator it  = factories.begin();
|       std::vector<TransformStore>::const_iterator end = factories.end();
|       for (; it != end; ++it) {
|               TransformCommand::ptr_type ptr;
|               ptr = it->getTransformer<RotationFactory>(rotationdata);
|               if (!ptr.get())
|                       ptr = it->getTransformer<ResizeFactory>(resizedata);
|               
|               if (ptr.get() == 0)
|                       continue;
>
|               std::ostringstream os;
|               os << ptr->front() << command <<  ptr->back();
|               command = os.str();
|       }
>
|       std::cout << command << std::endl;
| }

       for (; it != end; ++it) {
           TransformCommand::ptr_type ptr;
           try {
               ptr =
               it->getTransformer<RotationFactory>(rotationdata);
           }
           catch (...) {
                  try {
                         ptr =
                         it->getTransformer<ResizeFactory>(resizedata);
                  }
                  catch (...) {
                         continue;
                  }
           }
           std::ostringstream os;
           os << ptr->front() << command <<  ptr->back();
           command = os.str();
       }


But I would rewrite a bit further to make it even simpler...

-- 
        Lgb

Reply via email to