ronantakizawa/codereview-bench huggingface dataset:
Repository: SDWebImage/SDWebImage
File: SDWebImage/SDAnimatedImageView.m (Objective-C)

Code before:
        [self stopAnimating];
    }
}

#pragma mark - UIImageView Method Overrides
#pragma mark Image Data

- (void)startAnimating
{
    if (self.animatedImage) {
#if SD_MAC
        CVDisplayLinkStart(self.displayLink);
#else
        self.displayLink.paused = NO;
#endif
    } else {
#if SD_UIKIT
        [super startAnimating];
#endif
    }
}

- (void)stopAnimating
{
    if (self.animatedImage) {
        SD_LOCK(self.lock);
#if SD_MAC
        CVDisplayLinkStop(_displayLink);
#else
        _displayLink.paused = YES;
#endif
        SD_UNLOCK(self.lock);
    } else {
#if SD_UIKIT
        [super stopAnimating];
#endif
    }
}

- (BOOL)isAnimating
{
    BOOL isAnimating = NO;
    if (self.animatedImage) {
#if SD_MAC
        isAnimating = CVDisplayLinkIsRunning(self.displayLink);
#else
        isAnimating = !self.displayLink.isPaused;
#endif
    } else {
#if SD_UIKIT
        isAnimating = [super isAnimating];

Review comment (suggestion):
```suggestion
[self.fetchQueue cancelAllOperations]; // Stop next frames in background
```

Code after:
        [self stopAnimating];
    }
}

#pragma mark - UIImageView Method Overrides
#pragma mark Image Data

- (void)startAnimating
{
    if (self.animatedImage) {
#if SD_MAC
        CVDisplayLinkStart(self.displayLink);
#else
        self.displayLink.paused = NO;
#endif
    } else {
#if SD_UIKIT
        [super startAnimating];
#endif
    }
}

- (void)stopAnimating
{
    if (self.animatedImage) {
        [_fetchQueue cancelAllOperations];
        // Using `_displayLink` here because when UIImageView dealloc, it may trigger `[self stopAnimating]`, we already release the display link in SDAnimatedImageView's dealloc method.
#if SD_MAC
        CVDisplayLinkStop(_displayLink);
#else
        _displayLink.paused = YES;
#endif
    } else {
#if SD_UIKIT
        [super stopAnimating];
#endif
    }
}

- (BOOL)isAnimating
{
    BOOL isAnimating = NO;
    if (self.animatedImage) {
#if SD_MAC
        isAnimating = CVDisplayLinkIsRunning(self.displayLink);
#else
        isAnimating = !self.displayLink.isPaused;
#endif
    } else {
#if SD_UIKIT
        isAnimating = [super isAnimating];
Repository: SDWebImage/SDWebImage
File: SDWebImage/Core/SDImageCodersManager.m (Objective-C)

Code before:
@interface SDImageCodersManager ()

@property (nonatomic, strong, nonnull) dispatch_semaphore_t codersLock;

@end

@implementation SDImageCodersManager
{
    NSMutableArray<id<SDImageCoder>> *_imageCoders;
}

+ (nonnull instancetype)sharedManager {
    static dispatch_once_t once;
    static id instance;
    dispatch_once(&once, ^{
        instance = [self new];
    });
    return instance;
}

- (instancetype)init {
    if (self = [super init]) {
        // initialize with default coders
        _imageCoders = [NSMutableArray arrayWithArray:@[[SDImageIOCoder sharedCoder], [SDImageGIFCoder sharedCoder], [SDImageAPNGCoder sharedCoder]]];
        _codersLock = dispatch_semaphore_create(1);
    }
    return self;
}

- (NSArray<id<SDImageCoder>> *)coders
{
    SD_LOCK(self.codersLock);
    NSArray<id<SDImageCoder>> *coders = [_imageCoders copy];
    SD_UNLOCK(self.codersLock);
    return coders;
}

- (void)setCoders:(NSArray<id<SDImageCoder>> *)coders
{
    SD_LOCK(self.codersLock);
    [_imageCoders removeAllObjects];
    if (coders.count) {
        [_imageCoders addObjectsFromArray:coders];
    }
    SD_UNLOCK(self.codersLock);
}

#pragma mark - Coder IO operations

- (void)addCoder:(nonnull id<SDImageCoder>)coder {
    if (![coder conformsToProtocol:@protocol(SDImageCoder)]) {

Review comment (performance):
This need to be re-considerated.

Current HEIC Animated decoding speed is dramatically slow on both iOS && macOS. Even you have HEVC hardware codec. I assume this is Apple's issue. I've fired a radar.

Maybe make it configurable and not the default value is a better way. And to say, there are nearly no any animated HEIC image on the hole Internet.

Code after:

@interface SDImageCodersManager ()

@property (nonatomic, strong, nonnull) dispatch_semaphore_t codersLock;

@end

@implementation SDImageCodersManager
{
    NSMutableArray<id<SDImageCoder>> *_imageCoders;
}

+ (nonnull instancetype)sharedManager {
    static dispatch_once_t once;
    static id instance;
    dispatch_once(&once, ^{
        instance = [self new];
    });
    return instance;
}

- (instancetype)init {
    if (self = [super init]) {
        // initialize with default coders
        _imageCoders = [NSMutableArray arrayWithArray:@[[SDImageIOCoder sharedCoder], [SDImageGIFCoder sharedCoder], [SDImageAPNGCoder sharedCoder]]];
        if (@available(iOS 11, macOS 10.14, tvOS 11, watchOS 4, *)) {
            [_imageCoders addObject:[SDImageHEICCoder sharedCoder]];
        }
        _codersLock = dispatch_semaphore_create(1);
    }
    return self;
}

- (NSArray<id<SDImageCoder>> *)coders
{
    SD_LOCK(self.codersLock);
    NSArray<id<SDImageCoder>> *coders = [_imageCoders copy];
    SD_UNLOCK(self.codersLock);
    return coders;
}

- (void)setCoders:(NSArray<id<SDImageCoder>> *)coders
{
    SD_LOCK(self.codersLock);
    [_imageCoders removeAllObjects];
    if (coders.count) {
        [_imageCoders addObjectsFromArray:coders];
    }
    SD_UNLOCK(self.codersLock);
}
Repository: SDWebImage/SDWebImage
File: Tests/Tests/SDAnimatedImageTest.m (Objective-C)

Code before:
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 * (c) Matt Galloway
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#import "SDTestCase.h"
#import "SDInternalMacros.h"
#import <KVOController/KVOController.h>

static const NSUInteger kTestGIFFrameCount = 5; // local TestImage.gif loop count

// Internal header
@interface SDAnimatedImageView ()

@property (nonatomic, assign) BOOL isProgressive;
@property (nonatomic, strong) SDAnimatedImagePlayer *player;

@end

@interface SDAnimatedImagePlayer ()

@property (nonatomic, strong) NSMutableDictionary<NSNumber *, UIImage *> *frameBuffer;

@end

@interface SDAnimatedImageTest : SDTestCase

@property (nonatomic, strong) UIWindow *window;

@end

@implementation SDAnimatedImageTest

- (void)test01AnimatedImageInitWithData {
    NSData *invalidData = [@"invalid data" dataUsingEncoding:NSUTF8StringEncoding];
    SDAnimatedImage *image = [[SDAnimatedImage alloc] initWithData:invalidData];
    expect(image).beNil();
    
    NSData *validData = [self testGIFData];
    image = [[SDAnimatedImage alloc] initWithData:validData scale:2];

Review comment (suggestion):
This property can use instance level property. No need a class property.

```
expect(SDImageAPNGTestCoder.sharedCoder.isCalled).beTruth();
```

Code after:
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 * (c) Matt Galloway
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#import "SDTestCase.h"
#import "SDInternalMacros.h"
#import <KVOController/KVOController.h>

static const NSUInteger kTestGIFFrameCount = 5; // local TestImage.gif loop count

// Check whether the coder is called
@interface SDImageAPNGTestCoder : SDImageAPNGCoder

@property (nonatomic, class, assign) BOOL isCalled;

@end

@implementation SDImageAPNGTestCoder

static BOOL _isCalled;

+ (BOOL)isCalled {
    return _isCalled;
}

+ (void)setIsCalled:(BOOL)isCalled {
    _isCalled = isCalled;
}

+ (instancetype)sharedCoder {
    static SDImageAPNGTestCoder *coder;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        coder = [[SDImageAPNGTestCoder alloc] init];
    });
    return coder;
}

- (instancetype)initWithAnimatedImageData:(NSData *)data options:(SDImageCoderOptions *)options {
Repository: SDWebImage/SDWebImage
File: SDWebImage/Core/SDAnimatedImageView.m (Objective-C)

Code before:
}

- (NSUInteger)maxBufferSize {
    return _maxBufferSize; // Defaults to 0
}

- (void)setPlaybackRate:(double)playbackRate
{
    _playbackRate = playbackRate;
    self.player.playbackRate = playbackRate;
}

- (double)playbackRate
{
    if (!_initFinished) {
        return 1.0; // Defaults to 1.0
    }
    return _playbackRate;
}

- (void)setPlaybackMode:(SDAnimatedImagePlaybackMode)playbackMode {
    _playbackMode = playbackMode;
    self.player.playbackMode = playbackMode;
}

- (SDAnimatedImagePlaybackMode)playbackMode {
    return _playbackMode;
}


- (BOOL)shouldIncrementalLoad
{
    if (!_initFinished) {
        return YES; // Defaults to YES
    }
    return _initFinished;
}

#pragma mark - UIView Method Overrides
#pragma mark Observing View-Related Changes

#if SD_MAC
- (void)viewDidMoveToSuperview
#else
- (void)didMoveToSuperview
#endif
{
#if SD_MAC
    [super viewDidMoveToSuperview];
#else
    [super didMoveToSuperview];

Review comment (suggestion):
Write like other property:


```objective-c
- (SDAnimatedImagePlaybackMode)playbackMode
{
    if (!_initFinished) { 
        return SDAnimatedImagePlaybackModeNormal; // Defaults to .nomal
    }
    return _playbackMode;
}
```

Code after:
}

- (NSUInteger)maxBufferSize {
    return _maxBufferSize; // Defaults to 0
}

- (void)setPlaybackRate:(double)playbackRate
{
    _playbackRate = playbackRate;
    self.player.playbackRate = playbackRate;
}

- (double)playbackRate
{
    if (!_initFinished) {
        return 1.0; // Defaults to 1.0
    }
    return _playbackRate;
}

- (void)setPlaybackMode:(SDAnimatedImagePlaybackMode)playbackMode {
    _playbackMode = playbackMode;
    self.player.playbackMode = playbackMode;
}

- (SDAnimatedImagePlaybackMode)playbackMode {
    if (!_initFinished) {
        return SDAnimatedImagePlaybackModeNormal; // Default mode is normal
    }
    return _playbackMode;
}


- (BOOL)shouldIncrementalLoad
{
    if (!_initFinished) {
        return YES; // Defaults to YES
    }
    return _initFinished;
}

#pragma mark - UIView Method Overrides
#pragma mark Observing View-Related Changes

#if SD_MAC
- (void)viewDidMoveToSuperview
#else
- (void)didMoveToSuperview
#endif
{
#if SD_MAC
Repository: SerenityOS/serenity
File: Kernel/Memory/AnonymousVMObject.cpp (C++)

Code before:
        VERIFY(page);
        if (page->is_shared_zero_page())
            ++committed_pages_needed;
    }

    if (!committed_pages_needed) {
        m_volatile = false;
        return {};
    }

    m_unused_committed_pages = TRY(MM.commit_physical_pages(committed_pages_needed));

    for (auto& page : m_physical_pages) {
        if (page->is_shared_zero_page())
            page = MM.lazy_committed_page();
    }

    m_volatile = false;
    m_was_purged = false;
    remap_regions();
    return {};
}

NonnullRefPtr<PhysicalRAMPage> AnonymousVMObject::allocate_committed_page(Badge<Region>)
{
    return m_unused_committed_pages->take_one();
}

void AnonymousVMObject::reset_cow_map()
{
    for (size_t i = 0; i < page_count(); ++i) {
        auto& page = physical_pages()[i];
        bool should_cow = !page->is_shared_zero_page() && !page->is_lazy_committed_page();
        m_cow_map.set(i, should_cow);
    }
}

ErrorOr<void> AnonymousVMObject::ensure_cow_map()
{
    if (m_cow_map.is_null()) {
        m_cow_map = TRY(Bitmap::create(page_count(), true));
        reset_cow_map();
    }
    return {};
}

ErrorOr<void> AnonymousVMObject::ensure_or_reset_cow_map()
{
    if (m_cow_map.is_null())
        TRY(ensure_cow_map());
    else

Review comment (suggestion):
`AnonymousVMObject::should_cow` returns true if the physical page is the shared_zero_page or the lazy_committed_page, so I am unsure if we have other code expecting that pages referencing these physical pages are CoW (it does kind of make sense to make these CoW, since when writing to those we have to zero them and therefore essentially copy the contents).

Code after:
        return {};
    }

    m_unused_committed_pages = TRY(MM.commit_physical_pages(committed_pages_needed));

    for (auto& page : m_physical_pages) {
        if (page->is_shared_zero_page())
            page = MM.lazy_committed_page();
    }

    m_volatile = false;
    m_was_purged = false;
    remap_regions();
    return {};
}

NonnullRefPtr<PhysicalRAMPage> AnonymousVMObject::allocate_committed_page(Badge<Region>)
{
    return m_unused_committed_pages->take_one();
}

void AnonymousVMObject::reset_cow_map()
{
    for (size_t i = 0; i < page_count(); ++i) {
        auto& page = physical_pages()[i];
        bool should_cow = !page->is_shared_zero_page() && !page->is_lazy_committed_page();
        m_cow_map.set(i, should_cow);
    }
}

ErrorOr<void> AnonymousVMObject::ensure_cow_map()
{
    if (m_cow_map.is_null()) {
        m_cow_map = TRY(Bitmap::create(page_count(), true));
        reset_cow_map();
    }
    return {};
}

ErrorOr<void> AnonymousVMObject::ensure_or_reset_cow_map()
{
    if (m_cow_map.is_null())
        TRY(ensure_cow_map());
    else
        reset_cow_map();
    return {};
}

bool AnonymousVMObject::should_cow(size_t page_index, bool is_shared) const
{
    auto const& page = physical_pages()[page_index];
Repository: SerenityOS/serenity
File: Userland/Libraries/LibGfx/ImageFormats/ImageDecoder.h (C/C++)

Code before:
    int duration { 0 };
};

class Metadata {
public:
    Metadata() = default;
    virtual ~Metadata() = default;

    HashMap<StringView, String> const& main_tags() const
    {
        if (m_main_tags.is_empty())
            fill_main_tags();

        // This is designed to be used in a general GUI, don't include too much information here.
        VERIFY(m_main_tags.size() < 8);

        return m_main_tags;
    }

protected:
    virtual void fill_main_tags() const { }

    mutable HashMap<StringView, String> m_main_tags;
};

struct Gps {
    double latitude;
    double longitude;
};

enum class NaturalFrameFormat {
    RGB,
    Grayscale,
    CMYK,
    Vector,
};

class ImageDecoderPlugin {
public:
    virtual ~ImageDecoderPlugin() = default;

    // Each plugin should implement these static functions and register them in ImageDecoder.cpp
    // Implement sniff() if the file includes a magic number
    // static bool sniff(ReadonlyBytes);
    // Implement validate_before_create() otherwise
    // static ErrorOr<bool> validate_before_create(ReadonlyBytes);

    // This function should be used to both create the context and parse the image header.
    // static ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> create(ReadonlyBytes);

    // This should always be available as gathered in create()

Review comment (suggestion):
If you end up reusing this `struct`:

s/Gps/GPS

And please always default initialize the values of the struct.

Code after:
};

class Metadata {
public:
    Metadata() = default;
    virtual ~Metadata() = default;

    HashMap<StringView, String> const& main_tags() const
    {
        if (m_main_tags.is_empty())
            fill_main_tags();

        // This is designed to be used in a general GUI, don't include too much information here.
        VERIFY(m_main_tags.size() < 8);

        return m_main_tags;
    }

protected:
    virtual void fill_main_tags() const {};

    mutable HashMap<StringView, String> m_main_tags;
};

enum class NaturalFrameFormat {
    RGB,
    Grayscale,
    CMYK,
    Vector,
};

class ImageDecoderPlugin {
public:
    virtual ~ImageDecoderPlugin() = default;

    // Each plugin should implement these static functions and register them in ImageDecoder.cpp
    // Implement sniff() if the file includes a magic number
    // static bool sniff(ReadonlyBytes);
    // Implement validate_before_create() otherwise
    // static ErrorOr<bool> validate_before_create(ReadonlyBytes);

    // This function should be used to both create the context and parse the image header.
    // static ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> create(ReadonlyBytes);

    // This should always be available as gathered in create()
    virtual IntSize size() = 0;

    // Override this if the format supports animated images
    virtual bool is_animated() { return false; }
    virtual size_t loop_count() { return 0; }
    virtual size_t frame_count() { return 1; }
Repository: SerenityOS/serenity
File: Kernel/Arch/aarch64/PSCI.h (C/C++)

Code before:
/*
 * Copyright (c) 2025, the SerenityOS developers
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

namespace Kernel::PSCI {

bool psci_supported();
void do_psci_poweroff();
void do_psci_reset();

}


Review comment (suggestion):
We usually add the `is_` prefix to functions returning a `bool`. And, as it's already in the `PSCI` namespace, you could simply name that function `is_supported()`.

Code after:
/*
 * Copyright (c) 2025, the SerenityOS developers
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

namespace Kernel::PSCI {

bool is_supported();
void poweroff();
void reset();

}
Repository: SerenityOS/serenity
File: Kernel/Arch/aarch64/PSCI.cpp (C++)

Code before:
                 : "=r"(a0), "=r"(a1), "=r"(a2), "=r"(a3)
                 : "0"(a0),
                 "r"(a1),
                 "r"(a2),
                 "r"(a3),
                 "r"(a4),
                 "r"(a5),
                 "r"(a6),
                 "r"(a7));

    return a0;
}

bool is_supported()
{
    // https://www.kernel.org/doc/Documentation/devicetree/bindings/arm/psci.txt
    auto psci = DeviceTree::get().get_child("psci"sv);
    if (!psci.has_value())
        return false;

    // NOTE: We reject "arm,psci" on purpose, since these old devices don't have standardized function IDs.
    if (!psci->is_compatible_with("arm,psci-0.2"sv) && !psci->is_compatible_with("arm,psci-1.0"sv))
        return false;

    auto method = psci->get_property("method"sv);
    VERIFY(method.has_value());

    // Currently, we only support HVC (as opposed to SMC). While SMC is very similar to HVC, only the latter has been tested so far.
    if (method->as_string() != "hvc"sv)
        return false;

    return true;
}

void poweroff()
{
    aarch64_hvc(PSCI_SYSTEM_OFF, 0, 0, 0, 0, 0, 0, 0);
}

void reset()
{
    aarch64_hvc(PSCI_SYSTEM_RESET, 0, 0, 0, 0, 0, 0, 0);
}

}


Review comment (bug):
Please don't `VERIFY` here. Returning `false` and maybe printing a debug message seems nicer than crashing on invalid devicetrees.

Code after:
    asm volatile(
        "hvc #0"
        : "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3)
        :
        : "memory", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17");

    return x0;
}

bool is_supported()
{
    // https://www.kernel.org/doc/Documentation/devicetree/bindings/arm/psci.txt
    // FIXME: Make this a DeviceTree::Driver, and don't assume that the psci node is a child of the root node.
    auto psci = DeviceTree::get().get_child("psci"sv);
    if (!psci.has_value())
        return false;

    // NOTE: We reject "arm,psci" on purpose, since these old devices don't have standardized function IDs.
    if (!psci->is_compatible_with("arm,psci-0.2"sv) && !psci->is_compatible_with("arm,psci-1.0"sv))
        return false;

    auto method = psci->get_property("method"sv);
    if (!method.has_value()) {
        dbgln("PSCI: No method property found");
        return false;
    }

    // Currently, we only support HVC (as opposed to SMC). While SMC is very similar to HVC, only the latter has been tested so far.
    if (method->as_string() != "hvc"sv)
        return false;

    return true;
}

void poweroff()
{
    call(Function::SystemOff, 0, 0, 0);
}

void reset()
{
    call(Function::SystemReset, 0, 0, 0);
}

}
Repository: SerenityOS/serenity
File: Kernel/Arch/aarch64/PowerState.cpp (C++)

Code before:
/*
 * Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <Kernel/Arch/PowerState.h>
#include <Kernel/Arch/aarch64/PSCI.h>
#include <Kernel/Arch/aarch64/RPi/Watchdog.h>
#include <Kernel/Firmware/DeviceTree/DeviceTree.h>

namespace Kernel {

void arch_specific_reboot()
{
    if (PSCI::is_supported())
        PSCI::reset();
}

void arch_specific_poweroff()
{
    if (DeviceTree::get().is_compatible_with("raspberrypi,3-model-b"sv) || DeviceTree::get().is_compatible_with("raspberrypi,4-model-b"sv))
        RPi::Watchdog::the().system_shutdown();

    if (PSCI::is_supported())
        PSCI::poweroff();
}

}


Review comment (suggestion):
I would try `PSCI::poweroff` before platform-specific mechanisms, as the firmware might do some extra stuff before shutdown.
PSCI might be present even on the Pi 3 and 4 if we booted with Trusted Firmware-A (which is needed for the Raspberry Pi EDK2 UEFI firmware).

Code after:
/*
 * Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <Kernel/Arch/PowerState.h>
#include <Kernel/Arch/aarch64/PSCI.h>
#include <Kernel/Arch/aarch64/RPi/Watchdog.h>
#include <Kernel/Firmware/DeviceTree/DeviceTree.h>

namespace Kernel {

void arch_specific_reboot()
{
    if (PSCI::is_supported())
        PSCI::reset();
}

void arch_specific_poweroff()
{
    if (PSCI::is_supported())
        PSCI::poweroff();

    if (DeviceTree::get().is_compatible_with("raspberrypi,3-model-b"sv) || DeviceTree::get().is_compatible_with("raspberrypi,4-model-b"sv))
        RPi::Watchdog::the().system_shutdown();
}

}
Repository: SerenityOS/serenity
File: AK/SyncGenerator.h (C/C++)

Code before:
            new (&m_generator->m_value) Y(move(value));
            return {};
        }

        Detail::SuspendAlways yield_value(Y const& value)
        requires IsCopyConstructible<Y>
        {
            new (&m_generator->m_value) Y(value);
            return {};
        }

        void await_transform(auto&& awaiter) = delete;

        SyncGenerator* m_generator { nullptr };
    };

    SyncGenerator(std::coroutine_handle<PromiseType> handle)
        : m_handle(handle)
        , m_empty({})
    {
        m_handle.promise().m_generator = this;
    }

    std::coroutine_handle<PromiseType> m_handle;

    union {
        Empty m_empty;
        Y m_value;
    };
};

}

#ifdef USING_AK_GLOBALLY
using AK::SyncGenerator;
#endif


Review comment (suggestion):
AFAIK you don't need the `m_empty` member, as long as you don't use `constexpr`, and then it would have to be `Y`-sized to appease GCC

Code after:
            new (&m_generator->m_value) Y(move(value));
            return {};
        }

        Detail::SuspendAlways yield_value(Y const& value)
        requires IsCopyConstructible<Y>
        {
            new (&m_generator->m_value) Y(value);
            return {};
        }

        void await_transform(auto&& awaiter) = delete;

        SyncGenerator* m_generator { nullptr };
    };

    SyncGenerator(std::coroutine_handle<PromiseType> handle)
        : m_handle(handle)
    {
        m_handle.promise().m_generator = this;
    }

    std::coroutine_handle<PromiseType> m_handle;

    union {
        Y m_value;
    };
};

}

#ifdef USING_AK_GLOBALLY
using AK::SyncGenerator;
#endif