0001:
0002:
0003:
0004:
0005:
0006:
0007:
0008:
0009:
0010:
0011:
0012:
0013:
0014:
0015:
0016:
0017:
0018:
0019:
0020:
0021:
0022:
0023:
0024:
0025:
0026:
0027:
0028:
0029:
0030:
0031:
0032:
0033:
0034:
0035:
0036:
0037:
0038:
0039:
0040:
0041:
0042:
0043:
0044:
0045:
0046:
0047:
0048:
0049:
0050:
0051:
0052:
0053:
0054:
0055:
0056:
0057:
0058:
0059:
0060:
0061:
0062:
0063:
0064:
0065:
0066:
0067:
0068:
0069:
0070:
0071:
0072:
0073:
0074:
0075:
0076:
0077:
0078:
0079:
0080:
0081:
0082:
0083:
0084:
0085:
0086:
0087:
0088:
0089:
0090:
0091:
0092:
0093:
0094:
0095:
0096:
0097:
0098:
0099:
0100:
0101:
0102:
0103:
0104:
0105:
0106:
0107:
0108:
0109:
0110:
0111:
0112:
0113:
0114:
0115:
0116:
0117:
0118:
0119:
0120:
0121:
0122:
0123:
0124:
0125:
0126:
0127:
0128:
0129:
0130:
0131:
0132:
0133:
0134:
0135:
0136:
0137:
0138:
0139:
0140:
0141:
0142:
0143:
0144:
0145:
0146:
0147:
0148:
0149:
0150:
0151:
0152:
0153:
0154:
0155:
0156:
0157:
0158:
0159:
0160:
0161:
0162:
0163:
0164:
0165:
0166:
0167:
0168:
0169:
0170:
0171:
0172:
0173:
0174:
0175:
0176:
0177:
0178:
0179:
0180:
0181:
0182:
0183:
0184:
0185:
0186:
0187:
0188:
0189:
0190:
0191:
0192:
0193:
0194:
0195:
0196:
0197:
0198:
0199:
0200:
0201:
0202:
0203:
0204:
0205:
0206:
0207:
0208:
0209:
0210:
0211:
0212:
0213:
0214:
0215:
0216:
0217:
0218:
0219:
0220:
0221:
0222:
0223:
0224:
0225:
0226:
0227:
0228:
0229:
0230:
0231:
0232:
0233:
0234:
0235:
0236:
0237:
0238:
0239:
0240:
0241:
0242:
0243:
0244:
0245:
0246:
0247:
0248:
0249:
0250:
0251:
0252:
0253:
0254:
0255:
0256:
0257:
0258:
0259:
0260:
0261:
0262:
0263:
0264:
0265:
0266:
0267:
0268:
0269:
0270:
0271:
0272:
0273:
0274:
0275:
0276:
0277:
0278:
0279:
0280:
0281:
0282:
0283:
0284:
0285:
0286:
0287:
0288:
0289:
0290:
0291:
0292:
0293:
0294:
0295:
0296:
0297:
0298:
0299:
0300:
0301:
0302:
0303:
0304:
0305:
0306:
0307:
0308:
0309:
0310:
0311:
0312:
0313:
0314:
0315:
0316:
0317:
0318:
0319:
0320:
0321:
0322:
0323:
0324:
0325:
0326:
0327:
0328:
0329:
0330:
0331:
0332:
0333:
0334:
0335:
0336:
0337:
0338:
0339:
0340:
0341:
0342:
0343:
0344:
0345:
0346:
0347:
0348:
0349:
0350:
0351:
0352:
0353:
0354:
0355:
0356:
0357:
0358:
0359:
0360:
0361:
0362:
0363:
0364:
0365:
0366:
0367:
0368:
0369:
0370:
0371:
0372:
0373:
0374:
0375:
0376:
0377:
0378:
0379:
0380:
0381:
0382:
0383:
0384:
0385:
0386:
0387:
0388:
0389:
0390:
0391:
0392:
0393:
0394:
0395:
0396:
0397:
0398:
0399:
0400:
0401:
0402:
0403:
0404:
0405:
0406:
0407:
0408:
0409:
0410:
0411:
0412:
0413:
0414:
0415:
0416:
0417:
0418:
0419:
0420:
0421:
0422:
0423:
0424:
0425:
0426:
0427:
0428:
0429:
0430:
0431:
0432:
0433:
0434:
0435:
0436:
0437:
0438:
0439:
0440:
0441:
0442:
0443:
0444:
0445:
0446:
0447:
0448:
0449:
0450:
0451:
0452:
0453:
0454:
0455:
0456:
0457:
0458:
0459:
0460:
0461:
0462:
0463:
0464:
0465:
0466:
0467:
0468:
0469:
0470:
0471:
0472:
0473:
0474:
0475:
0476:
0477:
0478:
0479:
0480:
0481:
0482:
0483:
0484:
0485:
0486:
0487:
0488:
0489:
0490:
0491:
0492:
0493:
0494:
0495:
0496:
0497:
0498:
0499:
0500:
0501:
0502:
0503:
0504:
0505:
0506:
0507:
0508:
0509:
0510:
0511:
0512:
0513:
0514:
0515:
0516:
0517:
0518:
0519:
0520:
0521:
0522:
0523:
0524:
0525:
0526:
0527:
0528:
0529:
0530:
0531:
0532:
0533:
0534:
0535:
0536:
0537:
0538:
0539:
0540:
0541:
0542:
0543:
0544:
0545:
0546:
0547:
0548:
0549:
0550:
0551:
0552:
0553:
0554:
0555:
0556:
0557:
0558:
0559:
0560:
0561:
0562:
0563:
0564:
0565:
0566:
0567:
0568:
0569:
0570:
0571:
0572:
0573:
0574:
0575:
0576:
0577:
0578:
0579:
0580:
0581:
0582:
0583:
0584:
0585:
0586:
0587:
0588:
0589:
0590:
0591:
0592:
0593:
0594:
0595:
0596:
0597:
0598:
0599:
0600:
0601:
0602:
0603:
0604:
0605:
0606:
0607:
0608:
0609:
0610:
0611:
0612:
0613:
0614:
0615:
0616:
0617:
0618:
0619:
0620:
0621:
0622:
0623:
0624:
0625:
0626:
0627:
0628:
0629:
0630:
0631:
0632:
0633:
0634:
0635:
0636:
0637:
0638:
0639:
0640:
0641:
0642:
0643:
0644:
0645:
0646:
0647:
0648:
0649:
0650:
0651:
0652:
0653:
0654:
0655:
0656:
0657:
0658:
0659:
0660:
0661:
0662:
0663:
0664:
0665:
0666:
0667:
0668:
0669:
0670:
0671:
0672:
0673:
0674:
0675:
0676:
0677:
0678:
0679:
0680:
0681:
0682:
0683:
0684:
0685:
0686:
0687:
0688:
0689:
0690:
0691:
0692:
0693:
0694:
0695:
0696:
0697:
0698:
0699:
0700:
0701:
0702:
0703:
0704:
0705:
0706:
0707:
0708:
0709:
0710:
0711:
0712:
0713:
0714:
0715:
0716:
0717:
0718:
0719:
0720:
0721:
0722:
0723:
0724:
0725:
0726:
0727:
0728:
0729:
0730:
0731:
0732:
0733:
0734:
0735:
0736:
0737:
0738:
0739:
0740:
0741:
0742:
0743:
0744:
0745:
0746:
0747:
0748:
0749:
0750:
0751:
0752:
0753:
0754:
0755:
0756:
0757:
0758:
0759:
0760:
0761:
0762:
0763:
0764:
0765:
0766:
0767:
0768:
0769:
0770:
0771:
0772:
0773:
0774:
0775:
0776:
0777:
0778:
0779:
0780:
0781:
0782:
0783:
0784:
0785:
0786:
0787:
0788:
0789:
0790:
0791:
0792:
0793:
0794:
0795:
0796:
0797:
0798:
0799:
0800:
0801:
0802:
0803:
0804:
0805:
0806:
0807:
0808:
0809:
0810:
0811:
0812:
0813:
0814:
0815:
0816:
0817:
0818:
0819:
0820:
0821:
0822:
0823:
0824:
0825:
0826:
0827:
0828:
0829:
0830:
0831:
0832:
0833:
0834:
0835:
0836:
0837:
0838:
0839:
0840:
0841:
0842:
0843:
0844:
0845:
0846:
0847:
0848:
0849:
0850:
0851:
0852:
0853:
0854:
0855:
0856:
0857:
0858:
0859:
0860:
0861:
0862:
0863:
0864:
0865:
0866:
0867:
0868:
0869:
0870:
0871:
0872:
0873:
0874:
0875:
0876:
0877:
0878:
0879:
0880:
0881:
0882:
0883:
0884:
0885:
0886:
0887:
0888:
0889:
0890:
0891:
0892:
0893:
0894:
0895:
0896:
0897:
0898:
0899:
0900:
0901:
0902:
0903:
0904:
0905:
0906:
0907:
0908:
0909:
0910:
0911:
0912:
0913:
0914:
0915:
0916:
0917:
0918:
0919:
0920:
0921:
0922:
0923:
0924:
0925:
0926:
0927:
0928:
0929:
0930:
0931:
0932:
0933:
0934:
0935:
0936:
0937:
0938:
0939:
0940:
0941:
0942:
0943:
0944:
0945:
0946:
0947:
0948:
0949:
0950:
0951:
0952:
0953:
0954:
0955:
0956:
0957:
0958:
0959:
0960:
0961:
0962:
0963:
0964:
0965:
0966:
0967:
0968:
0969:
0970:
0971:
0972:
0973:
0974:
0975:
0976:
0977:
0978:
0979:
0980:
0981:
0982:
0983:
0984:
0985:
0986:
0987:
0988:
0989:
0990:
0991:
0992:
0993:
0994:
0995:
0996:
0997:
0998:
0999:
1000:
1001:
1002:
1003:
1004:
1005:
1006:
1007:
1008:
1009:
1010:
1011:
1012:
1013:
1014:
1015:
1016:
1017:
1018:
1019:
1020:
1021:
1022:
1023:
1024:
1025:
1026:
1027:
1028:
1029:
1030:
1031:
1032:
1033:
1034:
1035:
1036:
1037:
1038:
1039:
1040:
1041:
1042:
1043:
1044:
1045:
1046:
1047:
1048:
1049:
1050:
1051:
1052:
1053:
1054:
1055:
1056:
1057:
1058:
1059:
1060:
1061:
1062:
1063:
1064:
1065:
1066:
1067:
1068:
1069:
1070:
1071:
1072:
1073:
1074:
1075:
1076:
1077:
1078:
1079:
1080:
1081:
1082:
1083:
1084:
1085:
1086:
1087:
1088:
1089:
1090:
1091:
1092:
1093:
1094:
1095:
1096:
1097:
1098:
1099:
1100:
1101:
1102:
1103:
1104:
1105:
1106:
1107:
1108:
1109:
1110:
1111:
1112:
1113:
1114:
1115:
1116:
1117:
1118:
1119:
1120:
1121:
1122:
1123:
1124:
1125:
1126:
1127:
1128:
1129:
1130:
1131:
1132:
1133:
1134:
1135:
1136:
1137:
1138:
1139:
1140:
1141:
1142:
1143:
1144:
1145:
1146:
1147:
1148:
1149:
1150:
1151:
1152:
1153:
1154:
1155:
1156:
1157:
1158:
1159:
1160:
1161:
1162:
1163:
1164:
1165:
1166:
1167:
1168:
1169:
1170:
1171:
1172:
1173:
1174:
1175:
1176:
1177:
1178:
1179:
1180:
1181:
1182:
1183:
1184:
1185:
1186:
1187:
1188:
1189:
1190:
1191:
1192:
1193:
1194:
1195:
1196:
1197:
1198:
1199:
1200:
1201:
1202:
1203:
1204:
1205:
1206:
1207:
1208:
1209:
1210:
1211:
1212:
1213:
1214:
1215:
1216:
1217:
1218:
1219:
1220:
1221:
1222:
1223:
1224:
1225:
1226:
1227:
1228:
1229:
1230:
1231:
1232:
1233:
1234:
1235:
1236:
1237:
1238:
1239:
1240:
1241:
1242:
1243:
1244:
1245:
1246:
1247:
1248:
1249:
1250:
1251:
1252:
1253:
1254:
1255:
1256:
1257:
1258:
1259:
1260:
1261:
1262:
1263:
1264:
1265:
1266:
1267:
1268:
1269:
1270:
1271:
1272:
1273:
1274:
1275:
1276:
1277:
1278:
1279:
1280:
1281:
1282:
1283:
1284:
1285:
1286:
1287:
1288:
1289:
1290:
1291:
1292:
1293:
1294:
1295:
1296:
1297:
1298:
1299:
1300:
1301:
1302:
1303:
1304:
1305:
1306:
1307:
1308:
1309:
1310:
1311:
1312:
1313:
1314:
1315:
1316:
1317:
1318:
1319:
1320:
1321:
1322:
1323:
1324:
1325:
1326:
1327:
1328:
1329:
1330:
1331:
1332:
1333:
1334:
1335:
1336:
1337:
1338:
1339:
1340:
1341:
1342:
1343:
1344:
1345:
1346:
1347:
1348:
1349:
1350:
1351:
1352:
1353:
1354:
1355:
1356:
1357:
1358:
1359:
1360:
1361:
1362:
1363:
1364:
1365:
1366:
1367:
1368:
1369:
1370:
1371:
1372:
1373:
1374:
1375:
1376:
1377:
1378:
1379:
1380:
1381:
1382:
1383:
1384:
1385:
1386:
1387:











































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































/*
* This file is part of the Omni C++ framework
*
* Copyright (c) 2016, Zeriph Enterprises, LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of Zeriph, Zeriph Enterprises, LLC, nor the names
* of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ZERIPH AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ZERIPH AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(OMNI_DELEGATE16_HPP)
#define OMNI_DELEGATE16_HPP 1
#include <omni/defs/delegate_def.hpp>
#include <omni/types/invoke_t.hpp>

namespace omni {
    /**
     * The delegate is a powerful function pointer object that
     * encapsulates both an object instance and a method. The delegate is
     * agnostic to the type or method it encapsulates; all that matters is that
     * the method be signature compatible with the delegate. This allows for
     * 'anonymous' invocation by users of the delegate.
     *
     * @tparam Ret     Specifies the return type of the function the delegate is to attach to
     * @tparam PT1     Specifies the 1st parameter type passed to the function delegate
     * @tparam PT2     Specifies the 2nd parameter type passed to the function delegate
     * @tparam PT3     Specifies the 3rd parameter type passed to the function delegate
     * @tparam PT4     Specifies the 4th parameter type passed to the function delegate
     * @tparam PT5     Specifies the 5th parameter type passed to the function delegate
     * @tparam PT6     Specifies the 6th parameter type passed to the function delegate
     * @tparam PT7     Specifies the 7th parameter type passed to the function delegate
     * @tparam PT8     Specifies the 8th parameter type passed to the function delegate
     * @tparam PT9     Specifies the 9th parameter type passed to the function delegate
     * @tparam PT10     Specifies the 10th parameter type passed to the function delegate
     * @tparam PT11     Specifies the 11th parameter type passed to the function delegate
     * @tparam PT12     Specifies the 12th parameter type passed to the function delegate
     * @tparam PT13     Specifies the 13th parameter type passed to the function delegate
     * @tparam PT14     Specifies the 14th parameter type passed to the function delegate
     * @tparam PT15     Specifies the 15th parameter type passed to the function delegate
     * @tparam PT16     Specifies the 16th parameter type passed to the function delegate
     */
    template < typename Ret, typename PT1, typename PT2, typename PT3, typename PT4, typename PT5, typename PT6, typename PT7, typename PT8, typename PT9, typename PT10, typename PT11, typename PT12, typename PT13, typename PT14, typename PT15, typename PT16 >
    class delegate16
    {
        public:
            /** Defines the return type this delegate will represent */
            typedef Ret ret_t;
            /** Defines the 1st function parameter type of this delegate */
            typedef PT1 p1_t;
            /** Defines the 2nd function parameter type of this delegate */
            typedef PT2 p2_t;
            /** Defines the 3rd function parameter type of this delegate */
            typedef PT3 p3_t;
            /** Defines the 4th function parameter type of this delegate */
            typedef PT4 p4_t;
            /** Defines the 5th function parameter type of this delegate */
            typedef PT5 p5_t;
            /** Defines the 6th function parameter type of this delegate */
            typedef PT6 p6_t;
            /** Defines the 7th function parameter type of this delegate */
            typedef PT7 p7_t;
            /** Defines the 8th function parameter type of this delegate */
            typedef PT8 p8_t;
            /** Defines the 9th function parameter type of this delegate */
            typedef PT9 p9_t;
            /** Defines the 10th function parameter type of this delegate */
            typedef PT10 p10_t;
            /** Defines the 11th function parameter type of this delegate */
            typedef PT11 p11_t;
            /** Defines the 12th function parameter type of this delegate */
            typedef PT12 p12_t;
            /** Defines the 13th function parameter type of this delegate */
            typedef PT13 p13_t;
            /** Defines the 14th function parameter type of this delegate */
            typedef PT14 p14_t;
            /** Defines the 15th function parameter type of this delegate */
            typedef PT15 p15_t;
            /** Defines the 16th function parameter type of this delegate */
            typedef PT16 p16_t;

            /** Defines the functor signature this delegate will represent */
            typedef ret_t (*functor)(void* extObj, p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13, p14_t val14, p15_t val15, p16_t val16);
            /** Defines the function pointer signature this delegate will represent */
            typedef ret_t (*function_ptr)(p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13, p14_t val14, p15_t val15, p16_t val16);
            
            /**
             * The default constructor; constructs a default delegate
             * object with no function or member attached.
             */
            delegate16() :
                OMNI_SAFE_DGATE_MILST_FW
                m_method(OMNI_NULL),
                m_target(OMNI_NULL)
            {
                OMNI_SAFE_DGATE_INIT_FW
                OMNI_D5_FW("created delegate");
            }
            
            /**
             * The copy constructor; copies another delegates target and method.
             * The delegate being copied must be of the same signature.
             *
             * @param cp    The other delegate to copy
             */
            delegate16(const delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& cp) :
                OMNI_SAFE_DGATE_MILST_FW
                m_method(cp.m_method),
                m_target(cp.m_target)
            {
                OMNI_SAFE_DGATE_INIT_FW
                OMNI_D5_FW("copied delegate");
            }
            
            /**
             * Creates a new instance from a non-member or static member function pointer.
             *
             * @param fnptr The function pointer to attach
             */
            delegate16(function_ptr fnptr) :
                OMNI_SAFE_DGATE_MILST_FW
                m_method(reinterpret_cast<functor>(fnptr)),
                m_target(OMNI_NULL)
            {
                OMNI_SAFE_DGATE_INIT_FW
                OMNI_D5_FW("created delegate with function pointer");
            }
            
            /**
             * Creates a new instance from a functor and object.
             *
             * @param obj The instance of the object to use with this delegate
             * @param mthd The functor of the object to attach to this delegate for invocation
             */
            delegate16(void* obj, functor mthd) :
                OMNI_SAFE_DGATE_MILST_FW
                m_method(mthd),
                m_target(obj)
            {
                OMNI_SAFE_DGATE_INIT_FW
                OMNI_D5_FW("created delegate with target and method");
            }
            
            /** The default destructor, detaches this instance from its target and method */
            ~delegate16()
            {
                OMNI_TRY_FW
                this->unbind();
                OMNI_SAFE_DGATE_DTOR_FW
                OMNI_CATCH_FW
                OMNI_D5_FW("destroyed");
            }

            /**
             * Attach a static member or non-member function to this delegate.
             *
             * @param fnptr The function taking 16 parameters to attach to the delegate
             */
            inline void bond(function_ptr fnptr)
            {
                this->_bind(OMNI_NULL, reinterpret_cast<functor>(fnptr));
            }
            
            /**
             * Attach a static member or non-member function to this delegate.
             *
             * @tparam fnptr The function taking 16 parameters to attach to the delegate
             */
            template < ret_t (*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) >
            inline void bond()
            {
                this->_bind(OMNI_NULL, &_anon_param_fn<fnptr>);
            }
            
            /**
             * Attach a member function to this delegate.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             */
            template < class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) >
            inline void bond(T& obj)
            {
                this->_bind(static_cast<void*>(&obj), &_member_param_fn<T, fnptr>);
            }

            /**
             * Attach a member function to this delegate.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             */
            template < class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) >
            inline void bond(const T& obj)
            {
                this->_bind(static_cast<void*>(const_cast<T*>(&obj)), &_member_param_fn<T, fnptr>);
            }
            
            /**
             * Attach a member function to this delegate.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             */
            template < class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) >
            inline void bond(const T *const obj)
            {
                this->_bind(static_cast<void*>(const_cast<T *const>(obj)), &_member_param_fn<T, fnptr>);
            }

            /**
             * Attach a const member function to this delegate.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The const function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             */
            template < class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) const >
            inline void bond_const(const T& obj)
            {
                this->_bind(static_cast<void*>(const_cast<T*>(&obj)), &_member_param_fn_const<T, fnptr>);
            }
            
            /**
             * Attach a const member function to this delegate.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             */
            template < class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) const >
            inline void bond_const(const T *const obj)
            {
                this->_bind(static_cast<void*>(const_cast<T *const>(obj)), &_member_param_fn_const<T, fnptr>);
            }
            
            /**
             * Attach a static member or non-member function to this delegate.
             *
             * @tparam fnptr The function taking 16 parameters to attach to the delegate
             */
            template < ret_t (*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) >
            static delegate16 bind()
            {
                return delegate16(OMNI_NULL, &_anon_param_fn<fnptr>);
            }
            
            /**
             * Attach a parametrized member function to this delegate.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The parametrized function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             */
            template < class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) >
            static delegate16 bind(T& obj)
            {
                return delegate16(&obj, &_member_param_fn<T, fnptr>);
            }
            
            /**
             * Attach a parametrized member function to this delegate.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The parametrized function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             */
            template < class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) >
            static delegate16 bind(const T& obj)
            {
                return delegate16(const_cast<T *const>(&obj), &_member_param_fn<T, fnptr>);
            }
            
            /**
             * Attach a parametrized member function to this delegate.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The parametrized function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             */
            template < class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) >
            static delegate16 bind(const T *const obj)
            {
                return delegate16(const_cast<T *const>(obj), &_member_param_fn<T, fnptr>);
            }

            /**
             * Attach a const parametrized member function to this delegate.
             *
             * @tparam T         The type of class to associate with this delegate
             * @tparam fnptr     The parametrized function to attach to the delegate
             * @param obj         The instance of the class to reference in this delegate
             */
            template < class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) const >
            static delegate16 bind_const(const T& obj)
            {
                return delegate16(const_cast<T *const>(&obj), &_member_param_fn_const<T, fnptr>);
            }
            
            /**
             * Attach a parametrized member function to this delegate.
             *
             * @tparam T         The type of class to associate with this delegate
             * @tparam fnptr     The parametrized function to attach to the delegate
             * @param obj         The instance of the class to reference in this delegate
             */
            template < class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) const >
            static delegate16 bind_const(const T *const obj)
            {
                return delegate16(const_cast<T *const>(obj), &_member_param_fn_const<T, fnptr>);
            }
            
            /**
             * Gets if this instance is bound to a method
             *
             * @return True if this instance is currently bound
             */
            bool is_bound() const
            {
                OMNI_SAFE_DGATE_ALOCK_FW
                return (this->m_method != OMNI_NULL);
            }
            
            /**
             * Gets if this instance is bound to a member method
             *
             * @return True if this instance is currently bound to a target and method
             */
            bool is_member_bound() const
            {
                OMNI_SAFE_DGATE_ALOCK_FW
                return (this->m_method != OMNI_NULL && this->m_target != OMNI_NULL);
            }
            
            /**
             * Invoke the function bound to this delegate instance
             *
             * @return This function returns whatever is returned
             *         (if anything) from the invoked function
             */
            ret_t invoke(p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13, p14_t val14, p15_t val15, p16_t val16) const
            {
                #if defined(OMNI_SAFE_DELEGATES)
                    omni::sync::mutex_lock(this->m_mtx);
                    if (this->m_method != OMNI_NULL) {
                        if (this->m_target == OMNI_NULL) {
                            function_ptr fp = reinterpret_cast<function_ptr>(this->m_method);
                            omni::sync::mutex_unlock(this->m_mtx);
                            return (*fp)(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16);
                        } else {
                            functor m = this->m_method;
                            void* t = this->m_target;
                            omni::sync::mutex_unlock(this->m_mtx);
                            return (*m)(t, val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16);
                        }
                    }
                    omni::sync::mutex_unlock(this->m_mtx);
                #else
                    return (this->m_target == OMNI_NULL ?
                            (*reinterpret_cast<function_ptr>(this->m_method))(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16) :
                            (*this->m_method)(this->m_target, val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16));
                #endif
                OMNI_ERR_RETV_FW("No valid function has been assigned to the delegate", omni::invalid_delegate(), ret_t())
            }
            
            /**
             * Invoke the function bound to this delegate instance.
             * This method does not preform any safety checks on the
             * method or object instance and directly calls the method
             * for invocation (if bound).
             *
             * @return This function returns whatever is returned
             *         (if anything) from the invoked function
             */
            ret_t invoke_direct(p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13, p14_t val14, p15_t val15, p16_t val16) const
            {
                return (this->m_target == OMNI_NULL ?
                        (*reinterpret_cast<function_ptr>(this->m_method))(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16) :
                        (*this->m_method)(this->m_target, val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16));
            }
            
            /**
             * Gets the invocation type this delegate represents
             *
             * @return The delegates omni::invoke_type::enum_t
             */
            omni::invoke_t invoke_type() const
            {
                OMNI_SAFE_DGATE_ALOCK_FW
                if (this->m_method == OMNI_NULL) { return omni::invoke_type::NONE; }
                return (this->m_target == OMNI_NULL ?
                        omni::invoke_type::ANONYMOUS :
                        omni::invoke_type::MEMBER_FUNC);
            }
            
            /**
             * Gets the underlying functor called when this method is invoked.
             *
             * @return The underlying functor method
             */
            const functor method() const
            {
                OMNI_SAFE_DGATE_ALOCK_FW
                return this->m_method;
            }
            
            /**
             * Gets the underlying function pointer called when this method is invoked.
             *
             * @return The underlying function pointer, or an OMNI_NULL value if the
             * object instance is null;
             */
            const function_ptr function() const
            {
                OMNI_SAFE_DGATE_ALOCK_FW
                return ((this->m_target == OMNI_NULL) ?
                        reinterpret_cast<function_ptr>(this->m_method) : OMNI_NULL);
            }
            
            /**
             * Swaps the invocation method and target of 2 delegates
             */
            void swap(delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& d)
            {
                OMNI_SAFE_DGATE_ALOCK_FW
                #if defined(OMNI_SAFE_DELEGATES)
                    omni::sync::mutex_lock(d.m_mtx);
                #endif
                std::swap(this->m_target, d.m_target);
                std::swap(this->m_method, d.m_method);
                #if defined(OMNI_SAFE_DELEGATES)
                    omni::sync::mutex_unlock(d.m_mtx);
                #endif
            }
            
            /**
             * Gets the underlying target (if any) used when invoking this method.
             *
             * @return A pointer to the underlying target object (if any)
             */
            void *const target() const
            {
                OMNI_SAFE_DGATE_ALOCK_FW
                return this->m_target;
            }
            
            /**
             * Detaches the target and method from this instance
             */
            inline void unbind()
            {
                this->_bind(OMNI_NULL, OMNI_NULL);
                OMNI_D4_FW("instance unbound");
            }
            
            /**
             * Checks if the current delegate instance is valid
             *
             * @return True if the instance has a method attached, false if not
             */
            bool valid() const
            {
                OMNI_SAFE_DGATE_ALOCK_FW
                return (this->m_method != OMNI_NULL);
            }
            
            /**
             * Has the same effect as calling the invoke method.
             * Overloading this operator makes it such that you can
             * use the delegate as if it were a function.
             *
             * delegate<int> d = &some_func;
             * printf("value = %d", d());
             *
             * @return The return type specified at compile time
             */
            inline ret_t operator()(p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13, p14_t val14, p15_t val15, p16_t val16) const
            {
                return this->invoke(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16);
            }
            
            /**
             * The boolean operator allows you to check for validity as if
             * the delegate were a function pointer, example:
             * delegate<int> d;
             * if (d) { d(); } // fails check because d is not attached
             * d = &some_func;
             * if (d) { d(); } // success because d is bound
             *
             * @return True if the delegate is attached
             */
            inline operator bool() const
            {
                return this->valid();
            }
            
            /**
             * The negated boolean () operator is used to check negation of the boolean () operator
             */
            inline bool operator!() const
            {
                return !(this->operator bool());
            }
            
            /**
             * The assignment operator is used to set the target and method
             * of another delegate to this one.
             *
             * @param d        The right most operand which to assign to
             *
             * @return A reference to the current instance
             */
            delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& operator=(const delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& d)
            {
                if (this != &d) {
                    #if defined(OMNI_SAFE_DELEGATES)
                        omni::sync::mutex_lock(d.m_mtx);
                    #endif
                    this->_bind(d.m_target, d.m_method);
                    #if defined(OMNI_SAFE_DELEGATES)
                        omni::sync::mutex_unlock(d.m_mtx);
                    #endif
                }
                return *this;
            }
            
            /**
             * Allows for assignment to anonymous (non-member) functions
             * by saying = &func_name
             *
             * @param fp The function pointer to assign
             *
             * @return A reference to the current instance
             */
            delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& operator=(function_ptr fnptr)
            {
                this->_bind(OMNI_NULL, reinterpret_cast<functor>(fnptr));
                return *this;
            }
            
            /**
             * The equality operator test the target and method against the other
             *
             * @param d        The right most operand which to compare to
             *
             * @return     True if the two instance are equal
             */
            bool operator==(const delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& d) const
            {
                if (this == &d) { return true; }
                OMNI_SAFE_DGATE_ALOCK_FW
                return
                (
                    this->m_target == d.m_target &&
                    this->m_method == d.m_method
                );
            }
            
            /**
             * The != operator is used for comparison results (negates the == operator)
             *
             * @param d        The right most operand which to compare to
             *
             * @return True if the instances are not equal
             */
            bool operator!=(const delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& d) const
            {
                return !(*this == d);
            }
            
        private:
            OMNI_SAFE_DGATE_MTX_FW
            /** The 16 parameter member function to be called */
            functor m_method;
            /** The instance of the object set when attaching to the delegate */
            void* m_target;
            
            /**
             * The internal binding function that sets the underlying method and target
             *
             * @param obj The target to set
             * @param mthd The method to set
             * @param type The type to set
             */
            void _bind(void* obj, functor mthd)
            {
                OMNI_SAFE_DGATE_ALOCK_FW
                this->m_target = obj;
                this->m_method = mthd;
            }
            
            /**
             * Gets the parametrized non member (static/anonymous) function to use
             *
             * @tparam fnptr         The method to assign
             */
            template < ret_t (*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) >
            static ret_t _anon_param_fn(void*, p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13, p14_t val14, p15_t val15, p16_t val16)
            {
                return (fnptr)(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16);
            }
            
            /**
             * Get the parametrized member function to use
             *
             * @tparam T         The class type
             * @tparam fnptr     The parametrized member method to use
             * @param obj         The instance object associated with the member method
             *
             * @return             The functor
             */
            template < class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) >
            static ret_t _member_param_fn(void* obj, p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13, p14_t val14, p15_t val15, p16_t val16)
            {
                return ((static_cast<T*>(obj))->*reinterpret_cast<ret_t (T::*)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t, void*)>(fnptr))(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16, obj);
            }
            
            /**
             * Get the const parametrized member function to use
             *
             * @tparam T         The class type
             * @tparam fnptr     The parametrized member method to use
             * @param obj         The instance object associated with the member method
             *
             * @return             The functor
             */
            template < class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t) const >
            static ret_t _member_param_fn_const(void* obj, p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13, p14_t val14, p15_t val15, p16_t val16)
            {
                return ((static_cast<T*>(obj))->*reinterpret_cast<ret_t (T::*)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t, p14_t, p15_t, p16_t, void*) const>(fnptr))(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16, obj);
            }
    };
    
    /** A generic delegate that has 16 parameters and does not return a value. */
    typedef omni::delegate16<void, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*> callback16;
    
    /**
     * The templated event allows client code to attach multiple delegates
     * and invoke them, providing notification to attached code (i.e. event handlers).
     *
     * Invoking an event will invoke each attached handler (delegate) in the order
     * they have been attached.
     *
     * @tparam Ret     Specifies the return type of the delegates to be attached
     * @tparam 16     Specifies the parameter types passed to the delegate
     */
    template < typename Ret, typename PT1, typename PT2, typename PT3, typename PT4, typename PT5, typename PT6, typename PT7, typename PT8, typename PT9, typename PT10, typename PT11, typename PT12, typename PT13, typename PT14, typename PT15, typename PT16 >
    class event16
    {
        public:
            /** Defines the return type this event will represent */
            typedef Ret ret_t;
            /** Defines the delegate signature this event represents */
            typedef omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 > delegate_t;
            /** Defines the container type used by this event class */
            typedef typename std::deque< omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 > > container_t;
            /** Defines an iterator type to the underlying types */
            typedef typename std::deque< omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 > >::iterator iterator_t;
            /** Defines a const iterator type to the underlying types */
            typedef typename std::deque< omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 > >::const_iterator const_iterator_t;
            /** Defines a reverse iterator type to the underlying types */
            typedef typename std::reverse_iterator< iterator_t > reverse_iterator_t;
            /** Defines a const reverse iterator type to the underlying types */
            typedef typename std::reverse_iterator< const_iterator_t > const_reverse_iterator_t;
            /** Defines the 1st function parameter type of this delegate */
            typedef PT1 p1_t;
            /** Defines the 2nd function parameter type of this delegate */
            typedef PT2 p2_t;
            /** Defines the 3rd function parameter type of this delegate */
            typedef PT3 p3_t;
            /** Defines the 4th function parameter type of this delegate */
            typedef PT4 p4_t;
            /** Defines the 5th function parameter type of this delegate */
            typedef PT5 p5_t;
            /** Defines the 6th function parameter type of this delegate */
            typedef PT6 p6_t;
            /** Defines the 7th function parameter type of this delegate */
            typedef PT7 p7_t;
            /** Defines the 8th function parameter type of this delegate */
            typedef PT8 p8_t;
            /** Defines the 9th function parameter type of this delegate */
            typedef PT9 p9_t;
            /** Defines the 10th function parameter type of this delegate */
            typedef PT10 p10_t;
            /** Defines the 11th function parameter type of this delegate */
            typedef PT11 p11_t;
            /** Defines the 12th function parameter type of this delegate */
            typedef PT12 p12_t;
            /** Defines the 13th function parameter type of this delegate */
            typedef PT13 p13_t;
            /** Defines the 14th function parameter type of this delegate */
            typedef PT14 p14_t;
            /** Defines the 15th function parameter type of this delegate */
            typedef PT15 p15_t;
            /** Defines the 16th function parameter type of this delegate */
            typedef PT16 p16_t;


            /** The default constructor */
            event16() :
                OMNI_SAFE_EVENT_MILST_FW
                m_list()
            {
                OMNI_SAFE_EVENT_INIT_FW
                OMNI_D5_FW("created event");
            }
            
            /**
             * The copy constructor copies the elements from the
             * event passed in.
             *
             * @param cp    The event to copy
             */
            event16(const event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& cp) :
                OMNI_SAFE_EVENT_MILST_FW
                m_list(cp.m_list)
            {
                OMNI_SAFE_EVENT_INIT_FW
                OMNI_D5_FW("created event");
            }
            
            /**
             * Creates an event with a signature compatible delegate attached
             *
             * @param d     The signature compatible delegate to add to the invocation list
             */
            explicit event16(const omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& d) :
                OMNI_SAFE_EVENT_MILST_FW
                m_list()
            {
                OMNI_SAFE_EVENT_INIT_FW
                this->attach(d);
                OMNI_D5_FW("created event");
            }

            /**
             * The default destructor; clears the underlying list,
             * calling the destructor for each attached delegate
             */
            ~event16()
            {
                OMNI_TRY_FW
                this->clear();
                OMNI_SAFE_EVENT_DTOR_FW
                OMNI_CATCH_FW
                OMNI_D5_FW("destroyed");
            }
            
            /**
             * Add (attach) a member delegate to this event instance
             *
             * @param d        The member delegate to attach
             */
            void attach(const omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& d)
            {
                /* DEV_NOTE: don't check if 'd' doesn't have a valid function reference
                since on invoke 'd' would fail if it didn't have a valid fnptr */
                OMNI_SAFE_EVENT_ALOCK_FW
                this->m_list.push_back(d);
            }
            
            /**
             * Add (attach) another events invocation list to this instance
             *    
             * @param e        The other event to add invocation list
             */
            void attach(const event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& e)
            {
                if (this != &e) {
                    OMNI_SAFE_EVENT_ALOCK_FW
                    container_t tmp = e.invocation_list();
                    for (iterator_t it = tmp.begin(); it != tmp.end(); it++) {
                        this->m_list.push_back(*it);
                    }
                }
            }
            
            /**
             * Add (attach) a range of delegates to this event instance
             *
             * @param begin     The input iterator pointing to the initial position in the sequence to add
             * @param end     The input iterator pointing to the last position in the sequence to add
             */
            template < class InputIterator >
            void attach(InputIterator begin, InputIterator end)
            {
                OMNI_SAFE_EVENT_ALOCK_FW
                while (begin != end) {
                    this->m_list.push_back(*begin);
                    ++begin;
                }
            }
            
            /**
             * Attach a an anonymous/non-member or static member function to this delegate.
             *
             * @tparam fnptr         The function to attach to the delegate
             */
            template < ret_t (*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) >
            void attach()
            {
                this->attach( fnptr );
            }
            
            /**
             * Attach a member function to this delegate.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             */
            template < class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) >
            void attach(T& obj)
            {
                this->attach( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind< T, fnptr >(obj) );
            }
            
            /**
             * Attach a member function to this delegate.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             */
            template < class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) >
            void attach(const T& obj)
            {
                this->attach( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind< T, fnptr >(obj) );
            }
            
            /**
             * Attach a member function to this delegate.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             */
            template < class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) >
            void attach(const T *const obj)
            {
                this->attach( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind< T, fnptr >(obj) );
            }
            
            /**
             * Attach a const member function to this delegate.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             */
            template < class T, ret_t (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) const >
            void attach_const(const T& obj)
            {
                this->attach( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind_const< T, fnptr >(obj) );
            }
            
            /**
             * Attach a const member function to this delegate.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             */
            template < class T, ret_t (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) const >
            void attach_const(const T *const obj)
            {
                this->attach( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind_const< T, fnptr >(obj) );
            }
            
            /**
             * Clears the underlying invocation list
             */
            void clear()
            {
                OMNI_SAFE_EVENT_ALOCK_FW
                // clear the list container, calling the items destructors
                this->m_list.clear();
            }
            
            /**
             * Tests if a specified member delegate is in this event instance.
             *
             * @param d        The member delegate to search for
             *
             * @return True if the delegate is found, false otherwise
             */
            bool contains(const omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& d)
            {
                OMNI_SAFE_EVENT_ALOCK_FW
                return (this->_find(d) != this->m_list.end());
            }
            
            /**
             * Tests if a specified member delegate is in this event instance.
             *
             * @tparam fnptr         The function to attach to the delegate
             *
             * @return True if the delegate is found, false otherwise
             */
            template < ret_t (*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) >
            bool contains()
            {
                return this->contains( fnptr );
            }
            
            /**
             * Tests if a specified member delegate is in this event instance.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             *
             * @return True if the delegate is found, false otherwise
             */
            template < class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) >
            bool contains(T& obj)
            {
                return this->contains( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind< T, fnptr >(obj) );
            }
            
            /**
             * Tests if a specified member delegate is in this event instance.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             *
             * @return True if the delegate is found, false otherwise
             */
            template < class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) >
            bool contains(const T& obj)
            {
                return this->contains( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind< T, fnptr >(obj) );
            }
            
            /**
             * Tests if a specified member delegate is in this event instance.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             *
             * @return True if the delegate is found, false otherwise
             */
            template < class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) >
            bool contains(const T *const obj)
            {
                return this->contains( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind< T, fnptr >(obj) );
            }
            
            /**
             * Tests if a specified member delegate is in this event instance.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             *
             * @return True if the delegate is found, false otherwise
             */
            template < class T, ret_t (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) const >
            bool contains_const(const T& obj)
            {
                return this->contains( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind_const< T, fnptr >(obj) );
            }
            
            /**
             * Tests if a specified member delegate is in this event instance.
             *
             * @tparam T             The type of class to associate with this delegate
             * @tparam fnptr         The function to attach to the delegate
             * @param obj            The instance of the class to reference in this delegate
             *
             * @return True if the delegate is found, false otherwise
             */
            template < class T, ret_t (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) const >
            bool contains_const(const T *const obj)
            {
                return this->contains( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind_const< T, fnptr >(obj) );
            }
            
            /**
             * Detach a member delegate to this event instance
             *
             * @param d        The member delegate to detach
             */
            void detach(const omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& d)
            {
                OMNI_SAFE_EVENT_ALOCK_FW
                iterator_t found;
                while ((found = this->_find(d)) != this->m_list.end()) {
                    this->m_list.erase(found);
                }
            }
            
            /**
             * Detaches another events invocation list from this instance
             *
             * @param e        The event to detach invocation list of
             */
            void detach(const event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& e)
            {
                if (this != &e) {
                    OMNI_SAFE_EVENT_ALOCK_FW
                    iterator_t found = this->m_list.end();
                    container_t tmp = e.invocation_list();
                    for (iterator_t it = tmp.begin(); it != tmp.end(); ++it) {
                        while ((found = this->_find(*it)) != this->m_list.end()) {
                            this->m_list.erase(found);
                        }
                    }
                }
            }
            
            /**
             * Detach a range of delegates from this event instance
             *
             * @param begin     The input iterator pointing to the initial position in the sequence to remove
             * @param end     The input iterator pointing to the last position in the sequence to remove
             */
            template < class InputIterator >
            void detach(InputIterator begin, InputIterator end)
            {
                OMNI_SAFE_EVENT_ALOCK_FW
                iterator_t found = this->m_list.end();
                while (begin != end) {
                    while ((found = this->_find(*begin)) != this->m_list.end()) {
                        this->m_list.erase(found);
                    }
                    ++begin;
                }
            }
            
            /**
             * Detach an anonymous/non-member or static member function from this event.
             *
             * @tparam fnptr         The function to detach
             */
            template < ret_t (*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) >
            void detach()
            {
                this->detach( fnptr );
            }
            
            /**
             * Detach a member function from this event.
             *
             * @tparam T             The type of class to associate with the delegate
             * @tparam fnptr         The function to detach
             * @param obj            The instance of the class to reference
             */
            template < class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) >
            void detach(T& obj)
            {
                this->detach( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind< T, fnptr >(obj) );
            }
            
            /**
             * Detach a member function from this event.
             *
             * @tparam T             The type of class to associate with the delegate
             * @tparam fnptr         The function to detach
             * @param obj            The instance of the class to reference
             */
            template < class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) >
            void detach(const T& obj)
            {
                this->detach( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind< T, fnptr >(obj) );
            }
            
            /**
             * Detach a member function from this event.
             *
             * @tparam T             The type of class to associate with the delegate
             * @tparam fnptr         The function to detach
             * @param obj            The instance of the class to reference
             */
            template < class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) >
            void detach(const T *const obj)
            {
                this->detach( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind< T, fnptr >(obj) );
            }
            
            /**
             * Detach a const member function from this event.
             *
             * @tparam T             The type of class to associate with the delegate
             * @tparam fnptr         The function to detach
             * @param obj            The instance of the class to reference
             */
            template < class T, ret_t (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) const >
            void detach_const(const T& obj)
            {
                this->detach( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind_const< T, fnptr >(obj) );
            }
            
            /**
             * Detach a const member function from this event.
             *
             * @tparam T             The type of class to associate with the delegate
             * @tparam fnptr         The function to detach
             * @param obj            The instance of the class to reference
             */
            template < class T, ret_t (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16) const >
            void detach_const(const T *const obj)
            {
                this->detach( omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::template bind_const< T, fnptr >(obj) );
            }
            
            /**
             * Checks if the current event instance has any attached methods
             *
             * @return True if the instance has a method or methods attached, false if not
             */
            bool empty() const
            {
                OMNI_SAFE_EVENT_ALOCK_FW
                return this->m_list.empty();
            }
            
            /**
             * Gets the invocation list used to call the delegate objects on event invocation
             *
             * @return The underlying container variable
             */
            container_t invocation_list() const
            {
                OMNI_SAFE_EVENT_ALOCK_FW
                return this->m_list;
            }
            
            /**
             * Calls the functions bound to this event instance in a non-safe manner.
             * delegate::invoke_direct does not perform certain checks.
             *
             * @return The return type specified at compile time
             */
            ret_t invoke_direct(p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13, p14_t val14, p15_t val15, p16_t val16) const
            {
                OMNI_SAFE_EVENT_LOCK_FW
                const_iterator_t cur = this->m_list.begin();
                const_iterator_t tmp = this->m_list.begin();
                const_iterator_t end = this->m_list.end();
                while (cur != end) {
                    if ((++tmp) == end) {
                        OMNI_SAFE_EVENT_UNLOCK_FW
                        return cur->invoke_direct(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16);
                    }
                    OMNI_SAFE_EVENT_UNLOCK_FW
                    cur->invoke_direct(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16);
                    OMNI_SAFE_EVENT_LOCK_FW
                    tmp = (++cur);
                }
                OMNI_SAFE_EVENT_UNLOCK_FW
            }
            
            void swap(event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& e)
            {
                OMNI_SAFE_EVENT_ALOCK_FW
                #if defined(OMNI_SAFE_EVENTS)
                    omni::sync::mutex_lock(e.m_mtx);
                #endif
                std::swap(this->m_list, e.m_list);
                #if defined(OMNI_SAFE_EVENTS)
                    omni::sync::mutex_unlock(e.m_mtx);
                #endif
            }
            
            /**
             * The () operator can be used to call the functions bound to this event instance
             *
             * @return The return type specified at compile time
             */
            ret_t operator()(p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13, p14_t val14, p15_t val15, p16_t val16) const
            {
                OMNI_SAFE_EVENT_LOCK_FW
                const_iterator_t cur = this->m_list.begin();
                const_iterator_t tmp = this->m_list.begin();
                const_iterator_t end = this->m_list.end();
                while (cur != end) {
                    if ((++tmp) == end) {
                        OMNI_SAFE_EVENT_UNLOCK_FW
                        return cur->invoke(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16);
                    }
                    OMNI_SAFE_EVENT_UNLOCK_FW
                    cur->invoke(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16);
                    OMNI_SAFE_EVENT_LOCK_FW
                    tmp = (++cur);
                }
                OMNI_SAFE_EVENT_UNLOCK_FW
            }
            
            /**
             * The boolean () operator can be used to check if this delegate is valid (has a valid function assigned)
             */
            operator bool() const
            {
                return !this->empty();
            }
            
            /**
             * The negated boolean () operator is used to check negation of the boolean () operator
             */
            bool operator!() const
            {
                return (!operator bool());
            }

            /**
             * The = operator is used to assign one event invocation to another
             *
             * @param e        The right most operand event to assign
             */
            event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& operator=(const event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& e)
            {
                if (this != &e) {
                    OMNI_SAFE_EVENT_ALOCK_FW
                    this->m_list.clear();
                    #if defined(OMNI_SAFE_EVENTS)
                        omni::sync::mutex_lock(e.m_mtx);
                    #endif
                    this->m_list = e.m_list;
                    #if defined(OMNI_SAFE_EVENTS)
                        omni::sync::mutex_unlock(e.m_mtx);
                    #endif
                }
                return *this;
            }
            
            /**
             * The [int] operator can be used to access a specific delegate in the
             * invocation list directly.
             *
             * @return A reference to the delegate instance at the specified index
             */
            omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& operator[](std::size_t idx)
            {
                OMNI_SAFE_EVENT_ALOCK_FW
                if (this->m_list.empty() || (idx > (this->m_list.size() - 1))) {
                    OMNI_ERR_RETV_FW("Index out of range", omni::index_out_of_range(), NULL)
                }
                return *(this->m_list[idx]);
            }
            
            /**
             * The += operator is used to add delegates to this event instance
             *
             * @param d        The right most operand delegate to add
             */
            event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& operator+=(const omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& d)
            {
                this->attach(d);
                return *this;
            }
            
            /**
             * The += operator is used to add delegates to this event instance
             *
             * @param e        The right most operand event to add
             */
            event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& operator+=(const event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& e)
            {
                this->attach(e);
                return *this;
            }
            
            /**
             * The -= operator is used to remove delegates from this event instance
             *
             * @param d        The right most operand delegate to remove
             */
            event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& operator-=(const omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& d)
            {
                this->detach(d);
                return *this;
            }
            
            /**
             * The -= operator is used to remove delegates from this event instance
             *
             * @param e        The right most operand event to remove
             */
            event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& operator-=(const event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& e)
            {
                this->detach(e);
                return *this;
            }

            /**
             * The == operator is used for comparison results
             *
             * @param d        The right most operand which to compare to
             */
            bool operator==(const event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& e) const
            {
                if (this == &e) { return true; }
                OMNI_SAFE_EVENT_ALOCK_FW
                container_t l = e.invocation_list();
                bool ret = (l.size() == this->m_list.size());
                if (ret) {
                    const_iterator_t a = this->m_list.begin();
                    const_iterator_t b = l.begin();
                    while ((a != this->m_list.end()) && (b != l.end())) {
                        if (*a != *b) { ret = false; break; }
                        ++a; ++b;
                    }
                }
                return ret;
            }
            
            /**
             * The != operator is used for comparison results (negates the == operator)
             *
             * @param d        The right most operand which to compare to
             */
            bool operator!=(const event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& e) const
            {
                return !(*this == e);
            }
            
        private:
            OMNI_SAFE_EVENT_MTX_FW
            /** The collection of member methods */
            container_t m_list;

            /**
             * Find a specified member delegate in this event instance.
             *
             * @param d        The member delegate to search for
             *
             * @return An iterator to the found delegate, list.end() if not found
             */
            iterator_t _find(const omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& d)
            {
                // don't use any locks here as calling code does the lock
                if (this->m_list.empty()) { return this->m_list.end(); }
                iterator_t itr = this->m_list.end();
                while (itr != this->m_list.begin()) {
                    if (*(--itr) == d) { return itr; }
                }
                return this->m_list.end();
            }
    };
    
    /** A generic event that has 16 parameters and does not return a value. */
    typedef omni::event16<void, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*> action16;
} // namespace omni

#define OMNI_BIND16(Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16, Class, Function, Obj) omni::delegate16<Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16>::bind<Class, &Class::Function>(Obj)
#define OMNI_BIND16_CONST(Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16, Class, Function, Obj) omni::delegate16<Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16>::bind_const<Class, &Class::Function>(Obj)

namespace std {
    template < typename Ret, typename PT1, typename PT2, typename PT3, typename PT4, typename PT5, typename PT6, typename PT7, typename PT8, typename PT9, typename PT10, typename PT11, typename PT12, typename PT13, typename PT14, typename PT15, typename PT16 >
    inline void swap(omni::delegate16<Ret, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*>& d1, omni::delegate16<Ret, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*>& d2)
    {
        d1.swap(d2);
    }
    
    template < typename Ret, typename PT1, typename PT2, typename PT3, typename PT4, typename PT5, typename PT6, typename PT7, typename PT8, typename PT9, typename PT10, typename PT11, typename PT12, typename PT13, typename PT14, typename PT15, typename PT16 >
    inline void swap(omni::event16<Ret, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*>& e1, omni::event16<Ret, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*>& e2)
    {
        e1.swap(e2);
    }
}

#endif // OMNI_DELEGATE16_HPP