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:
1388:
1389:
1390:
1391:
1392:
1393:
1394:
1395:
1396:
1397:
1398:
1399:
1400:
1401:
1402:
1403:
1404:
1405:
1406:
1407:
1408:
1409:
1410:
1411:
1412:
1413:
1414:
1415:
1416:
1417:
1418:
1419:
1420:
1421:
1422:
1423:
1424:
1425:
1426:
1427:
1428:
1429:
1430:
1431:
1432:
1433:
1434:
1435:
1436:
1437:
1438:
1439:
1440:
1441:
1442:
1443:
1444:
1445:
1446:
1447:
1448:
1449:
1450:
1451:
1452:
1453:
1454:
1455:
1456:
1457:
1458:
1459:
1460:
1461:
1462:
1463:
1464:
1465:
1466:
1467:
1468:
1469:
1470:
1471:
1472:
1473:
1474:
1475:
1476:
1477:
1478:
1479:
1480:
1481:
1482:
1483:
1484:
1485:
1486:
1487:
1488:
1489:
1490:
1491:
1492:
1493:
1494:
1495:
1496:
1497:
1498:
1499:
1500:
1501:
1502:
1503:
1504:
1505:
1506:
1507:
1508:
1509:
1510:
1511:
1512:
1513:
1514:
1515:
1516:
1517:
1518:
1519:
1520:
1521:
1522:
1523:
1524:
1525:
1526:
1527:
1528:
1529:
1530:
1531:
1532:
1533:
1534:
1535:
1536:
1537:
1538:
1539:
1540:
1541:
1542:
1543:
1544:
1545:
1546:
1547:
1548:
1549:
1550:
1551:
1552:
1553:
1554:
1555:
1556:
1557:
1558:
1559:
1560:
1561:
1562:
1563:
1564:
1565:
1566:
1567:
1568:
1569:
1570:
1571:
1572:
1573:
1574:
1575:
1576:
1577:
1578:
1579:
1580:
1581:
1582:
1583:
1584:
1585:
1586:
1587:
1588:
1589:
1590:
1591:
1592:
1593:
1594:
1595:
1596:
1597:
1598:
1599:
1600:
1601:
1602:
1603:
1604:
1605:
1606:
1607:
1608:
1609:
1610:
1611:
1612:
1613:
1614:
1615:
1616:
1617:
1618:
1619:
1620:
1621:
1622:
1623:
1624:
1625:
1626:
1627:
1628:
1629:
1630:
1631:
1632:
1633:
1634:
1635:
1636:
1637:
1638:
1639:
1640:
1641:
1642:
1643:
1644:
1645:
1646:
1647:
1648:
1649:
1650:
1651:
1652:
1653:
1654:
1655:
1656:
1657:
1658:
1659:
1660:
1661:
1662:
1663:
1664:
1665:
1666:
1667:
1668:
1669:
1670:
1671:
1672:
1673:
1674:
1675:
1676:
1677:
1678:
1679:
1680:
1681:
1682:
1683:
1684:
1685:
1686:
1687:
1688:
1689:
1690:
1691:
1692:
1693:
1694:
1695:
1696:
1697:
1698:
1699:
1700:
1701:
1702:
1703:
1704:
1705:
1706:
1707:
1708:
1709:
1710:
1711:
1712:
1713:
1714:
1715:
1716:
1717:
1718:
1719:
1720:
1721:
1722:
1723:
1724:
1725:
1726:
1727:
1728:
1729:
1730:
1731:
1732:
1733:
1734:
1735:
1736:
1737:
1738:
1739:
1740:
1741:
1742:
1743:
1744:
1745:
1746:
1747:
1748:
1749:
1750:
1751:
1752:
1753:
1754:
1755:
1756:
1757:
1758:
1759:
1760:
1761:
1762:
1763:
1764:
1765:
1766:
1767:
1768:
1769:
1770:
1771:
1772:
1773:
1774:
1775:
1776:
1777:
1778:
1779:
1780:
1781:
1782:
1783:
1784:
1785:
1786:
1787:
1788:
1789:
1790:
1791:
1792:
1793:
1794:
1795:
1796:
1797:
1798:
1799:
1800:
1801:
1802:
1803:
1804:
1805:
1806:
1807:
1808:
1809:
1810:
1811:
1812:
1813:
1814:
1815:
1816:
1817:
1818:
1819:
1820:
1821:
1822:
1823:
1824:
1825:
1826:
1827:
1828:
1829:
1830:
1831:
1832:
1833:
1834:
1835:
1836:
1837:
1838:
1839:
1840:
1841:
1842:
1843:
1844:
1845:
1846:
1847:
1848:
1849:
1850:
1851:
1852:
1853:
1854:
1855:
1856:
1857:
1858:
1859:
1860:
1861:
1862:
1863:
1864:
1865:
1866:
1867:
1868:
1869:
1870:
1871:
1872:
1873:
1874:
1875:
1876:
1877:
1878:
1879:
1880:
1881:
1882:
1883:
1884:
1885:
1886:
1887:
1888:
1889:
1890:
1891:
1892:
1893:
1894:
1895:
1896:
1897:
1898:
1899:
1900:
1901:
1902:
1903:
1904:
1905:
1906:
1907:
1908:
1909:
1910:
1911:
1912:
1913:
1914:
1915:
1916:
1917:
1918:
1919:
1920:
1921:
1922:
1923:
1924:
1925:
1926:
1927:
1928:
1929:
1930:
1931:
1932:
1933:
1934:
1935:
1936:
1937:
1938:
1939:
1940:
1941:
1942:
1943:
1944:
1945:
1946:
1947:
1948:
1949:
1950:
1951:
1952:
1953:
1954:
1955:
1956:
1957:
1958:
1959:
1960:
1961:
1962:
1963:
1964:
1965:
1966:
1967:
1968:
1969:
1970:
1971:
1972:
1973:
1974:
1975:
1976:
1977:
1978:
1979:
1980:
1981:
1982:
1983:
1984:
1985:
1986:
1987:
1988:
1989:
1990:
1991:
1992:
1993:
1994:
1995:
1996:
1997:
1998:
1999:
2000:
2001:
2002:
2003:
2004:
2005:
2006:
2007:
2008:
2009:
2010:
2011:
2012:
2013:
2014:
2015:
2016:
2017:
2018:
2019:
2020:
2021:
2022:
2023:
2024:
2025:
2026:
2027:
2028:
2029:
2030:
2031:
2032:
2033:
2034:
2035:
2036:
2037:
2038:
2039:
2040:
2041:
2042:
2043:
2044:
2045:
2046:
2047:
2048:
2049:
2050:
2051:
2052:
2053:
2054:
2055:
2056:
2057:
2058:
2059:
2060:
2061:
2062:
2063:
2064:
2065:
2066:
2067:
2068:
2069:
2070:
2071:
2072:
2073:
2074:
2075:
2076:
2077:
2078:
2079:
2080:
2081:
2082:
2083:
2084:
2085:
2086:
2087:
2088:
2089:
2090:
2091:
2092:
2093:
2094:
2095:
2096:
2097:
2098:
2099:
2100:
2101:
2102:
2103:
2104:
2105:
2106:
2107:
2108:
2109:
2110:
2111:
2112:
2113:
2114:
2115:
2116:
2117:
2118:
2119:
2120:
2121:
2122:
2123:
2124:
2125:
2126:
2127:
2128:
2129:
2130:
2131:
2132:
2133:
2134:
2135:
2136:
2137:
2138:
2139:
2140:
2141:
2142:
2143:
2144:
2145:
2146:
2147:
2148:
2149:
2150:
2151:
2152:
2153:
2154:
2155:
2156:
2157:
2158:
2159:
2160:
2161:
2162:
2163:
2164:
2165:
2166:
2167:
2168:
2169:
2170:
2171:
2172:
2173:
2174:
2175:
2176:
2177:
2178:
2179:
2180:
2181:
2182:
2183:
2184:
2185:
2186:
2187:
2188:
2189:
2190:
2191:
2192:
2193:
2194:
2195:
2196:
2197:
2198:
2199:
2200:
2201:
2202:
2203:
2204:
2205:
2206:
2207:
2208:
2209:
2210:
2211:
2212:
2213:
2214:
2215:
2216:
2217:
2218:
2219:
2220:
2221:
2222:
2223:
2224:
2225:
2226:
2227:
2228:
2229:
2230:
2231:
2232:
2233:
2234:
2235:
2236:
2237:
2238:
2239:
2240:
2241:
2242:
2243:
2244:
2245:
2246:
2247:
2248:
2249:
2250:
2251:
2252:
2253:
2254:
2255:
2256:
2257:
2258:
2259:
2260:
2261:
2262:
2263:
2264:
2265:
2266:
2267:
2268:
2269:
2270:
2271:
2272:
2273:
2274:
2275:
2276:
2277:
2278:
2279:
2280:
2281:
2282:
2283:
2284:
2285:
2286:
2287:
2288:
2289:
2290:
2291:
2292:
2293:
2294:
2295:
2296:
2297:
2298:
2299:
2300:
2301:
2302:
2303:
2304:
2305:
2306:
2307:
2308:
2309:
2310:
2311:
2312:
2313:
2314:
2315:
2316:
2317:
2318:
2319:
2320:
2321:
2322:
2323:
2324:
2325:
2326:
2327:
2328:
2329:
2330:
2331:
2332:
2333:
2334:
2335:
2336:
2337:
2338:
2339:
2340:
2341:
2342:
2343:
2344:
2345:
2346:
2347:
2348:
2349:
2350:
2351:
2352:
2353:
2354:
2355:
2356:
2357:
2358:
2359:
2360:
2361:
2362:
2363:
2364:
2365:
2366:
2367:
2368:
2369:
2370:
2371:
2372:
2373:
2374:
2375:
2376:
2377:
2378:
2379:
2380:
2381:
2382:
2383:
2384:
2385:
2386:
2387:
2388:
2389:
2390:
2391:
2392:
2393:
2394:
2395:
2396:
2397:
2398:
2399:
2400:
2401:
2402:
2403:
2404:
2405:
2406:
2407:
2408:
2409:
2410:
2411:
2412:
2413:
2414:
2415:
2416:
2417:
2418:
2419:
2420:
2421:
2422:
2423:
2424:
2425:
2426:
2427:
2428:
2429:
2430:
2431:
2432:
2433:
2434:
2435:
2436:
2437:
2438:
2439:
2440:
2441:
2442:
2443:
2444:
2445:
2446:
2447:
2448:
2449:
2450:
2451:
2452:
2453:
2454:
2455:
2456:
2457:
2458:
2459:
2460:
2461:
2462:
2463:
2464:
2465:
2466:
2467:
2468:
2469:
2470:
2471:
2472:
2473:
2474:
2475:
2476:
2477:
2478:
2479:
2480:
2481:
2482:
2483:
2484:
2485:
2486:
2487:
2488:
2489:
2490:
2491:
2492:
2493:
2494:
2495:
2496:
2497:
2498:
2499:
2500:
2501:
2502:
2503:
2504:
2505:
2506:
2507:
2508:
2509:
2510:
2511:
2512:
2513:
2514:
2515:
2516:
2517:
2518:
2519:
2520:
2521:
2522:
2523:
2524:
2525:
2526:
2527:
2528:
2529:
2530:
2531:
2532:
2533:
2534:
2535:
2536:
2537:
2538:
2539:
2540:
2541:
2542:
2543:
2544:
2545:
2546:
2547:
2548:
2549:
2550:
2551:
2552:
2553:
2554:
2555:
2556:
2557:
2558:
2559:
2560:
2561:
2562:
2563:
2564:
2565:
2566:
2567:
2568:
2569:
2570:
2571:
2572:
2573:
2574:
2575:
2576:
2577:
2578:
2579:
2580:
2581:
2582:
2583:
2584:
2585:
2586:
2587:
2588:
2589:
2590:
2591:
2592:
2593:
2594:
2595:
2596:
2597:
2598:
2599:
2600:
2601:
2602:
2603:
2604:
2605:
2606:
2607:
2608:
2609:
2610:
2611:
2612:
2613:
2614:
2615:
2616:
2617:
2618:
2619:
2620:
2621:
2622:
2623:
2624:
2625:
2626:
2627:
2628:
2629:
2630:
2631:
2632:
2633:
2634:
2635:
2636:
2637:
2638:
2639:
2640:
2641:
2642:
2643:
2644:
2645:
2646:
2647:
2648:
2649:
2650:
2651:
2652:
2653:
2654:
2655:
2656:
2657:
2658:
2659:
2660:
2661:
2662:
2663:
2664:
2665:
2666:
2667:
2668:
2669:
2670:
2671:
2672:
2673:
2674:
2675:
2676:
2677:
2678:
2679:
2680:
2681:
2682:
2683:
2684:
2685:
2686:
2687:
2688:
2689:
2690:
2691:
2692:
2693:
2694:
2695:
2696:
2697:
2698:
2699:
2700:
2701:
2702:
2703:
2704:
2705:
2706:
2707:
2708:
2709:
2710:
2711:
2712:
2713:
2714:
2715:
2716:
2717:
2718:
2719:
2720:
2721:
2722:
2723:
2724:
2725:
2726:
2727:
2728:
2729:
2730:
2731:
2732:
2733:
2734:
2735:
2736:
2737:
2738:
2739:
2740:
2741:
2742:
2743:
2744:
2745:
2746:
2747:
2748:
2749:
2750:
2751:
2752:
2753:
2754:
2755:
2756:
2757:
2758:
2759:
2760:
2761:
2762:
2763:
2764:
2765:
2766:
2767:
2768:
2769:
2770:
2771:
2772:
2773:
2774:
2775:
2776:
2777:
2778:
2779:
2780:
2781:
2782:
2783:
2784:
2785:
2786:
2787:
2788:
2789:
2790:
2791:
2792:
2793:
2794:
2795:
2796:
2797:
2798:
2799:
2800:
2801:
2802:
2803:
2804:
2805:
2806:
2807:
2808:
2809:
2810:
2811:
2812:
2813:
2814:
2815:
2816:
2817:
2818:
2819:
2820:
2821:
2822:
2823:
2824:
2825:
2826:
2827:
2828:
2829:
2830:
2831:
2832:
2833:
2834:
2835:
2836:
2837:
2838:
2839:
2840:
2841:
2842:
2843:
2844:
2845:
2846:
2847:
2848:
2849:
2850:
2851:
2852:
2853:
2854:
2855:
2856:
2857:
2858:
2859:
2860:
2861:
2862:
2863:
2864:
2865:
2866:
2867:
2868:
2869:
2870:
2871:
2872:
2873:
2874:
2875:
2876:
2877:
2878:
2879:
2880:
2881:
2882:
2883:
2884:
2885:
2886:
2887:
2888:
2889:
2890:
2891:
2892:
2893:
2894:
2895:
2896:
2897:
2898:
2899:
2900:
2901:
2902:
2903:
2904:
2905:
2906:
2907:
2908:
2909:
2910:
2911:
2912:
2913:
2914:
2915:
2916:
2917:
2918:
2919:
2920:
2921:
2922:
2923:
2924:
2925:
2926:
2927:
2928:
2929:
2930:
2931:
2932:
2933:
2934:
2935:
2936:
2937:
2938:
2939:
2940:
2941:
2942:
2943:
2944:
2945:
2946:
2947:
2948:
2949:
2950:
2951:
2952:
2953:
2954:
2955:
2956:
2957:
2958:
2959:
2960:
2961:
2962:
2963:
2964:
2965:
2966:
2967:
2968:
2969:
2970:
2971:
2972:
2973:
2974:
2975:
2976:
2977:
2978:
2979:
2980:
2981:
2982:
2983:
2984:
2985:
2986:
2987:
2988:
2989:
2990:
2991:
2992:
2993:
2994:
2995:
2996:
2997:
2998:
2999:
3000:
3001:
3002:
3003:
3004:
3005:
3006:
3007:
3008:
3009:
3010:
3011:
3012:
3013:
3014:
3015:
3016:
3017:
3018:
3019:
3020:
3021:
3022:
3023:
3024:
3025:
3026:
3027:
3028:
3029:
3030:
3031:
3032:
3033:
3034:
3035:
3036:
3037:
3038:
3039:
3040:
3041:
3042:
3043:
3044:
3045:
3046:
3047:
3048:
3049:
3050:
3051:
3052:
3053:
3054:
3055:
3056:
3057:
3058:
3059:
3060:
3061:
3062:
3063:
3064:
3065:
3066:
3067:
3068:
3069:
3070:
3071:
3072:
3073:
3074:
3075:
3076:
3077:
3078:
3079:
3080:
3081:
3082:
3083:
3084:
3085:
3086:
3087:
3088:
3089:
3090:
3091:
3092:
3093:
3094:
3095:
3096:
3097:
3098:
3099:
3100:
3101:
3102:
3103:
3104:
3105:
3106:
3107:
3108:
3109:
3110:
3111:
3112:
3113:
3114:
3115:
3116:
3117:
3118:
3119:
3120:
3121:
3122:
3123:
3124:
3125:
3126:
3127:
3128:
3129:
3130:
3131:
3132:
3133:
3134:
3135:
3136:
3137:
3138:
3139:
3140:
3141:
3142:
3143:
3144:
3145:
3146:
3147:
3148:
3149:
3150:
3151:
3152:
3153:
3154:
3155:
3156:
3157:
3158:
3159:
3160:
3161:
3162:
3163:
3164:
3165:
3166:
3167:
3168:
3169:
3170:
3171:
3172:
3173:
3174:
3175:
3176:
3177:
3178:
3179:
3180:
3181:
3182:
3183:
3184:
3185:
3186:
3187:
3188:
3189:
3190:
3191:
3192:
3193:
3194:
3195:
3196:
3197:
3198:
3199:
3200:
3201:
3202:
3203:
3204:
3205:
3206:
3207:
3208:
3209:
3210:
3211:
3212:
3213:
3214:
3215:
3216:
3217:
3218:
3219:
3220:
3221:
3222:
3223:
3224:
3225:
3226:
3227:
3228:
3229:
3230:
3231:
3232:
3233:
3234:
3235:
3236:
3237:
3238:
3239:
3240:
3241:
3242:
3243:
3244:
3245:
3246:
3247:
3248:
3249:
3250:
3251:
3252:
3253:
3254:
3255:
3256:
3257:
3258:
3259:
3260:
3261:
3262:
3263:
3264:
3265:
3266:
3267:
3268:
3269:
3270:
3271:
3272:
3273:
3274:
3275:
3276:
3277:
3278:
3279:
3280:
3281:
3282:
3283:
3284:
3285:
3286:
3287:
3288:
3289:
3290:
3291:
3292:
3293:
3294:
3295:
3296:
3297:
3298:
3299:
3300:
3301:
3302:
3303:
3304:
3305:
3306:
3307:
3308:
3309:
3310:
3311:
3312:
3313:
3314:
3315:
3316:
3317:
3318:
3319:
3320:
3321:
3322:
3323:
3324:
3325:
3326:
3327:
3328:
3329:
3330:
3331:
3332:
3333:
3334:
3335:
3336:
3337:
3338:
3339:
3340:
3341:
3342:
3343:
3344:
3345:
3346:
3347:
3348:
3349:
3350:
3351:
3352:
3353:
3354:
3355:
3356:
3357:
3358:
3359:
3360:
3361:
3362:
3363:
3364:
3365:
3366:
3367:
3368:
3369:
3370:
3371:
3372:
3373:
3374:
3375:
3376:
3377:
3378:
3379:
3380:
3381:
3382:
3383:
3384:
3385:
3386:
3387:
3388:
3389:
3390:
3391:
3392:
3393:
3394:
3395:
3396:
3397:
3398:
3399:
3400:
3401:
3402:
3403:
3404:
3405:
3406:
3407:
3408:
3409:
3410:
3411:
3412:
3413:
3414:
3415:
3416:
3417:
3418:
3419:
3420:
3421:
3422:
3423:
3424:
3425:
3426:
3427:
3428:
3429:
3430:
3431:
3432:
3433:
3434:
3435:
3436:
3437:
3438:
3439:
3440:
3441:
3442:
3443:
3444:
3445:
3446:
3447:
3448:
3449:
3450:
3451:
3452:
3453:
3454:
3455:
3456:
3457:
3458:
3459:
3460:
3461:
3462:
3463:
3464:
3465:
3466:
3467:
3468:
3469:
3470:
3471:
3472:
3473:
3474:
3475:
3476:
3477:
3478:
3479:
3480:
3481:
3482:
3483:
3484:
3485:
3486:
3487:
3488:
3489:
3490:
3491:
3492:
3493:
3494:
3495:
3496:
3497:
3498:
3499:
3500:
3501:
3502:
3503:
3504:
3505:
3506:
3507:
3508:
3509:
3510:
3511:
3512:
3513:
3514:
3515:
3516:
3517:
3518:
3519:
3520:
3521:
3522:
3523:
3524:
3525:
3526:
3527:
3528:
3529:
3530:
3531:
3532:
3533:
3534:
3535:
3536:
3537:
3538:
3539:
3540:
3541:
3542:
3543:
3544:
3545:
3546:
3547:
3548:
3549:
3550:
3551:
3552:
3553:
3554:
3555:
3556:
3557:
3558:
3559:
3560:
3561:
3562:
3563:
3564:
3565:
3566:
3567:
3568:
3569:
3570:
3571:
3572:
3573:
3574:
3575:
3576:
3577:
3578:
3579:
3580:
3581:
3582:
3583:
3584:
3585:
3586:
3587:
3588:
3589:
3590:
3591:
3592:
3593:
3594:
3595:
3596:
3597:
3598:
3599:
3600:
3601:
3602:
3603:
3604:
3605:
3606:
3607:
3608:
3609:
3610:
3611:
3612:
3613:
3614:
3615:
3616:
3617:
3618:
3619:
3620:
3621:
3622:
3623:
3624:
3625:
3626:
3627:
3628:
3629:
3630:
3631:
3632:
3633:
3634:
3635:
3636:
3637:
3638:
3639:
3640:
3641:
3642:
3643:
3644:
3645:
3646:
3647:
3648:
3649:
3650:
3651:
3652:
3653:
3654:
3655:
3656:
3657:
3658:
3659:
3660:
3661:
3662:
3663:
3664:
3665:
3666:
3667:
3668:
3669:
3670:
3671:
3672:
3673:
3674:
3675:
3676:
3677:
3678:
3679:
3680:
3681:
3682:
3683:
3684:
3685:
3686:
3687:
3688:
3689:
3690:
3691:
3692:
3693:
3694:
3695:
3696:
3697:
3698:
3699:
3700:
3701:
3702:
3703:
3704:
3705:
3706:
3707:
3708:
3709:
3710:
3711:
3712:
3713:
3714:
3715:
3716:
3717:
3718:
3719:
3720:
3721:
3722:
3723:
3724:
3725:
3726:
3727:
3728:
3729:
3730:
3731:
3732:
3733:
3734:
3735:
3736:
3737:
3738:
3739:
3740:
3741:
3742:
3743:
3744:
3745:
3746:
3747:
3748:
3749:
3750:
3751:
3752:
3753:
3754:
3755:
3756:
3757:
3758:
3759:
3760:
3761:
3762:
3763:
3764:
3765:
3766:
3767:
3768:
3769:
3770:
3771:
3772:
3773:
3774:
3775:
3776:
3777:
3778:
3779:
3780:
3781:
3782:
3783:
3784:
3785:
3786:
3787:
3788:
3789:
3790:
3791:
3792:
3793:
3794:
3795:
3796:
3797:
3798:
3799:
3800:
3801:
3802:
3803:
3804:
3805:
3806:
3807:
3808:
3809:
3810:
3811:
3812:
3813:
3814:
3815:
3816:
3817:
3818:
3819:
3820:
3821:
3822:
3823:
3824:
3825:
3826:
3827:
3828:
3829:
3830:
3831:
3832:
3833:
3834:
3835:
3836:
3837:
3838:
3839:
3840:
3841:
3842:
3843:
3844:
3845:
3846:
3847:
3848:
3849:
3850:
3851:
3852:
3853:
3854:
3855:
3856:
3857:
3858:
3859:
3860:
3861:
3862:
3863:
3864:
3865:
3866:
3867:
3868:
3869:
3870:
3871:
3872:
3873:
3874:
3875:
3876:
3877:
3878:
3879:
3880:
3881:
3882:
3883:
3884:
3885:
3886:
3887:
3888:
3889:
3890:
3891:
3892:
3893:
3894:
3895:
3896:
3897:
3898:
3899:
3900:
3901:
3902:
3903:
3904:
3905:
3906:
3907:
3908:
3909:
3910:
3911:
3912:
3913:
3914:
3915:
3916:
3917:
3918:
3919:
3920:
3921:
3922:
3923:
3924:
3925:
3926:
3927:
3928:
3929:
3930:
3931:
3932:
3933:
3934:
3935:
3936:
3937:
3938:
3939:
3940:
3941:
3942:
3943:
3944:
3945:
3946:
3947:
3948:
3949:
3950:
3951:
3952:
3953:
3954:
3955:
3956:
3957:
3958:
3959:
3960:
3961:
3962:
3963:
3964:
3965:
3966:
3967:
3968:
3969:
3970:
3971:
3972:
3973:
3974:
3975:
3976:
3977:
3978:
3979:
3980:
3981:
3982:
3983:
3984:
3985:
3986:
3987:
3988:
3989:
3990:
3991:
3992:
3993:
3994:
3995:
3996:
3997:
3998:
3999:
4000:
4001:
4002:
4003:
4004:
4005:
4006:
4007:
4008:
4009:
4010:
4011:
4012:
4013:
4014:
4015:
4016:
4017:
4018:
4019:
4020:
4021:
4022:
4023:
4024:
4025:
4026:
4027:
4028:
4029:
4030:
4031:
4032:
4033:
4034:
4035:
4036:
4037:
4038:
4039:
4040:
4041:
4042:
4043:
4044:
4045:
4046:
4047:
4048:
4049:
4050:
4051:
4052:
4053:
4054:
4055:
4056:
4057:
4058:
4059:
4060:
4061:
4062:
4063:
4064:
4065:
4066:
4067:
4068:
4069:
4070:
4071:
4072:
4073:
4074:
4075:
4076:
4077:
4078:
4079:
4080:
4081:
4082:
4083:
4084:
4085:
4086:
4087:
4088:
4089:
4090:
4091:
4092:
4093:
4094:
4095:
4096:
4097:
4098:
4099:
4100:
4101:
4102:
4103:
4104:
4105:
4106:
4107:
4108:
4109:
4110:
4111:
4112:
4113:
4114:
4115:
4116:
4117:
4118:
4119:
4120:
4121:
4122:
4123:
4124:
4125:
4126:
4127:
4128:
4129:
4130:
4131:
4132:
4133:
4134:
4135:
4136:
4137:
4138:
4139:
4140:
4141:
4142:
4143:
4144:
4145:
4146:
4147:
4148:
4149:
4150:
4151:
4152:
4153:
4154:
4155:
4156:
4157:
4158:
4159:
4160:
4161:
4162:
4163:
4164:
4165:
4166:
4167:
4168:
4169:
4170:
4171:
4172:
4173:
4174:
4175:
4176:
4177:
4178:
4179:
4180:
4181:
4182:
4183:
4184:
4185:
4186:
4187:
4188:
4189:
4190:
4191:
4192:
4193:
4194:
4195:
4196:
4197:
4198:
4199:
4200:
4201:
4202:
4203:
4204:
4205:
4206:
4207:
4208:
4209:
4210:
4211:
4212:
4213:
4214:
4215:
4216:
4217:
4218:
4219:
4220:
4221:
4222:
4223:
4224:
4225:
4226:
4227:
4228:
4229:
4230:
4231:
4232:
4233:
4234:
4235:
4236:
4237:
4238:
4239:
4240:
4241:
4242:
4243:
4244:
4245:
4246:
4247:
4248:
4249:
4250:
4251:
4252:
4253:
4254:
4255:
4256:
4257:
4258:
4259:
4260:
4261:
4262:
4263:
4264:
4265:
4266:
4267:
4268:
4269:
4270:
4271:
4272:
4273:
4274:
4275:
4276:
4277:
4278:
4279:
4280:
4281:
4282:
4283:
4284:
4285:
4286:
4287:
4288:
4289:
4290:
4291:
4292:
4293:
4294:
4295:
4296:
4297:
4298:
4299:
4300:
4301:
4302:
4303:
4304:
4305:
4306:
4307:
4308:
4309:
4310:
4311:
4312:
4313:
4314:
4315:
4316:
4317:
4318:
4319:
4320:
4321:
4322:
4323:
4324:
4325:
4326:
4327:
4328:
4329:
4330:
4331:
4332:
4333:
4334:
4335:
4336:
4337:
4338:
4339:
4340:
4341:
4342:
4343:
4344:
4345:
4346:
4347:
4348:
4349:
4350:
4351:
4352:
4353:
4354:
4355:
4356:
4357:
4358:
4359:
4360:
4361:
4362:
4363:
4364:
4365:
4366:
4367:
4368:
4369:
4370:
4371:
4372:
4373:
4374:
4375:
4376:
4377:
4378:
4379:
4380:
4381:
4382:
4383:
4384:
4385:
4386:
4387:
4388:
4389:
4390:
4391:
4392:
4393:
4394:
4395:
4396:
4397:
4398:
4399:
4400:
4401:
4402:
4403:
4404:
4405:
4406:
4407:
4408:
4409:
4410:
4411:
4412:
4413:
4414:
4415:
4416:
4417:
4418:
4419:
4420:
4421:
4422:
4423:
4424:
4425:
4426:
4427:
4428:
4429:
4430:
4431:
4432:
4433:
4434:
4435:
4436:
4437:
4438:
4439:
4440:
4441:
4442:
4443:
4444:
4445:
4446:
4447:
4448:
4449:
4450:
4451:
4452:
4453:
4454:
4455:
4456:
4457:
4458:
4459:
4460:
4461:
4462:
4463:
4464:
4465:
4466:
4467:
4468:
4469:
4470:
4471:
4472:
4473:
4474:
4475:
4476:
4477:
4478:
4479:
4480:
4481:
4482:
4483:
4484:
4485:
4486:
4487:
4488:
4489:
4490:
4491:
4492:
4493:
4494:
4495:
4496:
4497:
4498:
4499:
4500:
4501:
4502:
4503:
4504:
4505:
4506:
4507:
4508:
4509:
4510:
4511:
4512:
4513:
4514:
4515:
4516:
4517:
4518:
4519:
4520:
4521:
4522:
4523:
4524:
4525:
4526:
4527:
4528:
4529:
4530:
4531:
4532:
4533:
4534:
4535:
4536:
4537:
4538:
4539:
4540:
4541:
4542:
4543:
4544:
4545:
4546:
4547:
4548:
4549:
4550:
4551:
4552:
4553:
4554:
4555:
4556:
4557:
4558:
4559:
4560:
4561:
4562:
4563:
4564:
4565:
4566:
4567:
4568:
4569:
4570:
4571:
4572:
4573:
4574:
4575:
4576:
4577:
4578:
4579:
4580:
4581:
4582:
4583:
4584:
4585:
4586:
4587:
4588:
4589:
4590:
4591:
4592:
4593:
4594:
4595:
4596:
4597:
4598:
4599:
4600:
4601:
4602:
4603:
4604:
4605:
4606:
4607:
4608:
4609:
4610:
4611:
4612:
4613:
4614:
4615:
4616:
4617:
4618:
4619:
4620:
4621:
4622:
4623:
4624:
4625:
4626:
4627:
4628:
4629:
4630:
4631:
4632:
4633:
4634:
4635:
4636:
4637:
4638:
4639:
4640:
4641:
4642:
4643:
4644:
4645:
4646:
4647:
4648:
4649:
4650:
4651:
4652:
4653:
4654:
4655:
4656:
4657:
4658:
4659:
4660:
4661:
4662:
4663:
4664:
4665:
4666:
4667:
4668:
4669:
4670:
4671:
4672:
4673:
4674:
4675:
4676:
4677:
4678:
4679:
4680:
4681:
4682:
4683:
4684:
4685:
4686:
4687:
4688:
4689:
4690:
4691:
4692:
4693:
4694:
4695:
4696:
4697:
4698:
4699:
4700:
4701:
4702:
4703:
4704:
4705:
4706:
4707:
4708:
4709:
4710:
4711:
4712:
4713:
4714:
4715:
4716:
4717:
4718:
4719:
4720:
4721:
4722:
4723:
4724:
4725:
4726:
4727:
4728:
4729:
4730:
4731:
4732:
4733:
4734:
4735:
4736:
4737:
4738:
4739:
4740:
4741:
4742:
4743:
4744:
4745:
4746:
4747:
4748:
4749:
4750:
4751:
4752:
4753:
4754:
4755:
4756:
4757:
4758:
4759:
4760:
4761:
4762:
4763:
4764:
4765:
4766:
4767:
4768:
4769:
4770:
4771:
4772:
4773:
4774:
4775:
4776:
4777:
4778:
4779:
4780:
4781:
4782:
4783:
4784:
4785:
4786:
4787:
4788:
4789:
4790:
4791:
4792:
4793:
4794:
4795:
4796:
4797:
4798:
4799:
4800:
4801:
4802:
4803:
4804:
4805:
4806:
4807:
4808:
4809:
4810:
4811:
4812:
4813:
4814:
4815:
4816:
4817:
4818:
4819:
4820:
4821:
4822:
4823:
4824:
4825:
4826:
4827:
4828:
4829:
4830:
4831:
4832:
4833:
4834:
4835:
4836:
4837:
4838:
4839:
4840:
4841:
4842:
4843:
4844:
4845:
4846:
4847:
4848:
4849:
4850:
4851:
4852:
4853:
4854:
4855:
4856:
4857:
4858:
4859:
4860:
4861:
4862:
4863:
4864:
4865:
4866:
4867:
4868:
4869:
4870:
4871:
4872:
4873:
4874:
4875:
4876:
4877:
4878:
4879:
4880:
4881:
4882:
4883:
4884:
4885:
4886:
4887:
4888:
4889:
4890:
4891:
4892:
4893:
4894:
4895:
4896:
4897:
4898:
4899:
4900:
4901:
4902:
4903:
4904:
4905:
4906:
4907:
4908:
4909:
4910:
4911:
4912:
4913:
4914:
4915:
4916:
4917:
4918:
4919:
4920:
4921:
4922:
4923:
4924:
4925:
4926:
4927:
4928:
4929:
4930:
4931:
4932:
4933:
4934:
4935:
4936:
4937:
4938:
4939:
4940:
4941:
4942:
4943:
4944:
4945:
4946:
4947:
4948:
4949:
4950:
4951:
4952:
4953:
4954:
4955:
4956:
4957:
4958:
4959:
4960:
4961:
4962:
4963:
4964:
4965:
4966:
4967:
4968:
4969:
4970:
4971:
4972:
4973:
4974:
4975:
4976:
4977:
4978:
4979:
4980:
4981:
4982:
4983:
4984:
4985:
4986:
4987:
4988:
4989:
4990:
4991:
4992:
4993:
4994:
4995:
4996:
4997:
4998:
4999:
5000:
5001:
5002:
5003:
5004:
5005:
5006:
5007:
5008:
5009:
5010:
5011:
5012:
5013:
5014:
5015:
5016:
5017:
5018:
5019:
5020:
5021:
5022:
5023:
5024:
5025:
5026:
5027:
5028:
5029:
5030:
5031:
5032:
5033:
5034:
5035:
5036:
5037:
5038:
5039:
5040:
5041:
5042:
5043:
5044:
5045:
5046:
5047:
5048:
5049:
5050:
5051:
5052:
5053:
5054:
5055:
5056:
5057:
5058:
5059:
5060:
5061:
5062:
5063:
5064:
5065:
5066:
5067:
5068:
5069:
5070:
5071:
5072:
5073:
5074:
5075:
5076:
5077:
5078:
5079:
5080:
5081:
5082:
5083:
5084:
5085:
5086:
5087:
5088:
5089:
5090:
5091:
5092:
5093:
5094:
5095:
5096:
5097:
5098:
5099:
5100:
5101:
5102:
5103:
5104:
5105:
5106:
5107:
5108:
5109:
5110:
5111:
5112:
5113:
5114:
5115:
5116:
5117:
5118:
5119:
5120:
5121:
5122:
5123:
5124:
5125:
5126:
5127:
5128:
5129:
5130:
5131:
5132:
5133:
5134:
5135:
5136:
5137:
5138:
5139:
5140:
5141:
5142:
5143:
5144:
5145:
5146:
5147:
5148:
5149:
5150:
5151:
5152:
5153:
5154:
5155:
5156:
5157:
5158:
5159:
5160:
5161:
5162:
5163:
5164:
5165:
5166:
5167:
5168:
5169:
5170:
5171:
5172:
5173:
5174:
5175:
5176:
5177:
5178:
5179:
5180:
5181:
5182:
5183:
5184:
5185:
5186:
5187:
5188:
5189:
5190:
5191:
5192:
5193:
5194:
5195:
5196:
5197:
5198:
5199:
5200:
5201:
5202:
5203:
5204:
5205:
5206:
5207:
5208:
5209:
5210:
5211:
5212:
5213:
5214:
5215:
5216:
5217:
5218:
5219:
5220:
5221:
5222:
5223:
5224:
5225:
5226:
5227:
5228:
5229:
5230:
5231:
5232:
5233:
5234:
5235:
5236:
5237:
5238:
5239:
5240:
5241:
5242:
5243:
5244:
5245:
5246:
5247:
5248:
5249:
5250:
5251:
5252:
5253:
5254:
5255:
5256:
5257:
5258:
5259:
5260:
5261:
5262:
5263:
5264:
5265:
5266:
5267:
5268:
5269:
5270:
5271:
5272:
5273:
5274:
5275:
5276:
5277:
5278:
5279:
5280:
5281:
5282:
5283:
5284:
5285:
5286:
5287:
5288:
5289:
5290:
5291:
5292:
5293:
5294:
5295:
5296:
5297:
5298:
5299:
5300:
5301:
5302:
5303:
5304:
5305:
5306:
5307:
5308:
5309:
5310:
5311:
5312:
5313:
5314:
5315:
5316:
5317:
5318:
5319:
5320:
5321:
5322:
5323:
5324:
5325:
5326:
5327:
5328:
5329:
5330:
5331:
5332:
5333:
5334:
5335:
5336:
5337:
5338:
5339:
5340:
5341:
5342:
5343:
5344:
5345:
5346:
5347:
5348:
5349:
5350:
5351:
5352:
5353:
5354:
5355:
5356:
5357:
5358:
5359:
5360:
5361:
5362:
5363:
5364:
5365:
5366:
5367:
5368:
5369:
5370:
5371:
5372:
5373:
5374:
5375:
5376:
5377:
5378:
5379:
5380:
5381:
5382:
5383:
5384:
5385:
5386:
5387:
5388:
5389:
5390:
5391:
5392:
5393:
5394:
5395:
5396:
5397:
5398:
5399:
5400:
5401:
5402:
5403:
5404:
5405:
5406:
5407:
5408:
5409:
5410:
5411:
5412:
5413:
5414:
5415:
5416:
5417:
5418:
5419:
5420:
5421:
5422:
5423:
5424:
5425:
5426:
5427:
5428:
5429:
5430:
5431:
5432:
5433:
5434:
5435:
5436:
5437:
5438:
5439:
5440:
5441:
5442:
5443:
5444:
5445:
5446:
5447:
5448:
5449:
5450:
5451:
5452:
5453:
5454:
5455:
5456:
5457:
5458:
5459:
5460:
5461:
5462:
5463:
5464:
5465:
5466:
5467:
5468:
5469:
5470:
5471:
5472:
5473:
5474:
5475:
5476:
5477:
5478:
5479:
5480:
5481:
5482:
5483:
5484:
5485:
5486:
5487:
5488:
5489:
5490:
5491:
5492:
5493:
5494:
5495:
5496:
5497:
5498:
5499:
5500:
5501:
5502:
5503:
5504:
5505:
5506:
5507:
5508:
5509:
5510:
5511:
5512:
5513:
5514:
5515:
5516:
5517:
5518:
5519:
5520:
5521:
5522:
5523:
5524:
5525:
5526:
5527:
5528:
5529:
5530:
5531:
5532:
5533:
5534:
5535:
5536:
5537:
5538:
5539:
5540:
5541:
5542:
5543:
5544:
5545:
5546:
5547:
5548:
5549:
5550:
5551:
5552:
5553:
5554:
5555:
5556:
5557:
5558:
5559:
5560:
5561:
5562:
5563:
5564:
5565:
5566:
5567:
5568:
5569:
5570:
5571:
5572:
5573:
5574:
5575:
5576:
5577:
5578:
5579:
5580:
5581:
5582:
5583:
5584:
5585:
5586:
5587:
5588:
5589:
5590:
5591:
5592:
5593:
5594:
5595:
5596:
5597:
5598:
5599:
5600:
5601:
5602:
5603:
5604:
5605:
5606:
5607:
5608:
5609:
5610:
5611:
5612:
5613:
5614:
5615:
5616:
5617:
5618:
5619:
5620:
5621:
5622:
5623:
5624:
5625:
5626:
5627:
5628:
5629:
5630:
5631:
5632:
5633:
5634:
5635:
5636:
5637:
5638:
5639:
5640:
5641:
5642:
5643:
5644:
5645:
5646:
5647:
5648:
5649:
5650:
5651:
5652:
5653:
5654:
5655:
5656:
5657:
5658:
5659:
5660:
5661:
5662:
5663:
5664:
5665:
5666:
5667:
5668:
5669:
5670:
5671:
5672:
5673:
5674:
5675:
5676:
5677:
5678:
5679:
5680:
5681:
5682:
5683:
5684:
5685:
5686:
5687:
5688:
5689:
5690:
5691:
5692:
5693:
5694:
5695:
5696:
5697:
5698:
5699:
5700:
5701:
5702:
5703:
5704:
5705:
5706:
5707:
5708:
5709:
5710:
5711:
5712:
5713:
5714:
5715:
5716:
5717:
5718:
5719:
5720:
5721:
5722:
5723:
5724:
5725:
5726:
5727:
5728:
5729:
5730:
5731:
5732:
5733:
5734:
5735:
5736:
5737:
5738:
5739:
5740:
5741:
5742:
5743:
5744:
5745:
5746:
5747:
5748:
5749:
5750:
5751:
5752:
5753:
5754:
5755:
5756:
5757:
5758:
5759:
5760:
5761:
5762:
5763:
5764:
5765:
5766:
5767:
5768:
5769:
5770:
5771:
5772:
5773:
5774:
5775:
5776:
5777:
5778:
5779:
5780:
5781:
5782:
5783:
5784:
5785:
5786:
5787:
5788:
5789:
5790:
5791:
5792:
5793:
5794:
5795:
5796:
5797:
5798:
5799:
5800:
5801:
5802:
5803:
5804:
5805:
5806:
5807:
5808:
5809:
5810:
5811:
5812:
5813:
5814:
5815:
5816:
5817:
5818:
5819:
5820:
5821:
5822:
5823:
5824:
5825:
5826:
5827:
5828:
5829:
5830:
5831:
5832:
5833:
5834:
5835:
5836:
5837:
5838:
5839:
5840:
5841:
5842:
5843:
5844:
5845:
5846:
5847:
5848:
5849:
5850:
5851:
5852:
5853:
5854:
5855:
5856:
5857:
5858:
5859:
5860:
5861:
5862:
5863:
5864:
5865:
5866:
5867:
5868:
5869:
5870:
5871:
5872:
5873:
5874:
5875:
5876:
5877:
5878:
5879:
5880:
5881:
5882:
5883:
5884:
5885:
5886:
5887:
5888:
5889:
5890:
5891:
5892:
5893:
5894:
5895:
5896:
5897:
5898:
5899:
5900:
5901:
5902:
5903:
5904:
5905:
5906:
5907:
5908:
5909:
5910:
5911:
5912:
5913:
5914:
5915:
5916:
5917:
5918:
5919:
5920:
5921:
5922:
5923:
5924:
5925:
5926:
5927:
5928:
5929:
5930:
5931:
5932:
5933:
5934:
5935:
5936:
5937:
5938:
5939:
5940:
5941:
5942:
5943:
5944:
5945:
5946:
5947:
5948:
5949:
5950:
5951:
5952:
5953:
5954:
5955:
5956:
5957:
5958:
5959:
5960:
5961:
5962:
5963:
5964:
5965:
5966:
5967:
5968:
5969:
5970:
5971:
5972:
5973:
5974:
5975:
5976:
5977:
5978:
5979:
5980:
5981:
5982:
5983:
5984:
5985:
5986:
5987:
5988:
5989:
5990:
5991:
5992:
5993:
5994:
5995:
5996:
5997:
5998:
5999:
6000:
6001:
6002:
6003:
6004:
6005:
6006:
6007:
6008:
6009:
6010:
6011:
6012:
6013:
6014:
6015:
6016:
6017:
6018:
6019:
6020:
6021:
6022:
6023:
6024:
6025:
6026:
6027:
6028:
6029:
6030:
6031:
6032:
6033:
6034:
6035:
6036:
6037:
6038:
6039:
6040:
6041:
6042:
6043:
6044:
6045:
6046:
6047:
6048:
6049:
6050:
6051:
6052:
6053:
6054:
6055:
6056:
6057:
6058:
6059:
6060:
6061:
6062:
6063:
6064:
6065:
6066:
6067:
6068:
6069:
6070:
6071:
6072:
6073:
6074:
6075:
6076:
6077:
6078:
6079:
6080:
6081:
6082:
6083:
6084:
6085:
6086:
6087:
6088:
6089:
6090:
6091:
6092:
6093:
6094:
6095:
6096:
6097:
6098:
6099:
6100:
6101:
6102:
6103:
6104:
6105:
6106:
6107:
6108:
6109:
6110:
6111:
6112:
6113:
6114:
6115:
6116:
6117:
6118:
6119:
6120:
6121:
6122:
6123:
6124:
6125:
6126:
6127:
6128:
6129:
6130:
6131:
6132:
6133:
6134:
6135:
6136:
6137:
6138:
6139:
6140:
6141:
6142:
6143:
6144:
6145:
6146:
6147:
6148:
6149:
6150:
6151:
6152:
6153:
6154:
6155:
6156:
6157:
6158:
6159:
6160:
6161:
6162:
6163:
6164:
6165:
6166:
6167:
6168:
6169:
6170:
6171:
6172:
6173:
6174:
6175:
6176:
6177:
6178:
6179:
6180:
6181:
6182:
6183:
6184:
6185:
6186:
6187:
6188:
6189:
6190:
6191:
6192:
6193:
6194:
6195:
6196:
6197:
6198:
6199:
6200:
6201:
6202:
6203:
6204:
6205:
6206:
6207:
6208:
6209:
6210:
6211:
6212:
6213:
6214:
6215:
6216:
6217:
6218:
6219:
6220:
6221:
6222:
6223:
6224:
6225:
6226:
6227:
6228:
6229:
6230:
6231:
6232:
6233:
6234:
6235:
6236:
6237:
6238:
6239:
6240:
6241:
6242:
6243:
6244:
6245:
6246:
6247:
6248:
6249:
6250:
6251:
6252:
6253:
6254:
6255:
6256:
6257:
6258:
6259:
6260:
6261:
6262:
6263:
6264:
6265:
6266:
6267:
6268:
6269:
6270:
6271:
6272:
6273:
6274:
6275:
6276:
6277:
6278:
6279:
6280:
6281:
6282:
6283:
6284:
6285:
6286:
6287:
6288:
6289:
6290:
6291:
6292:
6293:
6294:
6295:
6296:
6297:
6298:
6299:
6300:
6301:
6302:
6303:
6304:
6305:
6306:
6307:
6308:
6309:
6310:
6311:
6312:
6313:
6314:
6315:
6316:
6317:
6318:
6319:
6320:
6321:
6322:
6323:
6324:
6325:
6326:
6327:
6328:
6329:
6330:
6331:
6332:
6333:
6334:
6335:
6336:
6337:
6338:
6339:
6340:
6341:
6342:
6343:
6344:
6345:
6346:
6347:
6348:
6349:
6350:
6351:
6352:
6353:
6354:
6355:
6356:
6357:
6358:
6359:
6360:
6361:
6362:
6363:
6364:
6365:
6366:
6367:
6368:
6369:
6370:
6371:
6372:
6373:
6374:
6375:
6376:
6377:
6378:
6379:
6380:
6381:
6382:
6383:
6384:
6385:
6386:
6387:
6388:
6389:
6390:
6391:
6392:
6393:
6394:
6395:
6396:
6397:
6398:
6399:
6400:
6401:
6402:
6403:
6404:
6405:
6406:
6407:
6408:
6409:
6410:
6411:
6412:
6413:
6414:
6415:
6416:
6417:
6418:
6419:
6420:
6421:
6422:
6423:
6424:
6425:
6426:
6427:
6428:
6429:
6430:
6431:
6432:
6433:
6434:
6435:
6436:
6437:
6438:
6439:
6440:
6441:
6442:
6443:
6444:
6445:
6446:
6447:
6448:
6449:
6450:
6451:
6452:
6453:
6454:
6455:
6456:
6457:
6458:
6459:
6460:
6461:
6462:
6463:
6464:
6465:
6466:
6467:
6468:
6469:
6470:
6471:
6472:
6473:
6474:
6475:
6476:
6477:
6478:
6479:
6480:
6481:
6482:
6483:
6484:
6485:
6486:
6487:
6488:
6489:
6490:
6491:
6492:
6493:
6494:
6495:
6496:
6497:
6498:
6499:
6500:
6501:
6502:
6503:
6504:
6505:
6506:
6507:
6508:
6509:
6510:
6511:
6512:
6513:
6514:
6515:
6516:
6517:
6518:
6519:
6520:
6521:
6522:
6523:
6524:
6525:
6526:
6527:
6528:
6529:
6530:
6531:
6532:
6533:
6534:
6535:
6536:
6537:
6538:
6539:
6540:
6541:
6542:
6543:
6544:
6545:
6546:
6547:
6548:
6549:
6550:
6551:
6552:
6553:
6554:
6555:
6556:
6557:
6558:
6559:
6560:
6561:
6562:
6563:
6564:
6565:
6566:
6567:
6568:
6569:
6570:
6571:
6572:
6573:
6574:
6575:
6576:
6577:
6578:
6579:
6580:
6581:
6582:
6583:
6584:
6585:
6586:
6587:
6588:
6589:
6590:
6591:
6592:
6593:
6594:
6595:
6596:
6597:
6598:
6599:
6600:
6601:
6602:
6603:
6604:
6605:
6606:
6607:
6608:
6609:
6610:
Min/Max

























Min/Max























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































/*
* Copyright (c), Zeriph Enterprises
* All rights reserved.
*
* Contributor(s):
* Zechariah Perez, omni (at) zeriph (dot) com
*
* 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_NET_T_HPP)
#define OMNI_NET_T_HPP
#include <omni/defs/global.hpp>
#include <omni/defs/class_macros.hpp>
#include <omni/defs/net_def.hpp>
#include <omni/bits.hpp>
#include <omni/stack_buffer.hpp>

/*
    DEV_NOTE: There are numerous socket functions that are standard, while there are also numerous socket functions
    that are OS/implementation specific. Since there are _too_ many variations on what a socket can do, as well as
    what a socket _might_ be able to do, there are various enum types for the `net` namespace that do not have what
    could potentially be all types. Instead, the user can simply utilize the values they need for the platform they
    are targeting.
*/

namespace omni {
    namespace net {
        class address_family
        {
            public:
                typedef enum enum_t {
                    UNSPECIFIED = AF_UNSPEC,
                    INET = AF_INET,
                    INET6 = AF_INET6,
                    UNIX = AF_UNIX
                } enum_t;
                
                static inline unsigned short COUNT()
                {
                    return 4;
                }

                static inline enum_t DEFAULT_VALUE()
                {
                    return UNSPECIFIED;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, address_family& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, address_family& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }

                address_family() :
                    OMNI_CTOR_FW(omni::net::address_family)
                    m_val(DEFAULT_VALUE())
                { }

                address_family(const address_family& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                address_family(enum_t val) :
                    OMNI_CTOR_FW(omni::net::address_family)
                    m_val(val)
                { }

                ~address_family()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const address_family& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                address_family& operator=(const address_family& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                address_family& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                address_family& operator=(int32_t val)
                {
                    if (!address_family::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                address_family operator|(const address_family& val)
                {
                    return address_family(static_cast<enum_t>(this->m_val | val.m_val));
                }

                address_family operator|(enum_t val)
                {
                    return address_family(static_cast<enum_t>(this->m_val | val));
                }

                address_family operator|(int32_t val)
                {
                    return address_family(static_cast<enum_t>(this->m_val | val));
                }

                address_family& operator|=(const address_family& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val.m_val);
                    return *this;
                }

                address_family& operator|=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                address_family& operator|=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                address_family operator&(const address_family& val)
                {
                    return address_family(static_cast<enum_t>(this->m_val & val.m_val));
                }

                address_family operator&(enum_t val)
                {
                    return address_family(static_cast<enum_t>(this->m_val & val));
                }

                address_family operator&(int32_t val)
                {
                    return address_family(static_cast<enum_t>(this->m_val & val));
                }

                address_family& operator&=(const address_family& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val.m_val);
                    return *this;
                }

                address_family& operator&=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }

                address_family& operator&=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }
                
                address_family& operator++()
                {
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return *this;
                }

                address_family operator++(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    address_family ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return ret;
                }

                address_family& operator--()
                {
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return *this;
                }

                address_family operator--(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    address_family ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return ret;
                }

                address_family operator~()
                {
                    return address_family(static_cast<enum_t>(~static_cast<int32_t>(this->m_val)));
                }

                address_family operator^(const address_family& val)
                {
                    return address_family(static_cast<enum_t>(this->m_val ^ val.m_val));
                }

                address_family operator^(enum_t val)
                {
                    return address_family(static_cast<enum_t>(this->m_val ^ val));
                }

                address_family operator^(int32_t val)
                {
                    return address_family(static_cast<enum_t>(this->m_val ^ val));
                }

                address_family& operator^=(const address_family& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val.m_val);
                    return *this;
                }

                address_family& operator^=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                address_family& operator^=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                address_family operator<<(const address_family& val)
                {
                    return address_family(static_cast<enum_t>(this->m_val << val.m_val));
                }

                address_family operator<<(enum_t val)
                {
                    return address_family(static_cast<enum_t>(this->m_val << val));
                }

                address_family operator<<(int32_t val)
                {
                    return address_family(static_cast<enum_t>(this->m_val << val));
                }

                address_family& operator<<=(const address_family& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val.m_val);
                    return *this;
                }

                address_family& operator<<=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                address_family& operator<<=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                address_family operator>>(const address_family& val)
                {
                    return address_family(static_cast<enum_t>(this->m_val >> val.m_val));
                }

                address_family operator>>(enum_t val)
                {
                    return address_family(static_cast<enum_t>(this->m_val >> val));
                }

                address_family operator>>(int32_t val)
                {
                    return address_family(static_cast<enum_t>(this->m_val >> val));
                }

                address_family& operator>>=(const address_family& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val.m_val);
                    return *this;
                }

                address_family& operator>>=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                address_family& operator>>=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                bool operator<(const address_family& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const address_family& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const address_family& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::address_family) // disposing,name,type(),hash()
                
                OMNI_OSTREAM_FW(omni::net::address_family)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;

                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, address_family& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(UNSPECIFIED)
                        OMNI_S2E_FW(INET)
                        OMNI_S2E_FW(INET6)
                        OMNI_S2E_FW(UNIX)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(UNSPECIFIED);
                        OMNI_E2SS_FW(INET);
                        OMNI_E2SS_FW(INET6);
                        OMNI_E2SS_FW(UNIX);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(UNSPECIFIED) ||
                        OMNI_I2EV_FW(INET) ||
                        OMNI_I2EV_FW(INET6) ||
                        OMNI_I2EV_FW(UNIX)
                    );
                }
        };

        class connection_option
        {
            public:
                typedef enum enum_t {
                    NONE = 0,
                    CONNECTED = 1,
                    BOUND = 2,
                    OPEN = 4,
                    SHUT = 8,
                    LISTEN = 16,
                    // Allow IP4 fallback on IP6 dual stack socket; only valid for the socket6 class
                    ALLOW_IP4_FALLBACK = 32
                } enum_t;
                
                static inline unsigned short COUNT()
                {
                    return 7;
                }

                static inline enum_t DEFAULT_VALUE()
                {
                    return NONE;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, connection_option& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, connection_option& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }

                connection_option() :
                    OMNI_CTOR_FW(omni::net::connection_option)
                    m_val(DEFAULT_VALUE())
                { }

                connection_option(const connection_option& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                connection_option(enum_t val) :
                    OMNI_CTOR_FW(omni::net::connection_option)
                    m_val(val)
                { }

                ~connection_option()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const connection_option& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                connection_option& operator=(const connection_option& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                connection_option& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                connection_option& operator=(int32_t val)
                {
                    if (!connection_option::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                bool operator<(const connection_option& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const connection_option& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const connection_option& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::connection_option) // disposing,name,type(),hash()

                OMNI_OSTREAM_FW(omni::net::connection_option)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;
                
                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, connection_option& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(NONE)
                        OMNI_S2E_FW(CONNECTED)
                        OMNI_S2E_FW(BOUND)
                        OMNI_S2E_FW(OPEN)
                        OMNI_S2E_FW(SHUT)
                        OMNI_S2E_FW(LISTEN)
                        OMNI_S2E_FW(ALLOW_IP4_FALLBACK)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(NONE);
                        OMNI_E2SS_FW(CONNECTED);
                        OMNI_E2SS_FW(BOUND);
                        OMNI_E2SS_FW(OPEN);
                        OMNI_E2SS_FW(SHUT);
                        OMNI_E2SS_FW(LISTEN);
                        OMNI_E2SS_FW(ALLOW_IP4_FALLBACK);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(NONE) ||
                        OMNI_I2EV_FW(CONNECTED) ||
                        OMNI_I2EV_FW(BOUND) ||
                        OMNI_I2EV_FW(OPEN) ||
                        OMNI_I2EV_FW(SHUT) ||
                        OMNI_I2EV_FW(LISTEN) ||
                        OMNI_I2EV_FW(ALLOW_IP4_FALLBACK)
                    );
                }
        };
        
        class protocol_type
        {
            public:
                typedef enum enum_t {
                    UNKNOWN = -1,
                    IP = IPPROTO_IP,
                    ICMP = IPPROTO_ICMP,
                    IGMP = IPPROTO_IGMP,
                    EGP = IPPROTO_EGP,
                    TCP = IPPROTO_TCP,
                    PUP = IPPROTO_PUP,
                    UDP = IPPROTO_UDP,
                    IDP = IPPROTO_IDP,
                    IPV6 = IPPROTO_IPV6,
                    ICMPV6 = IPPROTO_ICMPV6,
                    RAW = IPPROTO_RAW
                } enum_t;
                
                static inline unsigned short COUNT()
                {
                    return 13;
                }

                static inline enum_t DEFAULT_VALUE()
                {
                    return IP;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, protocol_type& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, protocol_type& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }

                protocol_type() :
                    OMNI_CTOR_FW(omni::net::protocol_type)
                    m_val(DEFAULT_VALUE())
                { }

                protocol_type(const protocol_type& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                protocol_type(enum_t val) :
                    OMNI_CTOR_FW(omni::net::protocol_type)
                    m_val(val)
                { }

                ~protocol_type()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const protocol_type& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                protocol_type& operator=(const protocol_type& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                protocol_type& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                protocol_type& operator=(int32_t val)
                {
                    if (!protocol_type::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                protocol_type operator|(const protocol_type& val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val | val.m_val));
                }

                protocol_type operator|(enum_t val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val | val));
                }

                protocol_type operator|(int32_t val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val | val));
                }

                protocol_type& operator|=(const protocol_type& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val.m_val);
                    return *this;
                }

                protocol_type& operator|=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                protocol_type& operator|=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                protocol_type operator&(const protocol_type& val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val & val.m_val));
                }

                protocol_type operator&(enum_t val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val & val));
                }

                protocol_type operator&(int32_t val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val & val));
                }

                protocol_type& operator&=(const protocol_type& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val.m_val);
                    return *this;
                }

                protocol_type& operator&=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }

                protocol_type& operator&=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }
                
                protocol_type& operator++()
                {
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return *this;
                }

                protocol_type operator++(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    protocol_type ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return ret;
                }

                protocol_type& operator--()
                {
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return *this;
                }

                protocol_type operator--(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    protocol_type ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return ret;
                }

                protocol_type operator~()
                {
                    return protocol_type(static_cast<enum_t>(~static_cast<int32_t>(this->m_val)));
                }

                protocol_type operator^(const protocol_type& val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val ^ val.m_val));
                }

                protocol_type operator^(enum_t val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val ^ val));
                }

                protocol_type operator^(int32_t val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val ^ val));
                }

                protocol_type& operator^=(const protocol_type& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val.m_val);
                    return *this;
                }

                protocol_type& operator^=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                protocol_type& operator^=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                protocol_type operator<<(const protocol_type& val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val << val.m_val));
                }

                protocol_type operator<<(enum_t val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val << val));
                }

                protocol_type operator<<(int32_t val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val << val));
                }

                protocol_type& operator<<=(const protocol_type& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val.m_val);
                    return *this;
                }

                protocol_type& operator<<=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                protocol_type& operator<<=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                protocol_type operator>>(const protocol_type& val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val >> val.m_val));
                }

                protocol_type operator>>(enum_t val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val >> val));
                }

                protocol_type operator>>(int32_t val)
                {
                    return protocol_type(static_cast<enum_t>(this->m_val >> val));
                }

                protocol_type& operator>>=(const protocol_type& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val.m_val);
                    return *this;
                }

                protocol_type& operator>>=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                protocol_type& operator>>=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                bool operator<(const protocol_type& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const protocol_type& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const protocol_type& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::protocol_type) // disposing,name,type(),hash()

                OMNI_OSTREAM_FW(omni::net::protocol_type)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;

                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, protocol_type& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(UNKNOWN)
                        OMNI_S2E_FW(IP)
                        OMNI_S2E_FW(ICMP)
                        OMNI_S2E_FW(IGMP)
                        OMNI_S2E_FW(EGP)
                        OMNI_S2E_FW(TCP)
                        OMNI_S2E_FW(PUP)
                        OMNI_S2E_FW(UDP)
                        OMNI_S2E_FW(IDP)
                        OMNI_S2E_FW(IPV6)
                        OMNI_S2E_FW(ICMPV6)
                        OMNI_S2E_FW(RAW)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(UNKNOWN);
                        OMNI_E2SS_FW(IP);
                        OMNI_E2SS_FW(ICMP);
                        OMNI_E2SS_FW(IGMP);
                        OMNI_E2SS_FW(EGP);
                        OMNI_E2SS_FW(TCP);
                        OMNI_E2SS_FW(PUP);
                        OMNI_E2SS_FW(UDP);
                        OMNI_E2SS_FW(IDP);
                        OMNI_E2SS_FW(IPV6);
                        OMNI_E2SS_FW(ICMPV6);
                        OMNI_E2SS_FW(RAW);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(UNKNOWN) ||
                        OMNI_I2EV_FW(IP) ||
                        OMNI_I2EV_FW(ICMP) ||
                        OMNI_I2EV_FW(IGMP) ||
                        OMNI_I2EV_FW(EGP) ||
                        OMNI_I2EV_FW(TCP) ||
                        OMNI_I2EV_FW(PUP) ||
                        OMNI_I2EV_FW(UDP) ||
                        OMNI_I2EV_FW(IDP) ||
                        OMNI_I2EV_FW(IPV6) ||
                        OMNI_I2EV_FW(ICMPV6) ||
                        OMNI_I2EV_FW(RAW)
                    );
                }
        };

        class server_error
        {
            public:
                typedef enum enum_t {
                    UNSPECIFIED = -1,
                    SUCCESS = 0,
                    HOST_ADDRESS_REQUIRED,
                    NO_ADDRESSES_IN_FAMILY,
                    NAME_SERVER_TEMPORARY_FAILURE,
                    INVALID_FLAGS,
                    NAME_SERVER_PERMANENT_FAILURE,
                    ADDRESS_FAMILY_NOT_SUPPORTED,
                    OUT_OF_MEMORY,
                    HOST_EXISTS_NO_ADDRESSES_DEFINED,
                    NODE_OR_SERVICE_NOT_KNOWN,
                    SERVICE_NOT_AVAILABLE_FOR_SOCKET_TYPE,
                    SOCKET_TYPE_NOT_SUPPORTED,
                    SYSTEM_ERROR,
                    IN_PROGRESS = 10036,
                    PROCESS_LIMIT = 10067,
                    SYSTEM_NOT_READY = 10091,
                    VERSION_NOT_SUPPORTED = 10092,
                    NOT_INITIALIZED = 10093
                } enum_t;
                
                static inline unsigned short COUNT()
                {
                    return 19;
                }

                static inline enum_t DEFAULT_VALUE()
                {
                    return UNSPECIFIED;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, server_error& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, server_error& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }
                
                server_error() :
                    OMNI_CTOR_FW(omni::net::server_error)
                    m_val(DEFAULT_VALUE())
                { }

                server_error(const server_error& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                server_error(enum_t val) :
                    OMNI_CTOR_FW(omni::net::server_error)
                    m_val(val)
                { }

                ~server_error()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const server_error& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                server_error& operator=(const server_error& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                server_error& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                server_error& operator=(int32_t val)
                {
                    if (!server_error::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                server_error operator|(const server_error& val)
                {
                    return server_error(static_cast<enum_t>(this->m_val | val.m_val));
                }

                server_error operator|(enum_t val)
                {
                    return server_error(static_cast<enum_t>(this->m_val | val));
                }

                server_error operator|(int32_t val)
                {
                    return server_error(static_cast<enum_t>(this->m_val | val));
                }

                server_error& operator|=(const server_error& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val.m_val);
                    return *this;
                }

                server_error& operator|=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                server_error& operator|=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                server_error operator&(const server_error& val)
                {
                    return server_error(static_cast<enum_t>(this->m_val & val.m_val));
                }

                server_error operator&(enum_t val)
                {
                    return server_error(static_cast<enum_t>(this->m_val & val));
                }

                server_error operator&(int32_t val)
                {
                    return server_error(static_cast<enum_t>(this->m_val & val));
                }

                server_error& operator&=(const server_error& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val.m_val);
                    return *this;
                }

                server_error& operator&=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }

                server_error& operator&=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }
                
                server_error& operator++()
                {
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return *this;
                }

                server_error operator++(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    server_error ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return ret;
                }

                server_error& operator--()
                {
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return *this;
                }

                server_error operator--(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    server_error ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return ret;
                }

                server_error operator~()
                {
                    return server_error(static_cast<enum_t>(~static_cast<int32_t>(this->m_val)));
                }

                server_error operator^(const server_error& val)
                {
                    return server_error(static_cast<enum_t>(this->m_val ^ val.m_val));
                }

                server_error operator^(enum_t val)
                {
                    return server_error(static_cast<enum_t>(this->m_val ^ val));
                }

                server_error operator^(int32_t val)
                {
                    return server_error(static_cast<enum_t>(this->m_val ^ val));
                }

                server_error& operator^=(const server_error& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val.m_val);
                    return *this;
                }

                server_error& operator^=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                server_error& operator^=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                server_error operator<<(const server_error& val)
                {
                    return server_error(static_cast<enum_t>(this->m_val << val.m_val));
                }

                server_error operator<<(enum_t val)
                {
                    return server_error(static_cast<enum_t>(this->m_val << val));
                }

                server_error operator<<(int32_t val)
                {
                    return server_error(static_cast<enum_t>(this->m_val << val));
                }

                server_error& operator<<=(const server_error& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val.m_val);
                    return *this;
                }

                server_error& operator<<=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                server_error& operator<<=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                server_error operator>>(const server_error& val)
                {
                    return server_error(static_cast<enum_t>(this->m_val >> val.m_val));
                }

                server_error operator>>(enum_t val)
                {
                    return server_error(static_cast<enum_t>(this->m_val >> val));
                }

                server_error operator>>(int32_t val)
                {
                    return server_error(static_cast<enum_t>(this->m_val >> val));
                }

                server_error& operator>>=(const server_error& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val.m_val);
                    return *this;
                }

                server_error& operator>>=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                server_error& operator>>=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                bool operator<(const server_error& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const server_error& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const server_error& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::server_error) // disposing,name,type(),hash()

                OMNI_OSTREAM_FW(omni::net::server_error)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;
                
                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, server_error& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(UNSPECIFIED)
                        OMNI_S2E_FW(SUCCESS)
                        OMNI_S2E_FW(HOST_ADDRESS_REQUIRED)
                        OMNI_S2E_FW(NO_ADDRESSES_IN_FAMILY)
                        OMNI_S2E_FW(NAME_SERVER_TEMPORARY_FAILURE)
                        OMNI_S2E_FW(INVALID_FLAGS)
                        OMNI_S2E_FW(NAME_SERVER_PERMANENT_FAILURE)
                        OMNI_S2E_FW(ADDRESS_FAMILY_NOT_SUPPORTED)
                        OMNI_S2E_FW(OUT_OF_MEMORY)
                        OMNI_S2E_FW(HOST_EXISTS_NO_ADDRESSES_DEFINED)
                        OMNI_S2E_FW(NODE_OR_SERVICE_NOT_KNOWN)
                        OMNI_S2E_FW(SERVICE_NOT_AVAILABLE_FOR_SOCKET_TYPE)
                        OMNI_S2E_FW(SOCKET_TYPE_NOT_SUPPORTED)
                        OMNI_S2E_FW(SYSTEM_ERROR)
                        OMNI_S2E_FW(IN_PROGRESS)
                        OMNI_S2E_FW(PROCESS_LIMIT)
                        OMNI_S2E_FW(SYSTEM_NOT_READY)
                        OMNI_S2E_FW(VERSION_NOT_SUPPORTED)
                        OMNI_S2E_FW(NOT_INITIALIZED)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(UNSPECIFIED);
                        OMNI_E2SS_FW(SUCCESS);
                        OMNI_E2SS_FW(HOST_ADDRESS_REQUIRED);
                        OMNI_E2SS_FW(NO_ADDRESSES_IN_FAMILY);
                        OMNI_E2SS_FW(NAME_SERVER_TEMPORARY_FAILURE);
                        OMNI_E2SS_FW(INVALID_FLAGS);
                        OMNI_E2SS_FW(NAME_SERVER_PERMANENT_FAILURE);
                        OMNI_E2SS_FW(ADDRESS_FAMILY_NOT_SUPPORTED);
                        OMNI_E2SS_FW(OUT_OF_MEMORY);
                        OMNI_E2SS_FW(HOST_EXISTS_NO_ADDRESSES_DEFINED);
                        OMNI_E2SS_FW(NODE_OR_SERVICE_NOT_KNOWN);
                        OMNI_E2SS_FW(SERVICE_NOT_AVAILABLE_FOR_SOCKET_TYPE);
                        OMNI_E2SS_FW(SOCKET_TYPE_NOT_SUPPORTED);
                        OMNI_E2SS_FW(SYSTEM_ERROR);
                        OMNI_E2SS_FW(IN_PROGRESS);
                        OMNI_E2SS_FW(PROCESS_LIMIT);
                        OMNI_E2SS_FW(SYSTEM_NOT_READY);
                        OMNI_E2SS_FW(VERSION_NOT_SUPPORTED);
                        OMNI_E2SS_FW(NOT_INITIALIZED);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(UNSPECIFIED) ||
                        OMNI_I2EV_FW(SUCCESS) ||
                        OMNI_I2EV_FW(HOST_ADDRESS_REQUIRED) ||
                        OMNI_I2EV_FW(NO_ADDRESSES_IN_FAMILY) ||
                        OMNI_I2EV_FW(NAME_SERVER_TEMPORARY_FAILURE) ||
                        OMNI_I2EV_FW(INVALID_FLAGS) ||
                        OMNI_I2EV_FW(NAME_SERVER_PERMANENT_FAILURE) ||
                        OMNI_I2EV_FW(ADDRESS_FAMILY_NOT_SUPPORTED) ||
                        OMNI_I2EV_FW(OUT_OF_MEMORY) ||
                        OMNI_I2EV_FW(HOST_EXISTS_NO_ADDRESSES_DEFINED) ||
                        OMNI_I2EV_FW(NODE_OR_SERVICE_NOT_KNOWN) ||
                        OMNI_I2EV_FW(SERVICE_NOT_AVAILABLE_FOR_SOCKET_TYPE) ||
                        OMNI_I2EV_FW(SOCKET_TYPE_NOT_SUPPORTED) ||
                        OMNI_I2EV_FW(SYSTEM_ERROR) ||
                        OMNI_I2EV_FW(IN_PROGRESS) ||
                        OMNI_I2EV_FW(PROCESS_LIMIT) ||
                        OMNI_I2EV_FW(SYSTEM_NOT_READY) ||
                        OMNI_I2EV_FW(VERSION_NOT_SUPPORTED) ||
                        OMNI_I2EV_FW(NOT_INITIALIZED)
                    );
                }
        };

        class socket_error
        {
            public:
                typedef enum enum_t {
                    UNSPECIFIED = -1,
                    SUCCESS = 0,
                    OPERATION_ABORTED = OMNI_SOCK_ERR_OPERATION_ABORTED_FW,
                    IO_ERROR = OMNI_SOCK_ERR_IO_ERROR_FW,
                    IO_PENDING = OMNI_SOCK_ERR_IO_PENDING_FW,
                    INTERRUPTED = OMNI_SOCK_ERR_INTERRUPTED_FW,
                    PERMISSION = OMNI_SOCK_ERR_PERMISSION_FW,
                    ACCESS_DENIED = OMNI_SOCK_ERR_ACCESS_DENIED_FW,
                    FAULT = OMNI_SOCK_ERR_FAULT_FW,
                    INSUFFICIENT_MEMORY = OMNI_SOCK_ERR_INSUFFICIENT_MEMORY_FW,
                    INVALID_ARGUMENT = OMNI_SOCK_ERR_INVALID_ARGUMENT_FW,
                    INVALID_DESCRIPTOR = OMNI_SOCK_ERR_INVALID_DESCRIPTOR_FW,
                    TOO_MANY_OPEN_SOCKETS = OMNI_SOCK_ERR_TOO_MANY_OPEN_SOCKETS_FW,
                    WOULD_BLOCK = OMNI_SOCK_ERR_WOULD_BLOCK_FW,
                    IN_PROGRESS = OMNI_SOCK_ERR_IN_PROGRESS_FW,
                    ALREADY_IN_PROGRESS = OMNI_SOCK_ERR_ALREADY_IN_PROGRESS_FW,
                    NOT_SOCKET = OMNI_SOCK_ERR_NOT_SOCKET_FW,
                    DESTINATION_ADDRESS_REQUIRED = OMNI_SOCK_ERR_DESTINATION_ADDRESS_REQUIRED_FW,
                    MESSAGE_SIZE = OMNI_SOCK_ERR_MESSAGE_SIZE_FW,
                    PROTOCOL_TYPE = OMNI_SOCK_ERR_PROTOCOL_TYPE_FW,
                    PROTOCOL_OPTION = OMNI_SOCK_ERR_PROTOCOL_OPTION_FW,
                    PROTOCOL_NOT_SUPPORTED = OMNI_SOCK_ERR_PROTOCOL_NOT_SUPPORTED_FW,
                    SOCKET_NOT_SUPPORTED = OMNI_SOCK_ERR_SOCKET_NOT_SUPPORTED_FW,
                    OPERATION_NOT_SUPPORTED = OMNI_SOCK_ERR_OPERATION_NOT_SUPPORTED_FW,
                    PROTOCOL_FAMILY_NOT_SUPPORTED = OMNI_SOCK_ERR_PROTOCOL_FAMILY_NOT_SUPPORTED_FW,
                    ADDRESS_FAMILY_NOT_SUPPORTED = OMNI_SOCK_ERR_ADDRESS_FAMILY_NOT_SUPPORTED_FW,
                    ADDRESS_ALREADY_IN_USE = OMNI_SOCK_ERR_ADDRESS_ALREADY_IN_USE_FW,
                    ADDRESS_NOT_AVAILABLE = OMNI_SOCK_ERR_ADDRESS_NOT_AVAILABLE_FW,
                    NETWORK_DOWN = OMNI_SOCK_ERR_NETWORK_DOWN_FW,
                    NETWORK_UNREACHABLE = OMNI_SOCK_ERR_NETWORK_UNREACHABLE_FW,
                    NETWORK_RESET = OMNI_SOCK_ERR_NETWORK_RESET_FW,
                    CONNECTION_ABORTED = OMNI_SOCK_ERR_CONNECTION_ABORTED_FW,
                    CONNECTION_RESET = OMNI_SOCK_ERR_CONNECTION_RESET_FW,
                    NO_BUFFER_SPACE_AVAILABLE = OMNI_SOCK_ERR_NO_BUFFER_SPACE_AVAILABLE_FW,
                    IS_CONNECTED = OMNI_SOCK_ERR_IS_CONNECTED_FW,
                    NOT_CONNECTED = OMNI_SOCK_ERR_NOT_CONNECTED_FW,
                    SHUTDOWN = OMNI_SOCK_ERR_SHUTDOWN_FW,
                    TIMED_OUT = OMNI_SOCK_ERR_TIMED_OUT_FW,
                    CONNECTION_REFUSED = OMNI_SOCK_ERR_CONNECTION_REFUSED_FW,
                    LOOP = OMNI_SOCK_ERR_LOOP_FW,
                    NAME_TOO_LONG = OMNI_SOCK_ERR_NAME_TOO_LONG_FW,
                    HOST_DOWN = OMNI_SOCK_ERR_HOST_DOWN_FW,
                    HOST_UNREACHABLE = OMNI_SOCK_ERR_HOST_UNREACHABLE_FW,
                    PROCESS_LIMIT = OMNI_SOCK_ERR_PROCESS_LIMIT_FW,
                    SYSTEM_NOT_READY = OMNI_SOCK_ERR_SYSTEM_NOT_READY_FW,
                    VERSION_NOT_SUPPORTED = OMNI_SOCK_ERR_VERSION_NOT_SUPPORTED_FW,
                    NOT_INITIALIZED = OMNI_SOCK_ERR_NOT_INITIALIZED_FW,
                    DISCONNECTING = OMNI_SOCK_ERR_DISCONNECTING_FW,
                    TYPE_NOT_FOUND = OMNI_SOCK_ERR_TYPE_NOT_FOUND_FW,
                    NO_HOST = OMNI_SOCK_ERR_NO_HOST_FW,     // DEV_NOTE: HOST_NOT_FOUND is a #define in netdb.h
                    AGAIN = OMNI_SOCK_ERR_AGAIN_FW,         // DEV_NOTE: TRY_AGAIN is a #define in netdb.h
                    NO_RECOVER = OMNI_SOCK_ERR_NO_RECOVER_FW, // DEV_NOTE: NO_RECOVERY is a #define in netdb.h
                    NO_DAT = OMNI_SOCK_ERR_NO_DAT_FW         // DEV_NOTE: NO_DATA is a #define in netdb.h
                } enum_t;
                
                static inline unsigned short COUNT()
                {
                    return 53;
                }

                static inline enum_t DEFAULT_VALUE()
                {
                    return UNSPECIFIED;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, socket_error& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, socket_error& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }
                
                socket_error() :
                    OMNI_CTOR_FW(omni::net::socket_error)
                    m_val(DEFAULT_VALUE())
                { }

                socket_error(const socket_error& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                socket_error(enum_t val) :
                    OMNI_CTOR_FW(omni::net::socket_error)
                    m_val(val)
                { }

                ~socket_error()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const socket_error& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                socket_error& operator=(const socket_error& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                socket_error& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                socket_error& operator=(int32_t val)
                {
                    if (!socket_error::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                socket_error operator|(const socket_error& val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val | val.m_val));
                }

                socket_error operator|(enum_t val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val | val));
                }

                socket_error operator|(int32_t val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val | val));
                }

                socket_error& operator|=(const socket_error& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val.m_val);
                    return *this;
                }

                socket_error& operator|=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_error& operator|=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_error operator&(const socket_error& val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val & val.m_val));
                }

                socket_error operator&(enum_t val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val & val));
                }

                socket_error operator&(int32_t val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val & val));
                }

                socket_error& operator&=(const socket_error& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val.m_val);
                    return *this;
                }

                socket_error& operator&=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }

                socket_error& operator&=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }
                
                socket_error& operator++()
                {
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return *this;
                }

                socket_error operator++(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_error ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return ret;
                }

                socket_error& operator--()
                {
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return *this;
                }

                socket_error operator--(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_error ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return ret;
                }

                socket_error operator~()
                {
                    return socket_error(static_cast<enum_t>(~static_cast<int32_t>(this->m_val)));
                }

                socket_error operator^(const socket_error& val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val ^ val.m_val));
                }

                socket_error operator^(enum_t val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_error operator^(int32_t val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_error& operator^=(const socket_error& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val.m_val);
                    return *this;
                }

                socket_error& operator^=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_error& operator^=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_error operator<<(const socket_error& val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val << val.m_val));
                }

                socket_error operator<<(enum_t val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val << val));
                }

                socket_error operator<<(int32_t val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val << val));
                }

                socket_error& operator<<=(const socket_error& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val.m_val);
                    return *this;
                }

                socket_error& operator<<=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_error& operator<<=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_error operator>>(const socket_error& val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val >> val.m_val));
                }

                socket_error operator>>(enum_t val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val >> val));
                }

                socket_error operator>>(int32_t val)
                {
                    return socket_error(static_cast<enum_t>(this->m_val >> val));
                }

                socket_error& operator>>=(const socket_error& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val.m_val);
                    return *this;
                }

                socket_error& operator>>=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                socket_error& operator>>=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                bool operator<(const socket_error& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const socket_error& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const socket_error& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::socket_error) // disposing,name,type(),hash()

                OMNI_OSTREAM_FW(omni::net::socket_error)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;
                
                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, socket_error& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(UNSPECIFIED)
                        OMNI_S2E_FW(SUCCESS)
                        OMNI_S2E_FW(OPERATION_ABORTED)
                        OMNI_S2E_FW(IO_ERROR)
                        OMNI_S2E_FW(IO_PENDING)
                        OMNI_S2E_FW(INTERRUPTED)
                        OMNI_S2E_FW(PERMISSION)
                        OMNI_S2E_FW(ACCESS_DENIED)
                        OMNI_S2E_FW(FAULT)
                        OMNI_S2E_FW(INSUFFICIENT_MEMORY)
                        OMNI_S2E_FW(INVALID_ARGUMENT)
                        OMNI_S2E_FW(INVALID_DESCRIPTOR)
                        OMNI_S2E_FW(TOO_MANY_OPEN_SOCKETS)
                        OMNI_S2E_FW(WOULD_BLOCK)
                        OMNI_S2E_FW(IN_PROGRESS)
                        OMNI_S2E_FW(ALREADY_IN_PROGRESS)
                        OMNI_S2E_FW(NOT_SOCKET)
                        OMNI_S2E_FW(DESTINATION_ADDRESS_REQUIRED)
                        OMNI_S2E_FW(MESSAGE_SIZE)
                        OMNI_S2E_FW(PROTOCOL_TYPE)
                        OMNI_S2E_FW(PROTOCOL_OPTION)
                        OMNI_S2E_FW(PROTOCOL_NOT_SUPPORTED)
                        OMNI_S2E_FW(SOCKET_NOT_SUPPORTED)
                        OMNI_S2E_FW(OPERATION_NOT_SUPPORTED)
                        OMNI_S2E_FW(PROTOCOL_FAMILY_NOT_SUPPORTED)
                        OMNI_S2E_FW(ADDRESS_FAMILY_NOT_SUPPORTED)
                        OMNI_S2E_FW(ADDRESS_ALREADY_IN_USE)
                        OMNI_S2E_FW(ADDRESS_NOT_AVAILABLE)
                        OMNI_S2E_FW(NETWORK_DOWN)
                        OMNI_S2E_FW(NETWORK_UNREACHABLE)
                        OMNI_S2E_FW(NETWORK_RESET)
                        OMNI_S2E_FW(CONNECTION_ABORTED)
                        OMNI_S2E_FW(CONNECTION_RESET)
                        OMNI_S2E_FW(NO_BUFFER_SPACE_AVAILABLE)
                        OMNI_S2E_FW(IS_CONNECTED)
                        OMNI_S2E_FW(NOT_CONNECTED)
                        OMNI_S2E_FW(SHUTDOWN)
                        OMNI_S2E_FW(TIMED_OUT)
                        OMNI_S2E_FW(CONNECTION_REFUSED)
                        OMNI_S2E_FW(LOOP)
                        OMNI_S2E_FW(NAME_TOO_LONG)
                        OMNI_S2E_FW(HOST_DOWN)
                        OMNI_S2E_FW(HOST_UNREACHABLE)
                        OMNI_S2E_FW(PROCESS_LIMIT)
                        OMNI_S2E_FW(SYSTEM_NOT_READY)
                        OMNI_S2E_FW(VERSION_NOT_SUPPORTED)
                        OMNI_S2E_FW(NOT_INITIALIZED)
                        OMNI_S2E_FW(DISCONNECTING)
                        OMNI_S2E_FW(TYPE_NOT_FOUND)
                        OMNI_S2E_FW(NO_HOST)
                        OMNI_S2E_FW(AGAIN)
                        OMNI_S2E_FW(NO_RECOVER)
                        OMNI_S2E_FW(NO_DAT)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(UNSPECIFIED);
                        OMNI_E2SS_FW(SUCCESS);
                        OMNI_E2SS_FW(OPERATION_ABORTED);
                        OMNI_E2SS_FW(IO_ERROR);
                        OMNI_E2SS_FW(IO_PENDING);
                        OMNI_E2SS_FW(INTERRUPTED);
                        OMNI_E2SS_FW(PERMISSION);
                        OMNI_E2SS_FW(ACCESS_DENIED);
                        OMNI_E2SS_FW(FAULT);
                        OMNI_E2SS_FW(INSUFFICIENT_MEMORY);
                        OMNI_E2SS_FW(INVALID_ARGUMENT);
                        OMNI_E2SS_FW(INVALID_DESCRIPTOR);
                        OMNI_E2SS_FW(TOO_MANY_OPEN_SOCKETS);
                        OMNI_E2SS_FW(WOULD_BLOCK);
                        OMNI_E2SS_FW(IN_PROGRESS);
                        OMNI_E2SS_FW(ALREADY_IN_PROGRESS);
                        OMNI_E2SS_FW(NOT_SOCKET);
                        OMNI_E2SS_FW(DESTINATION_ADDRESS_REQUIRED);
                        OMNI_E2SS_FW(MESSAGE_SIZE);
                        OMNI_E2SS_FW(PROTOCOL_TYPE);
                        OMNI_E2SS_FW(PROTOCOL_OPTION);
                        OMNI_E2SS_FW(PROTOCOL_NOT_SUPPORTED);
                        OMNI_E2SS_FW(SOCKET_NOT_SUPPORTED);
                        OMNI_E2SS_FW(OPERATION_NOT_SUPPORTED);
                        OMNI_E2SS_FW(PROTOCOL_FAMILY_NOT_SUPPORTED);
                        OMNI_E2SS_FW(ADDRESS_FAMILY_NOT_SUPPORTED);
                        OMNI_E2SS_FW(ADDRESS_ALREADY_IN_USE);
                        OMNI_E2SS_FW(ADDRESS_NOT_AVAILABLE);
                        OMNI_E2SS_FW(NETWORK_DOWN);
                        OMNI_E2SS_FW(NETWORK_UNREACHABLE);
                        OMNI_E2SS_FW(NETWORK_RESET);
                        OMNI_E2SS_FW(CONNECTION_ABORTED);
                        OMNI_E2SS_FW(CONNECTION_RESET);
                        OMNI_E2SS_FW(NO_BUFFER_SPACE_AVAILABLE);
                        OMNI_E2SS_FW(IS_CONNECTED);
                        OMNI_E2SS_FW(NOT_CONNECTED);
                        OMNI_E2SS_FW(SHUTDOWN);
                        OMNI_E2SS_FW(TIMED_OUT);
                        OMNI_E2SS_FW(CONNECTION_REFUSED);
                        OMNI_E2SS_FW(LOOP);
                        OMNI_E2SS_FW(NAME_TOO_LONG);
                        OMNI_E2SS_FW(HOST_DOWN);
                        OMNI_E2SS_FW(HOST_UNREACHABLE);
                        OMNI_E2SS_FW(PROCESS_LIMIT);
                        OMNI_E2SS_FW(SYSTEM_NOT_READY);
                        OMNI_E2SS_FW(VERSION_NOT_SUPPORTED);
                        OMNI_E2SS_FW(NOT_INITIALIZED);
                        OMNI_E2SS_FW(DISCONNECTING);
                        OMNI_E2SS_FW(TYPE_NOT_FOUND);
                        OMNI_E2SS_FW(NO_HOST);
                        OMNI_E2SS_FW(AGAIN);
                        OMNI_E2SS_FW(NO_RECOVER);
                        OMNI_E2SS_FW(NO_DAT);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(UNSPECIFIED) ||
                        OMNI_I2EV_FW(SUCCESS) ||
                        OMNI_I2EV_FW(OPERATION_ABORTED) ||
                        OMNI_I2EV_FW(IO_ERROR) ||
                        OMNI_I2EV_FW(IO_PENDING) ||
                        OMNI_I2EV_FW(INTERRUPTED) ||
                        OMNI_I2EV_FW(PERMISSION) ||
                        OMNI_I2EV_FW(ACCESS_DENIED) ||
                        OMNI_I2EV_FW(FAULT) ||
                        OMNI_I2EV_FW(INSUFFICIENT_MEMORY) ||
                        OMNI_I2EV_FW(INVALID_ARGUMENT) ||
                        OMNI_I2EV_FW(INVALID_DESCRIPTOR) ||
                        OMNI_I2EV_FW(TOO_MANY_OPEN_SOCKETS) ||
                        OMNI_I2EV_FW(WOULD_BLOCK) ||
                        OMNI_I2EV_FW(IN_PROGRESS) ||
                        OMNI_I2EV_FW(ALREADY_IN_PROGRESS) ||
                        OMNI_I2EV_FW(NOT_SOCKET) ||
                        OMNI_I2EV_FW(DESTINATION_ADDRESS_REQUIRED) ||
                        OMNI_I2EV_FW(MESSAGE_SIZE) ||
                        OMNI_I2EV_FW(PROTOCOL_TYPE) ||
                        OMNI_I2EV_FW(PROTOCOL_OPTION) ||
                        OMNI_I2EV_FW(PROTOCOL_NOT_SUPPORTED) ||
                        OMNI_I2EV_FW(SOCKET_NOT_SUPPORTED) ||
                        OMNI_I2EV_FW(OPERATION_NOT_SUPPORTED) ||
                        OMNI_I2EV_FW(PROTOCOL_FAMILY_NOT_SUPPORTED) ||
                        OMNI_I2EV_FW(ADDRESS_FAMILY_NOT_SUPPORTED) ||
                        OMNI_I2EV_FW(ADDRESS_ALREADY_IN_USE) ||
                        OMNI_I2EV_FW(ADDRESS_NOT_AVAILABLE) ||
                        OMNI_I2EV_FW(NETWORK_DOWN) ||
                        OMNI_I2EV_FW(NETWORK_UNREACHABLE) ||
                        OMNI_I2EV_FW(NETWORK_RESET) ||
                        OMNI_I2EV_FW(CONNECTION_ABORTED) ||
                        OMNI_I2EV_FW(CONNECTION_RESET) ||
                        OMNI_I2EV_FW(NO_BUFFER_SPACE_AVAILABLE) ||
                        OMNI_I2EV_FW(IS_CONNECTED) ||
                        OMNI_I2EV_FW(NOT_CONNECTED) ||
                        OMNI_I2EV_FW(SHUTDOWN) ||
                        OMNI_I2EV_FW(TIMED_OUT) ||
                        OMNI_I2EV_FW(CONNECTION_REFUSED) ||
                        OMNI_I2EV_FW(LOOP) ||
                        OMNI_I2EV_FW(NAME_TOO_LONG) ||
                        OMNI_I2EV_FW(HOST_DOWN) ||
                        OMNI_I2EV_FW(HOST_UNREACHABLE) ||
                        OMNI_I2EV_FW(PROCESS_LIMIT) ||
                        OMNI_I2EV_FW(SYSTEM_NOT_READY) ||
                        OMNI_I2EV_FW(VERSION_NOT_SUPPORTED) ||
                        OMNI_I2EV_FW(NOT_INITIALIZED) ||
                        OMNI_I2EV_FW(DISCONNECTING) ||
                        OMNI_I2EV_FW(TYPE_NOT_FOUND) ||
                        OMNI_I2EV_FW(NO_HOST) ||
                        OMNI_I2EV_FW(AGAIN) ||
                        OMNI_I2EV_FW(NO_RECOVER) ||
                        OMNI_I2EV_FW(NO_DAT)
                    );
                }
        };
        
        class socket_flags
        {
            public:
                typedef enum enum_t {
                    NONE = OMNI_SOCK_FLAGS_NONE,
                    OUT_OF_BAND = MSG_OOB,             // 1
                    PEEK = MSG_PEEK,                    // 2
                    DONT_ROUTE = MSG_DONTROUTE,         // 4
                    END_OF_RECORD = OMNI_MSG_EOR_FW    // 8 (0 for Windows)
                } enum_t;

                static inline unsigned short COUNT()
                {
                    return 5;
                }

                static inline enum_t DEFAULT_VALUE()
                {
                    return NONE;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, socket_flags& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, socket_flags& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }
                
                socket_flags() :
                    OMNI_CTOR_FW(omni::net::socket_flags)
                    m_val(DEFAULT_VALUE())
                { }

                socket_flags(const socket_flags& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                socket_flags(enum_t val) :
                    OMNI_CTOR_FW(omni::net::socket_flags)
                    m_val(val)
                { }

                ~socket_flags()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const socket_flags& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                socket_flags& operator=(const socket_flags& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                socket_flags& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                socket_flags& operator=(int32_t val)
                {
                    if (!socket_flags::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                socket_flags operator|(const socket_flags& val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val | val.m_val));
                }

                socket_flags operator|(enum_t val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val | val));
                }

                socket_flags operator|(int32_t val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val | val));
                }

                socket_flags& operator|=(const socket_flags& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val.m_val);
                    return *this;
                }

                socket_flags& operator|=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_flags& operator|=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_flags operator&(const socket_flags& val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val & val.m_val));
                }

                socket_flags operator&(enum_t val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val & val));
                }

                socket_flags operator&(int32_t val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val & val));
                }

                socket_flags& operator&=(const socket_flags& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val.m_val);
                    return *this;
                }

                socket_flags& operator&=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }

                socket_flags& operator&=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }
                
                socket_flags& operator++()
                {
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return *this;
                }

                socket_flags operator++(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_flags ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return ret;
                }

                socket_flags& operator--()
                {
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return *this;
                }

                socket_flags operator--(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_flags ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return ret;
                }

                socket_flags operator~()
                {
                    return socket_flags(static_cast<enum_t>(~static_cast<int32_t>(this->m_val)));
                }

                socket_flags operator^(const socket_flags& val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val ^ val.m_val));
                }

                socket_flags operator^(enum_t val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_flags operator^(int32_t val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_flags& operator^=(const socket_flags& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val.m_val);
                    return *this;
                }

                socket_flags& operator^=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_flags& operator^=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_flags operator<<(const socket_flags& val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val << val.m_val));
                }

                socket_flags operator<<(enum_t val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val << val));
                }

                socket_flags operator<<(int32_t val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val << val));
                }

                socket_flags& operator<<=(const socket_flags& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val.m_val);
                    return *this;
                }

                socket_flags& operator<<=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_flags& operator<<=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_flags operator>>(const socket_flags& val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val >> val.m_val));
                }

                socket_flags operator>>(enum_t val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val >> val));
                }

                socket_flags operator>>(int32_t val)
                {
                    return socket_flags(static_cast<enum_t>(this->m_val >> val));
                }

                socket_flags& operator>>=(const socket_flags& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val.m_val);
                    return *this;
                }

                socket_flags& operator>>=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                socket_flags& operator>>=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                bool operator<(const socket_flags& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const socket_flags& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const socket_flags& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::socket_flags) // disposing,name,type(),hash()

                OMNI_OSTREAM_FW(omni::net::socket_flags)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;

                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, socket_flags& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(NONE)
                        OMNI_S2E_FW(OUT_OF_BAND)
                        OMNI_S2E_FW(PEEK)
                        OMNI_S2E_FW(DONT_ROUTE)
                        OMNI_S2E_FW(END_OF_RECORD)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(NONE);
                        OMNI_E2SS_FW(OUT_OF_BAND);
                        OMNI_E2SS_FW(PEEK);
                        OMNI_E2SS_FW(DONT_ROUTE);
                        OMNI_E2SS_FW(END_OF_RECORD);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(NONE) ||
                        OMNI_I2EV_FW(OUT_OF_BAND) ||
                        OMNI_I2EV_FW(PEEK) ||
                        OMNI_I2EV_FW(DONT_ROUTE) ||
                        OMNI_I2EV_FW(END_OF_RECORD)
                    );
                }
        };

        class select_mode
        {
            public:
                typedef enum enum_t {
                    NONE = -1,
                    SELECT_READ = 0,
                    SELECT_WRITE = 1,
                    SELECT_ERROR = 2
                } enum_t;
                
                static inline unsigned short COUNT()
                {
                    return 4;
                }
                
                static inline enum_t DEFAULT_VALUE()
                {
                    return NONE;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, select_mode& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, select_mode& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }
                
                select_mode() :
                    OMNI_CTOR_FW(omni::net::select_mode)
                    m_val(DEFAULT_VALUE())
                { }

                select_mode(const select_mode& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                select_mode(enum_t val) :
                    OMNI_CTOR_FW(omni::net::select_mode)
                    m_val(val)
                { }

                ~select_mode()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const select_mode& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                select_mode& operator=(const select_mode& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                select_mode& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                select_mode& operator=(int32_t val)
                {
                    if (!select_mode::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                bool operator<(const select_mode& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const select_mode& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const select_mode& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::select_mode) // disposing,name,type(),hash()
                
                OMNI_OSTREAM_FW(omni::net::select_mode)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;

                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, select_mode& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(NONE)
                        OMNI_S2E_FW(SELECT_READ)
                        OMNI_S2E_FW(SELECT_WRITE)
                        OMNI_S2E_FW(SELECT_ERROR)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(NONE);
                        OMNI_E2SS_FW(SELECT_READ);
                        OMNI_E2SS_FW(SELECT_WRITE);
                        OMNI_E2SS_FW(SELECT_ERROR);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(NONE) ||
                        OMNI_I2EV_FW(SELECT_READ) ||
                        OMNI_I2EV_FW(SELECT_WRITE) ||
                        OMNI_I2EV_FW(SELECT_ERROR)
                    );
                }
        };

        class blocking_mode
        {
            public:
                typedef enum enum_t {
                    BLOCK = 0,
                    DONT_BLOCK = 1
                } enum_t;
                
                static inline unsigned short COUNT()
                {
                    return 2;
                }
                
                static inline enum_t DEFAULT_VALUE()
                {
                    return BLOCK;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, blocking_mode& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, blocking_mode& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }
                
                blocking_mode() :
                    OMNI_CTOR_FW(omni::net::blocking_mode)
                    m_val(DEFAULT_VALUE())
                { }

                blocking_mode(const blocking_mode& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                blocking_mode(enum_t val) :
                    OMNI_CTOR_FW(omni::net::blocking_mode)
                    m_val(val)
                { }

                ~blocking_mode()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const blocking_mode& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                blocking_mode& operator=(const blocking_mode& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                blocking_mode& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                blocking_mode& operator=(int32_t val)
                {
                    if (!blocking_mode::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                bool operator<(const blocking_mode& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const blocking_mode& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const blocking_mode& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::blocking_mode) // disposing,name,type(),hash()
                
                OMNI_OSTREAM_FW(omni::net::blocking_mode)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;

                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, blocking_mode& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(BLOCK)
                        OMNI_S2E_FW(DONT_BLOCK)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(BLOCK);
                        OMNI_E2SS_FW(DONT_BLOCK);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(BLOCK) ||
                        OMNI_I2EV_FW(DONT_BLOCK)
                    );
                }
        };

        class socket_option_level
        {
            public:
                typedef enum enum_t {
                    UNSPECIFIED = -1,
                    IP = IPPROTO_IP, // 0
                    IP6 = IPPROTO_IPV6, // 41
                    TCP = IPPROTO_TCP, // 6
                    UDP = IPPROTO_UDP, //17
                    SOCKET = SOL_SOCKET // 65535
                } enum_t;
                
                static inline unsigned short COUNT()
                {
                    return 6;
                }

                static inline enum_t DEFAULT_VALUE()
                {
                    return UNSPECIFIED;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, socket_option_level& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, socket_option_level& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }

                socket_option_level() :
                    OMNI_CTOR_FW(omni::net::socket_option_level)
                    m_val(DEFAULT_VALUE())
                { }

                socket_option_level(const socket_option_level& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                socket_option_level(enum_t val) :
                    OMNI_CTOR_FW(omni::net::socket_option_level)
                    m_val(val)
                { }

                ~socket_option_level()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const socket_option_level& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                socket_option_level& operator=(const socket_option_level& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                socket_option_level& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                socket_option_level& operator=(int32_t val)
                {
                    if (!socket_option_level::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                socket_option_level operator|(const socket_option_level& val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val | val.m_val));
                }

                socket_option_level operator|(enum_t val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val | val));
                }

                socket_option_level operator|(int32_t val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val | val));
                }

                socket_option_level& operator|=(const socket_option_level& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val.m_val);
                    return *this;
                }

                socket_option_level& operator|=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_option_level& operator|=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_option_level operator&(const socket_option_level& val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val & val.m_val));
                }

                socket_option_level operator&(enum_t val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val & val));
                }

                socket_option_level operator&(int32_t val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val & val));
                }

                socket_option_level& operator&=(const socket_option_level& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val.m_val);
                    return *this;
                }

                socket_option_level& operator&=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }

                socket_option_level& operator&=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }
                
                socket_option_level& operator++()
                {
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return *this;
                }

                socket_option_level operator++(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_option_level ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return ret;
                }

                socket_option_level& operator--()
                {
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return *this;
                }

                socket_option_level operator--(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_option_level ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return ret;
                }

                socket_option_level operator~()
                {
                    return socket_option_level(static_cast<enum_t>(~static_cast<int32_t>(this->m_val)));
                }

                socket_option_level operator^(const socket_option_level& val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val ^ val.m_val));
                }

                socket_option_level operator^(enum_t val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_option_level operator^(int32_t val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_option_level& operator^=(const socket_option_level& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val.m_val);
                    return *this;
                }

                socket_option_level& operator^=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_option_level& operator^=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_option_level operator<<(const socket_option_level& val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val << val.m_val));
                }

                socket_option_level operator<<(enum_t val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val << val));
                }

                socket_option_level operator<<(int32_t val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val << val));
                }

                socket_option_level& operator<<=(const socket_option_level& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val.m_val);
                    return *this;
                }

                socket_option_level& operator<<=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_option_level& operator<<=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_option_level operator>>(const socket_option_level& val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val >> val.m_val));
                }

                socket_option_level operator>>(enum_t val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val >> val));
                }

                socket_option_level operator>>(int32_t val)
                {
                    return socket_option_level(static_cast<enum_t>(this->m_val >> val));
                }

                socket_option_level& operator>>=(const socket_option_level& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val.m_val);
                    return *this;
                }

                socket_option_level& operator>>=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                socket_option_level& operator>>=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                bool operator<(const socket_option_level& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const socket_option_level& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const socket_option_level& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::socket_option_level) // disposing,name,type(),hash()

                OMNI_OSTREAM_FW(omni::net::socket_option_level)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;

                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, socket_option_level& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(UNSPECIFIED)
                        OMNI_S2E_FW(IP)
                        OMNI_S2E_FW(IP6)
                        OMNI_S2E_FW(TCP)
                        OMNI_S2E_FW(UDP)
                        OMNI_S2E_FW(SOCKET)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(UNSPECIFIED);
                        OMNI_E2SS_FW(IP);
                        OMNI_E2SS_FW(IP6);
                        OMNI_E2SS_FW(TCP);
                        OMNI_E2SS_FW(UDP);
                        OMNI_E2SS_FW(SOCKET);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(UNSPECIFIED) ||
                        OMNI_I2EV_FW(IP) ||
                        OMNI_I2EV_FW(IP6) ||
                        OMNI_I2EV_FW(TCP) ||
                        OMNI_I2EV_FW(UDP) ||
                        OMNI_I2EV_FW(SOCKET)
                    );
                }
        };
        
        class socket_option
        {
            public:
                typedef enum enum_t {
                    DONT_LINGER = -129,
                    UNSPECIFIED = 0,
                    DBG = SO_DEBUG, // 1, -- DEV_NOTE: DBG instead of DEBUG to avoid macro confusion when -DDEBUG defined
                    ACCEPT_CONNECTION = SO_ACCEPTCONN, // 2,
                    REUSE_ADDRESS = SO_REUSEADDR, // 4,
                    KEEP_ALIVE = SO_KEEPALIVE, // 8,
                    DONT_ROUTE = SO_DONTROUTE, // 16,
                    BROADCAST = SO_BROADCAST, // 32,
                    LINGER = SO_LINGER, // 128,
                    OUT_OF_BAND_INLINE = SO_OOBINLINE, // 256,
                    SEND_BUFFER = SO_SNDBUF, // 4097,
                    RECEIVE_BUFFER = SO_RCVBUF, // 4098,
                    SEND_LOW_WATER = SO_SNDLOWAT, // 4099,
                    RECEIVE_LOW_WATER = SO_RCVLOWAT, // 4100,
                    SEND_TIMEOUT = SO_SNDTIMEO, // 4101,
                    RECEIVE_TIMEOUT = SO_RCVTIMEO, // 4102,
                    ERR = SO_ERROR, // 4103,
                    SOCKET_TYPE = SO_TYPE // 4104,
                } enum_t;
                
                static inline unsigned short COUNT()
                {
                    return 19;
                }

                static inline enum_t DEFAULT_VALUE()
                {
                    return UNSPECIFIED;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, socket_option& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, socket_option& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }

                socket_option() :
                    OMNI_CTOR_FW(omni::net::socket_option)
                    m_val(DEFAULT_VALUE())
                { }

                socket_option(const socket_option& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                socket_option(enum_t val) :
                    OMNI_CTOR_FW(omni::net::socket_option)
                    m_val(val)
                { }

                ~socket_option()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const socket_option& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                socket_option& operator=(const socket_option& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                socket_option& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                socket_option& operator=(int32_t val)
                {
                    if (!socket_option::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                socket_option operator|(const socket_option& val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val | val.m_val));
                }

                socket_option operator|(enum_t val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val | val));
                }

                socket_option operator|(int32_t val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val | val));
                }

                socket_option& operator|=(const socket_option& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val.m_val);
                    return *this;
                }

                socket_option& operator|=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_option& operator|=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_option operator&(const socket_option& val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val & val.m_val));
                }

                socket_option operator&(enum_t val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val & val));
                }

                socket_option operator&(int32_t val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val & val));
                }

                socket_option& operator&=(const socket_option& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val.m_val);
                    return *this;
                }

                socket_option& operator&=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }

                socket_option& operator&=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }
                
                socket_option& operator++()
                {
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return *this;
                }

                socket_option operator++(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_option ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return ret;
                }

                socket_option& operator--()
                {
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return *this;
                }

                socket_option operator--(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_option ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return ret;
                }

                socket_option operator~()
                {
                    return socket_option(static_cast<enum_t>(~static_cast<int32_t>(this->m_val)));
                }

                socket_option operator^(const socket_option& val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val ^ val.m_val));
                }

                socket_option operator^(enum_t val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_option operator^(int32_t val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_option& operator^=(const socket_option& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val.m_val);
                    return *this;
                }

                socket_option& operator^=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_option& operator^=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_option operator<<(const socket_option& val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val << val.m_val));
                }

                socket_option operator<<(enum_t val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val << val));
                }

                socket_option operator<<(int32_t val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val << val));
                }

                socket_option& operator<<=(const socket_option& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val.m_val);
                    return *this;
                }

                socket_option& operator<<=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_option& operator<<=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_option operator>>(const socket_option& val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val >> val.m_val));
                }

                socket_option operator>>(enum_t val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val >> val));
                }

                socket_option operator>>(int32_t val)
                {
                    return socket_option(static_cast<enum_t>(this->m_val >> val));
                }

                socket_option& operator>>=(const socket_option& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val.m_val);
                    return *this;
                }

                socket_option& operator>>=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                socket_option& operator>>=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                bool operator<(const socket_option& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const socket_option& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const socket_option& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::socket_option) // disposing,name,type(),hash()

                OMNI_OSTREAM_FW(omni::net::socket_option)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;

                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, socket_option& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(DONT_LINGER)
                        OMNI_S2E_FW(UNSPECIFIED)
                        OMNI_S2E_FW(DBG)
                        OMNI_S2E_FW(ACCEPT_CONNECTION)
                        OMNI_S2E_FW(REUSE_ADDRESS)
                        OMNI_S2E_FW(KEEP_ALIVE)
                        OMNI_S2E_FW(DONT_ROUTE)
                        OMNI_S2E_FW(BROADCAST)
                        OMNI_S2E_FW(LINGER)
                        OMNI_S2E_FW(OUT_OF_BAND_INLINE)
                        OMNI_S2E_FW(SEND_BUFFER)
                        OMNI_S2E_FW(RECEIVE_BUFFER)
                        OMNI_S2E_FW(SEND_LOW_WATER)
                        OMNI_S2E_FW(RECEIVE_LOW_WATER)
                        OMNI_S2E_FW(SEND_TIMEOUT)
                        OMNI_S2E_FW(RECEIVE_TIMEOUT)
                        OMNI_S2E_FW(ERR)
                        OMNI_S2E_FW(SOCKET_TYPE)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(DONT_LINGER);
                        OMNI_E2SS_FW(UNSPECIFIED);
                        OMNI_E2SS_FW(DBG);
                        OMNI_E2SS_FW(ACCEPT_CONNECTION);
                        OMNI_E2SS_FW(REUSE_ADDRESS);
                        OMNI_E2SS_FW(KEEP_ALIVE);
                        OMNI_E2SS_FW(DONT_ROUTE);
                        OMNI_E2SS_FW(BROADCAST);
                        OMNI_E2SS_FW(LINGER);
                        OMNI_E2SS_FW(OUT_OF_BAND_INLINE);
                        OMNI_E2SS_FW(SEND_BUFFER);
                        OMNI_E2SS_FW(RECEIVE_BUFFER);
                        OMNI_E2SS_FW(SEND_LOW_WATER);
                        OMNI_E2SS_FW(RECEIVE_LOW_WATER);
                        OMNI_E2SS_FW(SEND_TIMEOUT);
                        OMNI_E2SS_FW(RECEIVE_TIMEOUT);
                        OMNI_E2SS_FW(ERR);
                        OMNI_E2SS_FW(SOCKET_TYPE);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(DONT_LINGER) ||
                        OMNI_I2EV_FW(UNSPECIFIED) ||
                        OMNI_I2EV_FW(DBG) ||
                        OMNI_I2EV_FW(ACCEPT_CONNECTION) ||
                        OMNI_I2EV_FW(REUSE_ADDRESS) ||
                        OMNI_I2EV_FW(KEEP_ALIVE) ||
                        OMNI_I2EV_FW(DONT_ROUTE) ||
                        OMNI_I2EV_FW(BROADCAST) ||
                        OMNI_I2EV_FW(LINGER) ||
                        OMNI_I2EV_FW(OUT_OF_BAND_INLINE) ||
                        OMNI_I2EV_FW(SEND_BUFFER) ||
                        OMNI_I2EV_FW(RECEIVE_BUFFER) ||
                        OMNI_I2EV_FW(SEND_LOW_WATER) ||
                        OMNI_I2EV_FW(RECEIVE_LOW_WATER) ||
                        OMNI_I2EV_FW(SEND_TIMEOUT) ||
                        OMNI_I2EV_FW(RECEIVE_TIMEOUT) ||
                        OMNI_I2EV_FW(ERR) ||
                        OMNI_I2EV_FW(SOCKET_TYPE)
                    );
                }
        };

        class tcp_option
        {
            public:
                typedef enum enum_t {
                    UNSPECIFIED = -1,
                    NO_DELAY = TCP_NODELAY, // 1,
                    #if defined(TCP_KEEPALIVE)
                        KEEP_ALIVE = TCP_KEEPALIVE
                    #else
                        KEEP_ALIVE = SO_KEEPALIVE
                    #endif
                } enum_t;
                
                static inline unsigned short COUNT()
                {
                    return 3;
                }

                static inline enum_t DEFAULT_VALUE()
                {
                    return UNSPECIFIED;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, tcp_option& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, tcp_option& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }

                tcp_option() :
                    OMNI_CTOR_FW(omni::net::tcp_option)
                    m_val(DEFAULT_VALUE())
                { }

                tcp_option(const tcp_option& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                tcp_option(enum_t val) :
                    OMNI_CTOR_FW(omni::net::tcp_option)
                    m_val(val)
                { }

                ~tcp_option()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const tcp_option& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                tcp_option& operator=(const tcp_option& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                tcp_option& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                tcp_option& operator=(int32_t val)
                {
                    if (!tcp_option::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                tcp_option operator|(const tcp_option& val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val | val.m_val));
                }

                tcp_option operator|(enum_t val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val | val));
                }

                tcp_option operator|(int32_t val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val | val));
                }

                tcp_option& operator|=(const tcp_option& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val.m_val);
                    return *this;
                }

                tcp_option& operator|=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                tcp_option& operator|=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                tcp_option operator&(const tcp_option& val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val & val.m_val));
                }

                tcp_option operator&(enum_t val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val & val));
                }

                tcp_option operator&(int32_t val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val & val));
                }

                tcp_option& operator&=(const tcp_option& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val.m_val);
                    return *this;
                }

                tcp_option& operator&=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }

                tcp_option& operator&=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }
                
                tcp_option& operator++()
                {
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return *this;
                }

                tcp_option operator++(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    tcp_option ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return ret;
                }

                tcp_option& operator--()
                {
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return *this;
                }

                tcp_option operator--(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    tcp_option ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return ret;
                }

                tcp_option operator~()
                {
                    return tcp_option(static_cast<enum_t>(~static_cast<int32_t>(this->m_val)));
                }

                tcp_option operator^(const tcp_option& val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val ^ val.m_val));
                }

                tcp_option operator^(enum_t val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val ^ val));
                }

                tcp_option operator^(int32_t val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val ^ val));
                }

                tcp_option& operator^=(const tcp_option& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val.m_val);
                    return *this;
                }

                tcp_option& operator^=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                tcp_option& operator^=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                tcp_option operator<<(const tcp_option& val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val << val.m_val));
                }

                tcp_option operator<<(enum_t val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val << val));
                }

                tcp_option operator<<(int32_t val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val << val));
                }

                tcp_option& operator<<=(const tcp_option& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val.m_val);
                    return *this;
                }

                tcp_option& operator<<=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                tcp_option& operator<<=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                tcp_option operator>>(const tcp_option& val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val >> val.m_val));
                }

                tcp_option operator>>(enum_t val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val >> val));
                }

                tcp_option operator>>(int32_t val)
                {
                    return tcp_option(static_cast<enum_t>(this->m_val >> val));
                }

                tcp_option& operator>>=(const tcp_option& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val.m_val);
                    return *this;
                }

                tcp_option& operator>>=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                tcp_option& operator>>=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                bool operator<(const tcp_option& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const tcp_option& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const tcp_option& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::tcp_option) // disposing,name,type(),hash()

                OMNI_OSTREAM_FW(omni::net::tcp_option)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;

                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, tcp_option& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(UNSPECIFIED)
                        OMNI_S2E_FW(NO_DELAY)
                        OMNI_S2E_FW(KEEP_ALIVE)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(UNSPECIFIED);
                        OMNI_E2SS_FW(NO_DELAY);
                        OMNI_E2SS_FW(KEEP_ALIVE);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(UNSPECIFIED) ||
                        OMNI_I2EV_FW(NO_DELAY) ||
                        OMNI_I2EV_FW(KEEP_ALIVE)
                    );
                }
        };

        class socket_shutdown
        {
            public:
                typedef enum enum_t {
                    UNSPECIFIED = -1,
                    RECEIVE = OMNI_SOCK_RECEIVE_FW,
                    SEND = OMNI_SOCK_SEND_FW,
                    BOTH = OMNI_SOCK_BOTH_FW
                } enum_t;
                
                static inline unsigned short COUNT()
                {
                    return 4;
                }

                static inline enum_t DEFAULT_VALUE()
                {
                    return UNSPECIFIED;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, socket_shutdown& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, socket_shutdown& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }
                
                socket_shutdown() :
                    OMNI_CTOR_FW(omni::net::socket_shutdown)
                    m_val(DEFAULT_VALUE())
                { }

                socket_shutdown(const socket_shutdown& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                socket_shutdown(enum_t val) :
                    OMNI_CTOR_FW(omni::net::socket_shutdown)
                    m_val(val)
                { }

                ~socket_shutdown()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const socket_shutdown& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                socket_shutdown& operator=(const socket_shutdown& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                socket_shutdown& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                socket_shutdown& operator=(int32_t val)
                {
                    if (!socket_shutdown::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                socket_shutdown operator|(const socket_shutdown& val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val | val.m_val));
                }

                socket_shutdown operator|(enum_t val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val | val));
                }

                socket_shutdown operator|(int32_t val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val | val));
                }

                socket_shutdown& operator|=(const socket_shutdown& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val.m_val);
                    return *this;
                }

                socket_shutdown& operator|=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_shutdown& operator|=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_shutdown operator&(const socket_shutdown& val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val & val.m_val));
                }

                socket_shutdown operator&(enum_t val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val & val));
                }

                socket_shutdown operator&(int32_t val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val & val));
                }

                socket_shutdown& operator&=(const socket_shutdown& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val.m_val);
                    return *this;
                }

                socket_shutdown& operator&=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }

                socket_shutdown& operator&=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }
                
                socket_shutdown& operator++()
                {
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return *this;
                }

                socket_shutdown operator++(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_shutdown ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return ret;
                }

                socket_shutdown& operator--()
                {
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return *this;
                }

                socket_shutdown operator--(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_shutdown ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return ret;
                }

                socket_shutdown operator~()
                {
                    return socket_shutdown(static_cast<enum_t>(~static_cast<int32_t>(this->m_val)));
                }

                socket_shutdown operator^(const socket_shutdown& val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val ^ val.m_val));
                }

                socket_shutdown operator^(enum_t val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_shutdown operator^(int32_t val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_shutdown& operator^=(const socket_shutdown& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val.m_val);
                    return *this;
                }

                socket_shutdown& operator^=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_shutdown& operator^=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_shutdown operator<<(const socket_shutdown& val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val << val.m_val));
                }

                socket_shutdown operator<<(enum_t val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val << val));
                }

                socket_shutdown operator<<(int32_t val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val << val));
                }

                socket_shutdown& operator<<=(const socket_shutdown& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val.m_val);
                    return *this;
                }

                socket_shutdown& operator<<=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_shutdown& operator<<=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_shutdown operator>>(const socket_shutdown& val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val >> val.m_val));
                }

                socket_shutdown operator>>(enum_t val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val >> val));
                }

                socket_shutdown operator>>(int32_t val)
                {
                    return socket_shutdown(static_cast<enum_t>(this->m_val >> val));
                }

                socket_shutdown& operator>>=(const socket_shutdown& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val.m_val);
                    return *this;
                }

                socket_shutdown& operator>>=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                socket_shutdown& operator>>=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                bool operator<(const socket_shutdown& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const socket_shutdown& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const socket_shutdown& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::socket_shutdown) // disposing,name,type(),hash()

                OMNI_OSTREAM_FW(omni::net::socket_shutdown)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;

                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, socket_shutdown& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(UNSPECIFIED)
                        OMNI_S2E_FW(RECEIVE)
                        OMNI_S2E_FW(SEND)
                        OMNI_S2E_FW(BOTH)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(UNSPECIFIED);
                        OMNI_E2SS_FW(RECEIVE);
                        OMNI_E2SS_FW(SEND);
                        OMNI_E2SS_FW(BOTH);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(UNSPECIFIED) ||
                        OMNI_I2EV_FW(RECEIVE) ||
                        OMNI_I2EV_FW(SEND) ||
                        OMNI_I2EV_FW(BOTH)
                    );
                }
        };
        
        class socket_type
        {
            public:
                typedef enum enum_t {
                    UNKNOWN = -1,
                    STREAM = SOCK_STREAM,
                    DGRAM = SOCK_DGRAM,
                    RAW = SOCK_RAW,
                    RDM = SOCK_RDM,
                    SEQPACKET = SOCK_SEQPACKET
                } enum_t;
                
                static inline unsigned short COUNT()
                {
                    return 6;
                }

                static inline enum_t DEFAULT_VALUE()
                {
                    return UNKNOWN;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, socket_type& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, socket_type& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }

                socket_type() :
                    OMNI_CTOR_FW(omni::net::socket_type)
                    m_val(DEFAULT_VALUE())
                { }

                socket_type(const socket_type& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                socket_type(enum_t val) :
                    OMNI_CTOR_FW(omni::net::socket_type)
                    m_val(val)
                { }

                ~socket_type()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const socket_type& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                socket_type& operator=(const socket_type& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                socket_type& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                socket_type& operator=(int32_t val)
                {
                    if (!socket_type::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                socket_type operator|(const socket_type& val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val | val.m_val));
                }

                socket_type operator|(enum_t val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val | val));
                }

                socket_type operator|(int32_t val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val | val));
                }

                socket_type& operator|=(const socket_type& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val.m_val);
                    return *this;
                }

                socket_type& operator|=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_type& operator|=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_type operator&(const socket_type& val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val & val.m_val));
                }

                socket_type operator&(enum_t val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val & val));
                }

                socket_type operator&(int32_t val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val & val));
                }

                socket_type& operator&=(const socket_type& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val.m_val);
                    return *this;
                }

                socket_type& operator&=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }

                socket_type& operator&=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }
                
                socket_type& operator++()
                {
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return *this;
                }

                socket_type operator++(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_type ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return ret;
                }

                socket_type& operator--()
                {
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return *this;
                }

                socket_type operator--(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_type ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return ret;
                }

                socket_type operator~()
                {
                    return socket_type(static_cast<enum_t>(~static_cast<int32_t>(this->m_val)));
                }

                socket_type operator^(const socket_type& val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val ^ val.m_val));
                }

                socket_type operator^(enum_t val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_type operator^(int32_t val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_type& operator^=(const socket_type& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val.m_val);
                    return *this;
                }

                socket_type& operator^=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_type& operator^=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_type operator<<(const socket_type& val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val << val.m_val));
                }

                socket_type operator<<(enum_t val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val << val));
                }

                socket_type operator<<(int32_t val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val << val));
                }

                socket_type& operator<<=(const socket_type& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val.m_val);
                    return *this;
                }

                socket_type& operator<<=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_type& operator<<=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_type operator>>(const socket_type& val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val >> val.m_val));
                }

                socket_type operator>>(enum_t val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val >> val));
                }

                socket_type operator>>(int32_t val)
                {
                    return socket_type(static_cast<enum_t>(this->m_val >> val));
                }

                socket_type& operator>>=(const socket_type& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val.m_val);
                    return *this;
                }

                socket_type& operator>>=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                socket_type& operator>>=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                bool operator<(const socket_type& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const socket_type& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const socket_type& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::socket_type) // disposing,name,type(),hash()

                OMNI_OSTREAM_FW(omni::net::socket_type)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;
                
                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, socket_type& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(UNKNOWN)
                        OMNI_S2E_FW(STREAM)
                        OMNI_S2E_FW(DGRAM)
                        OMNI_S2E_FW(RAW)
                        OMNI_S2E_FW(RDM)
                        OMNI_S2E_FW(SEQPACKET)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(UNKNOWN);
                        OMNI_E2SS_FW(STREAM);
                        OMNI_E2SS_FW(DGRAM);
                        OMNI_E2SS_FW(RAW);
                        OMNI_E2SS_FW(RDM);
                        OMNI_E2SS_FW(SEQPACKET);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(UNKNOWN) ||
                        OMNI_I2EV_FW(STREAM) ||
                        OMNI_I2EV_FW(DGRAM) ||
                        OMNI_I2EV_FW(RAW) ||
                        OMNI_I2EV_FW(RDM) ||
                        OMNI_I2EV_FW(SEQPACKET)
                    );
                }
        };

        class socket_create_options
        {
            public:
                typedef enum enum_t {
                    OPEN_ON_CREATE,
                    USER_OPEN
                } enum_t;
                
                static inline unsigned short COUNT()
                {
                    return 2;
                }

                static inline enum_t DEFAULT_VALUE()
                {
                    return OPEN_ON_CREATE;
                }

                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, socket_create_options& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, socket_create_options& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }

                socket_create_options() :
                    OMNI_CTOR_FW(omni::net::socket_create_options)
                    m_val(DEFAULT_VALUE())
                { }

                socket_create_options(const socket_create_options& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                socket_create_options(enum_t val) :
                    OMNI_CTOR_FW(omni::net::socket_create_options)
                    m_val(val)
                { }

                ~socket_create_options()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }

                unsigned short count() const
                {
                    return COUNT();
                }

                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const socket_create_options& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                socket_create_options& operator=(const socket_create_options& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                socket_create_options& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                socket_create_options& operator=(int32_t val)
                {
                    if (!socket_create_options::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                socket_create_options operator|(const socket_create_options& val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val | val.m_val));
                }

                socket_create_options operator|(enum_t val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val | val));
                }

                socket_create_options operator|(int32_t val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val | val));
                }

                socket_create_options& operator|=(const socket_create_options& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val.m_val);
                    return *this;
                }

                socket_create_options& operator|=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_create_options& operator|=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val | val);
                    return *this;
                }

                socket_create_options operator&(const socket_create_options& val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val & val.m_val));
                }

                socket_create_options operator&(enum_t val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val & val));
                }

                socket_create_options operator&(int32_t val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val & val));
                }

                socket_create_options& operator&=(const socket_create_options& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val.m_val);
                    return *this;
                }

                socket_create_options& operator&=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }

                socket_create_options& operator&=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val & val);
                    return *this;
                }
                
                socket_create_options& operator++()
                {
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return *this;
                }

                socket_create_options operator++(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_create_options ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val + 1);
                    return ret;
                }

                socket_create_options& operator--()
                {
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return *this;
                }

                socket_create_options operator--(int dummy)
                {
                    OMNI_UNUSED(dummy);
                    socket_create_options ret(this->m_val);
                    this->m_val = static_cast<enum_t>(this->m_val - 1);
                    return ret;
                }

                socket_create_options operator~()
                {
                    return socket_create_options(static_cast<enum_t>(~static_cast<int32_t>(this->m_val)));
                }

                socket_create_options operator^(const socket_create_options& val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val ^ val.m_val));
                }

                socket_create_options operator^(enum_t val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_create_options operator^(int32_t val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val ^ val));
                }

                socket_create_options& operator^=(const socket_create_options& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val.m_val);
                    return *this;
                }

                socket_create_options& operator^=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_create_options& operator^=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val ^ val);
                    return *this;
                }

                socket_create_options operator<<(const socket_create_options& val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val << val.m_val));
                }

                socket_create_options operator<<(enum_t val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val << val));
                }

                socket_create_options operator<<(int32_t val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val << val));
                }

                socket_create_options& operator<<=(const socket_create_options& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val.m_val);
                    return *this;
                }

                socket_create_options& operator<<=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_create_options& operator<<=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val << val);
                    return *this;
                }

                socket_create_options operator>>(const socket_create_options& val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val >> val.m_val));
                }

                socket_create_options operator>>(enum_t val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val >> val));
                }

                socket_create_options operator>>(int32_t val)
                {
                    return socket_create_options(static_cast<enum_t>(this->m_val >> val));
                }

                socket_create_options& operator>>=(const socket_create_options& val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val.m_val);
                    return *this;
                }

                socket_create_options& operator>>=(enum_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                socket_create_options& operator>>=(int32_t val)
                {
                    this->m_val = static_cast<enum_t>(this->m_val >> val);
                    return *this;
                }

                bool operator<(const socket_create_options& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const socket_create_options& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const socket_create_options& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::net::socket_create_options) // disposing,name,type(),hash()

                OMNI_OSTREAM_FW(omni::net::socket_create_options)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;
                
                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, socket_create_options& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(OPEN_ON_CREATE)
                        OMNI_S2E_FW(USER_OPEN)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(OPEN_ON_CREATE);
                        OMNI_E2SS_FW(USER_OPEN);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (
                        OMNI_I2EV_FW(OPEN_ON_CREATE) ||
                        OMNI_I2EV_FW(USER_OPEN)
                    );
                }
        };

        class ip6_binary_address
        {
            public:
                ip6_binary_address() : m_ip()
                {
                    std::memset(m_ip, 0, sizeof(m_ip));
                }

                ip6_binary_address(const ip6_binary_address& cp) : m_ip()
                {
                    std::memcpy(this->m_ip, cp.m_ip, sizeof(this->m_ip));
                }

                ip6_binary_address(uint8_t (&ip)[16]) : m_ip()
                {
                    std::memcpy(this->m_ip, ip, sizeof(this->m_ip));
                }

                ~ip6_binary_address() {}

                void copy_to(uint8_t (&ip)[16]) const
                {
                    std::memcpy(ip, this->m_ip, sizeof(this->m_ip));
                }

                std::size_t size() const
                {
                    return sizeof(this->m_ip);
                }

                ip6_binary_address& operator=(const ip6_binary_address& other)
                {
                    std::memcpy(this->m_ip, other.m_ip, sizeof(m_ip));
                    return *this;
                }

                ip6_binary_address& operator=(const uint8_t (&ip)[16])
                {
                    std::memcpy(this->m_ip, ip, sizeof(m_ip));
                    return *this;
                }

                uint8_t operator[](std::size_t index) const
                {
                    return this->m_ip[index];
                }

                uint8_t& operator[](std::size_t index)
                {
                    return this->m_ip[index];
                }

                operator const uint8_t *const() const
                {
                    return this->m_ip;
                }

                operator uint8_t *const()
                {
                    return this->m_ip;
                }

            private:
                uint8_t m_ip[16];
        };

        typedef OMNI_SOCKET_T_FW socket_t;
        typedef OMNI_SOCKADDR_IN_T_FW sockaddr_in_t;
        typedef OMNI_SOCKADDR_IN6_T_FW sockaddr_in6_t;
        typedef OMNI_SOCKADDR_UN_T_FW sockaddr_un_t;
        typedef OMNI_SOCKADDR_T_FW sockaddr_t;
        typedef OMNI_SOCKET_XFR_T_FW xfr_t;

        typedef union dual_socket_addr_t {
            omni::net::sockaddr_in_t addr4;
            omni::net::sockaddr_in6_t addr6;
        } dual_socket_addr_t;

        typedef union dual_socket_endpoint_t {
            uint8_t ep6[16];
            uint32_t ep4;
        } dual_socket_endpoint_t;
    }
}

#endif // OMNI_NET_T_HPP