@@ -13,17 +13,23 @@ use std::{
1313
1414use debug_unreachable:: debug_unreachable;
1515use once_cell:: sync:: Lazy ;
16- use wtf8:: Wtf8 ;
1716
1817pub use crate :: dynamic:: { global_atom_store_gc, AtomStore } ;
19- use crate :: tagged_value:: TaggedValue ;
18+ use crate :: {
19+ macros:: { get_hash, impl_from_alias, partial_eq} ,
20+ tagged_value:: TaggedValue ,
21+ } ;
2022
2123mod dynamic;
2224mod global_store;
25+ mod macros;
2326mod tagged_value;
2427#[ cfg( test) ]
2528mod tests;
2629pub mod wtf8;
30+ mod wtf8_atom;
31+
32+ pub use wtf8_atom:: Wtf8Atom ;
2733
2834/// An immutable string which is cheap to clone, compare, hash, and has small
2935/// size.
@@ -253,25 +259,6 @@ impl Atom {
253259 }
254260}
255261
256- macro_rules! get_hash {
257- ( $self: expr) => {
258- match $self. tag( ) {
259- DYNAMIC_TAG => {
260- unsafe { crate :: dynamic:: deref_from( $self. unsafe_data) }
261- . header
262- . header
263- . hash
264- }
265- INLINE_TAG => {
266- // This is passed as input to the caller's `Hasher` implementation, so it's okay
267- // that this isn't really a hash
268- $self. unsafe_data. hash( )
269- }
270- _ => unsafe { debug_unreachable!( ) } ,
271- }
272- } ;
273- }
274-
275262impl Atom {
276263 fn get_hash ( & self ) -> u64 {
277264 get_hash ! ( self )
@@ -307,35 +294,6 @@ impl Atom {
307294 }
308295}
309296
310- macro_rules! partial_eq {
311- ( $self: expr, $other: expr) => {
312- if $self. unsafe_data == $other. unsafe_data {
313- return true ;
314- }
315-
316- // If one is inline and the other is not, the length is different.
317- // If one is static and the other is not, it's different.
318- if $self. tag( ) != $other. tag( ) {
319- return false ;
320- }
321-
322- if $self. is_dynamic( ) && $other. is_dynamic( ) {
323- let te = unsafe { crate :: dynamic:: deref_from( $self. unsafe_data) } ;
324- let oe = unsafe { crate :: dynamic:: deref_from( $other. unsafe_data) } ;
325-
326- if te. header. header. hash != oe. header. header. hash {
327- return false ;
328- }
329-
330- return te. slice == oe. slice;
331- }
332-
333- if $self. get_hash( ) != $other. get_hash( ) {
334- return false ;
335- }
336- } ;
337- }
338-
339297impl PartialEq for Atom {
340298 #[ inline( never) ]
341299 fn eq ( & self , other : & Self ) -> bool {
@@ -372,25 +330,6 @@ impl Clone for Atom {
372330 }
373331}
374332
375- macro_rules! impl_from_alias {
376- ( $ty: ty) => {
377- impl $ty {
378- #[ inline]
379- pub ( crate ) fn from_alias( alias: TaggedValue ) -> Self {
380- if alias. tag( ) & TAG_MASK == DYNAMIC_TAG {
381- unsafe {
382- let arc = crate :: dynamic:: restore_arc( alias) ;
383- forget( arc. clone( ) ) ;
384- forget( arc) ;
385- }
386- }
387-
388- Self { unsafe_data: alias }
389- }
390- }
391- } ;
392- }
393-
394333impl_from_alias ! ( Atom ) ;
395334
396335impl Deref for Atom {
@@ -485,190 +424,6 @@ impl Atom {
485424 }
486425}
487426
488- /// A WTF-8 encoded atom. This is like [Atom], but can contain unpaired
489- /// surrogates.
490- pub struct Wtf8Atom {
491- unsafe_data : TaggedValue ,
492- }
493-
494- impl Wtf8Atom {
495- #[ inline( always) ]
496- pub fn new < S > ( s : S ) -> Self
497- where
498- Self : From < S > ,
499- {
500- Self :: from ( s)
501- }
502-
503- #[ inline( always) ]
504- fn tag ( & self ) -> u8 {
505- self . unsafe_data . tag ( ) & TAG_MASK
506- }
507-
508- /// Return true if this is a dynamic Atom.
509- #[ inline( always) ]
510- fn is_dynamic ( & self ) -> bool {
511- self . tag ( ) == DYNAMIC_TAG
512- }
513- }
514-
515- impl Default for Wtf8Atom {
516- #[ inline( never) ]
517- fn default ( ) -> Self {
518- Wtf8Atom :: new ( "" )
519- }
520- }
521-
522- /// Immutable, so it's safe to be shared between threads
523- unsafe impl Send for Wtf8Atom { }
524-
525- /// Immutable, so it's safe to be shared between threads
526- unsafe impl Sync for Wtf8Atom { }
527-
528- impl Debug for Wtf8Atom {
529- #[ inline]
530- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
531- Debug :: fmt ( & self . to_string_lossy ( ) , f)
532- }
533- }
534-
535- #[ cfg( feature = "serde" ) ]
536- impl serde:: ser:: Serialize for Wtf8Atom {
537- fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
538- where
539- S : serde:: ser:: Serializer ,
540- {
541- serializer. serialize_bytes ( self . as_bytes ( ) )
542- }
543- }
544-
545- #[ cfg( feature = "serde" ) ]
546- impl < ' de > serde:: de:: Deserialize < ' de > for Wtf8Atom {
547- fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
548- where
549- D : serde:: Deserializer < ' de > ,
550- {
551- String :: deserialize ( deserializer) . map ( Self :: new)
552- }
553- }
554-
555- impl PartialEq for Wtf8Atom {
556- #[ inline( never) ]
557- fn eq ( & self , other : & Self ) -> bool {
558- partial_eq ! ( self , other) ;
559-
560- // If the store is different, the string may be the same, even though the
561- // `unsafe_data` is different
562- self . as_wtf8 ( ) == other. as_wtf8 ( )
563- }
564- }
565-
566- impl Eq for Wtf8Atom { }
567-
568- impl Hash for Wtf8Atom {
569- #[ inline( always) ]
570- fn hash < H : std:: hash:: Hasher > ( & self , state : & mut H ) {
571- state. write_u64 ( self . get_hash ( ) ) ;
572- }
573- }
574-
575- impl Drop for Wtf8Atom {
576- #[ inline( always) ]
577- fn drop ( & mut self ) {
578- if self . is_dynamic ( ) {
579- unsafe { drop ( crate :: dynamic:: restore_arc ( self . unsafe_data ) ) }
580- }
581- }
582- }
583-
584- impl Clone for Wtf8Atom {
585- #[ inline( always) ]
586- fn clone ( & self ) -> Self {
587- Self :: from_alias ( self . unsafe_data )
588- }
589- }
590-
591- impl Deref for Wtf8Atom {
592- type Target = Wtf8 ;
593-
594- #[ inline( always) ]
595- fn deref ( & self ) -> & Self :: Target {
596- self . as_wtf8 ( )
597- }
598- }
599-
600- impl AsRef < Wtf8 > for Wtf8Atom {
601- #[ inline( always) ]
602- fn as_ref ( & self ) -> & Wtf8 {
603- self . as_wtf8 ( )
604- }
605- }
606-
607- impl PartialEq < Wtf8 > for Wtf8Atom {
608- #[ inline]
609- fn eq ( & self , other : & Wtf8 ) -> bool {
610- self . as_wtf8 ( ) == other
611- }
612- }
613-
614- impl PartialEq < Atom > for Wtf8Atom {
615- #[ inline]
616- fn eq ( & self , other : & Atom ) -> bool {
617- self . as_str ( ) == Some ( other. as_str ( ) )
618- }
619- }
620-
621- impl PartialEq < & ' _ Wtf8 > for Wtf8Atom {
622- #[ inline]
623- fn eq ( & self , other : & & Wtf8 ) -> bool {
624- self . as_wtf8 ( ) == * other
625- }
626- }
627-
628- impl PartialEq < Wtf8Atom > for Wtf8 {
629- #[ inline]
630- fn eq ( & self , other : & Wtf8Atom ) -> bool {
631- self == other. as_wtf8 ( )
632- }
633- }
634-
635- impl Wtf8Atom {
636- fn get_hash ( & self ) -> u64 {
637- get_hash ! ( self )
638- }
639-
640- fn as_wtf8 ( & self ) -> & Wtf8 {
641- match self . tag ( ) {
642- DYNAMIC_TAG => unsafe {
643- let item = crate :: dynamic:: deref_from ( self . unsafe_data ) ;
644- Wtf8 :: from_bytes ( transmute :: < & [ u8 ] , & ' static [ u8 ] > ( & item. slice ) )
645- } ,
646- INLINE_TAG => {
647- let len = ( self . unsafe_data . tag ( ) & LEN_MASK ) >> LEN_OFFSET ;
648- let src = self . unsafe_data . data ( ) ;
649- Wtf8 :: from_bytes ( & src[ ..( len as usize ) ] )
650- }
651- _ => unsafe { debug_unreachable ! ( ) } ,
652- }
653- }
654- }
655-
656- impl_from_alias ! ( Wtf8Atom ) ;
657-
658- #[ cfg( test) ]
659- impl Wtf8Atom {
660- pub ( crate ) fn ref_count ( & self ) -> usize {
661- match self . tag ( ) {
662- DYNAMIC_TAG => {
663- let ptr = unsafe { crate :: dynamic:: deref_from ( self . unsafe_data ) } ;
664-
665- triomphe:: ThinArc :: strong_count ( & ptr. 0 )
666- }
667- _ => 1 ,
668- }
669- }
670- }
671-
672427#[ cfg( test) ]
673428mod macro_tests {
674429
0 commit comments