00001 /* 00002 * PROPRIETARY INFORMATION. This software is proprietary to 00003 * Side Effects Software Inc., and is not to be reproduced, 00004 * transmitted, or disclosed in any way without written permission. 00005 * 00006 * Produced by: 00007 * Side Effects Software Inc 00008 * 123 Front Street West, Suite 1401 00009 * Toronto, Ontario 00010 * Canada M5J 2M2 00011 * 416-504-9876 00012 * 00013 * COMMENTS: 00014 * This file defines a number of functions named UTlhsTuple() (tuples 00015 * that are valid left hand sides in assignments). These functions 00016 * are inspired by python, where it's very easy to return multiple values 00017 * from a function: 00018 * 00019 * def foo(): 00020 * return ([0, 1, 2], 6) 00021 * 00022 * (a, b) = foo() 00023 * ...do something with a and b... 00024 * 00025 * The C++ equivalent works with boost tuples, and looks like: 00026 * 00027 * static boost::tuple<UT_Vector3, int> foo() 00028 * { return boost::make_tuple(UT_Vector3(0, 1, 2), 6); } 00029 * 00030 * UT_Vector3 a; 00031 * int b; 00032 * UTlhsTuple(a, b) = foo(); 00033 * ...do something with a and b... 00034 * 00035 * One handy use of these functions is when you want to pass multiple 00036 * values into a callback function that takes a void *. Instead of 00037 * creating a struct to hold the values, pass in a pointer to a 00038 * boost::tuple: 00039 * void iterateOverSomething( 00040 * void (*callback)(void *), void *callback_data)); 00041 * 00042 * static void my_callback(void *data) 00043 * { 00044 * UT_Vector3 a; 00045 * int b; 00046 * UTlhsTuple(a, b) = *(boost::tuple<UT_Vector3, int>*)data; 00047 * ...do something with a and b... 00048 * } 00049 * 00050 * boost::tuple<UT_Vector3, int> data(UT_Vector3(1,2,3), 4); 00051 * iterateOverSomething(my_callback, &data); 00052 */ 00053 00054 #ifndef BOOST_PP_IS_ITERATING 00055 #ifndef __UT_LHSTuple_h__ 00056 #define __UT_LHSTuple_h__ 00057 00058 #include <boost/preprocessor/repetition.hpp> 00059 #include <boost/preprocessor/iteration/iterate.hpp> 00060 #include <boost/preprocessor/punctuation/comma_if.hpp> 00061 #include <boost/preprocessor/arithmetic/sub.hpp> 00062 #include <boost/preprocessor/comparison/less.hpp> 00063 #include <boost/preprocessor/repetition/enum_params.hpp> 00064 #include <boost/preprocessor/repetition/enum_binary_params.hpp> 00065 00066 #include <boost/tuple/tuple.hpp> 00067 00068 // Including BOOST_PP_ITERATE() will make this file get included again 00069 // over and over, with BOOST_PP_IS_ITERATING set and BOOST_PP_ITERATION() 00070 // set to a different value each time. 00071 // 00072 // We need to use different includes depending on whether we're being 00073 // included from UT or not. 00074 #define BOOST_PP_ITERATION_LIMITS (2, 10) 00075 #ifdef EXPORT_UT 00076 #define BOOST_PP_FILENAME_1 "UT_LHSTuple.h" 00077 #else 00078 #define BOOST_PP_FILENAME_1 <UT/UT_LHSTuple.h> 00079 #endif 00080 #include BOOST_PP_ITERATE() 00081 00082 #endif // __UT_LHSTuple_h__ 00083 00084 00085 #else // BOOST_PP_IS_ITERATING 00086 00087 00088 #define n BOOST_PP_ITERATION() 00089 00090 // This macro creates output of the form: 00091 // T1&, T2&, T3& 00092 #define TYPE_REF_LIST(z, num, p) T ## num & \ 00093 BOOST_PP_COMMA_IF(BOOST_PP_LESS(num, BOOST_PP_SUB(n, 1))) 00094 00095 // This macro creates output of the form: 00096 // boost::ref(parm1), boost::ref(parm2), boost::ref(parm3) 00097 // boost::ref ensures that make_tuple creates a tuple of references. 00098 #define PARAMS_AS_REF_LIST(z, num, p) boost::ref(parm ## num) \ 00099 BOOST_PP_COMMA_IF(BOOST_PP_LESS(num, BOOST_PP_SUB(n, 1))) 00100 00101 // Overload a function named UTlhsTuple() that takes different numbers of 00102 // arguments of any type and returns a boost::tuple of references to the 00103 // parameters passed it. You can then assign another tuple to the return 00104 // value of this function, causing it to assign to each of the variables 00105 // that were passed into the function. 00106 template <BOOST_PP_ENUM_PARAMS(n, typename T)> 00107 boost::tuple<BOOST_PP_REPEAT(n, TYPE_REF_LIST, _)> 00108 UTlhsTuple(BOOST_PP_ENUM_BINARY_PARAMS(n, T, &parm)) 00109 { 00110 return boost::make_tuple(BOOST_PP_REPEAT(n, PARAMS_AS_REF_LIST, _)); 00111 } 00112 00113 #undef TYPE_REF_LIST 00114 #undef PARAMS_AS_REF_LIST 00115 #undef n 00116 00117 #endif // BOOST_PP_IS_ITERATING
1.5.9