<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/71733>71733</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            clang-format enhance SeparateDefinitionBlocks
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang-format
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          FalcoGer
      </td>
    </tr>
</table>

<pre>
    I would like an option for the `SeparateDefinitionBlocks` for clang-format to include a setting that does insert empty lines if either definition spans multiple lines, but not if they both fit on the same line.

Example:

Always:
```c++
int f() { return 42; }

int g() { return 43; }

int h()
{
  const auto ret = 42;
  return ret;
}

int i() { return 44; }
```

Never:
```c++
int f() { return 42; }
int g() { return 43; }
int h()
{
  const auto ret = 42;
  return ret;
}
int i() { return 44; }
```

SeparateMultiline:
```c++
int f() { return 42; }
int g() { return 43; }

int h()
{
  const auto ret = 42;
  return ret;
}

int i() { return 44; }
```

This is especially helpful for classes with lots of simple functions that fit in one line.

```c++
template <typename T>
class TypeSafe
{
 public:
    TypeSafe() : m_value(T()) {}

    explicit TypeSafe(const T& value) : m_value(value) {}

    explicit TypeSafe(T&& value) : m_value(std::move(value)) {}

    TypeSafe(const TypeSafe& other) : m_value(other.m_value) {}

    TypeSafe(TypeSafe&& other) noexcept : m_value(std::move(other.m_value)) {}

    TypeSafe& operator= (const TypeSafe& other)
    {
        m_value = other.m_value;
        return *this;
    }

    TypeSafe& operator= (TypeSafe&& other)
    {
        m_value = std::move(other.m_value);
        return *this;
    }

 operator T () const { return m_value; }

    ~TypeSafe() = default;

  private:
    T m_value;
};
```

Would become a lot more compressed and still readable:

```c++
template <typename T>
class TypeSafe
{
  public:
    TypeSafe() : m_value(T()) {}
    explicit TypeSafe(const T& value) : m_value(value) {}
 explicit TypeSafe(T&& value) : m_value(std::move(value)) {}
 TypeSafe(const TypeSafe& other) : m_value(other.m_value) {}
 TypeSafe(TypeSafe&& other) noexcept : m_value(std::move(other.m_value)) {}

    TypeSafe& operator= (const TypeSafe& other)
    {
 m_value = other.m_value;
        return *this;
    }

 TypeSafe& operator= (TypeSafe&& other)
    {
        m_value = std::move(other.m_value);
        return *this;
    }

 operator T () const { return m_value; }
    ~TypeSafe() = default;

 private:
    T m_value;
};
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzkV02P4jgQ_TXmUmoUHD6aQw4wDKs97F4GaY8r41SIdxzbsit0c9nfvnISIND0DKPuXu1qUMRHufyq_OL3iEUIamcQMzZZsslqIGoqrc_WQkv7C_rB1uaH7Fd4srXOQauvCMKAdaSsgcJ6oBKBTZMv6IQXhCsslFFxdKmt_BrYNGnSpBZm91BYXwkCsqCM1HWOICAgkTI7oFIQ5BYDKBPQE2Dl6ABamRgqABWV6CE_FYDghAlQ1ZqU09hmMv4JtjWBsRQnUYkH2FoqoVAE1jTtBlG12UOWrFiyaN8_P4vKaWTpoh9d6CdxCOfgNGkvyfgyXk1UGYKC8UfG58BmS_BItTcw5ixdAput-oAxd3cjN30lt2xzu_CsqwggrQkEoiYbIYClq7becbzD9Uin4A10daOT8WUnxxX3p_6Oe_TvQsp9dHwUEW-g4Ljhf4vbL26mf5GO__ju2JQqgAqAwaFUQusDlKhdUeujFYSAAZ4UlaAtBbAFBBXFB0VtZNR2aO0gilYZsOaGXm_TTFg5LQiBpZ_o4NBErW9Y-rkdbmrD5uDwiyjwmjZXb7WSpxsJAOfUjol0AdWfe6HrGNl07LcUXREYZ-Oz00oq6sO0t2bD-BQ6nGvYc_hu0Aj3DcRAeVxVuqjsvl_h9SIvGz4FpmCjE7-s0oSHp993QPdAL3CNxWeJjr6zjOuC99ScgnXoBVkfRfHN5Z2n95TVvrqajbAuu0ivMjvdML6gUoWL4R_r8xWu7mzyu9S9oe9jo7CBTiYtpz3bOLNza9V_v1DZKv7Pi1r37KnLdl7tBeGlSOGa_Vjk9P2WR_3RPM9sUdoqPoRoS1BZjyBt5TyGgDkIk0MgpTV4FLnYvng2-AAHei8Lemfz-UjPeX-r-X87zIdYy8_kKz_oKG8wlEGepfk8nYsBZqPpfD6eTfgoGZTZFJPHiZjlc5kkqRgXYoajsXgUj3lSjJDjQGU84elolDzyhE8nyXDChZyPikmByRhRjtk4wUooPdR6Xw2t3w1UCDVms9EsTQdabFGH5sjGef9oxTiPhzifxWkP23oX2DjRKlA4A5EijdnFgQxNKYxEeO0UN6i9zkoi15yE-Jrx9U5RWW-H0laMryN29_HgvP0LJTG-bjoOjK-bpv8JAAD__zINF8A">