개요
이 프로젝트는 C++ 표준 템플릿 라이브러리(STL)의 컨테이너들을 ft 네임스페이스에서 재구현한 것이다. 모든 컨테이너는 표준 라이브러리와 동일한 인터페이스와 동작을 제공하며, 메모리 관리, 반복자, 템플릿 프로그래밍 등의 개념을 학습할 수 있다.
구현된 컨테이너
시퀀스 컨테이너 (Sequence Containers)
1. vector (Vector.hpp)
- 동적 배열 컨테이너
- 연속된 메모리 공간에 요소 저장
- 랜덤 액세스 반복자 지원
- 성장 인자: 1.5배 (동적 확장)
2. list (List.hpp)
- 이중 연결 리스트 컨테이너
- 양방향 반복자 지원
- 양쪽 끝에서 O(1) 삽입/삭제
- 특수 연산:
splice,merge,sort,reverse,unique,remove
3. deque (Deque.hpp)
- 양방향 큐 컨테이너
- 양쪽 끝에서 O(1) 삽입/삭제
- 랜덤 액세스 반복자 지원
컨테이너 어댑터 (Container Adapters)
4. stack (Stack.hpp)
- LIFO (Last In First Out) 스택
list컨테이너를 기반으로 구현push,pop,top연산 제공
5. queue (Queue.hpp)
- FIFO (First In First Out) 큐
list컨테이너를 기반으로 구현push,pop,front,back연산 제공
연관 컨테이너 (Associative Containers)
6. map (Map.hpp)
- 키-값 쌍을 저장하는 정렬된 연관 컨테이너
- 이진 탐색 트리(B-tree) 기반 구현
- 중복 키 허용 안 함
- O(log n) 검색, 삽입, 삭제
7. set (Set.hpp)
- 고유한 요소를 저장하는 정렬된 연관 컨테이너
- 이진 탐색 트리(B-tree) 기반 구현
- 중복 값 허용 안 함
- O(log n) 검색, 삽입, 삭제
8. multimap (MultiMap.hpp)
map과 유사하지만 중복 키 허용- 동일한 키를 가진 여러 요소 저장 가능
9. multiset (MultiSet.hpp)
set과 유사하지만 중복 값 허용- 동일한 값을 가진 여러 요소 저장 가능
주요 기능
반복자 (Iterators)
- Forward Iterator:
list,set,map등 - Bidirectional Iterator:
list,set,map등 - Random Access Iterator:
vector,deque - Reverse Iterator: 모든 컨테이너 지원
- Const Iterator: 모든 컨테이너 지원
메모리 관리
- 커스텀 allocator 지원
- RAII 원칙 준수: 리소스 획득은 초기화(Resource Acquisition Is Initialization)
- 객체가 생성될 때 리소스(메모리)를 획득하고, 소멸될 때 자동으로 해제
- 소멸자에서
destroy()와deallocate()를 호출하여 메모리 누수 방지 - 예시:
vector의 소멸자에서 할당된 모든 요소를destroy()하고 메모리를deallocate()
- 예외 안전성 보장: 예외 발생 시에도 리소스가 안전하게 관리된다
at(): 범위를 벗어나면std::out_of_range예외 발생reserve(): 너무 큰 크기 요청 시std::length_error예외 발생- 예외 발생 시에도 기존 데이터의 무결성 유지 (Basic Guarantee)
템플릿 프로그래밍
- SFINAE (Substitution Failure Is Not An Error) 활용
enable_if를 통한 템플릿 특수화is_integral타입 트레이트
파일 구조
ft_containers/
├── Vector.hpp # vector 컨테이너 구현
├── List.hpp # list 컨테이너 구현
├── Deque.hpp # deque 컨테이너 구현
├── Stack.hpp # stack 컨테이너 어댑터
├── Queue.hpp # queue 컨테이너 어댑터
├── Map.hpp # map 연관 컨테이너
├── Set.hpp # set 연관 컨테이너
├── MultiMap.hpp # multimap 연관 컨테이너
├── MultiSet.hpp # multiset 연관 컨테이너
├── iterator.hpp # 반복자 베이스 클래스 및 유틸리티
├── utility.hpp # 유틸리티 함수 및 타입 트레이트
├── Btree.hpp # 이진 탐색 트리 구현 (map/set 기반)
├── compile.sh # 컴파일 스크립트
└── test/ # 테스트 파일들
├── vectorTest.cpp
├── listTest.cpp
├── mapTest.cpp
├── setTest.cpp
├── dequeTest.cpp
├── stackTest.cpp
├── queueTest.cpp
├── multimapTest.cpp
├── multisetTest.cpp
└── test.hpp
사용 방법
기본 사용 예제
#include "Vector.hpp"
#include "List.hpp"
#include "Map.hpp"
#include <iostream>
int main() {
// Vector 사용 예제
ft::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
for (ft::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// List 사용 예제
ft::list<std::string> lst;
lst.push_back("Hello");
lst.push_back("World");
lst.push_front("ft");
// Map 사용 예제
ft::map<std::string, int> mp;
mp["one"] = 1;
mp["two"] = 2;
mp["three"] = 3;
ft::map<std::string, int>::iterator it = mp.find("two");
if (it != mp.end()) {
std::cout << "Found: " << it->first << " = " << it->second << std::endl;
}
return 0;
}
컴파일
# 컴파일 스크립트 사용
./compile.sh
# 또는 직접 컴파일
g++ -std=c++98 -Wall -Wextra -Werror your_file.cpp
구현 세부사항
Vector
- 메모리 할당: 동적 배열 할당
- 성장 전략: 현재 크기의 1.5배로 확장
- 반복자 무효화: 재할당 시 모든 반복자 무효화
- 예외 안전성: 기본 보장 (Basic Guarantee)
List
- 구조: 이중 연결 리스트
- 더미 노드: 순환 리스트 구조 (
_tip노드) - 특수 연산:
splice: O(1) 리스트 병합merge: 정렬된 리스트 병합sort: 버블 정렬 알고리즘reverse: O(n) 역순 변환
Map/Set
- 구조: 이진 탐색 트리 (B-tree)
- 균형: AVL 트리 또는 Red-Black 트리 (구현에 따라 다름)
- 정렬: 키/값의 비교 함수를 통한 자동 정렬
- 반복자: 중위 순회 (in-order traversal)
Iterator
- 베이스 클래스:
BaseIter<T>: vector, deque용ListBaseIter<T>: list용BtreeBaseIter<E, Compare, isMulti>: map/set용
- 역방향 반복자:
ReverseIterator,ConstReverseIterator래퍼
Utility
- pair: 키-값 쌍 구조체
- less: 비교 함수 객체
- enable_if: SFINAE를 위한 타입 트레이트
- is_integral: 정수 타입 판별
- swap: 값 교환 함수
- distance: 반복자 간 거리 계산
Allocator
프로젝트는 표준 std::allocator를 사용하며, 커스텀 allocator도 지원한다.
template <class T>
class allocator
{
public:
T* allocate(size_t n); // 메모리 할당
void deallocate(T*, size_t); // 메모리 해제
void construct(T*, const T&); // 객체 생성
void destroy(T*); // 객체 소멸
};
테스트
test/ 디렉토리에 각 컨테이너별 테스트 파일이 포함되어 있다. 각 테스트는 표준 라이브러리와의 동작 일치성을 검증한다.
주의사항
- C++98 표준 준수
- 표준 라이브러리(
std::) 사용 금지 (컨테이너 구현 시) - 메모리 누수 없이 구현
- 예외 안전성 보장
- 반복자 무효화 규칙 준수
라이선스
이 프로젝트는 교육 목적으로 작성되었다.