---
BasedOnStyle: LLVM
Standard:     Auto # let the formatter accept any C++ standard

# =============================================================================
# Indentation
# =============================================================================
TabWidth:                          2
ContinuationIndentWidth:           2
ConstructorInitializerIndentWidth: 2
NamespaceIndentation:              All        # everything inside namespace is indented
IndentCaseLabels:                  true       # case labels at switch-body indent level
IndentCaseBlocks:                  true       # indent block inside case label
IndentExternBlock:                 Indent
IndentWrappedFunctionNames:        true       # keep function name at same indent as return type
IndentPPDirectives:                BeforeHash # nested #if / #include get indented before the #
PPIndentWidth:                     2

# =============================================================================
# Braces & line-break style
# =============================================================================
BreakBeforeBraces:               Allman
BreakConstructorInitializers:    BeforeComma   # colon on new line, commas lead
BreakInheritanceList:            BeforeComma
BreakBeforeBinaryOperators:      NonAssignment
BreakStringLiterals:             false
AlwaysBreakTemplateDeclarations: Yes           # template <…> always on its own line
BreakAfterAttributes:            Always

# =============================================================================
# Short statements
# =============================================================================
AllowShortBlocksOnASingleLine:     Empty
AllowShortFunctionsOnASingleLine:  Empty  # only empty bodies: void f() {}
AllowShortCaseLabelsOnASingleLine: true   # case X: stmt; break; on one line
AllowShortLoopsOnASingleLine:      true
AllowShortLambdasOnASingleLine:    Inline

# =============================================================================
# Empty lines
# =============================================================================
KeepEmptyLinesAtTheStartOfBlocks: false
EmptyLineBeforeAccessModifier:    Always # blank line before public:/private:/protected:
EmptyLineAfterAccessModifier:     Always # blank line after  public:/private:/protected:
InsertNewlineAtEOF:               true

# =============================================================================
# Spacing
# =============================================================================
SpacesInAngles:            Leave # preserve C++03 "> >" vs C++11 ">>"
SpacesInContainerLiterals: false

# =============================================================================
# Alignment
# =============================================================================
PointerAlignment:             Left # T* ptr, const T& ref
ReferenceAlignment:           Left
AlignConsecutiveAssignments:  true
AlignConsecutiveDeclarations: true
AlignConsecutiveBitFields:    true
AlignConsecutiveMacros:       true # align macro bodies

# =============================================================================
# Line length and wrapping
# =============================================================================
ColumnLimit:    150
ReflowComments: true # preserve hand-formatted comment rulers
AlignEscapedNewlines: Left

# =============================================================================
# Includes
# =============================================================================
IncludeCategories:
  - Regex:    '^(<|")(.*/)?platform\.h(>|")$'
    Priority: -1
  - Regex:    'private'
    Priority: 1
  - Regex:    '.*'
    Priority: 0

# =============================================================================
# Arguments, parameters and constructor initialisers
# =============================================================================
PackConstructorInitializers: Never # each initialiser on its own line

# =============================================================================
# Namespaces and using declarations
# =============================================================================
SortUsingDeclarations: Lexicographic

# =============================================================================
# Macro-aware formatting
# =============================================================================
# ETL-specific macros that should be treated as statement-level constructs
StatementMacros:
  - ETL_DECLARE_DEBUG_COUNT
  - ETL_INCREMENT_DEBUG_COUNT
  - ETL_DECREMENT_DEBUG_COUNT
  - ETL_ADD_DEBUG_COUNT
  - ETL_STATIC_ASSERT
  - ETL_ASSERT
  - ETL_ASSERT_OR_RETURN
  - ETL_ASSERT_OR_RETURN_VALUE
  - ETL_ASSERT_FAIL
  - ETL_ASSERT_FAIL_AND_RETURN
  - ETL_ASSERT_FAIL_AND_RETURN_VALUE
  - ETL_MOVE
  - ETL_ENUM_CLASS
  - ETL_ENUM_CLASS_TYPE
  - ETL_IF_CONSTEXPR

# Macros that behave like attributes or specifiers.
AttributeMacros:
  - ETL_NORETURN
  - ETL_FINAL
  - ETL_OVERRIDE
  - ETL_EXPLICIT
  - ETL_DELETE
  - ETL_CONSTANT
  - ETL_CONSTEXPR
  - ETL_CONSTEXPR11
  - ETL_CONSTEXPR14
  - ETL_CONSTEXPR17
  - ETL_CONSTEXPR20
  - ETL_CONSTEXPR23
  - ETL_CONSTEVAL
  - ETL_NODISCARD
  - ETL_NORETURN
  - ETL_DEPRECATED
  - ETL_DEPRECATED_REASON
  - ETL_LIKELY
  - ETL_UNLIKELY
  - ETL_FALLTHROUGH
  - ETL_MAYBE_UNUSED
  - ETL_INLINE_VAR
  - ETL_ASSUME
  - ETL_LVALUE_REF_QUALIFIER
  - ETL_RVALUE_REF_QUALIFIER
  - ETL_NOEXCEPT
  - ETL_NOEXCEPT_EXPR
  - ETL_NOEXCEPT_IF
  - ETL_NOEXCEPT_FROM

Macros:
  - ETL_NORETURN=[[noreturn]]
  - ETL_FINAL=final
  - ETL_OVERRIDE=override
  - ETL_EXPLICIT=explicit
  - ETL_DELETE=delete
  - ETL_CONSTANT=const
  - ETL_CONSTEXPR=constexpr
  - ETL_CONSTEXPR11=constexpr
  - ETL_CONSTEXPR14=constexpr
  - ETL_CONSTEXPR17=constexpr
  - ETL_CONSTEXPR20=constexpr
  - ETL_CONSTEXPR23=constexpr
  - ETL_CONSTEVAL=consteval
  - ETL_NODISCARD=[[nodiscard]]
  - ETL_NORETURN=[[noreturn]]
  - ETL_DEPRECATED=[[deprecated]]
#  - ETL_DEPRECATED_REASON=[[deprecated(%0)]] # Hangs with clang-format 18
  - ETL_LIKELY=[[likely]]
  - ETL_UNLIKELY=[[unlikely]]
  - ETL_FALLTHROUGH=[[fallthrough]]
  - ETL_MAYBE_UNUSED=[[maybe_unused]]
  - ETL_INLINE_VAR=inline
  - ETL_ASSUME=[[assume(&0)]]
  - ETL_LVALUE_REF_QUALIFIER=&
  - ETL_RVALUE_REF_QUALIFIER=&&
  - ETL_NOEXCEPT=noexcept
#  - ETL_NOEXCEPT_EXPR=noexcept(&0)) # Hangs with clang-format 18
#  - ETL_NOEXCEPT_IF=noexcept(&0)    # Hangs with clang-format 18
#  - ETL_NOEXCEPT_FROM=noexcept(&0)  # Hangs with clang-format 18

# Macros that behave like type names
TypenameMacros:
  - ETL_OR_STD

# Do not reformat these macros — they contain DSL-like content
WhitespaceSensitiveMacros:
  - ETL_ERROR_TEXT
  - ETL_DECLARE_ENUM_TYPE
  - ETL_ENUM_TYPE
  - ETL_END_ENUM_TYPE
