@@ -1875,6 +1875,21 @@ class class_ {
18751875 }
18761876};
18771877
1878+ #if __cplusplus >= 201703L
1879+ template <typename T>
1880+ void register_optional () {
1881+ // Optional types are automatically registered for some internal types so
1882+ // only run the register method once so we don't conflict with a user's
1883+ // bindings if they also register the optional type.
1884+ thread_local bool hasRun;
1885+ if (hasRun) {
1886+ return ;
1887+ }
1888+ hasRun = true ;
1889+ internal::_embind_register_optional (internal::TypeID<std::optional<T>>::get (), internal::TypeID<T>::get ());
1890+ }
1891+ #endif
1892+
18781893// //////////////////////////////////////////////////////////////////////////////
18791894// VECTORS
18801895// //////////////////////////////////////////////////////////////////////////////
@@ -1883,6 +1898,20 @@ namespace internal {
18831898
18841899template <typename VectorType>
18851900struct VectorAccess {
1901+ // This nearly duplicated code is used for generating more specific TypeScript
1902+ // types when using more modern C++ versions.
1903+ #if __cplusplus >= 201703L
1904+ static std::optional<typename VectorType::value_type> get (
1905+ const VectorType& v,
1906+ typename VectorType::size_type index
1907+ ) {
1908+ if (index < v.size ()) {
1909+ return v[index];
1910+ } else {
1911+ return {};
1912+ }
1913+ }
1914+ #else
18861915 static val get (
18871916 const VectorType& v,
18881917 typename VectorType::size_type index
@@ -1893,6 +1922,7 @@ struct VectorAccess {
18931922 return val::undefined ();
18941923 }
18951924 }
1925+ #endif
18961926
18971927 static bool set (
18981928 VectorType& v,
@@ -1909,6 +1939,9 @@ struct VectorAccess {
19091939template <typename T>
19101940class_<std::vector<T>> register_vector (const char * name) {
19111941 typedef std::vector<T> VecType;
1942+ #if __cplusplus >= 201703L
1943+ register_optional<T>();
1944+ #endif
19121945
19131946 void (VecType::*push_back)(const T&) = &VecType::push_back;
19141947 void (VecType::*resize)(const size_t , const T&) = &VecType::resize;
@@ -1923,13 +1956,6 @@ class_<std::vector<T>> register_vector(const char* name) {
19231956 ;
19241957}
19251958
1926- #if __cplusplus >= 201703L
1927- template <typename T>
1928- void register_optional () {
1929- internal::_embind_register_optional (internal::TypeID<std::optional<T>>::get (), internal::TypeID<T>::get ());
1930- }
1931- #endif
1932-
19331959// //////////////////////////////////////////////////////////////////////////////
19341960// MAPS
19351961// //////////////////////////////////////////////////////////////////////////////
@@ -1938,6 +1964,21 @@ namespace internal {
19381964
19391965template <typename MapType>
19401966struct MapAccess {
1967+ // This nearly duplicated code is used for generating more specific TypeScript
1968+ // types when using more modern C++ versions.
1969+ #if __cplusplus >= 201703L
1970+ static std::optional<typename MapType::mapped_type> get (
1971+ const MapType& m,
1972+ const typename MapType::key_type& k
1973+ ) {
1974+ auto i = m.find (k);
1975+ if (i == m.end ()) {
1976+ return {};
1977+ } else {
1978+ return i->second ;
1979+ }
1980+ }
1981+ #else
19411982 static val get (
19421983 const MapType& m,
19431984 const typename MapType::key_type& k
@@ -1949,6 +1990,7 @@ struct MapAccess {
19491990 return val (i->second );
19501991 }
19511992 }
1993+ #endif
19521994
19531995 static void set (
19541996 MapType& m,
@@ -1975,6 +2017,9 @@ struct MapAccess {
19752017template <typename K, typename V>
19762018class_<std::map<K, V>> register_map (const char * name) {
19772019 typedef std::map<K,V> MapType;
2020+ #if __cplusplus >= 201703L
2021+ register_optional<V>();
2022+ #endif
19782023
19792024 size_t (MapType::*size)() const = &MapType::size;
19802025 return class_<MapType>(name)
0 commit comments