@@ -99,6 +99,7 @@ VALUE rb_cSet;
9999static ID id_each_entry ;
100100static ID id_any_p ;
101101static ID id_new ;
102+ static ID id_i_hash ;
102103static ID id_set_iter_lev ;
103104
104105#define RSET_INITIALIZED FL_USER1
@@ -1850,6 +1851,66 @@ set_i_hash(VALUE set)
18501851 return ST2FIX (hval );
18511852}
18521853
1854+ /* :nodoc: */
1855+ static int
1856+ set_to_hash_i (st_data_t key , st_data_t arg )
1857+ {
1858+ rb_hash_aset ((VALUE )arg , (VALUE )key , Qtrue );
1859+ return ST_CONTINUE ;
1860+ }
1861+
1862+ static VALUE
1863+ set_i_to_h (VALUE set )
1864+ {
1865+ st_index_t size = RSET_SIZE (set );
1866+ VALUE hash ;
1867+ if (RSET_COMPARE_BY_IDENTITY (set )) {
1868+ hash = rb_ident_hash_new_with_size (size );
1869+ }
1870+ else {
1871+ hash = rb_hash_new_with_size (size );
1872+ }
1873+ rb_hash_set_default (hash , Qfalse );
1874+
1875+ if (size == 0 ) return hash ;
1876+
1877+ set_iter (set , set_to_hash_i , (st_data_t )hash );
1878+ return hash ;
1879+ }
1880+
1881+ static VALUE
1882+ compat_dumper (VALUE set )
1883+ {
1884+ VALUE dumper = rb_class_new_instance (0 , 0 , rb_cObject );
1885+ rb_ivar_set (dumper , id_i_hash , set_i_to_h (set ));
1886+ return dumper ;
1887+ }
1888+
1889+ static int
1890+ set_i_from_hash_i (st_data_t key , st_data_t val , st_data_t set )
1891+ {
1892+ if ((VALUE )val != Qtrue ) {
1893+ rb_raise (rb_eRuntimeError , "expect true as Set value: %" PRIsVALUE , rb_obj_class ((VALUE )val ));
1894+ }
1895+ set_i_add ((VALUE )set , (VALUE )key );
1896+ return ST_CONTINUE ;
1897+ }
1898+
1899+ static VALUE
1900+ set_i_from_hash (VALUE set , VALUE hash )
1901+ {
1902+ Check_Type (hash , T_HASH );
1903+ if (rb_hash_compare_by_id_p (hash )) set_i_compare_by_identity (set );
1904+ rb_hash_stlike_foreach (hash , set_i_from_hash_i , (st_data_t )set );
1905+ return set ;
1906+ }
1907+
1908+ static VALUE
1909+ compat_loader (VALUE self , VALUE a )
1910+ {
1911+ return set_i_from_hash (self , rb_ivar_get (a , id_i_hash ));
1912+ }
1913+
18531914/*
18541915 * Document-class: Set
18551916 *
@@ -2068,6 +2129,7 @@ Init_Set(void)
20682129 id_each_entry = rb_intern_const ("each_entry" );
20692130 id_any_p = rb_intern_const ("any?" );
20702131 id_new = rb_intern_const ("new" );
2132+ id_i_hash = rb_intern_const ("@hash" );
20712133 id_set_iter_lev = rb_make_internal_id ();
20722134
20732135 rb_define_alloc_func (rb_cSet , set_s_alloc );
@@ -2132,7 +2194,12 @@ Init_Set(void)
21322194 rb_define_method (rb_cSet , "superset?" , set_i_superset , 1 );
21332195 rb_define_alias (rb_cSet , ">=" , "superset?" );
21342196 rb_define_method (rb_cSet , "to_a" , set_i_to_a , 0 );
2197+ rb_define_method (rb_cSet , "to_h" , set_i_to_h , 0 );
21352198 rb_define_method (rb_cSet , "to_set" , set_i_to_set , -1 );
21362199
2200+ /* :nodoc: */
2201+ VALUE compat = rb_define_class_under (rb_cSet , "compatible" , rb_cObject );
2202+ rb_marshal_define_compat (rb_cSet , compat , compat_dumper , compat_loader );
2203+
21372204 rb_provide ("set.rb" );
21382205}
0 commit comments