728x90

다른 글 이외에 잡다하지만 유용해 보이는 것들에 대해 정리...

 

https://en.cppreference.com/w/cpp/utility/source_location

 

std::source_location - cppreference.com

struct source_location; (since C++20) The std::source_location class represents certain information about the source code, such as file names, line numbers, and function names. Previously, functions that desire to obtain this information about the call sit

en.cppreference.com

 

https://en.cppreference.com/w/cpp/utility/functional/bind_front

 

std::bind_front, std::bind_back - cppreference.com

template< class F, class... Args > constexpr /* unspecified */ bind_front( F&& f, Args&&... args ); (1) (since C++20) template< auto ConstFn, class... Args > constexpr /* unspecified */ bind_front( Args&&... args ); (2) (since C++26) template< class F, cla

en.cppreference.com

 

https://en.cppreference.com/w/cpp/types/is_constant_evaluated

 

std::is_constant_evaluated - cppreference.com

constexpr bool is_constant_evaluated() noexcept; (since C++20) Detects whether the function call occurs within a constant-evaluated context. Returns true if the evaluation of the call occurs within the evaluation of an expression or conversion that is mani

en.cppreference.com

 

https://en.cppreference.com/w/cpp/atomic/atomic_ref

 

std::atomic_ref - cppreference.com

template< class T > struct atomic_ref; (1) (since C++20) template< class T > struct atomic_ref ; (2) (since C++20) The std::atomic_ref class template applies atomic operations to the object it references. For the lifetime of the std::atomic_ref object, the

en.cppreference.com

 

https://en.cppreference.com/w/cpp/experimental/atomic_shared_ptr

 

std::experimental::atomic_shared_ptr - cppreference.com

Merged into ISO C++ The functionality described on this page was merged into the mainline ISO C++ standard as of 11/2017; see std::atomic > (since C++20) template< class T > class atomic_shared_ptr; (concurrency TS) The class template atomic_shared_ptr pro

en.cppreference.com

 

https://en.cppreference.com/w/cpp/thread/counting_semaphore

 

std::counting_semaphore, std::binary_semaphore - cppreference.com

template< std::ptrdiff_t LeastMaxValue = /* implementation-defined */ > class counting_semaphore; (1) (since C++20) using binary_semaphore = std::counting_semaphore<1>; (2) (since C++20) 1) A counting_semaphore is a lightweight synchronization primitive th

en.cppreference.com

 

https://en.cppreference.com/w/cpp/thread/latch

 

std::latch - cppreference.com

class latch; (since C++20) The latch class is a downward counter of type std::ptrdiff_t which can be used to synchronize threads. The value of the counter is initialized on creation. Threads may block on the latch until the counter is decremented to zero.

en.cppreference.com

 

https://en.cppreference.com/w/cpp/thread/barrier

 

std::barrier - cppreference.com

template< class CompletionFunction = /* see below */ > class barrier; (since C++20) The class template std::barrier provides a thread-coordination mechanism that blocks a group of threads of known size until all threads in that group have reached the barri

en.cppreference.com

 

 

https://en.cppreference.com/w/cpp/io/basic_osyncstream

 

std::basic_osyncstream - cppreference.com

The class template std::basic_osyncstream is a convenience wrapper for std::basic_syncbuf. It provides a mechanism to synchronize threads writing to the same stream. It can be used with a named variable: { std::osyncstream synced_out(std::cout); // synchro

en.cppreference.com

 

 

728x90

'Basic Programming > C++ 20' 카테고리의 다른 글

C++20 - jthread  (0) 2024.01.21
C++20 - format  (0) 2024.01.20
C++20 - Time Zone  (0) 2024.01.20
C++20 - Calendar  (0) 2024.01.17
C++20 - 비트연산  (0) 2024.01.17
728x90

그 동안 std::thread를 사용한 예제를 보면 다음과 같다

void ThreadWork()
{
    while(true)
    {
        // work...
    }
};

int main()
{
    std::thread t(ThreadWork);
    
    // 쓰레드가 종료되길 기다려줘야 한다.
    if (t.joinable())
    {
        t.join();
    }
}

 

이번에 jthread는 쉽게 말하면 소멸자에서 join을 해준다. 즉 위의 코드를 아래와 같이 변경할 수 있다.

void ThreadWork()
{
    while(true)
    {
        // work...
    }
};

int main()
{
    std::jthread t(ThreadWork);
}

 

 

하지만 위의 코드들은 thread가 종료되지 않는다. 종료되는 코드를 추가하면 다음과 같다.

bool gRunning =true;

void ThreadWork()
{
    while(gRunning)
    {
        // work...
    }
};

int main()
{
    std::thread t(ThreadWork);
    
    // 쓰레드 종료 요청
    gRunning = false;
    
    // 쓰레드가 종료되길 기다려줘야 한다.
    if (t.joinable())
    {
        t.join();
    }
}

 

jthread를 이용하면 조금 더 우아하게 종료할 수 있게 된다.

void ThreadWork(std::stop_token stopToken)
{
    while(true)
    {
        if (stopToken.stop_requested())
            break;
    }
};

int main()
{
    std::jthread t(ThreadWork);
    
    t.request_stop();
}

 

그 동안 사용했던 std::thread를 좀 더 관리하기 쉬워질 것 같다.

728x90

'Basic Programming > C++ 20' 카테고리의 다른 글

C++20 - 그 외 함수들...  (0) 2024.01.21
C++20 - format  (0) 2024.01.20
C++20 - Time Zone  (0) 2024.01.20
C++20 - Calendar  (0) 2024.01.17
C++20 - 비트연산  (0) 2024.01.17
728x90

C++을 좀 사용해보신분들은 이미 fmt::format을 많이 쓰고 있었을거라고 생각한다.

이제 동일한 기능이 C++20에도 포함이 되었다.

// format : format string 반환
auto str = std::format("{}, {}, {}", 1, 1.1, asdf);

// format_to : 결과를 output iterator에 반환
std::string buffer;
format_to(std::back_inserter(buffer), "{}, {}, {}", 1, 1.1, asdf);

// format_to_n : 최대 n개의 문자를 output iterator에 반환
std::string buffer2;
format_to(std::back_inserter(buffer2), 2, "{}, {}, {}", 1, 1.1, asdf);

 

만약 문자열에 "{" 를 사용하고 싶으면 {{ 와 같이 두개를 사용하면된다.

auto str = format("{{asdf {}}}", 5);

 

순서 지정하는 방법

format("{}, {}, {}", 10, 20, 30);
format("{1}, {0}, {2}", 10, 20, 30);

 

빈칸 채우는 문자 지정 (default : space)
정렬
 < left : 숫자가 아니면 default
 > right : 숫자면 default
 ^ center

format("{:10}", 5);   // "         5"
format("{:*<10}", 5); // "5*********"
format("{:*>10}", 5); // "*********5"
format("{:*^10}", 5); // "****5*****"

 

부호 (정수나 부동소수점에 사용)
 + : 양수면 + 붙여라
 - : 음수면 - 붙여라

format("{0:}, {0:+}, {0:-}", 0) // 0, +0, 0
format("{0:}, {0:+}, {0:-}", 1) // 1, +1, 1
format("{0:}, {0:+}, {0:-}", -1) // -1, -1, -1

 

정수에 대한 이진수, 팔진수, 십육진수 표현
 b : 이진수
 미지정 : 팔진수
 x : 십육진수
 #015 : 0을 15개의 padding 추가

format("#015", 0x78)  "000000000000120"
format("#015b", 0x78) "0b0000001111000"
format("#015x", 0x78) "0x0000000000078"

 

위에서 {:10} 은 최소 10개를 만든다는 뜻이었다. 반대로 최대 갯수도 지정할 수 있다.
precision 부동소수점과 문자열의 최대 갯수를 지정

double d = 123.456789;

format("{:.50}", d);            // "123.45678900000000555777....."
format("{:.8}", d);             // "123.45679" - 반올림됨
format("{:.5}", d);             // "123.46" - 반올림됨
format("{:.5}", "Hello World");	// "Hello"

 

타입 지정
 s : string
 b : binary 0b로 시작
 B : b와 같지만 0B로 시작
 d : decimal
 o : octal
 x : hexadecimal 0x로 시작
 X : x와 같지만 0X로 시작
 부동소수점 관련 (e, E, f, F ,g, G) : 생략... (지수 표시, 정밀도 등등...)


728x90

'Basic Programming > C++ 20' 카테고리의 다른 글

C++20 - 그 외 함수들...  (0) 2024.01.21
C++20 - jthread  (0) 2024.01.21
C++20 - Time Zone  (0) 2024.01.20
C++20 - Calendar  (0) 2024.01.17
C++20 - 비트연산  (0) 2024.01.17
728x90

전 세계에서 사용하는 프로그램을 개발할 때 시간이 관련된 작업을 하게 될 것이다.

이때 Local Time으로 시간 계산을 하게되면 나라마다의 시차를 계산하기 어려워진다.

그렇기 때문에 UTC(Coordinated Universal Time 협정 세계시)를 이용하여 시간을 계산하게 된다

- 영국 : UTC+0.00 (Greenwich Mean Time, GMT)
- 한국 : UTC+9.00
- 뉴욕 : UTC-5.00
...

이렇듯 각 나라마다 시간 계산을 해줘야하는데, 드디어 C++20에서 지원해주게 되었다.

using namespace std;
using namespace std::chrono;

auto utcTime :: system_clock::now();
cout << utcTime << endl;

auto localTime = zoned_time(current_zone(), utcTime);
cout << localTime << endl;

auto localTime2 = zoned_time("Asia/Shanghai"s, utcTime);
cout << localTime2 << endl;

 

추가로 유닉스 시간이라는 개념에 대해서 알아둬야한다.

유닉스 시간(Unix Time)은 시각을 나타내는 방식이고, POSIX, Epoch 시간이라고도 부른다.
1970년 1월 1일 00:00:00 협정 세계시(UTC) 부터의 경과 시간을 초로 환산하여 정수로 나타낸 것이다.

using namespace std;
using namespace std::chrono;

auto utcTime = system_clock::now();

int64_t hoursSinceUtc = duration<hours>(utcTime.time_since_epoch()).count();
int64_t utcEpoch = duration<seconds>(utcTime.time_since_epoch()).count();
728x90

'Basic Programming > C++ 20' 카테고리의 다른 글

C++20 - jthread  (0) 2024.01.21
C++20 - format  (0) 2024.01.20
C++20 - Calendar  (0) 2024.01.17
C++20 - 비트연산  (0) 2024.01.17
C++20 - erase, erase_if  (1) 2023.12.29
728x90

이번에 chrono에 시간관련 라이브러리가 추가되었다

매우 사용하기 쉬우니... 한번 돌려보면 바로 이해 될 듯...

// hh_mm_ss : duration since midnight, split into hours, minutes, seconds, fractional seconds

auto timeOfDay = std::chrono::hh_mm_ss(12.5h + 32min + 100s + 0.6s);
cout << timeOfDay << endl;
cout << timeOfDay.hours() << endl;
cout << timeOfDay.minutes() << endl;
cout << timeOfDay.seconds() << endl;
cout << timeOfDay.subseconds() << endl;
cout << timeOfDay.to_duration() << endl;

// Calendar Date
using namespace chrono;
chrono::year_month_day ymd1{year(2021), month(11), day(14)};
chrono::year_month_day ymd2{year(2021)/month(11)/day(14)};
chrono::year_month_day ymd3{2021y, November, 14d};
cout << ymd1 << endl;
	
// 해당 년/월의 마지막날을 가져오는 방법
// year/month/day
// day/month/year
// month/day/year
std::chrono::year_month_day_last ymdl1 = 2021y / November / last;
std::chrono::year_month_day_last ymdl2 = last / November / 2021y;
std::chrono::year_month_day_last ymdl3 = November / last / 2021;
auto d1 = ymdl1.day();
chrono::year_month_day ymd4{ymdl1};

// 해당 년/월의 4번째 금요일 날짜 가져오는 방법
std::chrono::year_month_weekday ymwkd1{year(2021)/November/Friday[4]};
chrono::year_month_day ymd5{ ymwkd1 };

// timepoint
time_point timePoint = chrono::sys_days(ymd1);

// Cute Syntax
// 2021y, 30d, January, February, ... December

// Validation
std::chrono::day d{31};
d++;
bool valid = d.ok();

auto leapYear2000{year(2000)/2/29};
auto leapYear2001{year(2001)/2/29};
auto leapYear2002{year(2002)/2/29};

bool valid2 = leapYear2000.ok(); // true
bool valid3 = leapYear2001.ok(); // false
bool valid4 = leapYear2002.ok(); // false

auto now = std::chrono::system_clock::now();
auto diff = floor<chrono::hours>(now) - sys_days(1987y / January / 30d);

 

 

728x90

'Basic Programming > C++ 20' 카테고리의 다른 글

C++20 - format  (0) 2024.01.20
C++20 - Time Zone  (0) 2024.01.20
C++20 - 비트연산  (0) 2024.01.17
C++20 - erase, erase_if  (1) 2023.12.29
C++20 - Template Parameter for Lambda  (0) 2023.12.28
728x90

그 동안 사용했던 비트연산을 요약하면 다음과 같다

enum Type
{
    test = 3
};

unsigned int bit = 0;

// 추가
bit |= (1 << test);

// 포함 여부 확인
bool check = (bit & (1 << test));

// 삭제
bit &= ~(1 << test);

// 토글
bit ^= (1 << test);

 

좀 더 편하게 사용해라고 이번에 C++20에서 비트연산에 대한 다양한 함수들이 추가되었다.

 

엔디안 확인 기능

// 리틀 엔디안, 빅 엔디안 등등을 확인할 수 있다.
if (std::endian::native == std::endian::little)
{
    cout << "little" << endl;
}
else
{
    cout << "big" << endl;
}

 

그 외에 추가된 함수들...

// bit_cast : 새로운 캐스팅
// has_single_bit	: 어떤 숫자가 2^n 형태인지 (2의 거듭제곱)
// popcount : unsigned int 숫자에서 1의 개수
// bit_ceil : 해당 값보다 작지 않은 (2의 거듭제곱)중 제일 작은 것 (floor < num < ceil)
// bit_floor : 해당 값보다 크지 않은 (2의 거듭제곱)중 제일 큰 것 (floor < num < ceil)
// bit_width : 해당 값을 표현하기 위해 필요한 최소 비트 개수
// rotl : bitwise left-rotation
// rotr : bitwise right-rotation
// countl_zero : 제일 큰 비트부터 시작해서, 연속된 0의 개수
// countl_one : 제일 큰 비트부터 시작해서, 연속된 1의 개수
// countr_zero : 제일 작은 비트부터 시작해서, 연속된 0의 개수
// countr_one : 제일 작은 비트부터 시작해서, 연속된 1의 개수

std::uint8_t num = 0b00110010;
cout << boolalpha;

cout << std::has_single_bit(num) << endl; // false
cout << popcount(num) << endl; // 3
cout << std::bitset<8>(std::bit_ceil(num)) << endl; // 0b01000000
cout << std::bitset<8>(std::bit_floor(num)) << endl; // 
cout << std::bit_width(5u) << endl; // width(0x000101) = 3
cout << std::bitset<8>(std::rotl(num, 2)) << endl; // 0b11001000
cout << std::bitset<8>(std::rotr(num, 2)) << endl; // 0b10001100
cout << countl_zero(num) << endl; // 2
cout << countl_one(num) << endl; // 0
cout << countr_zero(num) << endl; // 1
cout << countr_one(num) << endl; // 0
728x90

'Basic Programming > C++ 20' 카테고리의 다른 글

C++20 - Time Zone  (0) 2024.01.20
C++20 - Calendar  (0) 2024.01.17
C++20 - erase, erase_if  (1) 2023.12.29
C++20 - Template Parameter for Lambda  (0) 2023.12.28
C++20 - NonType Template Parameter  (0) 2023.12.28
728x90

우리가 STL에서 어떤 요소를 삭제하려면 굉장히 귀찮은 작업을 했었다.

기존의 STL Vector에서의 요소 삭제 코드

int main()
{
    std::vector<int> vec = { -1, 1, -2, 2, -3, 3};
    
    for (auto it = vec.begin(); it != vec.end();)
    {
        auto value = *it;
        if (value < 0)
        {
            it = vec.erase(it);
        }
        else
        {
            ++it;
        }
    }
    
    return 0;
}

위와 같이 삭제 코드가 굉장히 길고 실수할 여지가 다분하다.

 

그래서 뒤에 나온 remove_if를 이용해서 삭제를 했었다.

int main()
{
    std::vector<int> vec = { -1, 1, -2, 2, -3, 3 };
    auto newEnd = std::remove_if(vec.begin(), vec.end(), [](int n) { return n < 0; });
    vec.erase(newEnd, vec.end());
    
    return 0;
}

 

드디어 erase_if가 나와서 좀 더 편하게 사용할 수 있다.

int main()
{
    std::vector<int> vec = { -1, 1, -2, 2, -3, 3 };
    
    std::erase(vec, 2); // 2만 삭제.
    std::erase_if(vec, [](int n) { return n < 0; }); // 0보다 작은 것들 삭제.

    return 0;
}
728x90
728x90

C++11 Typed Lambda

auto sumTyped = [](int a, int b) { return a + b; }

 

C++14 Generic Lambda

auto sumGeneric = [](auto a, auto b) { return a + b; }

 

위의 Lambda도 그 동안 편하게 사용하고 있었는데 이제는 템플릿을 이용해서 사용할 수 있게 되었다.

auto sumTemplate = []<template T>(T a, T b) { return a + b; }
728x90

'Basic Programming > C++ 20' 카테고리의 다른 글

C++20 - 비트연산  (0) 2024.01.17
C++20 - erase, erase_if  (1) 2023.12.29
C++20 - NonType Template Parameter  (0) 2023.12.28
C++20 - Conditionally Explicit Constructor (조건부 Explicit 생성자)  (1) 2023.12.27
C++20 - constinit  (2) 2023.12.27

+ Recent posts