<!--
{
  "availability" : [
    "iOS: 18.0.0 -",
    "iPadOS: 18.0.0 -",
    "macCatalyst: 18.0.0 -",
    "macOS: 15.0.0 -",
    "tvOS: 18.0.0 -",
    "visionOS: 2.0.0 -",
    "watchOS: 11.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "Swift",
  "identifier" : "/documentation/Synchronization/AtomicRepresentable",
  "metadataVersion" : "0.1.0",
  "role" : "Protocol",
  "symbol" : {
    "kind" : "Protocol",
    "modules" : [
      "Synchronization"
    ],
    "preciseIdentifier" : "s:15Synchronization19AtomicRepresentableP"
  },
  "title" : "AtomicRepresentable"
}
-->

# AtomicRepresentable

A type that supports atomic operations through a separate atomic storage
representation.

```
protocol AtomicRepresentable
```

## Overview

Types that conform to the `AtomicRepresentable` protocol can be used as the
`Value` type parameter with the `Atomic` type. Conformances that utilize
existing atomic storage representations as their own representation will get
the primitive atomic operations available on `Atomic` for free. Such
operations include `load`, `store`, `exchange`, `compareExchange`, and
`weakCompareExchange`.

## Conforming to the AtomicRepresentable protocol

Conforming your own custom types allow them to be used in the `Atomic` type
and get access to all of the primitive atomic operations explained above.
There are two main ways to conform your type to `AtomicRepresentable`:

1. Using a predefined `RawRepresentable` conformance
2. Manually conforming to `AtomicRepresentable`

If you custom type already conforms to `RawRepresentable`, then adding the
`AtomicRepresentable` conformance may be really simple! If the `RawValue`
associated type of your type is already itself an `AtomicRepresentable`,
then all you need to do is add the conformance and you’re done!

```
enum TrafficLight: UInt8 {
  case red
  case yellow
  case green
}

extension TrafficLight: AtomicRepresentable {}
```

And that’s it! Here, we’re utilizing Swift’s automatic `RawRepresentable`
conformance synthesis for enums by declaring our “raw value” to be a
`UInt8`. By adding the `AtomicRepresentable` conformance, we automatically
figure out how to do the conformance from the `RawRepresentable`
implementation and do all of the necessary work for you. However, it is still
possible to customize this behavior using the manual method explained below.

Defining your own `AtomicRepresentable` conformance is pretty simple. All
you have to do is decide what atomic storage representation fits best for
your type, and create the bidirectional relationship between the two.

```
// A point in an x-y coordinate system.
struct GridPoint {
  var x: Int
  var y: Int
}

extension GridPoint: AtomicRepresentable {
  typealias AtomicRepresentation = WordPair.AtomicRepresentation

  static func encodeAtomicRepresentation(
    _ value: consuming GridPoint
  ) -> AtomicRepresentation {
    let wordPair = WordPair(
      first: UInt(bitPattern: value.x),
      second: UInt(bitPattern: value.y)
    )

    return WordPair.encodeAtomicRepresentation(wordPair)
  }

  static func decodeAtomicRepresentation(
    _ representation: consuming AtomicRepresentation
  ) -> GridPoint {
    let wordPair = WordPair.decodeAtomicRepresentation(representation)

    return GridPoint(
      x: Int(bitPattern: wordPair.first),
      y: Int(bitPattern: wordPair.second)
    )
  }
}
```

Here, we’re going to select `WordPair`’s atomic storage representation as
our own. This is very important because we only get the atomic operations
like `load` and `store` if our representation is one of the *fundamental*
storage representations. Luckily for us, `WordPair` does use one of these
types as its storage type.

In addition to selecting what storage representation our type will use, we
define two static functions that go from both our custom type to its
representation and the representation back to our own type. Because our
representation is the same as `WordPair.AtomicRepresentation`, we will
actually go through `WordPair`’s `AtomicRepresentable` conformance to help
define our own.

This is all you need to do to conform your custom type to the
`AtomicRepresentable` protocol. From here, you can use this type in all of
the primitive atomic operations like shown below:

```
func atomicGridPoint(_ gridPoint: Atomic<GridPoint>) {
  let newGridPoint = GridPoint(x: 123, y: -456)

  let oldGridPoint1 = gridPoint.load(ordering: .relaxed)

  gridPoint.store(newGridPoint, ordering: .releasing)

  let oldGridPoint2 = gridPoint.exchange(
    desired: oldGridPoint1,
    ordering: .acquiringAndReleasing
  )

  let (exchanged1, oldGridPoint2) = gridPoint.compareExchange(
    expected: oldGridPoint1,
    desired: newGridPoint,
    ordering: .sequentiallyConsistent
  )

  let (exchanged2, oldGridPoint3) = gridPoint.weakCompareExchange(
    expected: newGridPoint,
    desired: oldGridPoint2,
    ordering: .relaxed
  )
}
```

## List of Fundamental Atomic Representations

When defining your own `AtomicRepresentable` conformance, it is critical
that your custom type should choose from the following list of types as its
own `AtomicRepresentation`:

- `UInt8.AtomicRepresentation`
- `UInt16.AtomicRepresentation`
- `UInt32.AtomicRepresentation`
- `UInt64.AtomicRepresentation`
- `UInt.AtomicRepresentation`
- `Int8.AtomicRepresentation`
- `Int16.AtomicRepresentation`
- `Int32.AtomicRepresentation`
- `Int64.AtomicRepresentation`
- `Int.AtomicRepresentation`
- `WordPair.AtomicRepresentation`

> Note: `Int8.AtomicRepresentation` is the same type as
> `UInt8.AtomicRepresentation` and the same is true for all of the same
> sized integer types. If your type wraps an unsigned integer, you should
> prefer to use an unsigned integer’s atomic representation instead of a
> signed ones and vice versa. `Int` and `UInt`’s representation will be
> 64 bits wide on 64 bit systems and 32 bit wide on 32 bit systems. `Int64`
> and `UInt64` always conform to `AtomicRepresentable` on 64 bit systems,
> but on 32 bit systems they will only conform if the platform supports
> double wide atomics. `WordPair` will only conform to `AtomicRepresentable`
> on platforms that support double wide atomics, but if they do it will be
> 128 bits wide on 64 bit systems and 64 bits wide on 32 bit systems.

## Topics

### Associated Types

[`associatedtype AtomicRepresentation : BitwiseCopyable`](/documentation/Synchronization/AtomicRepresentable/AtomicRepresentation)

The storage representation type that `Self` encodes to and decodes from
which is a suitable type when used in atomic operations.

### Type Methods

[`static func decodeAtomicRepresentation(consuming Self.AtomicRepresentation) -> Self`](/documentation/Synchronization/AtomicRepresentable/decodeAtomicRepresentation(_:))

Recovers the logical atomic type `Self` by destroying some
`AtomicRepresentation` storage instance returned from an atomic operation.

[`static func encodeAtomicRepresentation(consuming Self) -> Self.AtomicRepresentation`](/documentation/Synchronization/AtomicRepresentable/encodeAtomicRepresentation(_:))

Destroys a value of `Self` and prepares an `AtomicRepresentation` storage
type to be used for atomic operations.

## Relationships

### Conforming Types

[`Double`](/documentation/Swift/Double)

[`Never`](/documentation/Swift/Never)

[`UInt64`](/documentation/Swift/UInt64)

[`Optional`](/documentation/Swift/Optional)

[`WordPair`](/documentation/Synchronization/WordPair)

[`UInt`](/documentation/Swift/UInt)

[`UnsafePointer`](/documentation/Swift/UnsafePointer)

[`Float16`](/documentation/Swift/Float16)

[`Int32`](/documentation/Swift/Int32)

[`Bool`](/documentation/Swift/Bool)

[`Int128`](/documentation/Swift/Int128)

[`Int`](/documentation/Swift/Int)

[`UnsafeRawBufferPointer`](/documentation/Swift/UnsafeRawBufferPointer)

[`UInt8`](/documentation/Swift/UInt8)

[`UnsafeBufferPointer`](/documentation/Swift/UnsafeBufferPointer)

[`Float`](/documentation/Swift/Float)

[`Int64`](/documentation/Swift/Int64)

[`UnsafeMutableBufferPointer`](/documentation/Swift/UnsafeMutableBufferPointer)

[`UInt32`](/documentation/Swift/UInt32)

[`UInt128`](/documentation/Swift/UInt128)

[`Unmanaged`](/documentation/Swift/Unmanaged)

[`Int16`](/documentation/Swift/Int16)

[`Duration`](/documentation/Swift/Duration)

[`Int8`](/documentation/Swift/Int8)

[`OpaquePointer`](/documentation/Swift/OpaquePointer)

[`UnsafeRawPointer`](/documentation/Swift/UnsafeRawPointer)

[`UnsafeMutableRawPointer`](/documentation/Swift/UnsafeMutableRawPointer)

[`UnsafeMutablePointer`](/documentation/Swift/UnsafeMutablePointer)

[`UnsafeMutableRawBufferPointer`](/documentation/Swift/UnsafeMutableRawBufferPointer)

[`ObjectIdentifier`](/documentation/Swift/ObjectIdentifier)

[`UInt16`](/documentation/Swift/UInt16)

### Inherited By

[`AtomicOptionalRepresentable`](/documentation/Synchronization/AtomicOptionalRepresentable)

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)